# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1348.16.4 -> 1.1516 # arch/sparc/Kconfig 1.17 -> 1.18 # drivers/pci/hotplug/cpqphp_core.c 1.19 -> 1.20 # arch/mips/dec/prom/memory.c 1.3 -> 1.4 # include/asm-mips/dma.h 1.1 -> 1.2 # fs/nfsd/nfs3xdr.c 1.34 -> 1.35 # include/asm-mips/asm.h 1.2 -> 1.3 # net/ipv4/netfilter/ip_conntrack_core.c 1.30 -> 1.33 # drivers/mtd/devices/doc2001plus.c 1.1 -> 1.2 # arch/mips64/math-emu/dp_div.c 1.2 -> (deleted) # net/rose/sysctl_net_rose.c 1.3 -> 1.4 # include/asm-mips/string.h 1.2 -> 1.3 # arch/mips/math-emu/sp_frexp.c 1.1 -> 1.2 # arch/mips64/mm/Makefile 1.6 -> 1.7 # include/asm-mips/pci_channel.h 1.1 -> 1.2 # arch/mips64/kernel/r4k_fpu.S 1.2 -> 1.3 # include/asm-mips64/sn/intr.h 1.1 -> 1.2 # include/asm-alpha/pci.h 1.15 -> 1.16 # arch/i386/kernel/cpu/cpufreq/speedstep-ich.c 1.18.1.2 -> 1.21 # drivers/mtd/devices/doc2000.c 1.6 -> 1.7 # fs/xfs/xfs_mount.h 1.15 -> 1.16 # arch/mips64/lib/ide-no.c 1.3 -> 1.4 # arch/mips/philips/nino/prom.c 1.1 -> (deleted) # include/asm-mips64/xtalk/xtalk.h 1.2 -> 1.3 # arch/mips/baget/time.c 1.3 -> 1.4 # include/asm-mips/atomic.h 1.4 -> 1.5 # arch/mips/lib/kbd-std.c 1.3 -> (deleted) # arch/mips/math-emu/sp_cmp.c 1.1 -> 1.2 # include/asm-ppc/hardirq.h 1.20 -> 1.21 # include/asm-mips64/topology.h 1.3 -> 1.4 # arch/mips/mips-boards/malta/Makefile 1.4 -> 1.5 # arch/mips/mm/sb1.c 1.3 -> (deleted) # arch/mips/philips/nino/setup.c 1.1 -> (deleted) # include/asm-mips64/asm.h 1.2 -> 1.3 # fs/xfs/linux/xfs_sysctl.h 1.8 -> 1.9 # drivers/s390/block/dasd_eckd.c 1.19 -> 1.21 # drivers/media/dvb/ttpci/av7110_firm.h 1.1 -> 1.2 # drivers/media/common/saa7146_vbi.c 1.1 -> 1.3 # include/asm-mips/parport.h 1.1 -> 1.2 # arch/s390/kernel/smp.c 1.25 -> 1.26 # arch/mips64/kernel/setup.c 1.6 -> 1.7 # arch/mips/math-emu/ieee754sp.h 1.1 -> 1.2 # include/asm-ia64/topology.h 1.8 -> 1.9 # include/asm-mips64/page.h 1.4 -> 1.5 # include/asm-mips64/semaphore-helper.h 1.2 -> 1.3 # drivers/media/dvb/ttpci/av7110.h 1.1 -> 1.2 # drivers/media/dvb/frontends/Makefile 1.4 -> 1.5 # arch/mips64/sgi-ip27/ip27-nmi.c 1.2 -> 1.3 arch/mips/sgi-ip27/ip27-nmi.c (moved) # include/asm-mips64/ide.h 1.9 -> 1.10 # include/asm-mips64/fcntl.h 1.2 -> 1.3 # arch/x86_64/kernel/traps.c 1.24 -> 1.25 # drivers/ide/ide-taskfile.c 1.20 -> 1.22 # drivers/mtd/mtd_blkdevs.c 1.1 -> 1.3 # drivers/media/dvb/ttpci/av7110_ipack.h 1.1 -> 1.2 # arch/mips/philips/nino/time.c 1.2 -> (deleted) # include/asm-mips/addrspace.h 1.2 -> 1.3 # include/asm-mips/stackframe.h 1.2 -> 1.3 # drivers/ieee1394/raw1394.c 1.25 -> 1.26 # arch/mips/baget/setup.c 1.3 -> 1.4 # include/asm-mips/dec/tc.h 1.1 -> 1.2 # kernel/ksyms.c 1.205 -> 1.206 # drivers/char/n_tty.c 1.14 -> 1.15 # drivers/sgi/char/Makefile 1.6 -> (deleted) # arch/mips/Makefile 1.13 -> 1.14 # arch/mips/kernel/irix5sys.h 1.1 -> 1.2 # fs/xfs/linux/xfs_vfs.h 1.11.1.1 -> 1.14 # include/net/sctp/user.h 1.11 -> 1.12 # include/asm-mips64/elf.h 1.6 -> 1.7 # arch/mips/mm/rm7k.c 1.4 -> (deleted) # drivers/i2c/Makefile 1.11 -> 1.12 # arch/mips64/kernel/r4k_switch.S 1.3 -> 1.4 # include/asm-mips/unistd.h 1.6 -> 1.7 # arch/mips64/mm/r4xx0.c 1.7 -> (deleted) # include/asm-mips/floppy.h 1.2 -> 1.3 # include/asm-mips/au1000.h 1.1 -> 1.2 # drivers/mtd/nftlcore.c 1.44 -> 1.45 # include/media/saa7146.h 1.2 -> 1.3 # arch/mips/philips/nino/int-handler.S 1.2 -> (deleted) # include/asm-mips64/addrspace.h 1.2 -> 1.3 # include/asm-mips64/io.h 1.3 -> 1.4 # include/asm-mips/nile4.h 1.1 -> 1.2 # arch/mips64/sgi-ip22/Makefile 1.7 -> (deleted) # drivers/net/irda/vlsi_ir.c 1.16 -> 1.17 # include/asm-mips/processor.h 1.10 -> 1.11 # include/asm-mips/uaccess.h 1.2 -> 1.3 # include/asm-mips/vga.h 1.1 -> 1.2 # drivers/pnp/pnpbios/core.c 1.32 -> 1.33 # arch/x86_64/ia32/ia32_binfmt.c 1.13 -> 1.14 # net/sctp/associola.c 1.49.1.1 -> 1.55 # arch/ia64/Makefile 1.53 -> 1.55 # drivers/usb/net/cdc-ether.c 1.30 -> (deleted) # fs/xfs/pagebuf/page_buf.c 1.53 -> 1.54 # arch/ia64/kernel/efi.c 1.20 -> 1.21 # arch/mips/math-emu/ieee754.c 1.2 -> 1.3 # arch/mips64/mm/andes.c 1.6 -> (deleted) # arch/mips64/arc/time.c 1.2 -> (deleted) # net/ipv6/exthdrs.c 1.12 -> 1.13 # include/asm-mips/gfx.h 1.2 -> 1.3 # include/asm-mips64/sn/sn0/addrs.h 1.2 -> 1.3 # include/linux/nfsd/state.h 1.4 -> 1.7 # drivers/serial/8250.c 1.33 -> 1.34 # drivers/char/agp/sis-agp.c 1.23 -> 1.24 # arch/mips/kernel/syscalls.h 1.3 -> 1.4 # arch/mips/math-emu/kernel_linkage.c 1.1 -> 1.2 # arch/mips/mips-boards/generic/init.c 1.1 -> 1.2 # lib/Makefile 1.24 -> 1.25 # arch/mips/sgi/kernel/Makefile 1.7 -> (deleted) # arch/mips/sgi/kernel/indy_int.c 1.4 -> (deleted) # arch/mips64/sgi-ip22/system.c 1.2 -> (deleted) # arch/mips64/math-emu/dp_frexp.c 1.1 -> (deleted) # drivers/ieee1394/csr.h 1.4 -> 1.5 # include/asm-mips64/mmzone.h 1.6 -> 1.7 # arch/mips64/math-emu/dp_sqrt.c 1.1 -> (deleted) # net/ipv6/ip6_output.c 1.31 -> 1.34 # drivers/mtd/inftlmount.c 1.1 -> 1.2 # net/sunrpc/sysctl.c 1.4 -> 1.5 # arch/mips/dec/prom/locore.S 1.1 -> 1.2 # include/asm-mips64/shmbuf.h 1.1 -> 1.2 # drivers/usb/serial/io_edgeport.c 1.45 -> 1.46 # drivers/net/ioc3-eth.c 1.18 -> 1.20 # drivers/media/video/mxb.c 1.4 -> 1.5 # include/asm-mips/types.h 1.2 -> 1.3 # arch/mips64/math-emu/dp_modf.c 1.1 -> (deleted) # include/asm-mips/r4kcache.h 1.1 -> 1.2 # net/sctp/sm_statefuns.c 1.53.1.1 -> 1.60 # arch/mips/philips/nino/irq.c 1.5 -> (deleted) # arch/mips64/mips-boards/atlas/atlas_rtc.c 1.1 -> (deleted) # arch/mips/baget/ld.script.balo 1.2 -> 1.3 # arch/mips64/math-emu/sp_fint.c 1.1 -> (deleted) # include/asm-mips64/mmu.h 1.1 -> 1.2 # arch/i386/pci/pcbios.c 1.13 -> 1.14 # drivers/i2c/busses/Makefile 1.8 -> 1.9 # arch/mips/math-emu/dp_div.c 1.2 -> 1.3 # arch/mips/au1000/common/reset.c 1.1 -> 1.2 # include/asm-mips64/sn/sn0/hubni.h 1.2 -> 1.3 # arch/mips/kernel/irixinv.c 1.1 -> 1.2 # include/asm-mips64/dma.h 1.1 -> 1.2 # include/media/saa7146_vv.h 1.1 -> 1.3 # include/asm-mips64/xtalk/xwidget.h 1.2 -> 1.3 # arch/mips/math-emu/dp_tint.c 1.1 -> 1.2 # Documentation/cpu-freq/user-guide.txt 1.6 -> 1.7 # arch/mips/lib/Makefile 1.7 -> 1.8 # net/ipv6/sysctl_net_ipv6.c 1.6 -> 1.7 # include/asm-mips/bitops.h 1.5 -> 1.6 # include/asm-sparc/unistd.h 1.20 -> 1.21 # include/asm-mips/checksum.h 1.5 -> 1.6 # arch/mips64/lib/memcpy.S 1.3 -> 1.4 # include/asm-mips64/sn/sn0/ip27.h 1.2 -> 1.3 # include/asm-mips64/pci.h 1.9 -> 1.10 # arch/ia64/defconfig 1.19 -> 1.20 # include/asm-mips64/mmu_context.h 1.3 -> 1.4 # drivers/net/pcmcia/nmclan_cs.c 1.14 -> 1.15 # net/sched/cls_rsvp.h 1.4 -> 1.5 # drivers/media/dvb/dvb-core/dvb_net.h 1.3 -> 1.4 # arch/mips64/sgi-ip22/ip22-int.c 1.7 -> (deleted) # arch/mips64/mips-boards/atlas/atlas_setup.c 1.1 -> (deleted) # include/asm-mips/baget/vic.h 1.1 -> 1.2 # include/linux/netfilter_ipv4/lockhelp.h 1.1 -> 1.2 # arch/mips64/mips-boards/generic/pci.c 1.6 -> (deleted) # arch/s390/kernel/syscalls.S 1.2 -> 1.3 # arch/mips/lib/r3k_dump_tlb.c 1.2 -> 1.3 # arch/mips/ddb5074/prom.c 1.2 -> (deleted) # kernel/fork.c 1.126 -> 1.127 # net/sunrpc/svcsock.c 1.53 -> 1.54 # drivers/mtd/inftlcore.c 1.1 -> 1.3 # arch/mips64/mm/umap.c 1.6 -> (deleted) # include/asm-mips/fp.h 1.1 -> (deleted) # drivers/net/Space.c 1.22 -> 1.23 # kernel/sys.c 1.47 -> 1.49 # fs/jffs2/os-linux.h 1.10 -> 1.11 # include/linux/dvb/net.h 1.2 -> 1.3 # arch/mips/ddb5074/Makefile 1.6 -> 1.7 arch/mips/ddb5xxx/ddb5074/Makefile (moved) # include/asm-mips64/a.out.h 1.2 -> 1.3 # include/asm-mips/current.h 1.2 -> 1.3 # drivers/pci/hotplug/ibmphp.h 1.8 -> 1.9 # include/asm-mips64/sn/sn0/hubio.h 1.3 -> 1.4 # arch/mips64/sgi-ip22/time.c 1.2 -> (deleted) # include/asm-mips64/sn/sn0/sn0_fru.h 1.2 -> 1.3 # include/asm-mips/sgi/sgint23.h 1.2 -> (deleted) # arch/mips/math-emu/sp_sqrt.c 1.1 -> 1.2 # arch/mips64/tools/Makefile 1.4 -> (deleted) # arch/mips64/mm/extable.c 1.3 -> 1.4 # arch/mips64/math-emu/dp_scalb.c 1.1 -> (deleted) # include/net/tcp.h 1.49 -> 1.50 # include/asm-mips/irq.h 1.4 -> 1.5 # drivers/media/dvb/ttpci/budget-ci.c 1.1 -> 1.3 # drivers/media/dvb/frontends/alps_bsrv2.c 1.4 -> 1.6 # arch/mips64/kernel/scall_64.S 1.6 -> 1.7 # include/linux/netfilter_ipv4/listhelp.h 1.2 -> 1.3 # include/asm-mips64/atomic.h 1.3 -> 1.4 # drivers/s390/net/lcs.c 1.15 -> 1.16 # arch/mips/ddb5xxx/ddb5477/irq.c 1.1 -> 1.2 # include/asm-mips/mips-boards/malta.h 1.1 -> 1.2 # arch/mips/kernel/ioport.c 1.1 -> (deleted) # fs/smbfs/inode.c 1.41 -> 1.42 # net/sctp/endpointola.c 1.26 -> 1.27 # fs/dcache.c 1.58 -> 1.59 # drivers/ieee1394/sbp2.c 1.35 -> 1.36 # include/linux/dvb/video.h 1.2 -> 1.3 # arch/mips/math-emu/ieee754.h 1.1 -> 1.2 # fs/smbfs/proc.c 1.31 -> 1.32 # drivers/s390/block/dasd_erp.c 1.3 -> 1.4 # drivers/media/dvb/frontends/grundig_29504-401.c 1.3 -> 1.5 # include/asm-mips64/gfx.h 1.3 -> 1.4 # arch/mips/mips-boards/generic/memory.c 1.2 -> 1.3 # include/asm-mips64/cpu.h 1.2 -> 1.3 # arch/mips/kernel/irq.c 1.10 -> 1.11 # drivers/media/dvb/ttpci/budget-patch.c 1.1 -> 1.3 # arch/mips64/math-emu/Makefile 1.4 -> (deleted) # arch/mips/defconfig 1.6 -> 1.7 # arch/mips64/kernel/entry.S 1.4 -> 1.5 # include/asm-mips/cpu.h 1.3 -> 1.4 # include/asm-mips64/bootinfo.h 1.3 -> 1.4 # include/asm-mips64/sn/sn0/hubpi.h 1.2 -> 1.3 # arch/mips/arc/file.c 1.1 -> 1.2 # net/sctp/sm_make_chunk.c 1.51 -> 1.55 # arch/sparc/kernel/process.c 1.26 -> 1.27 # arch/ia64/sn/kernel/Makefile 1.13 -> 1.14 # arch/sparc/Makefile 1.23 -> 1.24 # include/asm-mips64/current.h 1.2 -> 1.3 # arch/mips/math-emu/dp_fsp.c 1.1 -> 1.2 # arch/mips/math-emu/ieee754xcpt.c 1.1 -> 1.2 # drivers/pnp/interface.c 1.16 -> 1.17 # drivers/net/sk98lin/skge.c 1.20 -> 1.21 # include/asm-h8300/processor.h 1.1 -> 1.2 # drivers/usb/host/uhci-debug.c 1.5 -> 1.6 # include/asm-mips/dec/ioasic_addrs.h 1.2 -> 1.3 # arch/i386/Kconfig 1.62 -> 1.64 # include/linux/nfsd/xdr4.h 1.11 -> 1.14 # net/ipv4/netfilter/ip_nat_core.c 1.27 -> 1.28 # drivers/ieee1394/video1394.c 1.35 -> 1.36 # drivers/media/dvb/frontends/Kconfig 1.4 -> 1.5 # include/asm-s390/dasd.h 1.8 -> 1.9 # arch/mips/kernel/i8259.c 1.2 -> 1.3 # drivers/pci/hotplug/ibmphp_ebda.c 1.10 -> 1.11 # drivers/mtd/nand/autcpu12.c 1.1 -> 1.2 # include/asm-s390/compat.h 1.3 -> 1.4 # include/linux/elf.h 1.23 -> 1.24 # include/asm-mips/smp.h 1.2 -> 1.3 # arch/mips/arc/env.c 1.1 -> 1.2 # drivers/atm/he.c 1.15 -> 1.16 # arch/x86_64/kernel/i8259.c 1.7 -> 1.8 # include/asm-mips64/sgi/sgimc.h 1.2 -> (deleted) # arch/mips/kernel/ipc.c 1.1 -> 1.2 # drivers/ieee1394/ieee1394_core.h 1.14 -> 1.15 # drivers/media/dvb/dvb-core/dvb_demux.c 1.4 -> 1.6 # include/asm-sparc64/unistd.h 1.19 -> 1.20 # arch/mips/sgi/kernel/time.c 1.3 -> (deleted) # drivers/usb/net/cdc-ether.h 1.6 -> (deleted) # arch/mips/algor/README 1.1 -> (deleted) # drivers/sgi/char/graphics.h 1.1 -> (deleted) # arch/i386/kernel/traps.c 1.54 -> 1.55 # arch/mips/arc/misc.c 1.4 -> 1.5 # arch/mips/kernel/smp.c 1.11 -> 1.12 # fs/nfsd/nfsctl.c 1.36 -> 1.37 # arch/i386/kernel/Makefile 1.44 -> 1.45 # include/asm-mips/isadep.h 1.3 -> 1.4 # arch/mips/sgi/kernel/reset.c 1.3 -> (deleted) # include/asm-mips64/floppy.h 1.2 -> 1.3 # include/asm-mips64/poll.h 1.2 -> 1.3 # include/asm-mips/rrm.h 1.1 -> (deleted) # drivers/mtd/maps/tqm8xxl.c 1.3 -> 1.4 # arch/mips/kernel/setup.c 1.10 -> 1.11 # arch/mips/kernel/entry.S 1.4 -> 1.5 # include/asm-mips64/hw_irq.h 1.1 -> 1.2 # arch/mips64/sgi-ip32/crime.c 1.1 -> 1.2 arch/mips/sgi-ip32/crime.c (moved) # drivers/mtd/maps/impa7.c 1.3 -> 1.4 # drivers/media/dvb/dvb-core/dvb_net.c 1.3 -> 1.5 # include/asm-x86_64/mtrr.h 1.5 -> 1.6 # arch/mips/tools/Makefile 1.3 -> (deleted) # arch/mips/ddb5xxx/ddb5477/debug.c 1.1 -> 1.2 # include/asm-mips/ddb5xxx/ddb5477.h 1.1 -> 1.2 # fs/xfs/xfs_vfsops.c 1.33.1.1 -> 1.36 # arch/mips64/mips-boards/generic/time.c 1.4 -> (deleted) # arch/mips64/sgi-ip27/ip27-irq-glue.S 1.2 -> 1.3 arch/mips/sgi-ip27/ip27-irq-glue.S (moved) # include/asm-mips/param.h 1.2 -> 1.3 # drivers/serial/sunsu.c 1.35 -> 1.36 # drivers/char/agp/nvidia-agp.c 1.10 -> 1.11 # drivers/net/wan/sdla_ppp.c 1.25 -> 1.26 # drivers/media/dvb/ttpci/av7110_ir.c 1.1 -> 1.3 # include/asm-mips/dec/tcmodule.h 1.2 -> 1.3 # include/asm-mips/cacheops.h 1.1 -> 1.2 # include/asm-mips/dec/tcinfo.h 1.1 -> 1.2 # arch/i386/pci/numa.c 1.13 -> 1.14 # arch/i386/kernel/cpu/cpufreq/Kconfig 1.7 -> 1.8 # net/sched/sch_teql.c 1.6 -> 1.7 # drivers/media/dvb/dvb-core/dvbdev.c 1.10 -> 1.12 # drivers/s390/cio/qdio.h 1.4 -> 1.5 # include/asm-mips/bootinfo.h 1.4 -> 1.5 # include/asm-mips64/r10kcacheops.h 1.2 -> (deleted) # drivers/pnp/support.c 1.5 -> 1.6 # net/ipv4/netfilter/ip_nat_amanda.c 1.2 -> 1.3 # drivers/media/dvb/frontends/alps_tdmb7.c 1.3 -> 1.5 # arch/mips/kernel/mips_ksyms.c 1.8 -> 1.9 # arch/mips/arc/identify.c 1.3 -> 1.4 # include/asm-mips/inventory.h 1.1 -> 1.2 # include/asm-mips64/stackframe.h 1.1 -> 1.2 # net/atm/atm_misc.c 1.6 -> 1.7 # arch/x86_64/kernel/acpi/boot.c 1.2 -> 1.3 # security/dummy.c 1.25 -> 1.26 # drivers/i2c/Kconfig 1.10 -> 1.11 # net/netrom/sysctl_net_netrom.c 1.3 -> 1.4 # arch/mips64/mips-boards/generic/Makefile 1.6 -> (deleted) # arch/mips/kernel/gdb-low.S 1.2 -> 1.3 # drivers/atm/eni.c 1.16 -> 1.17 # include/asm-ppc/thread_info.h 1.8 -> 1.9 # include/linux/xfrm.h 1.11 -> 1.14 # drivers/media/dvb/dvb-core/dvb_filter.h 1.3 -> 1.4 # include/asm-mips/time.h 1.2 -> 1.3 # include/asm-mips/dec/kn02xa.h 1.2 -> 1.3 # arch/i386/pci/direct.c 1.15 -> 1.17 # drivers/scsi/NCR53C9x.c 1.23 -> 1.24 # net/ipv4/netfilter/Makefile 1.19 -> 1.21 # arch/mips/tools/offset.c 1.3 -> (deleted) # drivers/block/nbd.c 1.56 -> 1.57 # drivers/media/dvb/dvb-core/dvb_frontend.c 1.4 -> 1.6 # include/asm-mips64/sn/arch.h 1.2 -> 1.3 # drivers/ieee1394/ieee1394_core.c 1.32 -> 1.33 # drivers/net/pcmcia/3c574_cs.c 1.17 -> 1.18 # arch/mips/lib/watch.S 1.1 -> 1.2 # net/ipv4/netfilter/ip_tables.c 1.16 -> 1.17 # include/asm-mips/module.h 1.2 -> 1.3 # arch/ia64/kernel/smpboot.c 1.35 -> 1.36 # arch/mips/defconfig-ddb5477 1.3 -> 1.4 # arch/mips64/math-emu/ieee754.c 1.2 -> (deleted) # arch/mips64/lib/strncpy_user.S 1.2 -> 1.3 # arch/mips/math-emu/dp_frexp.c 1.1 -> 1.2 # net/key/af_key.c 1.43 -> 1.44 # drivers/s390/char/tape_core.c 1.5 -> 1.6 # drivers/media/dvb/frontends/alps_tdlb7.c 1.3 -> 1.5 # include/asm-mips/mmu.h 1.1 -> 1.2 # arch/mips64/kernel/signal.c 1.8 -> 1.9 # arch/sparc64/solaris/fs.c 1.14 -> 1.15 # arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S 1.1 -> 1.2 # arch/mips/au1000/pb1000/init.c 1.1 -> 1.2 # arch/mips/ddb5xxx/ddb5477/irq_5477.c 1.1 -> 1.2 # arch/mips/kernel/proc.c 1.3 -> 1.4 # arch/mips/mips-boards/malta/malta_int.c 1.2 -> 1.3 # arch/mips/sgi/kernel/indy_rtc.c 1.2 -> (deleted) # arch/mips64/math-emu/dp_logb.c 1.1 -> (deleted) # arch/ia64/sn/kernel/setup.c 1.14 -> 1.15 # include/asm-mips64/posix_types.h 1.3 -> 1.4 # arch/mips64/Makefile 1.15 -> 1.16 # arch/mips/kernel/init_task.c 1.3 -> 1.4 # arch/mips64/arc/identify.c 1.2 -> (deleted) # include/asm-mips/tlb.h 1.1 -> 1.2 # drivers/acpi/pci_root.c 1.15 -> 1.16 # arch/mips/kernel/sysmips.c 1.5 -> 1.6 # arch/mips64/kernel/unaligned.c 1.3 -> 1.4 # arch/mips64/sgi-ip27/ip27-berr.c 1.2 -> 1.3 arch/mips/sgi-ip27/ip27-berr.c (moved) # include/asm-mips/pmc/ev64120int.h 1.1 -> (deleted) # drivers/sgi/char/sgiserial.c 1.19 -> (deleted) # arch/mips/arc/Makefile 1.5 -> 1.6 # drivers/pci/hotplug/ibmphp_hpc.c 1.11 -> 1.13 # include/asm-x86_64/floppy.h 1.3 -> 1.4 # arch/mips/mm/fault.c 1.5 -> 1.6 # arch/mips64/kernel/process.c 1.6 -> 1.7 # arch/mips64/sgi-ip27/ip27-memory.c 1.5 -> 1.6 arch/mips/sgi-ip27/ip27-memory.c (moved) # include/asm-mips/dec/kn01.h 1.1 -> 1.2 # include/net/sctp/sctp.h 1.44 -> 1.45 # drivers/mtd/chips/amd_flash.c 1.6 -> 1.7 # arch/mips/defconfig-malta 1.3 -> 1.4 # arch/ia64/sn/io/machvec/pci.c 1.7 -> 1.8 # include/asm-mips/hardirq.h 1.3 -> 1.4 # include/asm-mips64/sgialib.h 1.3 -> 1.4 # drivers/pci/pci.c 1.56 -> 1.57 # drivers/media/dvb/frontends/dvb_dummy_fe.c 1.1 -> 1.3 # include/asm-mips64/checksum.h 1.5 -> 1.6 # include/asm-mips64/asmmacro.h 1.2 -> 1.3 # drivers/net/Makefile 1.63 -> 1.65 # drivers/mtd/chips/cfi_cmdset_0001.c 1.8 -> 1.9 # arch/x86_64/ia32/ptrace32.c 1.7 -> 1.8 # include/asm-mips/pgtable.h 1.11 -> 1.12 # arch/mips64/Kconfig 1.15 -> 1.16 # net/atm/proc.c 1.19 -> 1.20 # drivers/ide/ide.c 1.74 -> 1.80 # arch/ia64/sn/io/machvec/pci_dma.c 1.9 -> 1.11 # drivers/ieee1394/ieee1394.h 1.7 -> 1.8 # drivers/mtd/devices/doc2001.c 1.5 -> 1.6 # arch/mips/math-emu/dp_add.c 1.2 -> 1.3 # arch/mips/ddb5xxx/ddb5477/Makefile 1.5 -> 1.6 # arch/mips64/kernel/binfmt_elf32.c 1.4 -> (deleted) # include/asm-mips/shmiq.h 1.2 -> 1.3 # net/atm/pvc.c 1.12 -> 1.13 # arch/mips/kernel/r4k_misc.S 1.4 -> (deleted) # arch/mips/philips/nino/ramdisk/ld.script 1.1 -> (deleted) # include/asm-mips64/bugs.h 1.2 -> 1.3 # include/asm-mips64/smp.h 1.3 -> 1.4 # arch/mips/au1000/common/serial.c 1.22 -> (deleted) # drivers/usb/serial/visor.c 1.62 -> 1.63 # arch/mips/baget/prom/init.c 1.2 -> 1.3 # arch/mips64/arc/env.c 1.2 -> (deleted) # include/asm-mips/mman.h 1.1 -> 1.2 # net/ipv6/reassembly.c 1.18 -> 1.19 # drivers/media/dvb/dvb-core/dvbdev.h 1.4 -> 1.6 # arch/mips64/kernel/r4k_tlb_glue.S 1.2 -> (deleted) # arch/mips64/kernel/head.S 1.2 -> 1.3 # arch/mips/mips-boards/generic/mipsIRQ.S 1.1 -> 1.2 # arch/mips64/math-emu/sp_add.c 1.2 -> (deleted) # arch/mips/dec/Makefile 1.9 -> 1.10 # drivers/sgi/Makefile 1.5 -> (deleted) # include/asm-mips/cache.h 1.3 -> 1.4 # include/asm-mips64/scatterlist.h 1.3 -> 1.4 # arch/mips/dec/rtc-dec.c 1.2 -> 1.3 # include/asm-mips64/mips-boards/malta.h 1.1 -> 1.2 # include/asm-mips64/pci/bridge.h 1.3 -> 1.4 # arch/mips64/kernel/branch.c 1.2 -> 1.3 # net/sctp/outqueue.c 1.35 -> 1.36 # drivers/video/i810/i810_main.c 1.10 -> 1.11 # arch/mips64/math-emu/sp_mul.c 1.2 -> (deleted) # arch/mips/au1000/common/int-handler.S 1.1 -> 1.2 # drivers/ieee1394/ieee1394_transactions.c 1.12 -> 1.13 # drivers/media/dvb/ttpci/budget-core.c 1.1 -> 1.3 # include/asm-mips/signal.h 1.3 -> 1.4 # drivers/net/au1000_eth.h 1.3 -> 1.4 # include/asm-mips/msgbuf.h 1.1 -> 1.2 # arch/i386/kernel/io_apic.c 1.71 -> 1.74 # fs/xfs/linux/xfs_iops.c 1.23 -> 1.25 # include/net/sctp/sla1.h 1.3 -> (deleted) # arch/mips64/kernel/init_task.c 1.3 -> 1.4 # arch/mips64/arc/file.c 1.2 -> (deleted) # arch/mips64/lib/strlen_user.S 1.2 -> 1.3 # include/asm-mips/branch.h 1.1 -> 1.2 # include/asm-mips/sembuf.h 1.1 -> 1.2 # include/asm-mips64/sn/io.h 1.1 -> 1.2 # arch/sparc64/defconfig 1.89 -> 1.91 # drivers/net/sunhme.c 1.34 -> 1.35 # arch/ia64/sn/io/drivers/ifconfig_net.c 1.6 -> (deleted) # include/net/sctp/constants.h 1.14 -> 1.15 # arch/mips/math-emu/ieee754sp.c 1.3 -> 1.4 # include/asm-mips64/uaccess.h 1.2 -> 1.3 # arch/mips64/math-emu/ieee754int.h 1.1 -> (deleted) # include/asm-mips/pmc/ev64120.h 1.1 -> (deleted) # arch/mips/vmlinux.lds.S 1.9 -> 1.10 # drivers/mtd/maps/arctic-mtd.c 1.1 -> 1.2 # drivers/media/dvb/dvb-core/demux.h 1.2 -> 1.4 # drivers/sgi/char/ds1286.c 1.7 -> (deleted) # net/ipv4/netfilter/ipt_ULOG.c 1.9 -> 1.10 # arch/s390/kernel/traps.c 1.19 -> 1.20 # include/asm-mips64/irq.h 1.3 -> 1.4 # arch/mips/lib/ide-no.c 1.2 -> 1.3 # arch/mips64/lib/strnlen_user.S 1.2 -> 1.3 # arch/mips/math-emu/sp_fint.c 1.1 -> 1.2 # arch/mips/lib/kbd-no.c 1.1 -> (deleted) # fs/xfs/xfs_mount.c 1.30 -> 1.31 # arch/mips/au1000/common/time.c 1.3 -> 1.4 # arch/mips/defconfig-pb1000 1.3 -> 1.4 # include/asm-mips/dec/interrupts.h 1.2 -> 1.3 # drivers/sgi/char/rrm.c 1.2 -> (deleted) # arch/mips64/math-emu/dp_cmp.c 1.1 -> (deleted) # arch/mips/math-emu/sp_sub.c 1.2 -> 1.3 # include/asm-mips64/user.h 1.2 -> 1.3 # include/asm-mips64/sgi/sgihpc.h 1.2 -> (deleted) # include/asm-mips64/sn/intr_public.h 1.1 -> 1.2 # security/capability.c 1.17 -> 1.18 # drivers/pcmcia/ti113x.h 1.6 -> 1.8 # arch/mips/defconfig-atlas 1.3 -> 1.4 # include/asm-mips64/sn/gda.h 1.2 -> 1.3 # include/asm-mips/sgiarcs.h 1.1 -> 1.2 # arch/mips/ddb5476/pci.c 1.9 -> (deleted) # include/asm-mips/page.h 1.4 -> 1.5 # arch/mips/au1000/common/irq.c 1.1 -> 1.2 # arch/mips64/math-emu/sp_tint.c 1.1 -> (deleted) # include/asm-mips/sgi/sgihpc.h 1.1 -> (deleted) # include/asm-mips64/param.h 1.1 -> 1.2 # drivers/pci/hotplug/pci_hotplug.h 1.8 -> 1.9 # drivers/s390/net/ctcmain.c 1.22 -> 1.23 # arch/mips64/sgi-ip27/ip27-timer.c 1.5 -> 1.6 arch/mips/sgi-ip27/ip27-timer.c (moved) # arch/mips/philips/nino/Makefile 1.6 -> (deleted) # include/asm-mips/mips-boards/atlas.h 1.1 -> 1.2 # arch/mips64/kernel/softfp.S 1.1 -> (deleted) # net/sctp/proc.c 1.5 -> 1.6 # drivers/scsi/fd_mcs.c 1.15 -> 1.16 # arch/mips/dec/prom/Makefile 1.7 -> 1.8 # net/sctp/sysctl.c 1.9 -> 1.12 # drivers/media/dvb/dvb-core/dvb_demux.h 1.3 -> 1.5 # arch/mips64/sgi-ip27/ip27-setup.c 1.2 -> 1.3 arch/mips/sgi-ip27/ip27-setup.c (moved) # arch/mips/ddb5074/nile4.c 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5074/nile4_pic.c (moved) # drivers/sgi/char/gconsole.h 1.1 -> (deleted) # include/linux/ide.h 1.58 -> 1.60 # drivers/mtd/mtdblock.c 1.44 -> 1.45 # net/unix/sysctl_net_unix.c 1.5 -> 1.6 # arch/mips64/kernel/Makefile 1.9 -> 1.10 # arch/mips/dec/setup.c 1.2 -> 1.3 # include/asm-mips/baget/vac.h 1.1 -> 1.2 # drivers/serial/sunsab.c 1.29 -> 1.30 # fs/xfs/xfs_acl.c 1.6 -> 1.7 # arch/mips/mips-boards/generic/gdb_hook.c 1.2 -> 1.3 # arch/mips64/sgi-ip22/ip22-irq.S 1.2 -> (deleted) # include/asm-mips/io.h 1.3 -> 1.4 # include/asm-mips64/hardirq.h 1.2 -> 1.3 # include/asm-mips64/sgiarcs.h 1.3 -> 1.4 # arch/mips/sgi/kernel/indyIRQ.S 1.1 -> (deleted) # include/asm-mips/paccess.h 1.1 -> 1.2 # include/asm-mips/prctl.h 1.1 -> 1.2 # arch/mips/mips-boards/generic/pci.c 1.8 -> (deleted) # arch/mips64/kernel/mips64_ksyms.c 1.8 -> 1.9 # arch/mips64/mips-boards/generic/cmdline.c 1.1 -> (deleted) # arch/mips64/sgi-ip27/ip27-klnuma.c 1.2 -> 1.3 arch/mips/sgi-ip27/ip27-klnuma.c (moved) # arch/s390/Kconfig 1.12 -> 1.13 # arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 1.1 -> 1.2 # arch/ia64/kernel/irq_ia64.c 1.12 -> 1.13 # mm/swap.c 1.50 -> 1.51 # arch/mips64/tools/offset.c 1.2 -> (deleted) # include/asm-mips/umap.h 1.2 -> (deleted) # include/asm-mips/semaphore.h 1.4 -> 1.5 # include/asm-mips/ddb5xxx/debug.h 1.1 -> (deleted) # arch/mips64/arc/cmdline.c 1.2 -> (deleted) # drivers/usb/storage/initializers.c 1.6 -> 1.7 # arch/mips/philips/nino/ramdisk/Makefile 1.3 -> (deleted) # drivers/sgi/Kconfig 1.1 -> (deleted) # arch/mips/mm/andes.c 1.4 -> (deleted) # include/asm-mips64/reg.h 1.1 -> 1.2 # fs/xfs/xfs_sb.h 1.4 -> 1.5 # include/linux/sunrpc/debug.h 1.3 -> 1.4 # arch/mips64/math-emu/dp_tint.c 1.1 -> (deleted) # arch/i386/pci/common.c 1.39 -> 1.40 # net/netsyms.c 1.83 -> 1.84 # drivers/media/video/dpc7146.c 1.2 -> 1.3 # fs/xfs/xfs_cap.c 1.4 -> 1.5 # net/rxrpc/sysctl.c 1.2 -> 1.3 # arch/mips64/mips-boards/malta/Makefile 1.5 -> (deleted) # include/asm-mips/user.h 1.1 -> 1.2 # include/linux/pci_ids.h 1.105 -> 1.106 # drivers/pci/hotplug/Kconfig 1.8 -> 1.9 # drivers/media/video/saa7111.c 1.12 -> 1.13 # arch/mips/kernel/process.c 1.9 -> 1.10 # arch/mips64/math-emu/sp_sub.c 1.2 -> (deleted) # drivers/sgi/char/usema.c 1.4 -> (deleted) # arch/mips/math-emu/dp_tlong.c 1.1 -> 1.2 # drivers/media/dvb/ttpci/av7110_ipack.c 1.1 -> 1.3 # arch/m68knommu/kernel/traps.c 1.2 -> 1.3 # arch/mips/ddb5476/int-handler.S 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5476/int-handler.S (moved) # arch/mips/sgi/kernel/indy_hpc.c 1.2 -> (deleted) # include/asm-mips64/mips-boards/gt64120.h 1.1 -> 1.2 # include/asm-ia64/tlb.h 1.14 -> 1.15 # arch/mips/kernel/Makefile 1.11 -> 1.12 # fs/hpfs/namei.c 1.17 -> 1.18 # include/asm-mips64/system.h 1.4 -> 1.5 # arch/mips/mm/r4xx0.c 1.6 -> (deleted) # arch/mips64/sgi-ip32/ip32-irq-glue.S 1.1 -> 1.2 arch/mips/sgi-ip32/ip32-irq-glue.S (moved) # arch/mips64/sgi-ip32/ip32-pci-dma.c 1.1 -> (deleted) # drivers/sgi/char/sgiserial.h 1.4 -> (deleted) # arch/mips/kernel/traps.c 1.7 -> 1.8 # include/asm-mips/ddb5xxx/pci.h 1.1 -> (deleted) # include/asm-mips64/sn/kldir.h 1.1 -> 1.2 # arch/x86_64/ia32/sys_ia32.c 1.33 -> 1.34 # arch/sparc64/kernel/systbls.S 1.39 -> 1.40 # include/asm-mips/elf.h 1.5 -> 1.6 # include/asm-mips/system.h 1.5 -> 1.6 # arch/mips64/math-emu/ieee754d.c 1.1 -> (deleted) # arch/x86_64/kernel/pci-gart.c 1.13 -> 1.14 # drivers/pci/hotplug/cpci_hotplug_core.c 1.6 -> 1.7 # include/linux/usb_gadget.h 1.2 -> 1.3 # arch/mips/kernel/time.c 1.8 -> 1.9 # arch/mips/math-emu/dp_mul.c 1.2 -> 1.3 # fs/jffs2/fs.c 1.12 -> 1.13 # drivers/video/vgastate.c 1.3 -> 1.4 # arch/mips/mm/r2300.c 1.5 -> (deleted) # arch/mips/arc/init.c 1.2 -> 1.3 # arch/mips/kernel/vm86.c 1.1 -> (deleted) # arch/i386/kernel/cpu/cpufreq/Makefile 1.7 -> 1.8 # include/linux/eventpoll.h 1.9 -> 1.10 # arch/mips/ddb5xxx/common/pci_auto.c 1.1 -> (deleted) # arch/ia64/pci/pci.c 1.31 -> 1.34 # arch/mips/arc/time.c 1.1 -> 1.2 # fs/binfmt_elf.c 1.47 -> 1.48 # include/net/sctp/sm.h 1.24 -> 1.25 # arch/mips/ddb5xxx/common/irq_cpu.c 1.1 -> (deleted) # arch/mips64/math-emu/sp_flong.c 1.1 -> (deleted) # arch/mips64/math-emu/sp_sqrt.c 1.1 -> (deleted) # include/asm-mips64/sn/mapped_kernel.h 1.2 -> 1.3 # drivers/net/irda/Makefile 1.15 -> 1.16 # include/asm-mips/dec/kn03.h 1.2 -> 1.3 # arch/v850/Kconfig 1.14 -> 1.15 # arch/x86_64/kernel/nmi.c 1.12 -> 1.13 # arch/mips64/vmlinux.lds.S 1.8 -> 1.9 # drivers/usb/serial/pl2303.c 1.41 -> 1.42 # drivers/s390/block/dasd.c 1.62 -> 1.63 # fs/xfs/xfs_trans.c 1.8 -> 1.9 # fs/compat.c 1.11 -> 1.12 # drivers/net/e1000/e1000_ethtool.c 1.26 -> 1.27 # arch/ia64/kernel/efivars.c 1.11 -> 1.12 # include/asm-mips/mmu_context.h 1.3 -> 1.4 # arch/mips64/sgi-ip27/ip27-rtc.c 1.7 -> (deleted) # include/asm-mips64/mips-boards/atlas.h 1.1 -> 1.2 # arch/mips64/math-emu/sp_modf.c 1.1 -> (deleted) # drivers/net/sgiseeq.h 1.1 -> 1.2 # drivers/net/acenic.c 1.33 -> 1.34 # net/ipv4/utils.c 1.2 -> 1.3 # include/asm-mips64/mman.h 1.2 -> 1.3 # include/linux/pci.h 1.95 -> 1.97 # arch/ia64/kernel/mca.c 1.33 -> 1.34 # drivers/net/e100/e100_main.c 1.76 -> 1.77 # arch/ia64/kernel/iosapic.c 1.27 -> 1.28 # Documentation/pci.txt 1.9 -> 1.10 # fs/xfs/xfs_attr_leaf.c 1.7 -> 1.8 # net/sctp/sla1.c 1.4 -> (deleted) # arch/mips/arc/console.c 1.3 -> 1.4 # include/linux/dvb/frontend.h 1.2 -> 1.3 # arch/mips64/math-emu/dp_sub.c 1.2 -> (deleted) # include/asm-ia64/hw_irq.h 1.6 -> 1.7 # arch/mips64/arc/memory.c 1.3 -> (deleted) # arch/mips/Kconfig 1.13 -> 1.14 # drivers/atm/idt77252.c 1.16 -> 1.17 # arch/ppc/kernel/process.c 1.36 -> 1.37 # arch/mips/ddb5074/pci.c 1.10 -> (deleted) # include/linux/nfs4.h 1.7 -> 1.9 # arch/mips/math-emu/sp_fdp.c 1.2 -> 1.3 # include/asm-mips64/div64.h 1.2 -> 1.3 # include/asm-mips64/sn/sn0/arch.h 1.2 -> 1.3 # arch/mips64/math-emu/dp_fsp.c 1.1 -> (deleted) # net/ipv4/ipmr.c 1.20 -> 1.27 # drivers/mtd/mtdblock_ro.c 1.27 -> 1.28 # include/asm-mips/shmbuf.h 1.2 -> 1.3 # include/asm-mips64/sn/klkernvars.h 1.1 -> 1.2 # arch/ia64/kernel/acpi.c 1.42 -> 1.43 # arch/x86_64/kernel/suspend.c 1.6 -> 1.7 # drivers/mtd/maps/elan-104nc.c 1.6 -> 1.7 # fs/nfs/dir.c 1.55 -> 1.56 # arch/mips/mm/ioremap.c 1.2 -> 1.3 # include/asm-mips64/inst.h 1.2 -> 1.3 # include/asm-mips/namei.h 1.1 -> 1.2 # include/linux/spinlock.h 1.26 -> 1.27 # drivers/net/wan/sdla_chdlc.c 1.31 -> 1.32 # Documentation/DocBook/gadget.tmpl 1.1 -> 1.2 # fs/xfs/support/kmem.c 1.3 -> (deleted) # arch/mips64/kernel/ioctl32.c 1.11 -> 1.12 # drivers/serial/8250_cs.c 1.11 -> 1.15 # arch/mips64/defconfig-ip27 1.7 -> 1.8 # arch/mips/ddb5074/time.c 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5074/time.c (moved) # arch/mips/ddb5xxx/ddb5477/pci.c 1.2 -> (deleted) # include/asm-mips64/processor.h 1.8 -> 1.9 # include/asm-mips/mipsregs.h 1.5 -> 1.6 # arch/mips/kernel/branch.c 1.3 -> 1.4 # include/asm-mips/fpu_emulator.h 1.1 -> 1.2 # include/linux/mroute.h 1.3 -> 1.4 # arch/mips/baget/print.c 1.1 -> 1.2 # arch/sparc/kernel/systbls.S 1.17 -> 1.18 # include/asm-mips64/semaphore.h 1.3 -> 1.4 # drivers/ide/legacy/pdc4030.c 1.11 -> 1.12 # drivers/media/common/saa7146_fops.c 1.2 -> 1.4 # drivers/ide/ide-dma.c 1.15 -> 1.17 # include/linux/netfilter.h 1.5 -> 1.6 # arch/mips64/sgi-ip22/ip22-timer.c 1.4 -> (deleted) # arch/mips64/sgi-ip32/ip32-irq.c 1.1 -> 1.2 arch/mips/sgi-ip32/ip32-irq.c (moved) # include/asm-mips/gdb-stub.h 1.1 -> 1.2 # drivers/usb/storage/initializers.h 1.5 -> 1.6 # drivers/media/dvb/frontends/ves1820.c 1.4 -> 1.6 # arch/mips64/sgi-ip27/ip27-irq.c 1.7 -> 1.8 arch/mips/sgi-ip27/ip27-irq.c (moved) # arch/mips64/kernel/signal32.c 1.9 -> 1.10 # arch/mips64/math-emu/sp_simple.c 1.1 -> (deleted) # include/asm-mips/baget/baget.h 1.1 -> 1.2 # drivers/s390/cio/device_fsm.c 1.5 -> 1.6 # drivers/ieee1394/dma.c 1.3 -> 1.4 # include/asm-mips64/sn/nmi.h 1.2 -> 1.3 # arch/mips64/mips-boards/malta/malta_setup.c 1.1 -> (deleted) # arch/mips/ddb5476/dbg_io.c 1.1 -> 1.2 arch/mips/ddb5xxx/ddb5476/dbg_io.c (moved) # arch/mips/lib/tinycon.c 1.1 -> 1.2 # include/asm-ppc/ptrace.h 1.7 -> 1.8 # include/asm-mips/ddb5xxx/ddb5xxx.h 1.2 -> 1.3 # include/asm-ia64/agp.h 1.3 -> 1.4 # arch/mips64/sgi-ip22/ip22-berr.c 1.2 -> (deleted) # arch/x86_64/ia32/ia32_ioctl.c 1.28 -> 1.29 # arch/mips/lib/dump_tlb.c 1.2 -> 1.3 # include/asm-mips/siginfo.h 1.4 -> 1.5 # arch/mips64/mips-boards/generic/mipsIRQ.S 1.1 -> (deleted) # include/linux/sunrpc/cache.h 1.12 -> 1.14 # include/asm-mips/pgalloc.h 1.5 -> 1.6 # arch/mips/kernel/old-irq.c 1.6 -> (deleted) # arch/mips64/math-emu/sp_cmp.c 1.1 -> (deleted) # arch/ia64/sn/kernel/machvec.c 1.6 -> 1.7 # arch/mips64/mm/loadmmu.c 1.3 -> 1.4 # include/asm-mips64/sigcontext.h 1.2 -> 1.3 # include/asm-mips64/mips-boards/generic.h 1.1 -> 1.2 # include/asm-mips64/sn/addrs.h 1.1 -> 1.2 # arch/arm/Kconfig 1.24 -> 1.25 # include/linux/mtd/doc2000.h 1.5 -> 1.6 # drivers/net/au1000_eth.c 1.13 -> 1.14 # arch/ia64/sn/io/hwgfs/hcl.c 1.2 -> 1.4 # arch/mips64/sgi-ip27/ip27-reset.c 1.1 -> 1.2 arch/mips/sgi-ip27/ip27-reset.c (moved) # fs/xfs/xfs_log_recover.c 1.23 -> 1.26 # include/asm-mips64/sn/klconfig.h 1.3 -> 1.4 # drivers/sgi/char/graphics.c 1.9 -> (deleted) # arch/mips/ddb5xxx/ddb5477/pci_ops.c 1.2 -> (deleted) # arch/mips/math-emu/sp_simple.c 1.1 -> 1.2 # arch/mips/arc/tree.c 1.1 -> 1.2 # include/linux/sunrpc/svc.h 1.23 -> 1.24 # arch/mips/mm/r5432.c 1.5 -> (deleted) # arch/mips/lib/ide-std.c 1.3 -> 1.4 # arch/mips/dec/prom/init.c 1.2 -> 1.3 # arch/mips64/arc/salone.c 1.2 -> (deleted) # arch/ppc64/Kconfig 1.22 -> 1.23 # drivers/pnp/isapnp/core.c 1.38 -> 1.39 # drivers/pci/hotplug/pcihp_skeleton.c 1.3 -> 1.4 # drivers/s390/cio/device_pgid.c 1.4 -> 1.5 # arch/mips/dec/boot/Makefile 1.6 -> 1.7 # include/asm-mips/semaphore-helper.h 1.3 -> 1.4 # drivers/s390/cio/chsc.c 1.11 -> 1.12 # arch/mips64/lib/ide-std.c 1.3 -> 1.4 # arch/mips/sgi/kernel/setup.c 1.3 -> (deleted) # arch/mips/baget/balo_supp.S 1.1 -> 1.2 # include/asm-mips64/ipcbuf.h 1.1 -> 1.2 # drivers/s390/net/ctctty.c 1.18 -> 1.19 # drivers/s390/cio/ccwgroup.c 1.3 -> 1.4 # include/asm-mips/errno.h 1.3 -> 1.4 # include/asm-mips/mips-boards/atlasint.h 1.1 -> 1.2 # include/asm-mips64/shmiq.h 1.3 -> 1.4 # fs/nfsd/nfssvc.c 1.38 -> 1.39 # drivers/media/dvb/ttpci/budget.c 1.1 -> 1.3 # arch/i386/pci/Makefile 1.15 -> 1.16 # arch/mips/math-emu/Makefile 1.4 -> 1.5 # arch/mips/mips-boards/atlas/atlas_setup.c 1.2 -> 1.3 # drivers/s390/net/netiucv.c 1.20 -> 1.21 # arch/mips64/sgi-ip32/Makefile 1.7 -> 1.8 arch/mips/sgi-ip32/Makefile (moved) # arch/mips/dec/irq.c 1.7 -> (deleted) # arch/mips64/mips-boards/generic/memory.c 1.1 -> (deleted) # arch/mips/mm/extable.c 1.2 -> 1.3 # net/sunrpc/cache.c 1.15 -> 1.19 # net/xfrm/xfrm_user.c 1.26 -> 1.28 # fs/xfs/xfs_ialloc.c 1.7 -> 1.8 # arch/mips64/mm/fault.c 1.8 -> 1.9 # include/asm-mips64/msgbuf.h 1.1 -> 1.2 # drivers/pnp/resource.c 1.16 -> 1.17 # drivers/block/loop.c 1.98 -> 1.100 # fs/buffer.c 1.202 -> 1.203 # drivers/s390/block/dasd_ioctl.c 1.16 -> 1.17 # include/asm-mips/riscos-syscall.h 1.1 -> 1.2 # arch/arm26/Kconfig 1.2 -> 1.3 # fs/nfsd/export.c 1.81 -> 1.86 # drivers/ide/ide-probe.c 1.50 -> 1.52 # include/asm-arm26/processor.h 1.1 -> 1.2 # include/asm-mips/ds1286.h 1.2 -> 1.3 # arch/mips/dec/promcon.c 1.3 -> 1.4 # fs/ext3/namei.c 1.41 -> 1.42 # include/asm-mips/dec/ioasic.h 1.1 -> 1.2 # drivers/net/declance.c 1.15 -> 1.16 # include/asm-mips/ptrace.h 1.3 -> 1.4 # arch/mips64/defconfig-ip22 1.7 -> 1.8 # arch/mips/kernel/unaligned.c 1.3 -> 1.4 # arch/m68k/Kconfig 1.16 -> 1.17 # drivers/net/tulip/tulip_core.c 1.43 -> 1.44 # arch/mips64/sgi-ip22/ip22-rtc.c 1.2 -> (deleted) # arch/mips/math-emu/ieee754int.h 1.1 -> 1.2 # arch/mips64/lib/floppy-std.c 1.1 -> 1.2 # include/asm-mips/byteorder.h 1.1 -> 1.2 # net/ipv6/ndisc.c 1.44 -> 1.48 # arch/mips/lib/memcpy.S 1.2 -> 1.3 # arch/mips/math-emu/ieee754dp.h 1.1 -> 1.2 # MAINTAINERS 1.149 -> 1.150 # arch/parisc/Kconfig 1.16 -> 1.17 # net/sctp/protocol.c 1.53 -> 1.54 # net/sctp/ipv6.c 1.43 -> 1.44 # drivers/ieee1394/amdtp.c 1.13 -> 1.14 # arch/mips64/math-emu/ieee754sp.c 1.3 -> (deleted) # drivers/pcmcia/yenta_socket.c 1.28 -> 1.29 # drivers/media/dvb/ttpci/budget.h 1.1 -> 1.2 # drivers/ide/pci/sc1200.c 1.6 -> 1.7 # arch/mips/math-emu/sp_mul.c 1.2 -> 1.3 # drivers/sgi/char/usema.h 1.1 -> (deleted) # drivers/block/rd.c 1.75 -> 1.76 # drivers/ieee1394/nodemgr.c 1.29 -> 1.30 # drivers/media/common/saa7146_hlp.c 1.1 -> 1.3 # arch/mips64/math-emu/ieee754xcpt.c 1.1 -> (deleted) # net/atm/lec.c 1.28 -> 1.29 # include/net/irda/vlsi_ir.h 1.8 -> 1.9 # drivers/ide/ide-pnp.c 1.6 -> 1.7 # arch/mips64/sgi-ip27/TODO 1.1 -> 1.2 arch/mips/sgi-ip27/TODO (moved) # drivers/pci/hotplug/acpiphp_core.c 1.4 -> 1.6 # drivers/ieee1394/eth1394.c 1.16 -> 1.18 # mm/mmap.c 1.85 -> 1.86 # arch/mips64/kernel/linux32.c 1.13 -> 1.14 # arch/mips/mm/Makefile 1.7 -> 1.8 # arch/mips64/kernel/r4k_genex.S 1.2 -> 1.3 # drivers/sgi/char/sgicons.c 1.2 -> (deleted) # arch/mips/math-emu/dp_modf.c 1.1 -> 1.2 # drivers/scsi/gdth.c 1.29 -> 1.30 # include/asm-sparc64/compat.h 1.14 -> 1.15 # fs/xfs/linux/xfs_globals.c 1.14 -> 1.15 # drivers/ieee1394/dv1394-private.h 1.9 -> 1.10 # arch/mips64/math-emu/cp1emu.c 1.4 -> (deleted) # include/asm-mips/gt64120.h 1.1 -> 1.2 # fs/lockd/svc.c 1.21 -> 1.22 # net/sunrpc/svcauth_unix.c 1.16 -> 1.20 # include/asm-mips/posix_types.h 1.2 -> 1.3 # arch/i386/pci/acpi.c 1.9 -> 1.10 # drivers/net/pppoe.c 1.29 -> 1.32 # include/linux/mtd/blktrans.h 1.1 -> 1.2 # arch/mips/kernel/pci-dma.c 1.2 -> 1.3 # include/asm-mips/bugs.h 1.2 -> 1.3 # arch/mips/baget/vacserial.c 1.18 -> (deleted) # drivers/media/common/saa7146_video.c 1.2 -> 1.4 # arch/mips64/kernel/traps.c 1.6 -> 1.7 # arch/mips/mips-boards/generic/time.c 1.5 -> 1.6 # include/asm-mips/statfs.h 1.1 -> 1.2 # drivers/atm/atmtcp.c 1.9 -> 1.10 # net/atm/svc.c 1.14 -> 1.15 # drivers/net/eepro100.c 1.62 -> 1.63 # arch/mips/ddb5xxx/common/nile4.c 1.2 -> 1.3 # arch/mips/ddb5476/setup.c 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5476/setup.c (moved) # arch/mips64/mips-boards/generic/init.c 1.1 -> (deleted) # arch/mips64/sgi-ip32/ip32-berr.c 1.1 -> 1.2 arch/mips/sgi-ip32/ip32-berr.c (moved) # drivers/usb/host/ehci-hcd.c 1.52 -> 1.53 # drivers/media/dvb/dvb-core/dvb_ringbuffer.c 1.1 -> 1.3 # include/asm-mips64/compat.h 1.1 -> 1.2 # include/linux/smb_fs.h 1.13 -> 1.14 # net/sctp/sm_sideeffect.c 1.45 -> 1.46 # arch/m68knommu/kernel/time.c 1.4 -> 1.5 # drivers/s390/block/dasd_fba.c 1.13 -> 1.14 # drivers/media/dvb/ttpci/av7110.c 1.1 -> 1.3 # include/asm-mips/rmap.h 1.1 -> 1.2 # arch/mips/kernel/head.S 1.3 -> 1.4 # include/asm-mips64/branch.h 1.2 -> 1.3 # include/asm-mips64/mc146818rtc.h 1.2 -> 1.3 # arch/s390/kernel/compat_ioctl.c 1.3 -> 1.4 # drivers/sgi/char/streamable.c 1.4 -> (deleted) # fs/ext3/inode.c 1.75 -> 1.76 # include/asm-i386/io_apic.h 1.11 -> 1.13 # arch/ia64/kernel/head.S 1.12 -> 1.13 # arch/mips/baget/irq.c 1.8 -> 1.9 # include/asm-mips64/unaligned.h 1.2 -> 1.3 # arch/mips/lib/strncpy_user.S 1.1 -> 1.2 # include/asm-mips/reg.h 1.1 -> 1.2 # drivers/net/pcmcia/fmvj18x_cs.c 1.21 -> 1.22 # net/ipv4/netfilter/ip_nat_ftp.c 1.8 -> 1.10 # arch/mips/ddb5xxx/ddb5477/int-handler.S 1.1 -> 1.2 # arch/mips64/mm/init.c 1.9 -> 1.10 # arch/mips64/arc/misc.c 1.3 -> (deleted) # arch/mips64/sgi-ip32/ip32-rtc.c 1.1 -> 1.2 arch/mips/sgi-ip32/ip32-rtc.c (moved) # arch/mips/arc/memory.c 1.3 -> 1.4 # mm/page-writeback.c 1.71 -> 1.72 # drivers/net/pcmcia/smc91c92_cs.c 1.18 -> 1.19 # include/asm-x86_64/unistd.h 1.14 -> 1.15 # arch/mips/baget/wbflush.c 1.2 -> (deleted) # arch/mips64/sgi-ip22/ip22-setup.c 1.2 -> (deleted) # arch/mips/math-emu/dp_flong.c 1.1 -> 1.2 # include/asm-mips/sgi/sgi.h 1.1 -> 1.2 # arch/x86_64/kernel/time.c 1.18 -> 1.19 # net/ipv4/tcp_output.c 1.30 -> 1.31 # arch/mips/math-emu/ieee754dp.c 1.3 -> 1.4 # arch/mips64/math-emu/ieee754m.c 1.1 -> (deleted) # drivers/mtd/maps/lubbock-flash.c 1.1 -> 1.2 # fs/xfs/xfs_inode_item.c 1.8 -> 1.9 # arch/mips/kernel/irixioctl.c 1.3 -> 1.4 # arch/mips/mips-boards/atlas/atlas_int.c 1.5 -> 1.6 # arch/mips/defconfig-nino 1.3 -> (deleted) # arch/mips64/sgi-ip27/ip27-klconfig.c 1.2 -> 1.3 arch/mips/sgi-ip27/ip27-klconfig.c (moved) # include/asm-mips64/r4kcacheops.h 1.2 -> (deleted) # include/asm-mips/wbflush.h 1.2 -> 1.3 # drivers/s390/char/con3215.c 1.23 -> 1.24 # drivers/ide/legacy/ide-cs.c 1.10 -> 1.11 # include/net/sctp/tsnmap.h 1.7 -> 1.8 # include/asm-mips/ng1hw.h 1.2 -> 1.3 # arch/mips64/sgi-ip27/ip27-console.c 1.3 -> 1.4 arch/mips/sgi-ip27/ip27-console.c (moved) # include/asm-mips/scatterlist.h 1.3 -> 1.4 # arch/mips/dec/int-handler.S 1.2 -> 1.3 # include/asm-mips/dec/machtype.h 1.1 -> 1.2 # arch/m68knommu/Kconfig 1.15 -> 1.18 # drivers/net/wan/sdla_x25.c 1.24 -> 1.25 # include/asm-mips/pci.h 1.10 -> 1.11 # include/asm-mips64/statfs.h 1.2 -> 1.3 # drivers/pci/pci-driver.c 1.30 -> 1.31 # arch/mips64/kernel/syscall.c 1.7 -> 1.8 # arch/mips/au1000/common/prom.c 1.1 -> 1.2 # arch/mips/philips/nino/power.c 1.1 -> (deleted) # include/asm-mips/div64.h 1.3 -> 1.4 # include/asm-mips/sgialib.h 1.2 -> 1.3 # arch/mips/ddb5476/nile4.c 1.1 -> 1.2 arch/mips/ddb5xxx/ddb5476/nile4_pic.c (moved) # arch/mips/mips-boards/generic/display.c 1.1 -> 1.2 # drivers/pci/probe.c 1.44 -> 1.46 # drivers/pci/hotplug/Makefile 1.15 -> 1.16 # arch/mips/kernel/pci.c 1.7 -> (deleted) # arch/mips64/lib/memset.S 1.2 -> 1.3 # arch/mips/boot/addinitrd.c 1.1 -> 1.2 # arch/mips/lib/floppy-std.c 1.1 -> 1.2 # fs/nfsd/nfs4state.c 1.5 -> 1.10 # arch/mips/kernel/old-time.c 1.4 -> (deleted) # drivers/media/common/saa7146_core.c 1.2 -> 1.4 # drivers/media/dvb/frontends/nxt6000.c 1.1 -> 1.2 # arch/mips64/kernel/smp.c 1.8 -> 1.9 # arch/mips/math-emu/dp_sub.c 1.3 -> 1.4 # include/asm-mips/ucontext.h 1.1 -> 1.2 # drivers/usb/net/kaweth.c 1.45 -> 1.49 # include/asm-mips/bug.h 1.2 -> 1.3 # drivers/s390/block/dasd_int.h 1.17 -> 1.18 # arch/mips64/mips-boards/malta/malta_int.c 1.4 -> (deleted) # include/acpi/acpi_drivers.h 1.14 -> 1.15 # arch/mips64/math-emu/dp_fint.c 1.1 -> (deleted) # arch/mips/baget/baget.c 1.1 -> 1.2 # include/asm-x86_64/pgtable.h 1.21 -> 1.22 # net/xfrm/xfrm_state.c 1.29 -> 1.30 # include/linux/security.h 1.23 -> 1.24 # arch/mips64/sgi-ip27/ip27-pci-dma.c 1.3 -> (deleted) # arch/mips/mm/loadmmu.c 1.4 -> 1.5 # arch/mips/ddb5xxx/ddb5477/kgdb_io.c 1.1 -> 1.2 # include/asm-mips/mips-boards/generic.h 1.1 -> 1.2 # drivers/ieee1394/dv1394.c 1.32 -> 1.33 # fs/xfs/xfs_inode.h 1.15 -> 1.17 # include/asm-mips/ide.h 1.10 -> 1.11 # arch/mips/baget/balo.c 1.1 -> 1.2 # include/asm-mips/dec/kn02.h 1.2 -> 1.3 # include/asm-mips64/r4kcache.h 1.2 -> 1.3 # arch/mips64/math-emu/sp_logb.c 1.1 -> (deleted) # arch/mips64/math-emu/sp_tlong.c 1.1 -> (deleted) # net/atm/common.h 1.8 -> 1.9 # drivers/ieee1394/ieee1394_types.h 1.17 -> 1.18 # arch/mips/ddb5476/Makefile 1.5 -> 1.6 arch/mips/ddb5xxx/ddb5476/Makefile (moved) # arch/mips/ddb5xxx/common/irq.c 1.1 -> 1.2 # drivers/mtd/mtdpart.c 1.5 -> 1.6 # arch/mips64/kernel/scall_o32.S 1.8 -> 1.9 # include/asm-mips64/signal.h 1.4 -> 1.5 # include/asm-s390/queue.h 1.4 -> (deleted) # drivers/s390/block/xpram.c 1.41 -> 1.42 # drivers/s390/cio/device.c 1.6 -> 1.7 # drivers/s390/cio/device_ops.c 1.4 -> 1.5 # drivers/net/irda/Kconfig 1.4 -> 1.5 # arch/mips64/sgi-ip27/ip27-pci.c 1.8 -> (deleted) # drivers/ieee1394/dv1394.h 1.3 -> 1.4 # net/ipv6/route.c 1.45 -> 1.47 # net/ipv4/tcp_input.c 1.39 -> 1.41 # include/linux/nfs.h 1.4 -> 1.5 # drivers/ieee1394/cmp.c 1.6 -> 1.7 # arch/mips64/defconfig 1.9 -> 1.10 # arch/mips/ddb5476/time.c 1.1 -> (deleted) # arch/mips/sgi/kernel/system.c 1.1 -> (deleted) # drivers/media/dvb/dvb-core/dvb_i2c.c 1.4 -> 1.6 # include/asm-mips64/ioctls.h 1.5 -> 1.6 # arch/mips/philips/nino/kgdb.c 1.1 -> (deleted) # net/ipv4/tcp_minisocks.c 1.40 -> 1.41 # drivers/media/dvb/dvb-core/dmxdev.c 1.3 -> 1.5 # net/sunrpc/svcauth.c 1.11 -> 1.12 # arch/mips64/sgi-ip22/ip22-reset.c 1.2 -> (deleted) # arch/mips/ddb5074/setup.c 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5074/setup.c (moved) # arch/mips/mips-boards/generic/printf.c 1.1 -> 1.2 # drivers/sgi/char/shmiq.c 1.10 -> (deleted) # fs/xfs/xfs_iocore.c 1.6 -> 1.7 # drivers/serial/8250_pci.c 1.22 -> 1.23 # arch/mips/ddb5074/int-handler.S 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5074/int-handler.S (moved) # arch/alpha/Kconfig 1.19 -> 1.21 # drivers/net/gt96100eth.c 1.9 -> 1.10 # arch/mips/kernel/signal.c 1.11 -> 1.12 # arch/mips64/lib/dump_tlb.c 1.3 -> 1.4 # arch/mips/kernel/scall_o32.S 1.4 -> 1.5 # arch/mips64/mips-boards/generic/gdb_hook.c 1.1 -> (deleted) # include/asm-mips/mips32_cache.h 1.1 -> (deleted) # net/atm/signaling.c 1.12 -> 1.13 # drivers/usb/storage/unusual_devs.h 1.42 -> 1.44 # net/ipv4/netfilter/ip_conntrack_irc.c 1.10 -> 1.12 # arch/mips/boot/Makefile 1.7 -> 1.8 # arch/mips64/math-emu/dp_flong.c 1.1 -> (deleted) # arch/mips/baget/bagetIRQ.S 1.1 -> 1.2 # arch/mips/dec/prom/prom.h 1.1 -> (deleted) # net/ipv4/netfilter/arp_tables.c 1.8 -> 1.9 # net/ipv4/netfilter/ip_conntrack_ftp.c 1.13 -> 1.15 # include/net/ndisc.h 1.4 -> 1.5 # arch/mips/mips-boards/generic/cmdline.c 1.2 -> 1.3 # fs/xfs/xfsidbg.c 1.27 -> 1.28 # drivers/media/dvb/ttpci/budget-av.c 1.1 -> 1.3 # arch/mips/au1000/pb1000/Makefile 1.5 -> 1.6 # arch/mips64/kernel/ptrace.c 1.7 -> 1.8 # arch/mips/kernel/syscall.c 1.4 -> 1.5 # arch/x86_64/Kconfig 1.24 -> 1.25 # include/linux/rtnetlink.h 1.17 -> 1.18 # drivers/s390/cio/device.h 1.3 -> 1.4 # arch/mips/dec/prom/cmdline.c 1.2 -> 1.3 # kernel/sched.c 1.195 -> 1.197 # fs/jffs2/dir.c 1.26 -> 1.27 # arch/s390/kernel/compat_linux.c 1.2 -> 1.3 # arch/mips/kernel/r2300_misc.S 1.2 -> (deleted) # arch/mips/dec/reset.c 1.2 -> 1.3 # drivers/sgi/char/newport.c 1.2 -> (deleted) # include/asm-mips64/sembuf.h 1.1 -> 1.2 # net/atm/resources.h 1.6 -> 1.7 # drivers/Makefile 1.35 -> 1.36 # arch/mips/math-emu/sp_div.c 1.2 -> 1.3 # arch/mips64/lib/csum_partial_copy.c 1.4 -> 1.5 # include/asm-mips/fcntl.h 1.2 -> 1.3 # include/asm-mips/shmparam.h 1.1 -> 1.2 # arch/mips/math-emu/sp_add.c 1.2 -> 1.3 # arch/mips64/math-emu/ieee754sp.h 1.1 -> (deleted) # arch/mips/math-emu/dp_simple.c 1.1 -> 1.2 # drivers/acpi/osl.c 1.38 -> 1.40 # arch/mips/mips-boards/generic/Makefile 1.5 -> 1.6 # arch/mips/dec/wbflush.c 1.3 -> 1.4 # arch/mips/philips/nino/reset.c 1.1 -> (deleted) # arch/mips64/arc/tree.c 1.3 -> (deleted) # include/asm-mips/asmmacro.h 1.2 -> 1.3 # arch/ia64/kernel/gate.S 1.17 -> 1.18 # include/net/ipv6.h 1.19 -> 1.20 # drivers/ieee1394/iso.c 1.6 -> 1.7 # net/ipv4/netfilter/ip_nat_snmp_basic.c 1.8 -> 1.9 # arch/mips/dec/time.c 1.5 -> 1.6 # arch/m68knommu/platform/5272/NETtel/crt0_ram.S 1.1 -> 1.2 # include/asm-mips64/unistd.h 1.5 -> 1.6 # include/asm-mips64/rmap.h 1.1 -> 1.2 # net/atm/mpc.c 1.19 -> 1.20 # drivers/ide/ide-io.c 1.12 -> 1.13 # drivers/media/dvb/frontends/grundig_29504-491.c 1.3 -> 1.5 # net/sctp/hashdriver.c 1.4 -> (deleted) # arch/mips64/sgi-ip32/ip32-timer.c 1.1 -> 1.2 arch/mips/sgi-ip32/ip32-timer.c (moved) # include/linux/atmdev.h 1.17 -> 1.18 # drivers/pci/hotplug/pci_hotplug_core.c 1.39 -> 1.40 # drivers/mtd/ftl.c 1.47 -> 1.48 # arch/ia64/sn/io/drivers/Makefile 1.3 -> 1.4 # net/ipv4/netfilter/Kconfig 1.6 -> 1.9 # arch/mips/au1000/common/puts.c 1.1 -> 1.2 # arch/mips64/mips-boards/generic/printf.c 1.1 -> (deleted) # include/asm-mips64/tlb.h 1.1 -> 1.2 # kernel/timer.c 1.60 -> 1.61 # fs/nfsd/nfs4xdr.c 1.18 -> 1.20 # include/net/xfrm.h 1.44 -> 1.45 # drivers/mtd/maps/ebony.c 1.1 -> 1.2 # arch/mips64/math-emu/ieee754dp.c 1.3 -> (deleted) # include/asm-mips64/mipsregs.h 1.5 -> 1.6 # arch/mips64/arc/init.c 1.2 -> (deleted) # include/asm-mips64/pgalloc.h 1.6 -> 1.7 # drivers/net/Makefile.lib 1.6 -> 1.7 # drivers/cdrom/Kconfig 1.2 -> 1.3 # arch/mips/ddb5xxx/common/rtc_ds1386.c 1.2 -> 1.3 # arch/mips64/mips-boards/atlas/Makefile 1.5 -> (deleted) # arch/mips/ddb5476/irq.c 1.1 -> 1.2 arch/mips/ddb5xxx/ddb5476/irq.c (moved) # net/sctp/bind_addr.c 1.17 -> 1.19 # drivers/s390/block/dasd_3990_erp.c 1.13 -> 1.14 # arch/mips/kernel/r2300_switch.S 1.6 -> 1.7 # include/asm-mips64/siginfo.h 1.6 -> 1.7 # arch/mips64/lib/kbd-no.c 1.2 -> (deleted) # arch/mips/math-emu/dp_cmp.c 1.1 -> 1.2 # arch/mips/lib/strnlen_user.S 1.1 -> 1.2 # include/asm-mips/dec/ioasic_ints.h 1.1 -> 1.2 # include/asm-ia64/timex.h 1.7 -> 1.8 # arch/mips64/lib/Makefile 1.6 -> 1.7 # arch/mips/kernel/irixsig.c 1.7 -> 1.8 # drivers/ieee1394/dma.h 1.2 -> 1.3 # arch/mips64/ld.script.elf64 1.5 -> (deleted) # arch/mips64/lib/kbd-std.c 1.2 -> (deleted) # arch/mips64/math-emu/kernel_linkage.c 1.1 -> (deleted) # include/asm-mips/bcache.h 1.2 -> 1.3 # arch/mips/math-emu/sp_flong.c 1.1 -> 1.2 # arch/mips/sgi/kernel/indy_mc.c 1.1 -> (deleted) # drivers/ieee1394/ohci1394.c 1.39 -> 1.40 # arch/s390/defconfig 1.22 -> 1.23 # drivers/media/dvb/frontends/at76c651.c 1.1 -> 1.3 # include/asm-mips64/r10kcache.h 1.3 -> (deleted) # arch/mips/sgi/kernel/indy_sc.c 1.4 -> (deleted) # drivers/net/Kconfig 1.29 -> 1.34 # drivers/pci/hotplug/ibmphp_res.c 1.7 -> 1.8 # drivers/i2c/busses/Kconfig 1.11 -> 1.12 # arch/mips/au1000/pb1000/setup.c 1.2 -> 1.3 # arch/mips/ddb5xxx/common/prom.c 1.1 -> 1.2 # net/ipv6/mcast.c 1.25 -> 1.26 # include/asm-s390/ccwdev.h 1.4 -> 1.5 # include/asm-mips64/bitops.h 1.4 -> 1.5 # arch/mips/mm/init.c 1.8 -> 1.9 # include/asm-mips/ioctls.h 1.4 -> 1.5 # arch/mips64/math-emu/dp_tlong.c 1.1 -> (deleted) # arch/sparc64/Kconfig 1.24 -> 1.25 # arch/mips/ddb5xxx/ddb5477/setup.c 1.2 -> 1.3 # include/asm-mips64/timex.h 1.2 -> 1.3 # include/asm-mips64/rrm.h 1.1 -> (deleted) # arch/mips/math-emu/dp_sqrt.c 1.1 -> 1.2 # kernel/exit.c 1.103 -> 1.104 # arch/ia64/kernel/irq.c 1.25 -> 1.26 # arch/mips64/sgi-ip32/ip32-setup.c 1.1 -> 1.2 arch/mips/sgi-ip32/ip32-setup.c (moved) # fs/jbd/commit.c 1.35 -> 1.36 # include/asm-x86_64/proto.h 1.12 -> 1.13 # arch/ppc/kernel/entry.S 1.29 -> 1.31 # drivers/ieee1394/iso.h 1.3 -> 1.4 # drivers/net/ixgb/ixgb_ethtool.c 1.4 -> 1.5 # drivers/mtd/chips/gen_probe.c 1.2 -> 1.3 # net/ipv6/netfilter/ip6_tables.c 1.18 -> 1.20 # fs/xfs/xfs_dir_leaf.c 1.8 -> 1.9 # include/linux/dvb/dmx.h 1.2 -> 1.3 # arch/mips/mm/umap.c 1.5 -> (deleted) # include/asm-mips64/serial.h 1.2 -> 1.3 # arch/mips/lib/floppy-no.c 1.1 -> 1.2 # arch/mips64/math-emu/dp_simple.c 1.1 -> (deleted) # arch/x86_64/kernel/module.c 1.9 -> 1.10 # arch/mips/math-emu/ieee754d.c 1.1 -> 1.2 # drivers/scsi/Kconfig 1.23 -> 1.24 # arch/mips64/arc/arc_con.c 1.1 -> (deleted) # arch/mips64/arc/console.c 1.2 -> (deleted) # drivers/pci/Makefile 1.30 -> 1.33 # arch/mips64/boot/Makefile 1.7 -> 1.8 # arch/mips/math-emu/cp1emu.c 1.4 -> 1.5 # include/asm-mips/hw_irq.h 1.2 -> 1.3 # include/asm-mips/unaligned.h 1.2 -> 1.3 # include/asm-mips/timex.h 1.1 -> 1.2 # include/asm-mips64/ipc.h 1.1 -> 1.2 # arch/cris/Kconfig 1.10 -> 1.12 # drivers/mtd/maps/iq80310.c 1.5 -> 1.6 # net/ax25/sysctl_net_ax25.c 1.6 -> 1.7 # arch/mips64/kernel/r4k_tlb_debug.c 1.2 -> (deleted) # fs/xfs/linux/xfs_super.c 1.46.1.1 -> 1.48 # include/asm-ia64/pci.h 1.19 -> 1.20 # drivers/pci/hotplug.c 1.17 -> 1.18 # drivers/serial/Kconfig 1.10 -> 1.12 # drivers/mtd/afs.c 1.3 -> 1.4 # drivers/net/sgiseeq.c 1.14 -> 1.15 # drivers/net/sb1250-mac.c 1.4 -> 1.5 # arch/mips/kernel/sysirix.c 1.10 -> 1.11 # include/asm-mips64/stat.h 1.3 -> 1.4 # include/asm-mips64/ptrace.h 1.2 -> 1.3 # arch/mips64/math-emu/sp_scalb.c 1.1 -> (deleted) # net/sunrpc/svc.c 1.21 -> 1.22 # mm/rmap.c 1.28 -> 1.29 # arch/mips/mips-boards/atlas/Makefile 1.5 -> 1.6 # arch/mips64/sgi-ip22/ip22-sc.c 1.4 -> (deleted) # include/asm-mips64/delay.h 1.3 -> 1.4 # arch/mips/ddb5476/prom.c 1.1 -> (deleted) # fs/jffs2/scan.c 1.10 -> 1.11 # arch/mips/dec/prom/identify.c 1.1 -> 1.2 # include/asm-mips/poll.h 1.1 -> 1.2 # arch/ia64/kernel/perfmon.c 1.50 -> 1.52 # drivers/pci/hotplug/cpqphp_pci.c 1.21 -> 1.22 # include/asm-mips64/sgi/sgint23.h 1.3 -> (deleted) # arch/mips64/math-emu/ieee754.h 1.1 -> (deleted) # net/ipv4/icmp.c 1.32 -> 1.34 # drivers/net/ppp_generic.c 1.33 -> 1.34 # arch/mips/ddb5xxx/common/Makefile 1.4 -> 1.5 # arch/mips64/sgi-ip27/Makefile 1.7 -> 1.8 arch/mips/sgi-ip27/Makefile (moved) # include/asm-mips64/sn/sn0/hubmd.h 1.2 -> 1.3 # arch/mips/lib/csum_partial.S 1.1 -> 1.2 # include/linux/netdevice.h 1.43 -> 1.44 # net/atm/resources.c 1.12 -> 1.13 # arch/mips64/math-emu/sp_fdp.c 1.2 -> (deleted) # include/asm-mips64/sn/launch.h 1.3 -> 1.4 # arch/mips64/sgi-ip22/ip22-mc.c 1.2 -> (deleted) # arch/mips/math-emu/sp_modf.c 1.1 -> 1.2 # include/asm-mips/ng1.h 1.1 -> 1.2 # arch/ia64/Kconfig 1.32 -> 1.35 # fs/compat_ioctl.c 1.2 -> 1.3 # drivers/net/pcmcia/3c589_cs.c 1.17 -> 1.18 # arch/mips/kernel/r4k_switch.S 1.5 -> 1.6 # arch/mips/mm/mips32.c 1.5 -> (deleted) # arch/mips/lib/strlen_user.S 1.1 -> 1.2 # arch/ia64/lib/Makefile 1.20 -> 1.21 # drivers/media/dvb/dvb-core/dvb_frontend.h 1.3 -> 1.5 # arch/mips/au1000/common/dbg_io.c 1.1 -> 1.2 # include/asm-mips/delay.h 1.2 -> 1.3 # include/asm-mips64/riscos-syscall.h 1.1 -> 1.2 # arch/mips64/sgi-ip27/ip27-init.c 1.6 -> 1.7 arch/mips/sgi-ip27/ip27-init.c (moved) # arch/mips64/kernel/proc.c 1.3 -> 1.4 # arch/mips/arc/cmdline.c 1.3 -> 1.4 # drivers/pnp/manager.c 1.7 -> 1.9 # drivers/net/sungem.c 1.38 -> 1.39 # arch/mips64/defconfig-ip32 1.3 -> 1.4 # include/asm-mips/tx3912.h 1.2 -> 1.3 # arch/ia64/scripts/toolchain-flags 1.1 -> 1.2 # drivers/media/common/saa7146_i2c.c 1.1 -> 1.3 # arch/mips/au1000/common/Makefile 1.8 -> 1.9 # arch/sparc64/mm/fault.c 1.15 -> 1.16 # include/asm-mips/spinlock.h 1.3 -> 1.4 # include/asm-mips64/mips-boards/atlasint.h 1.1 -> 1.2 # arch/mips/kernel/pci_auto.c 1.1 -> (deleted) # arch/mips64/mips-boards/generic/reset.c 1.1 -> (deleted) # arch/mips/ddb5074/irq.c 1.2 -> 1.3 arch/mips/ddb5xxx/ddb5074/irq.c (moved) # include/asm-mips/ipcbuf.h 1.1 -> 1.2 # fs/xfs/xfs_inode.c 1.23 -> 1.28 # fs/xfs/xfs_iget.c 1.15 -> 1.16 # arch/mips/defconfig-ddb5476 1.9 -> 1.10 # include/asm-mips64/spinlock.h 1.2 -> 1.3 # net/sctp/tsnmap.c 1.9 -> 1.11 # include/asm-mips64/bcache.h 1.2 -> 1.3 # include/linux/nfsd/nfsd.h 1.21 -> 1.22 # net/atm/clip.c 1.16 -> 1.17 # include/asm-mips64/bug.h 1.2 -> 1.3 # drivers/mtd/maps/Kconfig 1.6 -> 1.7 # arch/mips/boot/elf2ecoff.c 1.2 -> 1.3 # include/asm-mips/ipc.h 1.1 -> 1.2 # include/asm-x86_64/processor.h 1.17 -> 1.18 # include/asm-mips64/paccess.h 1.2 -> 1.3 # net/sctp/sm_statetable.c 1.17 -> 1.18 # drivers/media/dvb/dvb-core/dvb_ksyms.c 1.3 -> 1.5 # arch/mips64/mips-boards/atlas/atlas_int.c 1.4 -> (deleted) # include/asm-mips64/cache.h 1.3 -> 1.4 # arch/mips64/mips-boards/generic/display.c 1.1 -> (deleted) # arch/ppc/Kconfig 1.26 -> 1.28 # net/ipv4/igmp.c 1.26 -> 1.28 # include/linux/pnp.h 1.21 -> 1.22 # include/asm-s390/statfs.h 1.2 -> 1.3 # include/asm-mips64/pgtable.h 1.13 -> 1.14 # arch/sparc64/kernel/traps.c 1.25 -> 1.26 # include/asm-mips/topology.h 1.1 -> 1.2 # arch/mips64/math-emu/sp_frexp.c 1.1 -> (deleted) # kernel/workqueue.c 1.8 -> 1.9 # arch/mips64/arc/Makefile 1.6 -> (deleted) # drivers/net/wan/sdla_fr.c 1.27 -> 1.28 # arch/mips/kernel/gdb-stub.c 1.5 -> 1.6 # drivers/ieee1394/Makefile 1.18 -> 1.19 # arch/mips/ddb5xxx/common/pci.c 1.6 -> (deleted) # include/asm-mips64/types.h 1.3 -> 1.4 # include/asm-mips/sgi/sgimc.h 1.2 -> (deleted) # arch/sh/Kconfig 1.14 -> 1.16 # drivers/serial/sunzilog.c 1.31 -> 1.32 # arch/ia64/kernel/init_task.c 1.9 -> 1.10 # include/asm-mips/stat.h 1.3 -> 1.4 # include/asm-mips64/errno.h 1.4 -> 1.5 # drivers/media/dvb/dvb-core/Makefile 1.4 -> 1.5 # arch/mips/defconfig-ip22 1.5 -> 1.6 # arch/mips/arc/salone.c 1.1 -> 1.2 # drivers/atm/fore200e.c 1.17 -> 1.18 # include/net/sctp/structs.h 1.66 -> 1.68 # drivers/mtd/maps/pb1xxx-flash.c 1.1 -> 1.2 # arch/i386/kernel/i386_ksyms.c 1.52 -> 1.53 # include/asm-mips64/module.h 1.2 -> 1.3 # arch/mips/math-emu/sp_tint.c 1.1 -> 1.2 # drivers/ide/ide-tcq.c 1.5 -> 1.6 # arch/mips/arc/arc_con.c 1.2 -> 1.3 # arch/mips64/mips-boards/malta/malta_rtc.c 1.1 -> (deleted) # fs/nfsd/nfs4proc.c 1.13 -> 1.20 # include/asm-mips/watch.h 1.2 -> 1.3 # arch/mips/math-emu/sp_tlong.c 1.1 -> 1.2 # arch/mips64/sgi-ip32/ip32-pci.c 1.7 -> (deleted) # include/asm-s390/hardirq.h 1.9 -> 1.10 # net/ipv4/netfilter/ip_nat_irc.c 1.5 -> 1.6 # drivers/media/dvb/dvb-core/dvb_ringbuffer.h 1.1 -> 1.2 # include/asm-mips64/watch.h 1.2 -> 1.3 # arch/i386/kernel/apic.c 1.42 -> 1.43 # include/linux/loop.h 1.13 -> 1.15 # arch/ia64/sn/kernel/idle.c 1.1 -> 1.2 # drivers/media/dvb/frontends/stv0299.c 1.1 -> 1.3 # arch/mips64/kernel/r4k_tlb.S 1.2 -> (deleted) # include/asm-ia64/thread_info.h 1.9 -> 1.10 # fs/xfs/xfs_log.c 1.16 -> 1.19 # drivers/media/dvb/dvb-core/dmxdev.h 1.3 -> 1.5 # arch/mips64/math-emu/dp_add.c 1.2 -> (deleted) # arch/mips64/math-emu/sp_div.c 1.2 -> (deleted) # arch/mips/kernel/ptrace.c 1.9 -> 1.10 # include/asm-sparc/bug.h 1.3 -> 1.4 # arch/mips/philips/nino/rtc.c 1.1 -> (deleted) # include/asm-mips64/m48t35.h 1.2 -> 1.3 # arch/mips/lib/csum_partial_copy.c 1.3 -> 1.4 # include/asm-mips/serial.h 1.2 -> 1.3 # drivers/pci/hotplug/ibmphp_core.c 1.32 -> 1.33 # drivers/mtd/maps/edb7312.c 1.3 -> 1.4 # fs/xfs/xfs_vnodeops.c 1.28 -> 1.30 # drivers/media/dvb/dvb-core/dvb_filter.c 1.3 -> 1.5 # arch/mips/mips-boards/malta/malta_setup.c 1.2 -> 1.3 # arch/mips64/math-emu/ieee754dp.h 1.1 -> (deleted) # include/asm-mips/mc146818rtc.h 1.2 -> 1.3 # drivers/char/ip2main.c 1.38 -> 1.39 # arch/mips/defconfig-decstation 1.5 -> 1.6 # arch/mips64/sgi-ip22/ip22-hpc.c 1.2 -> (deleted) # arch/mips/lib/memset.S 1.2 -> 1.3 # include/asm-mips/sigcontext.h 1.1 -> 1.2 # drivers/mtd/nand/nand.c 1.3 -> 1.4 # arch/mips64/math-emu/dp_mul.c 1.2 -> (deleted) # arch/mips/baget/Makefile 1.7 -> 1.8 # net/sctp/socket.c 1.74.1.5 -> 1.83 # net/atm/common.c 1.31 -> 1.32 # arch/mips/kernel/irixelf.c 1.5 -> 1.6 # fs/xfs/linux/xfs_sysctl.c 1.10 -> 1.11 # drivers/s390/cio/css.h 1.2 -> 1.3 # (new) -> 1.1 arch/mips/lasat/ds1603.c # (new) -> 1.1 include/asm-mips/dec/kn05.h # (new) -> 1.1 arch/mips64/kernel/i8259.c # (new) -> 1.1 include/asm-mips64/thread_info.h # (new) -> 1.1 include/asm-mips64/traps.h # (new) -> 1.1 arch/mips/mm/cex-sb1.S # (new) -> 1.1 include/asm-mips/thread_info.h # (new) -> 1.1 include/asm-mips/mips-boards/bonito64.h # (new) -> 1.1 include/asm-mips64/kmap_types.h # (new) -> 1.1 include/asm-mips64/sibyte/trace_prof.h # (new) -> 1.1 arch/mips/pci/pci-auto.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/int-handler.S # (new) -> 1.1 arch/mips/galileo-boards/ev96100/Makefile # (new) -> 1.1 arch/mips/pci/ops-ddb5074.c # (new) -> 1.1 arch/mips/mm/sc-rm7k.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_mc.h # (new) -> 1.1 include/asm-mips/lasat/head.h # (new) -> 1.1 include/asm-mips64/dec/kn02ca.h # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_syncser.h # (new) -> 1.1 include/asm-mips64/pgtable-bits.h # (new) -> 1.1 include/asm-mips/ddb5xxx/ddb5074.h # (new) -> 1.1 arch/mips/cobalt/reset.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_int.h # (new) -> 1.1 arch/mips/pci/Makefile # (new) -> 1.1 arch/mips64/mm/sc-ip22.c # (new) -> 1.1 arch/mips/lasat/setup.c # (new) -> 1.1 include/asm-mips/lasat/lasatint.h # (new) -> 1.1 arch/mips/defconfig-jmr3927 # (new) -> 1.1 arch/mips/vr41xx/common/icu.c # (new) -> 1.1 include/asm-mips64/cacheflush.h # (new) -> 1.1 include/linux/dvb/version.h # (new) -> 1.1 arch/mips/kernel/module.c # (new) -> 1.1 arch/mips/cobalt/setup.c # (new) -> 1.3 arch/mips/Kconfig-shared # (new) -> 1.1 include/asm-mips/sibyte/sb1250_smbus.h # (new) -> 1.1 include/asm-mips64/sibyte/io.h # (new) -> 1.1 arch/mips/pci/pci-sni.c # (new) -> 1.2 drivers/media/dvb/frontends/cx24110.c # (new) -> 1.1 include/asm-mips/dec/rtc-dec.h # (new) -> 1.1 include/asm-mips/mips-boards/seadint.h # (new) -> 1.1 include/asm-mips/au1000_gpio.h # (new) -> 1.1 arch/mips/cobalt/via.c # (new) -> 1.1 include/asm-mips/vr41xx/tb0226.h # (new) -> 1.1 arch/mips/au1000/common/usbdev.c # (new) -> 1.1 arch/mips/au1000/pb1500/Makefile # (new) -> 1.1 include/asm-mips/sibyte/sb1250_dma.h # (new) -> 1.1 include/asm-mips/lasat/ds1603.h # (new) -> 1.1 arch/mips/pci/pci-mips.c # (new) -> 1.1 arch/mips64/mm/cache.c # (new) -> 1.1 include/linux/netfilter_arp/arpt_mangle.h # (new) -> 1.1 arch/mips/lasat/picvue_proc.c # (new) -> 1.1 arch/mips/mips-boards/sead/sead_setup.c # (new) -> 1.1 arch/mips/defconfig-cobalt # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/int-handler.S # (new) -> 1.1 arch/mips/galileo-boards/ev64120/setup.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-hpc.c # (new) -> 1.1 arch/mips/ddb5xxx/ddb5477/lcd44780.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/pci-irq.c # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0226/Makefile # (new) -> 1.1 arch/mips64/defconfig-sb1250-swarm # (new) -> 1.1 arch/mips/sgi-ip22/ip22-setup.c # (new) -> 1.1 arch/mips/galileo-boards/ev64120/README # (new) -> 1.1 include/asm-mips64/fpu_emulator.h # (new) -> 1.1 include/asm-mips64/mips-boards/bonito64.h # (new) -> 1.1 arch/mips/pci/ops-ddb5477.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_mac.h # (new) -> 1.1 arch/mips/vr41xx/ibm-workpad/setup.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_regs.h # (new) -> 1.1 include/asm-mips/sibyte/board.h # (new) -> 1.1 arch/mips/vr41xx/nec-eagle/ide-eagle.c # (new) -> 1.1 include/asm-mips/vr41xx/mpc30x.h # (new) -> 1.1 arch/mips/galileo-boards/ev64120/serialGT.c # (new) -> 1.1 arch/mips/vr41xx/common/giu.c # (new) -> 1.1 arch/mips/math-emu/dsemul.c # (new) -> 1.1 arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c # (new) -> 1.1 arch/mips/sibyte/cfe/cfe_error.h # (new) -> 1.1 arch/mips/pci/fixup-ivr.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/ocelot_pld.h # (new) -> 1.1 include/asm-mips/cobalt/cobalt.h # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0229/reboot.c # (new) -> 1.1 include/asm-mips/sibyte/swarm.h # (new) -> 1.1 arch/mips/pci/fixup-au1000.c # (new) -> 1.1 arch/mips/au1000/db1x00/init.c # (new) -> 1.1 include/asm-mips/pgtable-bits.h # (new) -> 1.1 arch/mips/lasat/image/Makefile # (new) -> 1.1 arch/mips/galileo-boards/ev96100/init.c # (new) -> 1.1 include/asm-mips/sgi/mc.h # (new) -> 1.2 net/ipv4/netfilter/ipt_recent.c # (new) -> 1.1 arch/mips/pci/pci-ddb5074.c # (new) -> 1.1 arch/mips/lasat/picvue.h # (new) -> 1.1 include/asm-mips/vr41xx/workpad.h # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/init.c # (new) -> 1.1 arch/mips/dec/ecc-berr.c # (new) -> 1.1 arch/mips/sibyte/cfe/cfe_api.h # (new) -> 1.1 include/asm-mips64/sgi/ioc.h # (new) -> 1.1 arch/mips/momentum/ocelot_g/gt-irq.c # (new) -> 1.1 arch/mips/vr41xx/casio-e55/init.c # (new) -> 1.1 arch/mips/tx4927/common/tx4927_irq_handler.S # (new) -> 1.1 arch/mips/pci/ops-ddb5476.c # (new) -> 1.1 include/asm-mips64/dec/kn02xa.h # (new) -> 1.1 arch/mips64/defconfig-malta # (new) -> 1.1 arch/mips/galileo-boards/ev64120/Makefile # (new) -> 1.1 arch/mips/momentum/ocelot_c/int-handler.S # (new) -> 1.1 arch/mips/vr41xx/nec-eagle/setup.c # (new) -> 1.1 include/asm-mips64/dec/io.h # (new) -> 1.1 arch/mips64/kernel/pci-dma.c # (new) -> 1.1 include/asm-mips/i8259.h # (new) -> 1.1 arch/mips/lasat/image/romscript.normal # (new) -> 1.1 arch/mips/defconfig-pb1100 # (new) -> 1.1 include/asm-mips/vr41xx/e55.h # (new) -> 1.1 include/net/irda/au1000_ircc.h # (new) -> 1.1 arch/mips/sgi-ip22/Makefile # (new) -> 1.1 arch/mips/pci/pci-sb1250.c # (new) -> 1.1 arch/mips/sibyte/cfe/cfe_api_int.h # (new) -> 1.1 include/asm-mips/galileo-boards/ev96100.h # (new) -> 1.1 include/asm-mips64/irq_cpu.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/setup.c # (new) -> 1.1 arch/mips/jmr3927/common/puts.c # (new) -> 1.1 include/asm-mips64/dec/tcinfo.h # (new) -> 1.1 arch/mips/sibyte/sb1250/setup.c # (new) -> 1.1 arch/mips/pci/ops-ev64120.c # (new) -> 1.1 arch/mips/pci/pci-ddb5476.c # (new) -> 1.1 include/asm-mips64/sgi/gio.h # (new) -> 1.1 include/asm-mips64/dec/kn02ba.h # (new) -> 1.1 arch/mips/sgi-ip22/ip22-time.c # (new) -> 1.1 arch/mips64/mm/cerr-sb1.c # (new) -> 1.1 include/asm-mips64/break.h # (new) -> 1.1 include/asm-mips64/dec/ecc.h # (new) -> 1.1 arch/mips/tx4927/common/Makefile # (new) -> 1.1 include/asm-mips64/sgi/ip22.h # (new) -> 1.1 arch/mips64/mm/tlb-andes.c # (new) -> 1.1 include/asm-mips64/tlbflush.h # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0226/init.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/prom.c # (new) -> 1.1 arch/mips/sibyte/swarm/rtc_m41t81.c # (new) -> 1.1 arch/mips/defconfig-ev64120 # (new) -> 1.1 arch/mips/galileo-boards/ev64120/irq.c # (new) -> 1.1 include/asm-mips/rtc.h # (new) -> 1.1 include/asm-mips64/ip32/io.h # (new) -> 1.1 include/asm-mips64/dec/kn01.h # (new) -> 1.1 include/asm-mips/tx4927/tx4927_mips.h # (new) -> 1.1 include/asm-mips64/fpu.h # (new) -> 1.1 arch/mips64/mm/c-r4k.c # (new) -> 1.1 arch/i386/kernel/cpu/cpufreq/speedstep-lib.h # (new) -> 1.1 arch/mips/pci/fixup-eagle.c # (new) -> 1.1 include/asm-mips/db1x00.h # (new) -> 1.1 arch/mips/momentum/ocelot_g/Makefile # (new) -> 1.1 include/asm-mips64/sibyte/carmel.h # (new) -> 1.1 arch/mips/defconfig-eagle # (new) -> 1.1 include/asm-mips/vr41xx/vr41xx.h # (new) -> 1.1 arch/mips/sibyte/cfe/setup.c # (new) -> 1.1 arch/mips/sibyte/swarm/rtc_xicor1241.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_regs.h # (new) -> 1.1 arch/mips64/defconfig-atlas # (new) -> 1.1 arch/mips/galileo-boards/ev96100/puts.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/dbg_io.c # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0226/setup.c # (new) -> 1.1 arch/mips/vr41xx/zao-capcella/setup.c # (new) -> 1.1 arch/mips64/mm/tlbex-r4k.S # (new) -> 1.1 arch/mips/mm/highmem.c # (new) -> 1.1 include/asm-mips64/dec/machtype.h # (new) -> 1.1 arch/mips/mm/tlb-r4k.c # (new) -> 1.1 include/asm-mips/jmr3927/txx927.h # (new) -> 1.1 include/asm-mips/vr41xx/tb0229.h # (new) -> 1.1 include/asm-mips/mips-boards/msc01_pci.h # (new) -> 1.1 arch/mips/sibyte/swarm/time.c # (new) -> 1.1 arch/mips/pci/ops-vrc4173.c # (new) -> 1.1 include/asm-mips64/sgi/hpc3.h # (new) -> 1.1 include/asm-mips64/exception.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/reset.c # (new) -> 1.1 include/asm-mips64/dec/kn02.h # (new) -> 1.1 arch/mips/pci/ops-ev96100.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/irq.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/setup.c # (new) -> 1.1 drivers/pcmcia/au1000_pb1x00.c # (new) -> 1.1 include/asm-mips/ddb5xxx/ddb5476.h # (new) -> 1.1 arch/mips/tx4927/toshiba_rbtx4927/Makefile # (new) -> 1.1 arch/mips/defconfig-sead # (new) -> 1.1 arch/mips/lasat/lasatIRQ.S # (new) -> 1.1 drivers/net/meth.h # (new) -> 1.1 arch/mips/pci/ops-jmr3927.c # (new) -> 1.1 include/asm-mips/debug.h # (new) -> 1.1 include/asm-mips/dec/prom.h # (new) -> 1.1 arch/mips/sibyte/cfe/Makefile # (new) -> 1.1 arch/mips/au1000/pb1100/init.c # (new) -> 1.1 arch/mips/dec/prom/call_o32.S # (new) -> 1.1 arch/mips/vr41xx/casio-e55/setup.c # (new) -> 1.1 arch/mips/tx4927/common/tx4927_dbgio.c # (new) -> 1.1 include/asm-mips64/mips-boards/msc01_pci.h # (new) -> 1.1 arch/mips/galileo-boards/ev64120/reset.c # (new) -> 1.1 arch/mips/vr41xx/common/cmu.c # (new) -> 1.1 arch/mips/kernel/cpu-probe.c # (new) -> 1.1 include/asm-mips/fixmap.h # (new) -> 1.1 arch/mips/defconfig-tb0229 # (new) -> 1.1 arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-irq.S # (new) -> 1.1 include/asm-mips64/smplock.h # (new) -> 1.1 drivers/i2c/i2c-prosavage.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-rtc.c # (new) -> 1.1 arch/mips/mm/pg-r4k.S # (new) -> 1.1 arch/mips64/kernel/binfmt_elfo32.c # (new) -> 1.1 arch/mips/lasat/sysctl.h # (new) -> 1.1 include/asm-mips64/dec/ioasic_ints.h # (new) -> 1.1 arch/mips64/mm/pgtable.c # (new) -> 1.1 include/asm-mips64/dec/prom.h # (new) -> 1.1 include/asm-mips64/sections.h # (new) -> 1.1 arch/mips/sibyte/swarm/cmdline.c # (new) -> 1.1 arch/mips/pci/fixups-ev96100.c # (new) -> 1.1 include/asm-mips/fpu.h # (new) -> 1.1 include/asm-mips/mv64340_dep.h # (new) -> 1.1 include/asm-mips/traps.h # (new) -> 1.1 arch/mips/pci/fixup-capcella.c # (new) -> 1.1 arch/mips/mm/pgtable.c # (new) -> 1.1 include/asm-mips/jmr3927/ds1742rtc.h # (new) -> 1.1 arch/mips/vr41xx/zao-capcella/ide-capcella.c # (new) -> 1.1 arch/mips/tx4927/common/tx4927_prom.c # (new) -> 1.1 arch/mips/sibyte/swarm/Makefile # (new) -> 1.1 arch/mips/mm/cache.c # (new) -> 1.1 arch/mips/vr41xx/common/serial.c # (new) -> 1.1 include/asm-mips64/dec/tc.h # (new) -> 1.1 arch/mips/tx4927/common/tx4927_setup.c # (new) -> 1.1 arch/mips/au1000/db1x00/setup.c # (new) -> 1.1 include/asm-mips/sgi/ioc.h # (new) -> 1.1 arch/mips/lasat/reset.c # (new) -> 1.1 arch/mips64/defconfig-decstation # (new) -> 1.1 arch/mips/pci/pci-vr41xx.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-eisa.c # (new) -> 1.1 include/asm-mips/sgi/hpc3.h # (new) -> 1.1 include/asm-mips/keyboard.h # (new) -> 1.1 include/asm-mips64/ip32/mace.h # (new) -> 1.1 arch/mips/sibyte/sb1250/bcm1250_tbprof.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-mc.c # (new) -> 1.1 include/asm-mips64/i8259.h # (new) -> 1.1 arch/mips/vr41xx/nec-eagle/init.c # (new) -> 1.1 include/asm-mips/au1000_pcmcia.h # (new) -> 1.1 arch/mips/defconfig-lasat200 # (new) -> 1.1 include/asm-mips64/dec/rtc-dec.h # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/irq.c # (new) -> 1.1 arch/mips/defconfig-capcella # (new) -> 1.1 include/asm-mips64/dec/kn05.h # (new) -> 1.1 arch/mips/sibyte/swarm/dbg_io.c # (new) -> 1.1 include/asm-mips/irq_cpu.h # (new) -> 1.1 arch/mips/mips-boards/sead/sead_time.c # (new) -> 1.1 include/asm-mips/sibyte/64bit.h # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_int.h # (new) -> 1.1 arch/mips/pci/pci-ddb5477.c # (new) -> 1.1 include/asm-mips64/tlbdebug.h # (new) -> 1.1 drivers/char/lcd.c # (new) -> 1.1 include/asm-mips/jmr3927/pci.h # (new) -> 1.1 arch/mips64/mm/pg-sb1.c # (new) -> 1.1 arch/mips64/mm/sc-rm7k.c # (new) -> 1.1 include/asm-mips64/suspend.h # (new) -> 1.1 arch/mips/vr41xx/nec-eagle/irq.c # (new) -> 1.1 arch/mips64/kernel/irq.c # (new) -> 1.1 arch/mips/au1000/common/rtc.c # (new) -> 1.1 arch/mips/mm/pg-r3k.c # (new) -> 1.1 arch/mips/sibyte/sb1250/bus_watcher.c # (new) -> 1.1 include/asm-mips64/dec/tcmodule.h # (new) -> 1.1 arch/mips/sibyte/sb1250/irq_handler.S # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_scd.h # (new) -> 1.1 arch/mips64/mm/sc-r5k.c # (new) -> 1.1 include/asm-mips/smplock.h # (new) -> 1.1 arch/mips/defconfig-e55 # (new) -> 1.1 include/asm-mips/pb1500.h # (new) -> 1.1 include/asm-mips/sgi/gio.h # (new) -> 1.1 arch/mips/mm/c-sb1.c # (new) -> 1.1 include/asm-mips/mips-boards/sead.h # (new) -> 1.1 arch/mips/defconfig-pb1500 # (new) -> 1.1 arch/mips/sibyte/sb1250/smp.c # (new) -> 1.1 arch/mips/sibyte/swarm/setup.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_l2c.h # (new) -> 1.1 arch/mips/sgi-ip22/ip22-int.c # (new) -> 1.1 include/asm-mips/percpu.h # (new) -> 1.1 arch/mips/pci/pci-ocelot-g.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-berr.c # (new) -> 1.1 arch/mips/lasat/lasat_models.h # (new) -> 1.1 arch/mips/vr41xx/casio-e55/ide-e55.c # (new) -> 1.1 arch/mips/galileo-boards/ev96100/time.c # (new) -> 1.1 arch/mips64/mm/cex-sb1.S # (new) -> 1.1 include/asm-mips64/cacheops.h # (new) -> 1.1 arch/mips/lasat/picvue.c # (new) -> 1.1 arch/mips/vr41xx/common/Makefile # (new) -> 1.1 arch/mips/sibyte/sb1250/Makefile # (new) -> 1.1 drivers/media/dvb/dvb-core/dvb_functions.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/prom.c # (new) -> 1.1 arch/mips/galileo-boards/ev96100/int-handler.S # (new) -> 1.1 include/asm-mips/pb1000.h # (new) -> 1.1 include/asm-mips/jmr3927/jmr3927.h # (new) -> 1.1 include/asm-mips/dec/ecc.h # (new) -> 1.1 arch/mips/au1000/pb1100/Makefile # (new) -> 1.1 include/asm-mips/au1000_usbdev.h # (new) -> 1.1 arch/mips/defconfig-sb1250-swarm # (new) -> 1.1 arch/mips/kernel/irq_cpu.c # (new) -> 1.1 arch/mips/jmr3927/common/rtc_ds1742.c # (new) -> 1.1 include/linux/netfilter_ipv4/ipt_recent.h # (new) -> 1.1 arch/mips/au1000/common/clocks.c # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0229/init.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_ldt.h # (new) -> 1.1 include/asm-mips64/reboot.h # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_dma.h # (new) -> 1.1 arch/mips/mm/sc-r5k.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/gt64240_dep.h # (new) -> 1.1 arch/mips/defconfig-workpad # (new) -> 1.1 arch/mips/galileo-boards/ev64120/promcon.c # (new) -> 1.1 include/asm-mips64/percpu.h # (new) -> 1.1 arch/mips/vr41xx/ibm-workpad/ide-workpad.c # (new) -> 1.1 arch/mips/sibyte/sb1250/time.c # (new) -> 1.1 arch/mips64/mm/tlb-dbg-r4k.c # (new) -> 1.1 arch/mips/pci/common.c # (new) -> 1.1 arch/mips64/kernel/time.c # (new) -> 1.1 arch/mips/lasat/Makefile # (new) -> 1.1 arch/mips/ddb5xxx/ddb5477/lcd44780.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_syncser.h # (new) -> 1.1 include/asm-mips64/wbflush.h # (new) -> 1.1 arch/mips/lib/promlib.c # (new) -> 1.1 arch/mips/lasat/prom.c # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0229/setup.c # (new) -> 1.1 arch/mips/pci/fixup-ite8172g.c # (new) -> 1.1 arch/mips64/mm/c-sb1.c # (new) -> 1.1 drivers/pcmcia/au1000_generic.c # (new) -> 1.1 arch/mips64/kernel/irq_cpu.c # (new) -> 1.1 arch/mips/cobalt/promcon.c # (new) -> 1.1 arch/mips/pci/fixup-ocelot.c # (new) -> 1.1 arch/mips64/kernel/binfmt_elfn32.c # (new) -> 1.1 arch/mips/jmr3927/common/prom.c # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/Makefile # (new) -> 1.1 include/asm-mips64/dec/kn230.h # (new) -> 1.1 include/asm-mips/sibyte/carmel.h # (new) -> 1.1 arch/mips/vr41xx/zao-capcella/Makefile # (new) -> 1.1 arch/mips/pci/pci.c # (new) -> 1.1 include/asm-mips64/rtc.h # (new) -> 1.1 arch/mips/lasat/interrupt.c # (new) -> 1.1 arch/mips/momentum/ocelot_g/reset.c # (new) -> 1.1 arch/mips/pci/pci-vr41xx.h # (new) -> 1.1 include/asm-mips64/dec/kn03.h # (new) -> 1.1 arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c # (new) -> 1.1 arch/mips/pci/fixup-tb0229.c # (new) -> 1.1 arch/mips/sgi-ip22/ip22-nvram.c # (new) -> 1.1 arch/mips/mm/sc-ip22.c # (new) -> 1.1 arch/mips/mm/tlbex-r3k.S # (new) -> 1.1 include/asm-mips/jmr3927/tx3927.h # (new) -> 1.1 arch/mips/au1000/pb1500/init.c # (new) -> 1.1 arch/mips/lasat/image/head.S # (new) -> 1.1 arch/mips/galileo-boards/ev96100/setup.c # (new) -> 1.1 arch/mips/cobalt/irq.c # (new) -> 1.1 arch/mips/math-emu/dsemul.h # (new) -> 1.1 drivers/pci/hotplug/fakephp.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_smbus.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/mv-irq.c # (new) -> 1.1 arch/mips/vr41xx/tanbac-tb0229/Makefile # (new) -> 1.1 include/asm-mips/sibyte/trace_prof.h # (new) -> 1.1 include/asm-mips64/vga.h # (new) -> 1.1 arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/kgdb_io.c # (new) -> 1.1 include/asm-mips/vr41xx/eagle.h # (new) -> 1.1 arch/mips64/kernel/module.c # (new) -> 1.1 arch/mips/ramdisk/Makefile # (new) -> 1.1 include/asm-mips64/war.h # (new) -> 1.1 arch/mips/sibyte/cfe/cfe_api.c # (new) -> 1.1 arch/mips/defconfig-ev96100 # (new) -> 1.1 include/asm-mips/galileo-boards/gt96100.h # (new) -> 1.1 arch/mips/vr41xx/common/vrc4173.c # (new) -> 1.1 include/asm-mips/suspend.h # (new) -> 1.1 include/asm-mips/jmr3927/irq.h # (new) -> 1.1 arch/mips/pci/pci-ocelot-c.c # (new) -> 1.1 include/asm-mips64/dec/ioasic.h # (new) -> 1.1 arch/mips/vr41xx/victor-mpc30x/setup.c # (new) -> 1.1 arch/mips/au1000/pb1500/setup.c # (new) -> 1.1 net/ipv4/netfilter/arpt_mangle.c # (new) -> 1.1 arch/mips/galileo-boards/generic/Makefile # (new) -> 1.1 arch/mips/pci/fixup-tb0226.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_scd.h # (new) -> 1.1 include/asm-mips/galileo-boards/ev64120.h # (new) -> 1.1 arch/mips/pci/pci-lasat.c # (new) -> 1.1 include/asm-mips/highmem.h # (new) -> 1.1 arch/mips/momentum/ocelot_g/pci-irq.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_defs.h # (new) -> 1.1 arch/mips64/lib/promlib.c # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/rtc.c # (new) -> 1.1 arch/mips/vr41xx/victor-mpc30x/Makefile # (new) -> 1.1 arch/mips64/kernel/reset.c # (new) -> 1.1 arch/mips/au1000/db1x00/Makefile # (new) -> 1.1 arch/mips/sibyte/cfe/console.c # (new) -> 1.1 include/asm-mips/break.h # (new) -> 1.1 arch/mips/sibyte/sb1250/prom.c # (new) -> 1.1 arch/mips64/kernel/cpu-probe.c # (new) -> 1.1 arch/mips/lasat/sysctl.c # (new) -> 1.1 include/asm-mips64/ip32/crime.h # (new) -> 1.1 include/asm-mips/sibyte/sentosa.h # (new) -> 1.1 include/asm-mips/pb1100.h # (new) -> 1.1 arch/mips/pci/pci-hplj.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250.h # (new) -> 1.1 arch/mips/kernel/offset.c # (new) -> 1.1 arch/mips/mm/cerr-sb1.c # (new) -> 1.1 include/asm-mips/cacheflush.h # (new) -> 1.1 include/asm-mips/mv64340.h # (new) -> 1.1 arch/mips/jmr3927/common/Makefile # (new) -> 1.1 include/asm-mips64/sibyte/board.h # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_l2c.h # (new) -> 1.1 arch/mips/mm/c-r3k.c # (new) -> 1.1 include/asm-mips/lasat/eeprom.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/dbg_io.c # (new) -> 1.1 arch/mips/sibyte/swarm/rtc.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_mc.h # (new) -> 1.1 include/asm-mips64/keyboard.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/ocelot_c_fpga.h # (new) -> 1.1 arch/mips/vr41xx/nec-eagle/Makefile # (new) -> 1.1 arch/mips64/kernel/offset.c # (new) -> 1.1 drivers/net/meth.c # (new) -> 1.1 include/asm-mips64/ip32/machine.h # (new) -> 1.1 arch/mips/momentum/ocelot_g/gt64240.h # (new) -> 1.1 arch/mips/vr41xx/ibm-workpad/Makefile # (new) -> 1.1 include/asm-mips/sibyte/sb1250_mac.h # (new) -> 1.1 arch/mips/sibyte/cfe/smp.c # (new) -> 1.1 arch/mips/pci/ops-it8172.c # (new) -> 1.1 include/asm-mips/lasat/lasat.h # (new) -> 1.1 include/asm-mips/tx4927/tx4927.h # (new) -> 1.2 drivers/media/dvb/dvb-core/dvb_functions.c # (new) -> 1.1 arch/mips/momentum/ocelot_c/irq.c # (new) -> 1.1 arch/mips/vr41xx/ibm-workpad/init.c # (new) -> 1.1 arch/mips/pci/pci-ip32.c # (new) -> 1.1 drivers/i2c/busses/i2c-ali1535.c # (new) -> 1.1 arch/mips/galileo-boards/ev64120/dma.c # (new) -> 1.1 arch/mips/pci/ops-ocelot.c # (new) -> 1.1 arch/mips/vr41xx/common/time.c # (new) -> 1.1 arch/mips/mips-boards/sead/sead_int.c # (new) -> 1.1 include/asm-mips/softirq.h # (new) -> 1.1 drivers/net/irda/au1k_ir.c # (new) -> 1.1 arch/mips/lasat/ds1603.h # (new) -> 1.1 arch/mips/sgi-ip32/ip32-reset.c # (new) -> 1.1 include/asm-mips/au1000_dma.h # (new) -> 1.1 include/asm-mips64/sibyte/64bit.h # (new) -> 1.1 arch/mips/sgi-ip22/ip22-ksyms.c # (new) -> 1.1 include/asm-mips/kmap_types.h # (new) -> 1.1 include/asm-mips64/ip32/ip32_ints.h # (new) -> 1.1 arch/mips/cobalt/Makefile # (new) -> 1.1 arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c # (new) -> 1.1 arch/mips/galileo-boards/ev64120/irq-handler.c # (new) -> 1.1 arch/mips/defconfig-mpc30x # (new) -> 1.1 arch/mips64/defconfig-sead # (new) -> 1.2 arch/i386/kernel/cpu/cpufreq/speedstep-lib.c # (new) -> 1.1 arch/mips/vr41xx/zao-capcella/init.c # (new) -> 1.1 include/asm-mips64/dec/interrupts.h # (new) -> 1.1 include/asm-mips/sibyte/sb1250_ldt.h # (new) -> 1.1 include/asm-mips64/mips-boards/seadint.h # (new) -> 1.1 include/asm-mips64/sibyte/sentosa.h # (new) -> 1.1 include/asm-mips64/softirq.h # (new) -> 1.1 arch/mips/vr41xx/common/bcu.c # (new) -> 1.1 arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c # (new) -> 1.1 include/asm-mips64/mv64340.h # (new) -> 1.1 arch/mips/galileo-boards/generic/reset.c # (new) -> 1.1 arch/mips64/mm/tlb-glue-r4k.S # (new) -> 1.1 arch/mips64/mm/tlb-r4k.c # (new) -> 1.1 include/asm-mips64/mv64340_dep.h # (new) -> 1.1 include/asm-mips/vr41xx/vrc4173.h # (new) -> 1.1 arch/mips/galileo-boards/ev96100/irq.c # (new) -> 1.1 arch/mips/jmr3927/rbhma3100/setup.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250.h # (new) -> 1.1 arch/mips/lasat/prom.h # (new) -> 1.1 arch/mips/dec/kn02-irq.c # (new) -> 1.1 include/asm-mips/tx4927/tx4927_pci.h # (new) -> 1.1 arch/mips/sgi-ip22/ip22-reset.c # (new) -> 1.1 arch/mips/sibyte/sb1250/irq.c # (new) -> 1.1 include/asm-mips/sibyte/sb1250_uart.h # (new) -> 1.1 include/asm-mips/galileo-boards/ev64120int.h # (new) -> 1.1 arch/mips/pci/pci-cobalt.c # (new) -> 1.1 arch/mips/mm/tlbex-r4k.S # (new) -> 1.1 include/asm-mips/tlbdebug.h # (new) -> 1.1 arch/mips/cobalt/int-handler.S # (new) -> 1.1 include/asm-mips/dec/kn02ca.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/cpci-irq.c # (new) -> 1.1 include/asm-mips/tx4927/toshiba_rbtx4927.h # (new) -> 1.1 arch/mips/au1000/common/dma.c # (new) -> 1.1 include/asm-mips/galileo-boards/ev96100int.h # (new) -> 1.1 arch/mips/au1000/common/power.c # (new) -> 1.1 arch/mips/momentum/ocelot_c/Makefile # (new) -> 1.1 arch/mips/dec/ioasic-irq.c # (new) -> 1.1 include/asm-mips/dec/kn230.h # (new) -> 1.1 arch/mips/mips-boards/sead/Makefile # (new) -> 1.1 include/asm-mips/sibyte/sb1250_genbus.h # (new) -> 1.1 arch/mips/mm/c-r4k.c # (new) -> 1.1 arch/mips/lasat/at93c.h # (new) -> 1.1 arch/mips/lasat/lasat_board.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_uart.h # (new) -> 1.1 include/asm-mips64/gdb-stub.h # (new) -> 1.1 include/asm-mips64/gt64120.h # (new) -> 1.1 arch/mips/pci/fixup-jmr3927.c # (new) -> 1.1 arch/mips/pci/ops-au1000.c # (new) -> 1.1 arch/mips/arc/promlib.c # (new) -> 1.1 arch/mips/defconfig-tb0226 # (new) -> 1.1 include/asm-mips64/dec/ioasic_addrs.h # (new) -> 1.1 arch/mips64/kernel/scall_n32.S # (new) -> 1.1 arch/mips/vr41xx/common/int-handler.S # (new) -> 1.1 arch/mips/tx4927/common/tx4927_irq.c # (new) -> 1.1 include/asm-mips64/sgi/mc.h # (new) -> 1.1 arch/mips/momentum/ocelot_c/uart-irq.c # (new) -> 1.1 include/asm-mips/vr41xx/capcella.h # (new) -> 1.1 arch/mips/mm/tlb-r3k.c # (new) -> 1.1 arch/mips/lasat/at93c.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_genbus.h # (new) -> 1.1 arch/mips64/mm/tlb-glue-sb1.S # (new) -> 1.1 include/asm-mips/dec/kn02ba.h # (new) -> 1.1 include/asm-mips64/time.h # (new) -> 1.1 arch/mips/galileo-boards/ev64120/int-handler.S # (new) -> 1.1 include/asm-mips/lasat/serial.h # (new) -> 1.1 arch/mips/pci/pci-ip27.c # (new) -> 1.1 arch/mips/vr41xx/common/reset.c # (new) -> 1.1 include/asm-mips/war.h # (new) -> 1.1 arch/mips/au1000/pb1100/setup.c # (new) -> 1.1 include/asm-mips64/mips-boards/sead.h # (new) -> 1.1 arch/mips/mm/tlb-sb1.c # (new) -> 1.1 arch/mips/ramdisk/ld.script # (new) -> 1.1 include/asm-mips/lasat/picvue.h # (new) -> 1.1 arch/mips/vr41xx/casio-e55/Makefile # (new) -> 1.1 arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c # (new) -> 1.1 arch/mips/galileo-boards/ev64120/i2o.c # (new) -> 1.1 arch/mips/pci/fixup-victor-mpc30x.c # (new) -> 1.1 include/asm-mips/sgi/ip22.h # (new) -> 1.1 arch/mips/mm/c-tx39.c # (new) -> 1.1 include/asm-mips/sections.h # (new) -> 1.1 arch/mips64/mm/pg-r4k.c # (new) -> 1.1 arch/mips64/mm/tlb-sb1.c # (new) -> 1.1 include/asm-mips64/sibyte/sb1250_defs.h # (new) -> 1.1 include/asm-mips/tlbflush.h # (new) -> 1.1 arch/mips/vr41xx/victor-mpc30x/init.c # (new) -> 1.1 include/asm-mips64/sibyte/swarm.h # (new) -> 1.1 arch/mips/mm/pg-sb1.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/06/23 paulus@samba.org 1.1348.16.5 # Merge samba.org:/stuff/paulus/kernel/linux-2.5 # into samba.org:/stuff/paulus/kernel/for-linus-ppc # -------------------------------------------- # 03/06/22 akpm@digeo.com 1.1348.17.1 # [PATCH] __devinitdata declarations should not be marked const. # # There are some bad compiler issues with section confusion ("const" stuff # likes going into the rodata section). # -------------------------------------------- # 03/06/22 Andries.Brouwer@cwi.nl 1.1348.17.2 # [PATCH] loop.c cleanups # # This does the following: # - remove trailing spaces # - make loop.h independent by including bio.h, blk.h, spinlock.h # - replace the lock/unlock functions by module_get/module_put; # in struct loop this is the change # - void (*lock)(struct loop_device *); # - void (*unlock)(struct loop_device *); # + struct module *owner; # - replace the integer lo_encrypt_type by the pointer lo_encryption; # there was a race with loop_unregister_transfer # - fixed an off-by-one in loop_register_transfer # # This is Step 1 of a series of half a dozen or so. # # Half of the above is from Jari. Anything that is wrong is mine. # -------------------------------------------- # 03/06/22 ldl@aros.net 1.1348.17.3 # [PATCH] fix nbd driver for 2.5 block layer # # This makes NBD work with the new linux 2.5 block layer design. # Specifically, it fixes memory corruption that results from module # removal and possible memory corruption from sending or receiving disk # data from the server. # # It essentially rolls together the changes from two of the last patchlets # that I emailed: the fix for module removal & the fix for incorrect # struct bio usage. I believe it's wisest to roll these both together # into this one patch since they both deal with making NBD work better # with the 2.5 linux block layer design and without either of which, it's # possible that NBD will corrupt memory. # # Other changes I'd like to see introduced (like in the earlier jumbo # patch) meanwhile are feature enhancements so they can wait. This patch # also should address all the very helpful concerns that have been raised # so far. Particularly: # # 1. that the very first submitted NBD patch was broken down [Andrew] # 2. that only 1 spinlock is used for all the NBD request_queue structures # used [Jens,Al] # 3. that kmap() is used in case of highmem pages [Jens] # 4. that the allocation of request_queue is dynamic and seperate from # other allocated objects [Al] # -------------------------------------------- # 03/06/22 davem@nuts.ninka.net 1.1348.18.1 # [SPARC64]: Update struct compat_statfs. # -------------------------------------------- # 03/06/22 davem@nuts.ninka.net 1.1348.18.2 # [SPARC64]: Update solaris compat layer for vfs_statfs() changes. # -------------------------------------------- # 03/06/22 davem@nuts.ninka.net 1.1348.18.3 # [SPARC]: Update for show_stack() changes. # -------------------------------------------- # 03/06/22 davem@nuts.ninka.net 1.1348.18.4 # [SPARC]: Add {f,}statfs64 syscall entries. # -------------------------------------------- # 03/06/22 davem@kernel.bkbits.net 1.1348.17.4 # Merge davem@nuts.ninka.net:/home/davem/src/BK/sparc-2.5 # into kernel.bkbits.net:/home/davem/sparc-2.5 # -------------------------------------------- # 03/06/22 rusty@rustcorp.com.au 1.1348.17.5 # [PATCH] Workqueue Exit Neatening # # Jeff Garzik points out the initializing the exit completion at # exit time is foolish: we should just initialize it at creation time # live everything else in that structure, and avoid the memory barrier. # -------------------------------------------- # 03/06/23 rmk@flint.arm.linux.org.uk 1.1348.1.26 # [PCMCIA] Fix ide-cs driver name (for PCMCIA binding) # # Problem noticed by Eivind Tagseth. # # We seem to have resurected the "ide_cs" driver name for the ide-cs module. # Restore the driver name to "ide-cs". # -------------------------------------------- # 03/06/23 dwmw2@infradead.org 1.1348.17.6 # MTD driver cleanups... # # - Fix AFS partitioning oops when no partitions are found # - Add missing spin_unlock, optimise buffer writes in Intel NOR driver # - Fix DiskOnChip Millennium Plus register OutputControl register definition # - Fix DiskOnChip drivers to indicate correct ECC type # - Fix map drivers to use ARRAY_SIZE instead of redefining it. # - Make uCLinux map driver depend on !MMU # - Fix NAND write verify problem on some chips # - Other trivia from Rusty. # -------------------------------------------- # 03/06/23 dwmw2@infradead.org 1.1348.17.7 # Replace mtd_blktrans ->ioctl() method with ->getgeo() and ->flush() # # ... and also fix the embarrassing bug where NFTL and INFTL will # barf and exit if the add_mtd_blktrans_dev() function _exists_, # rather than actually calling it and barfing if it returns non-zero :) # -------------------------------------------- # 03/06/23 dwmw2@infradead.org 1.1348.17.8 # Trivia: use JFFS2 PAD() macro instead of masking manually. # -------------------------------------------- # 03/06/23 dwmw2@infradead.org 1.1348.17.9 # Fix jffs2_statfs w.r.t. statfs64 # -------------------------------------------- # 03/06/23 dwmw2@infradead.org 1.1348.17.10 # Remove superfluous debugging in mtd_blkdevs.c # -------------------------------------------- # 03/06/23 jgrimm@touki.austin.ibm.com 1.1305.17.1 # Merge touki.austin.ibm.com:/home/jgrimm/bk/linux-2.5 # into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work # -------------------------------------------- # 03/06/23 greg@kroah.com 1.1348.19.1 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.5 # -------------------------------------------- # 03/06/23 ink@jurassic.park.msu.ru 1.1348.20.1 # [PATCH] PCI: fix non-hotplug build # # Current BK won't build when CONFIG_HOTPLUG is not set due to # undefined references to pci_destroy_dev in hotplug.c. # I think it makes sense to not compile hotplug.c in this case at all. # Also, this allows to get rid of several function which are unused # in non-hotplug kernel. # # Tested on Alpha. # -------------------------------------------- # 03/06/23 ink@jurassic.park.msu.ru 1.1348.20.2 # [PATCH] PCI: fix alpha for reimplement pci proc name # # On Fri, Jun 20, 2003 at 02:24:13PM -0700, Greg KH wrote: # > Thanks, I've reverted your previous patch, and fixed the one typo in # > this patch and applied it all to my bk tree. Hopefully Linus will pull # > from it sometime soon :) # # Argh, where were my eyes... There was another typo which broke Alpha. # -------------------------------------------- # 03/06/23 jes@wildopensource.com 1.1327.4.20 # [PATCH] ia64: fix static initializers # # No need to explicitly zero out global variables. # -------------------------------------------- # 03/06/23 lord@sgi.com 1.1374 # [PATCH] Fix XFS proc interface initializers # # [XFS] the intializers for the /proc interface to xfs got out of order, # and we are syncing 1000 times faster than we are supposed to! # # SGI Modid: 2.5.x-xfs:slinx:151712a # -------------------------------------------- # 03/06/23 torvalds@home.transmeta.com 1.1375 # Merge home.transmeta.com:/home/torvalds/v2.5/xfs # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1376 # [PATCH] MIPS merge, generic mips bits. # # This contains all the generic 32-bit MIPS code, so all arch/mips/ and # include/asm-mips/ stuff. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1377 # [PATCH] MIPS merge, generic mips64 bits. # # This updates the generic mips64 code. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1378 # [PATCH] SGI IP22 bits # # An update for the Indy aka IP22 support. Consolidates the 32-bit and # 64-bit copies of the support code into one directory, so in total this # patch deletes quite a bit of code. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1379 # [PATCH] PCI code # # This is the entire MIPS PCI code which I'm consolidating in arch/mips/pci/. # Applying this patch will result in some code duplication; the remaining # patches I'm about to send will clean that. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1380 # [PATCH] 2.7.73 SGI IP27 update # # An update of the SGI IP27 aka Origin 200/2000/Onyx 2 support. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1381 # [PATCH] Code for Galileo boards # # The support code for two more Galileo evaluation boards. # # (Evil stuff, just to get your tree in sync again. I've got a cleanup in # my work tree). # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1382 # [PATCH] Sibyte updates # # Update the code for the BCM1250 and evaluation platforms. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1383 # [PATCH] Alchemy update # # This is an update of the AMD Alchemy support for 2.5. # # (This is way behind what we have for 2.4 but forward porting is non-trivial # and work in progress.) # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1384 # [PATCH] Update for MIPS Inc's eval boards. # # This is an update for MIPS Inc's evaluation boards in all their ugly # versions ... # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1385 # [PATCH] TX49xx update # # This adds support for Toshiba's TX49xx SOCs and an evaluation board with # the nice nae RBTX4927. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1386 # [PATCH] Baget update # # This is an update for the Russian Baget industrial controller. Suffers a # bit from bitrot, the authors have promised an update to me. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1387 # [PATCH] DEC update # # An update of the code for the DECstations. This also adds 64-bit support # for the R4000 versions of DEC's good old workstations. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1388 # [PATCH] NEC DDB update # # This updates the support for NEC's DDB series of evaluation boards. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1389 # [PATCH] NEC VR41xx update # # This one adds support for a bunch of NEC VR41xx-based platforms such as # IBM's workpad and a bunch of eval boards. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1390 # [PATCH] JMR3927 update # # This updates support for the JMR3927 eval board. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1391 # [PATCH] Update Cobalt support # # This adds back support for the MIPS-based Cobalt Raq 1/2 and Qube 1/2 # systems. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1392 # [PATCH] Add support for SGI IP32 # # This adds support for SGI's O2 workstation aka IP32. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1393 # [PATCH] Momentum update # # This adds the board support code for Momentum's Ocelot series of boards. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1394 # [PATCH] drivers/sgi update # # This updates drivers/sgi by removing it :-) With all the conceptually # wrong code which has was rewritten or should be rewritten or better # live elsewhere there just was no point in keeping this directory around # any longer. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1395 # [PATCH] ARC update # # This updates the ARC firmware support code. Also removes the 64-bit # variant of the code; the 64-bit kernel now uses the 32-bit code also. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1396 # [PATCH] Lasat support # # This patch adds support for the Lasat 100 and 200 systems. # -------------------------------------------- # 03/06/23 ralf@linux-mips.org 1.1397 # [PATCH] Remove Nino support # # This patch mostly removes the support for the Phillips Nino at the # request of the author. The only remaining bits are directly related # to the SOC the Nino is based on which is used by other ports. # -------------------------------------------- # 03/06/23 torvalds@home.transmeta.com 1.1398 # Remove SGI subdirectory from driver Makefile, since it is now # gone. # -------------------------------------------- # 03/06/23 yoshfuji@linux-ipv6.org 1.1348.17.11 # [IPV6]: Clean-up advmss calculation. # -------------------------------------------- # 03/06/23 chas@cmf.nrl.navy.mil 1.1348.17.12 # [ATM]: Move vccs to global sk-based linked list. # -------------------------------------------- # 03/06/23 shemminger@osdl.org 1.1348.17.13 # [NET]: PPPoE cleanup [TRIVIAL]. # This is a cleanup patch, no change in functionality. # - Get rid of debug macro's that aren't used anywhere in the code. # - Make functions and data structures static where possible # - C99 initializer for ppoe_chan_ops # - fix whitespace typo # -------------------------------------------- # 03/06/23 shemminger@osdl.org 1.1348.17.14 # [NET]: Fix oops on /proc/net/pppoe. # -------------------------------------------- # 03/06/23 shemminger@osdl.org 1.1348.17.15 # [NET]: Convert PPPoE to new style protocol. # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1399 # [PATCH] update the generic saa7146 driver # # - update the generic saa7146 driver # - remove some #if LINUX_VERSION_CODE constructions # - sync with the interrupt handler changes in 2.5.69 # - add a missing kfree() call which caused the kernel to leak 32kB of # kmalloc()ed memory. iieek! # - fixed the capture code to handle cards that have swapped field order # (odd and even fields) # - added and fixed some debug messages # - changed from kmalloc() to pci_consistent() # - many small changes necessary to fix warnings/problems for ppc64 # compilation # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1400 # [PATCH] update dvb subsystem core # # - update dvb subsystem core # - switched from user-land types like __u8 to u8 and uint16_t to u16 # this makes the patch rather large. # - updated the dvr (digital videorecording) facility # - renamed some structures, like "struct dmxdev_s" to "struct dmxdev" # - introduced dvb_functions.[ch], where some linux-kernel specific # functions are encapsulated. by this, the dvb subsystem stays quite # independent from deeper linux kernel functions. # - moved dvb_usercopy() to dvb_functions.c -- this is essentially # video_usercopy() which should be generic_usercopy() instead... # - Made the dvb-core in dvbdev.c work with devfs again. # - remove all typedefs from structs # - remove all typedefs from enums # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1401 # [PATCH] update the av7110 and budget drivers # # - update the av7110 and budget drivers # - replaced ddelay() wait function with generic dvb_delay() # implementation # - new DATA_MPEG_VIDEO_EVENT for direct mpeg2 video playback # - added support for DVB-C cards with MSP3400 mixer and analog tuner # - fixed up the av7110_ir handler and especially the write_proc() # function; this fixed the bug the Stanford Checker has found # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1402 # [PATCH] update dvb frontend drivers # # - update dvb frontend drivers # - C99 initializers # - fix up some includes # - various bugfixes # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1403 # [PATCH] add a new driver for the cx24110 frontend # # - add a new driver for the cx24110 frontend by Peter Hettkamp # <peter.hettkamp@t-online.de> # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1404 # [PATCH] add dvb subsystem as a crc32 lib user # # - add dvb subsystem as a crc32 lib user # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1405 # [PATCH] update analog saa7146 drivers mxb and dpc7146 # # - update analog saa7146 drivers mxb and dpc7146 # - add MODULE_DEVICE_TABLE entries, so that /sbin/hotplug can handle the # devices # - fixup due to the latest i2c changes # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1406 # [PATCH] correct the i2c address of saa7111 # # - this patch corrects the i2c address from "34>>1" to 0x24 and 0x25. # # Believe me -- or look at the data sheet, for example from # # http://www.gdv.uni-hannover.de/~hunold1/linux/saa7146/specs/saa7111a.pdf # # Page 41 says: "Slave address read = 49H or 4BH; note 2 write = 48H or # 4AH" They use 8-bit addresses here, but i2c addresses are 7-bit, ie. # 0x48>>1 == 0x24 and 0x4a>>1 = 0x25 # -------------------------------------------- # 03/06/23 hunold@convergence.de 1.1407 # [PATCH] clean up the parts according to the comments on kernel mailing list # # clean up the parts according to the comments on kernel mailing list # (mainly by Christoph Hellwig) # # - ugly WRITE_RPS0 define in saa7146_hlp.c has been replaced by a proper # inline (I hope) # - use <linux/types.h> not <asm/types.h> everywhere # - include <asm/*.h> headers after <linux/*.h> ones # - revert the indentation from "static <newline> xxx to "static xxx" # -------------------------------------------- # 03/06/23 hadi@shell.cyberus.ca 1.1348.17.16 # [NET]: Fix OOPSes with RSVP. # -------------------------------------------- # 03/06/23 herbert@gondor.apana.org.au 1.1348.17.17 # [IPSEC]: Add encap_oa member to struct xfrm_encap_tmpl. # -------------------------------------------- # 03/06/23 herbert@gondor.apana.org.au 1.1348.17.18 # [IPSEC]: Close SADB_ADD race and add XFRM_MSG_UPDSA (SADB_UPDATE equivalent). # -------------------------------------------- # 03/06/23 whydoubt@yahoo.com 1.1348.17.19 # [NET]: Trivial patch to netfilter Kconfig. # -------------------------------------------- # 03/06/23 solt@dns.toxicfilms.tv 1.1348.17.20 # [IPV4]: Be more verbose about invalid ICMPs sent to broadcast. # -------------------------------------------- # 03/06/23 shemminger@osdl.org 1.1348.17.21 # [NET]: Update teql scheduler to dynamic net device. # - dynamically allocate and free the network device. # previously, used static network device. # - support multiple equalizers (default one) via module parameter (max_equalizers) # previously, limited to one. # -------------------------------------------- # 03/06/24 paulus@samba.org 1.1348.16.6 # Merge samba.org:/stuff/paulus/kernel/linux-2.5 # into samba.org:/stuff/paulus/kernel/for-linus-ppc # -------------------------------------------- # 03/06/23 rmk@flint.arm.linux.org.uk 1.1348.21.1 # Merge flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5 # into flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-serial # -------------------------------------------- # 03/06/23 willy@debian.org 1.1348.20.3 # [PATCH] PCI: unconfuse arch/i386/pci/Makefile # # I was looking in this Makefile for link order when my head began to hurt. # Apparently you can't have both NUMAQ and VISWS selected, so getting rid # of all the ifdefs/ifndefs like this should work. # -------------------------------------------- # 03/06/23 willy@debian.org 1.1348.20.4 # [PATCH] PCI: pci_raw_ops devfn # # Combine the dev and func arguments to pci_raw_ops into devfn which is # more natural all around. # -------------------------------------------- # 03/06/23 torvalds@home.transmeta.com 1.1408 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/23 bunk@fs.tum.de 1.1348.20.5 # [PATCH] PCI Hotplug: fix buggy comparison in cpqphp_pci.c # # I don't understand the code good enough to be sure my patch is correct, # but the current code is definitely buggy: # # 0xFF is the maximum value for an u8, so tdevice < 0x100 is _always_ # true. # -------------------------------------------- # 03/06/23 henk@god.dyndns.org 1.1348.22.1 # [PATCH] I2C: add i2c-prosavage driver # # Using the MMIO method now, the driver should be able to handle multiple # video cards. # # The driver could potentialy also handle other s3 devices. You can try this # by adding more pci id's to the prosavage_pci_tbl. # -------------------------------------------- # 03/06/23 willy@org.rmk.(none) 1.1348.21.2 # [SERIAL] Missing Kconfig dependencies # # If one turns off SERIAL_8250, these items shouldn't be selectable. # Also gets the indentation right in `make oldconfig'. # -------------------------------------------- # 03/06/23 dlstevens@us.ibm.com 1.1348.17.22 # [IPV{4,6}]: Fix "slow multicast on 2.5.69" bug. # -------------------------------------------- # 03/06/23 rmk@flint.arm.linux.org.uk 1.1348.21.3 # [SERIAL] 8250_cs update - remove serial_info_t # -------------------------------------------- # 03/06/23 greg@kroah.com 1.1348.22.2 # I2C: add i2c-ali1535 bus driver # # Ported from the i2c cvs tree. # -------------------------------------------- # 03/06/23 rmk@flint.arm.linux.org.uk 1.1348.21.4 # [SERIAL] 8250_cs update - remove work queue # # Remove the work queue for serial_remove; events always happen # in process context now so the work queue gains us nothing. # -------------------------------------------- # 03/06/23 rmk@flint.arm.linux.org.uk 1.1348.21.5 # [SERIAL] 8250_cs update - incorporate pcmcia-cs 3.1.34 serial_cs fixes # # - add buggy_uart parameter # - use detected Vcc values, not CIS Vcc values # - handle OxSemi OXCF950 ports # -------------------------------------------- # 03/06/23 greg@kroah.com 1.1409 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/pci-2.5 # -------------------------------------------- # 03/06/23 greg@kroah.com 1.1408.1.1 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/i2c-2.5 # -------------------------------------------- # 03/06/23 rusty@rustcorp.com.au 1.1408.2.1 # [PATCH] {PATCH 2.5.72] Use mod_timer in drivers_net_wan_sdla_fr.c # # From: Vinay K Nallamothu <vinay-rc@naturesoft.net> # -------------------------------------------- # 03/06/23 rusty@rustcorp.com.au 1.1408.2.2 # [PATCH] [PATCH 2.5.72] Use mod_timer in drivers_net_wan_sdla_ppp.c # # From: Vinay K Nallamothu <vinay-rc@naturesoft.net> # -------------------------------------------- # 03/06/23 rusty@rustcorp.com.au 1.1408.2.3 # [PATCH] [PATCH 2.5.72] Use mod_timer in drivers_net_wan_sdla_x25.c # # From: Vinay K Nallamothu <vinay-rc@naturesoft.net> # -------------------------------------------- # 03/06/23 rusty@rustcorp.com.au 1.1408.2.4 # [PATCH] [PATCH 2.5.72] Use mod_timer in drivers_net_wan_sdla_chdlc.c # # From: Vinay K Nallamothu <vinay-rc@naturesoft.net> # -------------------------------------------- # 03/06/23 romieu@fr.zoreil.com 1.1408.2.5 # [netdrvr sk98lin] PCI API conversion, and some cleanups # # # - PCI API init style conversion for drivers/net/sk98lin/skge.c; # - new helpers: SkGeDev{Init/CleanUp}; # - sk_devs_lock moved around as it's needed early. # # Compiles without error. Untested. # -------------------------------------------- # 03/06/23 oliver@neukum.org 1.1348.19.2 # [PATCH] USB: highdma support for kaweth # # this tells the network layer that we can DMA from high memory # if the host controller supports it. # # - enable 64bit DMA on platforms that support it # -------------------------------------------- # 03/06/23 davidm@tiger.hpl.hp.com 1.1327.4.21 # ia64: Rename init_thread_union to init_task_mem to avoid conflicting # declration in <linux/sched.h>. # -------------------------------------------- # 03/06/23 davidm@tiger.hpl.hp.com 1.1327.4.22 # Drop pcibios_update_resource() #warning. # -------------------------------------------- # 03/06/23 davidm@tiger.hpl.hp.com 1.1327.4.23 # ia64: Rename irq_desc() to irq_descp() to avoid conflict with variable # of same name declared in linux/irq.h. The expectation is that # this variable will be removed eventually and then irq_descp() # can be renamed to irq_desc() again. But for now, this makes it # easier to compile against Linus' source tree. # -------------------------------------------- # 03/06/23 davidm@tiger.hpl.hp.com 1.1327.4.24 # ia64: Update defconfig. Add missing include to <asm-ia64/tlb.h>. Fix # compiler warning in perfmon.c. # -------------------------------------------- # 03/06/23 davidm@tiger.hpl.hp.com 1.1348.23.1 # Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5 # into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5 # -------------------------------------------- # 03/06/24 jmorris@intercode.com.au 1.1408.3.1 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into intercode.com.au:/home/jmorris/bk/net/net-2.5 # -------------------------------------------- # 03/06/23 davem@nuts.ninka.net 1.1408.4.1 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/06/23 davem@nuts.ninka.net 1.1408.4.2 # [XFS]: Fix build error on big-endian. # -------------------------------------------- # 03/06/24 jmorris@intercode.com.au 1.1408.3.2 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into intercode.com.au:/home/jmorris/bk/net/net-2.5 # -------------------------------------------- # 03/06/24 paulus@samba.org 1.1348.16.7 # PPC32: Implement 2-argument show_stack(). # -------------------------------------------- # 03/06/24 yoshfuji@linux-ipv6.org 1.1408.3.3 # [IPV6] use macro for maximum payload length # -------------------------------------------- # 03/06/24 yoshfuji@linux-ipv6.org 1.1408.3.4 # [IPV6] Fix large packet length check # # There were two errors in length check in the output path. # We could not send large packet (65535bytes). # # This patch fixes the problem. # -------------------------------------------- # 03/06/24 jgrimm@touki.austin.ibm.com 1.1327.10.1 # Merge touki.austin.ibm.com:/home/jgrimm/bk/linux-2.5 # into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work # -------------------------------------------- # 03/06/18 jgrimm@touki.austin.ibm.com 1.1327.10.2 # [SCTP] Add ASSOCINFO and RTOINFO sockopts. (Ryan Layer and Anup Pemmaiah) # # Submitted by pemmaiah@cc.usu.edu and rmlayer@us.ibm.com. # -------------------------------------------- # 03/06/18 jgrimm@touki.austin.ibm.com 1.1327.10.3 # [SCTP] Fix wrong logic in hlist change. # # Otherwise, we leak bind_buckets. # -------------------------------------------- # 03/06/18 jgrimm@touki.austin.ibm.com 1.1327.10.4 # [SCTP] Remove some unused source modules. # # We use crypto api. Get rid of our own versions of hash code. # -------------------------------------------- # 03/06/19 jgrimm@touki.austin.ibm.com 1.1327.10.5 # [SCTP] Minor warning cleanups. # -------------------------------------------- # 03/06/19 jgrimm@touki.austin.ibm.com 1.1327.10.6 # [SCTP] More typedef removals. # # sctp_cookie_t -> sctp_cookie, sctp_signed_cookie_t ->sctp_signed_cookie_t. # -------------------------------------------- # 03/06/19 jgrimm@touki.austin.ibm.com 1.1327.10.7 # [SCTP] More typedef & name cleanup. # -------------------------------------------- # 03/06/20 jgrimm@touki.austin.ibm.com 1.1327.10.8 # [SCTP] Shorten SACK generation path. # # 1) Remove sctp_tsnmap_update_pending from the SACK path. The # pending_data variable is only used by a socket option, so just # calculate it when needed rather than the I/O path. # 2) Instead of walking the tsnmap twice, change the interface to # allow walking once. # 3) Only report a fixed number of gabs and reserve this room in the # association, saving us a kmalloc every sack generation. # TBD: Still need to kick out of tanmap walking early if we get to # max_tsn_seen. # -------------------------------------------- # 03/06/23 jgrimm@touki.austin.ibm.com 1.1327.10.9 # [SCTP] Don't search gap ack blocks past max_tsn_seen. # # There is no need to keep walking the tsnmap past the # max_tsn_seen, so don't. # -------------------------------------------- # 03/06/24 jgrimm@touki.austin.ibm.com 1.1348.24.1 # Merge touki.austin.ibm.com:/home/jgrimm/bk/linux-2.5 # into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1408.5.1 # Merge bk://bk.arm.linux.org.uk/linux-2.5-pcmcia # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1408.5.2 # Merge bk://bk.arm.linux.org.uk/linux-2.5-serial # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1408.1.2 # Merge bk://kernel.bkbits.net/gregkh/linux/i2c-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1410 # Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1411 # Merge bk://kernel.bkbits.net/jgarzik/irda-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1412 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1413 # Merge bk://ppc.bkbits.net/for-linus-ppc # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1414 # [PATCH] Fix bug in rpc cache_clean introduced by previous patch # # Having a 'continue' at the end of this look it pointless... it should # be a break. # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1415 # [PATCH] Always flush rpc caches after an update # # ..as the update might have set an expiry date in the past # and we want it to be removed instantly. # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1416 # [PATCH] Include update mode in declaration of RPC information caches. # # The sunrpc/cache.c caches which store nfsd export information # can be updated either "inplace" or by replacing the entry. # # replacement is needed when an entry hold a reference to some # other object, so the reference counts work properly. # # "inplace" can be used when no such references are held, and should be # used when the object could be refered to by another cache (as otherwise # the other cache would have to be updated whenever this one is). # # Previously the type of update (inplace or replace) was specified # as an argument to the *_lookup operation. This too easily lead to # inconsistancies. # # With this patch, the update mode is specified when the cache is # declared. # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1417 # [PATCH] Add some tracing when showing the content of an RPC cache. # # The /proc/net/rpc/*/content files now will show # entries that are still in the cache, but are either # expired or negative, as comment. # # ip_map_show is enhance to work if called with a negative # or incomplete entry. # # Also if cache debugging is enabled, the expiry time and # refcount of each entry will be included in a comment. # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1418 # [PATCH] Define cache_show methods for export and filehandle cache in nfsd. # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1419 # [PATCH] Use schedule_work to regular cache cleaning # # Cleaning of the export caches is currently done by idle # nfsd threads which isn't very reliable. # # This patch makes use of work_queues to do it all inside # cache.c # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1420 # [PATCH] Fix byte counting for NFSv3 readdir replies # # The amount of free space is calculated wrongly so # nfsv3 readdir replies are shorted than they could be. # -------------------------------------------- # 03/06/24 neilb@cse.unsw.edu.au 1.1421 # [PATCH] Get buf size and page count right for RPC services. # # The old calculations BUGed on 64k PAGESIZE machines. # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1422 # Merge http://lia64.bkbits.net/to-linus-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1423 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 B.Zolnierkiewicz@elka.pw.edu.pl 1.1424 # [PATCH] do not take ide_setting_sem under ide_lock # # From -mm tree, fixes oops when removing ide drivers. # -------------------------------------------- # 03/06/24 B.Zolnierkiewicz@elka.pw.edu.pl 1.1425 # [PATCH] fix use-after-free in ide_unregister() # -------------------------------------------- # 03/06/24 B.Zolnierkiewicz@elka.pw.edu.pl 1.1426 # [PATCH] build fix for pdc4030 without taskfile IO # # Noticed by Arkadiusz Miskiewicz. # -------------------------------------------- # 03/06/24 B.Zolnierkiewicz@elka.pw.edu.pl 1.1427 # [PATCH] fix compilation of NS SC1x00 driver without procfs # # Noticed by Adrian Bunk. # -------------------------------------------- # 03/06/24 B.Zolnierkiewicz@elka.pw.edu.pl 1.1428 # [PATCH] call setup_driver_defaults() only once for each driver # -------------------------------------------- # 03/06/24 mikpe@csd.uu.se 1.1429 # [PATCH] enable local APIC on P4 # # The current local APIC code refuses to enable the local APIC # on a P4 if the BIOS booted us with the local APIC disabled. # This patch removes this unnecessary restriction. Please apply. # # Most P4 machines do boot with the local APIC enabled, but # Keith Owens reported that the P4 based Compaq Evo N800v # disables the local APIC, even though the machine actually # works if Linux enables it. # # It is possible that some P4 machines with broken BIOSen # were saved by our refusal to enable the local APIC. We # can handle them via the DMI blacklist rules instead. # -------------------------------------------- # 03/06/24 ambx1@neo.rr.com 1.1348.25.1 # [PNP] pnp_init_resource_table compile fix # # In the last release, this api was accidently changed and therefore # affected some drivers. This patch corrects the issue by renaming # the api back to pnp_init_resource_table. # -------------------------------------------- # 03/06/24 ambx1@neo.rr.com 1.1348.25.2 # [PNP] Locking Fixes # # The semaphore in pnp_init_resource_table is not needed and, in some # cases, can cause resource management lockups. This patch removes the # improperly placed semaphore. # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1430 # [SEQ_FILE]: Export seq_path() to modules. # -------------------------------------------- # 03/06/24 greg@kroah.com 1.1348.19.3 # [PATCH] USB: add support for 50 baud to io_edgeport.c # -------------------------------------------- # 03/06/24 kpc-usbdev@gelato.uiuc.edu 1.1348.19.4 # [PATCH] USB: Desknote/ECS UCR-61S2B card reader (2.5.72 patched) # # This is for 2.5.72 with the US_PR_DEVICE / US_SC_DEVICE patch in place. # Tested and working. # -------------------------------------------- # 03/06/24 oliver@neukum.org 1.1348.19.5 # [PATCH] USB: make kaweth deal with ENOMEM # # this fixes the logic kaweth uses to deal with ENOMEM from # usb_submit_urb(). Using the interrupt endpoint's completion # handller is longer an option because automagic resubmission # has been removed. Thus we use workqueues which can be delayed # so that kswapd can do its job and can use GFP_NOIO which is much # likelier to succeed. # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1429.1.1 # Merge bk://kernel.bkbits.net/jmorris/net-2.5 # into nuts.ninka.net:/home/davem/src/BK/jmorris-2.5 # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1431 # Merge nuts.ninka.net:/home/davem/src/BK/jmorris-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/06/24 bernie@develer.com 1.1432 # [IPV4]: Trim the includes used in util.c # -------------------------------------------- # 03/06/24 ehabkost@conectiva.com.br 1.1429.2.1 # [PATCH] Fix compilation of ip2main # # The following patch fix compilation of drivers/char/ip2main.c. It was # broken by the removal of pci_present(). # # It just adds open and closing braces around the code that declares the # pci_dev_i variable. The rest of the patch just change the indentation. # -------------------------------------------- # 03/06/24 willy@debian.org 1.1429.2.2 # [PATCH] PCI: [PATCH] pcibios_scan_acpi() # # On Mon, Jun 23, 2003 at 02:39:05PM -0700, Greg KH wrote: # > > How about acpi_scan_pci_bus_root()? # > # > I agree, that sounds better. # # I think it's too long ... so unless anyone has a better idea, I'm going with # pci_acpi_scan_root(). Here's the patch, presented in patch -p1 format to # make greg's scripts happy ;-) # # ia64 needs to be passed the pci domain and the acpi handle corresponding # to each root bus. Rather than change pcibios_scan_root to take additional # arguments, this patch introduces pci_acpi_scan_root(). # -------------------------------------------- # 03/06/24 greg@kroah.com 1.1429.3.1 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/gregkh-2.5 # -------------------------------------------- # 03/06/24 laforge@netfilter.org 1.1433 # `cat msg` # -------------------------------------------- # 03/06/24 laforge@netfilter.org 1.1434 # [NETFILTER]: Forward port cosmetic fixes from 2.4.x # -------------------------------------------- # 03/06/24 laforge@netfilter.org 1.1435 # [NETFILTER]: Enhancement for ip{,6}_tables, add new /proc files. # -------------------------------------------- # 03/06/24 laforge@netfilter.org 1.1436 # [NETFILTER]: Fix conntrack master_ct refcounting. # -------------------------------------------- # 03/06/24 willy@debian.org 1.1429.2.3 # [PATCH] PCI documentation # # Update the PCI Documentation to reflect some of the functions which have # recently been added and removed. # # Index: Documentation/pci.txt # =================================================================== # RCS file: /var/cvs/linux-2.5/Documentation/pci.txt,v # retrieving revision 1.4 # -------------------------------------------- # 03/06/24 sfrost@snowman.net 1.1437 # [NETFILTER]: Add "recent" iptables facility. # -------------------------------------------- # 03/06/24 ink@jurassic.park.msu.ru 1.1438 # [NET]: Need sys_socket cond_syscall() entry. # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1439 # Merge bk://kernel.bkbits.net/gregkh/linux/linus-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 torvalds@home.transmeta.com 1.1440 # Merge bk://linux-pnp.bkbits.net/pnp-2.5 # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/24 Andries.Brouwer@cwi.nl 1.1441 # [PATCH] loop.c - part 2 of N # # This does the following: # # - IV value is current 512-byte sector relative to start of loop # container file. This is what all cryptoloop people have done, if I # am not mistaken. Andi or others - if you can demonstrate the need # for a more flexible setup an additional ioctl field may be needed. I # hope we can do without. # # - made some things static # # - made lo_offset a loff_t # # - added lo_sizelimit # # If one wanted a (crypto)loop somewhere inside a container file, the # old code allowed a starting offset, but no size, so that the # cryptoloop always extended to the end of the container file. This # field allows one to select an arbitrary interval. Note that this # changes struct loop_info64. # # - improve error handling of loop_init() # # - removed the unused typedef transfer_proc_t. # # - added a define for LO_CRYPT_CRYPTOAPI # -------------------------------------------- # 03/06/24 rddunlap@osdl.org 1.1442 # [PATCH] unexpected IO-APIC update # # Recently there has been a rash of Unexpected IO APIC reports on the # linux-smp mailing list. Most of the most recent ones are due to some # newer Intel chipsets (865, 875). # # The IO APIC Version register doesn't indicate the differences in these # IO APICs. # # I have an patch that addresses these chipsets. It has been tested by a # few people with good results and has been blessed by Maciej Rozycki. # # Other than conditionally decoding IO APIC registers 2 and 3, we could # alternately ignore them since Linux doesn't use the values for anything # other than printing them. # # This patch ignores IO APIC register 2 if it's the same value as IO APIC # register 1. It also reads IO APIC register 3 if the IO APIC version is # >= 0x20, but some chipsets don't support this register, so it is also # ignored if its value if the same as IO APIC register 1 or 2. # # Another possible(?) alternative is to read the PID/VID of the device to # determine which registers it supports. However, PCI devices have not # been scanned at this point in init, so it would require scanning PCI # config space directly and I don't yet see the point of doing that. # # Oh, and the UNEXPECTED_IO_APIC() function doesn't print anything in # 2.5.current and I didn't change that. # -------------------------------------------- # 03/06/24 daniel.ritz@gmx.ch 1.1443 # [PATCH] alloc_etherdev for 3c574_cs # # net_device is no longer allocated as part of the driver's private structure, # instead it's allocated via alloc_netdev. compile tested only since no hardware # against 2.5.73-bk # # # -daniel # # # ===== drivers/net/pcmcia/3c574_cs.c 1.17 vs edited ===== # -------------------------------------------- # 03/06/24 daniel.ritz@gmx.ch 1.1444 # [PATCH] alloc_etherdev for 3c589_cs # # net_device is no longer allocated as part of the driver's private structure, # instead it's allocated via alloc_netdev. compile tested only since no hardware # against 2.5.73-bk # # # -daniel # # ===== drivers/net/pcmcia/3c589_cs.c 1.17 vs edited ===== # -------------------------------------------- # 03/06/24 daniel.ritz@gmx.ch 1.1445 # [PATCH] alloc_etherdev for fmvj18x_cs # # net_device is no longer allocated as part of the driver's private structure, # instead it's allocated via alloc_netdev. compile tested only since no hardware # against 2.5.73-bk # # # -daniel # # ===== fmvj18x_cs.c 1.21 vs edited ===== # -------------------------------------------- # 03/06/24 daniel.ritz@gmx.ch 1.1446 # [PATCH] alloc_etherdev for nmclan_cs # # net_device is no longer allocated as part of the driver's private structure, # instead it's allocated via alloc_netdev. compile tested only since no hardware # against 2.5.73-bk # # # -daniel # # ===== nmclan_cs.c 1.14 vs edited ===== # -------------------------------------------- # 03/06/24 daniel.ritz@gmx.ch 1.1447 # [PATCH] alloc_etherdev for smc91c92_cs # # net_device is no longer allocated as part of the driver's private structure, # instead it's allocated via alloc_netdev. compile tested only since no hardware # against 2.5.73-bk # # # -daniel # # ===== smc91c92_cs.c 1.18 vs edited ===== # -------------------------------------------- # 03/06/24 scott.feldman@intel.com 1.1448 # [PATCH] Remove CAP_NET_ADMIN check for SIOCETHTOOL's # # dev_ioctl already checks capable(CAP_NET_ADMIN), so no need to do so in # drivers. # -------------------------------------------- # 03/06/24 shemminger@osdl.org 1.1449 # [PATCH] 2.5.70 - eepro100 - use alloc_etherdev # # Ignore earlier patch -- this one locks and free's as appropriate. # Tested on 2.5.72 with SMP. # # Of course, it begs the question why have two (now three) versions of drivers for # the same hardware... # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1442.1.1 # [USB]: Use linux/dma-mapping.h not asm/dma-mapping.h in kaweth.c # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1442.1.2 # [PCI]: Export pci_enable_device_bars to modules. # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1442.1.3 # [SPARC64]: Update defconfig. # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1442.1.4 # [SERIAL]: Sanitize sparc serial console configuration. # -------------------------------------------- # 03/06/24 davem@nuts.ninka.net 1.1442.1.5 # [SPARC64]: Update defconfig. # -------------------------------------------- # 03/06/25 paulus@samba.org 1.1348.16.8 # PPC32: remove check for ERESTARTNOHAND in syscall return path. # # This error is handled in the signal delivery code and should never be # returned from a syscall unless a signal is pending. Grepping seems to # indicate that that is in fact the case (but not for ERESTARTSYS, but # that is another problem). # -------------------------------------------- # 03/06/25 jgrimm@touki.austin.ibm.com 1.1348.24.2 # [SCTP] Peeled off/accepted sockets not in the right bind_bucket. # # hlist changes caused the peeloff testcase to fail. Investigation shows # that the peeloff sockets is not bound into bind_bucket, so the # bucket has gone away (original socket closed). Fixing this, shows # a problem that inet->num wasn't set on peeled off sockets, so autobind # kicks in creating a new bind_bucket. Ugh. One bug had been # hiding the other one all this time. # # Fix 1) peeledoff/accepted sockets need to have their own socket woven # into the bind_bucket->owner list. 2) Set inet->num, so autobind # doesn't think it needs to kick in. # -------------------------------------------- # 03/06/25 torvalds@home.transmeta.com 1.1442.1.6 # Merge bk://ppc.bkbits.net/for-linus-ppc # into home.transmeta.com:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/26 shemminger@osdl.org 1.1442.2.1 # [NET] remove skb_linearize from igmp.c # -------------------------------------------- # 03/06/26 shemminger@osdl.org 1.1442.1.7 # Merge bk://kernel.bkbits.net/torvalds/linux-2.5 # into osdl.org:/home/jmorris/bk/net/work-2.5 # -------------------------------------------- # 03/06/25 rddunlap@osdl.org 1.1442.3.1 # [PATCH] Unionize IO-APIC registers # # [ Registers of the world, unite! ] # # This makes the IO-APIC data structures use unions, so that we can # cleanly access them both as flat "raw" values, and as the bitmap # sub-entries. # -------------------------------------------- # 03/06/25 jgarzik@redhat.com 1.1450 # [irda] add driver for mips Alchemy Au1000 SIR/FIR # # Submitted by Ralf Baechle <ralf@linux-mips.org> # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1451 # [netdrvr] add driver "meth", for SGI O2 MACE fast eth # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1452 # [netdrvr] sgiseeq update # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1453 # [netdrvr] update ioc3_eth # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1454 # [netdrvr] update declance # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1455 # [netdrvr] au1000_eth update # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1456 # [netdrvr] update sb1250-mac # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1457 # [netdrvr tulip] add mips cobalt support # -------------------------------------------- # 03/06/25 ralf@linux-mips.org 1.1458 # [netdrvr] misc small mips updates # # Add missing CONFIG_TC35805 entry to Kconfig. # Update CONFIG_NET_SB1250_MAC Kconfig entry. # Minor cosmetic updates to gt96100eth. # -------------------------------------------- # 03/06/25 torvalds@home.osdl.org 1.1459 # Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/26 davej@tetrachloride.(none) 1.1348.26.1 # Merge tetrachloride.(none):/mnt/raid/src/kernel/2.5/bk-linus # into tetrachloride.(none):/mnt/raid/src/kernel/2.5/cpufreq # -------------------------------------------- # 03/06/25 willy@debian.org 1.1429.2.4 # [PATCH] PCI: more PCI gubbins # # I noticed we have a couple of redundancies in drivers/pci/Makefile, # have a patch... # -------------------------------------------- # 03/06/25 willy@debian.org 1.1429.2.5 # [PATCH] PCI: fixes for pci/probe.c # # - Combine pci_alloc_primary_bus_parented into pci_scan_bus_parented. # - Move the EXPORT_SYMBOL for pci_root_buses up to its definition. # - Don't EXPORT_SYMBOL pci_scan_bus since it's a static inline. # - Add the pci_domain_nr() to the sysfs name for this bus. # -------------------------------------------- # 03/06/25 greg@kroah.com 1.1429.2.6 # [PATCH] PCI Hotplug: fix core problem with kobject lifespans. # # Added needed release function, now all pci hotplug drivers need to implement # it... # -------------------------------------------- # 03/06/25 greg@kroah.com 1.1429.2.7 # [PATCH] IBM PCI Hotplug: fixes found by sparse # -------------------------------------------- # 03/06/25 greg@kroah.com 1.1429.2.8 # PCI Hotplug: add fake PCI hotplug driver. # # Useful for testing hotplug issues with pci drivers. # -------------------------------------------- # 03/06/25 greg@kroah.com 1.1460 # Merge kroah.com:/home/greg/linux/BK/bleed-2.5 # into kroah.com:/home/greg/linux/BK/pci-2.5 # -------------------------------------------- # 03/06/26 davej@codemonkey.org.uk 1.1348.26.2 # [CPUFREQ] speedstep cleanups. # From Dominik Brodowski. # # - separate functions which might be useful for speedstep-piix4, # speedstep-via or speedstep-bios into a new speedstep-lib.c. # - clean up speedstep-ich as it will only be used for ICH-based chipsets # in future. # - remove now-obsolete speedstep_coppermine parameter # -------------------------------------------- # 03/06/26 davej@codemonkey.org.uk 1.1348.26.3 # [CPUFREQ] Speedstep support for P4M/533 # From Dominik Brodowski. # # Add support for newest "Mobile Pentium 4-M" and the new "Mobile Pentium 4 with # 533 MHz FSB" processors. # -------------------------------------------- # 03/06/26 davej@codemonkey.org.uk 1.1348.26.4 # [CPUFREQ] Silence debug output on centrino speedstep driver. # -------------------------------------------- # 03/06/26 davej@codemonkey.org.uk 1.1348.27.1 # [AGPGART] Add missing pte masking in NVIDIA nForce driver. # Noticed by Marcelo Penna Guerra. # -------------------------------------------- # 03/06/26 shemminger@osdl.org 1.1442.1.8 # [NET][IPMR] ipmr fixes # # These patches fix ip multicast route (ipmr) on 2.5.73. # # 1 - Trivial C99 initialization # 2 - Change functions/variables to static # 3 - Drop and reacquire RTNL in error path # 4 - Use time_after() # 5 - Use alloc_netdev # 6 - Fix OOPS on dropped packets # 7 - Get rid of skb_linearize # # Tested on 8-way SMP by bringing up pimd. # # -------------------------------------------- # 03/06/26 davej@codemonkey.org.uk 1.1348.27.2 # [AGPGART] SiS 655 support. # Needs more testing, especially in x8 mode. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1461 # [PATCH] GCC 2.95.4 needs the spinlock workaround # # From: Mikael Pettersson <mikpe@csd.uu.se> # # 2.5.73 removed the workaround needed to prevent gcc-2.95.x from # miscompiling spinlocks on UP. It turns out that some versions of # gcc-2.95 still do have problems with empty structs, so re-introduce # the workaround. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1462 # [PATCH] show_stack fix # # sysrq-T currently displays the same stack trace for every process. # # Teach show_stack() to look in the passed task_struct first if the caller did # not pass in a stack address. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1463 # [PATCH] setscheduler needs to force a reschedule # # From: Robert Love <rml@tech9.net> # # Basically, the problem is that setscheduler() does not set need_resched # when needed. There are two basic cases where this is needed: # # - the task is running, but now it is no longer the highest # priority task on the rq # - the task is not running, but now it is the highest # priority task on the rq # # In either case, we need to set need_resched to invoke the scheduler. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1464 # [PATCH] misc fixes # # - unused var warning in pnp_add_irq_resource() # # - unused var in fd_mcs.c (Adrian Bunk) # # - remove dead code in i810_main.c (a u8 cannot exceed 255) (Adrian Bunk) # # - don't truncate dma_addr_t's in gdth.c (Jes Sorensen) # # - vgastate.c needs vmalloc.h (Geert Uytterhoeven <geert@linux-m68k.org>) # # - revert bogus test from rd_open() - it was a 2.4 forward-port, and 2.5 # doesn't need it. (The gendisks aren't registered, we cannot get there # anyway). # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1465 # [PATCH] AT_SECURE auxv entry # # From: Stephen Smalley <sds@epoch.ncsc.mil> # # This patch adds an AT_SECURE auxv entry to pass a boolean flag indicating # whether "secure mode" should be enabled (i.e. sanitize the environment, # initial descriptors, etc) and allows each security module to specify the # flag value via a new hook. # # New userland can then simply obey this flag when present rather than # applying other methods of deciding (sample patch for glibc-2.3.2 can be # found at http://www.cs.utah.edu/~sds/glibc-secureexec.patch). # # This change enables security modules like SELinux to request secure mode # upon changes to other security attributes (e.g. capabilities, # roles/domains, etc) in addition to uid/gid changes or even to completely # override the legacy logic. # # The legacy decision algorithm is preserved in the default hook functions # for the dummy and capability security modules. # # Credit for the idea of adding an AT_SECURE auxv entry goes to Roland # McGrath. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1466 # [PATCH] common name for the kernel DSO # # From: David Mosberger <davidm@napali.hpl.hp.com> # # Give the ia32 vsyscall DSO the same name as ia64's. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1467 # [PATCH] get_unmapped_area() speedup # # From: Ingo Molnar # # Apparently our thread-creation performance has gone down the tubes again, # because the mm.free_area_cache search heuristic broke. # # The initial, more naive hole-cache patch helped the testcode in the # beginning. Then after some point glibc started creating a 'small hole' in # the vmas, which hole was _below_ the thread stacks, and which hole thus # prevented the intended operation of the cache. # # The new code solves the problem by relaxing the 'smallest address hole cache' # rule a bit, the cache is now not re-set at every get_unmapped_area() time, # it's only re-set during unmaps. It's also re-set if there are no allocatable # mappings at all - ie. correctness is not affected. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1468 # [PATCH] dentry->d_count fixes: d_invalidate # # From: Maneesh Soni <maneesh@in.ibm.com> # # - d_invalidate() can incorrectly return success instead of returning -EBUSY # as we can have situations where lockless d_lookup has found a dentry # successfully before d_invalidate drops it # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1469 # [PATCH] dentry->d_count fixes: nfs_unlink # # From: Maneesh Soni <maneesh@in.ibm.com> # # - nfs_unlink() can race with lockless d_lookup() as d_lookup() can # successfully lookup a dentry for which nfs_unlink() can assume that no one # else is using and can go ahead and do nfs_safe_remove() on it. By using # per dentry lock, it is solved as we d_lookup() will fail the lookup for # unhashed dentries. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1470 # [PATCH] dentry->d_count fixes: hpfs # # From: Maneesh Soni <maneesh@in.ibm.com> # # - hpfs_unlink() can race with lockless d_lookup(), as we can have situations # where d_lookup() has successfully looked-up a dentry and at the sametime # hpfs_unlink()--->d_drop() has dropped it. Taking the per dentry lock # before checking the d_count in hpfs_unlink() solves this race condition. # -------------------------------------------- # 03/06/26 yoshfuji@linux-ipv6.org 1.1442.1.9 # [IPV6] DAD has to be destined to solicited node mulitcast address. # # Check if DAD is destined for solicited node multicast address # as RFC2461 required. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1471 # [PATCH] workaround for smb_proc_getattr oops # # From: Zwane Mwaikambo <zwane@linuxpower.ca> # # smbfs tends to oops over a null server->ops->getattr in smb_proc_getattr(). # # Urban says: # # In 2.5 the server->ops is initialized when smbfs gets a connection, to # match whatever the server is capable of or not. This happens after the # mount syscall so smbfs is then mounted but not usable. # # Not sure if smb_lookup is always called before any other operation that # uses server->ops. If it is then it would be enough to have a test there. # # Otherwise I will just change all users of server->ops to verify the # pointer first and return -EIO or something. # # Al Viro says (paraphrasing) # # ugh, we need mount2(). # # It doesn't look to me like we'll be getting mount2() in the 2.6 timeframe. # Zwane's patch implement's Urban's workaround. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1472 # [PATCH] Column counting fix in n_tty.c # # From: Chris Heath <chris@heathens.co.nz> # # Here's a column counting bug that was lurking in a corner of n_tty.c. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1473 # [PATCH] normalise node load for NUMA # # From: Andrew Theurer <habanero@us.ibm.com> # # This patch ensures that when node loads are compared, the load value is # normalised. Without this, load balance across nodes of dissimilar cpu # counts can cause unfairness and sometimes lower overall performance. # # For example, a 2 node system with 4 cpus in the first node and 2 cpus in # the second. A workload with 6 running tasks would have 3 tasks running on # one node and 3 on the other, leaving one cpu idle in the first node and two # tasks sharing a cpu in the second node. The patch would ensure that 4 # tasks run in the first node and 2 in the second. # # I ran some kernel compiles comparing this patch on a 2 node 4 cpu/2 cpu # system to show the benefits. Without the patch I got 140 second elapsed # time. With the patch I get 132 seconds (6% better). # # Although it is not very common to have nodes with dissimilar cpu counts, it # is already happening. PPC64 systems with partitioning have this happen, # and I expect it to be more common on ia32 as partitioning becomes more # common. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1474 # [PATCH] compat_sys_old_getrlimit() depends on # # From: David Mosberger <davidm@napali.hpl.hp.com> # # compat_sys_old_getrlimit() depends on sys_old_getrlimit() and the patch # below updates the guarding #ifdef accordingly. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1475 # [PATCH] ext3: fix page lock vs journal_start ranking bug # # ext3_block_truncate_page() is calling grab_cache_page() inside a JBD # transaction. This is wrong, because transactions nest inside lock_page(). # # The deadlock is against shrink_list->ext3_journalled_writepage->journal_start. # # This was not noticed before because we never used to journal writepage() data # in journalled-data mode. And because the deadlock against # generic_file_write() is covered up by i_sem. # # Rework things so that we lock the page prior to starting a transaction. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1476 # [PATCH] ext3: fix memory leak # # We need to unconditionally brelse() the buffer in there, because # journal_remove_journal_head() leaves a ref behind. # # release_buffer_page() does that. Call it all the time because we can usually # strip the buffers and free the page even if it was not marked buffer_freed(). # # Mainly affects data=journal mode # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1477 # [PATCH] correct mail addresses for visws support # # From: Andrey Panin <pazke@donpac.ru> # # this trivial patch changes mailing list address for visws subarch support # along with some occurences of my old email addresses. # -------------------------------------------- # 03/06/26 yoshfuji@linux-ipv6.org 1.1442.1.10 # [IPV6] DAD must not have source link-layer option # # Check if DAD does not have source link-layer address option; # RFC2461 7.1.1. # # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1478 # [PATCH] NCR53C9x compile fix # # From: Geert Uytterhoeven <geert@linux-m68k.org> # # NCR53C9x SCSI: Fix compilation after breakage in 2.5.71 # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1479 # [PATCH] htree: set the dir index bit in the right place # # From: Alex Tomas <bzzz@tmi.comex.ru> # # Don't set the directory's index flag until we know that we're doing ahead # with the directory modification. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1480 # [PATCH] export flush_tlb_all for drm modules # # From: Jan Dittmer <j.dittmer@portrix.net> # # This adds an export for flush_tlb_all to i386_ksyms.c. The drm modules # miss this, when compiling for SMP. # # I changed Jan's patch to use EXPORT_SYMBOL_GPL. # -------------------------------------------- # 03/06/25 akpm@digeo.com 1.1481 # [PATCH] Typo after 8250_cs update (SERIAL) # # From: Francois Romieu <romieu@fr.zoreil.com> # # s/GetConfiguration/GetConfigurationInfo/ # -------------------------------------------- # 03/06/25 torvalds@home.osdl.org 1.1482 # Merge bk://linux-dj.bkbits.net/cpufreq # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/25 torvalds@home.osdl.org 1.1483 # Merge bk://linux-dj.bkbits.net/agpgart # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/25 sfr@canb.auug.org.au 1.1484 # [PATCH] fix type in compat_sys_fcntl64 # # [Pointed out by Bjorn Helgaas via Arun Sharma] # # This fixes an obvious cut and paste error in my original patch. # -------------------------------------------- # 03/06/25 davem@nuts.ninka.net 1.1485 # Merge bk://kernel.bkbits.net/jmorris/net-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/06/25 davem@nuts.ninka.net 1.1486 # [NET]: Define LL_RESERVED_SPACE in terms of HH_DATA_MOD. # -------------------------------------------- # 03/06/25 romieu@fr.zoreil.com 1.1487 # [NETFILTER]: Fix leaks in error paths of ip_recent_ctrl. # -------------------------------------------- # 03/06/25 yoshfuji@linux-ipv6.org 1.1488 # [IPV6]: Inappropriate static variable in net/ipv6/ndisc.c # -------------------------------------------- # 03/06/25 bdschuym@pandora.be 1.1489 # [NETFILTER]: Missing return in arp_packet_match(). # -------------------------------------------- # 03/06/25 bdschuym@pandora.be 1.1490 # [NETFILTER]: Add arptables mangle module. # -------------------------------------------- # 03/06/25 rob@osinvestor.com 1.1484.1.1 # [SPARC]: Fix LIBS_Y. # -------------------------------------------- # 03/06/25 rob@osinvestor.com 1.1484.1.2 # [SPARC]: Do not use __builtin_trap() on sparc until gcc is fixed. # -------------------------------------------- # 03/06/26 davem@nuts.ninka.net 1.1491 # [TCP]: Sanitize initcwnd calculation, add new metrics. # 1) Remove srtt etc. tests in tcp_init_cwnd, was buggy # anyways. # 2) Add RTAX_INITCWMD route metric, use this in tcp_init_cwnd() # if non-zero. # 3) Add RTAX_FEATURES (to enable/disable ECN/SACK/TIMESTAMPS # on a per-route basis), currently unused. # -------------------------------------------- # 03/06/26 yoshfuji@linux-ipv6.org 1.1492 # [IPV6]: Make several ndisc private stuff static. # -------------------------------------------- # 03/06/26 dwmw2@infradead.org 1.1484.2.1 # DiskOnChip Millennium Plus translation layer fixes: # # - Fix geometry reporting. # - Avoid endless loop when deleting a Virtual Unit Chain. # -------------------------------------------- # 03/06/26 dwmw2@infradead.org 1.1484.2.2 # Add missing prototype in drivers/mtd/chips/gen_probe.c # -------------------------------------------- # 03/06/26 torvalds@home.osdl.org 1.1490.1.1 # Merge bk://kernel.bkbits.net/davem/sparc-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/26 ak@suse.de 1.1490.1.2 # [PATCH] x86-64 merge for 2.5.73 # # Bring the x86-64 architecture code uptodate for 2.5.73. # # One problem is that CONFIG_IDE_TASKFILE corrupts file systems on AMD 8111. It # may be worth to disable it in the configuration. # # - Disable 32bit vsyscalls for now until all bugs can be fixed # - Fix warnings # - Fix NULL pointer reference in 32bit ptrace # - Timing fixes from John Stultz # - Sync show_stack prototype # - Sync nmi and floppy.h code (Mikael P.) # - Set proper defines for AGP # - Make Simics work again # - Scale unit in 32bit sysinfo (originally from ppc64) # -------------------------------------------- # 03/06/26 ak@suse.de 1.1490.1.3 # [PATCH] Fix ACPI compilation for 2.5.73 # # Without this patch ACPI won't compile on AMD64 because of mismatched prototypes. # # Andrew stated that this is the way he wants it to be fixed. # -------------------------------------------- # 03/06/26 ak@suse.de 1.1490.1.4 # [PATCH] Change 64bit epoll ABI for AMD64 # # As discussed earlier. The 64bit epoll ABI on AMD64 is changed to # match 32bit. This way we avoid emulation overhead. # # To catch old binaries I allocate new syscall slots. # -------------------------------------------- # 03/06/26 willy@debian.org 1.1490.1.5 # [PATCH] remove *_segments() dummy functions again # # Last November Linus applied a patch to remove the now-unused # *_segments() functions from all architectures ... but some of the newer # architectures escaped and still have them. # -------------------------------------------- # 03/06/26 torvalds@home.osdl.org 1.1490.1.6 # Merge master.kernel.org:/home/dwmw2/BK/mtd-forlinus-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/26 willy@debian.org 1.1490.1.7 # [PATCH] Make SCSI selfcontained # # Move all the SCSI Kconfig bits from arch/*/Kconfig into driver/scsi/Kconfig. # Also add notes about FireWire & USB. # -------------------------------------------- # 03/06/26 greg@kroah.com 1.1490.1.8 # [PATCH] PCI Hotplug: pcihp_skeleton: fix delete bug and add release() callback # -------------------------------------------- # 03/06/26 greg@kroah.com 1.1490.1.9 # [PATCH] PCI Hotplug: acpiphp: add release() callback # -------------------------------------------- # 03/06/26 greg@kroah.com 1.1490.1.10 # [PATCH] PCI Hotplug: cpci: fix delete bug and add release() callback # -------------------------------------------- # 03/06/26 greg@kroah.com 1.1490.1.11 # [PATCH] PCI Hotplug: cpqphp: add release() callback and other minor cleanups. # -------------------------------------------- # 03/06/26 greg@kroah.com 1.1490.1.12 # [PATCH] PCI Hotplug: ibmphp: add release() callback and other minor cleanups # -------------------------------------------- # 03/06/26 willy@debian.org 1.1490.1.13 # [PATCH] PCI: i386/pci/direct.c fixes # # - Request resources before using them # - Don't allocate GFP_KERNEL memory with interrupts disabled # - Split pci_direct_init() into three functions to prevent it from # getting too long. # -------------------------------------------- # 03/06/26 willy@debian.org 1.1490.1.14 # [PATCH] PCI: create pci_name() # # This patch introduces pci_name() and converts slot_name into a pointer to # dev.bus_id. # -------------------------------------------- # 03/06/26 davem@nuts.ninka.net 1.1493 # Merge nuts.ninka.net:/home/davem/src/BK/network-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/06/26 gerg@snapgear.com 1.1490.2.1 # [PATCH] define KCORE_ELF in m68knommu/Kconfnig # # Define missing type for CONFIG_KCORE_ELF in m68knommu/Kconfig. # -------------------------------------------- # 03/06/26 gerg@snapgear.com 1.1490.2.2 # [PATCH] fix do_settimeofday() for 'struct timespec' argument # # Modify m68knommu do_settimeofday() routine to take "struct timespec" # argument, and adjust code to handle nsec size quantities. # -------------------------------------------- # 03/06/26 bcollins@debian.org 1.1490.2.3 # [PATCH] Update IEEE1394 (r972) # # IEEE1394 : Kbuildify oui2c. # ALL : C construct cleanups, macro namespace cleanups. # ETH1394 : Limited multicast support. Minor fixes for IPv4 interop. # ETH1394 : Add ethtool support. # -------------------------------------------- # 03/06/27 yoshfuji@linux-ipv6.org 1.1490.3.1 # [IPV6] Fixed fragment check in ip6_output.c:ip6_fragment() # # MTU / alignment check in ip6_fragment() was wrong; # first_len was not correct. # # -------------------------------------------- # 03/06/27 ahaas@airmail.net 1.1490.3.2 # [NET] Remove some 0 initializers. # # These small patches remove a number of '.maxlen = 0,' initializers. # # -------------------------------------------- # 03/06/27 herbert@gondor.apana.org.au 1.1490.3.3 # [XFRM] Set port/proto in acquire messages. # # Also append policy spec to acquire message. # -------------------------------------------- # 03/06/26 greg@kroah.com 1.1490.1.15 # PCI Hotplug: acpiphp: stupid typo fixes. # -------------------------------------------- # 03/06/26 torvalds@home.osdl.org 1.1490.1.16 # Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/26 davem@nuts.ninka.net 1.1494 # [NET]: Kill skb_linearize() and bogus feature flag settings in eth1394.c # -------------------------------------------- # 03/06/26 davem@nuts.ninka.net 1.1495 # Merge bk://kernel.bkbits.net/jmorris/net-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/06/26 davem@nuts.ninka.net 1.1496 # Merge http://linux-lksctp.bkbits.net/lksctp-2.5 # into nuts.ninka.net:/home/davem/src/BK/net-2.5 # -------------------------------------------- # 03/06/27 davem@nuts.ninka.net 1.1497 # [TCP]: Handle lack of cached dst in tcp_init_cwnd(). # -------------------------------------------- # 03/06/27 davem@nuts.ninka.net 1.1498 # [TCP]: If we have a lot of time-wait sockets to kill, do it via workqueue. # -------------------------------------------- # 03/06/27 davem@nuts.ninka.net 1.1499 # Merge Ben's and my fixes. # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.17 # [PATCH] Use new svc_export_show to implement e_show for /proc/fs/nfs/exports # # Also remove the path_buf that was passed around for # /proc/fs/nfs/exports as the existance of seq_path removes the need # for this. # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.18 # [PATCH] Remove path buffer passed around by cache_show routines # # this was need for paths, but now we have seq_path... # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.19 # [PATCH] NFSv4 server OPEN_CONFIRM # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # Add OPEN_CONFIRM functionality to the nfsv4 server, including a # preprocess_seqid_op function that will be used in subsequent patches. # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.20 # [PATCH] NFSv4 server Close state # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # Add share state processing to nfsd4_close. it includes some more # debug counters. # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.21 # [PATCH] NFSv4 server - open-downgrade # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # Add the opendowngrade call with share state processing. it includes # nfs4_preprocess_stateid_op() which will be used in read and write # state processing. # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.22 # [PATCH] NFSv4 server - Read "share" state # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # this patch adds share state processing to nfsd4_read(). # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.23 # [PATCH] NFSv4 server - Write "share" state # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # this patch adds share state processing to nfsd4_write(). # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.24 # [PATCH] NFSv4 server - setattr share state # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # this patch adds share state processing to nfsd4_setattr(). # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.25 # [PATCH] NFSv4 server - missing locking # # From: "William A.(Andy) Adamson" <andros@citi.umich.edu> # # sorry. i forgot to lock the nfsv4 state in nfsd4_read, nfsd4_write, and # nfsd4_setattr. # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.26 # [PATCH] NFSv4 server - Removed duplicate #define # # Already defined in state.h # -------------------------------------------- # 03/06/27 neilb@cse.unsw.edu.au 1.1490.1.27 # [PATCH] Provoide refrigerator support for nfsd # # Call refrigerator() in svc_recv, so it is there for nfsd and # no longer needed explicitly in lockd. # -------------------------------------------- # 03/06/27 randy.dunlap@verizon.net 1.1490.1.28 # [PATCH] remove IO APIC newline # # This patch is to 2.5.73-bk4 and is purely cosmetic. Please apply. # It removes the blank line after "testing the IO APIC....": # -------------------------------------------- # 03/06/27 david@gibson.dropbear.id.au 1.1490.1.29 # [PATCH] Fix compile with !CONFIG_VT # # Architectures using the generic 32/64-bit ioctl() compatibility shims # will get a link error if CONFIG_VT is not defined, since the # compatbility ioctl() code calls functions in drivers/char/vt.c which # is only included in the build if CONFIG_VT is set. # # This fixes the compile with a couple of #ifdefs: # -------------------------------------------- # 03/06/27 gerg@snapgear.com 1.1490.1.30 # [PATCH] fix arguments of show_stack() # # Fix the m68knommu version of show_stack(). It expects the task as an # argument. # -------------------------------------------- # 03/06/27 gerg@snapgear.com 1.1490.1.31 # [PATCH] conditional ROMfs copy for M5206eLITE board # # Make the ROMfs copy in the startup code for Motorola/M5206eLITE board # conditional on actually using a ROMfs setup. # -------------------------------------------- # 03/06/27 gerg@snapgear.com 1.1490.1.32 # [PATCH] conditional ROMfs copy for NETtel/5272 board # # Make the ROMfs copy in the startup code for NETtel/5272 board # conditional on actually using a ROMfs setup. # -------------------------------------------- # 03/06/27 rusty@rustcorp.com.au 1.1490.1.33 # [PATCH] Use Local Percpu Macros for Local Percpu Variables # # In general, it is more better to use get_cpu_var() and __get_cpu_var() # to access per-cpu variables on this CPU than to use smp_processor_id() # and per_cpu(). In the current default implemention they are equivalent, # but on IA64 the former is already faster, and other archs will follow. # -------------------------------------------- # 03/06/27 torvalds@home.osdl.org 1.1500 # Merge bk://kernel.bkbits.net/davem/net-2.5 # into home.osdl.org:/home/torvalds/v2.5/linux # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1501 # [PATCH] s390: base fixes # # - Remove unused variables from smp.c. # - Reserve system call number 110 for sys_lookup_dcache. # - Fix show_trace. # - Remove superfluous asm include file. # - Add statfs64 structure. # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1502 # [PATCH] s390: 31 bit compat. # # - Add missing includes to compat_ioctl.c. # - Fix 32 bit emulation of sys_settimeofday. # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1503 # [PATCH] s390: common i/o layer. # # - Make ccwgroup online attribute consistent with ccw online attribute. # - Add link incident record handling to channel subsystem code. # - Do path grouping only if the device driver explicitly requests it. # - Fix multicast or broadcast flood ping hand on HiperSockets. # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1504 # [PATCH] s390: dasd driver. # # - Simplify long busy condition handling, add quiesce/resume ioctl. # - Add sense data area to reserve/release/steal_lock ccw-chains. # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1505 # [PATCH] s390: set module owner. # # Pass correct argument to SET_MODULE_OWNER. # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1506 # [PATCH] s390: typos. # # Fix typos. # -------------------------------------------- # 03/06/27 schwidefsky@de.ibm.com 1.1507 # [PATCH] s390: tty3215_init. # # Add return statement to tty init function of 3215 driver. # -------------------------------------------- # 03/06/27 willy@debian.org 1.1508 # [PATCH] [KCONFIG] Make cdrom Kconfig selfcontained # # This patch moves all the duplicated cdrom Kconfig bits from arch/*/Kconfig # to drivers/cdrom/Kconfig # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1509 # [PATCH] ide: TCQ initialization fixes # # - do not enable TCQ in ide_init_drive(), its too early # - enable TCQ in __ide_dma_on() only if CONFIG_BLK_DEV_IDE_TCQ_DEFAULT=y # - try to enable TCQ only on disk drives # - correct check for two drives on one channel # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1510 # [PATCH] ide: fix IRQ handler returns # # Make the IDE driver return the proper status return # for unhandled interrupts. # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1511 # [PATCH] ide: fix drive->unmask handling for taskfile PIO # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1512 # [PATCH] ide: proper allocation of hwif->io_ports resources # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1513 # [PATCH] ide: tiny cleanup of "ideX=ata66" parameter handling in ide_setup() # # hwif->udma_four is always preset to 0 # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1514 # [PATCH] ide: remove dead code from ide_raw_build_sglist() # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1515 # [PATCH] ide: remove dead and broken ide_diag_taskfile() variant # -------------------------------------------- # 03/06/27 B.Zolnierkiewicz@elka.pw.edu.pl 1.1516 # [PATCH] ide: tiny cleanup of ide_init(), it is called only _once_ # -------------------------------------------- # diff -Nru a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl --- a/Documentation/DocBook/gadget.tmpl Fri Jun 27 14:19:56 2003 +++ b/Documentation/DocBook/gadget.tmpl Fri Jun 27 14:19:56 2003 @@ -6,31 +6,32 @@ <edition>02 June 2003</edition> <legalnotice> - <para>Permission is granted to copy, distribute, and/or modify - this document under the terms of the GNU Free Documentation - License, version 1.2, or any later version published by the - Free Software Foundation; with the Invariant Sections being - the "GNU Free Documentation License", - no Front-Cover Texts, - and - no Back-Cover Texts. - </para> - - <para>This documentation is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU Free Documentation License for more details. - </para> - - <para>Note that certain sections of this document are merged - into Linux kernel source code. - That content is the bulk of - <xref linkend="core" /> and - <xref linkend="utils" />, - where the "GNU Free Documentation License" is identified - as an alternate licence for its documentation. - </para> - + <para> + This documentation 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. + </para> + + <para> + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + </para> + + <para> + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + </para> + + <para> + For more details see the file COPYING in the source + distribution of Linux. + </para> </legalnotice> <copyright> <year>2003</year> @@ -325,9 +326,10 @@ of one or more "packets", and packet boundaries are visible to drivers. Compared to RS-232 serial protocols, USB resembles synchronous protocols like HDLC -(N bytes per frame, multipoint addressing from the host) +(N bytes per frame, multipoint addressing, host as the primary +station and devices as secondary stations) more than asynchronous ones -(tty style, like 8 bytes, no parity, one stop bit). +(tty style: 8 data bits per frame, no parity, one stop bit). So for example the controller drivers won't buffer two single byte writes into a single two-byte USB IN packet, although gadget drivers may do so when they implement @@ -527,438 +529,6 @@ </chapter> - -<appendix id="gfdl"> -<title>GNU Free Documentation License</title> -<subtitle>Version 1.2, November 2002</subtitle> - -<blockquote id="fsf-copyright"> - <para>Copyright (C) 2000,2001,2002 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed.</para> -</blockquote> - -<sect1 id="gfdl-0"><title>PREAMBLE</title> - -<para>The purpose of this License is to make a manual, textbook, or -other functional and useful document "free" in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, with -or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible for -modifications made by others.</para> - -<para>This License is a kind of "copyleft", which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft license -designed for free software.</para> - -<para>We have designed this License in order to use it for manuals for -free software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; it -can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference.</para> -</sect1> - -<sect1 id="gfdl-1"><title>APPLICABILITY AND DEFINITIONS</title> - -<para id="gfdl-doc">This License applies to any manual or other work, in -any medium, that contains a notice placed by the copyright holder saying -it can be distributed under the terms of this License. Such a notice -grants a world-wide, royalty-free license, unlimited in duration, to use -that work under the conditions stated herein. The "Document", below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as "you". You accept the license if you -copy, modify or distribute the work in a way requiring permission under -copyright law.</para> - -<para id="gfdl-mod-ver">A "Modified Version" of the Document means any -work containing the Document or a portion of it, either copied verbatim, -or with modifications and/or translated into another language.</para> - -<para id="gfdl-secnd-sect">A "Secondary Section" is a named appendix or -a front-matter section of the Document that deals exclusively with the -relationship of the publishers or authors of the Document to the -Document's overall subject (or to related matters) and contains nothing -that could fall directly within that overall subject. (Thus, if the -Document is in part a textbook of mathematics, a Secondary Section may -not explain any mathematics.) The relationship could be a matter of -historical connection with the subject or with related matters, or of -legal, commercial, philosophical, ethical or political position -regarding them.</para> - -<para id="gfdl-inv-sect">The "Invariant Sections" are certain Secondary -Sections whose titles are designated, as being those of Invariant -Sections, in the notice that says that the Document is released under -this License. If a section does not fit the above definition of -Secondary then it is not allowed to be designated as Invariant. The -Document may contain zero Invariant Sections. If the Document does not -identify any Invariant Sections then there are none.</para> - -<para id="gfdl-cov-text">The "Cover Texts" are certain short passages of -text that are listed, as Front-Cover Texts or Back-Cover Texts, in the -notice that says that the Document is released under this License. A -Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at -most 25 words.</para> - -<para id="gfdl-transparent">A "Transparent" copy of the Document means a -machine-readable copy, represented in a format whose specification is -available to the general public, that is suitable for revising the -document straightforwardly with generic text editors or (for images -composed of pixels) generic paint programs or (for drawings) some widely -available drawing editor, and that is suitable for input to text -formatters or for automatic translation to a variety of formats suitable -for input to text formatters. A copy made in an otherwise Transparent -file format whose markup, or absence of markup, has been arranged to -thwart or discourage subsequent modification by readers is not -Transparent. An image format is not Transparent if used for any -substantial amount of text. A copy that is not "Transparent" is called -"Opaque".</para> - -<para>Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, LaTeX input format, SGML or -XML using a publicly available DTD, and standard-conforming simple HTML, -PostScript or PDF designed for human modification. Examples of -transparent image formats include PNG, XCF and JPG. Opaque formats -include proprietary formats that can be read and edited only by -proprietary word processors, SGML or XML for which the DTD and/or -processing tools are not generally available, and the machine-generated -HTML, PostScript or PDF produced by some word processors for output -purposes only.</para> - -<para id="gfdl-title-page">The "Title Page" means, for a printed book, -the title page itself, plus such following pages as are needed to hold, -legibly, the material this License requires to appear in the title page. -For works in formats which do not have any title page as such, "Title -Page" means the text near the most prominent appearance of the work's -title, preceding the beginning of the body of the text.</para> - -<para id="gfdl-entitled">A section "Entitled XYZ" means a named subunit -of the Document whose title either is precisely XYZ or contains XYZ in -parentheses following text that translates XYZ in another language. -(Here XYZ stands for a specific section name mentioned below, such as -"Acknowledgements", "Dedications", "Endorsements", or "History".) To -"Preserve the Title" of such a section when you modify the Document -means that it remains a section "Entitled XYZ" according to this -definition.</para> - -<para>The Document may include Warranty Disclaimers next to the notice -which states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this License, -but only as regards disclaiming warranties: any other implication that -these Warranty Disclaimers may have is void and has no effect on the -meaning of this License.</para> -</sect1> - -<sect1 id="gfdl-2"><title>VERBATIM COPYING</title> - -<para>You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies to -the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further copying -of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. -</para> - -<para>You may also lend copies, under the same conditions stated above, -and you may publicly display copies.</para> -</sect1> - -<sect1 id="gfdl-3"><title>COPYING IN QUANTITY</title> - -<para>If you publish printed copies (or copies in media that commonly -have printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover Texts: -Front-Cover Texts on the front cover, and Back-Cover Texts on the back -cover. Both covers must also clearly and legibly identify you as the -publisher of these copies. The front cover must present the full title -with all words of the title equally prominent and visible. You may add -other material on the covers in addition. Copying with changes limited -to the covers, as long as they preserve the title of the Document and -satisfy these conditions, can be treated as verbatim copying in other -respects.</para> - -<para>If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages.</para> - -<para>If you publish or distribute Opaque copies of the Document -numbering more than 100, you must either include a machine-readable -Transparent copy along with each Opaque copy, or state in or with each -Opaque copy a computer-network location from which the general -network-using public has access to download using public-standard -network protocols a complete Transparent copy of the Document, free of -added material. If you use the latter option, you must take reasonably -prudent steps, when you begin distribution of Opaque copies in quantity, -to ensure that this Transparent copy will remain thus accessible at the -stated location until at least one year after the last time you -distribute an Opaque copy (directly or through your agents or retailers) -of that edition to the public.</para> - -<para>It is requested, but not required, that you contact the authors of -the Document well before redistributing any large number of copies, to -give them a chance to provide you with an updated version of the -Document.</para> -</sect1> - -<sect1 id="gfdl-4"><title>MODIFICATIONS</title> - -<para>You may copy and distribute a Modified Version of the Document -under the conditions of sections 2 and 3 above, provided that you -release the Modified Version under precisely this License, with the -Modified Version filling the role of the Document, thus licensing -distribution and modification of the Modified Version to whoever -possesses a copy of it. In addition, you must do these things in the -Modified Version:</para> - -<orderedlist id="gfdl-modif-cond" numeration="upperalpha"> -<listitem><simpara>Use in the Title Page (and on the covers, if any) a - title distinct from that of the Document, and from those of previous - versions (which should, if there were any, be listed in the History - section of the Document). You may use the same title as a previous - version if the original publisher of that version gives permission. -</simpara></listitem> -<listitem><simpara>List on the Title Page, as authors, one or more - persons or entities responsible for authorship of the modifications in - the Modified Version, together with at least five of the principal - authors of the Document (all of its principal authors, if it has fewer - than five), unless they release you from this requirement. -</simpara></listitem> -<listitem><simpara>State on the Title page the name of the publisher of - the Modified Version, as the publisher.</simpara></listitem> -<listitem><simpara>Preserve all the copyright notices of the Document. -</simpara></listitem> -<listitem><simpara>Add an appropriate copyright notice for your - modifications adjacent to the other copyright notices. -</simpara></listitem> -<listitem><simpara>Include, immediately after the copyright notices, a - license notice giving the public permission to use the Modified - Version under the terms of this License, in the form shown in the - <link linkend="gfdl-addendum">Addendum</link> below. -</simpara></listitem> -<listitem><simpara>Preserve in that license notice the full lists of - Invariant Sections and required Cover Texts given in the Document's - license notice.</simpara></listitem> -<listitem><simpara>Include an unaltered copy of this License. -</simpara></listitem> -<listitem><simpara>Preserve the section Entitled "History", Preserve its - Title, and add to it an item stating at least the title, year, new - authors, and publisher of the Modified Version as given on the Title - Page. If there is no section Entitled "History" in the Document, - create one stating the title, year, authors, and publisher of the - Document as given on its Title Page, then add an item describing the - Modified Version as stated in the previous sentence. -</simpara></listitem> -<listitem><simpara>Preserve the network location, if any, given in the - Document for public access to a Transparent copy of the Document, and - likewise the network locations given in the Document for previous - versions it was based on. These may be placed in the "History" - section. You may omit a network location for a work that was - published at least four years before the Document itself, or if the - original publisher of the version it refers to gives permission. -</simpara></listitem> -<listitem><simpara>For any section Entitled "Acknowledgements" or - "Dedications", Preserve the Title of the section, and preserve in the - section all the substance and tone of each of the contributor - acknowledgements and/or dedications given therein. -</simpara></listitem> -<listitem><simpara>Preserve all the Invariant Sections of the Document, - unaltered in their text and in their titles. Section numbers or the - equivalent are not considered part of the section titles. -</simpara></listitem> -<listitem><simpara>Delete any section Entitled "Endorsements". - Such a section may not be included in the Modified Version. -</simpara></listitem> -<listitem><simpara>Do not retitle any existing section to be Entitled - "Endorsements" or to conflict in title with any Invariant Section. -</simpara></listitem> -<listitem><simpara>Preserve any Warranty Disclaimers. -</simpara></listitem> -</orderedlist> - -<para>If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles.</para> - -<para>You may add a section Entitled "Endorsements", provided it -contains nothing but endorsements of your Modified Version by various -parties--for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard.</para> - -<para>You may add a passage of up to five words as a Front-Cover Text, -and a passage of up to 25 words as a Back-Cover Text, to the end of the -list of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or through -arrangements made by) any one entity. If the Document already includes -a cover text for the same cover, previously added by you or by -arrangement made by the same entity you are acting on behalf of, you may -not add another; but you may replace the old one, on explicit permission -from the previous publisher that added the old one.</para> - -<para>The author(s) and publisher(s) of the Document do not by this -License give permission to use their names for publicity for or to -assert or imply endorsement of any Modified Version.</para> -</sect1> - -<sect1 id="gfdl-5"><title>COMBINING DOCUMENTS</title> - -<para>You may combine the Document with other documents released under -this License, under the terms defined in <link linkend="gfdl-4">section -4</link> above for modified versions, provided that you include in the -combination all of the Invariant Sections of all of the original -documents, unmodified, and list them all as Invariant Sections of your -combined work in its license notice, and that you preserve all their -Warranty Disclaimers.</para> - -<para>The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by adding -at the end of it, in parentheses, the name of the original author or -publisher of that section if known, or else a unique number. Make the -same adjustment to the section titles in the list of Invariant Sections -in the license notice of the combined work.</para> - -<para>In the combination, you must combine any sections Entitled -"History" in the various original documents, forming one section -Entitled "History"; likewise combine any sections Entitled -"Acknowledgements", and any sections Entitled "Dedications". You must -delete all sections Entitled "Endorsements".</para> -</sect1> - -<sect1 id="gfdl-6"><title>COLLECTIONS OF DOCUMENTS</title> - -<para>You may make a collection consisting of the Document and other -documents released under this License, and replace the individual copies -of this License in the various documents with a single copy that is -included in the collection, provided that you follow the rules of this -License for verbatim copying of each of the documents in all other -respects.</para> - -<para>You may extract a single document from such a collection, and -distribute it individually under this License, provided you insert a -copy of this License into the extracted document, and follow this -License in all other respects regarding verbatim copying of that -document.</para> -</sect1> - -<sect1 id="gfdl-7"><title>AGGREGATION WITH INDEPENDENT WORKS</title> - -<para>A compilation of the Document or its derivatives with other -separate and independent documents or works, in or on a volume of a -storage or distribution medium, is called an "aggregate" if the -copyright resulting from the compilation is not used to limit the legal -rights of the compilation's users beyond what the individual works -permit. When the Document is included an aggregate, this License does -not apply to the other works in the aggregate which are not themselves -derivative works of the Document.</para> - -<para>If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on covers -that bracket the Document within the aggregate, or the electronic -equivalent of covers if the Document is in electronic form. Otherwise -they must appear on printed covers that bracket the whole -aggregate.</para> -</sect1> - -<sect1 id="gfdl-8"><title>TRANSLATION</title> - -<para>Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between the -translation and the original version of this License or a notice or -disclaimer, the original version will prevail.</para> - -<para>If a section in the Document is Entitled "Acknowledgements", -"Dedications", or "History", the requirement (section 4) to Preserve its -Title (section 1) will typically require changing the actual -title.</para> -</sect1> - -<sect1 id="gfdl-9"><title>TERMINATION</title> - -<para>You may not copy, modify, sublicense, or distribute the Document -except as expressly provided for under this License. Any other attempt -to copy, modify, sublicense or distribute the Document is void, and will -automatically terminate your rights under this License. However, -parties who have received copies, or rights, from you under this License -will not have their licenses terminated so long as such parties remain -in full compliance.</para> -</sect1> - -<sect1 id="gfdl-10"><title>FUTURE REVISIONS OF THIS LICENSE</title> - -<para>The Free Software Foundation may publish new, revised versions of -the GNU Free Documentation License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in -detail to address new problems or concerns. See -http://www.gnu.org/copyleft/.</para> - -<para>Each version of the License is given a distinguishing version -number. If the Document specifies that a particular numbered version of -this License "or any later version" applies to it, you have the option -of following the terms and conditions either of that specified version -or of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation.</para> -</sect1> - -<sect1 id="gfdl-addendum"><title>ADDENDUM: How to use this License for - your documents</title> - -<para>To use this License in a document you have written, include a copy -of the License in the document and put the following copyright and -license notices just after the title page:</para> - -<blockquote id="copyright-sample"><para> - Copyright (c) YEAR YOUR NAME. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.2 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. - A copy of the license is included in the section entitled "GNU - Free Documentation License". -</para></blockquote> - -<para>If you have Invariant Sections, Front-Cover Texts and Back-Cover -Texts, replace the "with...Texts." line with this:</para> - -<blockquote id="inv-cover-sample"><para> - with the Invariant Sections being LIST THEIR TITLES, with the - Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. -</para></blockquote> - -<para>If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation.</para> - -<para>If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of free -software license, such as the GNU General Public License, to permit -their use in free software.</para> -</sect1> -</appendix> </book> <!-- diff -Nru a/Documentation/cpu-freq/user-guide.txt b/Documentation/cpu-freq/user-guide.txt --- a/Documentation/cpu-freq/user-guide.txt Fri Jun 27 14:19:53 2003 +++ b/Documentation/cpu-freq/user-guide.txt Fri Jun 27 14:19:53 2003 @@ -56,19 +56,15 @@ AMD mobile Duron AMD mobile Athlon Cyrix Media GXm -Intel mobile PIII [*] and Intel mobile PIII-M on certain chipsets +Intel mobile PIII and Intel mobile PIII-M on certain chipsets Intel Pentium 4, Intel Xeon Intel Pentium M (Centrino) National Semiconductors Geode GX Transmeta Crusoe VIA Cyrix 3 / C3 -various processors on some ACPI 2.0-compatible systems [**] +various processors on some ACPI 2.0-compatible systems [*] -[*] only certain Intel mobile PIII processors are supported. If you -know that you own a speedstep-capable processor, pass the option -"speedstep_coppermine=1" to the module speedstep.o - -[**] Only if "ACPI Processor Performance States" are available +[*] Only if "ACPI Processor Performance States" are available to the ACPI<->BIOS interface. diff -Nru a/Documentation/pci.txt b/Documentation/pci.txt --- a/Documentation/pci.txt Fri Jun 27 14:19:56 2003 +++ b/Documentation/pci.txt Fri Jun 27 14:19:56 2003 @@ -155,17 +155,11 @@ VENDOR_ID or DEVICE_ID. This allows searching for any device from a specific vendor, for example. - In case you need to decide according to some more complex criteria, -you can walk the list of all known PCI devices yourself: - - struct pci_dev *dev; - pci_for_each_dev(dev) { - ... do anything you want with dev ... - } - -For compatibility with device ordering in older kernels, you can also -use pci_for_each_dev_reverse(dev) for walking the list in the opposite -direction. +Note that these functions are not hotplug-safe. Their hotplug-safe +replacements are pci_get_device(), pci_get_class() and pci_get_subsys(). +They increment the reference count on the pci_dev that they return. +You must eventually (possibly at module unload) decrement the reference +count on these devices by calling pci_dev_put(). 3. Enabling devices @@ -193,6 +187,10 @@ string by pcibios_strerror. Most drivers expect that accesses to valid PCI devices don't fail. + If you don't have a struct pci_dev available, you can call +pci_bus_(read|write)_config_(byte|word|dword) to access a given device +and function on that bus. + If you access fields in the standard portion of the config header, please use symbolic names of locations and bits declared in <linux/pci.h>. @@ -253,14 +251,23 @@ 8. Obsolete functions ~~~~~~~~~~~~~~~~~~~~~ -There are several functions kept only for compatibility with old drivers -not updated to the new PCI interface. Please don't use them in new code. +There are several functions which you might come across when trying to +port an old driver to the new PCI interface. They are no longer present +in the kernel as they aren't compatible with hotplug or PCI domains or +having sane locking. -pcibios_present() Since ages, you don't need to test presence - of PCI subsystem when trying to talk with it. +pcibios_present() and Since ages, you don't need to test presence +pci_present() of PCI subsystem when trying to talk to it. If it's not there, the list of PCI devices is empty and all functions for searching for devices just return NULL. pcibios_(read|write)_* Superseded by their pci_(read|write)_* counterparts. pcibios_find_* Superseded by their pci_find_* counterparts. +pci_for_each_dev() Superseded by pci_find_device() +pci_for_each_dev_reverse() Superseded by pci_find_device_reverse() +pci_for_each_bus() Superseded by pci_find_next_bus() +pci_find_device() Superseded by pci_get_device() +pci_find_subsys() Superseded by pci_get_subsys() +pcibios_find_class() Superseded by pci_find_class() +pci_(read|write)_*_nodev() Superseded by pci_bus_(read|write)_*() diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Fri Jun 27 14:19:58 2003 +++ b/MAINTAINERS Fri Jun 27 14:19:58 2003 @@ -1628,8 +1628,8 @@ SGI VISUAL WORKSTATION 320 AND 540 P: Andrey Panin -M: pazke@orbita1.ru -L: linux-visws@lists.sf.net +M: pazke@donpac.ru +L: linux-visws-devel@lists.sf.net W: http://linux-visws.sf.net S: Maintained for 2.5. diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig --- a/arch/alpha/Kconfig Fri Jun 27 14:20:00 2003 +++ b/arch/alpha/Kconfig Fri Jun 27 14:20:00 2003 @@ -665,33 +665,8 @@ source "drivers/ide/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" -endmenu - if PCI source "drivers/message/fusion/Kconfig" endif @@ -704,41 +679,7 @@ source "drivers/isdn/Kconfig" - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - source "drivers/cdrom/Kconfig" - -endmenu source "drivers/input/Kconfig" diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig Fri Jun 27 14:19:57 2003 +++ b/arch/arm/Kconfig Fri Jun 27 14:19:57 2003 @@ -898,32 +898,7 @@ source "drivers/ide/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "drivers/ieee1394/Kconfig" diff -Nru a/arch/arm26/Kconfig b/arch/arm26/Kconfig --- a/arch/arm26/Kconfig Fri Jun 27 14:19:57 2003 +++ b/arch/arm26/Kconfig Fri Jun 27 14:19:57 2003 @@ -364,31 +364,7 @@ endmenu -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "drivers/isdn/Kconfig" diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig --- a/arch/cris/Kconfig Fri Jun 27 14:20:03 2003 +++ b/arch/cris/Kconfig Fri Jun 27 14:20:03 2003 @@ -533,33 +533,8 @@ source "drivers/ide/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" -endmenu - source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" @@ -574,41 +549,7 @@ source "drivers/telephony/Kconfig" - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - source "drivers/cdrom/Kconfig" - -endmenu # # input before char - char/joystick depends on it. As does USB. diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Fri Jun 27 14:19:53 2003 +++ b/arch/i386/Kconfig Fri Jun 27 14:19:53 2003 @@ -1206,69 +1206,9 @@ source "drivers/ide/Kconfig" - -menu "SCSI device support" - -config SCSI - tristate "SCSI device support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" -endmenu - - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - depends on ISA - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - source "drivers/cdrom/Kconfig" - -endmenu source "drivers/md/Kconfig" diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Fri Jun 27 14:19:54 2003 +++ b/arch/i386/kernel/Makefile Fri Jun 27 14:19:54 2003 @@ -47,7 +47,7 @@ cmd_syscall = $(CC) -nostdlib $(SYSCFLAGS_$(@F)) \ -Wl,-T,$(filter-out FORCE,$^) -o $@ -vsyscall-flags = -shared -s -Wl,-soname=linux-vsyscall.so.1 +vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 SYSCFLAGS_vsyscall-sysenter.so = $(vsyscall-flags) SYSCFLAGS_vsyscall-int80.so = $(vsyscall-flags) diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c --- a/arch/i386/kernel/apic.c Fri Jun 27 14:20:06 2003 +++ b/arch/i386/kernel/apic.c Fri Jun 27 14:20:06 2003 @@ -616,7 +616,7 @@ goto no_apic; case X86_VENDOR_INTEL: if (boot_cpu_data.x86 == 6 || - (boot_cpu_data.x86 == 15 && cpu_has_apic) || + boot_cpu_data.x86 == 15 || (boot_cpu_data.x86 == 5 && cpu_has_apic)) break; goto no_apic; diff -Nru a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig --- a/arch/i386/kernel/cpu/cpufreq/Kconfig Fri Jun 27 14:19:54 2003 +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig Fri Jun 27 14:19:54 2003 @@ -123,6 +123,11 @@ If in doubt, say N. +config X86_SPEEDSTEP_LIB + tristate + depends on X86_SPEEDSTEP_ICH + default X86_SPEEDSTEP_ICH + config X86_P4_CLOCKMOD tristate "Intel Pentium 4 clock modulation" depends on CPU_FREQ_TABLE diff -Nru a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile --- a/arch/i386/kernel/cpu/cpufreq/Makefile Fri Jun 27 14:19:56 2003 +++ b/arch/i386/kernel/cpu/cpufreq/Makefile Fri Jun 27 14:19:56 2003 @@ -8,6 +8,7 @@ obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi.o obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o +obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o ifdef CONFIG_X86_ACPI_CPUFREQ ifdef CONFIG_ACPI_DEBUG diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c Fri Jun 27 14:19:55 2003 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c Fri Jun 27 14:19:55 2003 @@ -29,7 +29,7 @@ #define PFX "speedstep-centrino: " #define MAINTAINER "Jeremy Fitzhardinge <jeremy@goop.org>" -#define CENTRINO_DEBUG +/*#define CENTRINO_DEBUG*/ #ifdef CENTRINO_DEBUG #define dprintk(msg...) printk(msg) diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c --- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c Fri Jun 27 14:19:30 2003 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c Fri Jun 27 14:19:30 2003 @@ -1,6 +1,4 @@ /* - * $Id: speedstep.c,v 1.70 2003/02/22 10:23:46 db Exp $ - * * (C) 2001 Dave Jones, Arjan van de ven. * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de> * @@ -27,46 +25,32 @@ #include <linux/pci.h> #include <linux/slab.h> -#include <asm/msr.h> +#include "speedstep-lib.h" + /* speedstep_chipset: * It is necessary to know which chipset is used. As accesses to * this device occur at various places in this module, we need a * static struct pci_dev * pointing to that device. */ -static unsigned int speedstep_chipset; -static struct pci_dev *speedstep_chipset_dev; +static struct pci_dev *speedstep_chipset_dev; -#define SPEEDSTEP_CHIPSET_ICH2M 0x00000002 -#define SPEEDSTEP_CHIPSET_ICH3M 0x00000003 -#define SPEEDSTEP_CHIPSET_ICH4M 0x00000004 /* speedstep_processor */ -static unsigned int speedstep_processor = 0; -static int speedstep_coppermine = 0; - -#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000001 /* Coppermine core */ -#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000002 /* Tualatin core */ -#define SPEEDSTEP_PROCESSOR_P4M 0x00000003 /* P4-M with 100 MHz FSB */ +static unsigned int speedstep_processor = 0; -/* speedstep_[low,high]_freq +/* * There are only two frequency states for each processor. Values * are in kHz for the time being. */ -#define SPEEDSTEP_HIGH 0x00000000 -#define SPEEDSTEP_LOW 0x00000001 - static struct cpufreq_frequency_table speedstep_freqs[] = { {SPEEDSTEP_HIGH, 0}, {SPEEDSTEP_LOW, 0}, {0, CPUFREQ_TABLE_END}, }; -#define speedstep_low_freq speedstep_freqs[SPEEDSTEP_LOW].frequency -#define speedstep_high_freq speedstep_freqs[SPEEDSTEP_HIGH].frequency - /* DEBUG * Define it if you want verbose debug output, e.g. for bug reporting @@ -80,149 +64,82 @@ #endif - -/********************************************************************* - * LOW LEVEL CHIPSET INTERFACE * - *********************************************************************/ - -/** - * speedstep_get_state - read the current SpeedStep state - * @state: Speedstep state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) - * - * Tries to read the SpeedStep state. Returns -EIO when there has been - * trouble to read the status or write to the control register, -EINVAL - * on an unsupported chipset, and zero on success. - */ -static int speedstep_get_state (unsigned int *state) -{ - unsigned long flags; - u32 pmbase; - u8 value; - - if (!speedstep_chipset_dev || !state) - return -EINVAL; - - switch (speedstep_chipset) { - case SPEEDSTEP_CHIPSET_ICH2M: - case SPEEDSTEP_CHIPSET_ICH3M: - case SPEEDSTEP_CHIPSET_ICH4M: - /* get PMBASE */ - pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); - if (!(pmbase & 0x01)) - return -EIO; - - pmbase &= 0xFFFFFFFE; - if (!pmbase) - return -EIO; - - /* read state */ - local_irq_save(flags); - value = inb(pmbase + 0x50); - local_irq_restore(flags); - - dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); - - *state = value & 0x01; - return 0; - - } - - printk (KERN_ERR "cpufreq: setting CPU frequency on this chipset unsupported.\n"); - return -EINVAL; -} - - /** * speedstep_set_state - set the SpeedStep state * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) * * Tries to change the SpeedStep state. */ -static void speedstep_set_state (unsigned int state, int notify) +static void speedstep_set_state (unsigned int state, unsigned int notify) { - u32 pmbase; - u8 pm2_blk; - u8 value; - unsigned long flags; - unsigned int oldstate; - struct cpufreq_freqs freqs; + u32 pmbase; + u8 pm2_blk; + u8 value; + unsigned long flags; + struct cpufreq_freqs freqs; if (!speedstep_chipset_dev || (state > 0x1)) return; - if (speedstep_get_state(&oldstate)) - return; - - if (oldstate == state) - return; - - freqs.old = (oldstate == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; - freqs.new = (state == SPEEDSTEP_HIGH) ? speedstep_high_freq : speedstep_low_freq; + freqs.old = speedstep_get_processor_frequency(speedstep_processor); + freqs.new = speedstep_freqs[SPEEDSTEP_LOW].frequency; freqs.cpu = 0; /* speedstep.c is UP only driver */ if (notify) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - switch (speedstep_chipset) { - case SPEEDSTEP_CHIPSET_ICH2M: - case SPEEDSTEP_CHIPSET_ICH3M: - case SPEEDSTEP_CHIPSET_ICH4M: - /* get PMBASE */ - pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); - if (!(pmbase & 0x01)) - { - printk(KERN_ERR "cpufreq: could not find speedstep register\n"); - return; - } + /* get PMBASE */ + pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase); + if (!(pmbase & 0x01)) + { + printk(KERN_ERR "cpufreq: could not find speedstep register\n"); + return; + } - pmbase &= 0xFFFFFFFE; - if (!pmbase) { - printk(KERN_ERR "cpufreq: could not find speedstep register\n"); - return; - } + pmbase &= 0xFFFFFFFE; + if (!pmbase) { + printk(KERN_ERR "cpufreq: could not find speedstep register\n"); + return; + } - /* Disable IRQs */ - local_irq_save(flags); + /* Disable IRQs */ + local_irq_save(flags); - /* read state */ - value = inb(pmbase + 0x50); + /* read state */ + value = inb(pmbase + 0x50); - dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); - /* write new state */ - value &= 0xFE; - value |= state; + /* write new state */ + value &= 0xFE; + value |= state; - dprintk(KERN_DEBUG "cpufreq: writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); + dprintk(KERN_DEBUG "cpufreq: writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase); - /* Disable bus master arbitration */ - pm2_blk = inb(pmbase + 0x20); - pm2_blk |= 0x01; - outb(pm2_blk, (pmbase + 0x20)); + /* Disable bus master arbitration */ + pm2_blk = inb(pmbase + 0x20); + pm2_blk |= 0x01; + outb(pm2_blk, (pmbase + 0x20)); - /* Actual transition */ - outb(value, (pmbase + 0x50)); + /* Actual transition */ + outb(value, (pmbase + 0x50)); - /* Restore bus master arbitration */ - pm2_blk &= 0xfe; - outb(pm2_blk, (pmbase + 0x20)); + /* Restore bus master arbitration */ + pm2_blk &= 0xfe; + outb(pm2_blk, (pmbase + 0x20)); - /* check if transition was successful */ - value = inb(pmbase + 0x50); + /* check if transition was successful */ + value = inb(pmbase + 0x50); - /* Enable IRQs */ - local_irq_restore(flags); + /* Enable IRQs */ + local_irq_restore(flags); - dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); + dprintk(KERN_DEBUG "cpufreq: read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value); - if (state == (value & 0x1)) { - dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (freqs.new / 1000)); - } else { - printk (KERN_ERR "cpufreq: change failed - I/O error\n"); - } - break; - default: - printk (KERN_ERR "cpufreq: setting CPU frequency on this chipset unsupported.\n"); + if (state == (value & 0x1)) { + dprintk (KERN_INFO "cpufreq: change to %u MHz succeeded\n", (freqs.new / 1000)); + } else { + printk (KERN_ERR "cpufreq: change failed - I/O error\n"); } if (notify) @@ -240,31 +157,21 @@ */ static int speedstep_activate (void) { + u16 value = 0; + if (!speedstep_chipset_dev) return -EINVAL; - switch (speedstep_chipset) { - case SPEEDSTEP_CHIPSET_ICH2M: - case SPEEDSTEP_CHIPSET_ICH3M: - case SPEEDSTEP_CHIPSET_ICH4M: - { - u16 value = 0; - - pci_read_config_word(speedstep_chipset_dev, - 0x00A0, &value); - if (!(value & 0x08)) { - value |= 0x08; - dprintk(KERN_DEBUG "cpufreq: activating SpeedStep (TM) registers\n"); - pci_write_config_word(speedstep_chipset_dev, - 0x00A0, value); - } - - return 0; - } + pci_read_config_word(speedstep_chipset_dev, + 0x00A0, &value); + if (!(value & 0x08)) { + value |= 0x08; + dprintk(KERN_DEBUG "cpufreq: activating SpeedStep (TM) registers\n"); + pci_write_config_word(speedstep_chipset_dev, + 0x00A0, value); } - - printk (KERN_ERR "cpufreq: SpeedStep (TM) on this chipset unsupported.\n"); - return -EINVAL; + + return 0; } @@ -284,7 +191,7 @@ PCI_ANY_ID, NULL); if (speedstep_chipset_dev) - return SPEEDSTEP_CHIPSET_ICH4M; + return 4; /* 4-M */ speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, @@ -292,7 +199,7 @@ PCI_ANY_ID, NULL); if (speedstep_chipset_dev) - return SPEEDSTEP_CHIPSET_ICH3M; + return 3; /* 3-M */ speedstep_chipset_dev = pci_find_subsys(PCI_VENDOR_ID_INTEL, @@ -305,7 +212,7 @@ * 8100 which use a pretty old revision of the 82815 * host brige. Abort on these systems. */ - static struct pci_dev *hostbridge; + static struct pci_dev *hostbridge; u8 rev = 0; hostbridge = pci_find_subsys(PCI_VENDOR_ID_INTEL, @@ -315,7 +222,7 @@ NULL); if (!hostbridge) - return SPEEDSTEP_CHIPSET_ICH2M; + return 2; /* 2-M */ pci_read_config_byte(hostbridge, PCI_REVISION_ID, &rev); if (rev < 5) { @@ -324,266 +231,9 @@ return 0; } - return SPEEDSTEP_CHIPSET_ICH2M; - } - - return 0; -} - - - -/********************************************************************* - * LOW LEVEL PROCESSOR INTERFACE * - *********************************************************************/ - - -/** - * pentium3_get_frequency - get the core frequencies for PIIIs - * - * Returns the core frequency of a Pentium III processor (in kHz) - */ -static unsigned int pentium3_get_frequency (void) -{ - /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ - struct { - unsigned int ratio; /* Frequency Multiplier (x10) */ - u8 bitmap; /* power on configuration bits - [27, 25:22] (in MSR 0x2a) */ - } msr_decode_mult [] = { - { 30, 0x01 }, - { 35, 0x05 }, - { 40, 0x02 }, - { 45, 0x06 }, - { 50, 0x00 }, - { 55, 0x04 }, - { 60, 0x0b }, - { 65, 0x0f }, - { 70, 0x09 }, - { 75, 0x0d }, - { 80, 0x0a }, - { 85, 0x26 }, - { 90, 0x20 }, - { 100, 0x2b }, - { 0, 0xff } /* error or unknown value */ - }; - /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ - struct { - unsigned int value; /* Front Side Bus speed in MHz */ - u8 bitmap; /* power on configuration bits [18: 19] - (in MSR 0x2a) */ - } msr_decode_fsb [] = { - { 66, 0x0 }, - { 100, 0x2 }, - { 133, 0x1 }, - { 0, 0xff} - }; - u32 msr_lo, msr_tmp; - int i = 0, j = 0; - struct cpuinfo_x86 *c = cpu_data; - - /* read MSR 0x2a - we only need the low 32 bits */ - rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); - dprintk(KERN_DEBUG "cpufreq: P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); - msr_tmp = msr_lo; - - /* decode the FSB */ - msr_tmp &= 0x00c0000; - msr_tmp >>= 18; - while (msr_tmp != msr_decode_fsb[i].bitmap) { - if (msr_decode_fsb[i].bitmap == 0xff) - return -EINVAL; - i++; - } - - /* decode the multiplier */ - if ((c->x86_model == 0x08) && (c->x86_mask == 0x01)) - /* different on early Coppermine PIII */ - msr_lo &= 0x03c00000; - else - msr_lo &= 0x0bc00000; - msr_lo >>= 22; - while (msr_lo != msr_decode_mult[j].bitmap) { - if (msr_decode_mult[j].bitmap == 0xff) - return -EINVAL; - j++; - } - - return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100); -} - - -/** - * pentium4_get_frequency - get the core frequency for P4-Ms - * - * Should return the core frequency (in kHz) for P4-Ms. - */ -static unsigned int pentium4_get_frequency(void) -{ - u32 msr_lo, msr_hi; - - rdmsr(0x2c, msr_lo, msr_hi); - - dprintk(KERN_DEBUG "cpufreq: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); - - /* First 12 bits seem to change a lot (0x511, 0x410 and 0x30f seen - * yet). Next 12 bits always seem to be 0x300. If this is not true - * on this CPU, complain. Last 8 bits are frequency (in 100MHz). - */ - if (msr_hi || ((msr_lo & 0x00FFF000) != 0x300000)) { - printk(KERN_DEBUG "cpufreq: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); - printk(KERN_INFO "cpufreq: problem in initialization. Please contact Dominik Brodowski\n"); - printk(KERN_INFO "cpufreq: <linux@brodo.de> and attach this dmesg. Thanks in advance\n"); - return 0; - } - - msr_lo >>= 24; - return (msr_lo * 100000); -} - - -/** - * speedstep_detect_processor - detect Intel SpeedStep-capable processors. - * - * Returns the SPEEDSTEP_PROCESSOR_-number for the detected processor, - * or zero on failure. - */ -static unsigned int speedstep_detect_processor (void) -{ - struct cpuinfo_x86 *c = cpu_data; - u32 ebx; - - if ((c->x86_vendor != X86_VENDOR_INTEL) || - ((c->x86 != 6) && (c->x86 != 0xF))) - return 0; - - if (c->x86 == 0xF) { - /* Intel Pentium 4 Mobile P4-M */ - if (c->x86_model != 2) - return 0; - - if ((c->x86_mask != 4) && (c->x86_mask != 7)) - return 0; - - ebx = cpuid_ebx(0x00000001); - ebx &= 0x000000FF; - if ((ebx != 0x0e) && (ebx != 0x0f)) - return 0; - - return SPEEDSTEP_PROCESSOR_P4M; - } - - switch (c->x86_model) { - case 0x0B: /* Intel PIII [Tualatin] */ - /* cpuid_ebx(1) is 0x04 for desktop PIII, - 0x06 for mobile PIII-M */ - ebx = cpuid_ebx(0x00000001); - - ebx &= 0x000000FF; - if (ebx != 0x06) - return 0; - - /* So far all PIII-M processors support SpeedStep. See - * Intel's 24540633.pdf of August 2002 - */ - - return SPEEDSTEP_PROCESSOR_PIII_T; - - case 0x08: /* Intel PIII [Coppermine] */ - { - u32 msr_lo, msr_hi; - - /* all mobile PIII Coppermines have FSB 100 MHz - * ==> sort out a few desktop PIIIs. */ - rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); - dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_EBL_Cr_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi); - msr_lo &= 0x00c0000; - if (msr_lo != 0x0080000) - return 0; - - if (speedstep_coppermine) - return SPEEDSTEP_PROCESSOR_PIII_C; - - /* - * If the processor is a mobile version, - * platform ID has bit 50 set - * it has SpeedStep technology if either - * bit 56 or 57 is set - */ - rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi); - dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi); - if ((msr_hi & (1<<18)) && (msr_hi & (3<<24))) - return SPEEDSTEP_PROCESSOR_PIII_C; - - printk(KERN_INFO "cpufreq: in case this is a SpeedStep-capable Intel Pentium III Coppermine\n"); - printk(KERN_INFO "cpufreq: processor, please pass the boot option or module parameter\n"); - printk(KERN_INFO "cpufreq: `speedstep_coppermine=1` to the kernel. Thanks!\n"); - return 0; - } - - default: - return 0; - } -} - - - -/********************************************************************* - * HIGH LEVEL FUNCTIONS * - *********************************************************************/ - -/** - * speedstep_detect_speeds - detects low and high CPU frequencies. - * - * Detects the low and high CPU frequencies in kHz. Returns 0 on - * success or -EINVAL / -EIO on problems. - */ -static int speedstep_detect_speeds (void) -{ - unsigned long flags; - unsigned int state; - int i, result; - - /* Disable irqs for entire detection process */ - local_irq_save(flags); - - for (i=0; i<2; i++) { - /* read the current state */ - result = speedstep_get_state(&state); - if (result) { - local_irq_restore(flags); - return result; - } - - /* save the correct value, and switch to other */ - if (state == SPEEDSTEP_LOW) { - switch (speedstep_processor) { - case SPEEDSTEP_PROCESSOR_PIII_C: - case SPEEDSTEP_PROCESSOR_PIII_T: - speedstep_low_freq = pentium3_get_frequency(); - break; - case SPEEDSTEP_PROCESSOR_P4M: - speedstep_low_freq = pentium4_get_frequency(); - } - speedstep_set_state(SPEEDSTEP_HIGH, 0); - } else { - switch (speedstep_processor) { - case SPEEDSTEP_PROCESSOR_PIII_C: - case SPEEDSTEP_PROCESSOR_PIII_T: - speedstep_high_freq = pentium3_get_frequency(); - break; - case SPEEDSTEP_PROCESSOR_P4M: - speedstep_high_freq = pentium4_get_frequency(); - } - speedstep_set_state(SPEEDSTEP_LOW, 0); - } + return 2; /* 2-M */ } - local_irq_restore(flags); - - if (!speedstep_low_freq || !speedstep_high_freq || - (speedstep_low_freq == speedstep_high_freq)) - return -EIO; - return 0; } @@ -598,7 +248,7 @@ unsigned int target_freq, unsigned int relation) { - unsigned int newstate = 0; + unsigned int newstate = 0; if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0], target_freq, relation, &newstate)) return -EINVAL; @@ -632,22 +282,24 @@ return -ENODEV; /* detect low and high frequency */ - result = speedstep_detect_speeds(); + result = speedstep_get_freqs(speedstep_processor, + &speedstep_freqs[SPEEDSTEP_LOW].frequency, + &speedstep_freqs[SPEEDSTEP_HIGH].frequency, + &speedstep_set_state); if (result) return result; /* get current speed setting */ - result = speedstep_get_state(&speed); - if (result) - return result; + speed = speedstep_get_processor_frequency(speedstep_processor); + if (!speed) + return -EIO; - speed = (speed == SPEEDSTEP_LOW) ? speedstep_low_freq : speedstep_high_freq; dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", (speed == speedstep_low_freq) ? "low" : "high", (speed / 1000)); /* cpuinfo and default policy values */ - policy->policy = (speed == speedstep_low_freq) ? + policy->policy = (speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = speed; @@ -656,26 +308,6 @@ } -#ifndef MODULE -/** - * speedstep_setup speedstep command line parameter parsing - * - * speedstep command line parameter. Use: - * speedstep_coppermine=1 - * if the CPU in your notebook is a SpeedStep-capable Intel - * Pentium III Coppermine. These processors cannot be detected - * automatically, as Intel continues to consider the detection - * algorithm as proprietary material. - */ -static int __init speedstep_setup(char *str) -{ - speedstep_coppermine = simple_strtoul(str, &str, 0); - return 1; -} -__setup("speedstep_coppermine=", speedstep_setup); -#endif - - static struct cpufreq_driver speedstep_driver = { .name = "speedstep", .verify = speedstep_verify, @@ -694,20 +326,17 @@ */ static int __init speedstep_init(void) { - /* detect chipset */ - speedstep_chipset = speedstep_detect_chipset(); + /* detect processor */ + speedstep_processor = speedstep_detect_processor(); + if (!speedstep_processor) + return -ENODEV; /* detect chipset */ - if (speedstep_chipset) - speedstep_processor = speedstep_detect_processor(); - - if ((!speedstep_chipset) || (!speedstep_processor)) { - printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset"); + if (!speedstep_detect_chipset()) { + printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this chipset not (yet) available.\n"); return -ENODEV; } - dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.70 $\n"); - /* activate speedstep support */ if (speedstep_activate()) return -EINVAL; @@ -727,10 +356,8 @@ } -MODULE_PARM (speedstep_coppermine, "i"); - MODULE_AUTHOR ("Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>"); -MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors."); +MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges."); MODULE_LICENSE ("GPL"); module_init(speedstep_init); diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,275 @@ +/* + * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de> + * + * Licensed under the terms of the GNU GPL License version 2. + * + * Library for common functions for Intel SpeedStep v.1 and v.2 support + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/cpufreq.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include <asm/msr.h> +#include "speedstep-lib.h" + + +/* DEBUG + * Define it if you want verbose debug output, e.g. for bug reporting + */ +//#define SPEEDSTEP_DEBUG + +#ifdef SPEEDSTEP_DEBUG +#define dprintk(msg...) printk(msg) +#else +#define dprintk(msg...) do { } while(0) +#endif + +/********************************************************************* + * GET PROCESSOR CORE SPEED IN KHZ * + *********************************************************************/ + +static unsigned int pentium3_get_frequency (unsigned int processor) +{ + /* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */ + struct { + unsigned int ratio; /* Frequency Multiplier (x10) */ + u8 bitmap; /* power on configuration bits + [27, 25:22] (in MSR 0x2a) */ + } msr_decode_mult [] = { + { 30, 0x01 }, + { 35, 0x05 }, + { 40, 0x02 }, + { 45, 0x06 }, + { 50, 0x00 }, + { 55, 0x04 }, + { 60, 0x0b }, + { 65, 0x0f }, + { 70, 0x09 }, + { 75, 0x0d }, + { 80, 0x0a }, + { 85, 0x26 }, + { 90, 0x20 }, + { 100, 0x2b }, + { 0, 0xff } /* error or unknown value */ + }; + + /* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */ + struct { + unsigned int value; /* Front Side Bus speed in MHz */ + u8 bitmap; /* power on configuration bits [18: 19] + (in MSR 0x2a) */ + } msr_decode_fsb [] = { + { 66, 0x0 }, + { 100, 0x2 }, + { 133, 0x1 }, + { 0, 0xff} + }; + + u32 msr_lo, msr_tmp; + int i = 0, j = 0; + + /* read MSR 0x2a - we only need the low 32 bits */ + rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp); + dprintk(KERN_DEBUG "speedstep-lib: P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp); + msr_tmp = msr_lo; + + /* decode the FSB */ + msr_tmp &= 0x00c0000; + msr_tmp >>= 18; + while (msr_tmp != msr_decode_fsb[i].bitmap) { + if (msr_decode_fsb[i].bitmap == 0xff) + return 0; + i++; + } + + /* decode the multiplier */ + if (processor == SPEEDSTEP_PROCESSOR_PIII_C_EARLY) + msr_lo &= 0x03c00000; + else + msr_lo &= 0x0bc00000; + msr_lo >>= 22; + while (msr_lo != msr_decode_mult[j].bitmap) { + if (msr_decode_mult[j].bitmap == 0xff) + return 0; + j++; + } + + return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100); +} + + +static unsigned int pentium4_get_frequency(void) +{ + u32 msr_lo, msr_hi; + + rdmsr(0x2c, msr_lo, msr_hi); + + dprintk(KERN_DEBUG "speedstep-lib: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); + + msr_lo >>= 24; + return (msr_lo * 100000); +} + + +unsigned int speedstep_get_processor_frequency(unsigned int processor) +{ + switch (processor) { + case SPEEDSTEP_PROCESSOR_P4M: + return pentium4_get_frequency(); + case SPEEDSTEP_PROCESSOR_PIII_T: + case SPEEDSTEP_PROCESSOR_PIII_C: + case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: + return pentium3_get_frequency(processor); + default: + return 0; + }; + return 0; +} +EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency); + + +/********************************************************************* + * DETECT SPEEDSTEP-CAPABLE PROCESSOR * + *********************************************************************/ + +unsigned int speedstep_detect_processor (void) +{ + struct cpuinfo_x86 *c = cpu_data; + u32 ebx, msr_lo, msr_hi; + + if ((c->x86_vendor != X86_VENDOR_INTEL) || + ((c->x86 != 6) && (c->x86 != 0xF))) + return 0; + + if (c->x86 == 0xF) { + /* Intel Mobile Pentium 4-M + * or Intel Mobile Pentium 4 with 533 MHz FSB */ + if (c->x86_model != 2) + return 0; + + if ((c->x86_mask != 4) && /* B-stepping [M-P4-M] */ + (c->x86_mask != 7) && /* C-stepping [M-P4-M] */ + (c->x86_mask != 9)) /* D-stepping [M-P4-M or M-P4/533] */ + return 0; + + ebx = cpuid_ebx(0x00000001); + ebx &= 0x000000FF; + if ((ebx != 0x0e) && (ebx != 0x0f)) + return 0; + + return SPEEDSTEP_PROCESSOR_P4M; + } + + switch (c->x86_model) { + case 0x0B: /* Intel PIII [Tualatin] */ + /* cpuid_ebx(1) is 0x04 for desktop PIII, + 0x06 for mobile PIII-M */ + ebx = cpuid_ebx(0x00000001); + + ebx &= 0x000000FF; + if (ebx != 0x06) + return 0; + + /* So far all PIII-M processors support SpeedStep. See + * Intel's 24540640.pdf of June 2003 + */ + + return SPEEDSTEP_PROCESSOR_PIII_T; + + case 0x08: /* Intel PIII [Coppermine] */ + + /* all mobile PIII Coppermines have FSB 100 MHz + * ==> sort out a few desktop PIIIs. */ + rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi); + dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi); + msr_lo &= 0x00c0000; + if (msr_lo != 0x0080000) + return 0; + + /* + * If the processor is a mobile version, + * platform ID has bit 50 set + * it has SpeedStep technology if either + * bit 56 or 57 is set + */ + rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi); + dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n", msr_lo, msr_hi); + if ((msr_hi & (1<<18)) && (msr_hi & (3<<24))) { + if (c->x86_mask == 0x01) + return SPEEDSTEP_PROCESSOR_PIII_C_EARLY; + else + return SPEEDSTEP_PROCESSOR_PIII_C; + } + + default: + return 0; + } +} +EXPORT_SYMBOL_GPL(speedstep_detect_processor); + + +/********************************************************************* + * DETECT SPEEDSTEP SPEEDS * + *********************************************************************/ + +unsigned int speedstep_get_freqs(unsigned int processor, + unsigned int *low_speed, + unsigned int *high_speed, + void (*set_state) (unsigned int state, + unsigned int notify) + ) +{ + unsigned int prev_speed; + unsigned int ret = 0; + unsigned long flags; + + if ((!processor) || (!low_speed) || (!high_speed) || (!set_state)) + return EINVAL; + + /* get current speed */ + prev_speed = speedstep_get_processor_frequency(processor); + if (!prev_speed) + return EIO; + + local_irq_save(flags); + + /* switch to low state */ + set_state(SPEEDSTEP_LOW, 0); + *low_speed = speedstep_get_processor_frequency(processor); + if (!*low_speed) { + ret = EIO; + goto out; + } + + /* switch to high state */ + set_state(SPEEDSTEP_HIGH, 0); + *high_speed = speedstep_get_processor_frequency(processor); + if (!*high_speed) { + ret = EIO; + goto out; + } + + if (*low_speed == *high_speed) { + ret = ENODEV; + goto out; + } + + /* switch to previous state, if necessary */ + if (*high_speed != prev_speed) + set_state(SPEEDSTEP_LOW, 0); + + out: + local_irq_restore(flags); + return (ret); +} +EXPORT_SYMBOL_GPL(speedstep_get_freqs); + +MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>"); +MODULE_DESCRIPTION ("Library for Intel SpeedStep 1 or 2 cpufreq drivers."); +MODULE_LICENSE ("GPL"); diff -Nru a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,41 @@ +/* + * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de> + * + * Licensed under the terms of the GNU GPL License version 2. + * + * Library for common functions for Intel SpeedStep v.1 and v.2 support + * + * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* + */ + + + +/* processors */ + +#define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001 /* Coppermine core */ +#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002 /* Coppermine core */ +#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003 /* Tualatin core */ +#define SPEEDSTEP_PROCESSOR_P4M 0x00000004 /* P4-M with 100 MHz FSB */ + +/* speedstep states -- only two of them */ + +#define SPEEDSTEP_HIGH 0x00000000 +#define SPEEDSTEP_LOW 0x00000001 + + +/* detect a speedstep-capable processor */ +extern unsigned int speedstep_detect_processor (void); + +/* detect the current speed (in khz) of the processor */ +extern unsigned int speedstep_get_processor_frequency(unsigned int processor); + + +/* detect the low and high speeds of the processor. The callback + * set_state"'s first argument is either SPEEDSTEP_HIGH or + * SPEEDSTEP_LOW; the second argument is zero so that no + * cpufreq_notify_transition calls are initiated. + */ +extern unsigned int speedstep_get_freqs(unsigned int processor, + unsigned int *low_speed, + unsigned int *high_speed, + void (*set_state) (unsigned int state, unsigned int notify)); diff -Nru a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c --- a/arch/i386/kernel/i386_ksyms.c Fri Jun 27 14:20:06 2003 +++ b/arch/i386/kernel/i386_ksyms.c Fri Jun 27 14:20:06 2003 @@ -159,6 +159,7 @@ /* TLB flushing */ EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL_GPL(flush_tlb_all); #endif #ifdef CONFIG_X86_IO_APIC diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c --- a/arch/i386/kernel/io_apic.c Fri Jun 27 14:19:55 2003 +++ b/arch/i386/kernel/io_apic.c Fri Jun 27 14:19:55 2003 @@ -1272,9 +1272,10 @@ void __init print_IO_APIC(void) { int apic, i; - struct IO_APIC_reg_00 reg_00; - struct IO_APIC_reg_01 reg_01; - struct IO_APIC_reg_02 reg_02; + union IO_APIC_reg_00 reg_00; + union IO_APIC_reg_01 reg_01; + union IO_APIC_reg_02 reg_02; + union IO_APIC_reg_03 reg_03; unsigned long flags; printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); @@ -1291,51 +1292,70 @@ for (apic = 0; apic < nr_ioapics; apic++) { spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_00 = io_apic_read(apic, 0); - *(int *)®_01 = io_apic_read(apic, 1); - if (reg_01.version >= 0x10) - *(int *)®_02 = io_apic_read(apic, 2); + reg_00.raw = io_apic_read(apic, 0); + reg_01.raw = io_apic_read(apic, 1); + if (reg_01.bits.version >= 0x10) + reg_02.raw = io_apic_read(apic, 2); + if (reg_01.bits.version >= 0x20) + reg_03.raw = io_apic_read(apic, 3); spin_unlock_irqrestore(&ioapic_lock, flags); - printk("\n"); printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); - printk(KERN_DEBUG ".... register #00: %08X\n", *(int *)®_00); - printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.ID); - printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.delivery_type); - printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.LTS); - if (reg_00.ID >= APIC_BROADCAST_ID) + printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); + printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); + printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); + printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); + if (reg_00.bits.ID >= APIC_BROADCAST_ID) UNEXPECTED_IO_APIC(); - if (reg_00.__reserved_1 || reg_00.__reserved_2) + if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) UNEXPECTED_IO_APIC(); - printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)®_01); - printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.entries); - if ( (reg_01.entries != 0x0f) && /* older (Neptune) boards */ - (reg_01.entries != 0x17) && /* typical ISA+PCI boards */ - (reg_01.entries != 0x1b) && /* Compaq Proliant boards */ - (reg_01.entries != 0x1f) && /* dual Xeon boards */ - (reg_01.entries != 0x22) && /* bigger Xeon boards */ - (reg_01.entries != 0x2E) && - (reg_01.entries != 0x3F) + printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw); + printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); + if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ + (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ + (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ + (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ + (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ + (reg_01.bits.entries != 0x2E) && + (reg_01.bits.entries != 0x3F) ) UNEXPECTED_IO_APIC(); - printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.PRQ); - printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.version); - if ( (reg_01.version != 0x01) && /* 82489DX IO-APICs */ - (reg_01.version != 0x10) && /* oldest IO-APICs */ - (reg_01.version != 0x11) && /* Pentium/Pro IO-APICs */ - (reg_01.version != 0x13) && /* Xeon IO-APICs */ - (reg_01.version != 0x20) /* Intel P64H (82806 AA) */ + printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); + printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); + if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ + (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ + (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ + (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ + (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ ) UNEXPECTED_IO_APIC(); - if (reg_01.__reserved_1 || reg_01.__reserved_2) + if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) UNEXPECTED_IO_APIC(); - if (reg_01.version >= 0x10) { - printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)®_02); - printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.arbitration); - if (reg_02.__reserved_1 || reg_02.__reserved_2) + /* + * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, + * but the value of reg_02 is read as the previous read register + * value, so ignore it if reg_02 == reg_01. + */ + if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { + printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); + printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); + if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) + UNEXPECTED_IO_APIC(); + } + + /* + * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02 + * or reg_03, but the value of reg_0[23] is read as the previous read + * register value, so ignore it if reg_03 == reg_0[12]. + */ + if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw && + reg_03.raw != reg_01.raw) { + printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); + printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); + if (reg_03.bits.__reserved_1) UNEXPECTED_IO_APIC(); } @@ -1344,7 +1364,7 @@ printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol" " Stat Dest Deli Vect: \n"); - for (i = 0; i <= reg_01.entries; i++) { + for (i = 0; i <= reg_01.bits.entries; i++) { struct IO_APIC_route_entry entry; spin_lock_irqsave(&ioapic_lock, flags); @@ -1525,7 +1545,7 @@ static void __init enable_IO_APIC(void) { - struct IO_APIC_reg_01 reg_01; + union IO_APIC_reg_01 reg_01; int i; unsigned long flags; @@ -1542,9 +1562,9 @@ */ for (i = 0; i < nr_ioapics; i++) { spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_01 = io_apic_read(i, 1); + reg_01.raw = io_apic_read(i, 1); spin_unlock_irqrestore(&ioapic_lock, flags); - nr_ioapic_registers[i] = reg_01.entries+1; + nr_ioapic_registers[i] = reg_01.bits.entries+1; } /* @@ -1576,7 +1596,7 @@ #ifndef CONFIG_X86_NUMAQ static void __init setup_ioapic_ids_from_mpc(void) { - struct IO_APIC_reg_00 reg_00; + union IO_APIC_reg_00 reg_00; unsigned long phys_id_present_map; int apic; int i; @@ -1596,7 +1616,7 @@ /* Read the register 0 value */ spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_00 = io_apic_read(apic, 0); + reg_00.raw = io_apic_read(apic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); old_id = mp_ioapics[apic].mpc_apicid; @@ -1605,8 +1625,8 @@ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", apic, mp_ioapics[apic].mpc_apicid); printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", - reg_00.ID); - mp_ioapics[apic].mpc_apicid = reg_00.ID; + reg_00.bits.ID); + mp_ioapics[apic].mpc_apicid = reg_00.bits.ID; } /* @@ -1650,18 +1670,18 @@ printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...", mp_ioapics[apic].mpc_apicid); - reg_00.ID = mp_ioapics[apic].mpc_apicid; + reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0, *(int *)®_00); + io_apic_write(apic, 0, reg_00.raw); spin_unlock_irqrestore(&ioapic_lock, flags); /* * Sanity check */ spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_00 = io_apic_read(apic, 0); + reg_00.raw = io_apic_read(apic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); - if (reg_00.ID != mp_ioapics[apic].mpc_apicid) + if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) panic("could not set ID!\n"); else printk(" ok.\n"); @@ -2199,7 +2219,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) { - struct IO_APIC_reg_00 reg_00; + union IO_APIC_reg_00 reg_00; static unsigned long apic_id_map = 0; unsigned long flags; int i = 0; @@ -2217,13 +2237,13 @@ apic_id_map = phys_cpu_present_map; spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_00 = io_apic_read(ioapic, 0); + reg_00.raw = io_apic_read(ioapic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); if (apic_id >= IO_APIC_MAX_ID) { printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " - "%d\n", ioapic, apic_id, reg_00.ID); - apic_id = reg_00.ID; + "%d\n", ioapic, apic_id, reg_00.bits.ID); + apic_id = reg_00.bits.ID; } /* @@ -2248,16 +2268,16 @@ apic_id_map |= apicid_to_cpu_present(apic_id); - if (reg_00.ID != apic_id) { - reg_00.ID = apic_id; + if (reg_00.bits.ID != apic_id) { + reg_00.bits.ID = apic_id; spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(ioapic, 0, *(int *)®_00); - *(int *)®_00 = io_apic_read(ioapic, 0); + io_apic_write(ioapic, 0, reg_00.raw); + reg_00.raw = io_apic_read(ioapic, 0); spin_unlock_irqrestore(&ioapic_lock, flags); /* Sanity check */ - if (reg_00.ID != apic_id) + if (reg_00.bits.ID != apic_id) panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); } @@ -2269,27 +2289,27 @@ int __init io_apic_get_version (int ioapic) { - struct IO_APIC_reg_01 reg_01; + union IO_APIC_reg_01 reg_01; unsigned long flags; spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_01 = io_apic_read(ioapic, 1); + reg_01.raw = io_apic_read(ioapic, 1); spin_unlock_irqrestore(&ioapic_lock, flags); - return reg_01.version; + return reg_01.bits.version; } int __init io_apic_get_redir_entries (int ioapic) { - struct IO_APIC_reg_01 reg_01; + union IO_APIC_reg_01 reg_01; unsigned long flags; spin_lock_irqsave(&ioapic_lock, flags); - *(int *)®_01 = io_apic_read(ioapic, 1); + reg_01.raw = io_apic_read(ioapic, 1); spin_unlock_irqrestore(&ioapic_lock, flags); - return reg_01.entries; + return reg_01.bits.entries; } diff -Nru a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c --- a/arch/i386/kernel/traps.c Fri Jun 27 14:19:54 2003 +++ b/arch/i386/kernel/traps.c Fri Jun 27 14:19:54 2003 @@ -123,19 +123,20 @@ show_trace(tsk, (unsigned long *)esp); } -void show_stack(struct task_struct *task, unsigned long * esp) +void show_stack(struct task_struct *task, unsigned long *esp) { unsigned long *stack; int i; - // debugging aid: "show_stack(NULL);" prints the - // back trace for this cpu. - - if(esp==NULL) - esp=(unsigned long*)&esp; + if (esp == NULL) { + if (task) + esp = (unsigned long*)task->thread.esp; + else + esp = (unsigned long *)&esp; + } stack = esp; - for(i=0; i < kstack_depth_to_print; i++) { + for(i = 0; i < kstack_depth_to_print; i++) { if (((long) stack & (THREAD_SIZE-1)) == 0) break; if (i && ((i % 8) == 0)) diff -Nru a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile --- a/arch/i386/pci/Makefile Fri Jun 27 14:19:57 2003 +++ b/arch/i386/pci/Makefile Fri Jun 27 14:19:57 2003 @@ -1,27 +1,13 @@ -obj-y := i386.o +obj-y := i386.o obj-$(CONFIG_PCI_BIOS) += pcbios.o obj-$(CONFIG_PCI_DIRECT) += direct.o -obj-$(CONFIG_X86_VISWS) += visws.o +pci-y := fixup.o +pci-$(CONFIG_ACPI_PCI) += acpi.o +pci-y += legacy.o irq.o -ifdef CONFIG_X86_NUMAQ -obj-y += numa.o -else -obj-y += fixup.o +pci-$(CONFIG_X86_VISWS) := visws.o fixup.o +pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o -ifdef CONFIG_ACPI_PCI -obj-y += acpi.o -endif - -ifndef CONFIG_X86_VISWS -obj-y += legacy.o -endif - -endif # CONFIG_X86_NUMAQ - -ifndef CONFIG_X86_VISWS -obj-y += irq.o -endif - -obj-y += common.o +obj-y += $(pci-y) common.o diff -Nru a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c --- a/arch/i386/pci/acpi.c Fri Jun 27 14:19:58 2003 +++ b/arch/i386/pci/acpi.c Fri Jun 27 14:19:58 2003 @@ -3,6 +3,16 @@ #include <linux/init.h> #include "pci.h" +struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum) +{ + if (domain != 0) { + printk(KERN_WARNING "PCI: Multiple domains not supported\n"); + return NULL; + } + + return pcibios_scan_root(busnum); +} + static int __init pci_acpi_init(void) { if (pcibios_scanned) diff -Nru a/arch/i386/pci/common.c b/arch/i386/pci/common.c --- a/arch/i386/pci/common.c Fri Jun 27 14:19:55 2003 +++ b/arch/i386/pci/common.c Fri Jun 27 14:19:55 2003 @@ -27,14 +27,12 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { - return raw_pci_ops->read(0, bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where, size, value); + return raw_pci_ops->read(0, bus->number, devfn, where, size, value); } static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { - return raw_pci_ops->write(0, bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where, size, value); + return raw_pci_ops->write(0, bus->number, devfn, where, size, value); } struct pci_ops pci_root_ops = { diff -Nru a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c --- a/arch/i386/pci/direct.c Fri Jun 27 14:19:54 2003 +++ b/arch/i386/pci/direct.c Fri Jun 27 14:19:54 2003 @@ -10,19 +10,19 @@ * Functions for accessing PCI configuration space with type 1 accesses */ -#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \ - (0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) +#define PCI_CONF1_ADDRESS(bus, devfn, reg) \ + (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) -static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) +static int pci_conf1_read (int seg, int bus, int devfn, int reg, int len, u32 *value) { unsigned long flags; - if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); - outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); switch (len) { case 1: @@ -41,16 +41,16 @@ return 0; } -static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +static int pci_conf1_write (int seg, int bus, int devfn, int reg, int len, u32 value) { unsigned long flags; - if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); - outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8); + outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8); switch (len) { case 1: @@ -83,13 +83,17 @@ #define PCI_CONF2_ADDRESS(dev, reg) (u16)(0xC000 | (dev << 8) | reg) -static int pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) +static int pci_conf2_read(int seg, int bus, int devfn, int reg, int len, u32 *value) { unsigned long flags; + int dev, fn; - if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; + dev = PCI_SLOT(devfn); + fn = PCI_FUNC(devfn); + if (dev & 0x10) return PCIBIOS_DEVICE_NOT_FOUND; @@ -110,20 +114,24 @@ break; } - outb (0, 0xCF8); + outb(0, 0xCF8); spin_unlock_irqrestore(&pci_config_lock, flags); return 0; } -static int pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +static int pci_conf2_write (int seg, int bus, int devfn, int reg, int len, u32 value) { unsigned long flags; + int dev, fn; - if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; + dev = PCI_SLOT(devfn); + fn = PCI_FUNC(devfn); + if (dev & 0x10) return PCIBIOS_DEVICE_NOT_FOUND; @@ -134,17 +142,17 @@ switch (len) { case 1: - outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg)); + outb((u8)value, PCI_CONF2_ADDRESS(dev, reg)); break; case 2: - outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg)); + outw((u16)value, PCI_CONF2_ADDRESS(dev, reg)); break; case 4: - outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg)); + outl((u32)value, PCI_CONF2_ADDRESS(dev, reg)); break; } - outb (0, 0xCF8); + outb(0, 0xCF8); spin_unlock_irqrestore(&pci_config_lock, flags); @@ -178,14 +186,12 @@ return 1; for (devfn = 0; devfn < 0x100; devfn++) { - if (o->read(0, 0, PCI_SLOT(devfn), PCI_FUNC(devfn), - PCI_CLASS_DEVICE, 2, &x)) + if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x)) continue; if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA) return 1; - if (o->read(0, 0, PCI_SLOT(devfn), PCI_FUNC(devfn), - PCI_VENDOR_ID, 2, &x)) + if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x)) continue; if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ) return 1; @@ -195,54 +201,84 @@ return 0; } -static int __init pci_direct_init(void) +static int __init pci_check_type1(void) { + unsigned long flags; unsigned int tmp; + int works = 0; + + local_irq_save(flags); + + outb(0x01, 0xCFB); + tmp = inl(0xCF8); + outl(0x80000000, 0xCF8); + if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) { + works = 1; + } + outl(tmp, 0xCF8); + local_irq_restore(flags); + + return works; +} + +static int __init pci_check_type2(void) +{ unsigned long flags; + int works = 0; local_irq_save(flags); - /* - * Check if configuration type 1 works. - */ - if (pci_probe & PCI_PROBE_CONF1) { - outb (0x01, 0xCFB); - tmp = inl (0xCF8); - outl (0x80000000, 0xCF8); - if (inl (0xCF8) == 0x80000000 && - pci_sanity_check(&pci_direct_conf1)) { - outl (tmp, 0xCF8); - local_irq_restore(flags); - printk(KERN_INFO "PCI: Using configuration type 1\n"); - if (!request_region(0xCF8, 8, "PCI conf1")) - raw_pci_ops = NULL; - else - raw_pci_ops = &pci_direct_conf1; - return 0; - } - outl (tmp, 0xCF8); - } - - /* - * Check if configuration type 2 works. - */ - if (pci_probe & PCI_PROBE_CONF2) { - outb (0x00, 0xCFB); - outb (0x00, 0xCF8); - outb (0x00, 0xCFA); - if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 && - pci_sanity_check(&pci_direct_conf2)) { - local_irq_restore(flags); - printk(KERN_INFO "PCI: Using configuration type 2\n"); - if (!request_region(0xCF8, 4, "PCI conf2")) - raw_pci_ops = NULL; - else - raw_pci_ops = &pci_direct_conf2; - return 0; - } + outb(0x00, 0xCFB); + outb(0x00, 0xCF8); + outb(0x00, 0xCFA); + if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 && + pci_sanity_check(&pci_direct_conf2)) { + works = 1; } local_irq_restore(flags); + + return works; +} + +static int __init pci_direct_init(void) +{ + struct resource *region, *region2; + + if ((pci_probe & PCI_PROBE_CONF1) == 0) + goto type2; + region = request_region(0xCF8, 8, "PCI conf1"); + if (!region) + goto type2; + + if (pci_check_type1()) { + printk(KERN_INFO "PCI: Using configuration type 1\n"); + raw_pci_ops = &pci_direct_conf1; + return 0; + } + release_resource(region); + + type2: + if ((!pci_probe & PCI_PROBE_CONF2) == 0) + goto out; + region = request_region(0xCF8, 4, "PCI conf2"); + if (!region) + goto out; + region2 = request_region(0xC000, 0x1000, "PCI conf2"); + if (!region2) + goto fail2; + + if (pci_check_type2()) { + printk(KERN_INFO "PCI: Using configuration type 2\n"); + raw_pci_ops = &pci_direct_conf2; + return 0; + } + + release_resource(region2); + fail2: + release_resource(region); + + out: return 0; } diff -Nru a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c --- a/arch/i386/pci/numa.c Fri Jun 27 14:19:54 2003 +++ b/arch/i386/pci/numa.c Fri Jun 27 14:19:54 2003 @@ -10,19 +10,19 @@ #define BUS2LOCAL(global) (mp_bus_id_to_local[global]) #define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local]) -#define PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg) \ - (0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) +#define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \ + (0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3)) -static int pci_conf1_mq_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) +static int pci_conf1_mq_read (int seg, int bus, int devfn, int reg, int len, u32 *value) { unsigned long flags; - if (!value || (bus > MAX_MP_BUSSES) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (bus > MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); - outl_quad(PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus)); + outl_quad(PCI_CONF1_MQ_ADDRESS(bus, devfn, reg), 0xCF8, BUS2QUAD(bus)); switch (len) { case 1: @@ -41,16 +41,16 @@ return 0; } -static int pci_conf1_mq_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +static int pci_conf1_mq_write (int seg, int bus, int devfn, int reg, int len, u32 value) { unsigned long flags; - if ((bus > MAX_MP_BUSSES) || (dev > 31) || (fn > 7) || (reg > 255)) + if ((bus > MAX_MP_BUSSES) || (devfn > 255) || (reg > 255)) return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); - outl_quad(PCI_CONF1_MQ_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus)); + outl_quad(PCI_CONF1_MQ_ADDRESS(bus, devfn, reg), 0xCF8, BUS2QUAD(bus)); switch (len) { case 1: diff -Nru a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c --- a/arch/i386/pci/pcbios.c Fri Jun 27 14:19:53 2003 +++ b/arch/i386/pci/pcbios.c Fri Jun 27 14:19:53 2003 @@ -172,13 +172,13 @@ return (int) (ret & 0xff00) >> 8; } -static int pci_bios_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) +static int pci_bios_read (int seg, int bus, int devfn, int reg, int len, u32 *value) { unsigned long result = 0; unsigned long flags; - unsigned long bx = ((bus << 8) | (dev << 3) | fn); + unsigned long bx = (bus << 8) | devfn; - if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); @@ -227,13 +227,13 @@ return (int)((result & 0xff00) >> 8); } -static int pci_bios_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +static int pci_bios_write (int seg, int bus, int devfn, int reg, int len, u32 value) { unsigned long result = 0; unsigned long flags; - unsigned long bx = ((bus << 8) | (dev << 3) | fn); + unsigned long bx = (bus << 8) | devfn; - if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if ((bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; spin_lock_irqsave(&pci_config_lock, flags); diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig --- a/arch/ia64/Kconfig Fri Jun 27 14:20:04 2003 +++ b/arch/ia64/Kconfig Fri Jun 27 14:20:04 2003 @@ -544,6 +544,8 @@ source "drivers/block/Kconfig" +source "drivers/ide/Kconfig" + source "drivers/ieee1394/Kconfig" source "drivers/message/i2o/Kconfig" @@ -555,32 +557,8 @@ endif -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" -endmenu - source "net/Kconfig" @@ -590,42 +568,8 @@ source "drivers/isdn/Kconfig" - -menu "CD-ROM drivers (not for SCSI or IDE/ATAPI drives)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - source "drivers/cdrom/Kconfig" -endmenu - # # input before char - char/joystick depends on it. As does USB. # @@ -786,6 +730,10 @@ config IA64_EARLY_PRINTK_VGA bool "Early printk on VGA" depends on IA64_EARLY_PRINTK + +config IA64_EARLY_PRINTK_SGI_SN + bool "Early printk on SGI SN serial console" + depends on IA64_EARLY_PRINTK && (IA64_GENERIC || IA64_SGI_SN2) config DEBUG_SLAB bool "Debug memory allocations" diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile --- a/arch/ia64/Makefile Fri Jun 27 14:19:52 2003 +++ b/arch/ia64/Makefile Fri Jun 27 14:19:52 2003 @@ -27,7 +27,7 @@ GAS_STATUS=$(shell arch/ia64/scripts/check-gas $(CC) $(OBJDUMP)) -arch-cppflags := $(shell arch/ia64/scripts/toolchain-flags $(CC) $(LD) $(OBJDUMP)) +arch-cppflags := $(shell arch/ia64/scripts/toolchain-flags $(CC) $(OBJDUMP)) cflags-y += $(arch-cppflags) AFLAGS += $(arch-cppflags) @@ -66,7 +66,8 @@ drivers-$(CONFIG_PCI) += arch/ia64/pci/ drivers-$(CONFIG_IA64_HP_SIM) += arch/ia64/hp/sim/ drivers-$(CONFIG_IA64_HP_ZX1) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ -drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ +drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ \ + arch/ia64/sn/ boot := arch/ia64/boot diff -Nru a/arch/ia64/defconfig b/arch/ia64/defconfig --- a/arch/ia64/defconfig Fri Jun 27 14:19:53 2003 +++ b/arch/ia64/defconfig Fri Jun 27 14:19:53 2003 @@ -10,30 +10,38 @@ # # General setup # -CONFIG_NET=y +CONFIG_SWAP=y CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BSD_PROCESS_ACCT=y CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y # # Loadable module support # CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y -# CONFIG_KMOD is not set +CONFIG_KMOD=y # # Processor type and features # CONFIG_IA64=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_ITANIUM=y -# CONFIG_MCKINLEY is not set +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_TIME_INTERPOLATION=y +# CONFIG_ITANIUM is not set +CONFIG_MCKINLEY=y # CONFIG_IA64_GENERIC is not set -CONFIG_IA64_DIG=y +# CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_SIM is not set -# CONFIG_IA64_HP_ZX1 is not set -# CONFIG_IA64_SGI_SN1 is not set +CONFIG_IA64_HP_ZX1=y # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_PAGE_SIZE_4KB is not set # CONFIG_IA64_PAGE_SIZE_8KB is not set @@ -43,41 +51,64 @@ CONFIG_ACPI_EFI=y CONFIG_ACPI_INTERPRETER=y CONFIG_ACPI_KERNEL_CONFIG=y -CONFIG_IA64_BRL_EMU=y -# CONFIG_ITANIUM_BSTEP_SPECIFIC is not set -CONFIG_IA64_L1_CACHE_SHIFT=6 +CONFIG_IA64_L1_CACHE_SHIFT=7 +# CONFIG_MCKINLEY_ASTEP_SPECIFIC is not set # CONFIG_NUMA is not set +CONFIG_VIRTUAL_MEM_MAP=y CONFIG_IA64_MCA=y CONFIG_PM=y CONFIG_IOSAPIC=y CONFIG_KCORE_ELF=y CONFIG_FORCE_MAX_ZONEORDER=18 -# CONFIG_HUGETLB_PAGE is not set +CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLB_PAGE_SIZE_4GB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1GB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set +CONFIG_HUGETLB_PAGE_SIZE_64MB=y +# CONFIG_HUGETLB_PAGE_SIZE_16MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set +CONFIG_IA64_PAL_IDLE=y CONFIG_SMP=y +# CONFIG_PREEMPT is not set CONFIG_IA32_SUPPORT=y +CONFIG_COMPAT=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_EFI_VARS=y CONFIG_NR_CPUS=16 CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set +CONFIG_BINFMT_MISC=y # # ACPI Support # CONFIG_ACPI_BOOT=y CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_FAN=m -CONFIG_ACPI_PROCESSOR=m -CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_THERMAL=y # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_BUS=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG is not set +CONFIG_HOTPLUG=y + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set # # Parallel port support @@ -85,12 +116,17 @@ # CONFIG_PARPORT is not set # +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Memory Technology Devices (MTD) # # CONFIG_MTD is not set # -# Plug and Play configuration +# Plug and Play support # # CONFIG_PNP is not set @@ -104,7 +140,9 @@ # CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y # # IEEE 1394 (FireWire) support (EXPERIMENTAL) @@ -124,64 +162,11 @@ # # Fusion MPT device support # -# CONFIG_FUSION is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=y -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_BLK_DEV_GENERIC is not set -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDE_TCQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NFORCE is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDEDMA_IVB is not set +CONFIG_FUSION=y +CONFIG_FUSION_BOOT=y +CONFIG_FUSION_MAX_SGE=40 +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set # # SCSI support @@ -192,16 +177,17 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set +CONFIG_CHR_DEV_ST=y +CONFIG_CHR_DEV_OSST=y +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_REPORT_LUNS=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -212,57 +198,76 @@ # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC7XXX_OLD=y +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set +CONFIG_SCSI_MEGARAID=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # +# Networking support +# +CONFIG_NET=y + +# # Networking options # CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y +# CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -CONFIG_FILTER=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set CONFIG_UNIX=y +# CONFIG_NET_KEY is not set CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set +CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +CONFIG_IP_NF_ARPTABLES=y +# CONFIG_IP_NF_ARPFILTER is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -288,8 +293,9 @@ # CONFIG_NET_SCHED is not set # -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -297,7 +303,7 @@ # # CONFIG_ARCNET is not set CONFIG_DUMMY=y -# CONFIG_BONDING is not set +CONFIG_BONDING=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set # CONFIG_ETHERTAP is not set @@ -306,11 +312,10 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set # # Tulip family network device support @@ -319,9 +324,12 @@ # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set # CONFIG_DGRS is not set CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PIO is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -333,19 +341,25 @@ # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set -# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_E1000 is not set +CONFIG_E1000=y +# CONFIG_E1000_NAPI is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set +CONFIG_TIGON3=m + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PPP is not set @@ -357,9 +371,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -393,10 +406,10 @@ # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_JOYDEV=y # CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set @@ -407,26 +420,19 @@ # CONFIG_GAMEPORT is not set CONFIG_SOUND_GAMEPORT=y CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # # Input Device Drivers # -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_PCSPKR is not set -# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_MISC is not set # # Character devices @@ -441,12 +447,9 @@ # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set -# CONFIG_SERIAL_8250_RSA is not set +CONFIG_SERIAL_8250_ACPI=y +CONFIG_SERIAL_8250_HCDP=y +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support @@ -459,14 +462,16 @@ # # I2C support # -CONFIG_I2C=y -CONFIG_I2C_ALGOBIT=y -# CONFIG_I2C_ELV is not set -# CONFIG_I2C_VELLEMAN is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_ALGOPCF is not set -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_PROC=y +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set # # Mice @@ -475,12 +480,16 @@ # CONFIG_QIC02_TAPE is not set # +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_NVRAM is not set -# CONFIG_RTC is not set # CONFIG_GEN_RTC is not set CONFIG_EFI_RTC=y # CONFIG_DTLK is not set @@ -491,25 +500,17 @@ # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set -CONFIG_AGP=y -CONFIG_AGP_INTEL=y -CONFIG_AGP_I810=y -CONFIG_AGP_VIA=y -CONFIG_AGP_AMD=y -CONFIG_AGP_SIS=y -CONFIG_AGP_ALI=y -CONFIG_AGP_SWORKS=y -# CONFIG_AGP_AMD_8151 is not set -CONFIG_AGP_I460=y -CONFIG_AGP_HP_ZX1=y +CONFIG_AGP=m +CONFIG_AGP_I460=m +CONFIG_AGP_HP_ZX1=m CONFIG_DRM=y -CONFIG_DRM_TDFX=y -CONFIG_DRM_R128=y -CONFIG_DRM_RADEON=y -CONFIG_DRM_I810=y -CONFIG_DRM_I830=y -CONFIG_DRM_MGA=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_GAMMA is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=m +# CONFIG_DRM_MGA is not set # CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -517,51 +518,79 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_ZISOFS is not set +CONFIG_UDF_FS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +CONFIG_HUGETLBFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_XFS_FS is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y CONFIG_NFS_V4=y @@ -569,13 +598,16 @@ CONFIG_NFSD_V3=y # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -# CONFIG_CIFS is not set +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set # @@ -593,6 +625,7 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set @@ -603,53 +636,84 @@ # Native Language Support # CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=y +CONFIG_NLS_CODEPAGE_775=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_CODEPAGE_852=y +CONFIG_NLS_CODEPAGE_855=y +CONFIG_NLS_CODEPAGE_857=y +CONFIG_NLS_CODEPAGE_860=y +CONFIG_NLS_CODEPAGE_861=y +CONFIG_NLS_CODEPAGE_862=y +CONFIG_NLS_CODEPAGE_863=y +CONFIG_NLS_CODEPAGE_864=y +CONFIG_NLS_CODEPAGE_865=y +CONFIG_NLS_CODEPAGE_866=y +CONFIG_NLS_CODEPAGE_869=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_CODEPAGE_950=y +CONFIG_NLS_CODEPAGE_932=y +CONFIG_NLS_CODEPAGE_949=y +CONFIG_NLS_CODEPAGE_874=y +CONFIG_NLS_ISO8859_8=y # CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set +CONFIG_NLS_CODEPAGE_1251=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +CONFIG_NLS_ISO8859_3=y +CONFIG_NLS_ISO8859_4=y +CONFIG_NLS_ISO8859_5=y +CONFIG_NLS_ISO8859_6=y +CONFIG_NLS_ISO8859_7=y +CONFIG_NLS_ISO8859_9=y +CONFIG_NLS_ISO8859_13=y +CONFIG_NLS_ISO8859_14=y +CONFIG_NLS_ISO8859_15=y +CONFIG_NLS_KOI8_R=y +CONFIG_NLS_KOI8_U=y +CONFIG_NLS_UTF8=y + +# +# Graphics support +# +CONFIG_FB=y +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_RIVA=m +# CONFIG_FB_MATROX is not set +CONFIG_FB_RADEON=y +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_VIRTUAL is not set # -# Console drivers +# Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_PCI_CONSOLE=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y # -# Frame-buffer support -# -# CONFIG_FB is not set +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y # # Sound @@ -659,31 +723,62 @@ # # Advanced Linux Sound Architecture # -# CONFIG_SND is not set +CONFIG_SND=m +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY is not set +# CONFIG_SND_OSSEMUL is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_TRIDENT is not set +# CONFIG_SND_YMFPCI is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_MAESTRO3 is not set +CONFIG_SND_FM801=m +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VX222 is not set + +# +# ALSA USB devices +# +# CONFIG_SND_USB_AUDIO is not set # # Open Sound System # -CONFIG_SOUND_PRIME=y -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -CONFIG_SOUND_CS4281=y -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_MAESTRO3 is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_RME96XX is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND_PRIME is not set # # USB support @@ -694,17 +789,16 @@ # # Miscellaneous USB options # -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_LONG_TIMEOUT is not set -# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DEVICEFS is not set +CONFIG_USB_BANDWIDTH=y # CONFIG_USB_DYNAMIC_MINORS is not set # # USB Host Controller Drivers # -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -CONFIG_USB_UHCI_HCD_ALT=y +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_UHCI_HCD=m # # USB Device Class drivers @@ -725,6 +819,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_XPAD is not set @@ -748,8 +843,8 @@ # # USB Network adaptors # +# CONFIG_USB_AX8817X is not set # CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set @@ -772,17 +867,17 @@ # CONFIG_USB_RIO500 is not set # CONFIG_USB_BRLVGER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_TEST is not set +# CONFIG_USB_GADGET is not set # -# Library routines +# Bluetooth support # -# CONFIG_CRC32 is not set +# CONFIG_BT is not set # -# Bluetooth support +# Library routines # -# CONFIG_BT is not set +CONFIG_CRC32=y # # Kernel hacking @@ -794,18 +889,17 @@ CONFIG_IA64_PRINT_HAZARDS=y # CONFIG_DISABLE_VHPT is not set CONFIG_MAGIC_SYSRQ=y -CONFIG_IA64_EARLY_PRINTK=y -# CONFIG_IA64_EARLY_PRINTK_UART is not set -CONFIG_IA64_EARLY_PRINTK_VGA=y +# CONFIG_IA64_EARLY_PRINTK is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_IA64_DEBUG_CMPXCHG is not set # CONFIG_IA64_DEBUG_IRQ is not set # # Security options # -CONFIG_SECURITY_CAPABILITIES=y +# CONFIG_SECURITY is not set # # Cryptographic options diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c --- a/arch/ia64/kernel/acpi.c Fri Jun 27 14:19:56 2003 +++ b/arch/ia64/kernel/acpi.c Fri Jun 27 14:19:56 2003 @@ -575,59 +575,6 @@ } -#ifdef CONFIG_SERIAL_8250_ACPI - -#include <linux/acpi_serial.h> - -static int __init -acpi_parse_spcr (unsigned long phys_addr, unsigned long size) -{ - acpi_ser_t *spcr; - unsigned int gsi; - - if (!phys_addr || !size) - return -EINVAL; - - if (!iosapic_register_intr) - return -ENODEV; - - /* - * ACPI is able to describe serial ports that live at non-standard - * memory addresses and use non-standard interrupts, either via - * direct SAPIC mappings or via PCI interrupts. We handle interrupt - * routing for SAPIC-based (non-PCI) devices here. Interrupt routing - * for PCI devices will be handled when processing the PCI Interrupt - * Routing Table (PRT). - */ - - spcr = (acpi_ser_t *) __va(phys_addr); - - setup_serial_acpi(spcr); - - if (spcr->length < sizeof(acpi_ser_t)) - /* Table not long enough for full info, thus no interrupt */ - return -ENODEV; - - if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) && - (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) - { - int vector; - - /* We have a UART in memory space with an SAPIC interrupt */ - - gsi = ( (spcr->global_int[3] << 24) | - (spcr->global_int[2] << 16) | - (spcr->global_int[1] << 8) | - (spcr->global_int[0]) ); - - vector = iosapic_register_intr(gsi, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); - } - return 0; -} - -#endif /* CONFIG_SERIAL_8250_ACPI */ - - int __init acpi_boot_init (void) { @@ -681,16 +628,6 @@ */ if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1) printk(KERN_ERR PREFIX "Can't find FADT\n"); - -#ifdef CONFIG_SERIAL_8250_ACPI - /* - * TBD: Need phased approach to table parsing (only do those absolutely - * required during boot-up). Recommend expanding concept of fix- - * feature devices (LDM) to include table-based devices such as - * serial ports, EC, SMBus, etc. - */ - acpi_table_parse(ACPI_SPCR, acpi_parse_spcr); -#endif #ifdef CONFIG_SMP smp_boot_data.cpu_count = available_cpus; diff -Nru a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c --- a/arch/ia64/kernel/efi.c Fri Jun 27 14:19:52 2003 +++ b/arch/ia64/kernel/efi.c Fri Jun 27 14:19:52 2003 @@ -46,7 +46,7 @@ * prior to creating their own entries under /proc/efi. */ #ifdef CONFIG_PROC_FS -struct proc_dir_entry *efi_dir = NULL; +struct proc_dir_entry *efi_dir; #endif static unsigned long mem_limit = ~0UL; diff -Nru a/arch/ia64/kernel/efivars.c b/arch/ia64/kernel/efivars.c --- a/arch/ia64/kernel/efivars.c Fri Jun 27 14:19:56 2003 +++ b/arch/ia64/kernel/efivars.c Fri Jun 27 14:19:56 2003 @@ -119,7 +119,7 @@ */ static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED; static LIST_HEAD(efivar_list); -static struct proc_dir_entry *efi_vars_dir = NULL; +static struct proc_dir_entry *efi_vars_dir; #define efivar_entry(n) list_entry(n, efivar_entry_t, list) diff -Nru a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S --- a/arch/ia64/kernel/gate.S Fri Jun 27 14:20:00 2003 +++ b/arch/ia64/kernel/gate.S Fri Jun 27 14:20:00 2003 @@ -199,7 +199,7 @@ cmp.ne p8,p0=r15,r0 // do we need to switch the rbs? mov.m r9=ar.bsp // fetch ar.bsp .spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF -(p8) br.cond.spnt setup_rbs // yup -> (clobbers r14, r15, and r16) +(p8) br.cond.spnt setup_rbs // yup -> (clobbers p8, r14-r16, and r18-r20) back_from_setup_rbs: alloc r8=ar.pfs,0,0,3,0 ld8 out0=[base0],16 // load arg0 (signum) @@ -268,26 +268,30 @@ setup_rbs: mov ar.rsc=0 // put RSE into enforced lazy mode ;; - .save ar.rnat, r16 - mov r16=ar.rnat // save RNaT before switching backing store area + .save ar.rnat, r19 + mov r19=ar.rnat // save RNaT before switching backing store area adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp + mov r18=ar.bspstore mov ar.bspstore=r15 // switch over to new register backing store area ;; + .spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF - st8 [r14]=r16 // save sc_ar_rnat + st8 [r14]=r19 // save sc_ar_rnat .body - adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp - mov.m r16=ar.bsp // sc_loadrs <- (new bsp - new bspstore) << 16 + adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp ;; invala sub r15=r16,r15 + extr.u r20=r18,3,6 ;; + mov ar.rsc=0xf // set RSE into eager mode, pl 3 + cmp.eq p8,p0=63,r20 shl r15=r15,16 ;; st8 [r14]=r15 // save sc_loadrs - mov ar.rsc=0xf // set RSE into eager mode, pl 3 +(p8) st8 [r18]=r19 // if bspstore points at RNaT slot, store RNaT there now .restore sp // pop .prologue br.cond.sptk back_from_setup_rbs diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S --- a/arch/ia64/kernel/head.S Fri Jun 27 14:19:59 2003 +++ b/arch/ia64/kernel/head.S Fri Jun 27 14:19:59 2003 @@ -144,13 +144,13 @@ movl r3=task_for_booting_cpu ;; ld8 r3=[r3] - movl r2=init_thread_union + movl r2=init_task ;; cmp.eq isBP,isAP=r3,r0 ;; (isAP) mov r2=r3 #else - movl r2=init_thread_union + movl r2=init_task cmp.eq isBP,isAP=r0,r0 #endif ;; diff -Nru a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c --- a/arch/ia64/kernel/init_task.c Fri Jun 27 14:20:05 2003 +++ b/arch/ia64/kernel/init_task.c Fri Jun 27 14:20:05 2003 @@ -26,17 +26,17 @@ * We need to make sure that this is properly aligned due to the way process stacks are * handled. This is done by having a special ".data.init_task" section... */ -#define init_thread_info init_thread_union.s.thread_info +#define init_thread_info init_task_mem.s.thread_info -union init_thread { +static union { struct { struct task_struct task; struct thread_info thread_info; } s; unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)]; -} init_thread_union __attribute__((section(".data.init_task"))) = {{ - .task = INIT_TASK(init_thread_union.s.task), - .thread_info = INIT_THREAD_INFO(init_thread_union.s.task) +} init_task_mem __attribute__((section(".data.init_task"))) = {{ + .task = INIT_TASK(init_task_mem.s.task), + .thread_info = INIT_THREAD_INFO(init_task_mem.s.task) }}; -asm (".global init_task; init_task = init_thread_union"); +asm (".global init_task; init_task = init_task_mem"); diff -Nru a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c --- a/arch/ia64/kernel/iosapic.c Fri Jun 27 14:19:56 2003 +++ b/arch/ia64/kernel/iosapic.c Fri Jun 27 14:19:56 2003 @@ -382,7 +382,7 @@ static void iosapic_ack_edge_irq (unsigned int irq) { - irq_desc_t *idesc = irq_desc(irq); + irq_desc_t *idesc = irq_descp(irq); /* * Once we have recorded IRQ_PENDING already, we can mask the * interrupt for real. This prevents IRQ storms from unhandled @@ -478,7 +478,7 @@ else irq_type = &irq_type_iosapic_level; - idesc = irq_desc(vector); + idesc = irq_descp(vector); if (idesc->handler != irq_type) { if (idesc->handler != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", @@ -724,7 +724,7 @@ * If vector was previously initialized to a different * handler, re-initialize. */ - idesc = irq_desc(vector); + idesc = irq_descp(vector); if (idesc->handler != irq_type) register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW, IOSAPIC_LEVEL); diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c --- a/arch/ia64/kernel/irq.c Fri Jun 27 14:20:02 2003 +++ b/arch/ia64/kernel/irq.c Fri Jun 27 14:20:02 2003 @@ -74,7 +74,7 @@ }; #ifdef CONFIG_IA64_GENERIC -struct irq_desc * __ia64_irq_desc (unsigned int irq) +irq_desc_t * __ia64_irq_desc (unsigned int irq) { return _irq_desc + irq; } @@ -171,7 +171,7 @@ seq_putc(p, '\n'); for (i = 0 ; i < NR_IRQS ; i++) { - idesc = irq_desc(i); + idesc = irq_descp(i); spin_lock_irqsave(&idesc->lock, flags); action = idesc->action; if (!action) @@ -218,7 +218,7 @@ #ifdef CONFIG_SMP inline void synchronize_irq(unsigned int irq) { - while (irq_desc(irq)->status & IRQ_INPROGRESS) + while (irq_descp(irq)->status & IRQ_INPROGRESS) cpu_relax(); } #endif @@ -352,7 +352,7 @@ inline void disable_irq_nosync(unsigned int irq) { - irq_desc_t *desc = irq_desc(irq); + irq_desc_t *desc = irq_descp(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -395,7 +395,7 @@ void enable_irq(unsigned int irq) { - irq_desc_t *desc = irq_desc(irq); + irq_desc_t *desc = irq_descp(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -437,7 +437,7 @@ * 0 return value means that this irq is already being * handled by some other CPU. (or is disabled) */ - irq_desc_t *desc = irq_desc(irq); + irq_desc_t *desc = irq_descp(irq); struct irqaction * action; irqreturn_t action_ret; unsigned int status; @@ -620,7 +620,7 @@ if (irq >= NR_IRQS) return; - desc = irq_desc(irq); + desc = irq_descp(irq); spin_lock_irqsave(&desc->lock,flags); p = &desc->action; for (;;) { @@ -682,7 +682,7 @@ * flush such a longstanding irq before considering it as spurious. */ for (i = NR_IRQS-1; i > 0; i--) { - desc = irq_desc(i); + desc = irq_descp(i); spin_lock_irq(&desc->lock); if (!desc->action) @@ -700,7 +700,7 @@ * happened in the previous stage, it may have masked itself) */ for (i = NR_IRQS-1; i > 0; i--) { - desc = irq_desc(i); + desc = irq_descp(i); spin_lock_irq(&desc->lock); if (!desc->action) { @@ -722,7 +722,7 @@ */ val = 0; for (i = 0; i < NR_IRQS; i++) { - irq_desc_t *desc = irq_desc(i); + irq_desc_t *desc = irq_descp(i); unsigned int status; spin_lock_irq(&desc->lock); @@ -762,7 +762,7 @@ mask = 0; for (i = 0; i < 16; i++) { - irq_desc_t *desc = irq_desc(i); + irq_desc_t *desc = irq_descp(i); unsigned int status; spin_lock_irq(&desc->lock); @@ -807,7 +807,7 @@ nr_irqs = 0; irq_found = 0; for (i = 0; i < NR_IRQS; i++) { - irq_desc_t *desc = irq_desc(i); + irq_desc_t *desc = irq_descp(i); unsigned int status; spin_lock_irq(&desc->lock); @@ -836,7 +836,7 @@ int shared = 0; unsigned long flags; struct irqaction *old, **p; - irq_desc_t *desc = irq_desc(irq); + irq_desc_t *desc = irq_descp(irq); if (desc->handler == &no_irq_type) return -ENOSYS; @@ -963,15 +963,16 @@ } static int irq_affinity_write_proc (struct file *file, const char *buffer, - unsigned long count, void *data) + unsigned long count, void *data) { unsigned int irq = (unsigned long) data; int full_count = count, err; unsigned long new_value; const char *buf = buffer; + irq_desc_t *desc = irq_descp(irq); int redir; - if (!irq_desc(irq)->handler->set_affinity) + if (!desc->handler->set_affinity) return -EIO; if (buf[0] == 'r' || buf[0] == 'R') { @@ -993,8 +994,7 @@ if (!(new_value & cpu_online_map)) return -EINVAL; - irq_desc(irq)->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value); - + desc->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value); return full_count; } @@ -1030,7 +1030,7 @@ { char name [MAX_NAMELEN]; - if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type) || irq_dir[irq]) + if (!root_irq_dir || (irq_descp(irq)->handler == &no_irq_type) || irq_dir[irq]) return; memset(name, 0, MAX_NAMELEN); @@ -1083,7 +1083,7 @@ * Create entries for all existing IRQs. */ for (i = 0; i < NR_IRQS; i++) { - if (irq_desc(i)->handler == &no_irq_type) + if (irq_descp(i)->handler == &no_irq_type) continue; register_irq_proc(i); } diff -Nru a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c --- a/arch/ia64/kernel/irq_ia64.c Fri Jun 27 14:19:55 2003 +++ b/arch/ia64/kernel/irq_ia64.c Fri Jun 27 14:19:55 2003 @@ -162,7 +162,7 @@ for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vec) { - desc = irq_desc(irq); + desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; desc->handler = &irq_type_ia64_lsapic; if (action) diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c --- a/arch/ia64/kernel/mca.c Fri Jun 27 14:19:56 2003 +++ b/arch/ia64/kernel/mca.c Fri Jun 27 14:19:56 2003 @@ -734,7 +734,7 @@ if (cpev >= 0) { for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == cpev) { - desc = irq_desc(irq); + desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; desc->handler = &irq_type_iosapic_level; setup_irq(irq, &mca_cpe_irqaction); diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c --- a/arch/ia64/kernel/perfmon.c Fri Jun 27 14:20:04 2003 +++ b/arch/ia64/kernel/perfmon.c Fri Jun 27 14:20:04 2003 @@ -115,6 +115,8 @@ #define PMD_IS_COUNTING(i) ((pmu_conf.pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) #define PMC_IS_COUNTING(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING) #define PMC_IS_MONITOR(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_MONITOR) == PFM_REG_MONITOR) +#define PMC_IS_CONTROL(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_CONTROL) == PFM_REG_CONTROL) + #define PMC_DFL_VAL(i) pmu_conf.pmc_desc[i].default_value #define PMC_RSVD_MASK(i) pmu_conf.pmc_desc[i].reserved_mask #define PMD_PMD_DEP(i) pmu_conf.pmd_desc[i].dep_pmd[0] @@ -232,6 +234,8 @@ */ #define PMC0_HAS_OVFL(cmp0) (cmp0 & ~0x1UL) +#define PFMFS_MAGIC 0xa0b4d889 + /* * debugging */ @@ -328,7 +332,7 @@ pfm_counter_t ctx_pmds[IA64_NUM_PMD_REGS]; /* software state for PMDS */ - u64 ctx_saved_psr; /* copy of psr used for ctxsw */ + u64 ctx_saved_psr_up; /* only contains psr.up value */ unsigned long ctx_last_activation; /* context last activation number for last_cpu */ unsigned int ctx_last_cpu; /* CPU id of current or last CPU used (SMP only) */ @@ -560,100 +564,6 @@ close: pfm_vm_close }; -/* - * Linux 2.5 vs. 2.4 helper macros and definitions - * - * if not at least 2.5.69, then assume 2.4.x. - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69) - -#define PFM_COMPILED_FOR_2_4 1 - -#include <linux/wrapper.h> - -#define pfm_get_cpu_var(v) local_cpu_data->v -#define pfm_get_cpu_data(a,b) cpu_data((b))->a -typedef void pfm_irq_handler_t; -#define PFM_IRQ_HANDLER_RET(v) - -#define DEFINE_PER_CPU(a,b) - -static inline int -pfm_wait_task_inactive(struct task_struct *task) -{ -#ifdef CONFIG_SMP - /* Make sure the child gets off its CPU.. */ - for (;;) { - task_lock(task); - if (!task_has_cpu(task)) break; - task_unlock(task); - do { - if (task->state != TASK_STOPPED) - return -ESRCH; - barrier(); - cpu_relax(); - } while (task_has_cpu(task)); - } - task_unlock(task); -#endif - return 0; -} - -static inline void -pfm_put_task(struct task_struct *task) -{ - if (task != current) free_task_struct(task); -} - -static inline void -pfm_set_task_notify(struct task_struct *task) -{ -} - -static inline void -pfm_clear_task_notify(void) -{ -} - -static inline void -pfm_reserve_page(unsigned long a) -{ - unsigned long page; - - page = ia64_tpa(a); - mem_map_reserve(virt_to_page(__va(page))); -} - -static inline void -pfm_unreserve_page(unsigned long a) -{ - unsigned long page; - - page = ia64_tpa(a); - mem_map_unreserve(virt_to_page(__va(page))); -} - -static inline int -pfm_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot) -{ - return remap_page_range(from, phys_addr, size, prot); -} - -static inline unsigned long -pfm_protect_ctx_ctxsw(pfm_context_t *x) -{ - unsigned long f; - spin_lock(&(x)->ctx_lock); - return f; -} - -static inline unsigned long -pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) -{ - spin_unlock(&(x)->ctx_lock); -} - -#else /* 2.5.69 or higher */ #define pfm_wait_task_inactive(t) wait_task_inactive(t) #define pfm_get_cpu_var(v) __get_cpu_var(v) @@ -705,7 +615,7 @@ static inline unsigned long pfm_protect_ctx_ctxsw(pfm_context_t *x) { - spin_lock_irq(&(x)->ctx_lock); + spin_lock(&(x)->ctx_lock); return 0UL; } @@ -715,7 +625,30 @@ spin_unlock(&(x)->ctx_lock); } -#endif /* 2.5 vs. 2.4 */ +static inline unsigned int +pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) +{ + return do_munmap(mm, addr, len); +} + +static inline unsigned long +pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec) +{ + return get_unmapped_area(file, addr, len, pgoff, flags); +} + + +static struct super_block * +pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) +{ + return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC); +} + +static struct file_system_type pfm_fs_type = { + .name = "pfmfs", + .get_sb = pfmfs_get_sb, + .kill_sb = kill_anon_super, +}; DEFINE_PER_CPU(unsigned long, pfm_syst_info); DEFINE_PER_CPU(struct task_struct *, pmu_owner); @@ -758,13 +691,13 @@ static inline void pfm_clear_psr_up(void) { - __asm__ __volatile__ ("rum psr.up;; srlz.i;;"::: "memory"); + __asm__ __volatile__ ("rsm psr.up;; srlz.i;;"::: "memory"); } static inline void pfm_set_psr_up(void) { - __asm__ __volatile__ ("sum psr.up;; srlz.i;;"::: "memory"); + __asm__ __volatile__ ("ssm psr.up;; srlz.i;;"::: "memory"); } static inline unsigned long @@ -1502,7 +1435,7 @@ DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size)); - r = do_munmap(task->mm, (unsigned long)vaddr, size); + r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0); up_write(&task->mm->mmap_sem); if (r !=0) { @@ -1569,68 +1502,6 @@ * d_name - pfm: will go nicely and kill the special-casing in procfs. */ static struct vfsmount *pfmfs_mnt; -#define PFMFS_MAGIC 0xa0b4d889 - -#ifdef PFM_COMPILED_FOR_2_4 - -static int -pfmfs_statfs(struct super_block *sb, struct statfs *buf) -{ - buf->f_type = PFMFS_MAGIC; - buf->f_bsize = 1024; - buf->f_namelen = 255; - return 0; -} - -static struct super_operations pfmfs_ops = { - statfs: pfmfs_statfs, -}; - -static struct super_block * -pfmfs_read_super(struct super_block *sb, void *data, int silent) -{ - struct inode *root = new_inode(sb); - if (!root) - return NULL; - root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; - root->i_uid = root->i_gid = 0; - root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME; - sb->s_blocksize = 1024; - sb->s_blocksize_bits = 10; - sb->s_magic = PFMFS_MAGIC; - sb->s_op = &pfmfs_ops; - sb->s_root = d_alloc(NULL, &(const struct qstr) { "pfm:", 4, 0 }); - if (!sb->s_root) { - iput(root); - return NULL; - } - sb->s_root->d_sb = sb; - sb->s_root->d_parent = sb->s_root; - d_instantiate(sb->s_root, root); - return sb; -} - -//static DECLARE_FSTYPE(pfm_fs_type, "pfmfs", pfmfs_read_super, FS_NOMOUNT); -static struct file_system_type pfm_fs_type = { - name: "pfmfs", - read_super: pfmfs_read_super, - fs_flags: FS_NOMOUNT, -}; - -#else /* ! COMPILED_FOR_2_4 */ - -static struct super_block * -pfmfs_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data) -{ - return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC); -} - -static struct file_system_type pfm_fs_type = { - .name = "pfmfs", - .get_sb = pfmfs_get_sb, - .kill_sb = kill_anon_super, -}; -#endif /* COMPILED_FOR_2_4 */ static int __init init_pfm_fs(void) @@ -2453,7 +2324,7 @@ down_write(&task->mm->mmap_sem); /* find some free area in address space, must have mmap sem held */ - vma->vm_start = get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS); + vma->vm_start = pfm_get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS, 0); if (vma->vm_start == 0UL) { DPRINT(("Cannot find unmapped area for size %ld\n", size)); up_write(&task->mm->mmap_sem); @@ -3020,7 +2891,7 @@ * as attempts to modify PMC[0-3] which are used * as status registers by the PMU */ - if (!PMC_IS_IMPL(cnum) || cnum < 4) { + if (PMC_IS_IMPL(cnum) == 0 || PMC_IS_CONTROL(cnum)) { DPRINT(("pmc%u is unimplemented or invalid\n", cnum)); goto error; } @@ -4124,7 +3995,7 @@ /* * monitoring disabled in kernel at next reschedule */ - ctx->ctx_saved_psr &= ~IA64_PSR_UP; + ctx->ctx_saved_psr_up = 0; printk("pfm_stop: current [%d] task=[%d]\n", current->pid, ctx->ctx_task->pid); } return 0; @@ -4198,7 +4069,7 @@ * start monitoring at the kernel level the next * time the task is scheduled */ - ctx->ctx_saved_psr |= IA64_PSR_UP; + ctx->ctx_saved_psr_up = IA64_PSR_UP; /* * activate monitoring at user level @@ -4429,7 +4300,7 @@ SET_LAST_CPU(ctx, -1); /* initial saved psr (stopped) */ - ctx->ctx_saved_psr = pfm_get_psr() & ~(IA64_PSR_PP|IA64_PSR_UP); + ctx->ctx_saved_psr_up = 0UL; ia64_psr(regs)->up = ia64_psr(regs)->pp = 0; if (ctx->ctx_fl_unsecure) { @@ -5640,6 +5511,7 @@ unsigned long flags; u64 psr; + ctx = PFM_GET_CTX(task); if (ctx == NULL) goto save_error; t = &task->thread; @@ -5672,9 +5544,9 @@ * sanity check */ if (ctx->ctx_last_activation != GET_ACTIVATION()) { - DPRINT(("ctx_activation=%lu activation=%lu state=%d: no save\n", + printk("ctx_activation=%lu activation=%lu state=%d: no save\n", ctx->ctx_last_activation, - GET_ACTIVATION(), ctx->ctx_state)); + GET_ACTIVATION(), ctx->ctx_state); pfm_unprotect_ctx_ctxsw(ctx, flags); @@ -5684,8 +5556,11 @@ /* * save current PSR: needed because we modify it */ + ia64_srlz_d(); psr = pfm_get_psr(); + BUG_ON(psr & (IA64_PSR_I)); + /* * stop monitoring: * This is the last instruction which may generate an overflow @@ -5696,9 +5571,13 @@ pfm_clear_psr_up(); /* - * keep a copy of the saved psr (for reload) + * keep a copy of psr.up (for reload) */ - ctx->ctx_saved_psr = psr; + ctx->ctx_saved_psr_up = psr & IA64_PSR_UP; + + { u64 foo = pfm_get_psr(); + BUG_ON(foo & ((IA64_PSR_UP|IA64_PSR_PP))); + } /* * release ownership of this PMU. @@ -5772,18 +5651,16 @@ pfm_clear_psr_up(); /* - * keep a copy of the saved psr (for reload) + * keep a copy of psr.up (for reload) */ - ctx->ctx_saved_psr = psr; + ctx->ctx_saved_psr_up = psr & IA64_PSR_UP; - psr = pfm_get_psr(); - if (psr & IA64_PSR_UP) { - printk(KERN_ERR " perfmon: pfm_save_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, GET_PMU_OWNER()->pid, psr); - } - if (psr & IA64_PSR_I) { - printk(KERN_ERR " perfmon: pfm_save_regs: psr.i set current [%d] owner [%d] psr=0x%lx\n", current->pid, GET_PMU_OWNER()->pid, psr); +#if 1 + { u64 foo = pfm_get_psr(); + BUG_ON(foo & (IA64_PSR_I)); + BUG_ON(foo & ((IA64_PSR_UP|IA64_PSR_PP))); } - +#endif return; save_error: printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n", @@ -5797,13 +5674,10 @@ pfm_context_t *ctx; struct thread_struct *t; unsigned long flags; - unsigned long psr; #if 1 - psr = pfm_get_psr(); - if (psr & IA64_PSR_UP) { - printk(KERN_ERR " perfmon: pfm_lazy_save_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, task->pid, psr); - pfm_clear_psr_up(); + { u64 foo = pfm_get_psr(); + BUG_ON(foo & IA64_PSR_UP); } #endif @@ -5864,10 +5738,9 @@ { pfm_context_t *ctx; struct thread_struct *t; - struct task_struct *owner; unsigned long pmc_mask = 0UL, pmd_mask = 0UL; unsigned long flags; - u64 psr; + u64 psr, psr_up; ctx = PFM_GET_CTX(task); if (unlikely(ctx == NULL)) { @@ -5875,22 +5748,21 @@ return; } - owner = GET_PMU_OWNER(); + BUG_ON(GET_PMU_OWNER()); + t = &task->thread; + psr = pfm_get_psr(); #if 1 - psr = pfm_get_psr(); - BUG_ON(psr & IA64_PSR_UP); - psr = pfm_get_psr(); + BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); BUG_ON(psr & IA64_PSR_I); #endif - /* * possible on unload */ if (unlikely((t->flags & IA64_THREAD_PM_VALID) == 0)) { - DPRINT(("[%d] PM_VALID=0, nothing to do\n", task->pid)); + printk("[%d] PM_VALID=0, nothing to do\n", task->pid); return; } @@ -5923,19 +5795,15 @@ /* * we restore ALL the debug registers to avoid picking up * stale state. - * - * This must be done even when the task is still the owner - * as the registers may have been modified via ptrace() - * (not perfmon) by the previous task. */ if (ctx->ctx_fl_using_dbreg) { pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs); pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs); } /* - * retrieve saved psr + * retrieve saved psr.up */ - psr = ctx->ctx_saved_psr; + psr_up = ctx->ctx_saved_psr_up; /* * if we were the last user of the PMU on that CPU, @@ -5968,8 +5836,8 @@ */ pmc_mask = ctx->ctx_all_pmcs[0]; - DPRINT(("full reload for [%d] owner=%d activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n", - task->pid, owner ? owner->pid : -1, + DPRINT(("full reload for [%d] activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n", + task->pid, GET_ACTIVATION(), ctx->ctx_last_activation, GET_LAST_CPU(ctx), pmd_mask, pmc_mask)); @@ -6026,9 +5894,9 @@ SET_PMU_OWNER(task, ctx); /* - * restore the psr we changed + * restore the psr.up bit */ - pfm_set_psr_l(psr); + if (likely(psr_up)) pfm_set_psr_up(); /* * allow concurrent access to context @@ -6047,21 +5915,16 @@ pfm_context_t *ctx; struct task_struct *owner; unsigned long pmd_mask, pmc_mask; - u64 psr; + u64 psr, psr_up; - owner = GET_PMU_OWNER(); - ctx = PFM_GET_CTX(task); - t = &task->thread; + owner = GET_PMU_OWNER(); + ctx = PFM_GET_CTX(task); + t = &task->thread; + psr = pfm_get_psr(); #if 1 - psr = pfm_get_psr(); - if (psr & IA64_PSR_UP) { - printk(KERN_ERR " perfmon: pfm_load_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, owner->pid, psr); - } - psr = pfm_get_psr(); - if (psr & IA64_PSR_I) { - printk(KERN_ERR " perfmon: pfm_load_regs: psr.i set current [%d] owner [%d] psr=0x%lx\n", current->pid, owner->pid, psr); - } + BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); + BUG_ON(psr & IA64_PSR_I); #endif /* @@ -6078,9 +5941,9 @@ } /* - * retrieved save psr + * retrieved saved psr.up */ - psr = ctx->ctx_saved_psr; + psr_up = ctx->ctx_saved_psr_up; /* * short path, our state is still there, just @@ -6091,7 +5954,7 @@ * concurrency even without interrupt masking. */ if (likely(owner == task)) { - pfm_set_psr_l(psr); + if (likely(psr_up)) pfm_set_psr_up(); return; } @@ -6163,8 +6026,7 @@ * restore the psr. This is the point at which * new overflow interrupts can be generated again. */ - pfm_set_psr_l(psr); - + if (likely(psr_up)) pfm_set_psr_up(); } #endif /* CONFIG_SMP */ @@ -6469,13 +6331,13 @@ printk("pmd[%d]=0x%lx tpmd=0x%lx\n", i, ia64_get_pmd(i), t->pmds[i]); } if (ctx) { - printk("ctx_state=%d vaddr=%p addr=%p fd=%d ctx_task=[%d] saved_psr=0x%lx\n", + printk("ctx_state=%d vaddr=%p addr=%p fd=%d ctx_task=[%d] saved_psr_up=0x%lx\n", ctx->ctx_state, ctx->ctx_smpl_vaddr, ctx->ctx_smpl_hdr, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, - ctx->ctx_saved_psr); + ctx->ctx_saved_psr_up); } } diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c --- a/arch/ia64/kernel/smpboot.c Fri Jun 27 14:19:54 2003 +++ b/arch/ia64/kernel/smpboot.c Fri Jun 27 14:19:54 2003 @@ -452,7 +452,7 @@ sapicid = smp_boot_data.cpu_phys_id[i]; if (sapicid == boot_cpu_id) continue; - phys_cpu_present_map |= (1 << cpu); + phys_cpu_present_map |= (1UL << cpu); ia64_cpu_to_sapicid[cpu] = sapicid; cpu++; } diff -Nru a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile --- a/arch/ia64/lib/Makefile Fri Jun 27 14:20:04 2003 +++ b/arch/ia64/lib/Makefile Fri Jun 27 14:20:04 2003 @@ -12,12 +12,7 @@ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o - -ifeq ($(CONFIG_MD_RAID5),m) - lib-y += xor.o -else - lib-$(CONFIG_MD_RAID5) += xor.o -endif +lib-$(CONFIG_MD_RAID5) += xor.o IGNORE_FLAGS_OBJS = __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o diff -Nru a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c --- a/arch/ia64/pci/pci.c Fri Jun 27 14:19:56 2003 +++ b/arch/ia64/pci/pci.c Fri Jun 27 14:19:56 2003 @@ -53,21 +53,21 @@ * synchronization mechanism here. */ -#define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) \ +#define PCI_SAL_ADDRESS(seg, bus, devfn, reg) \ ((u64)(seg << 24) | (u64)(bus << 16) | \ - (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg)) + (u64)(devfn << 8) | (u64)(reg)) static int -pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) +pci_sal_read (int seg, int bus, int devfn, int reg, int len, u32 *value) { int result = 0; u64 data = 0; - if (!value || (seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if (!value || (seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; - result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data); + result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, devfn, reg), len, &data); *value = (u32) data; @@ -75,12 +75,12 @@ } static int -pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) +pci_sal_write (int seg, int bus, int devfn, int reg, int len, u32 value) { - if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) + if ((seg > 255) || (bus > 255) || (devfn > 255) || (reg > 255)) return -EINVAL; - return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value); + return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, devfn, reg), len, value); } struct pci_raw_ops pci_sal_ops = { @@ -95,14 +95,14 @@ pci_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) { return raw_pci_ops->read(pci_domain_nr(bus), bus->number, - PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, value); + devfn, where, size, value); } static int pci_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { return raw_pci_ops->write(pci_domain_nr(bus), bus->number, - PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, value); + devfn, where, size, value); } static struct pci_ops pci_root_ops = { @@ -284,21 +284,21 @@ } struct pci_bus * -pcibios_scan_root (void *handle, int seg, int bus) +pci_acpi_scan_root (struct acpi_device *device, int domain, int bus) { struct pci_root_info info; struct pci_controller *controller; unsigned int windows = 0; char *name; - printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus); - controller = alloc_pci_controller(seg); + printk("PCI: Probing PCI hardware on bus (%04x:%02x)\n", domain, bus); + controller = alloc_pci_controller(domain); if (!controller) goto out1; - controller->acpi_handle = handle; + controller->acpi_handle = device->handle; - acpi_walk_resources(handle, METHOD_NAME__CRS, count_window, &windows); + acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, &windows); controller->window = kmalloc(sizeof(*controller->window) * windows, GFP_KERNEL); if (!controller->window) goto out2; @@ -307,10 +307,10 @@ if (!name) goto out3; - sprintf(name, "PCI Bus %02x:%02x", seg, bus); + sprintf(name, "PCI Bus %04x:%02x", domain, bus); info.controller = controller; info.name = name; - acpi_walk_resources(handle, METHOD_NAME__CRS, add_window, &info); + acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); return scan_root_bus(bus, &pci_root_ops, controller); @@ -363,8 +363,6 @@ return; } - -#warning pcibios_update_resource() is now a generic implementation - please check void __devinit pcibios_update_irq (struct pci_dev *dev, int irq) diff -Nru a/arch/ia64/scripts/toolchain-flags b/arch/ia64/scripts/toolchain-flags --- a/arch/ia64/scripts/toolchain-flags Fri Jun 27 14:20:05 2003 +++ b/arch/ia64/scripts/toolchain-flags Fri Jun 27 14:20:05 2003 @@ -3,15 +3,13 @@ # Check whether linker can handle cross-segment @segrel(): # CC=$1 -LD=$2 -OBJDUMP=$3 +OBJDUMP=$2 dir=$(dirname $0) tmp=${TMPDIR:-/tmp} out=$tmp/out$$ -$CC -c $dir/check-segrel.S -o $out.o -$LD -static -T$dir/check-segrel.lds $out.o -o $out +$CC -nostdlib -static -Wl,-T$dir/check-segrel.lds $dir/check-segrel.S -o $out res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ') -rm -f $out $out.o +rm -f $out if [ $res != 00000a00 ]; then echo " -DHAVE_BUGGY_SEGREL" cat >&2 <<EOF diff -Nru a/arch/ia64/sn/io/drivers/Makefile b/arch/ia64/sn/io/drivers/Makefile --- a/arch/ia64/sn/io/drivers/Makefile Fri Jun 27 14:20:00 2003 +++ b/arch/ia64/sn/io/drivers/Makefile Fri Jun 27 14:20:00 2003 @@ -9,4 +9,4 @@ EXTRA_CFLAGS := -DLITTLE_ENDIAN -obj-y += ioconfig_bus.o ifconfig_net.o +obj-y += ioconfig_bus.o diff -Nru a/arch/ia64/sn/io/drivers/ifconfig_net.c b/arch/ia64/sn/io/drivers/ifconfig_net.c --- a/arch/ia64/sn/io/drivers/ifconfig_net.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,298 +0,0 @@ -/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * ifconfig_net - SGI's Persistent Network Device names. - * - * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. - */ - -#include <linux/types.h> -#include <linux/config.h> -#include <linux/slab.h> -#include <linux/ctype.h> -#include <linux/module.h> -#include <linux/init.h> - -#include <linux/pci.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> - -#include <asm/sn/sgi.h> -#include <linux/devfs_fs.h> -#include <linux/devfs_fs_kernel.h> -#include <asm/io.h> -#include <asm/sn/iograph.h> -#include <asm/sn/invent.h> -#include <asm/sn/hcl.h> -#include <asm/sn/labelcl.h> -#include <asm/sn/ifconfig_net.h> - -#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER" -#define SGI_IFCONFIG_NET_VERSION "1.0" - -/* - * Some Global definitions. - */ -static devfs_handle_t ifconfig_net_handle; -static unsigned long ifconfig_net_debug; - -/* - * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net". - */ -static int ifconfig_net_open(struct inode * inode, struct file * filp) -{ - if (ifconfig_net_debug) { - printk("ifconfig_net_open called.\n"); - } - - return(0); - -} - -/* - * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net". - */ -static int ifconfig_net_close(struct inode * inode, struct file * filp) -{ - - if (ifconfig_net_debug) { - printk("ifconfig_net_close called.\n"); - } - - return(0); -} - -/* - * assign_ifname - Assign the next available interface name from the persistent list. - */ -void -assign_ifname(struct net_device *dev, - struct ifname_num *ifname_num) - -{ - - /* - * Handle eth devices. - */ - if ( (memcmp(dev->name, "eth", 3) == 0) ) { - if (ifname_num->next_eth != -1) { - /* - * Assign it the next available eth interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "eth%d", (int)ifname_num->next_eth); - ifname_num->next_eth++; - } - - return; - } - - /* - * Handle fddi devices. - */ - if ( (memcmp(dev->name, "fddi", 4) == 0) ) { - if (ifname_num->next_fddi != -1) { - /* - * Assign it the next available fddi interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi); - ifname_num->next_fddi++; - } - - return; - } - - /* - * Handle hip devices. - */ - if ( (memcmp(dev->name, "hip", 3) == 0) ) { - if (ifname_num->next_hip != -1) { - /* - * Assign it the next available hip interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "hip%d", (int)ifname_num->next_hip); - ifname_num->next_hip++; - } - - return; - } - - /* - * Handle tr devices. - */ - if ( (memcmp(dev->name, "tr", 2) == 0) ) { - if (ifname_num->next_tr != -1) { - /* - * Assign it the next available tr interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "tr%d", (int)ifname_num->next_tr); - ifname_num->next_tr++; - } - - return; - } - - /* - * Handle fc devices. - */ - if ( (memcmp(dev->name, "fc", 2) == 0) ) { - if (ifname_num->next_fc != -1) { - /* - * Assign it the next available fc interface number. - */ - memset(dev->name, 0, strlen(dev->name)); - sprintf(dev->name, "fc%d", (int)ifname_num->next_fc); - ifname_num->next_fc++; - } - - return; - } -} - -/* - * find_persistent_ifname: Returns the entry that was seen in previous boot. - */ -struct ifname_MAC * -find_persistent_ifname(struct net_device *dev, - struct ifname_MAC *ifname_MAC) - -{ - - while (ifname_MAC->addr_len) { - if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0) - return(ifname_MAC); - - ifname_MAC++; - } - - return(NULL); -} - -/* - * ifconfig_net_ioctl: ifconfig_net driver ioctl interface. - */ -static int ifconfig_net_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - - extern struct net_device *__dev_get_by_name(const char *); -#ifdef CONFIG_NET - struct net_device *dev; - struct ifname_MAC *found; - char temp[64]; -#endif - struct ifname_MAC *ifname_MAC; - struct ifname_MAC *new_devices, *temp_new_devices; - struct ifname_num *ifname_num; - unsigned long size; - - - if (ifconfig_net_debug) { - printk("HCL: hcl_ioctl called.\n"); - } - - /* - * Read in the header and see how big of a buffer we really need to - * allocate. - */ - ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), - GFP_KERNEL); - copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num)); - size = ifname_num->size; - kfree(ifname_num); - ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL); - ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) ); - - copy_from_user( ifname_num, (char *) arg, size); - new_devices = kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL); - temp_new_devices = new_devices; - - memset(new_devices, 0, size - sizeof(struct ifname_num)); - -#ifdef CONFIG_NET - /* - * Go through the net device entries and make them persistent! - */ - for (dev = dev_base; dev != NULL; dev = dev->next) { - /* - * Skip NULL entries or "lo" - */ - if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){ - continue; - } - - /* - * See if we have a persistent interface name for this device. - */ - found = NULL; - found = find_persistent_ifname(dev, ifname_MAC); - if (found) { - strcpy(dev->name, found->name); - } else { - /* Never seen this before .. */ - assign_ifname(dev, ifname_num); - - /* - * Save the information for the next boot. - */ - sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, - dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], - dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); - strcpy(temp_new_devices->name, dev->name); - temp_new_devices->addr_len = dev->addr_len; - memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len); - temp_new_devices++; - } - - } -#endif - - /* - * Copy back to the User Buffer area any new devices encountered. - */ - copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, - size - sizeof(struct ifname_num)); - - return(0); - -} - -struct file_operations ifconfig_net_fops = { - ioctl:ifconfig_net_ioctl, /* ioctl */ - open:ifconfig_net_open, /* open */ - release:ifconfig_net_close /* release */ -}; - - -/* - * init_ifconfig_net() - Boot time initialization. Ensure that it is called - * after devfs has been initialized. - * - */ -#ifdef MODULE -int init_module (void) -#else -int __init init_ifconfig_net(void) -#endif -{ - ifconfig_net_handle = NULL; - ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net", - 0, 0, - 0, 0, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, - &ifconfig_net_fops, NULL); - - if (ifconfig_net_handle == NULL) { - panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n"); - } - - return(0); - -} diff -Nru a/arch/ia64/sn/io/hwgfs/hcl.c b/arch/ia64/sn/io/hwgfs/hcl.c --- a/arch/ia64/sn/io/hwgfs/hcl.c Fri Jun 27 14:19:57 2003 +++ b/arch/ia64/sn/io/hwgfs/hcl.c Fri Jun 27 14:19:57 2003 @@ -113,22 +113,10 @@ } struct file_operations hcl_fops = { - (struct module *)0, - NULL, /* lseek - default */ - NULL, /* read - general block-dev read */ - NULL, /* write - general block-dev write */ - NULL, /* readdir - bad */ - NULL, /* poll */ - hcl_ioctl, /* ioctl */ - NULL, /* mmap */ - hcl_open, /* open */ - NULL, /* flush */ - hcl_close, /* release */ - NULL, /* fsync */ - NULL, /* fasync */ - NULL, /* lock */ - NULL, /* readv */ - NULL, /* writev */ + .owner = (struct module *)0, + .ioctl = hcl_ioctl, + .open = hcl_open, + .release = hcl_close, }; @@ -140,7 +128,6 @@ { extern void string_table_init(struct string_table *); extern struct string_table label_string_table; - extern int init_ifconfig_net(void); extern int init_ioconfig_bus(void); extern int init_hwgfs_fs(void); int rv = 0; @@ -195,7 +182,6 @@ * Initialize the ifconfgi_net driver that does network devices * Persistent Naming. */ - init_ifconfig_net(); init_ioconfig_bus(); return(0); @@ -258,6 +244,7 @@ if (!de) { printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n"); + dump_stack(); return(-1); } @@ -568,7 +555,7 @@ * In this case the vertex was previous created with a REAL pathname. */ rv = hwgfs_mk_symlink (from, (const char *)name, - DEVFS_FL_DEFAULT, link, + 0, link, &handle, NULL); kfree(path); kfree(link); diff -Nru a/arch/ia64/sn/io/machvec/pci.c b/arch/ia64/sn/io/machvec/pci.c --- a/arch/ia64/sn/io/machvec/pci.c Fri Jun 27 14:19:54 2003 +++ b/arch/ia64/sn/io/machvec/pci.c Fri Jun 27 14:19:54 2003 @@ -49,6 +49,8 @@ vertex_hdl_t device_vertex; device_vertex = devfn_to_vertex(bus->number, devfn); + if (!device_vertex) + return PCIBIOS_DEVICE_NOT_FOUND; res = pciio_config_get(device_vertex, (unsigned) where, size); *val = (unsigned int) res; return PCIBIOS_SUCCESSFUL; @@ -59,6 +61,8 @@ vertex_hdl_t device_vertex; device_vertex = devfn_to_vertex(bus->number, devfn); + if (!device_vertex) + return PCIBIOS_DEVICE_NOT_FOUND; pciio_config_set( device_vertex, (unsigned)where, size, (uint64_t) val); return PCIBIOS_SUCCESSFUL; } diff -Nru a/arch/ia64/sn/io/machvec/pci_dma.c b/arch/ia64/sn/io/machvec/pci_dma.c --- a/arch/ia64/sn/io/machvec/pci_dma.c Fri Jun 27 14:19:54 2003 +++ b/arch/ia64/sn/io/machvec/pci_dma.c Fri Jun 27 14:19:54 2003 @@ -280,7 +280,7 @@ */ for (i = 0; i < nents; i++, sg++) { phys_addr = __pa(sg->dma_address ? sg->dma_address : - page_address(sg->page) + sg->offset); + (unsigned long)page_address(sg->page) + sg->offset); /* * Handle the most common case: 64 bit cards. This @@ -578,7 +578,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - return pci_dma_supported(to_pci_dev(dev), mask); + return sn_pci_dma_supported(to_pci_dev(dev), mask); } EXPORT_SYMBOL(sn_dma_supported); @@ -587,7 +587,11 @@ { BUG_ON(dev->bus != &pci_bus_type); - return pci_set_dma_mask(to_pci_dev(dev), dma_mask); + if (!sn_dma_supported(dev, dma_mask)) + return 0; + + dev->dma_mask = dma_mask; + return 1; } EXPORT_SYMBOL(sn_dma_set_mask); @@ -597,7 +601,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle); + return sn_pci_alloc_consistent(to_pci_dev(dev), size, dma_handle); } EXPORT_SYMBOL(sn_dma_alloc_coherent); @@ -607,7 +611,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle); + sn_pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle); } EXPORT_SYMBOL(sn_dma_free_coherent); @@ -617,7 +621,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction); + return sn_pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction); } EXPORT_SYMBOL(sn_dma_map_single); @@ -627,7 +631,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction); + sn_pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction); } EXPORT_SYMBOL(sn_dma_unmap_single); @@ -658,7 +662,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); + return sn_pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); } EXPORT_SYMBOL(sn_dma_map_sg); @@ -668,7 +672,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction); + sn_pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction); } EXPORT_SYMBOL(sn_dma_unmap_sg); @@ -678,7 +682,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction); + sn_pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction); } EXPORT_SYMBOL(sn_dma_sync_single); @@ -688,7 +692,7 @@ { BUG_ON(dev->bus != &pci_bus_type); - pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction); + sn_pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction); } EXPORT_SYMBOL(sn_dma_sync_sg); diff -Nru a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile --- a/arch/ia64/sn/kernel/Makefile Fri Jun 27 14:19:53 2003 +++ b/arch/ia64/sn/kernel/Makefile Fri Jun 27 14:19:53 2003 @@ -9,7 +9,8 @@ EXTRA_CFLAGS := -DLITTLE_ENDIAN -obj-y := probe.o setup.o sv.o bte.o irq.o mca.o sn2/ +obj-y := probe.o setup.o sv.o bte.o irq.o mca.o \ + idle.o sn2/ obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_MODULES) += sn_ksyms.o diff -Nru a/arch/ia64/sn/kernel/idle.c b/arch/ia64/sn/kernel/idle.c --- a/arch/ia64/sn/kernel/idle.c Fri Jun 27 14:20:06 2003 +++ b/arch/ia64/sn/kernel/idle.c Fri Jun 27 14:20:06 2003 @@ -12,7 +12,7 @@ void snidle(int state) { if (state) { - if (pda.idle_flag == 0) { + if (pda->idle_flag == 0) { /* * Turn the activity LED off. */ @@ -24,13 +24,13 @@ SIMULATOR_SLEEP(); #endif - pda.idle_flag = 1; + pda->idle_flag = 1; } else { /* * Turn the activity LED on. */ set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY); - pda.idle_flag = 0; + pda->idle_flag = 0; } } diff -Nru a/arch/ia64/sn/kernel/machvec.c b/arch/ia64/sn/kernel/machvec.c --- a/arch/ia64/sn/kernel/machvec.c Fri Jun 27 14:19:57 2003 +++ b/arch/ia64/sn/kernel/machvec.c Fri Jun 27 14:19:57 2003 @@ -31,4 +31,5 @@ */ #define MACHVEC_PLATFORM_NAME sn2 +#define MACHVEC_PLATFORM_HEADER <asm/machvec_sn2.h> #include <asm/machvec_init.h> diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c --- a/arch/ia64/sn/kernel/setup.c Fri Jun 27 14:19:54 2003 +++ b/arch/ia64/sn/kernel/setup.c Fri Jun 27 14:19:54 2003 @@ -75,11 +75,13 @@ #define pxm_to_nasid(pxm) ((pxm)<<1) +#define MAX_PHYS_MEMORY (1UL << 49) /* 1 TB */ + extern void bte_init_node (nodepda_t *, cnodeid_t); extern void bte_init_cpu (void); -extern void sn_timer_init (void); +extern void sn_timer_init(void); extern void (*ia64_mark_idle)(int); -void snidle(int); +extern void snidle(int); unsigned long sn_rtc_cycles_per_second; @@ -296,21 +298,20 @@ */ sn_check_for_wars(); + ia64_mark_idle = &snidle; + /* * For the bootcpu, we do this here. All other cpus will make the * call as part of cpu_init in slave cpu initialization. */ sn_cpu_init(); - #ifdef CONFIG_SMP init_smp_config(); #endif screen_info = sn_screen_info; sn_timer_init(); - - ia64_mark_idle = &snidle; } /** @@ -437,20 +438,4 @@ } bte_init_cpu(); -} - -void snidle(int idleness) -{ - if (!idleness) { - if (pda->idle_flag == 0) { - set_led_bits(0, LED_CPU_ACTIVITY); - } - - pda->idle_flag = 1; - } - else { - set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY); - - pda->idle_flag = 0; - } } diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig --- a/arch/m68k/Kconfig Fri Jun 27 14:19:58 2003 +++ b/arch/m68k/Kconfig Fri Jun 27 14:19:58 2003 @@ -585,32 +585,7 @@ source "drivers/ide/Kconfig" - -menu "SCSI device support" - -config SCSI - tristate "SCSI device support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "net/Kconfig" diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig --- a/arch/m68knommu/Kconfig Fri Jun 27 14:19:59 2003 +++ b/arch/m68knommu/Kconfig Fri Jun 27 14:19:59 2003 @@ -499,6 +499,7 @@ default y config KCORE_ELF + bool default y source "fs/Kconfig.binfmt" @@ -527,59 +528,9 @@ source "drivers/ide/Kconfig" - -menu "SCSI device support" - -config SCSI - tristate "SCSI device support" - help - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - source "drivers/scsi/Kconfig" -endmenu - - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - depends on ISA - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - source "drivers/cdrom/Kconfig" - -endmenu - source "drivers/md/Kconfig" diff -Nru a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c --- a/arch/m68knommu/kernel/time.c Fri Jun 27 14:19:59 2003 +++ b/arch/m68knommu/kernel/time.c Fri Jun 27 14:19:59 2003 @@ -162,28 +162,33 @@ tv->tv_usec = usec; } -void do_settimeofday(struct timeval *tv) +int do_settimeofday(struct timespec *tv) { + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + write_seqlock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec + /* + * This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. * Discover what correction gettimeofday * would have done, and then undo it! */ if (mach_gettimeoffset) - tv->tv_usec -= mach_gettimeoffset(); + tv->tv_nsec -= (mach_gettimeoffset() * 1000); - while (tv->tv_usec < 0) { - tv->tv_usec += 1000000; + while (tv->tv_nsec < 0) { + tv->tv_nsec += NSEC_PER_SEC; tv->tv_sec--; } xtime.tv_sec = tv->tv_sec; - xtime.tv_nsec = (tv->tv_usec * 1000); + xtime.tv_nsec = tv->tv_nsec; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; write_sequnlock_irq(&xtime_lock); + return 0; } diff -Nru a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c --- a/arch/m68knommu/kernel/traps.c Fri Jun 27 14:19:55 2003 +++ b/arch/m68knommu/kernel/traps.c Fri Jun 27 14:19:55 2003 @@ -82,7 +82,7 @@ printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, PAGE_SIZE+(unsigned long)current); - show_stack((unsigned long *)fp); + show_stack(NULL, (unsigned long *)fp); do_exit(SIGSEGV); } @@ -106,7 +106,7 @@ int kstack_depth_to_print = 48; -void show_stack(unsigned long *esp) +void show_stack(struct task_struct *task, unsigned long *esp) { unsigned long *stack, *endstack, addr; extern char _start, _etext; diff -Nru a/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S b/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S --- a/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S Fri Jun 27 14:19:54 2003 +++ b/arch/m68knommu/platform/5206e/MOTOROLA/crt0_ram.S Fri Jun 27 14:19:54 2003 @@ -96,6 +96,7 @@ movec %d0, %CACR /* Enable cache */ +#ifdef CONFIG_ROMFS_FS /* * Move ROM filesystem above bss :-) */ @@ -116,6 +117,12 @@ move.l %d0, -(%a1) cmp.l %a0, %a2 /* Check if at end */ bne _copy_romfs + +#else /* CONFIG_ROMFS_FS */ + lea.l _ebss, %a1 + move.l %a1, _ramstart +#endif /* CONFIG_ROMFS_FS */ + /* * Zero out the bss region. diff -Nru a/arch/m68knommu/platform/5272/NETtel/crt0_ram.S b/arch/m68knommu/platform/5272/NETtel/crt0_ram.S --- a/arch/m68knommu/platform/5272/NETtel/crt0_ram.S Fri Jun 27 14:20:00 2003 +++ b/arch/m68knommu/platform/5272/NETtel/crt0_ram.S Fri Jun 27 14:20:00 2003 @@ -116,6 +116,8 @@ movec %d0, %CACR /* Enable cache */ nop + +#ifdef CONFIG_ROMFS_FS #ifdef CONFIG_ROMFS_FROM_ROM /* * check for an in RAM romfs @@ -159,6 +161,12 @@ move.l %a1, _ramstart /* Set start of ram */ done_romfs: #endif + +#else /* CONFIG_ROMFS_FS */ + lea.l _ebss, %a1 + move.l %a1, _ramstart +#endif /* CONFIG_ROMFS_FS */ + /* * Zero out the bss region. diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig --- a/arch/mips/Kconfig Fri Jun 27 14:19:56 2003 +++ b/arch/mips/Kconfig Fri Jun 27 14:19:56 2003 @@ -6,1113 +6,12 @@ bool default y -config MMU +config MIPS32 bool default y -config SMP +config MIPS64 bool - ---help--- - This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. - - If you say N here, the kernel will run on single and multiprocessor - machines, but will use only one CPU of a multiprocessor machine. If - you say Y here, the kernel will run on many, but not all, - singleprocessor machines. On a singleprocessor machine, the kernel - will run faster if you say N here. - - Note that if you say Y here and choose architecture "586" or - "Pentium" under "Processor family", the kernel will not work on 486 - architectures. Similarly, multiprocessor kernels for the "PPro" - architecture may not work on all Pentium based boards. - - People using multiprocessor machines who say Y here should also say - Y to "Enhanced Real Time Clock Support", below. The "Advanced Power - Management" code will be disabled if you say Y here. - - See also the <file:Documentation/smp.tex>, - <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>, - <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at - <http://www.tldp.org/docs.html#howto>. - - If you don't know what to do here, say N. - -config GENERIC_ISA_DMA - bool - default y - - -mainmenu "Linux Kernel Configuration" - -source "init/Kconfig" - - -menu "Machine selection" - -config ACER_PICA_61 - bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This is a machine with a R4400 133/150 MHz CPU. To compile a Linux - kernel that runs on these, say Y here. For details about Linux on - the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - <http://oss.sgi.com/mips/>. - -config ALGOR_P4032 - bool "Support for Algorithmics P4032 (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This is an evaluation board of the British company Algorithmics. - The board uses the R4300 and a R5230 CPUs. For more information - about this board see <http://www.algor.co.uk/>. - -config BAGET_MIPS - bool "Support for BAGET MIPS series (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This enables support for the Baget, a Russian embedded system. For - more details about the Baget see the Linux/MIPS FAQ on - <http://oss.sgi.com/mips/>. - -config DECSTATION - bool "Support for DECstations (EXPERIMENTAL)" - depends on EXPERIMENTAL - ---help--- - This enables support for DEC's MIPS based workstations. For details - see the Linux/MIPS FAQ on <http://oss.sgi.com/mips/> and the - DECstation porting pages on <http://decstation.unix-ag.org/>. - - If you have one of the following DECstation Models you definitely - want to choose R4xx0 for the CPU Type: - - DECstation 5000/50 - DECstation 5000/150 - DECstation 5000/260 - DECsystem 5900/260 - - otherwise choose R3000. - -config DDB5074 - bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This enables support for the VR5000-based NEC DDB Vrc-5074 - evaluation board. - -config MIPS_EV96100 - bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This is an evaluation board based on the Galielo GT-96100 LAN/WAN - communications controllers containing a MIPS R5000 compatible core - running at 83MHz. Their website is <http://www.galileot.com/>. Say Y - here if you wish to build a kernel for this platform. - -config MIPS_EV64120 - bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This is an evaluation board based on the Galileo GT-64120 - single-chip system controller that contains a MIPS R5000 compatible - core running at 75/100MHz. Their website is located at - <http://www.galileot.com/>. Say Y here if you wish to build a - kernel for this platform. - -config EVB_PCI1 - bool "Enable Second PCI (PCI1)" - depends on MIPS_EV64120 - -choice - prompt "Galileo Chip Clock" - depends on MIPS_EV64120 - -config SYSCLK_75 - bool "75" - -config SYSCLK_83 - bool "83.3" - -config SYSCLK_100_1 - bool "100" - -endchoice - -config MIPS_ATLAS - bool "Support for MIPS Atlas board (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This enables support for the QED R5231-based MIPS Atlas evaluation - board. - -config MIPS_MALTA - bool "Support for MIPS Malta board (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - This enables support for the VR5000-based MIPS Malta evaluation - board. - -config NINO - bool "Support for Philips Nino (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - Say Y here to select a kernel for the Philips Nino Palm PC. The - website at <http://www.realitydiluted.com/projects/nino/index.html> - will have more information. - -choice - prompt "Nino Model Number" - depends on NINO - -config NINO_4MB - bool "Model-300/301/302/319" - help - Say Y here to build a kernel specifically for Nino Palm PCs with - 4MB of memory. These include models 300/301/302/319. - -config NINO_8MB - bool "Model-200/210/312/320/325/350/390" - help - Say Y here to build a kernel specifically for Nino Palm PCs with - 8MB of memory. These include models 200/210/312/320/325/350/390. - -config NINO_16MB - bool "Model-500/510" - help - Say Y here to build a kernel specifically for Nino 500/501 color - Palm PCs from Philips (INCOMPLETE). - -endchoice - -config MIPS_MAGNUM_4000 - bool "Support for Mips Magnum 4000" - help - This is a machine with a R4000 100 MHz CPU. To compile a Linux - kernel that runs on these, say Y here. For details about Linux on - the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - <http://oss.sgi.com/mips/>. - -config MOMENCO_OCELOT - bool "Support for Momentum Ocelot board" - help - The Ocelot is a MIPS-based Single Board Computer (SBC) made by - Momentum Computer <http://www.momenco.com/>. - -config DDB5476 - bool "Support for NEC DDB Vrc-5476" - help - This enables support for the R5432-based NEC DDB Vrc-5476 - evaluation board. - - Features : kernel debugging, serial terminal, NFS root fs, on-board - ether port (Need an additional patch at <http://linux.junsun.net/>), - USB, AC97, PCI, PCI VGA card & framebuffer console, IDE controller, - PS2 keyboard, PS2 mouse, etc. - -config DDB5477 - bool "Support for NEC DDB Vrc-5477" - help - This enables support for the R5432-based NEC DDB Vrc-5477 - evaluation board. - - Features : kernel debugging, serial terminal, NFS root fs, on-board - ether port (Need an additional patch at <http://linux.junsun.net/>), - USB, AC97, PCI, etc. - -config OLIVETTI_M700 - bool "Support for Olivetti M700-10" - help - This is a machine with a R4000 100 MHz CPU. To compile a Linux - kernel that runs on these, say Y here. For details about Linux on - the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at - <http://oss.sgi.com/mips/>. - -config SGI_IP22 - bool "Support for SGI IP22" - help - This are the SGI Indy, Challenge S and Indigo2, as well as certain - OEM variants like the Tandem CMN B006S. To compile a Linux kernel - that runs on these, say Y here. - -config SNI_RM200_PCI - bool "Support for SNI RM200 PCI" - help - The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens - Nixdorf Informationssysteme (SNI), parent company of Pyramid - Technology and now in turn merged with Fujitsu. Say Y here to - support this machine type. - -config MIPS_ITE8172 - bool "Support for ITE 8172G board" - help - Ths is an evaluation board made by ITE <http://www.ite.com.tw/> - with ATX form factor that utilizes a MIPS R5000 to work with its - ITE8172G companion internet appliance chip. The MIPS core can be - either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build - a kernel for this platform. - -config IT8172_REVC - bool "Support for older IT8172 (Rev C)" - depends on MIPS_ITE8172 - help - Say Y here to support the older, Revision C version of the Integrated - Technology Express, Inc. ITE8172 SBC. Vendor page at - <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the - board at <http://www.mvista.com/allies/semiconductor/ite.html>. - -config QTRONIX_KEYBOARD - bool "Enable Qtronix 990P Keyboard Support" - depends on MIPS_IVR || MIPS_ITE8172 - help - Images of Qtronix keyboards are at - <http://www.qtronix.com/keyboard.html>. - -config IT8172_CIR - bool - depends on QTRONIX_KEYBOARD && (MIPS_IVR || MIPS_ITE8172) - default y - -config PC_KEYB - bool "Enable PS2 Keyboard Support" if MIPS_ITE8172 && !QTRONIX_KEYBOARD - default y if NINO || MIPS_ITE8172 || DDB5476 || DDB5074 || SNI_RM200_PCI || SGI_IP22 || ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 - -config IT8172_SCR0 - bool "Enable Smart Card Reader 0 Support " - depends on MIPS_IVR || MIPS_ITE8172 - help - Say Y here to support smart-card reader 0 (SCR0) on the Integrated - Technology Express, Inc. ITE8172 SBC. Vendor page at - <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the - board at <http://www.mvista.com/allies/semiconductor/ite.html>. - -config IT8172_SCR1 - bool "Enable Smart Card Reader 1 Support " - depends on MIPS_ITE8172 - help - Say Y here to support smart-card reader 1 (SCR1) on the Integrated - Technology Express, Inc. ITE8172 SBC. Vendor page at - <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the - board at <http://www.mvista.com/allies/semiconductor/ite.html>. - -config MIPS_IVR - bool "Support for Globespan IVR board" - help - This is an evaluation board built by Globespan to showcase thir - iVR (Internet Video Recorder) design. It utilizes a QED RM5231 - R5000 MIPS core. More information can be found out their website - located at <http://www.globespan.net/products/product4.html>P. Say Y - here if you wish to build a kernel for this platform. - -config MIPS_PB1000 - bool "Support for Alchemy Semi PB1000 board" - help - This is an evaluation board built by Alchemy Semiconducttor to - showcase their Au1000 Internet Edge Processor. It is SOC design - containing a MIPS32 core running at 266/400/500MHz with many - integrated peripherals. Further information can be found at their - website, <http://www.alchemysemi.com/>. Say Y here if you wish to - build a kernel for this platform. - -config RWSEM_GENERIC_SPINLOCK - bool - default y - -config RWSEM_XCHGADD_ALGORITHM - bool - -# -# Select some configuration options automatically for certain systems. -# -config ISA - bool - depends on DDB5476 || DDB5074 || SNI_RM200_PCI || ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - help - Find out whether you have ISA slots on your motherboard. ISA is the - name of a bus system, i.e. the way the CPU talks to the other stuff - inside your box. Other bus systems are PCI, EISA, MicroChannel - (MCA) or VESA. ISA is an older system, now being displaced by PCI; - newer boards don't support it. If you have ISA, say Y, otherwise N. - -config EISA - bool - depends on ISA - default y - ---help--- - The Extended Industry Standard Architecture (EISA) bus was - developed as an open alternative to the IBM MicroChannel bus. - - The EISA bus provided some of the features of the IBM MicroChannel - bus while maintaining backward compatibility with cards made for - the older ISA bus. The EISA bus saw limited use between 1988 and - 1995 when it was made obsolete by the PCI bus. - - Say Y here if you are building a kernel for an EISA-based machine. - - Otherwise, say N. - -config PCI - bool - depends on MIPS_IVR || MIPS_ITE8172 || DDB5477 || DDB5476 || DDB5074 || SNI_RM200_PCI || MOMENCO_OCELOT || MIPS_MALTA || MIPS_ATLAS || ALGOR_P4032 || MIPS_EV64120 || MIPS_EV96100 - default y - help - Find out whether you have a PCI motherboard. PCI is the name of a - bus system, i.e. the way the CPU talks to the other stuff inside - your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or - VESA. If you have PCI, say Y, otherwise N. - - The PCI-HOWTO, available from - <http://www.tldp.org/docs.html#howto>, contains valuable - information about which PCI hardware does work under Linux and which - doesn't. - -config MCA - bool - help - MicroChannel Architecture is found in some IBM PS/2 machines and - laptops. It is a bus system similar to PCI or ISA. See - <file:Documentation/mca.txt> (and especially the web page given - there) before attempting to build an MCA bus kernel. - -config SBUS - bool - -config I8259 - bool - depends on DDB5074 || SNI_RM200_PCI || MIPS_MALTA || ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - -config MIPS_GT96100 - bool - depends on MIPS_EV96100 - default y - help - Say Y here to support the Galileo Technology GT96100 communications - controller card. There is a web page at <http://www.galileot.com/>. - -config SWAP_IO_SPACE - bool - depends on MOMENCO_OCELOT || MIPS_MALTA || MIPS_ATLAS || MIPS_EV96100 - default y - -config NEW_PCI - bool - depends on MIPS_ITE8172 || MIPS_EV96100 - default y - -config PCI_AUTO - bool - depends on MIPS_ITE8172 || MIPS_EV96100 - default y - -config MIPS_GT64120 - bool - depends on MIPS_EV64120 - default y - -config OLD_TIME_C - bool - depends on DDB5074 || SNI_RM200_PCI || SGI_IP22 || MOMENCO_OCELOT || ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ALGOR_P4032 || MIPS_EV64120 - default y - -config ARC32 - bool - depends on SNI_RM200_PCI || SGI_IP22 || ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - -config FB - bool - depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - ---help--- - The frame buffer device provides an abstraction for the graphics - hardware. It represents the frame buffer of some video hardware and - allows application software to access the graphics hardware through - a well-defined interface, so the software doesn't need to know - anything about the low-level (hardware register) stuff. - - Frame buffer devices work identically across the different - architectures supported by Linux and make the implementation of - application programs easier and more portable; at this point, an X - server exists which uses the frame buffer device exclusively. - On several non-X86 architectures, the frame buffer device is the - only way to use the graphics hardware. - - The device is accessed through special device nodes, usually located - in the /dev directory, i.e. /dev/fb*. - - You need an utility program called fbset to make full use of frame - buffer devices. Please read <file:Documentation/fb/framebuffer.txt> - and the Framebuffer-HOWTO at - <http://www.tahallah.demon.co.uk/programming/prog.html> for more - information. - - Say Y here and to the driver for your graphics board below if you - are compiling a kernel for a non-x86 architecture. - - If you are compiling for the x86 architecture, you can say Y if you - want to play with it, but it is not essential. Please note that - running graphical applications that directly touch the hardware - (e.g. an accelerated X server) and that are not frame buffer - device-aware may cause unexpected results. If unsure, say N. - -config FB_G364 - bool - depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - -config MIPS_JAZZ - bool - depends on ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - -config ROTTEN_IRQ - bool - depends on DDB5476 || DDB5074 || SNI_RM200_PCI || ACER_PICA_61 - default y - -config HAVE_STD_PC_SERIAL_PORT - bool - depends on DDB5476 || DDB5074 || MIPS_MALTA - default y - -config NEW_IRQ - bool - depends on MIPS_PB1000 || DDB5477 || SGI_IP22 || MOMENCO_OCELOT || MIPS_MALTA - default y - -config SYSCLK_100_2 - bool - depends on MOMENCO_OCELOT - default y - -config BOARD_SCACHE - bool - depends on SGI_IP22 - default y - -config SGI - bool - depends on SGI_IP22 - default y - -config NEW_TIME_C - bool - depends on DDB5477 || DDB5476 - default y - -config CPU_LITTLE_ENDIAN - bool - depends on DDB5477 - default y - help - Some MIPS machines can be configured for either little or big endian - byte order. These modes require different kernels. Say Y if your - machine is little endian, N if it's a big endian machine. - -config IT8712 - bool - depends on MIPS_ITE8172 - default y - -config MIPS_AU1000 - bool - depends on MIPS_PB1000 - default y - -config SYSCLK_100 - bool - depends on SYSCLK_100_1 || SYSCLK_100_2 - default y - -endmenu - - -menu "CPU selection" - -choice - prompt "CPU type" - default CPU_R4X00 - -config CPU_R3000 - bool "R3000" - ---help--- - Please make sure to pick the right CPU type. Linux/MIPS is not - designed to be generic, i.e. Kernels compiled for R3000 CPUs will - *not* work on R4000 machines and vice versa. However, since most - of the supported machines have an R4000 (or similar) CPU, R4x00 - might be a safe bet. If the resulting kernel does not work, - try to recompile with R3000. - - R3000 MIPS Technologies R3000-series processors, - including the 3041, 3051, and 3081. - - R6000 MIPS Technologies R6000-series processors, - including the 64474, 64475, 64574 and 64575. - - R4300 MIPS Technologies R4300-series processors. - - R4x00 MIPS Technologies R4000-series processors other than 4300, - including the 4640, 4650, and 4700. - - R5000 MIPS Technologies R5000-series processors other than the - Nevada. - - R52xx MIPS Technologies R52xx-series ("Nevada") processors. - - R10000 MIPS Technologies R10000-series processors. - -config CPU_R6000 - bool "R6000" - help - MIPS Technologies R6000-series processors, including the 64474, - 64475, 64574 and 64575. - -config CPU_VR41XX - bool "R41xx" - help - The options selects support for the NEC VR41xx series of processors. - Only choose this option if you have one of these processors as a - kernel built with this option will not run on any other type of - processor or vice versa. - -config CPU_R4300 - bool "R4300" - help - MIPS Technologies R4300-series processors. - -config CPU_R4X00 - bool "R4x00" - help - MIPS Technologies R4000-series processors other than 4300, including - the 4640, 4650, and 4700. - -config CPU_R5000 - bool "R5000" - help - MIPS Technologies R5000-series processors other than the Nevada. - -config CPU_R5432 - bool "R5432" - -config CPU_RM7000 - bool "RM7000" - -config CPU_NEVADA - bool "R52xx" - help - MIPS Technologies R52x0-series ("Nevada") processors. - -config CPU_R10000 - bool "R10000" - help - MIPS Technologies R10000-series processors. - -config CPU_SB1 - bool "SB1" - -config CPU_MIPS32 - bool "MIPS32" - -config CPU_MIPS64 - bool "MIPS64" - -endchoice - -config CPU_ADVANCED - bool "Override CPU Options" - help - Saying yes here allows you to select support for various features - your CPU may or may not have. Most people should say N here. - -config CPU_HAS_LLSC - bool "ll/sc Instructions available" if CPU_ADVANCED - default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX - help - MIPS R4000 series and later provide the Load Linked (ll) - and Store Conditional (sc) instructions. More information is - available at <http://www.go-ecs.com/mips/miptek1.htm>. - - Say Y here if your CPU has the ll and sc instructions. Say Y here - for better performance, N if you don't know. You must say Y here - for multiprocessor machines. - -config CPU_HAS_LLDSCD - bool "lld/scd Instructions available" if CPU_ADVANCED - default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_MIPS32 - help - Say Y here if your CPU has the lld and scd instructions, the 64-bit - equivalents of ll and sc. Say Y here for better performance, N if - you don't know. You must say Y here for multiprocessor machines. - -config CPU_HAS_WB - bool "Writeback Buffer available" if CPU_ADVANCED - default y if !CPU_ADVANCED && (CPU_R3000 || CPU_VR41XX) && CONFIG_DECSTATION=y - help - Say N here for slightly better performance. You must say Y here for - machines which require flushing of write buffers in software. Saying - Y is the safe option; N may result in kernel malfunction and crashes. - -endmenu - - -menu "General setup" - -config CPU_LITTLE_ENDIAN - bool "Generate little endian code" if !DECSTATION && !DDB5074 && !DDB5476 && !NINO - default y if DECSTATION || DDB5074 || DDB5476 || NINO - -config KCORE_ELF - bool - depends on PROC_FS - default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - -config ELF_KERNEL - bool - default y - -config BINFMT_IRIX - bool "Include IRIX binary compatibility" - depends on !CPU_LITTLE_ENDIAN - -config FORWARD_KEYBOARD - bool "Include forward keyboard" - depends on !CPU_LITTLE_ENDIAN - -config ARC_CONSOLE - bool "ARC console support" - depends on ARC32 - -source "fs/Kconfig.binfmt" - -source "drivers/pci/Kconfig" - -config HOTPLUG - bool "Support for hot-pluggable devices" - ---help--- - Say Y here if you want to plug devices into your computer while - the system is running, and be able to use them quickly. In many - cases, the devices can likewise be unplugged at any time too. - - One well known example of this is PCMCIA- or PC-cards, credit-card - size devices such as network cards, modems or hard drives which are - plugged into slots found on all modern laptop computers. Another - example, used on modern desktops as well as laptops, is USB. - - Enable HOTPLUG and KMOD, and build a modular kernel. Get agent - software (at <http://linux-hotplug.sourceforge.net/>) and install it. - Then your kernel will automatically call out to a user mode "policy - agent" (/sbin/hotplug) to load modules and set up software needed - to use devices as you hotplug them. - -source "drivers/pcmcia/Kconfig" - -config TC - bool "TURBOchannel support" - depends on DECSTATION - help - TurboChannel is a DEC (now Compaq) bus for Alpha and MIPS processors. - Documentation on writing device drivers for TurboChannel is available at: - <http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>. - -# if [ "$CONFIG_TC" = "y" ]; then -# bool ' Access.Bus support' CONFIG_ACCESSBUS -# fi -endmenu - - -if ISA -source "drivers/pnp/Kconfig" -endif - -source "drivers/base/Kconfig" - -source "drivers/mtd/Kconfig" - -source "drivers/parport/Kconfig" - -source "drivers/block/Kconfig" - -source "drivers/md/Kconfig" - -if !SGI_IP22 && !DECSTATION -source "drivers/ide/Kconfig" -endif - - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - -source "drivers/scsi/Kconfig" - -endmenu - - -if !DECSTATION && !SGI_IP22 -source "drivers/message/i2o/Kconfig" -endif - -source "net/Kconfig" - -source "net/ax25/Kconfig" - -source "net/irda/Kconfig" - -source "drivers/isdn/Kconfig" - -source "drivers/telephony/Kconfig" - - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - -source "drivers/cdrom/Kconfig" - -endmenu - -source "drivers/input/Kconfig" - -source "drivers/char/Kconfig" - -source "drivers/media/Kconfig" - - -menu "DECStation Character devices" - depends on DECSTATION - -config VT - bool "Virtual terminal" - -config VT_CONSOLE - bool "Support for console on virtual terminal" - depends on VT - -config SERIAL - tristate "Standard/generic (dumb) serial support" - ---help--- - This selects whether you want to include the driver for the standard - serial ports. The standard answer is Y. People who might say N - here are those that are setting up dedicated Ethernet WWW/FTP - servers, or users that have one of the various bus mice instead of a - serial mouse and don't intend to use their machine's standard serial - port for anything. (Note that the Cyclades and Stallion multi - serial port drivers do not need this driver built in for them to - work.) - - If you want to compile this driver as a module, say M here and read - <file:Documentation/modules.txt>. The module will be called - serial. - [WARNING: Do not compile this driver as a module if you are using - non-standard serial ports, since the configuration information will - be lost when the driver is unloaded. This limitation may be lifted - in the future.] - - BTW1: If you have a mouseman serial mouse which is not recognized by - the X window system, try running gpm first. - - BTW2: If you intend to use a software modem (also called Winmodem) - under Linux, forget it. These modems are crippled and require - proprietary drivers which are only available under Windows. - - Most people will say Y or M here, so that they can use serial mice, - modems and similar devices connecting to the standard serial ports. - -config DZ - bool "DZ11 Serial Support" - depends on SERIAL=y - help - DZ11-family serial controllers for VAXstations, including the - DC7085, M7814, and M7819. - -config ZS - bool "Z85C30 Serial Support" - depends on SERIAL=y && TC - help - Documentation on the Zilog 85C350 serial communications controller - is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf>. - -config SERIAL_CONSOLE - bool "Support for console on serial port" - depends on SERIAL=y - ---help--- - If you say Y here, it will be possible to use a serial port as the - system console (the system console is the device which receives all - kernel messages and warnings and which allows logins in single user - mode). This could be useful if some terminal or printer is connected - to that serial port. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttyS1". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - - If you don't have a VGA card installed and you say Y here, the - kernel will automatically use the first serial line, /dev/ttyS0, as - system console. - - If unsure, say N. - -config UNIX98_PTYS - bool "Unix98 PTY support" - -config UNIX98_PTY_COUNT - int "Maximum number of Unix98 PTYs in use (0-2048)" - depends on UNIX98_PTYS - default "256" - -# if [ "$CONFIG_ACCESSBUS" = "y" ]; then -# bool 'MAXINE Access.Bus mouse (VSXXX-BB/GB) support' CONFIG_DTOP_MOUSE -# fi -config RTC - tristate "Enhanced Real Time Clock Support" - -endmenu - - -menu "SGI Character devices" - depends on SGI_IP22 - -config VT - bool "Virtual terminal" - -config VT_CONSOLE - bool "Support for console on virtual terminal" - depends on VT - -config PSMOUSE - bool "PS/2 mouse support (aka \"auxiliary device\")" - ---help--- - The PS/2 mouse connects to a special mouse port that looks much like - the keyboard port (small circular connector with 6 pins). This way, - the mouse does not use any serial ports. This port can also be used - for other input devices like light pens, tablets, keypads. Compaq, - AST and IBM all use this as their mouse port on currently shipping - machines. The trackballs of some laptops are PS/2 mice also. In - particular, the C&T 82C710 mouse on TI Travelmates is a PS/2 mouse. - - Although PS/2 mice are not technically bus mice, they are explained - in detail in the Busmouse-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - When using a PS/2 mouse, you can get problems if you want to use the - mouse both on the Linux console and under X. Using the "-R" option - of the Linux mouse managing program gpm (available from - <ftp://gnu.systemy.it/pub/gpm/>) solves this problem, or you can get - the "mconv2" utility from <ftp://ibiblio.org/pub/Linux/system/mouse/>. - -config MOUSE - bool - depends on PSMOUSE - default y - ---help--- - This is for machines with a mouse which is neither a serial nor a - bus mouse. Examples are PS/2 mice (such as the track balls on some - laptops) and some digitizer pads. Most people have a regular serial - MouseSystem or Microsoft mouse (made by Logitech) that plugs into a - COM port (rectangular with 9 or 25 pins). These people say N here. - If you have something else, read the Busmouse-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. This HOWTO contains - information about all non-serial mice, not just bus mice. - - If you have a laptop, you either have to check the documentation or - experiment a bit to find out whether the trackball is a serial mouse - or not; it's best to say Y here for you. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about non-serial mice. If unsure, say Y. - -config UNIX98_PTYS - bool "Unix98 PTY support" - -config UNIX98_PTY_COUNT - int "Maximum number of Unix98 PTYs in use (0-2048)" - depends on UNIX98_PTYS - default "256" - -endmenu - -source "fs/Kconfig" - -source "drivers/video/Kconfig" - -menu "Sound" - depends on !DECSTATION - -config SOUND - tristate "Sound card support" - ---help--- - If you have a sound card in your computer, i.e. if it can say more - than an occasional beep, say Y. Be sure to have all the information - about your sound card and its configuration down (I/O port, - interrupt and DMA channel), because you will be asked for it. - - You want to read the Sound-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. General information about - the modular sound system is contained in the files - <file:Documentation/sound/Introduction>. The file - <file:Documentation/sound/README.OSS> contains some slightly - outdated but still useful information as well. - - If you have a PnP sound card and you want to configure it at boot - time using the ISA PnP tools (read - <http://www.roestock.demon.co.uk/isapnptools/>), then you need to - compile the sound card support as a module ( = code which can be - inserted in and removed from the running kernel whenever you want) - and load that module after the PnP configuration is finished. To do - this, say M here and read <file:Documentation/modules.txt> as well - as <file:Documentation/sound/README.modules>; the module will be - called soundcore. - - I'm told that even without a sound card, you can make your computer - say more than an occasional beep, by programming the PC speaker. - Kernel patches and supporting utilities to do that are in the pcsp - package, available at <ftp://ftp.infradead.org/pub/pcsp/>. - -source "sound/Kconfig" - -endmenu - -source "drivers/sgi/Kconfig" - -source "drivers/usb/Kconfig" - - -menu "Kernel hacking" - -config CROSSCOMPILE - bool "Are you using a crosscompiler" - help - Say Y here if you are compiling the kernel on a different - architecture than the one it is intended to run on. - -config REMOTE_DEBUG - bool "Remote GDB kernel debugging" - depends on SERIAL=y || AU1000_UART - help - If you say Y here, it will be possible to remotely debug the MIPS - kernel using gdb. This enlarges your kernel image disk size by - several megabytes and requires a machine with more than 16 MB, - better 32 MB RAM to avoid excessive linking time. This is only - useful for kernel hackers. If unsure, say N. - -config GDB_CONSOLE - bool "Console output to GDB" - depends on REMOTE_DEBUG - help - If you are using GDB for remote debugging over a serial port and - would like kernel messages to be formatted into GDB $O packets so - that GDB prints them as program output, say 'Y'. - -config LL_DEBUG - bool "Low-level debugging" - depends on SERIAL=y - help - Enable low-level debugging assertion macros in the kernel code. - Currently used only by the time services code in the MIPS port. - Don't turn this on unless you know what you are doing. - -config MAGIC_SYSRQ - bool "Magic SysRq key" - help - If you say Y here, you will have some control over the system even - if the system crashes for example during kernel debugging (e.g., you - will be able to flush the buffer cache to disk, reboot the system - immediately or dump some status information). This is accomplished - by pressing various keys while holding SysRq (Alt+PrintScreen). It - also works on a serial console (on PC hardware at least), if you - send a BREAK and then within 5 seconds a command keypress. The - keys are documented in <file:Documentation/sysrq.txt>. Don't say Y - unless you really know what this hack does. - -config MIPS_UNCACHED - bool "Run uncached" - depends on !SMP - help - If you say Y here there kernel will disable all CPU caches. This will - reduce the system's performance dramatically but can help finding - otherwise hard to track bugs. It can also useful if you're doing - hardware debugging with a logic analyzer and need to see all traffic - on the bus. - -config NR_CPUS - int "Maximum number of CPUs (2-32)" - depends on SMP - default "32" - -endmenu - -source "security/Kconfig" - -source "crypto/Kconfig" - -source "lib/Kconfig" + default n +source "arch/mips/Kconfig-shared" diff -Nru a/arch/mips/Kconfig-shared b/arch/mips/Kconfig-shared --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/Kconfig-shared Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1371 @@ +mainmenu "Linux/MIPS Kernel Configuration" + +source "init/Kconfig" + +menu "Machine selection" + +config ACER_PICA_61 + bool "Support for Acer PICA 1 chipset (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + This is a machine with a R4400 133/150 MHz CPU. To compile a Linux + kernel that runs on these, say Y here. For details about Linux on + the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at + <http://oss.sgi.com/mips/>. + +config BAGET_MIPS + bool "Support for BAGET MIPS series (EXPERIMENTAL)" + depends on MIPS32 && EXPERIMENTAL + help + This enables support for the Baget, a Russian embedded system. For + more details about the Baget see the Linux/MIPS FAQ on + <http://oss.sgi.com/mips/>. + +config CASIO_E55 + bool "Support for CASIO CASSIOPEIA E-10/15/55/65" + +config MIPS_COBALT + bool "Support for Cobalt Server (EXPERIMENTAL)" + depends on EXPERIMENTAL + +config DECSTATION + bool "Support for DECstations" + depends on MIPS32 || EXPERIMENTAL + ---help--- + This enables support for DEC's MIPS based workstations. For details + see the Linux/MIPS FAQ on <http://oss.sgi.com/mips/> and the + DECstation porting pages on <http://decstation.unix-ag.org/>. + + If you have one of the following DECstation Models you definitely + want to choose R4xx0 for the CPU Type: + + DECstation 5000/50 + DECstation 5000/150 + DECstation 5000/260 + DECsystem 5900/260 + + otherwise choose R3000. + +config MIPS_EV64120 + bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + This is an evaluation board based on the Galileo GT-64120 + single-chip system controller that contains a MIPS R5000 compatible + core running at 75/100MHz. Their website is located at + <http://www.galileot.com/>. Say Y here if you wish to build a + kernel for this platform. + +config EVB_PCI1 + bool "Enable Second PCI (PCI1)" + depends on MIPS_EV64120 + +if MOMENCO_OCELOT_G || MOMENCO_OCELOT + +config SYSCLK_100 + bool + default y + +endif +if MIPS_EV64120 + +choice + prompt "Galileo Chip Clock" + default SYSCLK_83 + +config SYSCLK_75 + bool "75" + +config SYSCLK_83 + bool "83.3" + +config SYSCLK_100 + bool "100" if MIPS_EV64120 + +endchoice + +endif + +config MIPS_EV96100 + bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + This is an evaluation board based on the Galielo GT-96100 LAN/WAN + communications controllers containing a MIPS R5000 compatible core + running at 83MHz. Their website is <http://www.galileot.com/>. Say Y + here if you wish to build a kernel for this platform. + +config MIPS_IVR + bool "Support for Globespan IVR board" + help + This is an evaluation board built by Globespan to showcase thir + iVR (Internet Video Recorder) design. It utilizes a QED RM5231 + R5000 MIPS core. More information can be found out their website + located at <http://www.globespan.net/products/product4.html>P. Say Y + here if you wish to build a kernel for this platform. + +config LASAT + bool "Support for LASAT Networks platforms" + +config LASAT_100 + bool "Support for LASAT Networks 100 series" + depends on LASAT + +config LASAT_200 + bool "Support for LASAT Networks 200 series" + depends on LASAT + +config PICVUE + tristate "PICVUE LCD display driver" + depends on LASAT + +config PICVUE_PROC + tristate "PICVUE LCD display driver /proc interface" + depends on PICVUE + +config DS1603 + bool "DS1603 RTC driver" + depends on LASAT + +config LASAT_SYSCTL + bool "LASAT sysctl interface" + depends on LASAT + +config HP_LASERJET + bool "Support for Hewlett Packard LaserJet board" + +config IBM_WORKPAD + bool "Support for IBM WorkPad z50" + +config MIPS_ITE8172 + bool "Support for ITE 8172G board" + help + Ths is an evaluation board made by ITE <http://www.ite.com.tw/> + with ATX form factor that utilizes a MIPS R5000 to work with its + ITE8172G companion internet appliance chip. The MIPS core can be + either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build + a kernel for this platform. + +config IT8172_REVC + bool "Support for older IT8172 (Rev C)" + depends on MIPS_ITE8172 + help + Say Y here to support the older, Revision C version of the Integrated + Technology Express, Inc. ITE8172 SBC. Vendor page at + <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the + board at <http://www.mvista.com/allies/semiconductor/ite.html>. + +config MIPS_ATLAS + bool "Support for MIPS Atlas board" + help + This enables support for the QED R5231-based MIPS Atlas evaluation + board. + +config MIPS_MAGNUM_4000 + bool "Support for MIPS Magnum 4000" + help + This is a machine with a R4000 100 MHz CPU. To compile a Linux + kernel that runs on these, say Y here. For details about Linux on + the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at + <http://oss.sgi.com/mips/>. + +config MIPS_MALTA + bool "Support for MIPS Malta board" + help + This enables support for the VR5000-based MIPS Malta evaluation + board. + +config MIPS_SEAD + bool "Support for MIPS SEAD board (EXPERIMENTAL)" + depends on EXPERIMENTAL + +config MOMENCO_OCELOT + bool "Support for Momentum Ocelot board" + help + The Ocelot is a MIPS-based Single Board Computer (SBC) made by + Momentum Computer <http://www.momenco.com/>. + +config MOMENCO_OCELOT_G + bool "Support for Momentum Ocelot-G board" + help + The Ocelot is a MIPS-based Single Board Computer (SBC) made by + Momentum Computer <http://www.momenco.com/>. + +config MOMENCO_OCELOT_C + bool "Support for Momentum Ocelot-C board" + help + The Ocelot is a MIPS-based Single Board Computer (SBC) made by + Momentum Computer <http://www.momenco.com/>. + +config DDB5074 + bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + This enables support for the VR5000-based NEC DDB Vrc-5074 + evaluation board. + +config DDB5476 + bool "Support for NEC DDB Vrc-5476" + help + This enables support for the R5432-based NEC DDB Vrc-5476 + evaluation board. + + Features : kernel debugging, serial terminal, NFS root fs, on-board + ether port USB, AC97, PCI, PCI VGA card & framebuffer console, + IDE controller, PS2 keyboard, PS2 mouse, etc. + +config DDB5477 + bool "Support for NEC DDB Vrc-5477" + help + This enables support for the R5432-based NEC DDB Vrc-5477, + or Rockhopper/SolutionGear boards with R5432/R5500 CPUs. + + Features : kernel debugging, serial terminal, NFS root fs, on-board + ether port USB, AC97, PCI, etc. + +config DDB5477_BUS_FREQUENCY + int "bus frequency (in kHZ, 0 for auto-detect)" + depends on DDB5477 + default 0 + +config NEC_OSPREY + bool "Support for NEC Osprey board" + +config NEC_EAGLE + bool "Support for NEC Eagle/Hawk board" + +config OLIVETTI_M700 + bool "Support for Olivetti M700-10" + help + This is a machine with a R4000 100 MHz CPU. To compile a Linux + kernel that runs on these, say Y here. For details about Linux on + the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at + <http://oss.sgi.com/mips/>. + +config SGI_IP22 + bool "Support for SGI IP22 (Indy/Indigo2)" + help + This are the SGI Indy, Challenge S and Indigo2, as well as certain + OEM variants like the Tandem CMN B006S. To compile a Linux kernel + that runs on these, say Y here. + +config SGI_IP27 + bool "Support for SGI IP27 (Origin200/2000)" + depends on MIPS64 + help + This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics + workstations. To compile a Linux kernel that runs on these, say Y + here. + +#config SGI_SN0_XXL +# bool "IP27 XXL" +# depends on SGI_IP27 +# This options adds support for userspace processes upto 16TB size. +# Normally the limit is just .5TB. + +config SGI_SN0_N_MODE + bool "IP27 N-Mode" + depends on SGI_IP27 + help + The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be + configured in either N-Modes which allows for more nodes or M-Mode + which allows for more memory. Your system is most probably + running in M-Mode, so you should say N here. + +config DISCONTIGMEM + bool "Discontiguous Memory Support" + depends on SGI_IP27 + help + Say Y to upport efficient handling of discontiguous physical memory, + for architectures which are either NUMA (Non-Uniform Memory Access) + or have huge holes in the physical address space for other reasons. + See <file:Documentation/vm/numa> for more. + +config NUMA + bool "NUMA Support" + depends on SGI_IP27 + help + Say Y to compile the kernel to support NUMA (Non-Uniform Memory + Access). This option is for configuring high-end multiprocessor + server machines. If in doubt, say N. + +config MAPPED_KERNEL + bool "Mapped kernel support" + depends on SGI_IP27 + help + Change the way a Linux kernel is loaded unto memory on a MIPS64 + machine. This is required in order to support text replication and + NUMA. If you need to undersatand it, read the source code. + +config REPLICATE_KTEXT + bool "Kernel text replication support" + depends on SGI_IP27 + help + Say Y here to enable replicating the kernel text across multiple + nodes in a NUMA cluster. This trades memory for speed. + +config REPLICATE_EXHANDLERS + bool "Exception handler replication support" + depends on SGI_IP27 + help + Say Y here to enable replicating the kernel exception handlers + across multiple nodes in a NUMA cluster. This trades memory for + speed. + +config SGI_IP32 + bool "Support for SGI IP32 (O2) (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + If you want this kernel to run on SGI O2 workstation, say Y here. + +config SOC_AU1X00 + depends on MIPS32 + bool "Support for AMD/Alchemy Au1X00 SOCs" + +choice + prompt "Au1X00 SOC Type" + depends on SOC_AU1X00 + help + Say Y here to enable support for one of three AMD/Alchemy + SOCs. For additional documentation see www.amd.com. + +config SOC_AU1000 + bool "SOC_AU1000" +config SOC_AU1100 + bool "SOC_AU1100" +config SOC_AU1500 + bool "SOC_AU1500" + +endchoice + +choice + prompt "AMD/Alchemy Pb1x and Db1x board support" + depends on SOC_AU1X00 + help + These are evaluation boards built by AMD/Alchemy to + showcase their Au1X00 Internet Edge Processors. The SOC design + is based on the MIPS32 architecture running at 266/400/500MHz + with many integrated peripherals. Further information can be + found at their website, <http://www.amd.com/>. Say Y here if you + wish to build a kernel for this platform. + +config MIPS_PB1000 + bool "PB1000 board" + depends on SOC_AU1000 + +config MIPS_PB1100 + bool "PB1100 board" + depends on SOC_AU1100 + +config MIPS_PB1500 + bool "PB1500 board" + depends on SOC_AU1500 + +config MIPS_DB1000 + bool "DB1000 board" + depends on SOC_AU1000 + +config MIPS_DB1100 + bool "DB1100 board" + depends on SOC_AU1100 + +config MIPS_DB1500 + bool "DB1500 board" + depends on SOC_AU1500 + +endchoice + +config SIBYTE_SB1xxx_SOC + bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)" + depends on EXPERIMENTAL + +choice + prompt "BCM1xxx SOC Type" + depends on SIBYTE_SB1xxx_SOC + default SIBYTE_SB1250 + +config SIBYTE_SB1250 + bool "BCM1250" + +endchoice + +config SIMULATION + bool "Running under simulation" + depends on SIBYTE_SB1xxx_SOC + +config SIBYTE_CFE + bool "Booting from CFE" + depends on SIBYTE_SB1xxx_SOC + +config SIBYTE_CFE_CONSOLE + bool "Use firmware console" + depends on SIBYTE_CFE + +config SIBYTE_STANDALONE + bool + depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE + default y + +config SIBYTE_STANDALONE_RAM_SIZE + int "Memory size (in megabytes)" + depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE + default "32" + +config SIBYTE_BUS_WATCHER + bool "Support for Bus Watcher statistics" + depends on SIBYTE_SB1xxx_SOC + +config SIBYTE_SB1250_PROF + bool "Support for SB1/SOC profiling - SB1/SCD perf counters" + depends on SIBYTE_SB1xxx_SOC + +config SIBYTE_TBPROF + bool "Support for ZBbus profiling" + depends on SIBYTE_SB1xxx_SOC + +config SIBYTE_SWARM + bool "Support for SWARM board" + depends on SIBYTE_SB1250 + +config SIBYTE_BOARD + bool + depends on SIBYTE_SWARM + default y + +config SNI_RM200_PCI + bool "Support for SNI RM200 PCI" + help + The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens + Nixdorf Informationssysteme (SNI), parent company of Pyramid + Technology and now in turn merged with Fujitsu. Say Y here to + support this machine type. + +config TANBAC_TB0226 + bool "Support for TANBAC TB0226 (Mbase)" + help + The TANBAC TB0226 (Mbase) is a MIPS-based platform manufactured by TANBAC. + Please refer to <http://www.tanbac.co.jp/> about Mbase. + +config TANBAC_TB0229 + bool "Support for TANBAC TB0229 (VR4131DIMM)" + help + The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC. + Please refer to <http://www.tanbac.co.jp/> about VR4131DIMM. + +config TOSHIBA_JMR3927 + bool "Support for Toshiba JMR-TX3927 board" + depends on MIPS32 + +config TOSHIBA_RBTX4927 + bool "Support for Toshiba TBTX49[23]7 board" + depends on MIPS32 + +config VICTOR_MPC30X + bool "Support for Victor MP-C303/304" + +config ZAO_CAPCELLA + bool "Support for ZAO Networks Capcella" + +config RWSEM_GENERIC_SPINLOCK + bool + default y + +config RWSEM_XCHGADD_ALGORITHM + bool + +# +# Select some configuration options automatically based on user selections. +# +config ARC + bool + depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP27 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 + default y + +config GENERIC_ISA_DMA + bool + depends on SNI_RM200_PCI || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 + default y + +config CONFIG_GT64120 + bool + depends on MIPS_EV64120 || MOMENCO_OCELOT + default y + +config I8259 + bool + depends on SNI_RM200_PCI || DDB5477 || DDB5476 || DDB5074 || MIPS_MALTA || MIPS_MAGNUM_4000 || OLIVETTI_M700 || MIPS_COBALT || ACER_PICA_61 + default y + +config MIPS_JAZZ + bool + depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 + default y + +config NONCOHERENT_IO + bool + depends on ZAO_CAPCELLA || VICTOR_MPC30X || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || SNI_RM200_PCI || SGI_IP32 || SGI_IP22 || NEC_EAGLE || NEC_OSPREY || DDB5477 || DDB5476 || DDB5074 || MOMENCO_OCELOT || MOMENCO_OCELOT_C || MOMENCO_OCELOT_G || MIPS_SEAD || MIPS_MALTA || MIPS_MAGNUM_4000 || OLIVETTI_M700 || MIPS_ATLAS || LASAT || MIPS_ITE8172 || IBM_WORKPAD || HP_LASERJET || MIPS_IVR || MIPS_EV96100 || MIPS_EV64120 || DECSTATION || MIPS_COBALT || MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 || CASIO_E55 || ACER_PICA_61 || TANBAC_TB0226 || TANBAC_TB0229 + default y if ZAO_CAPCELLA || VICTOR_MPC30X || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || SNI_RM200_PCI || SGI_IP32 || SGI_IP22 || NEC_EAGLE || NEC_OSPREY || DDB5477 || DDB5476 || DDB5074 || MOMENCO_OCELOT_G || MOMENCO_OCELOT || MIPS_SEAD || MIPS_MALTA || MIPS_MAGNUM_4000 || OLIVETTI_M700 || MIPS_ATLAS || LASAT || MIPS_ITE8172 || IBM_WORKPAD || HP_LASERJET || MIPS_IVR || MIPS_EV96100 || MIPS_EV64120 || DECSTATION || MIPS_COBALT || MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 || CASIO_E55 || ACER_PICA_61 || TANBAC_TB0226 || TANBAC_TB0229 + default n if (SIBYTE_SB1250 || SGI_IP27) + +config CPU_LITTLE_ENDIAN + bool "Generate little endian code" + default y if ACER_PICA_61 || CASIO_E55 || DDB5074 || DDB5476 || DDB5477 || DECSTATION || HP_LASERJET || IBM_WORKPAD || LASAT || MIPS_COBALT || MIPS_ITE8172 || MIPS_IVR || MIPS_PB1000 || MIPS_PB1100 || MIPS_PB1500 || NEC_OSPREY || NEC_EAGLE || OLIVETTI_M700 || SNI_RM200_PCI || VICTOR_MPC30X || ZAO_CAPCELLA + default n if BAGET_MIPS || MIPS_EV64120 || MIPS_EV96100 || MOMENCO_OCELOT || MOMENCO_OCELOT_G || SGI_IP22 || SGI_IP27 || SGI_IP32 || TOSHIBA_JMR3927 + help + Some MIPS machines can be configured for either little or big endian + byte order. These modes require different kernels. Say Y if your + machine is little endian, N if it's a big endian machine. + +config IRQ_CPU + bool + depends on ZAO_CAPCELLA || VICTOR_MPC30X || SGI_IP22 || NEC_EAGLE || NEC_OSPREY || DDB5477 || DDB5476 || DDB5074 || IBM_WORKPAD || HP_LASERJET || DECSTATION || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 + default y + +config VR41XX_TIME_C + bool + depends on ZAO_CAPCELLA || VICTOR_MPC30X || NEC_EAGLE || IBM_WORKPAD || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 + default y + +config DUMMY_KEYB + bool + depends on ZAO_CAPCELLA || VICTOR_MPC30X || SIBYTE_SB1250 || NEC_EAGLE || NEC_OSPREY || DDB5477 || IBM_WORKPAD || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 + default y + +config VR41XX_COMMON + bool + depends on NEC_EAGLE || ZAO_CAPCELLA || VICTOR_MPC30X || IBM_WORKPAD || CASIO_E55 || TANBAC_TB0226 || TANBAC_TB0229 + default y + +config VRC4173 + tristate "NEC VRC4173 Support" + depends on NEC_EAGLE || VICTOR_MPC30X + +config DDB5XXX_COMMON + bool + depends on DDB5074 || DDB5476 || DDB5477 + default y + +config MIPS_BOARDS_GEN + bool + depends on MIPS_ATLAS || MIPS_MALTA || MIPS_SEAD + default y + +config ITE_BOARD_GEN + bool + depends on MIPS_IVR || MIPS_ITE8172 + default y + +config NEW_PCI + bool + depends on ZAO_CAPCELLA || VICTOR_MPC30X || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || NEC_EAGLE || DDB5477 || DDB5476 || DDB5074 || MIPS_ITE8172 || HP_LASERJET || MIPS_IVR || MIPS_EV96100 || MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 || TANBAC_TB0226 || TANBAC_TB0229 + default y + +config SWAP_IO_SPACE + bool "Support for paging of anonymous memory" + depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || SIBYTE_SB1250 || SGI_IP22 || MOMENCO_OCELOT_C || MOMENCO_OCELOT_G || MOMENCO_OCELOT || MIPS_MALTA || MIPS_ATLAS || MIPS_EV96100 || MIPS_PB1100 || MIPS_PB1000 + default y + help + This option allows you to choose whether you want to have support + for socalled swap devices or swap files in your kernel that are + used to provide more virtual memory than the actual RAM present + in your computer. If unusre say Y. + +config AU1000_USB_DEVICE + bool + depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 + default n + +config COBALT_LCD + bool + depends on MIPS_COBALT + default y + +config MIPS_GT64120 + bool + depends on MIPS_EV64120 + default y + +config MIPS_GT96100 + bool + depends on MIPS_EV96100 + default y + help + Say Y here to support the Galileo Technology GT96100 communications + controller card. There is a web page at <http://www.galileot.com/>. + +config IT8172_CIR + bool + depends on MIPS_ITE8172 || MIPS_IVR + default y + +config IT8712 + bool + depends on MIPS_ITE8172 + default y + +config BOOT_ELF32 + bool + depends on DECSTATION || MIPS_ATLAS || MIPS_MALTA || SIBYTE_SB1250 || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI + default y + +config L1_CACHE_SHIFT + int + default "4" if DECSTATION + default "5" if SGI_IP32 || SGI_IP22 || MIPS_SEAD || MIPS_MALTA || MIPS_ATLAS + default "7" if SGI_IP27 + +config ARC32 + bool + depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 + default y + +config FB + bool + depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 + default y + ---help--- + The frame buffer device provides an abstraction for the graphics + hardware. It represents the frame buffer of some video hardware and + allows application software to access the graphics hardware through + a well-defined interface, so the software doesn't need to know + anything about the low-level (hardware register) stuff. + + Frame buffer devices work identically across the different + architectures supported by Linux and make the implementation of + application programs easier and more portable; at this point, an X + server exists which uses the frame buffer device exclusively. + On several non-X86 architectures, the frame buffer device is the + only way to use the graphics hardware. + + The device is accessed through special device nodes, usually located + in the /dev directory, i.e. /dev/fb*. + + You need an utility program called fbset to make full use of frame + buffer devices. Please read <file:Documentation/fb/framebuffer.txt> + and the Framebuffer-HOWTO at + <http://www.tahallah.demon.co.uk/programming/prog.html> for more + information. + + Say Y here and to the driver for your graphics board below if you + are compiling a kernel for a non-x86 architecture. + + If you are compiling for the x86 architecture, you can say Y if you + want to play with it, but it is not essential. Please note that + running graphical applications that directly touch the hardware + (e.g. an accelerated X server) and that are not frame buffer + device-aware may cause unexpected results. If unsure, say N. + +config FB_G364 + bool + depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 + default y + +config HAVE_STD_PC_SERIAL_PORT + bool + depends on DDB5476 || DDB5074 || MIPS_MALTA + default y + +config VR4181 + bool + depends on NEC_OSPREY + default y + +config ARC_CONSOLE + bool "ARC console support" + depends on SGI_IP22 || SNI_RM200_PCI + +config ARC_MEMORY + bool + depends on SNI_RM200_PCI || SGI_IP32 + default y + +config ARC_PROMLIB + bool + depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP22 + default y + +config BOARD_SCACHE + bool + depends on MIPS_EV96100 || MOMENCO_OCELOT || SGI_IP22 + default y + +config ARC64 + bool + depends on SGI_IP27 + default y + +config BOOT_ELF64 + bool + depends on SGI_IP27 + default y + +#config MAPPED_PCI_IO y +# bool +# depends on SGI_IP27 +# default y + +config QL_ISP_A64 + bool + depends on SGI_IP27 + default y + +config TOSHIBA_BOARDS + bool + depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 + default y + +config TANBAC_TB0219 + bool "Added TANBAC TB0219 Base board support" + depends on TANBAC_TB0229 + +endmenu + + +menu "CPU selection" + +choice + prompt "CPU type" + default CPU_R4X00 + +config CPU_MIPS32 + bool "MIPS32" + +config CPU_MIPS64 + bool "MIPS64" + +config CPU_R3000 + bool "R3000" + depends on MIPS32 + help + Please make sure to pick the right CPU type. Linux/MIPS is not + designed to be generic, i.e. Kernels compiled for R3000 CPUs will + *not* work on R4000 machines and vice versa. However, since most + of the supported machines have an R4000 (or similar) CPU, R4x00 + might be a safe bet. If the resulting kernel does not work, + try to recompile with R3000. + +config CPU_TX39XX + bool "R39XX" + depends on MIPS32 + +config CPU_VR41XX + bool "R41xx" + help + The options selects support for the NEC VR41xx series of processors. + Only choose this option if you have one of these processors as a + kernel built with this option will not run on any other type of + processor or vice versa. + +config CPU_R4300 + bool "R4300" + help + MIPS Technologies R4300-series processors. + +config CPU_R4X00 + bool "R4x00" + help + MIPS Technologies R4000-series processors other than 4300, including + the R4000, R4400, R4600, and 4700. + +config CPU_TX49XX + bool "R49XX" + +config CPU_R5000 + bool "R5000" + help + MIPS Technologies R5000-series processors other than the Nevada. + +config CPU_R5432 + bool "R5432" + +config CPU_R6000 + bool "R6000" + depends on MIPS32 && EXPERIMENTAL + help + MIPS Technologies R6000 and R6000A series processors. Note these + processors are extremly rare and the support for them is incomplete. + +config CPU_NEVADA + bool "R52xx" + help + MIPS Technologies R52x0-series ("Nevada") processors. + +config CPU_R8000 + bool "R8000" + depends on MIPS64 && EXPERIMENTAL + help + MIPS Technologies R8000 processors. Note these processors are + uncommon and the support for them is incomplete. + +config CPU_R10000 + bool "R10000" + help + MIPS Technologies R10000-series processors. + +config CPU_RM7000 + bool "RM7000" + +config CPU_SB1 + bool "SB1" + +endchoice + +config R5000_CPU_SCACHE + bool + depends on CPU_NEVADA || CPU_R5000 + default y if SGI_IP32 || LASAT + +config BOARD_SCACHE + bool + depends on CPU_NEVADA || CPU_R4X00 || CPU_R5000 + default y if SGI_IP22 || (SGI_IP32 && CPU_R5000) || R5000_CPU_SCACHE + +config CPU_HAS_PREFETCH + bool "Enable prefetches" if CPU_SB1 && !CPU_SB1_PASS_2 + default y if CPU_RM7000 || CPU_MIPS64 || CPU_MIPS32 + +config VTAG_ICACHE + bool "Support for Virtual Tagged I-cache" if CPU_MIPS64 || CPU_MIPS32 + default y if CPU_SB1 + +choice + prompt "SB1 Pass" + depends on CPU_SB1 + default CPU_SB1_PASS_1 + +config CPU_SB1_PASS_1 + bool "Pass1" + +config CPU_SB1_PASS_2 + bool "Pass2" + +config CPU_SB1_PASS_2_2 + bool "Pass2.2" + +endchoice + +config SB1_PASS_1_WORKAROUNDS + bool + depends on CPU_SB1_PASS_1 + default y + +config SB1_PASS_2_WORKAROUNDS + bool + depends on CPU_SB1 && (CPU_SB1_PASS_2_2 || CPU_SB1_PASS_2) + default y + +# Avoid prefetches on Pass 2 (before 2.2) +# XXXKW for now, let 2.2 use same WORKAROUNDS flag as pre-2.2 +config SB1_CACHE_ERROR + bool "Support for SB1 Cache Error handler" + depends on CPU_SB1 + +config SB1_CERR_IGNORE_RECOVERABLE + bool "Ignore recoverable cache errors" + depends on SB1_CACHE_ERROR + +config SB1_CERR_SPIN + bool "Spin instead of running handler" + depends on SB1_CACHE_ERROR + +config 64BIT_PHYS_ADDR + bool "Support for 64-bit physical address space" + depends on (CPU_R4X00 || CPU_R5000 || CPU_RM7000 || CPU_R10000 || CPU_SB1 || CPU_MIPS32 || CPU_MIPS64) && MIPS32 + +config CPU_ADVANCED + bool "Override CPU Options" + depends on MIPS32 + help + Saying yes here allows you to select support for various features + your CPU may or may not have. Most people should say N here. + +config CPU_HAS_LLSC + bool "ll/sc Instructions available" if CPU_ADVANCED + default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX + help + MIPS R4000 series and later provide the Load Linked (ll) + and Store Conditional (sc) instructions. More information is + available at <http://www.go-ecs.com/mips/miptek1.htm>. + + Say Y here if your CPU has the ll and sc instructions. Say Y here + for better performance, N if you don't know. You must say Y here + for multiprocessor machines. + +config CPU_HAS_LLDSCD + bool "lld/scd Instructions available" if CPU_ADVANCED + default y if !CPU_ADVANCED && !CPU_R3000 && !CPU_VR41XX && !CPU_TX39XX && !CPU_MIPS32 + help + Say Y here if your CPU has the lld and scd instructions, the 64-bit + equivalents of ll and sc. Say Y here for better performance, N if + you don't know. You must say Y here for multiprocessor machines. + +config CPU_HAS_WB + bool "Writeback Buffer available" if CPU_ADVANCED + default y if !CPU_ADVANCED && (CPU_R3000 || CPU_VR41XX || CPU_TX39XX) && DECSTATION + help + Say N here for slightly better performance. You must say Y here for + machines which require flushing of write buffers in software. Saying + Y is the safe option; N may result in kernel malfunction and crashes. + +config CPU_HAS_SYNC + bool + depends on !CPU_R3000 + default y + +# +# - Highmem only makes sense for the 32-bit kernel. +# - The current highmem code will only work properly on physically indexed +# caches such as R3000, SB1, R7000 or those that look like they're virtually +# indexed such as R4000/R4400 SC and MC versions or R10000. So for the +# moment we protect the user and offer the highmem option only on machines +# where it's known to be safe. This will not offer highmem on a few systems +# such as MIPS32 and MIPS64 CPUs which may have virtual and physically +# indexed CPUs but we're playing safe. +# - We should not offer highmem for system of which we already know that they +# don't have memory configurations that could gain from highmem support in +# the kernel because they don't support configurations with RAM at physical +# addresses > 0x20000000. +# +config HIGHMEM + bool "High Memory Support" + depends on MIPS32 && (CPU_R3000 || CPU_SB1 || CPU_R7000 || CPU_R10000) && !(BAGET_MIPS || DECSTATION) + +config SMP + bool "Multi-Processing support" + depends on SIBYTE_SB1xxx_SOC && SIBYTE_SB1250 && !SIBYTE_STANDALONE || SGI_IP27 + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + People using multiprocessor machines who say Y here should also say + Y to "Enhanced Real Time Clock Support", below. + + See also the <file:Documentation/smp.tex>, + <file:Documentation/smp.txt> and the SMP-HOWTO available at + <http://www.tldp.org/docs.html#howto>. + + If you don't know what to do here, say N. + +config NR_CPUS + int "Maximum number of CPUs (2-32)" + depends on SMP + default "32" + help + This allows you to specify the maximum number of CPUs which this + kernel will support. The maximum supported value is 32 and the + minimum value which makes sense is 2. + + This is purely to save memory - each supported CPU adds + approximately eight kilobytes to the kernel image. + +config PREEMPT + bool "Preemptible Kernel" + help + This option reduces the latency of the kernel when reacting to + real-time or interactive events by allowing a low priority process to + be preempted even if it is in kernel mode executing a system call. + This allows applications to run more reliably even when the system is + under load. + +config KALLSYMS + bool "Load all symbols for debugging/kksymoops" + help + Say Y here to let the kernel print out symbolic crash information and + symbolic stack backtraces. This increases the size of the kernel + somewhat, as all symbols have to be loaded into the kernel image. + +config DEBUG_SPINLOCK_SLEEP + bool "Sleep-inside-spinlock checking" + help + If you say Y here, various routines which may sleep will become very + noisy if they are called with a spinlock held. + +config RTC_DS1742 + bool "DS1742 BRAM/RTC support" + depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 + +config MIPS_INSANE_LARGE + bool "Support for large 64-bit configurations" + depends on CPU_R10000 && MIPS64 + help + MIPS R10000 does support a 44 bit / 16TB address space as opposed to + previous 64-bit processors which only supported 40 bit / 1TB. If you + need processes of more than 1TB virtual address space, say Y here. + This will result in additional memory usage, so it is not + recommended for normal users. + +config RWSEM_GENERIC_SPINLOCK + bool + default y + +endmenu + +menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" + +config PCI + bool "Support for PCI controller" + depends on MIPS_DB1000 || DDB5074 || DDB5476 || DDB5477 || HP_LASERJET || LASAT || MIPS_IVR || MIPS_ATLAS || MIPS_COBALT || MIPS_EV64120 || MIPS_EV96100 || MIPS_ITE8172 || MIPS_MALTA || MOMENCO_OCELOT || MOMENCO_OCELOT_C || MOMENCO_OCELOT_G || MIPS_PB1000 || MIPS_PB1100 || MIPS_PB1500 || NEC_EAGLE || SGI_IP27 || SGI_IP32 || SIBYTE_SB1250 || SNI_RM200_PCI || TANBAC_TB0226 || TANBAC_TB0229 || TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 || VICTOR_MPC30X || ZAO_CAPCELLA + help + Find out whether you have a PCI motherboard. PCI is the name of a + bus system, i.e. the way the CPU talks to the other stuff inside + your box. Other bus systems are ISA, EISA, or VESA. If you have PCI, + say Y, otherwise N. + + The PCI-HOWTO, available from + <http://www.tldp.org/docs.html#howto>, contains valuable + information about which PCI hardware does work under Linux and which + doesn't. + +source "drivers/pci/Kconfig" + +config ISA + bool "ISA bus support" + depends on ACER_PICA_61 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || SNI_RM200_PCI + default y if TOSHIBA_RBTX4927 || DDB5476 || DDB5074 || IBM_WORKPAD || CASIO_E55 + help + Find out whether you have ISA slots on your motherboard. ISA is the + name of a bus system, i.e. the way the CPU talks to the other stuff + inside your box. Other bus systems are PCI, EISA, or VESA. ISA is + an older system, now being displaced by PCI; newer boards don't + support it. If you have ISA, say Y, otherwise N. + +# +# The SCSI bits are needed to get the SCSI code to link ... +# +config GENERIC_ISA_DMA + bool + default y if ACER_PICA_61 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || SNI_RM200_PCI || SCSI + +config EISA + bool "EISA support" + depends on ISA && (SGI_IP22 || SNI_RM200_PCI) + ---help--- + The Extended Industry Standard Architecture (EISA) bus was + developed as an open alternative to the IBM MicroChannel bus. + + The EISA bus provided some of the features of the IBM MicroChannel + bus while maintaining backward compatibility with cards made for + the older ISA bus. The EISA bus saw limited use between 1988 and + 1995 when it was made obsolete by the PCI bus. + + Say Y here if you are building a kernel for an EISA-based machine. + + Otherwise, say N. + +source "drivers/eisa/Kconfig" + +config TC + bool "TURBOchannel support" + depends on DECSTATION + help + TurboChannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS + processors. Documentation on writing device drivers for TurboChannel + is available at: + <http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>. + +#config ACCESSBUS +# bool "Access.Bus support" +# depends on TC + +config MMU + bool + default y + +config MCA + bool + +config SBUS + bool + +config HOTPLUG + bool "Support for hot-pluggable devices" + ---help--- + Say Y here if you want to plug devices into your computer while + the system is running, and be able to use them quickly. In many + cases, the devices can likewise be unplugged at any time too. + + One well known example of this is PCMCIA- or PC-cards, credit-card + size devices such as network cards, modems or hard drives which are + plugged into slots found on all modern laptop computers. Another + example, used on modern desktops as well as laptops, is USB. + + Enable HOTPLUG and KMOD, and build a modular kernel. Get agent + software (at <http://linux-hotplug.sourceforge.net/>) and install it. + Then your kernel will automatically call out to a user mode "policy + agent" (/sbin/hotplug) to load modules and set up software needed + to use devices as you hotplug them. + +source "drivers/pcmcia/Kconfig" + +source "drivers/pci/hotplug/Kconfig" + +endmenu + +menu "Executable file formats" + +config KCORE_ELF + bool + default y + ---help--- + If you enabled support for /proc file system then the file + /proc/kcore will contain the kernel core image. This can be used + in gdb: + + $ cd /usr/src/linux ; gdb vmlinux /proc/kcore + + You have two choices here: ELF and A.OUT. Selecting ELF will make + /proc/kcore appear in ELF core format as defined by the Executable + and Linking Format specification. Selecting A.OUT will choose the + old "a.out" format which may be necessary for some old versions + of binutils or on some architectures. + + This is especially useful if you have compiled the kernel with the + "-g" option to preserve debugging information. It is mainly used + for examining kernel data structures on the live kernel so if you + don't understand what this means or are not a kernel hacker, just + leave it at its default value ELF. + +config KCORE_AOUT + bool + +source "fs/Kconfig.binfmt" + +config BINFMT_IRIX + bool "Include IRIX binary compatibility" + depends on !CPU_LITTLE_ENDIAN && MIPS32 + +config MIPS32_COMPAT + bool "Kernel support for Linux/MIPS 32-bit binary compatibility" + depends on MIPS64 + help + Select this option if you want Linux/MIPS 32-bit binary + compatibility. Since all software available for Linux/MIPS is + currently 32-bit you should say Y here. + +config COMPAT + bool + depends on MIPS32_COMPAT + default y + +config MIPS32_O32 + bool "Kernel support for o32 binaries" + depends on MIPS32_COMPAT + help + Select this option if you want to run o32 binaries. These are pure + 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of + existing binaries are in this format. + + If unsure, say Y. + +config MIPS32_N32 + bool "Kernel support for n32 binaries" + depends on MIPS32_COMPAT + help + Select this option if you want to run n32 binaries. These are + 64-bit binaries using 32-bit quantities for addressing and certain + data that would normally be 64-bit. They are used in special + cases. + + If unsure, say N. + +config BINFMT_ELF32 + bool + default y if MIPS32_O32 || MIPS32_N32 + +config PM + bool "Power Management support (EXPERIMENTAL)" + depends on EXPERIMENTAL && SOC_AU1X00 + +endmenu + +source "drivers/mtd/Kconfig" + +source "drivers/parport/Kconfig" + +source "drivers/pnp/Kconfig" + +source "drivers/base/Kconfig" + +source "drivers/block/Kconfig" + + +menu "MIPS initrd options" + depends on BLK_DEV_INITRD + +config EMBEDDED_RAMDISK + bool "Embed root filesystem ramdisk into the kernel" + +config EMBEDDED_RAMDISK_IMAGE + string "Filename of gziped ramdisk image" + depends on EMBEDDED_RAMDISK + default "ramdisk.gz" + help + This is the filename of the ramdisk image to be built into the + kernel. Relative pathnames are relative to arch/mips/ramdisk/. + The ramdisk image is not part of the kernel distribution; you must + provide one yourself. + +endmenu + +source "drivers/ide/Kconfig" + +source "drivers/scsi/Kconfig" + +source "drivers/cdrom/Kconfig" + +source "drivers/md/Kconfig" + +source "drivers/message/fusion/Kconfig" + +source "drivers/ieee1394/Kconfig" + +source "drivers/message/i2o/Kconfig" + +source "net/Kconfig" + +source "net/ax25/Kconfig" + +source "net/irda/Kconfig" + +source "drivers/isdn/Kconfig" + +source "drivers/telephony/Kconfig" + +# +# input before char - char/joystick depends on it. As does USB. +# +source "drivers/input/Kconfig" + +source "drivers/char/Kconfig" + +#source drivers/misc/Config.in + +source "drivers/media/Kconfig" + +source "fs/Kconfig" + +source "drivers/video/Kconfig" + + +menu "Sound" + +config SOUND + tristate "Sound card support" + ---help--- + If you have a sound card in your computer, i.e. if it can say more + than an occasional beep, say Y. Be sure to have all the information + about your sound card and its configuration down (I/O port, + interrupt and DMA channel), because you will be asked for it. + + You want to read the Sound-HOWTO, available from + <http://www.tldp.org/docs.html#howto>. General information about + the modular sound system is contained in the files + <file:Documentation/sound/Introduction>. The file + <file:Documentation/sound/README.OSS> contains some slightly + outdated but still useful information as well. + + If you have a PnP sound card and you want to configure it at boot + time using the ISA PnP tools (read + <http://www.roestock.demon.co.uk/isapnptools/>), then you need to + compile the sound card support as a module ( = code which can be + inserted in and removed from the running kernel whenever you want) + and load that module after the PnP configuration is finished. To do + this, say M here and read <file:Documentation/modules.txt> as well + as <file:Documentation/sound/README.modules>; the module will be + called soundcore. + + I'm told that even without a sound card, you can make your computer + say more than an occasional beep, by programming the PC speaker. + Kernel patches and supporting utilities to do that are in the pcsp + package, available at <ftp://ftp.infradead.org/pub/pcsp/>. + +source "sound/Kconfig" + +endmenu + +source "drivers/usb/Kconfig" + +source "net/bluetooth/Kconfig" + + +menu "Kernel hacking" + +config CROSSCOMPILE + bool "Are you using a crosscompiler" + help + Say Y here if you are compiling the kernel on a different + architecture than the one it is intended to run on. + +config DEBUG_KERNEL + bool "Kernel debugging" + +config KGDB + bool "Remote GDB kernel debugging" + depends on DEBUG_KERNEL + help + If you say Y here, it will be possible to remotely debug the MIPS + kernel using gdb. This enlarges your kernel image disk size by + several megabytes and requires a machine with more than 16 MB, + better 32 MB RAM to avoid excessive linking time. This is only + useful for kernel hackers. If unsure, say N. + +config GDB_CONSOLE + bool "Console output to GDB" + depends on KGDB + help + If you are using GDB for remote debugging over a serial port and + would like kernel messages to be formatted into GDB $O packets so + that GDB prints them as program output, say 'Y'. + +config RUNTIME_DEBUG + bool "Enable run-time debugging" + depends on DEBUG_KERNEL + help + If you say Y here, some debugging macros will do run-time checking. + If you say N here, those macros will mostly turn to no-ops. See + include/asm-mips/debug.h for debuging macros. + If unsure, say N. + + +config MAGIC_SYSRQ + bool "Magic SysRq key" + depends on DEBUG_KERNEL + help + If you say Y here, you will have some control over the system even + if the system crashes for example during kernel debugging (e.g., you + will be able to flush the buffer cache to disk, reboot the system + immediately or dump some status information). This is accomplished + by pressing various keys while holding SysRq (Alt+PrintScreen). It + also works on a serial console (on PC hardware at least), if you + send a BREAK and then within 5 seconds a command keypress. The + keys are documented in <file:Documentation/sysrq.txt>. Don't say Y + unless you really know what this hack does. + +config MIPS_UNCACHED + bool "Run uncached" + depends on DEBUG_KERNEL && !SMP && !SGI_IP27 + help + If you say Y here there kernel will disable all CPU caches. This will + reduce the system's performance dramatically but can help finding + otherwise hard to track bugs. It can also useful if you're doing + hardware debugging with a logic analyzer and need to see all traffic + on the bus. + +config DEBUG_HIGHMEM + bool "Highmem debugging" + depends on DEBUG_KERNEL && HIGHMEM + +endmenu + +source "security/Kconfig" + +source "crypto/Kconfig" + +source "lib/Kconfig" diff -Nru a/arch/mips/Makefile b/arch/mips/Makefile --- a/arch/mips/Makefile Fri Jun 27 14:19:52 2003 +++ b/arch/mips/Makefile Fri Jun 27 14:19:52 2003 @@ -5,11 +5,11 @@ # # Copyright (C) 1994, 1995, 1996 by Ralf Baechle # DECStation modifications by Paul M. Antoine, 1996 +# Copyright (C) 2002 Maciej W. Rozycki # # 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 -# this architecture +# for "archclean" cleaning up for this architecture. # # @@ -17,16 +17,20 @@ # ifdef CONFIG_CPU_LITTLE_ENDIAN tool-prefix = mipsel-linux- +JIFFIES32 = jiffies_64 +LDFLAGS_BLOB := --format binary --oformat elf32-tradlittlemips else tool-prefix = mips-linux- +JIFFIES32 = jiffies_64 + 4 +LDFLAGS_BLOB := --format binary --oformat elf32-tradbigmips endif ifdef CONFIG_CROSSCOMPILE -CROSS_COMPILE = $(tool-prefix) +CROSS_COMPILE := $(tool-prefix) endif # -# GCC uses -G0 -mabicalls -fpic as default. We don't want PIC in the kernel +# GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel # code since it only slows down the whole thing. At some point we might make # use of global pointer optimizations but their use of $28 conflicts with # the current pointer optimization. @@ -35,218 +39,314 @@ # machines may also. Since BFD is incredibly buggy with respect to # crossformat linking we rely on the elf2ecoff tool for format conversion. # -GCCFLAGS := -G 0 -mno-abicalls -fno-pic -LDFLAGS_vmlinux += -static -MODFLAGS += -mlong-calls -LDFLAGS := -G 0 +cflags-y := -I $(TOPDIR)/include/asm/gcc +cflags-y += -G 0 -mno-abicalls -fno-pic -pipe +LDFLAGS_vmalinux += -G 0 -static # -N +MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG -CFLAGS := $(CFLAGS) -g -endif +cflags-$(CONFIG_KGDB) += -g +cflags-$(CONFIG_SB1XXX_CORELIS) += -mno-sched-prolog -fno-omit-frame-pointer + +check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) # # CPU-dependent compiler/assembler options for optimization. # -ifdef CONFIG_CPU_R3000 -GCCFLAGS += -mcpu=r3000 -mips1 -endif -ifdef CONFIG_CPU_R6000 -GCCFLAGS += -mcpu=r6000 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_R4300 -GCCFLAGS += -mcpu=r4300 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_VR41XX -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_R4X00 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_MIPS32 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_MIPS64 -GCCFLAGS += -mcpu=r4600 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_R5000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_R5432 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_NEVADA +cflags-$(CONFIG_CPU_R3000) += -mcpu=r3000 -mips1 +cflags-$(CONFIG_CPU_TX39XX) += -mcpu=r3000 -mips1 +cflags-$(CONFIG_CPU_R6000) += -mcpu=r6000 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_R4300) += -mcpu=r4300 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_VR41XX) += -mcpu=r4600 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_R4X00) += -mcpu=r4600 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_TX49XX) += -mcpu=r4600 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_MIPS32) += -mcpu=r4600 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_MIPS64) += -mcpu=r4600 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_R5000) += -mcpu=r5000 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_R5432) += -mcpu=r5000 -mips2 -Wa,--trap # Cannot use -mmad with currently recommended tools -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap -endif -ifdef CONFIG_CPU_RM7000 -GCCFLAGS += -mcpu=r5000 -mips2 -Wa,--trap -endif +cflags-$(CONFIG_CPU_NEVADA) += -mcpu=r5000 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_RM7000) += -mcpu=r5000 -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_RM7000) += $(call check_gcc, -mcpu=r7000, -mcpu=r5000) \ + -mips2 -Wa,--trap +cflags-$(CONFIG_CPU_SB1) += $(call check_gcc, -mcpu=sb1, -mcpu=r8000) \ + -mips2 -Wa,--trap ifdef CONFIG_CPU_SB1 -GCCFLAGS += -mcpu=sb1 -mips2 -Wa,--trap +ifdef CONFIG_SB1_PASS_1_WORKAROUNDS +MODFLAGS += -msb1-pass1-workarounds endif +endif + +AFLAGS += $(cflags-y) +CFLAGS += $(cflags-y) -GCCFLAGS += -pipe -CFLAGS := -I $(TOPDIR)/include/asm/gcc $(CFLAGS) $(GCCFLAGS) -AFLAGS += $(GCCFLAGS) -ASFLAGS += $(GCCFLAGS) +# +# ramdisk/initrd support +# You need a compressed ramdisk image, named ramdisk.gz in +# arch/mips/ramdisk +# +ifdef CONFIG_EMBEDDED_RAMDISK +CORE_FILES += arch/mips/ramdisk/ramdisk.o +SUBDIRS += arch/mips/ramdisk +endif # -# We unconditionally build the math emulator +# Firmware support # -core-y += arch/mips/math-emu/ +libs-$(CONFIG_ARC) += arch/mips/arc/ +libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/ # # Board-dependent options and extra files # -ifdef CONFIG_ALGOR_P4032 -core-y += arch/mips/algor/ -LOADADDR += 0x80000000 -endif # -# DECstation family +# Acer PICA 61, Mips Magnum 4000 and Olivetti M700. # -ifdef CONFIG_DECSTATION -core-y += arch/mips/dec/ -libs-y += arch/mips/dec/prom/ -LOADADDR += 0x80040000 -endif +core-$(CONFIG_MIPS_JAZZ) += arch/mips/jazz/ +load-$(CONFIG_MIPS_JAZZ) += 0x80080000 -ifdef CONFIG_MIPS_ATLAS -core-y += arch/mips/mips-boards/atlas/ arch/mips/mips-boards/generic/ -LOADADDR += 0x80100000 -endif -ifdef CONFIG_MIPS_MALTA -core-y += arch/mips/mips-boards/malta/ arch/mips/mips-boards/generic/ -LOADADDR += 0x80100000 -endif +# +# Au1500 (Alchemy Semi PB1500) eval board +# +core-$(CONFIG_MIPS_PB1500) += arch/mips/au1000/common/ +libs-$(CONFIG_MIPS_PB1500) += arch/mips/au1000/pb1500/ +load-$(CONFIG_MIPS_PB1500) += 0x80100000 # -# Acer PICA 61, Mips Magnum 4000 and Olivetti M700. +# Baget/MIPS # -ifdef CONFIG_MIPS_JAZZ -core-y += arch/mips/jazz/ -libs-y += arch/mips/arc/ -LOADADDR += 0x80080000 -endif +libs-$(CONFIG_BAGET_MIPS) += arch/mips/baget/ arch/mips/baget/prom/ +load-$(CONFIG_BAGET_MIPS) += 0x80001000 -ifdef CONFIG_SNI_RM200_PCI -core-y += arch/mips/sni/ -libs-y += arch/mips/arc/ -LOADADDR += 0x80080000 -endif +# +# Cobalt Server +# +core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/ +load-$(CONFIG_MIPS_COBALT) += 0x80080000 -ifdef CONFIG_SGI_IP22 -core-y += arch/mips/sgi/kernel/ -libs-y += arch/mips/arc/ -# -# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon, -# 0x88002000 for production kernels. Note that the value must be -# 8kb aligned or the handling of the current variable will break. # -LOADADDR += 0x88002000 -endif +# DECstation family +# +core-$(CONFIG_DECSTATION) += arch/mips/dec/ +libs-$(CONFIG_DECSTATION) += arch/mips/dec/prom/ +load-$(CONFIG_DECSTATION) += 0x80040000 +CLEAN_FILES += drivers/tc/lk201-map.c # -# Baget/MIPS +# Galileo EV64120 Board # -ifdef CONFIG_BAGET_MIPS -core-y += arch/mips/baget/ -libs-y += arch/mips/baget/prom/ -LOADADDR += 0x80001000 -endif +core-$(CONFIG_MIPS_EV64120) += arch/mips/galileo-boards/ev64120/ +load-$(CONFIG_MIPS_EV64120) += 0x80100000 # -# NEC DDB Vrc-5074 +# Galileo EV96100 Board # -ifdef CONFIG_DDB5074 -core-y += arch/mips/ddb5074/ -LOADADDR += 0x80080000 -endif +core-$(CONFIG_MIPS_EV96100) += arch/mips/galileo-boards/generic/ \ + arch/mips/galileo-boards/ev96100/ +load-$(CONFIG_MIPS_EV96100) += 0x80100000 # +# Globespan IVR eval board with QED 5231 CPU # -# NEC DDB Vrc-5476 +core-$(CONFIG_ITE_BOARD_GEN) += arch/mips/ite-boards/generic/ +core-$(CONFIG_MIPS_IVR) += arch/mips/ite-boards/ivr/ +load-$(CONFIG_MIPS_IVR) += 0x80100000 + # -ifdef CONFIG_DDB5476 -core-y += arch/mips/ddb5476/ -LOADADDR += 0x80080000 -endif +# HP LaserJet +# +core-$(CONFIG_HP_LASERJET) += arch/mips/hp-lj/ +load-$(CONFIG_HP_LASERJET) += 0x80030000 # +# ITE 8172 eval board with QED 5231 CPU # -# NEC DDB Vrc-5477 +core-$(CONFIG_MIPS_ITE8172) += arch/mips/ite-boards/qed-4n-s01b/ +load-$(CONFIG_MIPS_ITE8172) += 0x80100000 + # -ifdef CONFIG_DDB5477 -core-y += arch/mips/ddb5xxx/common/ \ - arch/mips/ddb5xxx/ddb5477/ -LOADADDR += 0x80080000 -endif +# MIPS Atlas board +# +core-$(CONFIG_MIPS_BOARDS_GEN) += arch/mips/mips-boards/generic/ +core-$(CONFIG_MIPS_ATLAS) += arch/mips/mips-boards/atlas/ +load-$(CONFIG_MIPS_ATLAS) += 0x80100000 # -# Galileo EV64120 Board +# MIPS Malta board # -ifdef CONFIG_MIPS_EV64120 -core-y += arch/mips/galileo-boards/ev64120/ -LOADADDR += 0x80100000 -endif +core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/ +load-$(CONFIG_MIPS_MALTA) := 0x80100000 # -# Galileo EV96100 Board +# MIPS SEAD board # -ifdef CONFIG_MIPS_EV96100 -core-y += arch/mips/galileo-boards/ev96100/ \ - arch/mips/galileo-boards/generic/ -LOADADDR += 0x80100000 -endif +core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/ +load-$(CONFIG_MIPS_SEAD) += 0x80100000 # # Momentum Ocelot board # -ifdef CONFIG_MOMENCO_OCELOT # The Ocelot setup.o must be linked early - it does the ioremap() for the # mips_io_port_base. -core-y += arch/mips/gt64120/common/ \ - arch/mips/gt64120/momenco_ocelot/ -LOADADDR += 0x80100000 -endif +# +core-$(CONFIG_MOMENCO_OCELOT) += arch/mips/gt64120/common/ \ + arch/mips/gt64120/momenco_ocelot/ +load-$(CONFIG_MOMENCO_OCELOT) += 0x80100000 # -# Philips Nino +# Momentum Ocelot-G board # -ifdef CONFIG_NINO -core-y += arch/mips/philips/nino/ -LOADADDR += 0x80000000 -endif +# The Ocelot-G setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +# +core-$(CONFIG_MOMENCO_OCELOT_G) += arch/mips/momentum/ocelot_g/ +load-$(CONFIG_MOMENCO_OCELOT_G) += 0x80100000 # -# ITE 8172 eval board with QED 5231 CPU +# Momentum Ocelot-C and -CS boards # -ifdef CONFIG_MIPS_ITE8172 -core-y += arch/mips/ite-boards/qed-4n-s01b/ \ - arch/mips/ite-boards/generic/ -LOADADDR += 0x80100000 -endif +# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +core-$(CONFIG_MOMENCO_OCELOT_C) += arch/mips/momentum/ocelot_c/ +load-$(CONFIG_MOMENCO_OCELOT_C) += 0x80100000 # -# Globespan IVR eval board with QED 5231 CPU +# NEC DDB Vrc-5074 # -ifdef CONFIG_MIPS_IVR -core-y += arch/mips/ite-boards/ivr/ \ - arch/mips/ite-boards/generic/ -LOADADDR += 0x80100000 -endif +core-$(CONFIG_DDB5XXX_COMMON) += arch/mips/ddb5xxx/common/ +core-$(CONFIG_DDB5074) += arch/mips/ddb5xxx/ddb5074/ +load-$(CONFIG_DDB5074) += 0x80080000 # -# Au1000 eval board +# NEC DDB Vrc-5476 # -ifdef CONFIG_MIPS_PB1000 -core-y += arch/mips/au1000/pb1000/ \ - arch/mips/au1000/common/ -LOADADDR += 0x80100000 -endif +core-$(CONFIG_DDB5476) += arch/mips/ddb5xxx/ddb5476/ +load-$(CONFIG_DDB5476) += 0x80080000 + +# +# NEC DDB Vrc-5477 +# +core-$(CONFIG_DDB5477) += arch/mips/ddb5xxx/ddb5477/ +load-$(CONFIG_DDB5477) += 0x80100000 + +core-$(CONFIG_LASAT) += arch/mips/lasat/ +load-$(CONFIG_LASAT) += 0x80000000 + +# +# NEC Osprey (vr4181) board +# +core-$(CONFIG_NEC_OSPREY) += arch/mips/vr4181/common/ \ + arch/mips/vr4181/osprey/ +load-$(CONFIG_NEC_OSPREY) += 0x80002000 + +# +# NEC Eagle/Hawk (VR4122/VR4131) board +# +core-$(CONFIG_VR41XX_COMMON) += arch/mips/vr41xx/common/ +core-$(CONFIG_NEC_EAGLE) += arch/mips/vr41xx/nec-eagle/ +load-$(CONFIG_NEC_EAGLE) += 0x80000000 + +# +# ZAO Networks Capcella (VR4131) +# +core-$(CONFIG_ZAO_CAPCELLA) += arch/mips/vr41xx/zao-capcella/ +load-$(CONFIG_ZAO_CAPCELLA) += 0x80000000 + +# +# Victor MP-C303/304 (VR4122) +# +core-$(CONFIG_VICTOR_MPC30X) += arch/mips/vr41xx/victor-mpc30x/ +load-$(CONFIG_VICTOR_MPC30X) += 0x80001000 + +# +# IBM WorkPad z50 (VR4121) +# +core-$(CONFIG_IBM_WORKPAD) += arch/mips/vr41xx/ibm-workpad/ +load-$(CONFIG_IBM_WORKPAD) += 0x80004000 + +# +# CASIO CASSIPEIA E-55/65 (VR4111) +# +core-$(CONFIG_CASIO_E55) += arch/mips/vr41xx/casio-e55/ +load-$(CONFIG_CASIO_E55) += 0x80004000 + +# +# TANBAC TB0226 Mbase (VR4131) +# +core-$(CONFIG_TANBAC_TB0226) += arch/mips/vr41xx/tanbac-tb0226/ +load-$(CONFIG_TANBAC_TB0226) += 0x80000000 + +# +# TANBAC TB0229 VR4131DIMM (VR4131) +# +core-$(CONFIG_TANBAC_TB0229) += arch/mips/vr41xx/tanbac-tb0229/ +load-$(CONFIG_TANBAC_TB0229) += 0x80000000 + +# +# SGI IP22 (Indy/Indigo2) +# +# Set the load address to >= 0x88069000 if you want to leave space for symmon, +# 0x88002000 for production kernels. Note that the value must be 8kb aligned +# or the handling of the current variable will break. +# +core-$(CONFIG_SGI_IP22) += arch/mips/sgi-ip22/ +load-$(CONFIG_SGI_IP22) += 0x88002000 + +# +# Sibyte SB1250 SOC +# +# This is a LIB so that it links at the end, and initcalls are later +# the sequence; but it is built as an object so that modules don't get +# removed (as happens, even if they have __initcall/module_init) +# +core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/sb1250/ +core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/sb1250/ + +# +# Sibyte BCM91120x (Carmel) board +# Sibyte BCM91120C (CRhine) board +# Sibyte BCM91125C (CRhone) board +# Sibyte BCM91125E (Rhone) board +# Sibyte SWARM board +# +libs-$(CONFIG_SIBYTE_CARMEL) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_CARMEL) := 0x80100000 +libs-$(CONFIG_SIBYTE_CRHINE) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_CRHINE) := 0x80100000 +libs-$(CONFIG_SIBYTE_CRHONE) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_CRHONE) := 0x80100000 +libs-$(CONFIG_SIBYTE_RHONE) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_RHONE) := 0x80100000 +libs-$(CONFIG_SIBYTE_SENTOSA) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_SENTOSA) := 0x80100000 +libs-$(CONFIG_SIBYTE_SWARM) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_SWARM) := 0x80100000 + +# +# SNI RM200 PCI +# +core-$(CONFIG_SNI_RM200_PCI) += arch/mips/sni/ +load-$(CONFIG_SNI_RM200_PCI) += 0x80080000 + +# +# Toshiba JMR-TX3927 board +# +core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/jmr3927/rbhma3100/ \ + arch/mips/jmr3927/common/ +load-$(CONFIG_TOSHIBA_JMR3927) += 0x80050000 + +# +# Toshiba RBTX4927 board or +# Toshiba RBTX4937 board +# +core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/toshiba_rbtx4927/ +core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/ +load-$(CONFIG_TOSHIBA_RBTX4927) := 0x80020000 + +drivers-$(CONFIG_PCI) += arch/mips/pci/ + # # Choosing incompatible machines durings configuration will result in @@ -254,42 +354,79 @@ # none has been choosen above. # -AFLAGS_vmlinux.lds.o := -DLOADADDR=$(LOADADDR) +AFLAGS_vmlinux.lds.o := -D"LOADADDR=$(load-y)" -D"JIFFIES32=$(JIFFIES32)" head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o -SUBDIRS := arch/mips/tools - -core-y += arch/mips/kernel/ arch/mips/mm/ -libs-y += arch/mips/lib/lib.a +libs-y += arch/mips/lib/ +core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ ifdef CONFIG_BAGET_MIPS BAGETBOOT = $(MAKE) -C arch/$(ARCH)/baget -balo: vmlinux +balo: vmlinux $(BAGETBOOT) balo endif -ifdef CONFIG_MIPS_EV64120 -GALILEOBOOT = $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120 +ifdef CONFIG_LASAT +rom.bin rom.sw: vmlinux + $(call descend,arch/mips/lasat/image,$@) +endif + +makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/mips/boot $(1) -gboot: vmlinux - $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120/compressed +# +# SNI firmware is f*cked in interesting ways ... +# +ifdef CONFIG_SNI_RM200_PCI +all: vmlinux.rm200 endif -MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot +vmlinux.ecoff vmlinux.rm200: vmlinux + +@$(call makeboot,$@) -vmlinux.ecoff: vmlinux - @$(MAKEBOOT) $@ +CLEAN_FILES += vmlinux.ecoff \ + vmlinux.rm200.tmp \ + vmlinux.rm200 archclean: - @$(MAKEBOOT) clean - rm -f arch/$(ARCH)/ld.script - $(MAKE) -C arch/$(ARCH)/tools clean - $(MAKE) -C arch/mips/baget clean + @$(MAKE) -f scripts/Makefile.clean obj=arch/mips/boot + @$(MAKE) -f scripts/Makefile.clean obj=arch/mips/baget + @$(MAKE) -f scripts/Makefile.clean obj=arch/mips/lasat archmrproper: - @$(MAKEBOOT) mrproper - $(MAKE) -C arch/$(ARCH)/tools mrproper + +# Generate <asm/offset.h +# +# The default rule is suffering from funny problems on MIPS so we using our +# own ... +# +# --------------------------------------------------------------------------- + +define filechk_gen-asm-offset.h + (set -e; \ + echo "#ifndef __ASM_OFFSET_H"; \ + echo "#define __ASM_OFFSET_H"; \ + echo "/*"; \ + echo " * DO NOT MODIFY."; \ + echo " *"; \ + echo " * This file was generated by arch/$(ARCH)/Makefile"; \ + echo " *"; \ + echo " */"; \ + echo ""; \ + sed -ne "/^@@@/s///p"; \ + echo "#endif /* __ASM_OFFSET_H */" ) +endef + +prepare: include/asm-$(ARCH)/offset.h + +arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \ + include/config/MARKER + +include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s + $(call filechk,gen-asm-offset.h) + +CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \ + include/asm-$(ARCH)/offset.h diff -Nru a/arch/mips/algor/README b/arch/mips/algor/README --- a/arch/mips/algor/README Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,5 +0,0 @@ -The code for the Algorithmics P4032 evaluation board is currently under -development. I'll release it when it's up to the same strength as -the other ports. - - Ralf diff -Nru a/arch/mips/arc/Makefile b/arch/mips/arc/Makefile --- a/arch/mips/arc/Makefile Fri Jun 27 14:19:54 2003 +++ b/arch/mips/arc/Makefile Fri Jun 27 14:19:54 2003 @@ -1,9 +1,10 @@ # -# Makefile for the SGI arcs prom monitor library routines -# under Linux. +# Makefile for the ARC prom monitor library routines under Linux. # -lib-y += console.o init.o memory.o tree.o env.o cmdline.o misc.o \ - time.o file.o identify.o +lib-y += cmdline.o env.o file.o identify.o init.o \ + misc.o time.o tree.o -lib-$(CONFIG_ARC_CONSOLE) += arc_con.o +lib-$(CONFIG_ARC_MEMORY) += memory.o +lib-$(CONFIG_ARC_CONSOLE) += arc_con.o +lib-$(CONFIG_ARC_PROMLIB) += promlib.o diff -Nru a/arch/mips/arc/arc_con.c b/arch/mips/arc/arc_con.c --- a/arch/mips/arc/arc_con.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/arc/arc_con.c Fri Jun 27 14:20:06 2003 @@ -2,69 +2,49 @@ * Wrap-around code for a console using the * ARC io-routines. * - * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 2001 Ralf Baechle + * Copyright (c) 2002 Thiemo Seufer */ - #include <linux/tty.h> #include <linux/major.h> -#include <linux/ptrace.h> #include <linux/init.h> #include <linux/console.h> #include <linux/fs.h> - -extern char prom_getchar (void); -extern void prom_printf (char *, ...); +#include <asm/sgialib.h> static void prom_console_write(struct console *co, const char *s, unsigned count) { - unsigned i; - - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - if (*s == 10) - prom_printf("%c", 13); - prom_printf("%c", *s++); + /* Do each character */ + while (count--) { + if (*s == '\n') + prom_putchar('\r'); + prom_putchar(*s++); } } -static int prom_console_wait_key(struct console *co) -{ - return prom_getchar(); -} - static int __init prom_console_setup(struct console *co, char *options) { - return 0; -} - -static kdev_t prom_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); + return !(prom_flags & PROM_FLAG_USE_AS_CONSOLE); } static struct console arc_cons = { - "ttyS", - prom_console_write, - NULL, - prom_console_device, - prom_console_wait_key, - NULL, - prom_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL + .name = "arc", + .write = prom_console_write, + .setup = prom_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; /* * Register console. */ -static void __init arc_console_init(void) +static int __init arc_console_init(void) { register_console(&arc_cons); + + return 0; } console_initcall(arc_console_init); diff -Nru a/arch/mips/arc/cmdline.c b/arch/mips/arc/cmdline.c --- a/arch/mips/arc/cmdline.c Fri Jun 27 14:20:04 2003 +++ b/arch/mips/arc/cmdline.c Fri Jun 27 14:20:04 2003 @@ -1,4 +1,8 @@ /* + * 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. + * * cmdline.c: Kernel command line creation using ARCS argc/argv. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) @@ -12,11 +16,11 @@ #undef DEBUG_CMDLINE -char arcs_cmdline[COMMAND_LINE_SIZE]; +char arcs_cmdline[CL_SIZE]; char * __init prom_getcmdline(void) { - return &(arcs_cmdline[0]); + return arcs_cmdline; } static char *ignored[] = { @@ -28,7 +32,6 @@ "OSLoadFilename=", "OSLoadOptions=" }; -#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) static char *used_arc[][2] = { { "OSLoadPartition=", "root=" }, @@ -43,16 +46,16 @@ actr = 1; /* Always ignore argv[0] */ while (actr < prom_argc) { - for(i = 0; i < NENTS(used_arc); i++) { + for(i = 0; i < ARRAY_SIZE(used_arc); i++) { int len = strlen(used_arc[i][0]); - if(!strncmp(prom_argv[actr], used_arc[i][0], len)) { + if (!strncmp(prom_argv(actr), used_arc[i][0], len)) { /* Ok, we want it. First append the replacement... */ strcat(cp, used_arc[i][1]); cp += strlen(used_arc[i][1]); /* ... and now the argument */ - s = strstr(prom_argv[actr], "="); - if(s) { + s = strstr(prom_argv(actr), "="); + if (s) { s++; strcpy(cp, s); cp += strlen(s); @@ -67,7 +70,6 @@ return cp; } - void __init prom_init_cmdline(void) { char *cp; @@ -75,33 +77,34 @@ actr = 1; /* Always ignore argv[0] */ - cp = &(arcs_cmdline[0]); - /* + cp = arcs_cmdline; + /* * Move ARC variables to the beginning to make sure they can be * overridden by later arguments. */ cp = move_firmware_args(cp); while (actr < prom_argc) { - for (i = 0; i < NENTS(ignored); i++) { + for (i = 0; i < ARRAY_SIZE(ignored); i++) { int len = strlen(ignored[i]); - if(!strncmp(prom_argv[actr], ignored[i], len)) + if (!strncmp(prom_argv(actr), ignored[i], len)) goto pic_cont; } /* Ok, we want it. */ - strcpy(cp, prom_argv[actr]); - cp += strlen(prom_argv[actr]); + strcpy(cp, prom_argv(actr)); + cp += strlen(prom_argv(actr)); *cp++ = ' '; pic_cont: actr++; } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + + if (cp != arcs_cmdline) /* get rid of trailing space */ --cp; *cp = '\0'; #ifdef DEBUG_CMDLINE - prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); + printk(KERN_DEBUG "prom cmdline: %s\n", arcs_cmdline); #endif } diff -Nru a/arch/mips/arc/console.c b/arch/mips/arc/console.c --- a/arch/mips/arc/console.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/arc/console.c Fri Jun 27 14:19:56 2003 @@ -6,14 +6,9 @@ * Copyright (C) 1996 David S. Miller (dm@sgi.com) * Compability with board caches, Ulf Carlsson */ -#include <linux/config.h> -#include <linux/init.h> #include <linux/kernel.h> #include <asm/sgialib.h> #include <asm/bcache.h> -#include <linux/console.h> -#include <linux/kdev_t.h> -#include <linux/major.h> /* * IP22 boardcache is not compatible with board caches. Thus we disable it @@ -27,44 +22,42 @@ void prom_putchar(char c) { - long cnt; - char it = c; + ULONG cnt; + CHAR it = c; bc_disable(); - romvec->write(1, &it, 1, &cnt); + ArcWrite(1, &it, 1, &cnt); bc_enable(); } -char __init prom_getchar(void) +char prom_getchar(void) { - long cnt; - char c; + ULONG cnt; + CHAR c; bc_disable(); - romvec->read(0, &c, 1, &cnt); + ArcRead(0, &c, 1, &cnt); bc_enable(); return c; } -static char ppbuf[1024]; - void prom_printf(char *fmt, ...) { va_list args; - char ch, *bptr; - int i; + char ppbuf[1024]; + char *bptr; va_start(args, fmt); - i = vsprintf(ppbuf, fmt, args); + vsprintf(ppbuf, fmt, args); bptr = ppbuf; - while ((ch = *(bptr++)) != 0) { - if (ch == '\n') + while (*bptr != 0) { + if (*bptr == '\n') prom_putchar('\r'); - prom_putchar(ch); + prom_putchar(*bptr++); } va_end(args); } diff -Nru a/arch/mips/arc/env.c b/arch/mips/arc/env.c --- a/arch/mips/arc/env.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/arc/env.c Fri Jun 27 14:19:54 2003 @@ -1,24 +1,27 @@ /* + * 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. + * * env.c: ARCS environment variable routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: env.c,v 1.2 1999/10/09 00:00:57 ralf Exp $ */ #include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h> +#include <asm/arc/types.h> #include <asm/sgialib.h> PCHAR __init ArcGetEnvironmentVariable(CHAR *name) { - return romvec->get_evar(name); + return (CHAR *) ARC_CALL1(get_evar, name); } LONG __init ArcSetEnvironmentVariable(PCHAR name, PCHAR value) { - return romvec->set_evar(name, value); + return ARC_CALL2(set_evar, name, value); } diff -Nru a/arch/mips/arc/file.c b/arch/mips/arc/file.c --- a/arch/mips/arc/file.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/arc/file.c Fri Jun 27 14:19:53 2003 @@ -1,59 +1,75 @@ /* - * file.c: ARCS firmware interface to files. + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * ARC firmware interface. * - * $Id: file.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $ + * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. */ #include <linux/init.h> + +#include <asm/arc/types.h> #include <asm/sgialib.h> -long __init prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt) +LONG __init +ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer, + ULONG N, ULONG *Count) { - return romvec->get_vdirent(fd, ent, num, cnt); + return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count); } -long __init prom_open(char *name, enum linux_omode md, unsigned long *fd) +LONG __init +ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID) { - return romvec->open(name, md, fd); + return ARC_CALL3(open, Path, OpenMode, FileID); } -long __init prom_close(unsigned long fd) +LONG __init +ArcClose(ULONG FileID) { - return romvec->close(fd); + return ARC_CALL1(close, FileID); } -long __init prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt) +LONG __init +ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count) { - return romvec->read(fd, buf, num, cnt); + return ARC_CALL4(read, FileID, Buffer, N, Count); } -long __init prom_getrstatus(unsigned long fd) +LONG __init +ArcGetReadStatus(ULONG FileID) { - return romvec->get_rstatus(fd); + return ARC_CALL1(get_rstatus, FileID); } -long __init prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt) +LONG __init +ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count) { - return romvec->write(fd, buf, num, cnt); + return ARC_CALL4(write, FileID, Buffer, N, Count); } -long __init prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm) +LONG __init +ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode) { - return romvec->seek(fd, off, sm); + return ARC_CALL3(seek, FileID, Position, SeekMode); } -long __init prom_mount(char *name, enum linux_mountops op) +LONG __init +ArcMount(char *name, enum linux_mountops op) { - return romvec->mount(name, op); + return ARC_CALL2(mount, name, op); } -long __init prom_getfinfo(unsigned long fd, struct linux_finfo *buf) +LONG __init +ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information) { - return romvec->get_finfo(fd, buf); + return ARC_CALL2(get_finfo, FileID, Information); } -long __init prom_setfinfo(unsigned long fd, unsigned long flags, unsigned long msk) +LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags, + ULONG AttributeMask) { - return romvec->set_finfo(fd, flags, msk); + return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask); } diff -Nru a/arch/mips/arc/identify.c b/arch/mips/arc/identify.c --- a/arch/mips/arc/identify.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/arc/identify.c Fri Jun 27 14:19:54 2003 @@ -1,65 +1,117 @@ /* + * 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. + * * identify.c: identify machine by looking up system identifier * * Copyright (C) 1998 Thomas Bogendoerfer - * + * * This code is based on arch/mips/sgi/kernel/system.c, which is - * + * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ +#include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> -#include <asm/sgi/sgi.h> #include <asm/sgialib.h> #include <asm/bootinfo.h> struct smatch { - char *name; + char *arcname; + char *liname; int group; int type; int flags; }; static struct smatch mach_table[] = { - {"SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS}, - {"Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0}, - {"PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0}, - {"RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0} + { "SGI-IP22", + "SGI Indy", + MACH_GROUP_SGI, + MACH_SGI_IP22, + PROM_FLAG_ARCS + }, { "SGI-IP27", + "SGI Origin", + MACH_GROUP_SGI, + MACH_SGI_IP27, + PROM_FLAG_ARCS + }, { "SGI-IP28", + "SGI IP28", + MACH_GROUP_SGI, + MACH_SGI_IP28, + PROM_FLAG_ARCS + }, { "SGI-IP32", + "SGI IP32", + MACH_GROUP_SGI, + MACH_SGI_IP32, + PROM_FLAG_ARCS + }, { "Microsoft-Jazz", + "Jazz MIPS_Magnum_4000", + MACH_GROUP_JAZZ, + MACH_MIPS_MAGNUM_4000, + 0 + }, { "PICA-61", + "Jazz Acer_PICA_61", + MACH_GROUP_JAZZ, + MACH_ACER_PICA_61, + 0 + }, { "RM200PCI", + "SNI RM200_PCI", + MACH_GROUP_SNI_RM, + MACH_SNI_RM200_PCI, + 0 + } }; int prom_flags; -static struct smatch *__init string_to_mach(char *s) +static struct smatch * __init string_to_mach(const char *s) { int i; for (i = 0; i < (sizeof(mach_table) / sizeof (mach_table[0])); i++) { - if (!strcmp(s, mach_table[i].name)) + if (!strcmp(s, mach_table[i].arcname)) return &mach_table[i]; } - prom_printf("\nYeee, could not determine architecture type <%s>\n", - s); - prom_printf("press a key to reboot\n"); - prom_getchar(); - romvec->imode(); - return NULL; + + panic("Yeee, could not determine architecture type <%s>", s); +} + +char *system_type; + +const char *get_system_type(void) +{ + return system_type; } void __init prom_identify_arch(void) { pcomponent *p; struct smatch *mach; + const char *iname; /* - * The root component tells us what machine architecture we - * have here. + * The root component tells us what machine architecture we have here. */ - p = prom_getchild(PROM_NULL_COMPONENT); - printk("ARCH: %s\n", p->iname); - mach = string_to_mach(p->iname); + p = ArcGetChild(PROM_NULL_COMPONENT); + if (p == NULL) { +#ifdef CONFIG_SGI_IP27 + /* IP27 PROM misbehaves, seems to not implement ARC + GetChild(). So we just assume it's an IP27. */ + iname = "SGI-IP27"; +#else + iname = "Unknown"; +#endif + } else + iname = (char *) (long) p->iname; + + printk("ARCH: %s\n", iname); + mach = string_to_mach(iname); + system_type = mach->liname; mips_machgroup = mach->group; mips_machtype = mach->type; diff -Nru a/arch/mips/arc/init.c b/arch/mips/arc/init.c --- a/arch/mips/arc/init.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/arc/init.c Fri Jun 27 14:19:56 2003 @@ -1,5 +1,5 @@ /* - * This file is subject to the terms and conditions of the GNU General Public+ + * 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. * @@ -16,38 +16,17 @@ /* Master romvec interface. */ struct linux_romvec *romvec; -struct linux_promblock *sgi_pblock; int prom_argc; -char **prom_argv, **prom_envp; -unsigned short prom_vers, prom_rev; - -extern void prom_testtree(void); - -extern void arc_setup_console(void); +LONG *_prom_argv, *_prom_envp; void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) { - struct linux_promblock *pb; - + PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK; romvec = ROMVECTOR; - pb = sgi_pblock = PROMBLOCK; prom_argc = argc; - prom_argv = argv; - prom_envp = envp; + _prom_argv = (LONG *) argv; + _prom_envp = (LONG *) envp; -#if 0 - /* arc_printf should not use prom_printf as soon as we free - * the prom buffers - This horribly breaks on Indys with framebuffer - * as it simply stops after initialising swap - On the Indigo2 serial - * console you will get A LOT illegal instructions - Only enable - * this for early init crashes - This also brings up artefacts of - * printing everything twice on serial console and on GFX Console - * this has the effect of having the prom printing everything - * in the small rectangle and the kernel printing around. - */ - - arc_setup_console(); -#endif if (pb->magic != 0x53435241) { prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic); while(1) @@ -55,19 +34,14 @@ } prom_init_cmdline(); - - prom_vers = pb->ver; - prom_rev = pb->rev; prom_identify_arch(); - printk("PROMLIB: ARC firmware Version %d Revision %d\n", - prom_vers, prom_rev); + printk(KERN_INFO "PROMLIB: ARC firmware Version %d Revision %d\n", + pb->ver, pb->rev); prom_meminit(); #ifdef DEBUG_PROM_INIT - { - prom_printf("Press a key to reboot\n"); - (void) prom_getchar(); - romvec->imode(); - } + prom_printf("Press a key to reboot\n"); + prom_getchar(); + ArcEnterInteractiveMode(); #endif } diff -Nru a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c --- a/arch/mips/arc/memory.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/arc/memory.c Fri Jun 27 14:19:59 2003 @@ -2,7 +2,14 @@ * memory.c: PROM library functions for acquiring/using memory descriptors * given to us from the ARCS firmware. * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1996 by David S. Miller + * Copyright (C) 1999, 2000, 2001 by Ralf Baechle + * Copyright (C) 1999, 2000 by Silicon Graphics, Inc. + * + * PROM library functions for acquiring/using memory descriptors given to us + * from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set + * because on some machines like SGI IP27 the ARC memory configuration data + * completly bogus and alternate easier to use mechanisms are available. */ #include <linux/init.h> #include <linux/kernel.h> @@ -19,10 +26,9 @@ #undef DEBUG -struct linux_mdesc * __init -ArcGetMemoryDescriptor(struct linux_mdesc *Current) +struct linux_mdesc * __init ArcGetMemoryDescriptor(struct linux_mdesc *Current) { - return romvec->get_mdesc(Current); + return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); } #ifdef DEBUG /* convenient for debugging */ @@ -47,7 +53,8 @@ "FirmwarePermanent", "FreeContiguous" }; -#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc] +#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \ + : arc_mtypes[a.arc] #endif static inline int memtype_classify_arcs (union linux_memtypes type) @@ -92,7 +99,7 @@ static int __init prom_memtype_classify (union linux_memtypes type) { - if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */ + if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */ return memtype_classify_arcs(type); return memtype_classify_arc(type); @@ -128,8 +135,7 @@ } } -void __init -prom_free_prom_memory (void) +void __init prom_free_prom_memory (void) { unsigned long freed = 0; unsigned long addr; @@ -149,5 +155,5 @@ freed += PAGE_SIZE; } } - printk("Freeing prom memory: %ldkb freed\n", freed >> 10); + printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10); } diff -Nru a/arch/mips/arc/misc.c b/arch/mips/arc/misc.c --- a/arch/mips/arc/misc.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/arc/misc.c Fri Jun 27 14:19:54 2003 @@ -1,13 +1,21 @@ /* - * misc.c: Miscellaneous ARCS PROM routines. + * 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. + * + * Miscellaneous ARCS PROM routines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. */ #include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <asm/bcache.h> + +#include <asm/arc/types.h> #include <asm/sgialib.h> #include <asm/bootinfo.h> #include <asm/system.h> @@ -15,68 +23,81 @@ extern void *sgiwd93_host; extern void reset_wd33c93(void *instance); -void prom_halt(void) +VOID +ArcHalt(VOID) { bc_disable(); - cli(); + local_irq_disable(); #ifdef CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); #endif - romvec->halt(); + ARC_CALL0(halt); +never: goto never; } -void prom_powerdown(void) +VOID +ArcPowerDown(VOID) { bc_disable(); - cli(); + local_irq_disable(); #ifdef CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); #endif - romvec->pdown(); + ARC_CALL0(pdown); +never: goto never; } /* XXX is this a soft reset basically? XXX */ -void prom_restart(void) +VOID +ArcRestart(VOID) { bc_disable(); - cli(); + local_irq_disable(); #ifdef CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); #endif - romvec->restart(); + ARC_CALL0(restart); +never: goto never; } -void prom_reboot(void) +VOID +ArcReboot(VOID) { bc_disable(); - cli(); + local_irq_disable(); #ifdef CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); #endif - romvec->reboot(); + ARC_CALL0(reboot); +never: goto never; } -void ArcEnterInteractiveMode(void) +VOID +ArcEnterInteractiveMode(VOID) { bc_disable(); - cli(); + local_irq_disable(); #ifdef CONFIG_SCSI_SGIWD93 reset_wd33c93(sgiwd93_host); #endif - romvec->imode(); + ARC_CALL0(imode); +never: goto never; } -long prom_cfgsave(void) +LONG +ArcSaveConfiguration(VOID) { - return romvec->cfg_save(); + return ARC_CALL0(cfg_save); } -struct linux_sysid *prom_getsysid(void) +struct linux_sysid * +ArcGetSystemId(VOID) { - return romvec->get_sysid(); + return (struct linux_sysid *) ARC_CALL0(get_sysid); } -void __init prom_cacheflush(void) +VOID __init +ArcFlushAllCaches(VOID) { - romvec->cache_flush(); + ARC_CALL0(cache_flush); } diff -Nru a/arch/mips/arc/promlib.c b/arch/mips/arc/promlib.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/arc/promlib.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,43 @@ +/* + * 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) 1996 David S. Miller (dm@sgi.com) + * Compability with board caches, Ulf Carlsson + */ +#include <linux/kernel.h> +#include <asm/sgialib.h> +#include <asm/bcache.h> + +/* + * IP22 boardcache is not compatible with board caches. Thus we disable it + * during romvec action. Since r4xx0.c is always compiled and linked with your + * kernel, this shouldn't cause any harm regardless what MIPS processor you + * have. + * + * The ARC write and read functions seem to interfere with the serial lines + * in some way. You should be careful with them. + */ + +void prom_putchar(char c) +{ + ULONG cnt; + CHAR it = c; + + bc_disable(); + ArcWrite(1, &it, 1, &cnt); + bc_enable(); +} + +char prom_getchar(void) +{ + ULONG cnt; + CHAR c; + + bc_disable(); + ArcRead(0, &c, 1, &cnt); + bc_enable(); + + return c; +} diff -Nru a/arch/mips/arc/salone.c b/arch/mips/arc/salone.c --- a/arch/mips/arc/salone.c Fri Jun 27 14:20:05 2003 +++ b/arch/mips/arc/salone.c Fri Jun 27 14:20:05 2003 @@ -1,25 +1,24 @@ /* - * salone.c: Routines to load into memory and execute stand-along - * program images using ARCS PROM firmware. + * Routines to load into memory and execute stand-along program images using + * ARCS PROM firmware. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: salone.c,v 1.1 1998/10/18 13:32:09 tsbogend Exp $ */ #include <linux/init.h> #include <asm/sgialib.h> -long __init prom_load(char *name, unsigned long end, unsigned long *pc, unsigned long *eaddr) +LONG __init ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr) { - return romvec->load(name, end, pc, eaddr); + return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr); } -long __init prom_invoke(unsigned long pc, unsigned long sp, long argc, char **argv, char **envp) +LONG __init ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[], + CHAR *Envp[]) { - return romvec->invoke(pc, sp, argc, argv, envp); + return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp); } -long __init prom_exec(char *name, long argc, char **argv, char **envp) +LONG __init ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[]) { - return romvec->exec(name, argc, argv, envp); + return ARC_CALL4(exec, Path, Argc, Argv, Envp); } diff -Nru a/arch/mips/arc/time.c b/arch/mips/arc/time.c --- a/arch/mips/arc/time.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/arc/time.c Fri Jun 27 14:19:56 2003 @@ -1,19 +1,25 @@ /* - * time.c: Extracting time information from ARCS prom. + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * Extracting time information from ARCS prom. * - * $Id: time.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $ + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ #include <linux/init.h> + +#include <asm/arc/types.h> #include <asm/sgialib.h> -struct linux_tinfo * __init prom_gettinfo(void) +struct linux_tinfo * __init +ArcGetTime(VOID) { - return romvec->get_tinfo(); + return (struct linux_tinfo *) ARC_CALL0(get_tinfo); } -unsigned long __init prom_getrtime(void) +ULONG __init +ArcGetRelativeTime(VOID) { - return romvec->get_rtime(); + return ARC_CALL0(get_rtime); } diff -Nru a/arch/mips/arc/tree.c b/arch/mips/arc/tree.c --- a/arch/mips/arc/tree.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/arc/tree.c Fri Jun 27 14:19:57 2003 @@ -1,72 +1,88 @@ /* - * tree.c: PROM component device tree code. + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * PROM component device tree code. * - * $Id: tree.c,v 1.1 1998/10/18 13:32:10 tsbogend Exp $ + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. */ #include <linux/init.h> +#include <asm/arc/types.h> #include <asm/sgialib.h> -#define DEBUG_PROM_TREE +#undef DEBUG_PROM_TREE -pcomponent * __init prom_getsibling(pcomponent *this) +pcomponent * __init +ArcGetPeer(pcomponent *Current) { - if(this == PROM_NULL_COMPONENT) + if (Current == PROM_NULL_COMPONENT) return PROM_NULL_COMPONENT; - return romvec->next_component(this); + + return (pcomponent *) ARC_CALL1(next_component, Current); } -pcomponent * __init prom_getchild(pcomponent *this) +pcomponent * __init +ArcGetChild(pcomponent *Current) { - return romvec->child_component(this); + return (pcomponent *) ARC_CALL1(child_component, Current); } -pcomponent * __init prom_getparent(pcomponent *child) +pcomponent * __init +ArcGetParent(pcomponent *Current) { - if(child == PROM_NULL_COMPONENT) + if (Current == PROM_NULL_COMPONENT) return PROM_NULL_COMPONENT; - return romvec->parent_component(child); + + return (pcomponent *) ARC_CALL1(parent_component, Current); } -long __init prom_getcdata(void *buffer, pcomponent *this) +LONG __init +ArcGetConfigurationData(VOID *Buffer, pcomponent *Current) { - return romvec->component_data(buffer, this); + return ARC_CALL2(component_data, Buffer, Current); } -pcomponent * __init prom_childadd(pcomponent *this, pcomponent *tmp, void *data) +pcomponent * __init +ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData) { - return romvec->child_add(this, tmp, data); + return (pcomponent *) + ARC_CALL3(child_add, Current, Template, ConfigurationData); } -long __init prom_delcomponent(pcomponent *this) +LONG __init +ArcDeleteComponent(pcomponent *ComponentToDelete) { - return romvec->comp_del(this); + return ARC_CALL1(comp_del, ComponentToDelete); } -pcomponent * __init prom_componentbypath(char *path) +pcomponent * __init +ArcGetComponent(CHAR *Path) { - return romvec->component_by_path(path); + return (pcomponent *)ARC_CALL1(component_by_path, Path); } #ifdef DEBUG_PROM_TREE + static char *classes[] = { "system", "processor", "cache", "adapter", "controller", "peripheral", "memory" }; static char *types[] = { - "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", "sccache", - "memdev", "eisa adapter", "tc adapter", "scsi adapter", "dti adapter", - "multi-func adapter", "disk controller", "tp controller", - "cdrom controller", "worm controller", "serial controller", - "net controller", "display controller", "parallel controller", - "pointer controller", "keyboard controller", "audio controller", - "misc controller", "disk peripheral", "floppy peripheral", - "tp peripheral", "modem peripheral", "monitor peripheral", - "printer peripheral", "pointer peripheral", "keyboard peripheral", - "terminal peripheral", "line peripheral", "net peripheral", - "misc peripheral", "anonymous" + "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", + "sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter", + "dti adapter", "multi-func adapter", "disk controller", + "tp controller", "cdrom controller", "worm controller", + "serial controller", "net controller", "display controller", + "parallel controller", "pointer controller", "keyboard controller", + "audio controller", "misc controller", "disk peripheral", + "floppy peripheral", "tp peripheral", "modem peripheral", + "monitor peripheral", "printer peripheral", "pointer peripheral", + "keyboard peripheral", "terminal peripheral", "line peripheral", + "net peripheral", "misc peripheral", "anonymous" }; static char *iflags[] = { @@ -74,7 +90,8 @@ "input", "output" }; -static void __init dump_component(pcomponent *p) +static void __init +dump_component(pcomponent *p) { prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", p, classes[p->class], types[p->type], @@ -83,27 +100,28 @@ p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); } -static void __init traverse(pcomponent *p, int op) +static void __init +traverse(pcomponent *p, int op) { dump_component(p); - if(prom_getchild(p)) - traverse(prom_getchild(p), 1); - if(prom_getsibling(p) && op) - traverse(prom_getsibling(p), 1); + if(ArcGetChild(p)) + traverse(ArcGetChild(p), 1); + if(ArcGetPeer(p) && op) + traverse(ArcGetPeer(p), 1); } -void __init prom_testtree(void) +void __init +prom_testtree(void) { pcomponent *p; - p = prom_getchild(PROM_NULL_COMPONENT); + p = ArcGetChild(PROM_NULL_COMPONENT); dump_component(p); - p = prom_getchild(p); + p = ArcGetChild(p); while(p) { dump_component(p); - p = prom_getsibling(p); + p = ArcGetPeer(p); } - prom_printf("press a key\n"); - prom_getchar(); } -#endif + +#endif /* DEBUG_PROM_TREE */ diff -Nru a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile --- a/arch/mips/au1000/common/Makefile Fri Jun 27 14:20:05 2003 +++ b/arch/mips/au1000/common/Makefile Fri Jun 27 14:20:05 2003 @@ -5,14 +5,14 @@ # # Makefile for the Alchemy Au1000 CPU, generic files. # +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# -obj-y := prom.o dbg_io.o int-handler.o irq.o puts.o time.o reset.o +obj-y += prom.o int-handler.o dma.o irq.o puts.o \ + time.o reset.o clocks.o power.o -obj-$(CONFIG_AU1000_UART) += serial.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o -obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o - -EXTRA_AFLAGS := $(CFLAGS) - -ramdisk.o: - mkramobj ramdisk ramdisk.o +obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o +obj-$(CONFIG_KGDB) += dbg_io.o +obj-$(CONFIG_RTC) += rtc.o diff -Nru a/arch/mips/au1000/common/clocks.c b/arch/mips/au1000/common/clocks.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/common/clocks.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,97 @@ +/* + * BRIEF MODULE DESCRIPTION + * Simple Au1000 clocks routines. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/module.h> +#include <asm/au1000.h> + +static unsigned int au1x00_clock; // Hz +static unsigned int lcd_clock; // KHz +static unsigned long uart_baud_base; + +/* + * Set the au1000_clock + */ +void set_au1x00_speed(unsigned int new_freq) +{ + au1x00_clock = new_freq; +} + +unsigned int get_au1x00_speed(void) +{ + return au1x00_clock; +} + + + +/* + * The UART baud base is not known at compile time ... if + * we want to be able to use the same code on different + * speed CPUs. + */ +unsigned long get_au1x00_uart_baud_base(void) +{ + return uart_baud_base; +} + +void set_au1x00_uart_baud_base(unsigned long new_baud_base) +{ + uart_baud_base = new_baud_base; +} + +/* + * Calculate the Au1x00's LCD clock based on the current + * cpu clock and the system bus clock, and try to keep it + * below 40 MHz (the Pb1000 board can lock-up if the LCD + * clock is over 40 MHz). + */ +void set_au1x00_lcd_clock(void) +{ + unsigned int static_cfg0; + unsigned int sys_busclk = + (get_au1x00_speed()/1000) / + ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2); + + static_cfg0 = au_readl(MEM_STCFG0); + + if (static_cfg0 & (1<<11)) + lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */ + else + lcd_clock = sys_busclk / 4; + + if (lcd_clock > 50000) /* Epson MAX */ + printk("%s: warning: LCD clock too high (%d KHz)\n", + __FUNCTION__, lcd_clock); +} + +unsigned int get_au1x00_lcd_clock(void) +{ + return lcd_clock; +} + +EXPORT_SYMBOL(get_au1x00_lcd_clock); diff -Nru a/arch/mips/au1000/common/dbg_io.c b/arch/mips/au1000/common/dbg_io.c --- a/arch/mips/au1000/common/dbg_io.c Fri Jun 27 14:20:04 2003 +++ b/arch/mips/au1000/common/dbg_io.c Fri Jun 27 14:20:04 2003 @@ -3,13 +3,13 @@ #include <asm/io.h> #include <asm/au1000.h> -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB /* * FIXME the user should be able to select the * uart to be used for debugging. */ -#define DEBUG_BASE UART2_ADDR +#define DEBUG_BASE UART_DEBUG_BASE /**/ /* we need uint32 uint8 */ @@ -53,8 +53,11 @@ #define UART_MOD_CNTRL 0x100 /* Module Control */ /* memory-mapped read/write of the port */ -#define UART16550_READ(y) (inl(DEBUG_BASE + y) & 0xff) -#define UART16550_WRITE(y,z) (outl(z&0xff, DEBUG_BASE + y)) +#define UART16550_READ(y) (au_readl(DEBUG_BASE + y) & 0xff) +#define UART16550_WRITE(y,z) (au_writel(z&0xff, DEBUG_BASE + y)) + +extern unsigned long get_au1x00_uart_baud_base(void); +extern unsigned long cal_r4koff(void); void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) { @@ -68,16 +71,16 @@ UART16550_WRITE(UART_IER, 0); /* set up baud rate */ - { + { uint32 divisor; /* set divisor */ - divisor = get_au1000_uart_baud() / baud; + divisor = get_au1x00_uart_baud_base() / baud; UART16550_WRITE(UART_CLK, divisor & 0xffff); } /* set data format */ - UART16550_WRITE(UART_LCR, data | parity | stop); + UART16550_WRITE(UART_LCR, (data | parity | stop)); } static int remoteDebugInitialized = 0; @@ -99,7 +102,8 @@ int putDebugChar(uint8 byte) { - int i; +// int i; + if (!remoteDebugInitialized) { remoteDebugInitialized = 1; debugInit(UART16550_BAUD_115200, diff -Nru a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/common/dma.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,217 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * A DMA channel allocator for Au1000. API is modeled loosely off of + * linux/kernel/dma.c. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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 <linux/kernel.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <asm/au1000.h> +#include <asm/au1000_dma.h> +#include <asm/system.h> + + + +/* + * A note on resource allocation: + * + * All drivers needing DMA channels, should allocate and release them + * through the public routines `request_dma()' and `free_dma()'. + * + * In order to avoid problems, all processes should allocate resources in + * the same sequence and release them in the reverse order. + * + * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ. + * When releasing them, first release the IRQ, then release the DMA. The + * main reason for this order is that, if you are requesting the DMA buffer + * done interrupt, you won't know the irq number until the DMA channel is + * returned from request_dma. + */ + + +spinlock_t au1000_dma_spin_lock = SPIN_LOCK_UNLOCKED; + +struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = { + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,}, + {dev_id:-1,} +}; + +// Device FIFO addresses and default DMA modes +static const struct { + unsigned int fifo_addr; + unsigned int dma_mode; +} dma_dev_table[DMA_NUM_DEV] = { + {UART0_ADDR + UART_TX, 0}, + {UART0_ADDR + UART_RX, 0}, + {0, 0}, + {0, 0}, + {AC97C_DATA, DMA_DW16 }, // coherent + {AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent + {UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC}, + {UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC}, + {USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC}, + {USBD_EP0WR, DMA_DW8 | DMA_NC}, + {USBD_EP2WR, DMA_DW8 | DMA_NC}, + {USBD_EP3WR, DMA_DW8 | DMA_NC}, + {USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC}, + {USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC}, + {I2S_DATA, DMA_DW32 | DMA_NC}, + {I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC} +}; + + +int au1000_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data) +{ + int i, len = 0; + struct dma_chan *chan; + + for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) { + if ((chan = get_dma_chan(i)) != NULL) { + len += sprintf(buf + len, "%2d: %s\n", + i, chan->dev_str); + } + } + + if (fpos >= len) { + *start = buf; + *eof = 1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof = 1; + return len; +} + + +void dump_au1000_dma_channel(unsigned int dmanr) +{ + struct dma_chan *chan; + + if (dmanr > NUM_AU1000_DMA_CHANNELS) + return; + chan = &au1000_dma_table[dmanr]; + + printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr); + printk(KERN_INFO " mode = 0x%08x\n", + au_readl(chan->io + DMA_MODE_SET)); + printk(KERN_INFO " addr = 0x%08x\n", + au_readl(chan->io + DMA_PERIPHERAL_ADDR)); + printk(KERN_INFO " start0 = 0x%08x\n", + au_readl(chan->io + DMA_BUFFER0_START)); + printk(KERN_INFO " start1 = 0x%08x\n", + au_readl(chan->io + DMA_BUFFER1_START)); + printk(KERN_INFO " count0 = 0x%08x\n", + au_readl(chan->io + DMA_BUFFER0_COUNT)); + printk(KERN_INFO " count1 = 0x%08x\n", + au_readl(chan->io + DMA_BUFFER1_COUNT)); +} + + +/* + * Finds a free channel, and binds the requested device to it. + * Returns the allocated channel number, or negative on error. + * Requests the DMA done IRQ if irqhandler != NULL. + */ +int request_au1000_dma(int dev_id, const char *dev_str, + void (*irqhandler)(int, void *, struct pt_regs *), + unsigned long irqflags, + void *irq_dev_id) +{ + struct dma_chan *chan; + int i, ret; + + if (dev_id < 0 || dev_id >= DMA_NUM_DEV) + return -EINVAL; + + for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) { + if (au1000_dma_table[i].dev_id < 0) + break; + } + if (i == NUM_AU1000_DMA_CHANNELS) + return -ENODEV; + + chan = &au1000_dma_table[i]; + + if (irqhandler) { + chan->irq = AU1000_DMA_INT_BASE + i; + chan->irq_dev = irq_dev_id; + if ((ret = request_irq(chan->irq, irqhandler, irqflags, + dev_str, chan->irq_dev))) { + chan->irq = 0; + chan->irq_dev = NULL; + return ret; + } + } else { + chan->irq = 0; + chan->irq_dev = NULL; + } + + // fill it in + chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN; + chan->dev_id = dev_id; + chan->dev_str = dev_str; + chan->fifo_addr = dma_dev_table[dev_id].fifo_addr; + chan->mode = dma_dev_table[dev_id].dma_mode; + + /* initialize the channel before returning */ + init_dma(i); + + return i; +} + + +void free_au1000_dma(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) { + printk("Trying to free DMA%d\n", dmanr); + return; + } + + disable_dma(dmanr); + if (chan->irq) + free_irq(chan->irq, chan->irq_dev); + + chan->irq = 0; + chan->irq_dev = NULL; + chan->dev_id = -1; +} diff -Nru a/arch/mips/au1000/common/int-handler.S b/arch/mips/au1000/common/int-handler.S --- a/arch/mips/au1000/common/int-handler.S Fri Jun 27 14:19:55 2003 +++ b/arch/mips/au1000/common/int-handler.S Fri Jun 27 14:19:55 2003 @@ -9,7 +9,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include <linux/config.h> #include <asm/asm.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> @@ -40,32 +39,30 @@ 1: andi a0, t0, CAUSEF_IP2 # Interrupt Controller 0, Request 0 - beq a0, zero, 2f - move a0,sp + beq a0, zero, 2f + move a0,sp jal intc0_req0_irqdispatch j ret_from_irq 2: andi a0, t0, CAUSEF_IP3 # Interrupt Controller 0, Request 1 - beq a0, zero, 3f - move a0,sp + beq a0, zero, 3f + move a0,sp jal intc0_req1_irqdispatch j ret_from_irq 3: andi a0, t0, CAUSEF_IP4 # Interrupt Controller 1, Request 0 - beq a0, zero, 4f - move a0,sp + beq a0, zero, 4f + move a0,sp jal intc1_req0_irqdispatch j ret_from_irq 4: andi a0, t0, CAUSEF_IP5 # Interrupt Controller 1, Request 1 - beq a0, zero, 5f - move a0, sp + beq a0, zero, 5f + move a0, sp jal intc1_req1_irqdispatch j ret_from_irq -5: +5: move a0, sp - jal mips_spurious_interrupt -done: - j ret_from_irq + j spurious_interrupt END(au1000_IRQ) diff -Nru a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c --- a/arch/mips/au1000/common/irq.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/au1000/common/irq.c Fri Jun 27 14:19:55 2003 @@ -28,6 +28,7 @@ */ #include <linux/errno.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/kernel_stat.h> #include <linux/module.h> #include <linux/signal.h> @@ -47,7 +48,21 @@ #include <asm/system.h> #include <asm/au1000.h> -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) +#if defined(CONFIG_MIPS_PB1000) +#include <asm/pb1000.h> +#elif defined(CONFIG_MIPS_PB1500) +#include <asm/pb1500.h> +#elif defined(CONFIG_MIPS_PB1100) +#include <asm/pb1100.h> +#elif defined(CONFIG_MIPS_DB1000) +#include <asm/db1x00.h> +#elif defined(CONFIG_MIPS_DB1100) +#include <asm/db1x00.h> +#elif defined(CONFIG_MIPS_DB1500) +#include <asm/db1x00.h> +#else +#error unsupported Alchemy board +#endif #undef DEBUG_IRQ #ifdef DEBUG_IRQ @@ -63,16 +78,13 @@ #define EXT_INTC1_REQ1 5 /* IP 5 */ #define MIPS_TIMER_IP 7 /* IP 7 */ -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); #endif extern asmlinkage void au1000_IRQ(void); - extern void set_debug_traps(void); -extern irq_cpustat_t irq_stat []; -extern irq_desc_t irq_desc[NR_IRQS]; - +extern irq_cpustat_t irq_stat [NR_CPUS]; unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; @@ -82,154 +94,113 @@ static inline void mask_and_ack_level_irq(unsigned int irq_nr); static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr); -static inline void local_enable_irq(unsigned int irq_nr); -static inline void local_disable_irq(unsigned int irq_nr); +inline void local_enable_irq(unsigned int irq_nr); +inline void local_disable_irq(unsigned int irq_nr); -unsigned long spurious_interrupts; -extern unsigned int do_IRQ(int irq, struct pt_regs *regs); extern void __init init_generic_irq(void); -static inline void sync(void) -{ - __asm volatile ("sync"); -} - - -/* Function for careful CP0 interrupt mask access */ -static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) -{ - unsigned long status = read_32bit_cp0_register(CP0_STATUS); - status &= ~((clr_mask & 0xFF) << 8); - status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); -} - - -static inline void mask_cpu_irq_input(unsigned int irq_nr) -{ - modify_cp0_intmask(irq_nr, 0); -} - - -static inline void unmask_cpu_irq_input(unsigned int irq_nr) -{ - modify_cp0_intmask(0, irq_nr); -} - - -static void disable_cpu_irq_input(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - mask_cpu_irq_input(irq_nr); - restore_flags(flags); -} - - -static void enable_cpu_irq_input(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - unmask_cpu_irq_input(irq_nr); - restore_flags(flags); -} +#ifdef CONFIG_PM +extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs); +#endif +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; static void setup_local_irq(unsigned int irq_nr, int type, int int_req) { + if (irq_nr > AU1000_MAX_INTR) return; /* Config2[n], Config1[n], Config0[n] */ if (irq_nr > AU1000_LAST_INTC0_INT) { switch (type) { case INTC_INT_RISE_EDGE: /* 0:0:1 */ - outl(1<<irq_nr,INTC1_CONFIG2_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG0_SET); + au_writel(1<<(irq_nr-32), IC1_CFG2CLR); + au_writel(1<<(irq_nr-32), IC1_CFG1CLR); + au_writel(1<<(irq_nr-32), IC1_CFG0SET); break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ - outl(1<<irq_nr, INTC1_CONFIG2_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG1_SET); - outl(1<<irq_nr, INTC1_CONFIG0_CLEAR); + au_writel(1<<(irq_nr-32), IC1_CFG2CLR); + au_writel(1<<(irq_nr-32), IC1_CFG1SET); + au_writel(1<<(irq_nr-32), IC1_CFG0CLR); break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ - outl(1<<irq_nr, INTC1_CONFIG2_SET); - outl(1<<irq_nr, INTC1_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG0_SET); + au_writel(1<<(irq_nr-32), IC1_CFG2SET); + au_writel(1<<(irq_nr-32), IC1_CFG1CLR); + au_writel(1<<(irq_nr-32), IC1_CFG0SET); break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ - outl(1<<irq_nr, INTC1_CONFIG2_SET); - outl(1<<irq_nr, INTC1_CONFIG1_SET); - outl(1<<irq_nr, INTC1_CONFIG0_CLEAR); + au_writel(1<<(irq_nr-32), IC1_CFG2SET); + au_writel(1<<(irq_nr-32), IC1_CFG1SET); + au_writel(1<<(irq_nr-32), IC1_CFG0CLR); break; case INTC_INT_DISABLED: /* 0:0:0 */ - outl(1<<irq_nr, INTC1_CONFIG0_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG2_CLEAR); + au_writel(1<<(irq_nr-32), IC1_CFG0CLR); + au_writel(1<<(irq_nr-32), IC1_CFG1CLR); + au_writel(1<<(irq_nr-32), IC1_CFG2CLR); break; default: /* disable the interrupt */ printk("unexpected int type %d (irq %d)\n", type, irq_nr); - outl(1<<irq_nr, INTC1_CONFIG0_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC1_CONFIG2_CLEAR); + au_writel(1<<(irq_nr-32), IC1_CFG0CLR); + au_writel(1<<(irq_nr-32), IC1_CFG1CLR); + au_writel(1<<(irq_nr-32), IC1_CFG2CLR); return; } if (int_req) /* assign to interrupt request 1 */ - outl(1<<irq_nr, INTC1_ASSIGN_REQ_CLEAR); + au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR); else /* assign to interrupt request 0 */ - outl(1<<irq_nr, INTC1_ASSIGN_REQ_SET); - outl(1<<irq_nr, INTC1_SOURCE_SET); - outl(1<<irq_nr, INTC1_MASK_CLEAR); + au_writel(1<<(irq_nr-32), IC1_ASSIGNSET); + au_writel(1<<(irq_nr-32), IC1_SRCSET); + au_writel(1<<(irq_nr-32), IC1_MASKCLR); + au_writel(1<<(irq_nr-32), IC1_WAKECLR); } else { switch (type) { case INTC_INT_RISE_EDGE: /* 0:0:1 */ - outl(1<<irq_nr,INTC0_CONFIG2_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG0_SET); + au_writel(1<<irq_nr, IC0_CFG2CLR); + au_writel(1<<irq_nr, IC0_CFG1CLR); + au_writel(1<<irq_nr, IC0_CFG0SET); break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ - outl(1<<irq_nr, INTC0_CONFIG2_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG1_SET); - outl(1<<irq_nr, INTC0_CONFIG0_CLEAR); + au_writel(1<<irq_nr, IC0_CFG2CLR); + au_writel(1<<irq_nr, IC0_CFG1SET); + au_writel(1<<irq_nr, IC0_CFG0CLR); break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ - outl(1<<irq_nr, INTC0_CONFIG2_SET); - outl(1<<irq_nr, INTC0_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG0_SET); + au_writel(1<<irq_nr, IC0_CFG2SET); + au_writel(1<<irq_nr, IC0_CFG1CLR); + au_writel(1<<irq_nr, IC0_CFG0SET); break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ - outl(1<<irq_nr, INTC0_CONFIG2_SET); - outl(1<<irq_nr, INTC0_CONFIG1_SET); - outl(1<<irq_nr, INTC0_CONFIG0_CLEAR); + au_writel(1<<irq_nr, IC0_CFG2SET); + au_writel(1<<irq_nr, IC0_CFG1SET); + au_writel(1<<irq_nr, IC0_CFG0CLR); break; case INTC_INT_DISABLED: /* 0:0:0 */ - outl(1<<irq_nr, INTC0_CONFIG0_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG2_CLEAR); + au_writel(1<<irq_nr, IC0_CFG0CLR); + au_writel(1<<irq_nr, IC0_CFG1CLR); + au_writel(1<<irq_nr, IC0_CFG2CLR); break; default: /* disable the interrupt */ printk("unexpected int type %d (irq %d)\n", type, irq_nr); - outl(1<<irq_nr, INTC0_CONFIG0_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG1_CLEAR); - outl(1<<irq_nr, INTC0_CONFIG2_CLEAR); + au_writel(1<<irq_nr, IC0_CFG0CLR); + au_writel(1<<irq_nr, IC0_CFG1CLR); + au_writel(1<<irq_nr, IC0_CFG2CLR); return; } if (int_req) /* assign to interrupt request 1 */ - outl(1<<irq_nr, INTC0_ASSIGN_REQ_CLEAR); + au_writel(1<<irq_nr, IC0_ASSIGNCLR); else /* assign to interrupt request 0 */ - outl(1<<irq_nr, INTC0_ASSIGN_REQ_SET); - outl(1<<irq_nr, INTC0_SOURCE_SET); - outl(1<<irq_nr, INTC0_MASK_CLEAR); + au_writel(1<<irq_nr, IC0_ASSIGNSET); + au_writel(1<<irq_nr, IC0_SRCSET); + au_writel(1<<irq_nr, IC0_MASKCLR); + au_writel(1<<irq_nr, IC0_WAKECLR); } - sync(); + au_sync(); } static unsigned int startup_irq(unsigned int irq_nr) { local_enable_irq(irq_nr); - return 0; + return 0; } @@ -240,71 +211,133 @@ } -static inline void local_enable_irq(unsigned int irq_nr) +inline void local_enable_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - outl(1<<irq_nr, INTC1_MASK_SET); + au_writel(1<<(irq_nr-32), IC1_MASKSET); + au_writel(1<<(irq_nr-32), IC1_WAKESET); } else { - outl(1<<irq_nr, INTC0_MASK_SET); + au_writel(1<<irq_nr, IC0_MASKSET); + au_writel(1<<irq_nr, IC0_WAKESET); } - sync(); + au_sync(); } -static inline void local_disable_irq(unsigned int irq_nr) +inline void local_disable_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - outl(1<<irq_nr, INTC1_MASK_CLEAR); + au_writel(1<<(irq_nr-32), IC1_MASKCLR); + au_writel(1<<(irq_nr-32), IC1_WAKECLR); } else { - outl(1<<irq_nr, INTC0_MASK_CLEAR); + au_writel(1<<irq_nr, IC0_MASKCLR); + au_writel(1<<irq_nr, IC0_WAKECLR); } - sync(); + au_sync(); } static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - outl(1<<irq_nr, INTC1_R_EDGE_DETECT_CLEAR); - outl(1<<irq_nr, INTC1_MASK_CLEAR); + au_writel(1<<(irq_nr-32), IC1_RISINGCLR); + au_writel(1<<(irq_nr-32), IC1_MASKCLR); } else { - outl(1<<irq_nr, INTC0_R_EDGE_DETECT_CLEAR); - outl(1<<irq_nr, INTC0_MASK_CLEAR); + au_writel(1<<irq_nr, IC0_RISINGCLR); + au_writel(1<<irq_nr, IC0_MASKCLR); } - sync(); + au_sync(); } static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { - outl(1<<irq_nr, INTC1_F_EDGE_DETECT_CLEAR); - outl(1<<irq_nr, INTC1_MASK_CLEAR); + au_writel(1<<(irq_nr-32), IC1_FALLINGCLR); + au_writel(1<<(irq_nr-32), IC1_MASKCLR); } else { - outl(1<<irq_nr, INTC0_F_EDGE_DETECT_CLEAR); - outl(1<<irq_nr, INTC0_MASK_CLEAR); + au_writel(1<<irq_nr, IC0_FALLINGCLR); + au_writel(1<<irq_nr, IC0_MASKCLR); } + au_sync(); } static inline void mask_and_ack_level_irq(unsigned int irq_nr) { + local_disable_irq(irq_nr); - sync(); + au_sync(); +#if defined(CONFIG_MIPS_PB1000) + if (irq_nr == AU1000_GPIO_15) { + au_writel(0x8000, PB1000_MDR); /* ack int */ + au_sync(); + } +#endif return; } static void end_irq(unsigned int irq_nr) { - if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { local_enable_irq(irq_nr); + } +#if defined(CONFIG_MIPS_PB1000) + if (irq_nr == AU1000_GPIO_15) { + au_writel(0x4000, PB1000_MDR); /* enable int */ + au_sync(); + } +#endif +} + +unsigned long save_local_and_disable(int controller) +{ + int i; + unsigned long flags, mask; + + spin_lock_irqsave(&irq_lock, flags); + if (controller) { + mask = au_readl(IC1_MASKSET); + for (i=32; i<64; i++) { + local_disable_irq(i); + } + } + else { + mask = au_readl(IC0_MASKSET); + for (i=0; i<32; i++) { + local_disable_irq(i); + } + } + spin_unlock_irqrestore(&irq_lock, flags); + + return mask; +} + +void restore_local_and_enable(int controller, unsigned long mask) +{ + int i; + unsigned long flags, new_mask; + + spin_lock_irqsave(&irq_lock, flags); + for (i=0; i<32; i++) { + if (mask & (1<<i)) { + if (controller) + local_enable_irq(i+32); + else + local_enable_irq(i); + } + } + if (controller) + new_mask = au_readl(IC1_MASKSET); else - printk("warning: end_irq %d did not enable\n", irq_nr); + new_mask = au_readl(IC0_MASKSET); + + spin_unlock_irqrestore(&irq_lock, flags); } @@ -319,7 +352,7 @@ NULL }; - +/* static struct hw_interrupt_type fall_edge_irq_type = { "Au1000 Fall Edge", startup_irq, @@ -330,7 +363,7 @@ end_irq, NULL }; - +*/ static struct hw_interrupt_type level_irq_type = { "Au1000 Level", @@ -343,11 +376,12 @@ NULL }; - -void enable_cpu_timer(void) +#ifdef CONFIG_PM +void startup_match20_interrupt(void) { - enable_cpu_irq_input(1<<MIPS_TIMER_IP); /* timer interrupt */ + local_enable_irq(AU1000_TOY_MATCH2_INT); } +#endif void __init init_IRQ(void) @@ -355,61 +389,158 @@ int i; unsigned long cp0_status; - cp0_status = read_32bit_cp0_register(CP0_STATUS); + cp0_status = read_c0_status(); memset(irq_desc, 0, sizeof(irq_desc)); set_except_vector(0, au1000_IRQ); init_generic_irq(); - - /* - * Setup high priority interrupts on int_request0; low priority on - * int_request1 - */ - for (i = 0; i <= NR_IRQS; i++) { + + for (i = 0; i <= AU1000_MAX_INTR; i++) { switch (i) { + case AU1000_UART0_INT: + case AU1000_UART3_INT: +#ifdef CONFIG_MIPS_PB1000 + case AU1000_UART1_INT: + case AU1000_UART2_INT: + + case AU1000_SSI0_INT: + case AU1000_SSI1_INT: +#endif + +#ifdef CONFIG_MIPS_PB1100 + case AU1000_UART1_INT: + + case AU1000_SSI0_INT: + case AU1000_SSI1_INT: +#endif + case AU1000_DMA_INT_BASE: + case AU1000_DMA_INT_BASE+1: + case AU1000_DMA_INT_BASE+2: + case AU1000_DMA_INT_BASE+3: + case AU1000_DMA_INT_BASE+4: + case AU1000_DMA_INT_BASE+5: + case AU1000_DMA_INT_BASE+6: + case AU1000_DMA_INT_BASE+7: + + case AU1000_IRDA_TX_INT: + case AU1000_IRDA_RX_INT: + case AU1000_MAC0_DMA_INT: +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) case AU1000_MAC1_DMA_INT: +#endif + case AU1500_GPIO_204: setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); irq_desc[i].handler = &level_irq_type; break; + +#ifdef CONFIG_MIPS_PB1000 + case AU1000_GPIO_15: +#endif + case AU1000_USB_HOST_INT: +#if defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) + case AU1000_PCI_INTA: + case AU1000_PCI_INTB: + case AU1000_PCI_INTC: + case AU1000_PCI_INTD: + case AU1500_GPIO_201: + case AU1500_GPIO_202: + case AU1500_GPIO_203: + case AU1500_GPIO_205: + case AU1500_GPIO_207: +#endif + +#ifdef CONFIG_MIPS_PB1100 + case AU1000_GPIO_9: // PCMCIA Card Fully_Interted# + case AU1000_GPIO_10: // PCMCIA_STSCHG# + case AU1000_GPIO_11: // PCMCIA_IRQ# + case AU1000_GPIO_13: // DC_IRQ# + case AU1000_GPIO_23: // 2-wire SCL +#endif +#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) + case AU1000_GPIO_0: // PCMCIA Card 0 Fully_Interted# + case AU1000_GPIO_1: // PCMCIA Card 0 STSCHG# + case AU1000_GPIO_2: // PCMCIA Card 0 IRQ# + + case AU1000_GPIO_3: // PCMCIA Card 1 Fully_Interted# + case AU1000_GPIO_4: // PCMCIA Card 1 STSCHG# + case AU1000_GPIO_5: // PCMCIA Card 1 IRQ# +#endif + setup_local_irq(i, INTC_INT_LOW_LEVEL, 0); + irq_desc[i].handler = &level_irq_type; + break; + case AU1000_ACSYNC_INT: + case AU1000_AC97C_INT: + case AU1000_TOY_INT: + case AU1000_TOY_MATCH0_INT: + case AU1000_TOY_MATCH1_INT: + case AU1000_USB_DEV_SUS_INT: + case AU1000_USB_DEV_REQ_INT: + case AU1000_RTC_INT: + case AU1000_RTC_MATCH0_INT: + case AU1000_RTC_MATCH1_INT: + case AU1000_RTC_MATCH2_INT: + setup_local_irq(i, INTC_INT_RISE_EDGE, 0); + irq_desc[i].handler = &rise_edge_irq_type; + break; + + // Careful if you change match 2 request! + // The interrupt handler is called directly + // from the low level dispatch code. + case AU1000_TOY_MATCH2_INT: + setup_local_irq(i, INTC_INT_RISE_EDGE, 1); + irq_desc[i].handler = &rise_edge_irq_type; + break; default: /* active high, level interrupt */ - setup_local_irq(i, INTC_INT_HIGH_LEVEL, 1); + setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0); irq_desc[i].handler = &level_irq_type; break; } } - set_cp0_status(ALLINTS); -#ifdef CONFIG_REMOTE_DEBUG + set_c0_status(ALLINTS); +#ifdef CONFIG_KGDB /* If local serial I/O used for debug port, enter kgdb at once */ puts("Waiting for kgdb to connect..."); set_debug_traps(); - breakpoint(); + breakpoint(); #endif } -void mips_spurious_interrupt(struct pt_regs *regs) -{ - spurious_interrupts++; -} - +/* + * Interrupts are nested. Even if an interrupt handler is registered + * as "fast", we might get another interrupt before we return from + * intcX_reqX_irqdispatch(). + */ void intc0_req0_irqdispatch(struct pt_regs *regs) { int irq = 0, i; - unsigned long int_request; + static unsigned long intc0_req0 = 0; - int_request = inl(INTC0_REQ0_INT); + intc0_req0 |= au_readl(IC0_REQ0INT); - if (!int_request) return; + if (!intc0_req0) return; + + /* + * Because of the tight timing of SETUP token to reply + * transactions, the USB devices-side packet complete + * interrupt needs the highest priority. + */ + if ((intc0_req0 & (1<<AU1000_USB_DEV_REQ_INT))) { + intc0_req0 &= ~(1<<AU1000_USB_DEV_REQ_INT); + do_IRQ(AU1000_USB_DEV_REQ_INT, regs); + return; + } for (i=0; i<32; i++) { - if ((int_request & 0x1)) { + if ((intc0_req0 & (1<<i))) { + intc0_req0 &= ~(1<<i); do_IRQ(irq, regs); + break; } irq++; - int_request >>= 1; } } @@ -417,55 +548,84 @@ void intc0_req1_irqdispatch(struct pt_regs *regs) { int irq = 0, i; - unsigned long int_request; + static unsigned long intc0_req1 = 0; - int_request = inl(INTC0_REQ1_INT); + intc0_req1 = au_readl(IC0_REQ1INT); - if (!int_request) return; + if (!intc0_req1) return; for (i=0; i<32; i++) { - if ((int_request & 0x1)) { - do_IRQ(irq, regs); + if ((intc0_req1 & (1<<i))) { + intc0_req1 &= ~(1<<i); +#ifdef CONFIG_PM + if (i == AU1000_TOY_MATCH2_INT) { + mask_and_ack_rise_edge_irq(irq); + counter0_irq(irq, NULL, regs); + local_enable_irq(irq); + } + else +#endif + { + do_IRQ(irq, regs); + } + break; } irq++; - int_request >>= 1; } } +/* + * Interrupt Controller 1: + * interrupts 32 - 63 + */ void intc1_req0_irqdispatch(struct pt_regs *regs) { int irq = 0, i; - unsigned long int_request; + static unsigned long intc1_req0 = 0; - int_request = inl(INTC1_REQ0_INT); + intc1_req0 |= au_readl(IC1_REQ0INT); - if (!int_request) return; + if (!intc1_req0) return; +#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ) + au_writel(1, CPLD_AUX0); /* debug led 0 */ +#endif for (i=0; i<32; i++) { - if ((int_request & 0x1)) { - do_IRQ(irq, regs); + if ((intc1_req0 & (1<<i))) { + intc1_req0 &= ~(1<<i); +#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ) + au_writel(2, CPLD_AUX0); /* turn on debug led 1 */ + do_IRQ(irq+32, regs); + au_writel(0, CPLD_AUX0); /* turn off debug led 1 */ +#else + do_IRQ(irq+32, regs); +#endif + break; } irq++; - int_request >>= 1; } +#if defined(CONFIG_MIPS_PB1000) && defined(DEBUG_IRQ) + au_writel(0, CPLD_AUX0); +#endif } void intc1_req1_irqdispatch(struct pt_regs *regs) { int irq = 0, i; - unsigned long int_request; + static unsigned long intc1_req1 = 0; - int_request = inl(INTC1_REQ1_INT); + intc1_req1 |= au_readl(IC1_REQ1INT); - if (!int_request) return; + if (!intc1_req1) return; for (i=0; i<32; i++) { - if ((int_request & 0x1)) { - do_IRQ(irq, regs); + if ((intc1_req1 & (1<<i))) { + intc1_req1 &= ~(1<<i); + do_IRQ(irq+32, regs); + break; } irq++; - int_request >>= 1; } } diff -Nru a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/common/power.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,332 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1000 Power Management routines. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Some of the routines are right out of init/main.c, whose + * copyrights apply here. + * + * 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 <linux/config.h> +#include <linux/init.h> +#include <linux/pm.h> +#include <linux/slab.h> +#include <linux/sysctl.h> + +#include <asm/string.h> +#include <asm/uaccess.h> +#include <asm/io.h> +#include <asm/system.h> +#include <asm/au1000.h> + +#define DEBUG 1 +#ifdef DEBUG +# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) +#else +# define DPRINTK(fmt, args...) +#endif + +extern void au1k_wait(void); +static void calibrate_delay(void); + +extern void set_au1000_speed(unsigned int new_freq); +extern unsigned int get_au1000_speed(void); +extern unsigned long get_au1000_uart_baud_base(void); +extern void set_au1000_uart_baud_base(unsigned long new_baud_base); +extern unsigned long save_local_and_disable(int controller); +extern void restore_local_and_enable(int controller, unsigned long mask); +extern void local_enable_irq(unsigned int irq_nr); + +/* Quick acpi hack. This will have to change! */ +#define CTL_ACPI 9999 +#define ACPI_S1_SLP_TYP 19 +#define ACPI_SLEEP 21 + +#ifdef CONFIG_PM + +static spinlock_t pm_lock = SPIN_LOCK_UNLOCKED; + +unsigned long suspend_mode; + +void wakeup_from_suspend(void) +{ + suspend_mode = 0; +} + +int au_sleep(void) +{ + unsigned long wakeup, flags; + spin_lock_irqsave(&pm_lock,flags); + + flush_cache_all(); + /* pin 6 is gpio */ + au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD); + + /* gpio 6 can cause a wake up event */ + wakeup = au_readl(SYS_WAKEMSK); + wakeup &= ~(1 << 8); /* turn off match20 wakeup */ + wakeup |= 1 << 6; /* turn on gpio 6 wakeup */ + au_writel(wakeup, SYS_WAKEMSK); + + au_writel(1, SYS_WAKESRC); /* clear cause */ + au_writel(1, SYS_SLPPWR); /* prepare to sleep */ + + __asm__("la $4, 1f\n\t" + "lui $5, 0xb190\n\t" + "ori $5, 0x18\n\t" + "sw $4, 0($5)\n\t" + "li $4, 1\n\t" + "lui $5, 0xb190\n\t" + "ori $5, 0x7c\n\t" + "sw $4, 0($5)\n\t" "sync\n\t" "1:\t\n\t" "nop\n\t"); + + /* after a wakeup, the cpu vectors back to 0x1fc00000 so + * it's up to the boot code to get us back here. + */ + spin_unlock_irqrestore(&pm_lock, flags); + return 0; +} + +static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, + void *buffer, size_t * len) +{ + int retval = 0; + + if (!write) { + *len = 0; + } else { + retval = pm_send_all(PM_SUSPEND, (void *) 2); + if (retval) + return retval; + + au_sleep(); + retval = pm_send_all(PM_RESUME, (void *) 0); + } + return retval; +} + +static int pm_do_suspend(ctl_table * ctl, int write, struct file *file, + void *buffer, size_t * len) +{ + int retval = 0; + + if (!write) { + *len = 0; + } else { + retval = pm_send_all(PM_SUSPEND, (void *) 2); + if (retval) + return retval; + suspend_mode = 1; + au1k_wait(); + retval = pm_send_all(PM_RESUME, (void *) 0); + } + return retval; +} + + +static int pm_do_freq(ctl_table * ctl, int write, struct file *file, + void *buffer, size_t * len) +{ + int retval = 0, i; + unsigned long val, pll; +#define TMPBUFLEN 64 +#define MAX_CPU_FREQ 396 + char buf[8], *p; + unsigned long flags, intc0_mask, intc1_mask; + unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk, + old_refresh; + unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh; + + spin_lock_irqsave(&pm_lock, flags); + if (!write) { + *len = 0; + } else { + /* Parse the new frequency */ + if (*len > TMPBUFLEN - 1) { + spin_unlock_irqrestore(&pm_lock, flags); + return -EFAULT; + } + if (copy_from_user(buf, buffer, *len)) { + spin_unlock_irqrestore(&pm_lock, flags); + return -EFAULT; + } + buf[*len] = 0; + p = buf; + val = simple_strtoul(p, &p, 0); + if (val > MAX_CPU_FREQ) { + spin_unlock_irqrestore(&pm_lock, flags); + return -EFAULT; + } + + pll = val / 12; + if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */ + /* revisit this for higher speed cpus */ + spin_unlock_irqrestore(&pm_lock, flags); + return -EFAULT; + } + + old_baud_base = get_au1000_uart_baud_base(); + old_cpu_freq = get_au1000_speed(); + + new_cpu_freq = pll * 12 * 1000000; + new_baud_base = (new_cpu_freq / 4) / 16; + set_au1000_speed(new_cpu_freq); + set_au1000_uart_baud_base(new_baud_base); + + old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff; + new_refresh = + ((old_refresh * new_cpu_freq) / + old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff); + + au_writel(pll, SYS_CPUPLL); + au_sync_delay(1); + au_writel(new_refresh, MEM_SDREFCFG); + au_sync_delay(1); + + for (i = 0; i < 4; i++) { + if (au_readl + (UART_BASE + UART_MOD_CNTRL + + i * 0x00100000) == 3) { + old_clk = + au_readl(UART_BASE + UART_CLK + + i * 0x00100000); + // baud_rate = baud_base/clk + baud_rate = old_baud_base / old_clk; + /* we won't get an exact baud rate and the error + * could be significant enough that our new + * calculation will result in a clock that will + * give us a baud rate that's too far off from + * what we really want. + */ + if (baud_rate > 100000) + baud_rate = 115200; + else if (baud_rate > 50000) + baud_rate = 57600; + else if (baud_rate > 30000) + baud_rate = 38400; + else if (baud_rate > 17000) + baud_rate = 19200; + else + (baud_rate = 9600); + // new_clk = new_baud_base/baud_rate + new_clk = new_baud_base / baud_rate; + au_writel(new_clk, + UART_BASE + UART_CLK + + i * 0x00100000); + au_sync_delay(10); + } + } + } + + + /* We don't want _any_ interrupts other than + * match20. Otherwise our calibrate_delay() + * calculation will be off, potentially a lot. + */ + intc0_mask = save_local_and_disable(0); + intc1_mask = save_local_and_disable(1); + local_enable_irq(AU1000_TOY_MATCH2_INT); + spin_unlock_irqrestore(&pm_lock, flags); + calibrate_delay(); + restore_local_and_enable(0, intc0_mask); + restore_local_and_enable(1, intc1_mask); + return retval; +} + + +static struct ctl_table pm_table[] = { + {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend}, + {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep}, + {CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq}, + {0} +}; + +static struct ctl_table pm_dir_table[] = { + {CTL_ACPI, "pm", NULL, 0, 0555, pm_table}, + {0} +}; + +/* + * Initialize power interface + */ +static int __init pm_init(void) +{ + register_sysctl_table(pm_dir_table, 1); + return 0; +} + +__initcall(pm_init); + + +/* + * This is right out of init/main.c + */ + +/* This is the number of bits of precision for the loops_per_jiffy. Each + bit takes on average 1.5/HZ seconds. This (like the original) is a little + better than 1% */ +#define LPS_PREC 8 + +static void calibrate_delay(void) +{ + unsigned long ticks, loopbit; + int lps_precision = LPS_PREC; + + loops_per_jiffy = (1 << 12); + + while (loops_per_jiffy <<= 1) { + /* wait for "start of" clock tick */ + ticks = jiffies; + while (ticks == jiffies) + /* nothing */ ; + /* Go .. */ + ticks = jiffies; + __delay(loops_per_jiffy); + ticks = jiffies - ticks; + if (ticks) + break; + } + +/* Do a binary approximation to get loops_per_jiffy set to equal one clock + (up to lps_precision bits) */ + loops_per_jiffy >>= 1; + loopbit = loops_per_jiffy; + while (lps_precision-- && (loopbit >>= 1)) { + loops_per_jiffy |= loopbit; + ticks = jiffies; + while (ticks == jiffies); + ticks = jiffies; + __delay(loops_per_jiffy); + if (jiffies != ticks) /* longer than 1 tick */ + loops_per_jiffy &= ~loopbit; + } +} + +void au1k_wait(void) +{ + __asm__("nop\n\t" "nop\n\t"); +} + +#endif /* CONFIG_PM */ diff -Nru a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c --- a/arch/mips/au1000/common/prom.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/au1000/common/prom.c Fri Jun 27 14:19:59 2003 @@ -4,11 +4,11 @@ * PROM library initialisation code, assuming a version of * pmon is the boot code. * - * Copyright 2000 MontaVista Software Inc. + * Copyright 2000,2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * This file was derived from Carsten Langgaard's + * This file was derived from Carsten Langgaard's * arch/mips/mips-boards/xx files. * * Carsten Langgaard, carstenl@mips.com @@ -35,7 +35,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> @@ -44,22 +44,23 @@ /* #define DEBUG_CMDLINE */ -char arcs_cmdline[COMMAND_LINE_SIZE]; -int prom_argc; -char **prom_argv, **prom_envp; +char arcs_cmdline[CL_SIZE]; +extern int prom_argc; +extern char **prom_argv, **prom_envp; -typedef struct { - char *name; -/* char *val; */ -} t_env_var; +typedef struct +{ + char *name; +/* char *val; */ +}t_env_var; -char * __init prom_getcmdline(void) +char * prom_getcmdline(void) { return &(arcs_cmdline[0]); } -void __init prom_init_cmdline(void) +void prom_init_cmdline(void) { char *cp; int actr; @@ -101,20 +102,57 @@ return(NULL); } -static inline unsigned char str2hexnum(unsigned char c) +inline unsigned char str2hexnum(unsigned char c) { if(c >= '0' && c <= '9') - return c - '0'; + return c - '0'; if(c >= 'a' && c <= 'f') - return c - 'a' + 10; + return c - 'a' + 10; + if(c >= 'A' && c <= 'F') + return c - 'A' + 10; return 0; /* foo */ } -int __init page_is_ram(unsigned long pagenr) +inline void str2eaddr(unsigned char *ea, unsigned char *str) { - return 1; + int i; + + for(i = 0; i < 6; i++) { + unsigned char num; + + if((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } } -void prom_free_prom_memory (void) +int get_ethernet_addr(char *ethernet_addr) { + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + +#if 0 + { + int i; + + printk("get_ethernet_addr: "); + for (i=0; i<5; i++) + printk("%02x:", (unsigned char)*(ethernet_addr+i)); + printk("%02x\n", *(ethernet_addr+i)); + } +#endif + + return 0; } + +void prom_free_prom_memory (void) {} +EXPORT_SYMBOL(prom_getcmdline); +EXPORT_SYMBOL(get_ethernet_addr); diff -Nru a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c --- a/arch/mips/au1000/common/puts.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/au1000/common/puts.c Fri Jun 27 14:20:00 2003 @@ -29,8 +29,9 @@ */ #include <linux/types.h> +#include <asm/au1000.h> -#define SERIAL_BASE 0xB1100000 /* au1000, uart 0 */ +#define SERIAL_BASE UART_BASE #define SER_CMD 0x7 #define SER_DATA 0x1 #define TX_BUSY 0x20 diff -Nru a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c --- a/arch/mips/au1000/common/reset.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/au1000/common/reset.c Fri Jun 27 14:19:53 2003 @@ -27,7 +27,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> #include <asm/io.h> @@ -35,23 +35,107 @@ #include <asm/processor.h> #include <asm/reboot.h> #include <asm/system.h> +#include <asm/au1000.h> + +extern int au_sleep(void); void au1000_restart(char *command) { - set_cp0_status(ST0_BEV | ST0_ERL); - set_cp0_config(CONF_CM_UNCACHED); + /* Set all integrated peripherals to disabled states */ + u32 prid = read_c0_prid(); + + printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n"); + switch (prid & 0xFF000000) + { + case 0x00000000: /* Au1000 */ + au_writel(0x02, 0xb0000010); /* ac97_enable */ + au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ + asm("sync"); + au_writel(0x00, 0xb017fffc); /* usbh_enable */ + au_writel(0x00, 0xb0200058); /* usbd_enable */ + au_writel(0x00, 0xb0300040); /* ir_enable */ + au_writel(0x00, 0xb0520000); /* macen0 */ + au_writel(0x00, 0xb0520004); /* macen1 */ + au_writel(0x00, 0xb1000008); /* i2s_enable */ + au_writel(0x00, 0xb1100100); /* uart0_enable */ + au_writel(0x00, 0xb1200100); /* uart1_enable */ + au_writel(0x00, 0xb1300100); /* uart2_enable */ + au_writel(0x00, 0xb1400100); /* uart3_enable */ + au_writel(0x02, 0xb1600100); /* ssi0_enable */ + au_writel(0x02, 0xb1680100); /* ssi1_enable */ + au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ + au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ + au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x00, 0xb1900100); /* sys_pininputen */ + break; + case 0x01000000: /* Au1500 */ + au_writel(0x02, 0xb0000010); /* ac97_enable */ + au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ + asm("sync"); + au_writel(0x00, 0xb017fffc); /* usbh_enable */ + au_writel(0x00, 0xb0200058); /* usbd_enable */ + au_writel(0x00, 0xb1520000); /* macen0 */ + au_writel(0x00, 0xb1520004); /* macen1 */ + au_writel(0x00, 0xb1100100); /* uart0_enable */ + au_writel(0x00, 0xb1400100); /* uart3_enable */ + au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ + au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ + au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x00, 0xb1900100); /* sys_pininputen */ + break; + case 0x02000000: /* Au1100 */ + au_writel(0x02, 0xb0000010); /* ac97_enable */ + au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ + asm("sync"); + au_writel(0x00, 0xb017fffc); /* usbh_enable */ + au_writel(0x00, 0xb0200058); /* usbd_enable */ + au_writel(0x00, 0xb0300040); /* ir_enable */ + au_writel(0x00, 0xb0520000); /* macen0 */ + au_writel(0x00, 0xb1000008); /* i2s_enable */ + au_writel(0x00, 0xb1100100); /* uart0_enable */ + au_writel(0x00, 0xb1200100); /* uart1_enable */ + au_writel(0x00, 0xb1400100); /* uart3_enable */ + au_writel(0x02, 0xb1600100); /* ssi0_enable */ + au_writel(0x02, 0xb1680100); /* ssi1_enable */ + au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ + au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ + au_writel(0x00, 0xb1900028); /* sys_clksrc */ + au_writel(0x00, 0xb1900100); /* sys_pininputen */ + break; + + default: + break; + } + + set_c0_status(ST0_BEV | ST0_ERL); + set_c0_config(CONF_CM_UNCACHED); flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); + write_c0_wired(0); + +#if defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) + /* Do a HW reset if the board can do it */ + + au_writel(0x00000000, 0xAE00001C); +#endif + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); } void au1000_halt(void) { printk(KERN_NOTICE "\n** You can safely turn off the power\n"); +#ifdef CONFIG_PM + au_sleep(); + + /* should not get here */ + printk(KERN_ERR "Unable to put cpu in sleep mode\n"); + while(1); +#else while (1) __asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0"); +#endif } void au1000_power_off(void) diff -Nru a/arch/mips/au1000/common/rtc.c b/arch/mips/au1000/common/rtc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/common/rtc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,37 @@ +/* + * 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. + * + * RTC routines for PC style attached Dallas chip. + * + * Copyright (C) 1998, 2001 by Ralf Baechle + */ +#include <linux/mc146818rtc.h> +#include <asm/io.h> +#include <asm/au1000.h> + +#define PB1500_RTC_ADDR 0xAC000000 + +unsigned char std_rtc_read_data(unsigned long offset) +{ + offset <<= 2; + return (u8)(au_readl(offset + PB1500_RTC_ADDR) & 0xff); +} + +static void std_rtc_write_data(unsigned char data, unsigned long offset) +{ + offset <<= 2; + au_writel(data, offset + PB1500_RTC_ADDR); +} + +static int std_rtc_bcd_mode(void) +{ + return 1; +} + +struct rtc_ops pb1500_rtc_ops = { + &std_rtc_read_data, + &std_rtc_write_data, + &std_rtc_bcd_mode +}; diff -Nru a/arch/mips/au1000/common/serial.c b/arch/mips/au1000/common/serial.c --- a/arch/mips/au1000/common/serial.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2980 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * Au1000 serial port driver. - * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com - * - * Derived almost entirely from drivers/char/serial.c: - * - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, - * 1998, 1999 Theodore Ts'o - * - * 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. - */ - -static char *serial_version = "1.01"; -static char *serial_revdate = "2001-02-08"; - - -#include <linux/config.h> -#include <linux/version.h> - -#undef SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT -#undef SERIAL_DEBUG_PCI -#undef SERIAL_DEBUG_AUTOCONF - -#ifdef MODULE -#undef CONFIG_AU1000_SERIAL_CONSOLE -#endif - -#define CONFIG_SERIAL_RSA - -#define RS_STROBE_TIME (10*HZ) -#define RS_ISR_PASS_LIMIT 256 - -/* - * End of serial driver configuration section. - */ - -#include <linux/module.h> - -#include <linux/types.h> -#ifdef LOCAL_HEADERS -#include "serial_local.h" -#else -#include <linux/serial.h> -#include <linux/serialP.h> -#include <asm/au1000.h> -#include <asm/serial.h> -#define LOCAL_VERSTRING "" -#endif - -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/major.h> -#include <linux/string.h> -#include <linux/fcntl.h> -#include <linux/ptrace.h> -#include <linux/ioport.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <asm/uaccess.h> -#include <linux/delay.h> -#ifdef CONFIG_AU1000_SERIAL_CONSOLE -#include <linux/console.h> -#endif -#ifdef CONFIG_MAGIC_SYSRQ -#include <linux/sysrq.h> -#endif - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/bitops.h> - -#ifdef CONFIG_MAC_SERIAL -#define SERIAL_DEV_OFFSET 2 -#else -#define SERIAL_DEV_OFFSET 0 -#endif - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#else -#define _INLINE_ -#endif - -static char *serial_name = "Serial driver"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver *serial_driver; - -static struct timer_list serial_timer; - -extern unsigned long get_au1000_uart_baud(void); - -/* serial subtype definitions */ -#ifndef SERIAL_TYPE_NORMAL -#define SERIAL_TYPE_NORMAL 1 -#endif - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * IRQ_timeout - How long the timeout should be for each IRQ - * should be after the IRQ has been active. - */ - -static struct async_struct *IRQ_ports[NR_IRQS]; -static int IRQ_timeout[NR_IRQS]; -#ifdef CONFIG_AU1000_SERIAL_CONSOLE -static struct console sercons; -static int lsr_break_flag; -#endif -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -static unsigned long break_pressed; /* break, really ... */ -#endif - -static void autoconfig(struct serial_state * state); -static void change_speed(struct async_struct *info, struct termios *old); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); - -/* - * Here we define the default xmit fifo size used for each type of - * UART - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, - { "8250", 1, 0 }, - { "16450", 1, 0 }, - { "16550", 1, 0 }, - { 0, 0} -}; - - -static struct serial_state rs_table[RS_TABLE_SIZE] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -#ifndef PREPARE_FUNC -#define PREPARE_FUNC(dev) (dev->prepare) -#define ACTIVATE_FUNC(dev) (dev->activate) -#define DEACTIVATE_FUNC(dev) (dev->deactivate) -#endif - -#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) printk("(%s): [%x], refc=%d, serc=%d, ttyc=%d -> %s\n", \ - tty->name, (info->flags), serial_driver->refcount, info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -#ifdef DECLARE_MUTEX -static DECLARE_MUTEX(tmp_buf_sem); -#else -static struct semaphore tmp_buf_sem = MUTEX; -#endif - - -static inline int serial_paranoia_check(struct async_struct *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - - -static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset) -{ - return (inl(info->port+offset) & 0xff); -} - -static _INLINE_ void serial_out(struct async_struct *info, int offset, int value) -{ - outl(value & 0xff, info->port+offset); -} - - -/* - * We used to support using pause I/O for certain machines. We - * haven't supported this for a while, but just in case it's badly - * needed for certain old 386 machines, I've left these #define's - * in.... - */ -#define serial_inp(info, offset) serial_in(info, offset) -#define serial_outp(info, offset, value) serial_out(info, offset, value) - - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->IER & UART_IER_THRI) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit.head != info->xmit.tail - && info->xmit.buf - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(struct async_struct *info, - int *status, struct pt_regs * regs) -{ - struct tty_struct *tty = info->tty; - unsigned char ch; - int ignored = 0; - struct async_icount *icount; - - icount = &info->state->icount; - do { - ch = serial_inp(info, UART_RX); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - printk("DR%02x:%02x...", ch, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (*status & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE)) { - /* - * For statistics only - */ - if (*status & UART_LSR_BI) { - *status &= ~(UART_LSR_FE | UART_LSR_PE); - icount->brk++; - /* - * We do the SysRQ and SAK checking - * here because otherwise the break - * may get masked by ignore_status_mask - * or read_status_mask. - */ -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (info->line == sercons.index) { - if (!break_pressed) { - break_pressed = jiffies; - goto ignore_char; - } - break_pressed = 0; - } -#endif - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & UART_LSR_PE) - icount->parity++; - else if (*status & UART_LSR_FE) - icount->frame++; - if (*status & UART_LSR_OE) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (*status & info->ignore_status_mask) { - if (++ignored > 100) - break; - goto ignore_char; - } - *status &= info->read_status_mask; - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if (info->line == sercons.index) { - /* Recover the break flag from console xmit */ - *status |= lsr_break_flag; - lsr_break_flag = 0; - } -#endif - if (*status & (UART_LSR_BI)) { -#ifdef SERIAL_DEBUG_INTR - printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - } else if (*status & UART_LSR_PE) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & UART_LSR_FE) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (*status & UART_LSR_OE) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - } - } -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) - if (break_pressed && info->line == sercons.index) { - if (ch != 0 && - time_before(jiffies, break_pressed + HZ*5)) { - handle_sysrq(ch, regs, NULL); - break_pressed = 0; - goto ignore_char; - } - break_pressed = 0; - } -#endif - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - *status = serial_inp(info, UART_LSR); - } while (*status & UART_LSR_DR); - tty_flip_buffer_push(tty); -} - -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) -{ - int count; - - if (info->x_char) { - serial_outp(info, UART_TX, info->x_char); - info->state->icount.tx++; - info->x_char = 0; - if (intr_done) - *intr_done = 0; - return; - } - if (info->xmit.head == info->xmit.tail - || info->tty->stopped - || info->tty->hw_stopped) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - return; - } - - count = info->xmit_fifo_size; - do { - serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]); - info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - if (info->xmit.head == info->xmit.tail) - break; - } while (--count > 0); - - if (CIRC_CNT(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - - if (info->xmit.head == info->xmit.tail) { - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } -} - -static _INLINE_ void check_modem_status(struct async_struct *info) -{ - int status; - struct async_icount *icount; - - status = serial_in(info, UART_MSR); - - if (status & UART_MSR_ANY_DELTA) { - icount = &info->state->icount; - /* update input line counters */ - if (status & UART_MSR_TERI) - icount->rng++; - if (status & UART_MSR_DDSR) - icount->dsr++; - if (status & UART_MSR_DDCD) { - icount->dcd++; -#ifdef CONFIG_HARD_PPS - if ((info->flags & ASYNC_HARDPPS_CD) && - (status & UART_MSR_DCD)) - hardpps(); -#endif - } - if (status & UART_MSR_DCTS) - icount->cts++; - wake_up_interruptible(&info->delta_msr_wait); - } - - if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { -#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) - printk("ttys%d CD now %s...", info->line, - (status & UART_MSR_DCD) ? "on" : "off"); -#endif - if (status & UART_MSR_DCD) - wake_up_interruptible(&info->open_wait); - else { -#ifdef SERIAL_DEBUG_OPEN - printk("doing serial hangup..."); -#endif - if (info->tty) - tty_hangup(info->tty); - } - } - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty->hw_stopped) { - if (status & UART_MSR_CTS) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx start..."); -#endif - info->tty->hw_stopped = 0; - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - return; - } - } else { - if (!(status & UART_MSR_CTS)) { -#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) - printk("CTS tx stop..."); -#endif - info->tty->hw_stopped = 1; - info->IER &= ~UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - } - } -} - - - -/* - * This is the serial driver's interrupt routine for a single port - */ -static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs) -{ - int status; - int pass_counter = 0; - struct async_struct * info; - -#ifdef SERIAL_DEBUG_INTR - printk("rs_interrupt_single(%d)...", irq); -#endif - - info = IRQ_ports[irq]; - if (!info || !info->tty) - return; - - do { - status = serial_inp(info, UART_LSR); -#ifdef SERIAL_DEBUG_INTR - printk("status = %x...", status); -#endif - if (status & UART_LSR_DR) - receive_chars(info, &status, regs); - check_modem_status(info); - if (status & UART_LSR_THRE) - transmit_chars(info, 0); - if (pass_counter++ > RS_ISR_PASS_LIMIT) { -#if 0 - printk("rs_single loop break.\n"); -#endif - break; - } - } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT)); - info->last_active = jiffies; -#ifdef SERIAL_DEBUG_INTR - printk("end.\n"); -#endif -} - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); -#ifdef SERIAL_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - } -} - -/* - * This subroutine is called when the RS_TIMER goes off. It is used - * by the serial driver to handle ports that do not have an interrupt - * (irq=0). This doesn't work very well for 16450's, but gives barely - * passable results for a 16550A. (Although at the expense of much - * CPU overhead). - */ -static void rs_timer(unsigned long dummy) -{ - static unsigned long last_strobe; - struct async_struct *info; - unsigned int i; - unsigned long flags; - - if ((jiffies - last_strobe) >= RS_STROBE_TIME) { - for (i=0; i < NR_IRQS; i++) { - info = IRQ_ports[i]; - if (!info) - continue; - save_flags(flags); cli(); - rs_interrupt_single(i, NULL, NULL); - restore_flags(flags); - } - } - last_strobe = jiffies; - mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); - -#if 0 - if (IRQ_ports[0]) { - save_flags(flags); cli(); - rs_interrupt_single(0, NULL, NULL); - restore_flags(flags); - - mod_timer(&serial_timer, jiffies + IRQ_timeout[0]); - } -#endif -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -/* - * This routine figures out the correct timeout for a particular IRQ. - * It uses the smallest timeout of all of the serial ports in a - * particular interrupt chain. Now only used for IRQ 0.... - */ -static void figure_IRQ_timeout(int irq) -{ - struct async_struct *info; - int timeout = 60*HZ; /* 60 seconds === a long time :-) */ - - info = IRQ_ports[irq]; - if (!info) { - IRQ_timeout[irq] = 60*HZ; - return; - } - while (info) { - if (info->timeout < timeout) - timeout = info->timeout; - info = info->next_port; - } - if (!irq) - timeout = timeout / 2; - IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1; -} - - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - void (*handler)(int, void *, struct pt_regs *); - struct serial_state *state= info->state; - unsigned long page; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - - if (!CONFIGURED_SERIAL_PORT(state) || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit.buf) - free_page(page); - else - info->xmit.buf = (unsigned char *) page; - - - if (inl(UART_MOD_CNTRL + state->port) != 0x3) { - outl(3, UART_MOD_CNTRL + state->port); - } -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - - /* - * Clear the FIFO buffers and disable them - * (they will be reenabled in change_speed()) - */ - if (uart_config[state->type].flags & UART_CLEAR_FIFO) { - serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO); - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - } - - /* - * Clear the interrupt registers. - */ - (void) serial_inp(info, UART_LSR); - (void) serial_inp(info, UART_RX); - (void) serial_inp(info, UART_IIR); - (void) serial_inp(info, UART_MSR); - - /* - * At this point there's no way the LSR could still be 0xFF; - * if it is, then bail out, because there's likely no UART - * here. - */ - if (!(info->flags & ASYNC_BUGGY_UART) && - (serial_inp(info, UART_LSR) == 0xff)) { - printk("LSR safety check engaged!\n"); - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - } else - retval = -ENODEV; - goto errout; - } - - /* - * Allocate the IRQ if necessary - */ -#if 0 - /* au1000, uart0 irq is 0 */ - if (state->irq && (!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { -#endif - if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - retval = -EBUSY; - goto errout; - } else - handler = rs_interrupt_single; - - retval = request_irq(state->irq, handler, SA_SHIRQ, - "serial", &IRQ_ports[state->irq]); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } - - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); - - /* - * Now, initialize the UART - */ - serial_outp(info, UART_LCR, UART_LCR_WLEN8); - - info->MCR = 0; - if (info->tty->termios->c_cflag & CBAUD) - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - { - if (state->irq != 0) - info->MCR |= UART_MCR_OUT2; - } - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - serial_outp(info, UART_MCR, info->MCR); - - /* - * Finally, enable interrupts - */ - info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; - serial_outp(info, UART_IER, info->IER); /* enable interrupts */ - - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(info, UART_LSR); - (void)serial_inp(info, UART_RX); - (void)serial_inp(info, UART_IIR); - (void)serial_inp(info, UART_MSR); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit.head = info->xmit.tail = 0; - - /* - * Set up serial timers... - */ - mod_timer(&serial_timer, jiffies + 2*HZ/100); - - /* - * Set up the tty->alt_speed kludge - */ - if (info->tty) { - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - } - - /* - * and set the speed of the serial port - */ - change_speed(info, 0); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->delta_msr_wait); - - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - figure_IRQ_timeout(state->irq); - - /* - * Free the IRQ, if necessary - */ -// if (state->irq && (!IRQ_ports[state->irq] || - if ((!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, &IRQ_ports[state->irq]); - retval = request_irq(state->irq, rs_interrupt_single, - SA_SHIRQ, "serial", - &IRQ_ports[state->irq]); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, &IRQ_ports[state->irq]); - } - - if (info->xmit.buf) { - unsigned long pg = (unsigned long) info->xmit.buf; - info->xmit.buf = 0; - free_page(pg); - } - - info->IER = 0; - serial_outp(info, UART_IER, 0x00); /* disable all intrs */ - info->MCR &= ~UART_MCR_OUT2; - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - - /* disable break condition */ - serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC); - - if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - serial_outp(info, UART_MCR, info->MCR); - - /* disable FIFO's */ - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - - (void)serial_in(info, UART_RX); /* read data port to reset things */ - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); -} - - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info, - struct termios *old_termios) -{ - int quot = 0, baud_base, baud; - unsigned cflag, cval, fcr = 0; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!CONFIGURED_SERIAL_PORT(info)) - return; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: cval = 0x00; bits = 7; break; - case CS6: cval = 0x01; bits = 8; break; - case CS7: cval = 0x02; bits = 9; break; - case CS8: cval = 0x03; bits = 10; break; - /* Never happens, but GCC is too dumb to figure it out */ - default: cval = 0x00; bits = 7; break; - } - if (cflag & CSTOPB) { - cval |= 0x04; - bits++; - } - if (cflag & PARENB) { - cval |= UART_LCR_PARITY; - bits++; - } - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; -#ifdef CMSPAR - if (cflag & CMSPAR) - cval |= UART_LCR_SPAR; -#endif - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) { - baud = 9600; /* B0 transition handled in rs_set_termios */ - } - baud_base = info->state->baud_base; - //if (baud == 38400 && - if (((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { - quot = info->state->custom_divisor; - } - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is zero refuse the change */ - if (!quot && old_termios) { - info->tty->termios->c_cflag &= ~CBAUD; - info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - } - /* As a last resort, if the quotient is zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - /* Set up FIFO's */ - if (uart_config[info->state->type].flags & UART_USE_FIFO) { - if ((info->state->baud_base / quot) < 2400) - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_1; - else - fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIGGER_8; - } - - /* CTS flow control flag and modem status interrupts */ - info->IER &= ~UART_IER_MSI; - if (info->flags & ASYNC_HARDPPS_CD) - info->IER |= UART_IER_MSI; - if (cflag & CRTSCTS) { - info->flags |= ASYNC_CTS_FLOW; - info->IER |= UART_IER_MSI; - } else - info->flags &= ~ASYNC_CTS_FLOW; - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else { - info->flags |= ASYNC_CHECK_CD; - info->IER |= UART_IER_MSI; - } - serial_out(info, UART_IER, info->IER); - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; - if (I_INPCK(info->tty)) - info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= UART_LSR_BI; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= UART_LSR_BI; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= UART_LSR_OE; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= UART_LSR_DR; - save_flags(flags); cli(); - - serial_outp(info, UART_CLK, quot & 0xffff); - serial_outp(info, UART_LCR, cval); - info->LCR = cval; /* Save LCR */ - restore_flags(flags); -} - -static void rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return; - - if (!tty || !info->xmit.buf) - return; - - save_flags(flags); cli(); - if (CIRC_SPACE(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE) == 0) { - restore_flags(flags); - return; - } - - info->xmit.buf[info->xmit.head] = ch; - info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1); - restore_flags(flags); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) - return; - - if (info->xmit.head == info->xmit.tail - || tty->stopped - || tty->hw_stopped - || !info->xmit.buf) - return; - - save_flags(flags); cli(); - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - restore_flags(flags); -} - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!tty || !info->xmit.buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - int c1; - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c1 = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (c1 < c) - c = c1; - memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - cli(); - while (1) { - c = CIRC_SPACE_TO_END(info->xmit.head, - info->xmit.tail, - SERIAL_XMIT_SIZE); - if (count < c) - c = count; - if (c <= 0) { - break; - } - memcpy(info->xmit.buf + info->xmit.head, buf, c); - info->xmit.head = ((info->xmit.head + c) & - (SERIAL_XMIT_SIZE-1)); - buf += c; - count -= c; - ret += c; - } - restore_flags(flags); - } - if (info->xmit.head != info->xmit.tail - && !tty->stopped - && !tty->hw_stopped - && !(info->IER & UART_IER_THRI)) { - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - save_flags(flags); cli(); - info->xmit.head = info->xmit.tail = 0; - restore_flags(flags); - wake_up_interruptible(&tty->write_wait); -#ifdef SERIAL_HAVE_POLL_WAIT - wake_up_interruptible(&tty->poll_wait); -#endif - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - info->IER |= UART_IER_THRI; - serial_out(info, UART_IER, info->IER); - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); - - if (tty->termios->c_cflag & CRTSCTS) - info->MCR &= ~UART_MCR_RTS; - - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } - if (tty->termios->c_cflag & CRTSCTS) - info->MCR |= UART_MCR_RTS; - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - if (HIGH_BITS_OFFSET) - tmp.port_high = state->port >> HIGH_BITS_OFFSET; - else - tmp.port_high = 0; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tmp.hub6 = state->hub6; - tmp.io_type = state->io_type; - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int i,change_irq,change_port; - int retval = 0; - unsigned long new_port; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - state = info->state; - old_state = *state; - - new_port = new_serial.port; - if (HIGH_BITS_OFFSET) - new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; - - change_irq = new_serial.irq != state->irq; - change_port = (new_port != ((int) state->port)) || - (new_serial.hub6 != state->hub6); - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != state->baud_base) || - (new_serial.type != state->type) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((info->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - new_serial.irq = irq_canonicalize(new_serial.irq); - - if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || - (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) || - (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || - (new_serial.type == PORT_STARTECH)) { - return -EINVAL; - } - - if ((new_serial.type != state->type) || - (new_serial.xmit_fifo_size <= 0)) - new_serial.xmit_fifo_size = - uart_config[new_serial.type].dfl_xmit_fifo_size; - - /* Make sure address is not already in use */ - if (new_serial.type) { - for (i = 0 ; i < NR_PORTS; i++) - if ((state != &rs_table[i]) && - (rs_table[i].port == new_port) && - rs_table[i].type) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->xmit_fifo_size = state->xmit_fifo_size = - new_serial.xmit_fifo_size; - - if ((state->type != PORT_UNKNOWN) && state->port) { - release_region(state->port,8); - } - state->type = new_serial.type; - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - state->irq = new_serial.irq; - info->port = state->port = new_port; - info->hub6 = state->hub6 = new_serial.hub6; - if (info->hub6) - info->io_type = state->io_type = SERIAL_IO_HUB6; - else if (info->io_type == SERIAL_IO_HUB6) - info->io_type = state->io_type = SERIAL_IO_PORT; - } - if ((state->type != PORT_UNKNOWN) && state->port) { - request_region(state->port,8,"serial(set)"); - } - - -check_and_exit: - if (!state->port || !state->type) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info, 0); - } - } else { - retval = startup(info); - } - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - unsigned long flags; - - save_flags(flags); cli(); - status = serial_in(info, UART_LSR); - restore_flags(flags); - result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); - - /* - * If we're about to load something into the transmit - * register, we'll pretend the transmitter isn't empty to - * avoid a race condition (depending on when the transmit - * interrupt happens). - */ - if (info->x_char || - ((CIRC_CNT(info->xmit.head, info->xmit.tail, - SERIAL_XMIT_SIZE) > 0) && - !info->tty->stopped && !info->tty->hw_stopped)) - result &= TIOCSER_TEMT; - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - - -static int get_modem_info(struct async_struct * info, unsigned int *value) -{ - unsigned char control, status; - unsigned int result; - unsigned long flags; - - control = info->MCR; - save_flags(flags); cli(); - status = serial_in(info, UART_MSR); - restore_flags(flags); - result = ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) - | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) -#ifdef TIOCM_OUT1 - | ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0) - | ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0) -#endif - | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) - | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) - | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) - | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); - - if (copy_to_user(value, &result, sizeof(int))) - return -EFAULT; - return 0; -} - -static int set_modem_info(struct async_struct * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - unsigned long flags; - - if (copy_from_user(&arg, value, sizeof(int))) - return -EFAULT; - - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - info->MCR |= UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR |= UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR |= UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR |= UART_MCR_OUT2; -#endif - if (arg & TIOCM_LOOP) - info->MCR |= UART_MCR_LOOP; - break; - case TIOCMBIC: - if (arg & TIOCM_RTS) - info->MCR &= ~UART_MCR_RTS; - if (arg & TIOCM_DTR) - info->MCR &= ~UART_MCR_DTR; -#ifdef TIOCM_OUT1 - if (arg & TIOCM_OUT1) - info->MCR &= ~UART_MCR_OUT1; - if (arg & TIOCM_OUT2) - info->MCR &= ~UART_MCR_OUT2; -#endif - if (arg & TIOCM_LOOP) - info->MCR &= ~UART_MCR_LOOP; - break; - case TIOCMSET: - info->MCR = ((info->MCR & ~(UART_MCR_RTS | -#ifdef TIOCM_OUT1 - UART_MCR_OUT1 | - UART_MCR_OUT2 | -#endif - UART_MCR_LOOP | - UART_MCR_DTR)) - | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0) -#ifdef TIOCM_OUT1 - | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0) - | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0) -#endif - | ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0) - | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0)); - break; - default: - return -EINVAL; - } - save_flags(flags); cli(); - info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */ - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - return 0; -} - -static int do_autoconfig(struct async_struct * info) -{ - int retval; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (info->state->count > 1) - return -EBUSY; - - shutdown(info); - - autoconfig(info->state); - retval = startup(info); - if (retval) - return retval; - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_break")) - return; - - if (!CONFIGURED_SERIAL_PORT(info)) - return; - save_flags(flags); cli(); - if (break_state == -1) - info->LCR |= UART_LCR_SBC; - else - info->LCR &= ~UART_LCR_SBC; - serial_out(info, UART_LCR, info->LCR); - restore_flags(flags); -} - - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct icount; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERCONFIG: - return do_autoconfig(info); - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - restore_flags(flags); - /* Force modem status interrupts on */ - info->IER |= UART_IER_MSI; - serial_out(info, UART_IER, info->IER); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; - icount.dcd = cnow.dcd; - icount.rx = cnow.rx; - icount.tx = cnow.tx; - icount.frame = cnow.frame; - icount.overrun = cnow.overrun; - icount.parity = cnow.parity; - icount.brk = cnow.brk; - icount.buf_overrun = cnow.buf_overrun; - - if (copy_to_user((void *)arg, &icount, sizeof(icount))) - return -EFAULT; - return 0; - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info, old_termios); - - /* Handle transition to B0 status */ - if ((old_termios->c_cflag & CBAUD) && - !(cflag & CBAUD)) { - info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - (cflag & CBAUD)) { - info->MCR |= UART_MCR_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->MCR |= UART_MCR_RTS; - } - save_flags(flags); cli(); - serial_out(info, UART_MCR, info->MCR); - restore_flags(flags); - } - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - restore_flags(flags); - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~UART_IER_RLSI; - info->read_status_mask &= ~UART_LSR_DR; - if (info->flags & ASYNC_INITIALIZED) { - serial_out(info, UART_IER, info->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long orig_jiffies, char_time; - int lsr; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - - if (info->state->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout && timeout < char_time) - char_time = timeout; - /* - * If the transmitter hasn't cleared in twice the approximate - * amount of time to send the entire FIFO, it probably won't - * ever clear. This assumes the UART isn't doing flow - * control, which is currently the case. Hence, if it ever - * takes longer than info->timeout, this is probably due to a - * UART bug of some kind. So, we clamp the timeout parameter at - * 2*info->timeout. - */ - if (!timeout || timeout > 2*info->timeout) - timeout = 2*info->timeout; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time); - printk("jiff=%lu...", jiffies); -#endif - while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - set_current_state(TASK_RUNNING); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - if (info->flags & ASYNC_CLOSING) - return; - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - save_flags(flags); cli(); - if (tty->termios->c_cflag & CBAUD) - serial_out(info, UART_MCR, - serial_inp(info, UART_MCR) | - (UART_MCR_DTR | UART_MCR_RTS)); - restore_flags(flags); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || (serial_in(info, UART_MSR) & - UART_MSR_DCD))) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - memset(info, 0, sizeof(struct async_struct)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->io_type = sstate->io_type; - info->iomem_base = sstate->iomem_base; - info->iomem_reg_shift = sstate->iomem_reg_shift; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - unsigned long page; - - MOD_INC_USE_COUNT; - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->name, "rs_open")) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s, count = %d\n", tty->name, info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - MOD_DEC_USE_COUNT; - return -ENOMEM; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - MOD_DEC_USE_COUNT; -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - MOD_DEC_USE_COUNT; - return retval; - } - -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; - change_speed(info, 0); - } -#endif - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s successful...", tty->name); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - char stat_buf[30], control, status; - int ret; - unsigned long flags; - - ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d", - state->line, uart_config[state->type].name, - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - save_flags(flags); cli(); - status = serial_in(info, UART_MSR); - control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR); - restore_flags(flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (control & UART_MCR_RTS) - strcat(stat_buf, "|RTS"); - if (status & UART_MSR_CTS) - strcat(stat_buf, "|CTS"); - if (control & UART_MCR_DTR) - strcat(stat_buf, "|DTR"); - if (status & UART_MSR_DSR) - strcat(stat_buf, "|DSR"); - if (status & UART_MSR_DCD) - strcat(stat_buf, "|CD"); - if (status & UART_MSR_RI) - strcat(stat_buf, "|RI"); - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - /* - * Last thing is the RS-232 status lines - */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); - return ret; -} - -int rs_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0, l; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n", - serial_version, LOCAL_VERSTRING, serial_revdate); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - l = line_info(page + len, &rs_table[i]); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static char serial_options[] __initdata = - " no serial options enabled\n"; -#undef SERIAL_OPT - -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name, - serial_version, LOCAL_VERSTRING, serial_revdate, - serial_options); -} - - -/* - * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A. The important question is - * whether or not this UART is a 16550A or not, since this will - * determine whether or not we can use its FIFO features or not. - */ -static void autoconfig(struct serial_state * state) -{ - struct async_struct *info, scr_info; - unsigned long flags; - - -#ifdef SERIAL_DEBUG_AUTOCONF - printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line, - state->port, (unsigned) state->iomem_base); -#endif - - if (!CONFIGURED_SERIAL_PORT(state)) - return; - - if (inl(UART_MOD_CNTRL + state->port) != 0x3) { - outl(3, UART_MOD_CNTRL + state->port); - } - - state->type = PORT_16550; - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->state = state; - info->port = state->port; - info->flags = state->flags; - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; - - - save_flags(flags); cli(); - state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; - - if (info->port) { - request_region(info->port,8,"serial(auto)"); - } - - /* - * Reset the UART. - */ - serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO | - UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT)); - serial_outp(info, UART_FCR, 0); - (void)serial_in(info, UART_RX); - serial_outp(info, UART_IER, 0); - - restore_flags(flags); -} - -int register_serial(struct serial_struct *req); -void unregister_serial(int line); - -EXPORT_SYMBOL(register_serial); -EXPORT_SYMBOL(unregister_serial); - -static struct tty_operations serial_ops = { - .open = rs_open, - .close = rs_close, - .write = rs_write, - .put_char = rs_put_char, - .flush_chars = rs_flush_chars, - .write_room = rs_write_room, - .chars_in_buffer = rs_chars_in_buffer, - .flush_buffer = rs_flush_buffer, - .ioctl = rs_ioctl, - .throttle = rs_throttle, - .unthrottle = rs_unthrottle, - .set_termios = rs_set_termios, - .stop = rs_stop, - .start = rs_start, - .hangup = rs_hangup, - .break_ctl = rs_break, - .send_xchar = rs_send_xchar, - .wait_until_sent = rs_wait_until_sent, - .read_proc = rs_read_proc, -}; - - -/* - * The serial driver boot-time initialization code! - */ -static int __init rs_init(void) -{ - int i; - struct serial_state * state; - - serial_driver = alloc_tty_driver(NR_PORTS); - if (!serial_driver) - return -ENOMEM; - - init_bh(SERIAL_BH, do_serial_bh); - init_timer(&serial_timer); - serial_timer.function = rs_timer; - mod_timer(&serial_timer, jiffies + RS_STROBE_TIME); - - for (i = 0; i < NR_IRQS; i++) { - IRQ_ports[i] = 0; - IRQ_timeout[i] = 0; - } -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - /* - * The interrupt of the serial console port - * can't be shared. - */ - if (sercons.flags & CON_CONSDEV) { - for(i = 0; i < NR_PORTS; i++) - if (i != sercons.index && - rs_table[i].irq == rs_table[sercons.index].irq) - rs_table[i].irq = 0; - } -#endif - show_serial_version(); - - /* Initialize the tty_driver structure */ - - serial_driver->driver_name = "serial"; - serial_driver->devfs_name = "tts/"; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64 + SERIAL_DEV_OFFSET; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS; - tty_set_operations(serial_driver, &serial_ops); - - if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->baud_base = get_au1000_uart_baud(); - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - state->irq = irq_canonicalize(state->irq); - if (state->hub6) - state->io_type = SERIAL_IO_HUB6; - if (state->port && check_region(state->port,8)) { - continue; - } - - if (state->flags & ASYNC_BOOT_AUTOCONF) { - autoconfig(state); - } - } - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - if (state->type == PORT_UNKNOWN) { - continue; - } - printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", - state->port, state->irq, - uart_config[state->type].name); - tty_register_device(serial_driver, state->line, NULL); - } - return 0; -} - -/* - * register_serial and unregister_serial allows for 16x50 serial ports to be - * configured at run-time, to support PCMCIA modems. - */ - -/** - * register_serial - configure a 16x50 serial port at runtime - * @req: request structure - * - * Configure the serial port specified by the request. If the - * port exists and is in use an error is returned. If the port - * is not currently in the table it is added. - * - * The port is then probed and if necessary the IRQ is autodetected - * If this fails an error is returned. - * - * On success the port is ready to use and the line number is returned. - */ - -int register_serial(struct serial_struct *req) -{ - int i; - unsigned long flags; - struct serial_state *state; - struct async_struct *info; - unsigned long port; - - port = req->port; - if (HIGH_BITS_OFFSET) - port += (unsigned long) req->port_high << HIGH_BITS_OFFSET; - - save_flags(flags); cli(); - for (i = 0; i < NR_PORTS; i++) { - if ((rs_table[i].port == port) && - (rs_table[i].iomem_base == req->iomem_base)) - break; - } - if (i == NR_PORTS) { - for (i = 0; i < NR_PORTS; i++) - if ((rs_table[i].type == PORT_UNKNOWN) && - (rs_table[i].count == 0)) - break; - } - if (i == NR_PORTS) { - restore_flags(flags); - return -1; - } - state = &rs_table[i]; - if (rs_table[i].count) { - restore_flags(flags); - printk("Couldn't configure serial #%d (port=%ld,irq=%d): " - "device already open\n", i, port, req->irq); - return -1; - } - state->irq = req->irq; - state->port = port; - state->flags = req->flags; - state->io_type = req->io_type; - state->iomem_base = req->iomem_base; - state->iomem_reg_shift = req->iomem_reg_shift; - if (req->baud_base) - state->baud_base = req->baud_base; - if ((info = state->info) != NULL) { - info->port = port; - info->flags = req->flags; - info->io_type = req->io_type; - info->iomem_base = req->iomem_base; - info->iomem_reg_shift = req->iomem_reg_shift; - } - autoconfig(state); - if (state->type == PORT_UNKNOWN) { - restore_flags(flags); - printk("register_serial(): autoconfig failed\n"); - return -1; - } - restore_flags(flags); - - printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n", - state->line + SERIAL_DEV_OFFSET, - state->iomem_base ? "iomem" : "port", - state->iomem_base ? (unsigned long)state->iomem_base : - state->port, state->irq, uart_config[state->type].name); - tty_register_device(serial_driver, state->line, NULL); - return state->line + SERIAL_DEV_OFFSET; -} - -/** - * unregister_serial - deconfigure a 16x50 serial port - * @line: line to deconfigure - * - * The port specified is deconfigured and its resources are freed. Any - * user of the port is disconnected as if carrier was dropped. Line is - * the port number returned by register_serial(). - */ - -void unregister_serial(int line) -{ - unsigned long flags; - struct serial_state *state = &rs_table[line]; - - save_flags(flags); cli(); - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - state->type = PORT_UNKNOWN; - printk(KERN_INFO "tty%02d unloaded\n", state->line); - /* These will be hidden, because they are devices that will no longer - * be available to the system. (ie, PCMCIA modems, once ejected) - */ - tty_unregister_device(serial_driver, state->line); - restore_flags(flags); -} - -static void __exit rs_fini(void) -{ - unsigned long flags; - int e1, e2; - int i; - struct async_struct *info; - - /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ - del_timer_sync(&serial_timer); - save_flags(flags); cli(); - remove_bh(SERIAL_BH); - if ((e1 = tty_unregister_driver(serial_driver))) - printk("serial: failed to unregister serial driver (%d)\n", - e1); - restore_flags(flags); - put_tty_driver(serial_driver); - - for (i = 0; i < NR_PORTS; i++) { - if ((info = rs_table[i].info)) { - rs_table[i].info = NULL; - kfree(info); - } - if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) { - release_region(rs_table[i].port, 8); - } - } - if (tmp_buf) { - unsigned long pg = (unsigned long) tmp_buf; - tmp_buf = NULL; - free_page(pg); - } -} - -module_init(rs_init); -module_exit(rs_fini); -MODULE_DESCRIPTION("Au1000 serial driver"); - - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - -#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) - -static struct async_struct async_sercons; - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct async_struct *info) -{ - unsigned int status, tmout = 0xffffff; - - do { - status = serial_in(info, UART_LSR); - - if (status & UART_LSR_BI) - lsr_break_flag = UART_LSR_BI; - - if (--tmout == 0) - break; - } while((status & BOTH_EMPTY) != BOTH_EMPTY); -} - - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - static struct async_struct *info = &async_sercons; - int ier; - unsigned i; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_in(info, UART_IER); - serial_out(info, UART_IER, 0x00); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(info); - - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_out(info, UART_TX, *s); - if (*s == 10) { - wait_for_xmitr(info); - serial_out(info, UART_TX, 13); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - wait_for_xmitr(info); - serial_out(info, UART_IER, ier); -} - -static struct tty_driver *serial_console_device(struct console *c, int *index) -{ - *index = c->index - SERIAL_DEV_OFFSET; - return serial_driver; -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init serial_console_setup(struct console *co, char *options) -{ - static struct async_struct *info; - struct serial_state *state; - unsigned cval; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - int quot = 0; - char *s; - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * Divisor, bytesize and parity - */ - state = rs_table + co->index; - info = &async_sercons; - info->magic = SERIAL_MAGIC; - info->state = state; - info->port = state->port; - info->flags = state->flags; - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; - state->baud_base = get_au1000_uart_baud(); - quot = state->baud_base / baud; - - cval = cflag & (CSIZE | CSTOPB); - cval >>= 4; - if (cflag & PARENB) - cval |= UART_LCR_PARITY; - if (!(cflag & PARODD)) - cval |= UART_LCR_EPAR; - - /* - * Disable UART interrupts, set DTR and RTS high - * and set speed. - */ - serial_out(info, UART_CLK, quot & 0xffff); - serial_out(info, UART_IER, 0); - serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS); - - /* - * If we read 0xff from the LSR, there is no UART here. - */ - if (serial_in(info, UART_LSR) == 0xff) - return -1; - - return 0; -} - -static struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Register console. - */ -static void __init au1000_serial_console_init(void) -{ - register_console(&sercons); -} -console_initcall(au1000_serial_console_init); -#endif - -/* - Local variables: - compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -pipe -fno-strength-reduce -march=i586 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -DEXPORT_SYMTAB -c serial.c" - End: -*/ diff -Nru a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c --- a/arch/mips/au1000/common/time.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/au1000/common/time.c Fri Jun 27 14:19:55 2003 @@ -5,8 +5,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -20,10 +18,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Setting up the clock on the MIPS boards. */ +#include <linux/types.h> #include <linux/config.h> #include <linux/init.h> #include <linux/kernel_stat.h> @@ -33,27 +30,39 @@ #include <asm/mipsregs.h> #include <asm/ptrace.h> +#include <asm/time.h> +#include <asm/hardirq.h> #include <asm/div64.h> #include <asm/au1000.h> #include <linux/mc146818rtc.h> #include <linux/timex.h> +extern void startup_match20_interrupt(void); +extern void do_softirq(void); extern volatile unsigned long wall_jiffies; unsigned long missed_heart_beats = 0; -unsigned long uart_baud_base; static unsigned long r4k_offset; /* Amount to increment compare reg each time */ static unsigned long r4k_cur; /* What counter should be at next timer irq */ +extern unsigned int mips_counter_frequency; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi = 0, timerlo = 0; -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) +#ifdef CONFIG_PM +#define MATCH20_INC 328 +extern void startup_match20_interrupt(void); +static unsigned long last_pc0, last_match20; +#endif + +static spinlock_t time_lock = SPIN_LOCK_UNLOCKED; static inline void ack_r4ktimer(unsigned long newval) { - write_32bit_cp0_register(CP0_COMPARE, newval); + write_c0_compare(newval); } - /* * There are a lot of conceptually broken versions of the MIPS timer interrupt * handler floating around. This one is rather different, but the algorithm @@ -62,108 +71,201 @@ unsigned long wtimer; void mips_timer_interrupt(struct pt_regs *regs) { - int irq = 7; + int irq = 63; + unsigned long count; + int cpu = smp_processor_id(); + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + +#ifdef CONFIG_PM + printk(KERN_ERR "Unexpected CP0 interrupt\n"); + regs->cp0_status &= ~IE_IRQ5; /* disable CP0 interrupt */ + return; +#endif if (r4k_offset == 0) goto null; do { + count = read_c0_count(); + timerhi += (count < timerlo); /* Wrap around */ + timerlo = count; + kstat_cpu(0).irqs[irq]++; do_timer(regs); r4k_cur += r4k_offset; ack_r4ktimer(r4k_cur); - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) + } while (((unsigned long)read_c0_count() - r4k_cur) < 0x7fffffff); + irq_exit(); + + if (softirq_pending(cpu)) + do_softirq(); return; null: ack_r4ktimer(0); } -/* +#ifdef CONFIG_PM +void counter0_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long pc0; + int time_elapsed; + static int jiffie_drift = 0; + + kstat_cpu(0).irqs[irq]++; + if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) { + /* should never happen! */ + printk(KERN_WARNING "counter 0 w status eror\n"); + return; + } + + pc0 = au_readl(SYS_TOYREAD); + if (pc0 < last_match20) { + /* counter overflowed */ + time_elapsed = (0xffffffff - last_match20) + pc0; + } + else { + time_elapsed = pc0 - last_match20; + } + + while (time_elapsed > 0) { + do_timer(regs); + time_elapsed -= MATCH20_INC; + last_match20 += MATCH20_INC; + jiffie_drift++; + } + + last_pc0 = pc0; + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); + + /* our counter ticks at 10.009765625 ms/tick, we we're running + * almost 10uS too slow per tick. + */ + + if (jiffie_drift >= 999) { + jiffie_drift -= 999; + do_timer(regs); /* increment jiffies by one */ + } +} +#endif + +/* * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. + * register for each time tick. * Use the Programmable Counter 1 to do this. */ unsigned long cal_r4koff(void) { unsigned long count; - unsigned long cpu_pll; unsigned long cpu_speed; unsigned long start, end; unsigned long counter; - int i; int trim_divide = 16; + unsigned long flags; - counter = inl(PC_COUNTER_CNTRL); - outl(counter | PC_CNTRL_EN1, PC_COUNTER_CNTRL); + spin_lock_irqsave(&time_lock, flags); - while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T1S); - outl(trim_divide-1, PC1_TRIM); /* RTC now ticks at 32.768/16 kHz */ - while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T1S); - - while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_C1S); - outl (0, PC1_COUNTER_WRITE); - while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_C1S); + counter = au_readl(SYS_COUNTER_CNTRL); + au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); - start = inl(PC1_COUNTER_READ); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); + au_writel(trim_divide-1, SYS_RTCTRIM); /* RTC now ticks at 32.768/16 kHz */ + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); + au_writel (0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); + + start = au_readl(SYS_RTCREAD); start += 2; /* wait for the beginning of a new tick */ - while (inl(PC1_COUNTER_READ) < start); + while (au_readl(SYS_RTCREAD) < start); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); end = start + (32768 / trim_divide)/2; /* wait 0.5 seconds */ - while (end > inl(PC1_COUNTER_READ)); + while (end > au_readl(SYS_RTCREAD)); - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); cpu_speed = count * 2; - uart_baud_base = (((cpu_speed) / 4) / 16); + mips_counter_frequency = count; + set_au1x00_uart_baud_base(((cpu_speed) / 4) / 16); + spin_unlock_irqrestore(&time_lock, flags); return (cpu_speed / HZ); } -static unsigned long __init get_mips_time(void) -{ - return inl(PC0_COUNTER_READ); -} - -void __init time_init(void) +void __init au1x_time_init(void) { - unsigned int est_freq, flags; + unsigned int est_freq; printk("calculating r4koff... "); r4k_offset = cal_r4koff(); printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - //est_freq = 2*r4k_offset*HZ; - est_freq = r4k_offset*HZ; + //est_freq = 2*r4k_offset*HZ; + est_freq = r4k_offset*HZ; est_freq += 5000; /* round */ est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); + set_au1x00_speed(est_freq); + set_au1x00_lcd_clock(); // program the LCD clock + r4k_cur = (read_c0_count() + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ALLINTS); + write_c0_compare(r4k_cur); - /* Read time from the RTC chipset. */ - write_seqlock_irqsave (&xtime_lock, flags); - xtime.tv_sec = get_mips_time(); - xtime.tv_usec = 0; - write_sequnlock_irqrestore(&xtime_lock, flags); + /* no RTC on the pb1000 */ + xtime.tv_sec = 0; + //xtime.tv_usec = 0; + +#ifdef CONFIG_PM + /* + * setup counter 0, since it keeps ticking after a + * 'wait' instruction has been executed. The CP0 timer and + * counter 1 do NOT continue running after 'wait' + * + * It's too early to call request_irq() here, so we handle + * counter 0 interrupt as a special irq and it doesn't show + * up under /proc/interrupts. + */ + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + au_writel(0, SYS_TOYWRITE); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); + + au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK); + au_writel(~0, SYS_WAKESRC); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + + /* setup match20 to interrupt once every 10ms */ + last_pc0 = last_match20 = au_readl(SYS_TOYREAD); + au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); + startup_match20_interrupt(); +#endif + + //set_c0_status(ALLINTS); + au_sync(); } -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff) +void __init au1x_timer_setup(struct irqaction *irq) +{ -/* Cycle counter value at the previous timer interrupt.. */ +} -static unsigned int timerhi = 0, timerlo = 0; +/* This is for machines which generate the exact clock. */ +#define USECS_PER_JIFFY (1000000/HZ) +#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) +#ifndef CONFIG_PM static unsigned long div64_32(unsigned long v1, unsigned long v2, unsigned long v3) { @@ -171,13 +273,30 @@ do_div64_32(r0, v1, v2, v3); return r0; } +#endif - -/* - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ static unsigned long do_fast_gettimeoffset(void) { +#ifdef CONFIG_PM + unsigned long pc0; + unsigned long offset; + + pc0 = au_readl(SYS_TOYREAD); + if (pc0 < last_pc0) { + offset = 0xffffffff - last_pc0 + pc0; + printk("offset over: %x\n", (unsigned)offset); + } + else { + offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10); + } + if ((pc0-last_pc0) > 2*MATCH20_INC) { + printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", + (unsigned)offset, (unsigned)last_pc0, + (unsigned)last_match20, (unsigned)pc0); + } + au_sync(); + return offset; +#else u32 count; unsigned long res, tmp; unsigned long r0; @@ -206,7 +325,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -218,73 +337,12 @@ "r" (quotient)); /* - * Due to possible jiffies inconsistencies, we need to check + * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) res = USECS_PER_JIFFY-1; return res; -} - -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } -} - -void do_settimeofday(struct timeval *tv) -{ - write_seqlock_irq (&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. - * Discover what correction gettimeofday would have done, and then - * undo it! - */ - tv->tv_usec -= do_fast_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; - - write_sequnlock_irq (&xtime_lock); -} - -/* - * The UART baud base is not known at compile time ... if - * we want to be able to use the same code on different - * speed CPUs. - */ -unsigned long get_au1000_uart_baud() -{ - return uart_baud_base; +#endif } diff -Nru a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/common/usbdev.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1562 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1000 USB Device-Side (device layer) + * + * Copyright 2001-2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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 <linux/config.h> +#include <linux/kernel.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/signal.h> +#include <linux/errno.h> +#include <linux/poll.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/fcntl.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/list.h> +#include <linux/smp_lock.h> +#define DEBUG +#include <linux/usb.h> + +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/au1000.h> +#include <asm/au1000_dma.h> +#include <asm/au1000_usbdev.h> + +#ifdef DEBUG +#undef VDEBUG +#ifdef VDEBUG +#define vdbg(fmt, arg...) printk(KERN_DEBUG __FILE__ ": " fmt "\n" , ## arg) +#else +#define vdbg(fmt, arg...) do {} while (0) +#endif +#else +#define vdbg(fmt, arg...) do {} while (0) +#endif + +#define MAX(a,b) (((a)>(b))?(a):(b)) + +#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL) + +#define EP_FIFO_DEPTH 8 + +typedef enum { + SETUP_STAGE = 0, + DATA_STAGE, + STATUS_STAGE +} ep0_stage_t; + +typedef struct { + int read_fifo; + int write_fifo; + int ctrl_stat; + int read_fifo_status; + int write_fifo_status; +} endpoint_reg_t; + +typedef struct { + usbdev_pkt_t *head; + usbdev_pkt_t *tail; + int count; +} pkt_list_t; + +typedef struct { + int active; + struct usb_endpoint_descriptor *desc; + endpoint_reg_t *reg; + /* Only one of these are used, unless this is the control ep */ + pkt_list_t inlist; + pkt_list_t outlist; + unsigned int indma, outdma; /* DMA channel numbers for IN, OUT */ + /* following are extracted from endpoint descriptor for easy access */ + int max_pkt_size; + int type; + int direction; + /* WE assign endpoint addresses! */ + int address; + spinlock_t lock; +} endpoint_t; + + +static struct usb_dev { + endpoint_t ep[6]; + ep0_stage_t ep0_stage; + + struct usb_device_descriptor * dev_desc; + struct usb_interface_descriptor* if_desc; + struct usb_config_descriptor * conf_desc; + u8 * full_conf_desc; + struct usb_string_descriptor * str_desc[6]; + + /* callback to function layer */ + void (*func_cb)(usbdev_cb_type_t type, unsigned long arg, + void *cb_data); + void* cb_data; + + usbdev_state_t state; // device state + int suspended; // suspended flag + int address; // device address + int interface; + int num_ep; + u8 alternate_setting; + u8 configuration; // configuration value + int remote_wakeup_en; +} usbdev; + + +static endpoint_reg_t ep_reg[] = { + // FIFO's 0 and 1 are EP0 default control + {USBD_EP0RD, USBD_EP0WR, USBD_EP0CS, USBD_EP0RDSTAT, USBD_EP0WRSTAT }, + {0}, + // FIFO 2 is EP2, IN + { -1, USBD_EP2WR, USBD_EP2CS, -1, USBD_EP2WRSTAT }, + // FIFO 3 is EP3, IN + { -1, USBD_EP3WR, USBD_EP3CS, -1, USBD_EP3WRSTAT }, + // FIFO 4 is EP4, OUT + {USBD_EP4RD, -1, USBD_EP4CS, USBD_EP4RDSTAT, -1 }, + // FIFO 5 is EP5, OUT + {USBD_EP5RD, -1, USBD_EP5CS, USBD_EP5RDSTAT, -1 } +}; + +static struct { + unsigned int id; + const char *str; +} ep_dma_id[] = { + { DMA_ID_USBDEV_EP0_TX, "USBDev EP0 IN" }, + { DMA_ID_USBDEV_EP0_RX, "USBDev EP0 OUT" }, + { DMA_ID_USBDEV_EP2_TX, "USBDev EP2 IN" }, + { DMA_ID_USBDEV_EP3_TX, "USBDev EP3 IN" }, + { DMA_ID_USBDEV_EP4_RX, "USBDev EP4 OUT" }, + { DMA_ID_USBDEV_EP5_RX, "USBDev EP5 OUT" } +}; + +#define DIR_OUT 0 +#define DIR_IN (1<<3) + +#define CONTROL_EP USB_ENDPOINT_XFER_CONTROL +#define BULK_EP USB_ENDPOINT_XFER_BULK + +static inline endpoint_t * +epaddr_to_ep(struct usb_dev* dev, int ep_addr) +{ + if (ep_addr >= 0 && ep_addr < 2) + return &dev->ep[0]; + if (ep_addr < 6) + return &dev->ep[ep_addr]; + return NULL; +} + +static const char* std_req_name[] = { + "GET_STATUS", + "CLEAR_FEATURE", + "RESERVED", + "SET_FEATURE", + "RESERVED", + "SET_ADDRESS", + "GET_DESCRIPTOR", + "SET_DESCRIPTOR", + "GET_CONFIGURATION", + "SET_CONFIGURATION", + "GET_INTERFACE", + "SET_INTERFACE", + "SYNCH_FRAME" +}; + +static inline const char* +get_std_req_name(int req) +{ + return (req >= 0 && req <= 12) ? std_req_name[req] : "UNKNOWN"; +} + +#if 0 +static void +dump_setup(struct usb_ctrlrequest* s) +{ + dbg(__FUNCTION__ ": requesttype=%d", s->requesttype); + dbg(__FUNCTION__ ": request=%d %s", s->request, + get_std_req_name(s->request)); + dbg(__FUNCTION__ ": value=0x%04x", s->wValue); + dbg(__FUNCTION__ ": index=%d", s->index); + dbg(__FUNCTION__ ": length=%d", s->length); +} +#endif + +static inline usbdev_pkt_t * +alloc_packet(endpoint_t * ep, int data_size, void* data) +{ + usbdev_pkt_t* pkt = + (usbdev_pkt_t *)kmalloc(sizeof(usbdev_pkt_t) + data_size, + ALLOC_FLAGS); + if (!pkt) + return NULL; + pkt->ep_addr = ep->address; + pkt->size = data_size; + pkt->status = 0; + pkt->next = NULL; + if (data) + memcpy(pkt->payload, data, data_size); + + return pkt; +} + + +/* + * Link a packet to the tail of the enpoint's packet list. + * EP spinlock must be held when calling. + */ +static void +link_tail(endpoint_t * ep, pkt_list_t * list, usbdev_pkt_t * pkt) +{ + if (!list->tail) { + list->head = list->tail = pkt; + list->count = 1; + } else { + list->tail->next = pkt; + list->tail = pkt; + list->count++; + } +} + +/* + * Unlink and return a packet from the head of the given packet + * list. It is the responsibility of the caller to free the packet. + * EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +unlink_head(pkt_list_t * list) +{ + usbdev_pkt_t *pkt; + + pkt = list->head; + if (!pkt || !list->count) { + return NULL; + } + + list->head = pkt->next; + if (!list->head) { + list->head = list->tail = NULL; + list->count = 0; + } else + list->count--; + + return pkt; +} + +/* + * Create and attach a new packet to the tail of the enpoint's + * packet list. EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +add_packet(endpoint_t * ep, pkt_list_t * list, int size) +{ + usbdev_pkt_t *pkt = alloc_packet(ep, size, NULL); + if (!pkt) + return NULL; + + link_tail(ep, list, pkt); + return pkt; +} + + +/* + * Unlink and free a packet from the head of the enpoint's + * packet list. EP spinlock must be held when calling. + */ +static inline void +free_packet(pkt_list_t * list) +{ + kfree(unlink_head(list)); +} + +/* EP spinlock must be held when calling. */ +static inline void +flush_pkt_list(pkt_list_t * list) +{ + while (list->count) + free_packet(list); +} + +/* EP spinlock must be held when calling */ +static inline void +flush_write_fifo(endpoint_t * ep) +{ + if (ep->reg->write_fifo_status >= 0) { + au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF | + USBDEV_FSTAT_OF, + ep->reg->write_fifo_status); + //udelay(100); + //au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF, + // ep->reg->write_fifo_status); + } +} + +/* EP spinlock must be held when calling */ +static inline void +flush_read_fifo(endpoint_t * ep) +{ + if (ep->reg->read_fifo_status >= 0) { + au_writel(USBDEV_FSTAT_FLUSH | USBDEV_FSTAT_UF | + USBDEV_FSTAT_OF, + ep->reg->read_fifo_status); + //udelay(100); + //au_writel(USBDEV_FSTAT_UF | USBDEV_FSTAT_OF, + // ep->reg->read_fifo_status); + } +} + + +/* EP spinlock must be held when calling. */ +static void +endpoint_flush(endpoint_t * ep) +{ + // First, flush all packets + flush_pkt_list(&ep->inlist); + flush_pkt_list(&ep->outlist); + + // Now flush the endpoint's h/w FIFO(s) + flush_write_fifo(ep); + flush_read_fifo(ep); +} + +/* EP spinlock must be held when calling. */ +static void +endpoint_stall(endpoint_t * ep) +{ + u32 cs; + + warn(__FUNCTION__); + + cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL; + au_writel(cs, ep->reg->ctrl_stat); +} + +/* EP spinlock must be held when calling. */ +static void +endpoint_unstall(endpoint_t * ep) +{ + u32 cs; + + warn(__FUNCTION__); + + cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL; + au_writel(cs, ep->reg->ctrl_stat); +} + +static void +endpoint_reset_datatoggle(endpoint_t * ep) +{ + // FIXME: is this possible? +} + + +/* EP spinlock must be held when calling. */ +static int +endpoint_fifo_read(endpoint_t * ep) +{ + int read_count = 0; + u8 *bufptr; + usbdev_pkt_t *pkt = ep->outlist.tail; + + if (!pkt) + return -EINVAL; + + bufptr = &pkt->payload[pkt->size]; + while (au_readl(ep->reg->read_fifo_status) & USBDEV_FSTAT_FCNT_MASK) { + *bufptr++ = au_readl(ep->reg->read_fifo) & 0xff; + read_count++; + pkt->size++; + } + + return read_count; +} + +#if 0 +/* EP spinlock must be held when calling. */ +static int +endpoint_fifo_write(endpoint_t * ep, int index) +{ + int write_count = 0; + u8 *bufptr; + usbdev_pkt_t *pkt = ep->inlist.head; + + if (!pkt) + return -EINVAL; + + bufptr = &pkt->payload[index]; + while ((au_readl(ep->reg->write_fifo_status) & + USBDEV_FSTAT_FCNT_MASK) < EP_FIFO_DEPTH) { + if (bufptr < pkt->payload + pkt->size) { + au_writel(*bufptr++, ep->reg->write_fifo); + write_count++; + } else { + break; + } + } + + return write_count; +} +#endif + +/* + * This routine is called to restart transmission of a packet. + * The endpoint's TSIZE must be set to the new packet's size, + * and DMA to the write FIFO needs to be restarted. + * EP spinlock must be held when calling. + */ +static void +kickstart_send_packet(endpoint_t * ep) +{ + u32 cs; + usbdev_pkt_t *pkt = ep->inlist.head; + + vdbg(__FUNCTION__ ": ep%d, pkt=%p", ep->address, pkt); + + if (!pkt) { + err(__FUNCTION__ ": head=NULL! list->count=%d", + ep->inlist.count); + return; + } + + dma_cache_wback_inv((unsigned long)pkt->payload, pkt->size); + + /* + * make sure FIFO is empty + */ + flush_write_fifo(ep); + + cs = au_readl(ep->reg->ctrl_stat) & USBDEV_CS_STALL; + cs |= (pkt->size << USBDEV_CS_TSIZE_BIT); + au_writel(cs, ep->reg->ctrl_stat); + + if (get_dma_active_buffer(ep->indma) == 1) { + set_dma_count1(ep->indma, pkt->size); + set_dma_addr1(ep->indma, virt_to_phys(pkt->payload)); + enable_dma_buffer1(ep->indma); // reenable + } else { + set_dma_count0(ep->indma, pkt->size); + set_dma_addr0(ep->indma, virt_to_phys(pkt->payload)); + enable_dma_buffer0(ep->indma); // reenable + } + if (dma_halted(ep->indma)) + start_dma(ep->indma); +} + + +/* + * This routine is called when a packet in the inlist has been + * completed. Frees the completed packet and starts sending the + * next. EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +send_packet_complete(endpoint_t * ep) +{ + usbdev_pkt_t *pkt = unlink_head(&ep->inlist); + + if (pkt) { + pkt->status = + (au_readl(ep->reg->ctrl_stat) & USBDEV_CS_NAK) ? + PKT_STATUS_NAK : PKT_STATUS_ACK; + + vdbg(__FUNCTION__ ": ep%d, %s pkt=%p, list count=%d", + ep->address, (pkt->status & PKT_STATUS_NAK) ? + "NAK" : "ACK", pkt, ep->inlist.count); + } + + /* + * The write fifo should already be drained if things are + * working right, but flush it anyway just in case. + */ + flush_write_fifo(ep); + + // begin transmitting next packet in the inlist + if (ep->inlist.count) { + kickstart_send_packet(ep); + } + + return pkt; +} + +/* + * Add a new packet to the tail of the given ep's packet + * inlist. The transmit complete interrupt frees packets from + * the head of this list. EP spinlock must be held when calling. + */ +static int +send_packet(struct usb_dev* dev, usbdev_pkt_t *pkt, int async) +{ + pkt_list_t *list; + endpoint_t* ep; + + if (!pkt || !(ep = epaddr_to_ep(dev, pkt->ep_addr))) + return -EINVAL; + + if (!pkt->size) + return 0; + + list = &ep->inlist; + + if (!async && list->count) { + halt_dma(ep->indma); + flush_pkt_list(list); + } + + link_tail(ep, list, pkt); + + vdbg(__FUNCTION__ ": ep%d, pkt=%p, size=%d, list count=%d", + ep->address, pkt, pkt->size, list->count); + + if (list->count == 1) { + /* + * if the packet count is one, it means the list was empty, + * and no more data will go out this ep until we kick-start + * it again. + */ + kickstart_send_packet(ep); + } + + return pkt->size; +} + +/* + * This routine is called to restart reception of a packet. + * EP spinlock must be held when calling. + */ +static void +kickstart_receive_packet(endpoint_t * ep) +{ + usbdev_pkt_t *pkt; + + // get and link a new packet for next reception + if (!(pkt = add_packet(ep, &ep->outlist, ep->max_pkt_size))) { + err(__FUNCTION__ ": could not alloc new packet"); + return; + } + + if (get_dma_active_buffer(ep->outdma) == 1) { + clear_dma_done1(ep->outdma); + set_dma_count1(ep->outdma, ep->max_pkt_size); + set_dma_count0(ep->outdma, 0); + set_dma_addr1(ep->outdma, virt_to_phys(pkt->payload)); + enable_dma_buffer1(ep->outdma); // reenable + } else { + clear_dma_done0(ep->outdma); + set_dma_count0(ep->outdma, ep->max_pkt_size); + set_dma_count1(ep->outdma, 0); + set_dma_addr0(ep->outdma, virt_to_phys(pkt->payload)); + enable_dma_buffer0(ep->outdma); // reenable + } + if (dma_halted(ep->outdma)) + start_dma(ep->outdma); +} + + +/* + * This routine is called when a packet in the outlist has been + * completed (received) and we need to prepare for a new packet + * to be received. Halts DMA and computes the packet size from the + * remaining DMA counter. Then prepares a new packet for reception + * and restarts DMA. FIXME: what if another packet comes in + * on top of the completed packet? Counter would be wrong. + * EP spinlock must be held when calling. + */ +static usbdev_pkt_t * +receive_packet_complete(endpoint_t * ep) +{ + usbdev_pkt_t *pkt = ep->outlist.tail; + u32 cs; + + halt_dma(ep->outdma); + + cs = au_readl(ep->reg->ctrl_stat); + + if (!pkt) + return NULL; + + pkt->size = ep->max_pkt_size - get_dma_residue(ep->outdma); + if (pkt->size) + dma_cache_inv((unsigned long)pkt->payload, pkt->size); + /* + * need to pull out any remaining bytes in the FIFO. + */ + endpoint_fifo_read(ep); + /* + * should be drained now, but flush anyway just in case. + */ + flush_read_fifo(ep); + + pkt->status = (cs & USBDEV_CS_NAK) ? PKT_STATUS_NAK : PKT_STATUS_ACK; + if (ep->address == 0 && (cs & USBDEV_CS_SU)) + pkt->status |= PKT_STATUS_SU; + + vdbg(__FUNCTION__ ": ep%d, %s pkt=%p, size=%d", + ep->address, (pkt->status & PKT_STATUS_NAK) ? + "NAK" : "ACK", pkt, pkt->size); + + kickstart_receive_packet(ep); + + return pkt; +} + + +/* + **************************************************************************** + * Here starts the standard device request handlers. They are + * all called by do_setup() via a table of function pointers. + **************************************************************************** + */ + +static ep0_stage_t +do_get_status(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + switch (setup->bRequestType) { + case 0x80: // Device + // FIXME: send device status + break; + case 0x81: // Interface + // FIXME: send interface status + break; + case 0x82: // End Point + // FIXME: send endpoint status + break; + default: + // Invalid Command + endpoint_stall(&dev->ep[0]); // Stall End Point 0 + break; + } + + return STATUS_STAGE; +} + +static ep0_stage_t +do_clear_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + switch (setup->bRequestType) { + case 0x00: // Device + if ((le16_to_cpu(setup->wValue) & 0xff) == 1) + dev->remote_wakeup_en = 0; + else + endpoint_stall(&dev->ep[0]); + break; + case 0x02: // End Point + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { + endpoint_t *ep = + epaddr_to_ep(dev, + le16_to_cpu(setup->wIndex) & 0xff); + + endpoint_unstall(ep); + endpoint_reset_datatoggle(ep); + } else + endpoint_stall(&dev->ep[0]); + break; + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_reserved(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // Invalid request, stall End Point 0 + endpoint_stall(&dev->ep[0]); + return SETUP_STAGE; +} + +static ep0_stage_t +do_set_feature(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + switch (setup->bRequestType) { + case 0x00: // Device + if ((le16_to_cpu(setup->wValue) & 0xff) == 1) + dev->remote_wakeup_en = 1; + else + endpoint_stall(&dev->ep[0]); + break; + case 0x02: // End Point + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { + endpoint_t *ep = + epaddr_to_ep(dev, + le16_to_cpu(setup->wIndex) & 0xff); + + endpoint_stall(ep); + } else + endpoint_stall(&dev->ep[0]); + break; + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_set_address(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + int new_state = dev->state; + int new_addr = le16_to_cpu(setup->wValue); + + dbg(__FUNCTION__ ": our address=%d", new_addr); + + if (new_addr > 127) { + // usb spec doesn't tell us what to do, so just go to + // default state + new_state = DEFAULT; + dev->address = 0; + } else if (dev->address != new_addr) { + dev->address = new_addr; + new_state = ADDRESS; + } + + if (dev->state != new_state) { + dev->state = new_state; + /* inform function layer of usbdev state change */ + dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data); + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_get_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + int strnum, desc_len = le16_to_cpu(setup->wLength); + + switch (le16_to_cpu(setup->wValue) >> 8) { + case USB_DT_DEVICE: + // send device descriptor! + desc_len = desc_len > dev->dev_desc->bLength ? + dev->dev_desc->bLength : desc_len; + dbg("sending device desc, size=%d", desc_len); + send_packet(dev, alloc_packet(&dev->ep[0], desc_len, + dev->dev_desc), 0); + break; + case USB_DT_CONFIG: + // If the config descr index in low-byte of + // setup->wValue is valid, send config descr, + // otherwise stall ep0. + if ((le16_to_cpu(setup->wValue) & 0xff) == 0) { + // send config descriptor! + if (desc_len <= USB_DT_CONFIG_SIZE) { + dbg("sending partial config desc, size=%d", + desc_len); + send_packet(dev, + alloc_packet(&dev->ep[0], + desc_len, + dev->conf_desc), + 0); + } else { + int len = dev->conf_desc->wTotalLength; + dbg("sending whole config desc," + " size=%d, our size=%d", desc_len, len); + desc_len = desc_len > len ? len : desc_len; + send_packet(dev, + alloc_packet(&dev->ep[0], + desc_len, + dev->full_conf_desc), + 0); + } + } else + endpoint_stall(&dev->ep[0]); + break; + case USB_DT_STRING: + // If the string descr index in low-byte of setup->wValue + // is valid, send string descr, otherwise stall ep0. + strnum = le16_to_cpu(setup->wValue) & 0xff; + if (strnum >= 0 && strnum < 6) { + struct usb_string_descriptor *desc = + dev->str_desc[strnum]; + desc_len = desc_len > desc->bLength ? + desc->bLength : desc_len; + dbg("sending string desc %d", strnum); + send_packet(dev, + alloc_packet(&dev->ep[0], desc_len, + desc), 0); + } else + endpoint_stall(&dev->ep[0]); + break; + default: + // Invalid request + err("invalid get desc=%d, stalled", + le16_to_cpu(setup->wValue) >> 8); + endpoint_stall(&dev->ep[0]); // Stall endpoint 0 + break; + } + + return STATUS_STAGE; +} + +static ep0_stage_t +do_set_descriptor(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // TODO: implement + // there will be an OUT data stage (the descriptor to set) + return DATA_STAGE; +} + +static ep0_stage_t +do_get_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // send dev->configuration + dbg("sending config"); + send_packet(dev, alloc_packet(&dev->ep[0], 1, &dev->configuration), + 0); + return STATUS_STAGE; +} + +static ep0_stage_t +do_set_configuration(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // set active config to low-byte of setup->wValue + dev->configuration = le16_to_cpu(setup->wValue) & 0xff; + dbg("set config, config=%d", dev->configuration); + if (!dev->configuration && dev->state > DEFAULT) { + dev->state = ADDRESS; + /* inform function layer of usbdev state change */ + dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data); + } else if (dev->configuration == 1) { + dev->state = CONFIGURED; + /* inform function layer of usbdev state change */ + dev->func_cb(CB_NEW_STATE, dev->state, dev->cb_data); + } else { + // FIXME: "respond with request error" - how? + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_get_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // interface must be zero. + if ((le16_to_cpu(setup->wIndex) & 0xff) || dev->state == ADDRESS) { + // FIXME: respond with "request error". how? + } else if (dev->state == CONFIGURED) { + // send dev->alternate_setting + dbg("sending alt setting"); + send_packet(dev, alloc_packet(&dev->ep[0], 1, + &dev->alternate_setting), 0); + } + + return STATUS_STAGE; + +} + +static ep0_stage_t +do_set_interface(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + if (dev->state == ADDRESS) { + // FIXME: respond with "request error". how? + } else if (dev->state == CONFIGURED) { + dev->interface = le16_to_cpu(setup->wIndex) & 0xff; + dev->alternate_setting = + le16_to_cpu(setup->wValue) & 0xff; + // interface and alternate_setting must be zero + if (dev->interface || dev->alternate_setting) { + // FIXME: respond with "request error". how? + } + } + + return SETUP_STAGE; +} + +static ep0_stage_t +do_synch_frame(struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + // TODO + return SETUP_STAGE; +} + +typedef ep0_stage_t (*req_method_t)(struct usb_dev* dev, + struct usb_ctrlrequest* setup); + + +/* Table of the standard device request handlers */ +static const req_method_t req_method[] = { + do_get_status, + do_clear_feature, + do_reserved, + do_set_feature, + do_reserved, + do_set_address, + do_get_descriptor, + do_set_descriptor, + do_get_configuration, + do_set_configuration, + do_get_interface, + do_set_interface, + do_synch_frame +}; + + +// SETUP packet request dispatcher +static void +do_setup (struct usb_dev* dev, struct usb_ctrlrequest* setup) +{ + req_method_t m; + + dbg(__FUNCTION__ ": req %d %s", setup->bRequestType, + get_std_req_name(setup->bRequestType)); + + if ((setup->bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD || + (setup->bRequestType & USB_RECIP_MASK) != USB_RECIP_DEVICE) { + err(__FUNCTION__ ": invalid requesttype 0x%02x", + setup->bRequestType); + return; + } + + if ((setup->bRequestType & 0x80) == USB_DIR_OUT && setup->wLength) + dbg(__FUNCTION__ ": OUT phase! length=%d", setup->wLength); + + if (setup->bRequestType < sizeof(req_method)/sizeof(req_method_t)) + m = req_method[setup->bRequestType]; + else + m = do_reserved; + + dev->ep0_stage = (*m)(dev, setup); +} + +/* + * A SETUP, DATA0, or DATA1 packet has been received + * on the default control endpoint's fifo. + */ +static void +process_ep0_receive (struct usb_dev* dev) +{ + endpoint_t *ep0 = &dev->ep[0]; + usbdev_pkt_t *pkt; + + spin_lock(&ep0->lock); + + // complete packet and prepare a new packet + pkt = receive_packet_complete(ep0); + if (!pkt) { + // FIXME: should put a warn/err here. + spin_unlock(&ep0->lock); + return; + } + + // unlink immediately from endpoint. + unlink_head(&ep0->outlist); + + // override current stage if h/w says it's a setup packet + if (pkt->status & PKT_STATUS_SU) + dev->ep0_stage = SETUP_STAGE; + + switch (dev->ep0_stage) { + case SETUP_STAGE: + vdbg("SU bit is %s in setup stage", + (pkt->status & PKT_STATUS_SU) ? "set" : "not set"); + + if (pkt->size == sizeof(struct usb_ctrlrequest)) { +#ifdef VDEBUG + if (pkt->status & PKT_STATUS_ACK) + vdbg("received SETUP"); + else + vdbg("received NAK SETUP"); +#endif + do_setup(dev, (struct usb_ctrlrequest*)pkt->payload); + } else + err(__FUNCTION__ ": wrong size SETUP received"); + break; + case DATA_STAGE: + /* + * this setup has an OUT data stage. Of the standard + * device requests, only set_descriptor has this stage, + * so this packet is that descriptor. TODO: drop it for + * now, set_descriptor not implemented. + * + * Need to place a byte in the write FIFO here, to prepare + * to send a zero-length DATA ack packet to the host in the + * STATUS stage. + */ + au_writel(0, ep0->reg->write_fifo); + dbg("received OUT stage DATAx on EP0, size=%d", pkt->size); + dev->ep0_stage = SETUP_STAGE; + break; + case STATUS_STAGE: + // this setup had an IN data stage, and host is ACK'ing + // the packet we sent during that stage. + if (pkt->size != 0) + warn("received non-zero ACK on EP0??"); +#ifdef VDEBUG + else + vdbg("received ACK on EP0"); +#endif + dev->ep0_stage = SETUP_STAGE; + break; + } + + spin_unlock(&ep0->lock); + // we're done processing the packet, free it + kfree(pkt); +} + + +/* + * A DATA0/1 packet has been received on one of the OUT endpoints (4 or 5) + */ +static void +process_ep_receive (struct usb_dev* dev, endpoint_t *ep) +{ + usbdev_pkt_t *pkt; + + spin_lock(&ep->lock); + pkt = receive_packet_complete(ep); + spin_unlock(&ep->lock); + + dev->func_cb(CB_PKT_COMPLETE, (unsigned long)pkt, dev->cb_data); +} + + + +/* This ISR handles the receive complete and suspend events */ +static void +req_sus_intr (int irq, void *dev_id, struct pt_regs *regs) +{ + struct usb_dev *dev = (struct usb_dev *) dev_id; + u32 status; + + status = au_readl(USBD_INTSTAT); + au_writel(status, USBD_INTSTAT); // ack'em + + if (status & (1<<0)) + process_ep0_receive(dev); + if (status & (1<<4)) + process_ep_receive(dev, &dev->ep[4]); + if (status & (1<<5)) + process_ep_receive(dev, &dev->ep[5]); +} + + +/* This ISR handles the DMA done events on EP0 */ +static void +dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct usb_dev *dev = (struct usb_dev *) dev_id; + usbdev_pkt_t* pkt; + endpoint_t *ep0 = &dev->ep[0]; + u32 cs0, buff_done; + + spin_lock(&ep0->lock); + cs0 = au_readl(ep0->reg->ctrl_stat); + + // first check packet transmit done + if ((buff_done = get_dma_buffer_done(ep0->indma)) != 0) { + // transmitted a DATAx packet during DATA stage + // on control endpoint 0 + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep0->indma); + if (buff_done & DMA_D1) + clear_dma_done1(ep0->indma); + + pkt = send_packet_complete(ep0); + if (pkt) + kfree(pkt); + } + + /* + * Now check packet receive done. Shouldn't get these, + * the receive packet complete intr should happen + * before the DMA done intr occurs. + */ + if ((buff_done = get_dma_buffer_done(ep0->outdma)) != 0) { + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep0->outdma); + if (buff_done & DMA_D1) + clear_dma_done1(ep0->outdma); + + //process_ep0_receive(dev); + } + + spin_unlock(&ep0->lock); +} + +/* This ISR handles the DMA done events on endpoints 2,3,4,5 */ +static void +dma_done_ep_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct usb_dev *dev = (struct usb_dev *) dev_id; + int i; + + for (i = 2; i < 6; i++) { + u32 buff_done; + usbdev_pkt_t* pkt; + endpoint_t *ep = &dev->ep[i]; + + if (!ep->active) continue; + + spin_lock(&ep->lock); + + if (ep->direction == USB_DIR_IN) { + buff_done = get_dma_buffer_done(ep->indma); + if (buff_done != 0) { + // transmitted a DATAx pkt on the IN ep + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep->indma); + if (buff_done & DMA_D1) + clear_dma_done1(ep->indma); + + pkt = send_packet_complete(ep); + + spin_unlock(&ep->lock); + dev->func_cb(CB_PKT_COMPLETE, + (unsigned long)pkt, + dev->cb_data); + spin_lock(&ep->lock); + } + } else { + /* + * Check packet receive done (OUT ep). Shouldn't get + * these, the rx packet complete intr should happen + * before the DMA done intr occurs. + */ + buff_done = get_dma_buffer_done(ep->outdma); + if (buff_done != 0) { + // received a DATAx pkt on the OUT ep + // clear DMA done bit + if (buff_done & DMA_D0) + clear_dma_done0(ep->outdma); + if (buff_done & DMA_D1) + clear_dma_done1(ep->outdma); + + //process_ep_receive(dev, ep); + } + } + + spin_unlock(&ep->lock); + } +} + + +/*************************************************************************** + * Here begins the external interface functions + *************************************************************************** + */ + +/* + * allocate a new packet + */ +int +usbdev_alloc_packet(int ep_addr, int data_size, usbdev_pkt_t** pkt) +{ + endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr); + usbdev_pkt_t* lpkt = NULL; + + if (!ep || !ep->active || ep->address < 2) + return -ENODEV; + if (data_size > ep->max_pkt_size) + return -EINVAL; + + lpkt = *pkt = alloc_packet(ep, data_size, NULL); + if (!lpkt) + return -ENOMEM; + return 0; +} + + +/* + * packet send + */ +int +usbdev_send_packet(int ep_addr, usbdev_pkt_t * pkt) +{ + unsigned long flags; + int count; + endpoint_t * ep; + + if (!pkt || !(ep = epaddr_to_ep(&usbdev, pkt->ep_addr)) || + !ep->active || ep->address < 2) + return -ENODEV; + if (ep->direction != USB_DIR_IN) + return -EINVAL; + + spin_lock_irqsave(&ep->lock, flags); + count = send_packet(&usbdev, pkt, 1); + spin_unlock_irqrestore(&ep->lock, flags); + + return count; +} + +/* + * packet receive + */ +int +usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt) +{ + unsigned long flags; + usbdev_pkt_t* lpkt = NULL; + endpoint_t *ep = epaddr_to_ep(&usbdev, ep_addr); + + if (!ep || !ep->active || ep->address < 2) + return -ENODEV; + if (ep->direction != USB_DIR_OUT) + return -EINVAL; + + spin_lock_irqsave(&ep->lock, flags); + if (ep->outlist.count > 1) + lpkt = unlink_head(&ep->outlist); + spin_unlock_irqrestore(&ep->lock, flags); + + if (!lpkt) { + /* no packet available */ + *pkt = NULL; + return -ENODATA; + } + + *pkt = lpkt; + + return lpkt->size; +} + + +/* + * return total queued byte count on the endpoint. + */ +int +usbdev_get_byte_count(int ep_addr) +{ + unsigned long flags; + pkt_list_t *list; + usbdev_pkt_t *scan; + int count = 0; + endpoint_t * ep = epaddr_to_ep(&usbdev, ep_addr); + + if (!ep || !ep->active || ep->address < 2) + return -ENODEV; + + if (ep->direction == USB_DIR_IN) { + list = &ep->inlist; + + spin_lock_irqsave(&ep->lock, flags); + for (scan = list->head; scan; scan = scan->next) + count += scan->size; + spin_unlock_irqrestore(&ep->lock, flags); + } else { + list = &ep->outlist; + + spin_lock_irqsave(&ep->lock, flags); + if (list->count > 1) { + for (scan = list->head; scan != list->tail; + scan = scan->next) + count += scan->size; + } + spin_unlock_irqrestore(&ep->lock, flags); + } + + return count; +} + + +void +usbdev_exit(void) +{ + endpoint_t *ep; + int i; + + au_writel(0, USBD_INTEN); // disable usb dev ints + au_writel(0, USBD_ENABLE); // disable usb dev + + free_irq(AU1000_USB_DEV_REQ_INT, &usbdev); + free_irq(AU1000_USB_DEV_SUS_INT, &usbdev); + + // free all control endpoint resources + ep = &usbdev.ep[0]; + free_au1000_dma(ep->indma); + free_au1000_dma(ep->outdma); + endpoint_flush(ep); + + // free ep resources + for (i = 2; i < 6; i++) { + ep = &usbdev.ep[i]; + if (!ep->active) continue; + + if (ep->direction == USB_DIR_IN) { + free_au1000_dma(ep->indma); + } else { + free_au1000_dma(ep->outdma); + } + endpoint_flush(ep); + } + + if (usbdev.full_conf_desc) + kfree(usbdev.full_conf_desc); +} + +int +usbdev_init(struct usb_device_descriptor* dev_desc, + struct usb_config_descriptor* config_desc, + struct usb_interface_descriptor* if_desc, + struct usb_endpoint_descriptor* ep_desc, + struct usb_string_descriptor* str_desc[], + void (*cb)(usbdev_cb_type_t, unsigned long, void *), + void* cb_data) +{ + endpoint_t *ep0; + int i, ret=0; + u8* fcd; + + if (dev_desc->bNumConfigurations > 1 || + config_desc->bNumInterfaces > 1 || + if_desc->bNumEndpoints > 4) { + err("Only one config, one i/f, and no more " + "than 4 ep's allowed"); + ret = -EINVAL; + goto out; + } + + if (!cb) { + err("Function-layer callback required"); + ret = -EINVAL; + goto out; + } + + if (dev_desc->bMaxPacketSize0 != USBDEV_EP0_MAX_PACKET_SIZE) { + warn("EP0 Max Packet size must be %d", + USBDEV_EP0_MAX_PACKET_SIZE); + dev_desc->bMaxPacketSize0 = USBDEV_EP0_MAX_PACKET_SIZE; + } + + memset(&usbdev, 0, sizeof(struct usb_dev)); + + usbdev.state = DEFAULT; + usbdev.dev_desc = dev_desc; + usbdev.if_desc = if_desc; + usbdev.conf_desc = config_desc; + for (i=0; i<6; i++) + usbdev.str_desc[i] = str_desc[i]; + usbdev.func_cb = cb; + usbdev.cb_data = cb_data; + + /* Initialize default control endpoint */ + ep0 = &usbdev.ep[0]; + ep0->active = 1; + ep0->type = CONTROL_EP; + ep0->max_pkt_size = USBDEV_EP0_MAX_PACKET_SIZE; + spin_lock_init(&ep0->lock); + ep0->desc = NULL; // ep0 has no descriptor + ep0->address = 0; + ep0->direction = 0; + ep0->reg = &ep_reg[0]; + + /* Initialize the other requested endpoints */ + for (i = 0; i < if_desc->bNumEndpoints; i++) { + struct usb_endpoint_descriptor* epd = &ep_desc[i]; + endpoint_t *ep; + + if ((epd->bEndpointAddress & 0x80) == USB_DIR_IN) { + ep = &usbdev.ep[2]; + ep->address = 2; + if (ep->active) { + ep = &usbdev.ep[3]; + ep->address = 3; + if (ep->active) { + err("too many IN ep's requested"); + ret = -ENODEV; + goto out; + } + } + } else { + ep = &usbdev.ep[4]; + ep->address = 4; + if (ep->active) { + ep = &usbdev.ep[5]; + ep->address = 5; + if (ep->active) { + err("too many OUT ep's requested"); + ret = -ENODEV; + goto out; + } + } + } + + ep->active = 1; + epd->bEndpointAddress &= ~0x0f; + epd->bEndpointAddress |= (u8)ep->address; + ep->direction = epd->bEndpointAddress & 0x80; + ep->type = epd->bmAttributes & 0x03; + ep->max_pkt_size = epd->wMaxPacketSize; + spin_lock_init(&ep->lock); + ep->desc = epd; + ep->reg = &ep_reg[ep->address]; + } + + /* + * initialize the full config descriptor + */ + usbdev.full_conf_desc = fcd = kmalloc(config_desc->wTotalLength, + ALLOC_FLAGS); + if (!fcd) { + err("failed to alloc full config descriptor"); + ret = -ENOMEM; + goto out; + } + + memcpy(fcd, config_desc, USB_DT_CONFIG_SIZE); + fcd += USB_DT_CONFIG_SIZE; + memcpy(fcd, if_desc, USB_DT_INTERFACE_SIZE); + fcd += USB_DT_INTERFACE_SIZE; + for (i = 0; i < if_desc->bNumEndpoints; i++) { + memcpy(fcd, &ep_desc[i], USB_DT_ENDPOINT_SIZE); + fcd += USB_DT_ENDPOINT_SIZE; + } + + /* Now we're ready to enable the controller */ + au_writel(0x0002, USBD_ENABLE); + udelay(100); + au_writel(0x0003, USBD_ENABLE); + udelay(100); + + /* build and send config table based on ep descriptors */ + for (i = 0; i < 6; i++) { + endpoint_t *ep; + if (i == 1) + continue; // skip dummy ep + ep = &usbdev.ep[i]; + if (ep->active) { + au_writel((ep->address << 4) | 0x04, USBD_CONFIG); + au_writel(((ep->max_pkt_size & 0x380) >> 7) | + (ep->direction >> 4) | (ep->type << 4), + USBD_CONFIG); + au_writel((ep->max_pkt_size & 0x7f) << 1, USBD_CONFIG); + au_writel(0x00, USBD_CONFIG); + au_writel(ep->address, USBD_CONFIG); + } else { + u8 dir = (i==2 || i==3) ? DIR_IN : DIR_OUT; + au_writel((i << 4) | 0x04, USBD_CONFIG); + au_writel(((16 & 0x380) >> 7) | dir | + (BULK_EP << 4), USBD_CONFIG); + au_writel((16 & 0x7f) << 1, USBD_CONFIG); + au_writel(0x00, USBD_CONFIG); + au_writel(i, USBD_CONFIG); + } + } + + /* + * Enable Receive FIFO Complete interrupts only. Transmit + * complete is being handled by the DMA done interrupts. + */ + au_writel(0x31, USBD_INTEN); + + /* + * Controller is now enabled, request DMA and IRQ + * resources. + */ + + /* request the USB device transfer complete interrupt */ + if (request_irq(AU1000_USB_DEV_REQ_INT, req_sus_intr, SA_INTERRUPT, + "USBdev req", &usbdev)) { + err("Can't get device request intr"); + ret = -ENXIO; + goto out; + } + /* request the USB device suspend interrupt */ + if (request_irq(AU1000_USB_DEV_SUS_INT, req_sus_intr, SA_INTERRUPT, + "USBdev sus", &usbdev)) { + err("Can't get device suspend intr"); + ret = -ENXIO; + goto out; + } + + /* Request EP0 DMA and IRQ */ + if ((ep0->indma = request_au1000_dma(ep_dma_id[0].id, + ep_dma_id[0].str, + dma_done_ep0_intr, + SA_INTERRUPT, + &usbdev)) < 0) { + err("Can't get %s DMA", ep_dma_id[0].str); + ret = -ENXIO; + goto out; + } + if ((ep0->outdma = request_au1000_dma(ep_dma_id[1].id, + ep_dma_id[1].str, + NULL, 0, NULL)) < 0) { + err("Can't get %s DMA", ep_dma_id[1].str); + ret = -ENXIO; + goto out; + } + + // Flush the ep0 buffers and FIFOs + endpoint_flush(ep0); + // start packet reception on ep0 + kickstart_receive_packet(ep0); + + /* Request DMA and IRQ for the other endpoints */ + for (i = 2; i < 6; i++) { + endpoint_t *ep = &usbdev.ep[i]; + if (!ep->active) + continue; + + // Flush the endpoint buffers and FIFOs + endpoint_flush(ep); + + if (ep->direction == USB_DIR_IN) { + ep->indma = + request_au1000_dma(ep_dma_id[ep->address].id, + ep_dma_id[ep->address].str, + dma_done_ep_intr, + SA_INTERRUPT, + &usbdev); + if (ep->indma < 0) { + err("Can't get %s DMA", + ep_dma_id[ep->address].str); + ret = -ENXIO; + goto out; + } + } else { + ep->outdma = + request_au1000_dma(ep_dma_id[ep->address].id, + ep_dma_id[ep->address].str, + NULL, 0, NULL); + if (ep->outdma < 0) { + err("Can't get %s DMA", + ep_dma_id[ep->address].str); + ret = -ENXIO; + goto out; + } + + // start packet reception on OUT endpoint + kickstart_receive_packet(ep); + } + } + + out: + if (ret) + usbdev_exit(); + return ret; +} + +EXPORT_SYMBOL(usbdev_init); +EXPORT_SYMBOL(usbdev_exit); +EXPORT_SYMBOL(usbdev_alloc_packet); +EXPORT_SYMBOL(usbdev_receive_packet); +EXPORT_SYMBOL(usbdev_send_packet); +EXPORT_SYMBOL(usbdev_get_byte_count); diff -Nru a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/db1x00/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,20 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor PB1000 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +.S.s: + $(CPP) $(CFLAGS) $< -o $*.s +.S.o: + $(CC) $(CFLAGS) -c $< -o $*.o + +O_TARGET := db1x00.o + +obj-y := init.o setup.o diff -Nru a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/db1x00/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,73 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PB1000 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <linux/config.h> +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Alchemy Db1000"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_DB1000; /* set the platform # */ + prom_init_cmdline(); + + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -Nru a/arch/mips/au1000/db1x00/setup.c b/arch/mips/au1000/db1x00/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/db1x00/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,230 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Db1000 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/console.h> +#include <linux/mc146818rtc.h> +#include <linux/delay.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/keyboard.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/pgtable.h> +#include <asm/au1000.h> +#include <asm/db1x00.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +extern struct rtc_ops no_rtc_ops; +extern char * __init prom_getcmdline(void); +extern void au1000_restart(char *); +extern void au1000_halt(void); +extern void au1000_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); +static phys_t db_fixup_bigphys_addr(phys_t phys_addr, phys_t size); +#endif + +void __init au1x00_setup(void) +{ + char *argptr; + u32 pin_func, static_cfg0; + u32 sys_freqctrl, sys_clksrc; + u32 prid = read_c0_prid(); + + argptr = prom_getcmdline(); + + /* Various early Au1000 Errata corrected by this */ + set_c0_config(1<<19); /* Config[OD] */ + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + +#ifdef CONFIG_FB_AU1100 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + /* default panel */ + //strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); + strcat(argptr, " video=au1100fb:panel:s10,nohwcursor"); + } +#endif + +#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) + // au1000 does not support vra, au1500 and au1100 do + strcat(argptr, " au1000_audio=vra"); + argptr = prom_getcmdline(); +#endif + + rtc_ops = &no_rtc_ops; + _machine_restart = au1000_restart; + _machine_halt = au1000_halt; + _machine_power_off = au1000_power_off; +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) + fixup_bigphys_addr = db_fixup_bigphys_addr; +#endif + + // IO/MEM resources. + set_io_port_base(0); +#ifdef CONFIG_SOC_AU1500 + ioport_resource.start = 0x00000000; +#else + /* don't allow any legacy ports probing */ + ioport_resource.start = 0x10000000; +#endif + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x10000000; + iomem_resource.end = 0xffffffff; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + // + // NOTE: + // + // YAMON (specifically reset_db1500.s) enables 32khz osc + // YAMON (specifically reset_db1x00.s) setups all clocking and GPIOs + // YAMON (specifically reset_db1500.s) setups all PCI + // + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + +#ifdef CONFIG_USB_OHCI + // enable host controller and wait for reset done + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0E, USB_HOST_CONFIG); + udelay(1000); + au_readl(USB_HOST_CONFIG); // throw away first read + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + au_readl(USB_HOST_CONFIG); +#endif + +#ifdef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB device + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); + au_writel(pin_func, SYS_PINFUNC); +#endif + +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + +#ifdef CONFIG_FB + // Needed if PCI video card in use + conswitchp = &dummy_con; +#endif + +#ifndef CONFIG_SERIAL_NONSTANDARD + /* don't touch the default serial console */ + au_writel(0, UART_ADDR + UART_CLK); +#endif + //au_writel(0, UART3_ADDR + UART_CLK); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + +#if 0 + //// FIX!!! must be valid for au1000, au1500 and au1100 + /* Enable Au1000 BCLK switching */ + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + break; + default: /* HC and newer */ + au_writel(0x00000060, 0xb190003c); + break; + } +#endif + + au_writel(0, 0xAE000010); /* turn off pcmcia power */ + +#ifdef CONFIG_MIPS_DB1000 + printk("AMD Alchemy Au1000/Db1000 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1500 + printk("AMD Alchemy Au1500/Db1500 Board\n"); +#endif +#ifdef CONFIG_MIPS_DB1100 + printk("AMD Alchemy Au1100/Db1100 Board\n"); +#endif +} + +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500) +static phys_t db_fixup_bigphys_addr(phys_t phys_addr, phys_t size) +{ + u32 pci_start = (u32)Au1500_PCI_MEM_START; + u32 pci_end = (u32)Au1500_PCI_MEM_END; + + /* Don't fixup 36 bit addresses */ + if ((phys_addr >> 32) != 0) return phys_addr; + + /* check for pci memory window */ + if ((phys_addr >= pci_start) && ((phys_addr + size) < pci_end)) { + return (phys_t)((phys_addr - pci_start) + + Au1500_PCI_MEM_START); + } + else + return phys_addr; +} +#endif diff -Nru a/arch/mips/au1000/pb1000/Makefile b/arch/mips/au1000/pb1000/Makefile --- a/arch/mips/au1000/pb1000/Makefile Fri Jun 27 14:20:00 2003 +++ b/arch/mips/au1000/pb1000/Makefile Fri Jun 27 14:20:00 2003 @@ -5,5 +5,13 @@ # # Makefile for the Alchemy Semiconductor PB1000 board. # +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := pb1000.o obj-y := init.o setup.o diff -Nru a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c --- a/arch/mips/au1000/pb1000/init.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/au1000/pb1000/init.c Fri Jun 27 14:19:54 2003 @@ -33,27 +33,39 @@ #include <linux/bootmem.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> -#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/sched.h> -extern int prom_argc; -extern char **prom_argv, **prom_envp; +int prom_argc; +char **prom_argv, **prom_envp; extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Alchemy Pb1000"; +} int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) { + unsigned char *memsize_str; + unsigned long memsize; + prom_argc = argc; prom_argv = argv; prom_envp = envp; mips_machgroup = MACH_GROUP_ALCHEMY; - mips_machtype = MACH_PB1000; + mips_machtype = MACH_PB1000; prom_init_cmdline(); - - add_memory_region(1, 64 << 20, BOOT_MEM_RAM); - + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); return 0; } diff -Nru a/arch/mips/au1000/pb1000/setup.c b/arch/mips/au1000/pb1000/setup.c --- a/arch/mips/au1000/pb1000/setup.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/au1000/pb1000/setup.c Fri Jun 27 14:20:01 2003 @@ -1,7 +1,7 @@ /* * * BRIEF MODULE DESCRIPTION - * Au1000-based board setup. + * Alchemy Pb1000 board setup. * * Copyright 2000 MontaVista Software Inc. * Author: MontaVista Software, Inc. @@ -31,88 +31,271 @@ #include <linux/init.h> #include <linux/sched.h> #include <linux/ioport.h> +#include <linux/mm.h> #include <linux/console.h> #include <linux/mc146818rtc.h> +#include <linux/major.h> +#include <linux/kdev_t.h> #include <linux/root_dev.h> +#include <linux/delay.h> #include <asm/cpu.h> #include <asm/bootinfo.h> #include <asm/irq.h> #include <asm/mipsregs.h> #include <asm/reboot.h> +#include <asm/pgtable.h> #include <asm/au1000.h> +#include <asm/pb1000.h> -#if defined(CONFIG_AU1000_SERIAL_CONSOLE) -extern void console_setup(char *, int *); +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) char serial_console[20]; #endif -void (*__wbflush) (void); +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + extern struct rtc_ops no_rtc_ops; extern char * __init prom_getcmdline(void); -extern void au1000_restart(void); +extern void au1000_restart(char *); extern void au1000_halt(void); extern void au1000_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; -struct { - struct resource ram; - struct resource io; - struct resource sram; - struct resource flash; - struct resource boot; - struct resource pcmcia; - struct resource lcd; -} au1000_resources = { - { "RAM", 0, 0x3FFFFFF, IORESOURCE_MEM }, - { "I/O", 0x10000000, 0x119FFFFF }, - { "SRAM", 0x1e000000, 0x1E03FFFF }, - { "System Flash", 0x1F800000, 0x1FBFFFFF }, - { "Boot ROM", 0x1FC00000, 0x1FFFFFFF }, - { "PCMCIA", 0x20000000, 0x27FFFFFF }, - { "LCD", 0x60000000, 0x603FFFFF }, -}; - -void au1000_wbflush(void) -{ - __asm__ volatile ("sync"); -} - -void __init au1000_setup(void) +void __init au1x00_setup(void) { char *argptr; + u32 pin_func, static_cfg0; + u32 sys_freqctrl, sys_clksrc; + u32 prid = read_c0_prid(); argptr = prom_getcmdline(); -#ifdef CONFIG_AU1000_SERIAL_CONSOLE - if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { + /* Various early Au1000 Errata corrected by this */ + set_c0_config(1<<19); /* Config[OD] */ + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if ((argptr = strstr(argptr, "console=")) == NULL) { argptr = prom_getcmdline(); strcat(argptr, " console=ttyS0,115200"); } -#endif +#endif - //set_cp0_status(ST0_FR,0); rtc_ops = &no_rtc_ops; - __wbflush = au1000_wbflush; _machine_restart = au1000_restart; _machine_halt = au1000_halt; _machine_power_off = au1000_power_off; - /* - * IO/MEM resources. - */ - mips_io_port_base = KSEG1; - ioport_resource.start = au1000_resources.io.start; - ioport_resource.end = au1000_resources.lcd.end; + // IO/MEM resources. + set_io_port_base(0); + ioport_resource.start = 0x10000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x10000000; + iomem_resource.end = 0xffffffff; #ifdef CONFIG_BLK_DEV_INITRD ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; #endif - outl(PC_CNTRL_E0 | PC_CNTRL_EN0 | PC_CNTRL_EN0, PC_COUNTER_CNTRL); - while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T0S); - outl(0x8000-1, PC0_TRIM); + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif - printk("Alchemy Semi PB1000 Board\n"); - printk("Au1000/PB1000 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); -} + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + /* CPU core freq to 48MHz to slow it way down... */ + au_writel(4, SYS_CPUPLL); + + /* + * Setup 48MHz FREQ2 from CPUPLL for USB Host + */ + /* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */ + sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* CPU core freq to 384MHz */ + au_writel(0x20, SYS_CPUPLL); + + printk("Au1000: 48MHz OHCI workaround enabled\n"); + break; + + default: /* HC and newer */ + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + break; + } + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); +#ifdef CONFIG_USB_OHCI + // enable host controller and wait for reset done + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0E, USB_HOST_CONFIG); + udelay(1000); + au_readl(USB_HOST_CONFIG); // throw away first read + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + au_readl(USB_HOST_CONFIG); +#endif + + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080); + +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); + au_writel(0x2800, SYS_TRIOUTCLR); + au_writel(0x0030, SYS_OUTPUTCLR); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + // make gpio 15 an input (for interrupt line) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100); + // we don't need I2S, so make it available for GPIO[31:29] + pin_func |= (1<<5); + au_writel(pin_func, SYS_PINFUNC); + + au_writel(0x8000, SYS_TRIOUTCLR); + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00); + au_writel(static_cfg0, MEM_STCFG0); + + // configure RCE2* for LCD + au_writel(0x00000004, MEM_STCFG2); + + // MEM_STTIME2 + au_writel(0x09000000, MEM_STTIME2); + + // Set 32-bit base address decoding for RCE2* + au_writel(0x10003ff0, MEM_STADDR2); + + // PCI CPLD setup + // expand CE0 to cover PCI + au_writel(0x11803e40, MEM_STADDR1); + + // burst visibility on + au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0); + + au_writel(0x83, MEM_STCFG1); // ewait enabled, flash timing + au_writel(0x33030a10, MEM_STTIME1); // slower timing for FPGA + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + +#ifdef CONFIG_FB_E1356 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1"); + } +#endif // CONFIG_FB_E1356 + + +#ifdef CONFIG_PCI + au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 + au_writel(0, SDRAM_MBAR); // set mbar to 0 + au_writel(0x2, SDRAM_CMD); // enable memory accesses + au_sync_delay(1); +#endif + +#ifndef CONFIG_SERIAL_NONSTANDARD + /* don't touch the default serial console */ + au_writel(0, UART0_ADDR + UART_CLK); +#endif + au_writel(0, UART1_ADDR + UART_CLK); + au_writel(0, UART2_ADDR + UART_CLK); + au_writel(0, UART3_ADDR + UART_CLK); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + // setup irda clocks + // aux clock, divide by 2, clock from 2/4 divider + au_writel(au_readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC); + pin_func = au_readl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD + au_writel(pin_func, SYS_PINFUNC); + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); + au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); + au_writel(0, SYS_TOYTRIM); + + /* Enable Au1000 BCLK switching - note: sed1356 must not use + * its BCLK (Au1000 LCLK) for any timings */ + switch (prid & 0x000000FF) + { + case 0x00: /* DA */ + case 0x01: /* HA */ + case 0x02: /* HB */ + break; + default: /* HC and newer */ + au_writel(0x00000060, 0xb190003c); + break; + } +} diff -Nru a/arch/mips/au1000/pb1100/Makefile b/arch/mips/au1000/pb1100/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/pb1100/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,17 @@ +# +# Copyright 2000,2001 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor Pb1100 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +USE_STANDARD_AS_RULE := true + +O_TARGET := pb1100.o + +obj-y := init.o setup.o diff -Nru a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/pb1100/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,73 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Pb1100 board setup + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <linux/config.h> +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Alchemy Pb1100"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_PB1100; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -Nru a/arch/mips/au1000/pb1100/setup.c b/arch/mips/au1000/pb1100/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/pb1100/setup.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,248 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1100 board setup. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/console.h> +#include <linux/mc146818rtc.h> +#include <linux/delay.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/pgtable.h> +#include <asm/au1000.h> +#include <asm/pb1100.h> + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) +extern void console_setup(char *, int *); +char serial_console[20]; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops pb1500_rtc_ops; +#endif + +extern char * __init prom_getcmdline(void); +extern void au1000_restart(char *); +extern void au1000_halt(void); +extern void au1000_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; + + +void __init au1x00_setup(void) +{ + char *argptr; + u32 pin_func, static_cfg0; + u32 sys_freqctrl, sys_clksrc; + + argptr = prom_getcmdline(); + + /* NOTE: The memory map is established by YAMON 2.08+ */ + + /* Various early Au1000 Errata corrected by this */ + set_c0_config(1<<19); /* Config[OD] */ + +#ifdef CONFIG_AU1X00_SERIAL_CONSOLE + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + +#ifdef CONFIG_SOUND_AU1X00 + strcat(argptr, " au1000_audio=vra"); + argptr = prom_getcmdline(); +#endif + + _machine_restart = au1000_restart; + _machine_halt = au1000_halt; + _machine_power_off = au1000_power_off; + + // IO/MEM resources. + set_io_port_base(0); + ioport_resource.start = 0x10000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x10000000; + iomem_resource.end = 0xffffffff; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PININPUTEN); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + // configure pins GPIO[14:9] as GPIO + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x80); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD/IrDA clock */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x0000001F; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USBH/USBD/IrDA + */ + sys_clksrc |= ((4<<2) | (0<<1) | 0 ); + au_writel(sys_clksrc, SYS_CLKSRC); + + /* setup the static bus controller */ + au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */ + au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */ + au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */ + + // get USB Functionality pin state (device vs host drive pins) + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + +#ifdef CONFIG_USB_OHCI + // enable host controller and wait for reset done + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0c, USB_HOST_CONFIG); + udelay(1000); + au_readl(USB_HOST_CONFIG); + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + ; + au_readl(USB_HOST_CONFIG); +#endif + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_FB_AU1100 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + /* default panel */ + strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16"); + } +#endif + +#ifdef CONFIG_FB_E1356 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=e1356fb:system:pb1500"); + } +#endif + +#ifndef CONFIG_SERIAL_NONSTANDARD + /* don't touch the default serial console */ + au_writel(0, UART0_ADDR + UART_CLK); +#endif + au_writel(0, UART1_ADDR + UART_CLK); + au_writel(0, UART3_ADDR + UART_CLK); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); + au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); + au_writel(0, SYS_TOYTRIM); + + au_writel(0x00000060, 0xb190003c); + +#ifdef CONFIG_RTC + rtc_ops = &pb1500_rtc_ops; + // Enable the RTC if not already enabled + if (!(readb(0xac000028) & 0x20)) { + writeb(readb(0xac000028) | 0x20, 0xac000028); + au_sync(); + } + // Put the clock in BCD mode + if (readb(0xac00002C) & 0x4) { /* reg B */ + writeb(readb(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} diff -Nru a/arch/mips/au1000/pb1500/Makefile b/arch/mips/au1000/pb1500/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/pb1500/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,13 @@ +# +# Copyright 2000,2001 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Alchemy Semiconductor Pb1500 board. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +lib-y := init.o setup.o diff -Nru a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/pb1500/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,71 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * PB1500 board setup + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Alchemy Pb1500"; +} + +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + unsigned char *memsize_str; + unsigned long memsize; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_ALCHEMY; + mips_machtype = MACH_PB1500; + + prom_init_cmdline(); + memsize_str = prom_getenv("memsize"); + if (!memsize_str) { + memsize = 0x04000000; + } else { + memsize = simple_strtol(memsize_str, NULL, 0); + } + add_memory_region(0, memsize, BOOT_MEM_RAM); + return 0; +} diff -Nru a/arch/mips/au1000/pb1500/setup.c b/arch/mips/au1000/pb1500/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/au1000/pb1500/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,293 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Alchemy Pb1000 board setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mm.h> +#include <linux/console.h> +#include <linux/mc146818rtc.h> +#include <linux/delay.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/cpu.h> +#include <asm/time.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/pgtable.h> +#include <asm/au1000.h> +#include <asm/pb1500.h> + +#ifdef CONFIG_USB_OHCI +// Enable the workaround for the OHCI DoneHead +// register corruption problem. +#define CONFIG_AU1000_OHCI_FIX +#endif + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +#ifdef CONFIG_RTC +extern struct rtc_ops pb1500_rtc_ops; +#endif + +extern char * __init prom_getcmdline(void); +extern void __init au1x_time_init(void); +extern void __init au1x_timer_setup(struct irqaction *irq); +extern void au1000_restart(char *); +extern void au1000_halt(void); +extern void au1000_power_off(void); +extern struct resource ioport_resource; +extern struct resource iomem_resource; +#ifdef CONFIG_64BIT_PHYS_ADDR +extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); +static phys_t pb1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size); +#endif + + +void __init au1x00_setup(void) +{ + char *argptr; + u32 pin_func, static_cfg0; + u32 sys_freqctrl, sys_clksrc; + + argptr = prom_getcmdline(); + + /* NOTE: The memory map is established by YAMON 2.08+ */ + + /* Various early Au1500 Errata corrected by this */ + set_c0_config(1<<19); /* Config[OD] */ + + board_time_init = au1x_time_init; + board_timer_setup = au1x_timer_setup; + +#ifdef CONFIG_SERIAL_AU1X00_CONSOLE + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + +#ifdef CONFIG_SOUND_AU1X00 + strcat(argptr, " au1000_audio=vra"); + argptr = prom_getcmdline(); +#endif + + _machine_restart = au1000_restart; + _machine_halt = au1000_halt; + _machine_power_off = au1000_power_off; +#ifdef CONFIG_64BIT_PHYS_ADDR + fixup_bigphys_addr = pb1500_fixup_bigphys_addr; +#endif + + // IO/MEM resources. + set_io_port_base(0); + ioport_resource.start = 0x00000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x10000000; + iomem_resource.end = 0xffffffff; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + // set AUX clock to 12MHz * 8 = 96 MHz + au_writel(8, SYS_AUXPLL); + au_writel(0, SYS_PINSTATERD); + udelay(100); + +#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) +#ifdef CONFIG_USB_OHCI + if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { + char usb_args[80]; + argptr = prom_getcmdline(); + memset(usb_args, 0, sizeof(usb_args)); + sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", + USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); + strcat(argptr, usb_args); + } +#endif + + /* GPIO201 is input for PCMCIA card detect */ + /* GPIO203 is input for PCMCIA interrupt request */ + au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR); + + /* zero and disable FREQ2 */ + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* zero and disable USBH/USBD clocks */ + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + au_writel(sys_clksrc, SYS_CLKSRC); + + sys_freqctrl = au_readl(SYS_FREQCTRL0); + sys_freqctrl &= ~0xFFF00000; + + sys_clksrc = au_readl(SYS_CLKSRC); + sys_clksrc &= ~0x00007FE0; + + // FREQ2 = aux/2 = 48 MHz + sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); + au_writel(sys_freqctrl, SYS_FREQCTRL0); + + /* + * Route 48MHz FREQ2 into USB Host and/or Device + */ +#ifdef CONFIG_USB_OHCI + sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); +#endif +#ifdef CONFIG_AU1X00_USB_DEVICE + sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); +#endif + au_writel(sys_clksrc, SYS_CLKSRC); + + + pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); +#ifndef CONFIG_AU1X00_USB_DEVICE + // 2nd USB port is USB host + pin_func |= 0x8000; +#endif + au_writel(pin_func, SYS_PINFUNC); +#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) + + +#ifdef CONFIG_USB_OHCI + // enable host controller and wait for reset done + au_writel(0x08, USB_HOST_CONFIG); + udelay(1000); + au_writel(0x0c, USB_HOST_CONFIG); + udelay(1000); + au_readl(USB_HOST_CONFIG); + while (!(au_readl(USB_HOST_CONFIG) & 0x10)) + ; + au_readl(USB_HOST_CONFIG); +#endif + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_FB_E1356 + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=e1356fb:system:pb1500"); + } +#elif defined (CONFIG_FB_XPERT98) + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=atyfb:1024x768-8@70"); + } +#endif // CONFIG_FB_E1356 + +#ifndef CONFIG_SERIAL_AU1X00_CONSOLE + /* don't touch the default serial console */ + au_writel(0, UART0_ADDR + UART_CLK); +#endif + au_writel(0, UART3_ADDR + UART_CLK); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + +#ifdef CONFIG_PCI + // Setup PCI bus controller + au_writel(0, Au1500_PCI_CMEM); + au_writel(0x00003fff, Au1500_CFG_BASE); +#if defined(__MIPSEB__) + au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); +#else + au_writel(0xf, Au1500_PCI_CFG); +#endif + au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); + au_writel(0, Au1500_PCI_MWBASE_REV_CCL); + au_writel(0x02a00356, Au1500_PCI_STATCMD); + au_writel(0x00003c04, Au1500_PCI_HDRTYPE); + au_writel(0x00000008, Au1500_PCI_MBAR); + au_sync(); +#endif + + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); + au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); + au_sync(); + while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); + au_writel(0, SYS_TOYTRIM); + + /* Enable BCLK switching */ + au_writel(0x00000060, 0xb190003c); + +#ifdef CONFIG_RTC + rtc_ops = &pb1500_rtc_ops; + // Enable the RTC if not already enabled + if (!(au_readl(0xac000028) & 0x20)) { + printk("enabling clock ...\n"); + au_writel((au_readl(0xac000028) | 0x20), 0xac000028); + } + // Put the clock in BCD mode + if (readl(0xac00002C) & 0x4) { /* reg B */ + au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); + au_sync(); + } +#endif +} + +#ifdef CONFIG_64BIT_PHYS_ADDR +static phys_t pb1500_fixup_bigphys_addr(phys_t phys_addr, + phys_t size) +{ + u32 pci_start = (u32)Au1500_PCI_MEM_START; + u32 pci_end = (u32)Au1500_PCI_MEM_END; + + /* Don't fixup 36 bit addresses */ + if ((phys_addr >> 32) != 0) return phys_addr; + + /* check for pci memory window */ + if ((phys_addr >= pci_start) && ((phys_addr + size) < pci_end)) { + return (phys_t)((phys_addr - pci_start) + + Au1500_PCI_MEM_START); + } + else + return phys_addr; +} +#endif diff -Nru a/arch/mips/baget/Makefile b/arch/mips/baget/Makefile --- a/arch/mips/baget/Makefile Fri Jun 27 14:20:06 2003 +++ b/arch/mips/baget/Makefile Fri Jun 27 14:20:06 2003 @@ -4,10 +4,11 @@ # obj-y := baget.o print.o setup.o time.o irq.o bagetIRQ.o \ - reset.o wbflush.o -obj-$(CONFIG_SERIAL) += vacserial.o + reset.o obj-$(CONFIG_VAC_RTC) += vacrtc.o +EXTRA_AFLAGS := $(CFLAGS) + bagetIRQ.o : bagetIRQ.S $(CC) $(CFLAGS) -c -o $@ $< @@ -28,7 +29,7 @@ dummy.o: dummy.c image.bin ramdisk.bin $(CC) $(CFLAGS) -c -o $@ $< $(OBJCOPY) --add-section=.vmlinux=image.bin \ - --add-section=.ramdisk=ramdisk.bin $@ + --add-section=.ramdisk=ramdisk.bin $@ balo.h: image $(NM) $< | awk ' \ @@ -39,13 +40,13 @@ /balo_ramdisk_size/ { printf "#define RAMDISK_SIZE 0x%s\n", $$1 } \ ' > $@ balo.o: balo.c balo.h - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< balo_supp.o: balo_supp.S $(CC) $(CFLAGS) -c $< balo: balo.o dummy.o balo_supp.o print.o - $(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^ + $(LD) $(LDFLAGS) -T ld.script.balo -o $@ $^ clean: rm -f balo balo.h dummy.c image image.bin diff -Nru a/arch/mips/baget/baget.c b/arch/mips/baget/baget.c --- a/arch/mips/baget/baget.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/baget/baget.c Fri Jun 27 14:19:59 2003 @@ -1,5 +1,4 @@ -/* $Id: baget.c,v 1.1 1999/01/17 03:49:37 ralf Exp $ - * +/* * baget.c: Baget low level stuff * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov @@ -21,7 +20,7 @@ * Following code is based on routines from 'mm/vmalloc.c' * Additional parameters ioaddr is needed to iterate across real I/O address. */ -static inline int alloc_area_pte(pte_t * pte, unsigned long address, +static inline int alloc_area_pte(pte_t * pte, unsigned long address, unsigned long size, unsigned long ioaddr) { unsigned long end; @@ -36,7 +35,7 @@ printk("kseg2_alloc_io: page already exists\n"); /* * For MIPS looks pretty to have transparent mapping - * for KSEG2 areas -- user can't access one, and no + * for KSEG2 areas -- user can't access one, and no * problems with virtual <--> physical translation. */ page = ioaddr & PAGE_MASK; @@ -50,7 +49,7 @@ return 0; } -static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, +static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, unsigned long ioaddr) { unsigned long end; diff -Nru a/arch/mips/baget/bagetIRQ.S b/arch/mips/baget/bagetIRQ.S --- a/arch/mips/baget/bagetIRQ.S Fri Jun 27 14:20:00 2003 +++ b/arch/mips/baget/bagetIRQ.S Fri Jun 27 14:20:00 2003 @@ -1,9 +1,8 @@ -/* $Id: bagetIRQ.S,v 1.1 1999/01/17 03:49:37 ralf Exp $ +/* * bagetIRQ.S: Interrupt exception dispatch code for Baget/MIPS * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ - #include <asm/asm.h> #include <asm/mipsregs.h> #include <asm/regdef.h> @@ -25,28 +24,28 @@ .set push .set noreorder jal a1 - .set pop - move a0, sp + .set pop + move a0, sp la a1, ret_from_irq jr a1 END(bagetIRQ) - + #define DBE_HANDLER 0x1C - + NESTED(try_read, PT_SIZE, sp) mfc0 t3, CP0_STATUS # save flags and CLI # disable interrupts li t0, KSEG2 - sltu t1, t0, a0 # Is it KSEG2 address ? - beqz t1, mapped # No - already mapped ! - - move t0, a0 + sltu t1, t0, a0 # Is it KSEG2 address ? + beqz t1, mapped # No - already mapped ! + + move t0, a0 ori t0, 0xfff xori t0, 0xfff # round address to page - ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G) + ori t1, t0, 0xf00 # prepare EntryLo (N,V,D,G) mfc0 t2, CP0_ENTRYHI # save ASID value mtc0 zero, CP0_INDEX @@ -57,15 +56,15 @@ tlbwi # ... and write ones nop nop - mtc0 t2, CP0_ENTRYHI - -mapped: + mtc0 t2, CP0_ENTRYHI + +mapped: la t0, exception_handlers lw t1, DBE_HANDLER(t0) # save real handler - la t2, dbe_handler + la t2, dbe_handler sw t2, DBE_HANDLER(t0) # set temporary local handler li v0, -1 # default (failure) value - + li t2, 1 beq t2, a1, 1f li t2, 2 @@ -81,13 +80,13 @@ b out 4: lw v0, (a0) # word - -out: + +out: sw t1, DBE_HANDLER(t0) # restore real handler mtc0 t3, CP0_STATUS # restore CPU flags - jr ra - -dbe_handler: + jr ra + +dbe_handler: li v0, -1 # mark our failure .set push .set noreorder diff -Nru a/arch/mips/baget/balo.c b/arch/mips/baget/balo.c --- a/arch/mips/baget/balo.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/baget/balo.c Fri Jun 27 14:19:59 2003 @@ -1,9 +1,7 @@ -/* $Id$ - * +/* * balo.c: BAget LOader * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - * */ #include <linux/kernel.h> #include <asm/system.h> @@ -18,7 +16,7 @@ static void mem_move (long *to, long *from, long size) { - while (size > 0) { + while (size > 0) { *to++ = *from++; size -= sizeof(long); } @@ -42,27 +40,29 @@ static __inline__ void reset_and_jump(int start, int mem_upper) { + unsigned long tmp; + __asm__ __volatile__( ".set\tnoreorder\n\t" ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" + "mfc0\t$1, $12\n\t" "nop\n\t" "nop\n\t" "nop\n\t" - "ori\t$1,$1,0xff00\n\t" - "xori\t$1,$1,0xff00\n\t" - "mtc0\t$1,$12\n\t" + "ori\t$1, $1, 0xff00\n\t" + "xori\t$1, $1, 0xff00\n\t" + "mtc0\t$1, $12\n\t" "nop\n\t" "nop\n\t" "nop\n\t" - "move\t$4,%1\n\t" - "jr\t%0\n\t" + "move\t%0, %2\n\t" + "jr\t%1\n\t" "nop\n\t" ".set\tat\n\t" - ".set\treorder" - : /* no outputs */ - :"Ir" (start), "Ir" (mem_upper) - :"$1", "$4", "memory"); + ".set\treorder" + : "=&r" (tmp) + : "Ir" (start), "Ir" (mem_upper) + : "memory"); } static void start_kernel(void) @@ -71,7 +71,7 @@ extern char _ramdisk_start, _ramdisk_end; outs( "Relocating Linux... " ); - mem_move((long*)KSEG0, (long*)&_vmlinux_start, + mem_move((long*)KSEG0, (long*)&_vmlinux_start, &_vmlinux_end-&_vmlinux_start); outs("done.\n"); @@ -86,7 +86,7 @@ outs("done.\n"); } - { + { extern void flush_cache_low(int isize, int dsize); flush_cache_low(256*1024,256*1024); } @@ -102,10 +102,10 @@ balo_state = MEM_PROBE; outs("RAM: <"); while(mem_limit < mem_limit_dbe) { - if (can_write(mem_limit) && *mem_limit != 0) + if (can_write(mem_limit) && *mem_limit != 0) break; /* cycle found */ outc('.'); - if (can_write(mem_limit)) + if (can_write(mem_limit)) *mem_limit = -1; /* mark */ mem_limit += 0x40000; } @@ -124,7 +124,7 @@ } void int_handler(struct pt_regs *regs) -{ +{ switch (balo_state) { case BALO_INIT: balo_printf("\nBALO: trap in balo itself.\n"); @@ -162,7 +162,7 @@ while(1) { *mem_limit_dbe; - if (can_write(mem_limit_dbe)) + if (can_write(mem_limit_dbe)) *mem_limit_dbe = 0; mem_limit_dbe += 0x40000; /* +1M */ @@ -174,7 +174,7 @@ { extern void except_vec3_generic(void); - cli(); + cli(); outs(banner); memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); mem_init(); diff -Nru a/arch/mips/baget/balo_supp.S b/arch/mips/baget/balo_supp.S --- a/arch/mips/baget/balo_supp.S Fri Jun 27 14:19:57 2003 +++ b/arch/mips/baget/balo_supp.S Fri Jun 27 14:19:57 2003 @@ -1,18 +1,17 @@ -/* $Id: balo_supp.S,v 1.1 1999/01/17 03:49:38 ralf Exp $ +/* * balo_supp.S: BAget Loader supplement * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ - #include <asm/asm.h> #include <asm/regdef.h> #include <asm/stackframe.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> - + .text .set mips1 - + /* General exception vector. */ NESTED(except_vec3_generic, 0, sp) .set noat @@ -21,7 +20,7 @@ END(except_vec3_generic) NESTED(except_vec3_generic_code, 0, sp) - SAVE_ALL + SAVE_ALL mfc0 k1, CP0_CAUSE la k0, int_cause sw k1, (k0) @@ -34,7 +33,7 @@ la k0, badvaddr sw k1, (k0) - la k0, int_handler + la k0, int_handler .set noreorder jal k0 .set reorder @@ -48,7 +47,7 @@ .set at .set macro .set noreorder - + move t1, a0 # ISIZE move t2, a1 # DSIZE @@ -89,7 +88,7 @@ sb zero, -8(t0) bne t0, t1, 1b sb zero, -4(t0) - + la v0, 1f or v0, KSEG1 j v0 # Run uncached diff -Nru a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c --- a/arch/mips/baget/irq.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/baget/irq.c Fri Jun 27 14:19:59 2003 @@ -17,7 +17,6 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/delay.h> -#include <linux/seq_file.h> #include <asm/bitops.h> #include <asm/bootinfo.h> @@ -28,24 +27,24 @@ #include <asm/baget/baget.h> -unsigned long spurious_count = 0; +volatile unsigned long irq_err_count; /* * This table is a correspondence between IRQ numbers and CPU PILs */ - -static int irq_to_pil_map[BAGET_IRQ_NR] = { + +static int irq_to_pil_map[BAGET_IRQ_NR] = { 7/*fixme: dma_err -1*/,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x00 - 0x0f */ -1,-1,-1,-1, 3,-1,-1,-1, 2, 2, 2,-1, 3,-1,-1,3/*fixme: lance*/, /* 0x10 - 0x1f */ -1,-1,-1,-1,-1,-1, 5,-1,-1,-1,-1,-1, 7,-1,-1,-1, /* 0x20 - 0x2f */ -1, 3, 2/*fixme systimer:3*/, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 /* 0x30 - 0x3f */ }; -static inline int irq_to_pil(int irq_nr) +static inline int irq_to_pil(int irq_nr) { int pil = -1; - if (irq_nr >= BAGET_IRQ_NR) + if (irq_nr >= BAGET_IRQ_NR) baget_printk("irq_to_pil: too large irq_nr = 0x%x\n", irq_nr); else { pil = irq_to_pil_map[irq_nr]; @@ -60,13 +59,13 @@ static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) { - unsigned long status = read_32bit_cp0_register(CP0_STATUS); + unsigned long status = read_c0_status(); status &= ~((clr_mask & 0xFF) << 8); status |= (set_mask & 0xFF) << 8; - write_32bit_cp0_register(CP0_STATUS, status); + write_c0_status(status); } -/* +/* * These two functions may be used for unconditional IRQ * masking via their PIL protection. */ @@ -92,26 +91,26 @@ static volatile unsigned int pil_in_use[BAGET_PIL_NR] = { 0, }; -void mask_irq_count(int irq_nr) +void mask_irq_count(int irq_nr) { unsigned long flags; int pil = irq_to_pil(irq_nr); - - save_and_cli(flags); + + local_irq_save(flags); if (!--pil_in_use[pil]) mask_irq(irq_nr); - restore_flags(flags); + local_irq_restore(flags); } -void unmask_irq_count(int irq_nr) +void unmask_irq_count(int irq_nr) { unsigned long flags; int pil = irq_to_pil(irq_nr); - - save_and_cli(flags); + + local_irq_save(flags); if (!pil_in_use[pil]++) unmask_irq(irq_nr); - restore_flags(flags); + local_irq_restore(flags); } /* @@ -122,18 +121,18 @@ { unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); mask_irq(irq_nr); - restore_flags(flags); + local_irq_restore(flags); } void enable_irq(unsigned int irq_nr) { unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); unmask_irq(irq_nr); - restore_flags(flags); + local_irq_restore(flags); } /* @@ -142,31 +141,31 @@ */ static struct irqaction *irq_action[BAGET_IRQ_NR] = { NULL, }; -int show_interrupts(struct seq_file *p, void *v) +int get_irq_list(char *buf) { - int i; + int i, len = 0; struct irqaction * action; unsigned long flags; for (i = 0 ; i < BAGET_IRQ_NR ; i++) { local_irq_save(flags); action = irq_action[i]; - if (!action) - goto skip; - seq_printf(p, "%2d: %8d %c %s", + if (!action) + gotos skip; + len += sprintf(buf+len, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], (action->flags & SA_INTERRUPT) ? '+' : ' ', action->name); for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", + len += sprintf(buf+len, ",%s %s", (action->flags & SA_INTERRUPT) ? " +" : "", action->name); } - seq_putc(p, '\n'); + len += sprintf(buf+len, "\n"); skip: local_irq_restore(flags); } - return 0; + return len; } @@ -183,10 +182,10 @@ int do_random, cpu; cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat_cpu(cpu).irqs[irq]++; + irq_enter(); + kstat_cpus(cpu)[irq]++; - mask_irq(irq); + mask_irq(irq); action = *(irq + irq_action); if (action) { if (!(action->flags & SA_INTERRUPT)) @@ -205,7 +204,7 @@ printk("do_IRQ: Unregistered IRQ (0x%X) occurred\n", irq); } unmask_irq(irq); - irq_exit(cpu, irq); + irq_exit(); /* unmasking and bottom half handling is done magically for us. */ } @@ -213,14 +212,14 @@ /* * What to do in case of 'no VIC register available' for current interrupt */ -static void vic_reg_error(unsigned long address, unsigned char active_pils) +static void vic_reg_error(unsigned long address, unsigned char active_pils) { printk("\nNo VIC register found: reg=%08lx active_pils=%02x\n" - "Current interrupt mask from CP0_CAUSE: %02x\n", - address, 0xff & active_pils, - 0xff & (read_32bit_cp0_register(CP0_CAUSE)>>8)); + "Current interrupt mask from CP0_CAUSE: %02x\n", + address, 0xff & active_pils, + 0xff & (read_c0_cause()>>8)); { int i; for (i=0; i<10000; i++) udelay(1000); } -} +} static char baget_fpu_irq = BAGET_FPU_IRQ; #define BAGET_INT_FPU {(unsigned long)&baget_fpu_irq, 1} @@ -230,27 +229,27 @@ */ asmlinkage void baget_interrupt(struct pt_regs *regs) { - static struct baget_int_reg int_reg[BAGET_PIL_NR] = { + static struct baget_int_reg int_reg[BAGET_PIL_NR] = { BAGET_INT_NONE, BAGET_INT_NONE, BAGET_INT0_ACK, BAGET_INT1_ACK, - BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK + BAGET_INT_NONE, BAGET_INT_FPU, BAGET_INT_NONE, BAGET_INT5_ACK }; unsigned char active_pils; - while ((active_pils = read_32bit_cp0_register(CP0_CAUSE)>>8)) { + while ((active_pils = read_c0_cause()>>8)) { int pil; struct baget_int_reg* reg; for (pil = 0; pil < BAGET_PIL_NR; pil++) { if (!(active_pils & (1<<pil))) continue; - + reg = &int_reg[pil]; if (reg->address) { extern int try_read(unsigned long,int); int irq = try_read(reg->address, reg->size); - if (irq != -1) + if (irq != -1) do_IRQ(BAGET_IRQ_MASK(irq), regs); - else + else vic_reg_error(reg->address, active_pils); } else { printk("baget_interrupt: unknown interrupt " @@ -291,9 +290,9 @@ if (new->flags & SA_SAMPLE_RANDOM) rand_initialize_irq(irq); - save_and_cli(flags); + local_irq_save(flags); *p = new; - restore_flags(flags); + local_irq_restore(flags); if (!shared) { unmask_irq_count(irq); @@ -302,9 +301,9 @@ return 0; } -int request_irq(unsigned int irq, +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, + unsigned long irqflags, const char * devname, void *dev_id) { @@ -315,12 +314,12 @@ return -EINVAL; if (!handler) return -EINVAL; - if (irq_to_pil_map[irq] < 0) + if (irq_to_pil_map[irq] < 0) return -EINVAL; action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) + if (!action) return -ENOMEM; action->handler = handler; @@ -337,13 +336,13 @@ return retval; } - + void free_irq(unsigned int irq, void *dev_id) { struct irqaction * action, **p; unsigned long flags; - if (irq >= BAGET_IRQ_NR) + if (irq >= BAGET_IRQ_NR) printk("Trying to free IRQ%d\n",irq); for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { @@ -351,11 +350,11 @@ continue; /* Found it - now free it */ - save_and_cli(flags); + local_irq_save(flags); *p = action->next; if (!irq[irq_action]) unmask_irq_count(irq); - restore_flags(flags); + local_irq_restore(flags); kfree(action); return; } @@ -380,7 +379,7 @@ *(volatile char*) BAGET_WRERR_ACK = 0; } -static struct irqaction irq0 = +static struct irqaction irq0 = { write_err_interrupt, SA_INTERRUPT, 0, "bus write error", NULL, NULL}; void __init init_IRQ(void) @@ -393,6 +392,6 @@ /* Enable interrupts for pils 2 and 3 (lines 0 and 1) */ modify_cp0_intmask(0, (1<<2)|(1<<3)); - if (setup_baget_irq(0, &irq0) < 0) + if (setup_baget_irq(0, &irq0) < 0) printk("init_IRQ: unable to register write_err irq\n"); } diff -Nru a/arch/mips/baget/ld.script.balo b/arch/mips/baget/ld.script.balo --- a/arch/mips/baget/ld.script.balo Fri Jun 27 14:19:53 2003 +++ b/arch/mips/baget/ld.script.balo Fri Jun 27 14:19:53 2003 @@ -1,4 +1,4 @@ -OUTPUT_FORMAT("elf32-bigmips") +OUTPUT_FORMAT("elf32-tradbigmips") OUTPUT_ARCH(mips) ENTRY(balo_entry) SECTIONS @@ -42,13 +42,13 @@ /* Startup code */ . = ALIGN(4096); __init_begin = .; - *(.text.init) - *(.data.init) + *(.text.init) + *(.data.init) . = ALIGN(4096); /* Align double page for init_task_union */ __init_end = .; - *(.fini) - *(.reginfo) + *(.fini) + *(.reginfo) /* Adjust the address for the data segment. We want to adjust up to the same address within the page on the next page up. It would be more correct to do this: @@ -68,18 +68,18 @@ *(.data) CONSTRUCTORS - *(.data1) + *(.data1) _gp = . + 0x8000; - *(.lit8) - *(.lit4) - *(.ctors) - *(.dtors) - *(.got.plt) *(.got) - *(.dynamic) + *(.lit8) + *(.lit4) + *(.ctors) + *(.dtors) + *(.got.plt) *(.got) + *(.dynamic) /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ - *(.sdata) + *(.sdata) _edata = .; PROVIDE (edata = .); @@ -96,21 +96,21 @@ /* These are needed for ELF backends which have not yet been converted to the new style linker. */ - *(.stab) - *(.stabstr) + *(.stab) + *(.stabstr) /* DWARF debug sections. Symbols in the .debug DWARF section are relative to the beginning of the section so we begin .debug at 0. It's not clear yet what needs to happen for the others. */ - *(.debug) - *(.debug_srcinfo) - *(.debug_aranges) - *(.debug_pubnames) - *(.debug_sfnames) - *(.line) + *(.debug) + *(.debug_srcinfo) + *(.debug_aranges) + *(.debug_pubnames) + *(.debug_sfnames) + *(.line) /* These must appear regardless of . */ - *(.gptab.data) *(.gptab.sdata) - *(.gptab.bss) *(.gptab.sbss) + *(.gptab.data) *(.gptab.sdata) + *(.gptab.bss) *(.gptab.sbss) _vmlinux_start = .; *(.vmlinux) diff -Nru a/arch/mips/baget/print.c b/arch/mips/baget/print.c --- a/arch/mips/baget/print.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/baget/print.c Fri Jun 27 14:19:56 2003 @@ -1,9 +1,7 @@ -/* $Id: print.c,v 1.1 1999/01/17 03:49:38 ralf Exp $ - * +/* * print.c: Simple print fascility * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - * */ #include <stdarg.h> #include <linux/kernel.h> @@ -16,7 +14,7 @@ */ // #define BAGET_PRINTK -/* +/* * This function is same for BALO and Linux baget_printk, * and normally prints characted to second (UART A) console. */ @@ -27,7 +25,7 @@ { int i; vac_outb(c, VAC_UART_B_TX); - for (i=0; i<10000; i++) + for (i=0; i<10000; i++) delay(); } @@ -38,7 +36,7 @@ outc_low(c); } -void outs(char *s) +void outs(char *s) { while(*s) outc(*s++); } @@ -79,7 +77,7 @@ void __init balo_printf( char *f, ... ) { int *arg = (int*)&f + 1; - char c; + char c; int format = 0; while((c = *f++) != 0) { @@ -112,7 +110,7 @@ } void __init balo_hungup(void) -{ +{ outs("Hunging up.\n"); - while(1); + while(1); } diff -Nru a/arch/mips/baget/prom/init.c b/arch/mips/baget/prom/init.c --- a/arch/mips/baget/prom/init.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/baget/prom/init.c Fri Jun 27 14:19:54 2003 @@ -1,13 +1,19 @@ /* * init.c: PROM library initialisation code. * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ #include <linux/init.h> #include <asm/addrspace.h> #include <asm/bootinfo.h> -char arcs_cmdline[COMMAND_LINE_SIZE]; +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + /* Should probably return one of "BT23-201", "BT23-202" */ + return "Baget"; +} void __init prom_init(unsigned int mem_upper) { diff -Nru a/arch/mips/baget/setup.c b/arch/mips/baget/setup.c --- a/arch/mips/baget/setup.c Fri Jun 27 14:19:52 2003 +++ b/arch/mips/baget/setup.c Fri Jun 27 14:19:52 2003 @@ -1,9 +1,7 @@ -/* $Id: setup.c,v 1.4 1999/10/09 00:00:57 ralf Exp $ - * +/* * setup.c: Baget/MIPS specific setup, including init of the feature struct. * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - * */ #include <linux/init.h> #include <linux/kernel.h> @@ -17,9 +15,9 @@ long int vac_memory_upper; #define CACHEABLE_STR(val) ((val) ? "not cached" : "cached") - + static void __init vac_show(void) -{ +{ int i; unsigned short val, decode = vac_inw(VAC_DECODE_CTRL); unsigned short a24_base = vac_inw(VAC_A24_BASE); @@ -38,7 +36,7 @@ VAC_IOSEL3_CTRL, VAC_IOSEL4_CTRL, VAC_IOSEL5_CTRL }; - + printk("[DSACKi %s, DRAMCS%s qualified, boundary%s qualified%s]\n", (decode & VAC_DECODE_DSACKI) ? "on" : "off", (decode & VAC_DECODE_QFY_DRAMCS) ? "" : " not", @@ -72,24 +70,24 @@ VAC_ICFSEL_MODULE_VAL(vac_inw(VAC_ICFSEL_BASE)))<<4, (decode & VAC_DECODE_QFY_ICFSEL) ? "qualified" : ""); - + printk("region0 at 00000000 (%dMB)\t[dram, %s, delay %d cpuclk" ", cached]\n", (vac_inw(VAC_DRAM_MASK)+1)>>4, (decode & VAC_DECODE_DSACK) ? "D32" : "3state", VAC_DECODE_CPUCLK_VAL(decode)); - + for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) { - unsigned long from = + unsigned long from = ((unsigned long)vac_inw(bndr[i]))<<16; - unsigned long to = + unsigned long to = ((unsigned long) - ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ? + ((i+1 == sizeof(bndr)/sizeof(bndr[0])) ? 0xff00 : vac_inw(bndr[i+1])))<<16; - - + + val = vac_inw(regs[i]); - printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n", + printk("region%d at %08lx (%dMB)\t[%s %s/%s, %s]\n", i+1, from, (unsigned int)((to - from) >> 20), @@ -97,13 +95,13 @@ asiz[VAC_REG_ASIZ_VAL(val)], ((val & VAC_REG_WORD) ? "D16" : "D32"), CACHEABLE_STR(val&VAC_A24_A24_CACHINH)); - + if (a24_addr >= from && a24_addr < to) printk("\ta24 at %08lx (%dMB)\t[vme, A24/%s, %s]\n", a24_addr, min((unsigned int)(a24_addr - from)>>20, 32U), (a24_base & VAC_A24_DATAPATH) ? "user" : - ((a24_base & VAC_A24_D32_ENABLE) ? + ((a24_base & VAC_A24_D32_ENABLE) ? "D32" : "D16"), CACHEABLE_STR(a24_base & VAC_A24_A24_CACHINH)); } @@ -123,7 +121,7 @@ (VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "", VAC_CTRL_DELAY_IOSELI_VAL(val)/2, (VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : ""); - + printk("region5 at fff00000 (896KB)\t[local io, %s]\n", CACHEABLE_STR(vac_inw(VAC_A24_BASE) & VAC_A24_IO_CACHINH)); @@ -132,7 +130,7 @@ printk("\tio%d[ack %d cpuclk%s, %s%srecovery %d cpuclk, " "\n\t read %d%s cpuclk, write %d%s cpuclk, " "assert %d%s%s cpuclk]\n", - i, + i, VAC_CTRL_DELAY_DSACKI_VAL(val), state[val & (VAC_CTRL_IORD|VAC_CTRL_IOWR)], (val & VAC_CTRL_DSACK0) ? "dsack0*, " : "", @@ -144,15 +142,15 @@ (VAC_CTRL_DELAY_IOWR_VAL(val)&1) ? ".5" : "", VAC_CTRL_DELAY_IOSELI_VAL(val)/2, (VAC_CTRL_DELAY_IOSELI_VAL(val)&1) ? ".5" : "", - (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ? + (vac_inw(VAC_DEV_LOC) & VAC_DEV_LOC_IOSEL(i)) ? ", id" : ""); } - + printk("region6 at fffe0000 (128KB)\t[vme, A16/%s, " "not cached]\n", - (a24_base & VAC_A24_A16D32_ENABLE) ? + (a24_base & VAC_A24_A16D32_ENABLE) ? ((a24_base & VAC_A24_A16D32) ? "D32" : "D16") : "user"); - + val = vac_inw(VAC_SHRCS_CTRL); printk("shared[ack %d cpuclk%s, %s%srecovery %d cpuclk, " "read %d%s, write %d%s, assert %d%s]\n", @@ -183,8 +181,8 @@ default: panic("Unknown VAC revision number"); } - - vac_outw(mem_limit-1, VAC_DRAM_MASK); + + vac_outw(mem_limit-1, VAC_DRAM_MASK); vac_outw(mem_limit, VAC_BNDR2); vac_outw(mem_limit, VAC_BNDR3); vac_outw(((BAGET_A24M_BASE>>16)&~VAC_A24_D32_ENABLE)|VAC_A24_DATAPATH, @@ -294,19 +292,19 @@ vac_outw(VAC_INT_CTRL_TIMER_PIO10| VAC_INT_CTRL_UART_B_PIO7| VAC_INT_CTRL_UART_A_PIO7,VAC_INT_CTRL); - /* + /* * Set quadro speed for both UARTs. * To do it we need use formulae from VIC/VAC manual, * keeping in mind Baget's 50MHz frequency... */ - vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV); + vac_outw((500000/(384*16))<<8,VAC_CPU_CLK_DIV); } static void __init vic_show(void) { unsigned char val; char *timeout[] = { "4", "16", "32", "64", "128", "256", "disabled" }; - char *deadlock[] = { "[dedlk only]", "[dedlk only]", + char *deadlock[] = { "[dedlk only]", "[dedlk only]", "[dedlk], [halt w/ rmc], [lberr]", "[dedlk], [halt w/o rmc], [lberr]" }; @@ -319,7 +317,7 @@ printk("metastability delay "); printk("%s ", deadlock[VIC_IFACE_CFG_DEADLOCK_VAL(val)]); - + printk("interrupts: "); val = vic_inb(VIC_ERR_INT); @@ -332,7 +330,7 @@ if (!(val & VIC_ERR_INT_ACFAIL)) printk("[acfail] "); printk("\n"); - + printk("timeouts: "); val = vic_inb(VIC_XFER_TIMO); printk("local %s, vme %s ", @@ -358,7 +356,7 @@ printk("[local boundary cross]"); if (val & VIC_BXFER_DEF_VME_CROSS) printk("[vme boundary cross]"); - + } static void __init vic_init(void) @@ -373,7 +371,7 @@ vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT2); vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT3); vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE,VIC_VME_INT4); -/* +/* vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT5); */ vic_outb(VIC_INT_IPL(3)|VIC_INT_DISABLE, VIC_VME_INT6); @@ -388,7 +386,7 @@ VIC_INT_HIGH|VIC_INT_DISABLE, VIC_LINT3); vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_EDGE| VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT4); -/* +/* vic_outb(VIC_INT_IPL(3)|VIC_INT_NOAUTO|VIC_INT_LEVEL| VIC_INT_LOW|VIC_INT_DISABLE, VIC_LINT5); */ @@ -447,7 +445,7 @@ VIC_RELEASE_RWD, VIC_RELEASE); vic_outb(VIC_IC6_RUN, VIC_IC6); vic_outb(0, VIC_IC7); - + vic_show(); } @@ -471,7 +469,7 @@ extern void baget_machine_restart(char *command); extern void baget_machine_halt(void); extern void baget_machine_power_off(void); - + void __init baget_setup(void) { printk("BT23/63-201n found.\n"); diff -Nru a/arch/mips/baget/time.c b/arch/mips/baget/time.c --- a/arch/mips/baget/time.c Fri Jun 27 14:19:30 2003 +++ b/arch/mips/baget/time.c Fri Jun 27 14:19:30 2003 @@ -20,23 +20,23 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/ptrace.h> -#include <asm/system.h> +#include <asm/system.h> #include <asm/baget/baget.h> -/* +/* * To have precision clock, we need to fix available clock frequency */ #define FREQ_NOM 79125 /* Baget frequency ratio */ #define FREQ_DEN 10000 -static inline int timer_intr_valid(void) +static inline int timer_intr_valid(void) { static unsigned long long ticks, valid_ticks; if (ticks++ * FREQ_DEN >= valid_ticks * FREQ_NOM) { - /* - * We need no overflow checks, + /* + * We need no overflow checks, * due baget unable to work 3000 years... * At least without reboot... */ @@ -62,10 +62,10 @@ vic_outb(ss0cr0, VIC_SS0CR0); vic_outb(VIC_INT_IPL(6)|VIC_INT_NOAUTO|VIC_INT_EDGE| - VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); + VIC_INT_LOW|VIC_INT_ENABLE, VIC_LINT2); } -static struct irqaction timer_irq = +static struct irqaction timer_irq = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL}; void __init time_init(void) @@ -82,17 +82,19 @@ do { seq = read_seqbegin(&xtime_lock); - *tv = xtime; + tv->tv_sec = xtime.tv_sec; + tv->tv_usec = xtime.tv_nsec / 1000; } while (read_seqretry(&xtime_lock, seq)); } void do_settimeofday(struct timeval *tv) { - write_seqlock_irq (&xtime_lock); - xtime = *tv; + write_seqlock_irq(&xtime_lock); + xtime.tv_usec = tv->tv_sec; + xtime.tv_nsec = tv->tv_usec; time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_sequnlock_irq (&xtime_lock); + write_sequnlock_irq(&xtime_lock); } diff -Nru a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c --- a/arch/mips/baget/vacserial.c Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2837 +0,0 @@ -/* - * vacserial.c: VAC UART serial driver - * This code stealed and adopted from linux/drivers/char/serial.c - * See that for author info - * - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - */ - -#undef SERIAL_PARANOIA_CHECK -#define CONFIG_SERIAL_NOPAUSE_IO -#define SERIAL_DO_RESTART - -#define CONFIG_SERIAL_SHARE_IRQ - -/* Set of debugging defines */ - -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW -#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - -#define RS_STROBE_TIME (10*HZ) -#define RS_ISR_PASS_LIMIT 2 /* Beget is not a super-computer (old=256) */ - -#define IRQ_T(state) \ - ((state->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT) - -#define SERIAL_INLINE - -#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) -#define DBG_CNT(s) baget_printk("(%s):[%x] refc=%d, serc=%d, ttyc=%d-> %s\n", \ - tty->name,(info->flags),serial_driver->refcount,info->count,tty->count,s) -#else -#define DBG_CNT(s) -#endif - -#define QUAD_UART_SPEED /* Useful for Baget */ - -/* - * End of serial driver configuration section. - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/serial.h> -#include <linux/major.h> -#include <linux/string.h> -#include <linux/fcntl.h> -#include <linux/ptrace.h> -#include <linux/ioport.h> -#include <linux/mm.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/delay.h> -#ifdef CONFIG_SERIAL_CONSOLE -#include <linux/console.h> -#endif - -#include <asm/system.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/bitops.h> -#include <asm/serial.h> -#include <asm/baget/baget.h> - -#define BAGET_VAC_UART_IRQ 0x35 - -/* - * Implementation note: - * It was descovered by means of advanced electronic tools, - * if the driver works via TX_READY interrupts then VIC generates - * strange self-eliminating traps. Thus, the driver is rewritten to work - * via TX_EMPTY - */ - -/* VAC-specific check/debug switches */ - -#undef CHECK_REG_INDEX -#undef DEBUG_IO_PORT_A - -#ifdef SERIAL_INLINE -#define _INLINE_ inline -#endif - -static char *serial_name = "VAC Serial driver"; -static char *serial_version = "4.26"; - -static DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver *serial_driver; - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* - * IRQ_timeout - How long the timeout should be for each IRQ - * should be after the IRQ has been active. - */ - -static struct async_struct *IRQ_ports[NR_IRQS]; -static int IRQ_timeout[NR_IRQS]; -#ifdef CONFIG_SERIAL_CONSOLE -static struct console sercons; -#endif - -static void autoconfig(struct serial_state * info); -static void change_speed(struct async_struct *info); -static void rs_wait_until_sent(struct tty_struct *tty, int timeout); -static void rs_timer(unsigned long dummy); - -static struct timer_list vacs_timer; - -/* - * Here we define the default xmit fifo size used for each type of - * UART - */ -static struct serial_uart_config uart_config[] = { - { "unknown", 1, 0 }, /* Must go first -- used as unassigned */ - { "VAC UART", 1, 0 } -}; -#define VAC_UART_TYPE 1 /* Just index in above array */ - -static struct serial_state rs_table[] = { -/* - * VAC has tricky layout for pair of his SIO registers, - * so we need special function to access ones. - * To identify port we use their TX offset - */ - { 0, 9600, VAC_UART_B_TX, BAGET_VAC_UART_IRQ, - STD_COM_FLAGS }, /* VAC UART B */ - { 0, 9600, VAC_UART_A_TX, BAGET_VAC_UART_IRQ, - STD_COM_FLAGS } /* VAC UART A */ -}; - -#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state)) - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the copy_from_user blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); - -static inline int serial_paranoia_check(struct async_struct *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = - "Warning: bad magic number for serial struct (%s) in %s\n"; - static const char *badinfo = - "Warning: null async_struct for (%s) in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - To unify UART A/B access we will use following function - to compute register offsets by register index. - */ - -#define VAC_UART_MODE 0 -#define VAC_UART_TX 1 -#define VAC_UART_RX 2 -#define VAC_UART_INT_MASK 3 -#define VAC_UART_INT_STATUS 4 - -#define VAC_UART_REG_NR 5 - -static inline int uart_offset_map(unsigned long port, int reg_index) -{ - static const unsigned int ind_to_reg[VAC_UART_REG_NR][NR_PORTS] = { - { VAC_UART_B_MODE, VAC_UART_A_MODE }, - { VAC_UART_B_TX, VAC_UART_A_TX }, - { VAC_UART_B_RX, VAC_UART_A_RX }, - { VAC_UART_B_INT_MASK, VAC_UART_A_INT_MASK }, - { VAC_UART_B_INT_STATUS, VAC_UART_A_INT_STATUS } - }; -#ifdef CHECK_REG_INDEX - if (reg_index > VAC_UART_REG_NR) panic("vacserial: bad reg_index"); -#endif - return ind_to_reg[reg_index][port == VAC_UART_B_TX ? 0 : 1]; -} - -static inline unsigned int serial_inw(struct async_struct *info, int offset) -{ - int val = vac_inw(uart_offset_map(info->port,offset)); -#ifdef DEBUG_IO_PORT_A - if (info->port == VAC_UART_A_TX) - printk("UART_A_IN: reg = 0x%04x, val = 0x%04x\n", - uart_offset_map(info->port,offset), val); -#endif - return val; -} - -static inline unsigned int serial_inp(struct async_struct *info, int offset) -{ - return serial_inw(info, offset); -} - -static inline unsigned int serial_in(struct async_struct *info, int offset) -{ - return serial_inw(info, offset); -} - -static inline void serial_outw(struct async_struct *info,int offset, int value) -{ -#ifdef DEBUG_IO_PORT_A - if (info->port == VAC_UART_A_TX) - printk("UART_A_OUT: offset = 0x%04x, val = 0x%04x\n", - uart_offset_map(info->port,offset), value); -#endif - vac_outw(value, uart_offset_map(info->port,offset)); -} - -static inline void serial_outp(struct async_struct *info,int offset, int value) -{ - serial_outw(info,offset,value); -} - -static inline void serial_out(struct async_struct *info,int offset, int value) -{ - serial_outw(info,offset,value); -} - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->IER & VAC_UART_INT_TX_EMPTY) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt && info->xmit_buf - && !(info->IER & VAC_UART_INT_TX_EMPTY)) { - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - restore_flags(flags); -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct async_struct *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -static _INLINE_ void receive_chars(struct async_struct *info, - int *status) -{ - struct tty_struct *tty = info->tty; - unsigned short rx; - unsigned char ch; - int ignored = 0; - struct async_icount *icount; - - icount = &info->state->icount; - do { - rx = serial_inw(info, VAC_UART_RX); - ch = VAC_UART_RX_DATA_MASK & rx; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - *tty->flip.char_buf_ptr = ch; - icount->rx++; - -#ifdef SERIAL_DEBUG_INTR - baget_printk("DR%02x:%02x...", rx, *status); -#endif - *tty->flip.flag_buf_ptr = 0; - if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE - | VAC_UART_STATUS_RX_ERR_PARITY - | VAC_UART_STATUS_RX_ERR_FRAME - | VAC_UART_STATUS_RX_ERR_OVERRUN)) { - /* - * For statistics only - */ - if (*status & VAC_UART_STATUS_RX_BREAK_CHANGE) { - *status &= ~(VAC_UART_STATUS_RX_ERR_FRAME - | VAC_UART_STATUS_RX_ERR_PARITY); - icount->brk++; - } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) - icount->parity++; - else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) - icount->frame++; - if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) - icount->overrun++; - - /* - * Now check to see if character should be - * ignored, and mask off conditions which - * should be ignored. - */ - if (*status & info->ignore_status_mask) { - if (++ignored > 100) - break; - goto ignore_char; - } - *status &= info->read_status_mask; - - if (*status & (VAC_UART_STATUS_RX_BREAK_CHANGE)) { -#ifdef SERIAL_DEBUG_INTR - baget_printk("handling break...."); -#endif - *tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (*status & VAC_UART_STATUS_RX_ERR_PARITY) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (*status & VAC_UART_STATUS_RX_ERR_FRAME) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (*status & VAC_UART_STATUS_RX_ERR_OVERRUN) { - /* - * Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - if (tty->flip.count < TTY_FLIPBUF_SIZE) { - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - } - } - } - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - ignore_char: - *status = serial_inw(info, VAC_UART_INT_STATUS); - } while ((*status & VAC_UART_STATUS_RX_READY)); - tty_flip_buffer_push(tty); -} - -static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done) -{ - int count; - - if (info->x_char) { - serial_outw(info, VAC_UART_TX, - (((unsigned short)info->x_char)<<8)); - info->state->icount.tx++; - info->x_char = 0; - if (intr_done) - *intr_done = 0; - return; - } - if ((info->xmit_cnt <= 0) || info->tty->stopped || - info->tty->hw_stopped) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_outw(info, VAC_UART_INT_MASK, info->IER); - return; - } - count = info->xmit_fifo_size; - do { - serial_out(info, VAC_UART_TX, - (unsigned short)info->xmit_buf[info->xmit_tail++] \ - << 8); - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->state->icount.tx++; - if (--info->xmit_cnt <= 0) - break; - } while (--count > 0); - - if (info->xmit_cnt < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - -#ifdef SERIAL_DEBUG_INTR - baget_printk("THRE..."); -#endif - if (intr_done) - *intr_done = 0; - - if (info->xmit_cnt <= 0) { - info->IER &= ~VAC_UART_INT_TX_EMPTY; - serial_outw(info, VAC_UART_INT_MASK, info->IER); - } -} - -static _INLINE_ void check_modem_status(struct async_struct *info) -{ -#if 0 /* VAC hasn't modem control */ - wake_up_interruptible(&info->open_wait); - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); -#endif -} - -#ifdef CONFIG_SERIAL_SHARE_IRQ - - -/* - * Specific functions needed for VAC UART interrupt enter/leave - */ - -#define VAC_INT_CTRL_UART_ENABLE \ - (VAC_INT_CTRL_TIMER_PIO10|VAC_INT_CTRL_UART_B_PIO7|VAC_INT_CTRL_UART_A_PIO7) - -#define VAC_INT_CTRL_UART_DISABLE(info) \ - (VAC_INT_CTRL_TIMER_PIO10 | \ - ((info->port == VAC_UART_A_TX) ? \ - (VAC_INT_CTRL_UART_A_DISABLE|VAC_INT_CTRL_UART_B_PIO7) : \ - (VAC_INT_CTRL_UART_A_PIO7|VAC_INT_CTRL_UART_B_DISABLE))) - -/* - * Following two functions were proposed by Pavel Osipenko - * to make VAC/VIC behaviour more regular. - */ -static void intr_begin(struct async_struct* info) -{ - serial_outw(info, VAC_UART_INT_MASK, 0); -} - -static void intr_end(struct async_struct* info) -{ - vac_outw(VAC_INT_CTRL_UART_DISABLE(info), VAC_INT_CTRL); - vac_outw(VAC_INT_CTRL_UART_ENABLE, VAC_INT_CTRL); - - serial_outw(info, VAC_UART_INT_MASK, info->IER); -} - -/* - * This is the serial driver's generic interrupt routine - */ -static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - int status; - struct async_struct * info; - int pass_counter = 0; - struct async_struct *end_mark = 0; - -#ifdef SERIAL_DEBUG_INTR - baget_printk("rs_interrupt(%d)...", irq); -#endif - - info = IRQ_ports[irq]; - if (!info) - return; - - do { - intr_begin(info); /* Mark we begin port handling */ - - if (!info->tty || - (serial_inw (info, VAC_UART_INT_STATUS) - & VAC_UART_STATUS_INTS) == 0) - { - if (!end_mark) - end_mark = info; - goto next; - } - end_mark = 0; - - info->last_active = jiffies; - - status = serial_inw(info, VAC_UART_INT_STATUS); -#ifdef SERIAL_DEBUG_INTR - baget_printk("status = %x...", status); -#endif - if (status & VAC_UART_STATUS_RX_READY) { - receive_chars(info, &status); - } - check_modem_status(info); - if (status & VAC_UART_STATUS_TX_EMPTY) - transmit_chars(info, 0); - - next: - intr_end(info); /* Mark this port handled */ - - info = info->next_port; - if (!info) { - info = IRQ_ports[irq]; - if (pass_counter++ > RS_ISR_PASS_LIMIT) { - break; /* Prevent infinite loops */ - } - continue; - } - } while (end_mark != info); -#ifdef SERIAL_DEBUG_INTR - baget_printk("end.\n"); -#endif - - -} -#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */ - - -/* The original driver was simplified here: - two functions were joined to reduce code */ - -#define rs_interrupt_single rs_interrupt - - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct async_struct *info = (struct async_struct *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } -} - -/* - * --------------------------------------------------------------- - * Low level utility subroutines for the serial driver: routines to - * figure out the appropriate timeout for an interrupt chain, routines - * to initialize and startup a serial port, and routines to shutdown a - * serial port. Useful stuff like that. - * --------------------------------------------------------------- - */ - -/* - * This routine figures out the correct timeout for a particular IRQ. - * It uses the smallest timeout of all of the serial ports in a - * particular interrupt chain. Now only used for IRQ 0.... - */ -static void figure_IRQ_timeout(int irq) -{ - struct async_struct *info; - int timeout = 60*HZ; /* 60 seconds === a long time :-) */ - - info = IRQ_ports[irq]; - if (!info) { - IRQ_timeout[irq] = 60*HZ; - return; - } - while (info) { - if (info->timeout < timeout) - timeout = info->timeout; - info = info->next_port; - } - if (!irq) - timeout = timeout / 2; - IRQ_timeout[irq] = timeout ? timeout : 1; -} - -static int startup(struct async_struct * info) -{ - unsigned long flags; - int retval=0; - void (*handler)(int, void *, struct pt_regs *); - struct serial_state *state= info->state; - unsigned long page; - - page = get_zeroed_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - - save_flags(flags); cli(); - - if (info->flags & ASYNC_INITIALIZED) { - free_page(page); - goto errout; - } - if (!state->port || !state->type) { - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - free_page(page); - goto errout; - } - if (info->xmit_buf) - free_page(page); - else - info->xmit_buf = (unsigned char *) page; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("starting up ttys%d (irq %d)...", info->line, state->irq); -#endif - - if (uart_config[info->state->type].flags & UART_STARTECH) { - /* Wake up UART */ - serial_outp(info, VAC_UART_MODE, 0); - serial_outp(info, VAC_UART_INT_MASK, 0); - } - - /* - * Allocate the IRQ if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - - if (IRQ_ports[state->irq]) { -#ifdef CONFIG_SERIAL_SHARE_IRQ - free_irq(state->irq, NULL); - handler = rs_interrupt; -#else - retval = -EBUSY; - goto errout; -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - } else - handler = rs_interrupt_single; - - - retval = request_irq(state->irq, handler, IRQ_T(state), - "serial", NULL); - if (retval) { - if (capable(CAP_SYS_ADMIN)) { - if (info->tty) - set_bit(TTY_IO_ERROR, - &info->tty->flags); - retval = 0; - } - goto errout; - } - } - - /* - * Insert serial port into IRQ chain. - */ - info->prev_port = 0; - info->next_port = IRQ_ports[state->irq]; - if (info->next_port) - info->next_port->prev_port = info; - IRQ_ports[state->irq] = info; - figure_IRQ_timeout(state->irq); - - /* - * Clear the interrupt registers. - */ - /* (void) serial_inw(info, VAC_UART_INT_STATUS); */ /* (see above) */ - (void) serial_inw(info, VAC_UART_RX); - - /* - * Now, initialize the UART - */ - serial_outp(info, VAC_UART_MODE, VAC_UART_MODE_INITIAL); /*reset DLAB*/ - - /* - * Finally, enable interrupts - */ - info->IER = VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS | \ - VAC_UART_INT_RX_READY; - serial_outp(info, VAC_UART_INT_MASK, info->IER); /*enable interrupts*/ - - /* - * And clear the interrupt registers again for luck. - */ - (void)serial_inp(info, VAC_UART_INT_STATUS); - (void)serial_inp(info, VAC_UART_RX); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - /* - * Set up serial timers... - */ - mod_timer(&vacs_timer, jiffies + 2*HZ/100); - - /* - * and set the speed of the serial port - */ - change_speed(info); - - info->flags |= ASYNC_INITIALIZED; - restore_flags(flags); - return 0; - -errout: - restore_flags(flags); - return retval; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct async_struct * info) -{ - unsigned long flags; - struct serial_state *state; - int retval; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - state = info->state; - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("Shutting down serial port %d (irq %d)....", info->line, - state->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - /* - * clear delta_msr_wait queue to avoid mem leaks: we may free the irq - * here so the queue might never be waken up - */ - wake_up_interruptible(&info->delta_msr_wait); - - /* - * First unlink the serial port from the IRQ chain... - */ - if (info->next_port) - info->next_port->prev_port = info->prev_port; - if (info->prev_port) - info->prev_port->next_port = info->next_port; - else - IRQ_ports[state->irq] = info->next_port; - figure_IRQ_timeout(state->irq); - - /* - * Free the IRQ, if necessary - */ - if (state->irq && (!IRQ_ports[state->irq] || - !IRQ_ports[state->irq]->next_port)) { - if (IRQ_ports[state->irq]) { - free_irq(state->irq, NULL); - retval = request_irq(state->irq, rs_interrupt_single, - IRQ_T(state), "serial", NULL); - - if (retval) - printk("serial shutdown: request_irq: error %d" - " Couldn't reacquire IRQ.\n", retval); - } else - free_irq(state->irq, NULL); - } - - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = 0; - } - - info->IER = 0; - serial_outp(info, VAC_UART_INT_MASK, 0x00); /* disable all intrs */ - - /* disable break condition */ - serial_out(info, VAC_UART_MODE, serial_inp(info, VAC_UART_MODE) & \ - ~VAC_UART_MODE_SEND_BREAK); - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; - restore_flags(flags); -} - -/* - * When we set line mode, we call this function - * for Baget-specific adjustments. - */ - -static inline unsigned short vac_uart_mode_fixup (unsigned short cval) -{ -#ifdef QUAD_UART_SPEED - /* - * When we are using 4-x advantage in speed: - * - * Disadvantage : can't support 75, 150 bauds - * Advantage : can support 19200, 38400 bauds - */ - char speed = 7 & (cval >> 10); - cval &= ~(7 << 10); - cval |= VAC_UART_MODE_BAUD(speed-2); -#endif - - /* - * In general, we have Tx and Rx ON all time - * and use int mask flag for their disabling. - */ - cval |= VAC_UART_MODE_RX_ENABLE; - cval |= VAC_UART_MODE_TX_ENABLE; - cval |= VAC_UART_MODE_CHAR_RX_ENABLE; - cval |= VAC_UART_MODE_CHAR_TX_ENABLE; - - /* Low 4 bits are not used in UART */ - cval &= ~0xf; - - return cval; -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct async_struct *info) -{ - unsigned short port; - int quot = 0, baud_base, baud; - unsigned cflag, cval; - int bits; - unsigned long flags; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!(port = info->port)) - return; - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS7: cval = 0x0; bits = 9; break; - case CS8: cval = VAC_UART_MODE_8BIT_CHAR; bits = 10; break; - /* Never happens, but GCC is too dumb to figure it out */ - case CS5: - case CS6: - default: cval = 0x0; bits = 9; break; - } - cval &= ~VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARENB) { - cval |= VAC_UART_MODE_PARITY_ENABLE; - bits++; - } - if (cflag & PARODD) - cval |= VAC_UART_MODE_PARITY_ODD; - - /* Determine divisor based on baud rate */ - baud = tty_get_baud_rate(info->tty); - if (!baud) - baud = 9600; /* B0 transition handled in rs_set_termios */ - baud_base = info->state->baud_base; - if (baud == 38400 && - ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) - quot = info->state->custom_divisor; - else { - if (baud == 134) - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) - quot = baud_base / baud; - } - /* If the quotient is ever zero, default to 9600 bps */ - if (!quot) - quot = baud_base / 9600; - info->quot = quot; - info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base); - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - serial_out(info, VAC_UART_INT_MASK, info->IER); - - /* - * Set up parity check flag - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - - info->read_status_mask = VAC_UART_STATUS_RX_ERR_OVERRUN | \ - VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_RX_READY; - if (I_INPCK(info->tty)) - info->read_status_mask |= VAC_UART_STATUS_RX_ERR_FRAME | \ - VAC_UART_STATUS_RX_ERR_PARITY; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; - - /* - * Characters to ignore - */ - info->ignore_status_mask = 0; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= VAC_UART_STATUS_RX_ERR_PARITY | \ - VAC_UART_STATUS_RX_ERR_FRAME; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= VAC_UART_STATUS_RX_BREAK_CHANGE; - /* - * If we're ignore parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= \ - VAC_UART_STATUS_RX_ERR_OVERRUN; - } - /* - * !!! ignore all characters if CREAD is not set - */ - if ((cflag & CREAD) == 0) - info->ignore_status_mask |= VAC_UART_STATUS_RX_READY; - save_flags(flags); cli(); - - - switch (baud) { - default: - case 9600: - cval |= VAC_UART_MODE_BAUD(7); - break; - case 4800: - cval |= VAC_UART_MODE_BAUD(6); - break; - case 2400: - cval |= VAC_UART_MODE_BAUD(5); - break; - case 1200: - cval |= VAC_UART_MODE_BAUD(4); - break; - case 600: - cval |= VAC_UART_MODE_BAUD(3); - break; - case 300: - cval |= VAC_UART_MODE_BAUD(2); - break; -#ifndef QUAD_UART_SPEED - case 150: -#else - case 38400: -#endif - cval |= VAC_UART_MODE_BAUD(1); - break; -#ifndef QUAD_UART_SPEED - case 75: -#else - case 19200: -#endif - cval |= VAC_UART_MODE_BAUD(0); - break; - } - - /* Baget VAC need some adjustments for computed value */ - cval = vac_uart_mode_fixup(cval); - - serial_outp(info, VAC_UART_MODE, cval); - restore_flags(flags); -} - -static void rs_put_char(struct tty_struct *tty, unsigned char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_put_char")) - return; - - if (!tty || !info->xmit_buf) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { - restore_flags(flags); - return; - } - - info->xmit_buf[info->xmit_head++] = ch; - info->xmit_head &= SERIAL_XMIT_SIZE-1; - info->xmit_cnt++; - restore_flags(flags); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->xmit_buf) - return; - - save_flags(flags); cli(); - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - restore_flags(flags); -} - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, ret = 0; - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!tty || !info->xmit_buf || !tmp_buf) - return 0; - - save_flags(flags); - if (from_user) { - down(&tmp_buf_sem); - while (1) { - c = MIN(count, - MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; - - c -= copy_from_user(tmp_buf, buf, c); - if (!c) { - if (!ret) - ret = -EFAULT; - break; - } - cli(); - c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - up(&tmp_buf_sem); - } else { - while (1) { - cli(); - c = MIN(count, - MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) { - restore_flags(flags); - break; - } - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = ((info->xmit_head + c) & - (SERIAL_XMIT_SIZE-1)); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - ret += c; - } - } - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped && - !(info->IER & VAC_UART_INT_TX_EMPTY)) { - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } - return ret; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return info->xmit_cnt; -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - - save_flags(flags); cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -/* - * This function is used to send a high-priority XON/XOFF character to - * the device - */ -static void rs_send_xchar(struct tty_struct *tty, char ch) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_send_char")) - return; - - info->x_char = ch; - if (ch) { - /* Make sure transmit interrupts are on */ - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, info->IER); - } -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - baget_printk("throttle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - rs_send_xchar(tty, STOP_CHAR(tty)); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - baget_printk("unthrottle %s: %d....\n", tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - rs_send_xchar(tty, START_CHAR(tty)); - } -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct async_struct * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - struct serial_state *state = info->state; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = state->type; - tmp.line = state->line; - tmp.port = state->port; - tmp.irq = state->irq; - tmp.flags = state->flags; - tmp.xmit_fifo_size = state->xmit_fifo_size; - tmp.baud_base = state->baud_base; - tmp.close_delay = state->close_delay; - tmp.closing_wait = state->closing_wait; - tmp.custom_divisor = state->custom_divisor; - tmp.hub6 = state->hub6; - if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) - return -EFAULT; - return 0; -} - -static int set_serial_info(struct async_struct * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct serial_state old_state, *state; - unsigned int i,change_irq,change_port; - int retval = 0; - - if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) - return -EFAULT; - state = info->state; - old_state = *state; - - change_irq = new_serial.irq != state->irq; - change_port = (new_serial.port != state->port) || - (new_serial.hub6 != state->hub6); - - if (!capable(CAP_SYS_ADMIN)) { - if (change_irq || change_port || - (new_serial.baud_base != state->baud_base) || - (new_serial.type != state->type) || - (new_serial.close_delay != state->close_delay) || - (new_serial.xmit_fifo_size != state->xmit_fifo_size) || - ((new_serial.flags & ~ASYNC_USR_MASK) != - (state->flags & ~ASYNC_USR_MASK))) - return -EPERM; - state->flags = ((state->flags & ~ASYNC_USR_MASK) | - (new_serial.flags & ASYNC_USR_MASK)); - info->flags = ((state->flags & ~ASYNC_USR_MASK) | - (info->flags & ASYNC_USR_MASK)); - state->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - new_serial.irq = new_serial.irq; - - if ((new_serial.irq >= NR_IRQS) || (new_serial.port > 0xffff) || - (new_serial.baud_base == 0) || (new_serial.type < PORT_UNKNOWN) || - (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) || - (new_serial.type == PORT_STARTECH)) { - return -EINVAL; - } - - if ((new_serial.type != state->type) || - (new_serial.xmit_fifo_size <= 0)) - new_serial.xmit_fifo_size = - uart_config[state->type].dfl_xmit_fifo_size; - - /* Make sure address is not already in use */ - if (new_serial.type) { - for (i = 0 ; i < NR_PORTS; i++) - if ((state != &rs_table[i]) && - (rs_table[i].port == new_serial.port) && - rs_table[i].type) - return -EADDRINUSE; - } - - if ((change_port || change_irq) && (state->count > 1)) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - state->baud_base = new_serial.baud_base; - state->flags = ((state->flags & ~ASYNC_FLAGS) | - (new_serial.flags & ASYNC_FLAGS)); - info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) | - (info->flags & ASYNC_INTERNAL_FLAGS)); - state->custom_divisor = new_serial.custom_divisor; - state->type = new_serial.type; - state->close_delay = new_serial.close_delay * HZ/100; - state->closing_wait = new_serial.closing_wait * HZ/100; - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - info->xmit_fifo_size = state->xmit_fifo_size = - new_serial.xmit_fifo_size; - - release_region(state->port,8); - if (change_port || change_irq) { - /* - * We need to shutdown the serial port at the old - * port/irq combination. - */ - shutdown(info); - state->irq = new_serial.irq; - info->port = state->port = new_serial.port; - info->hub6 = state->hub6 = new_serial.hub6; - } - if (state->type != PORT_UNKNOWN) - request_region(state->port,8,"serial(set)"); - - -check_and_exit: - if (!state->port || !state->type) - return 0; - if (info->flags & ASYNC_INITIALIZED) { - if (((old_state.flags & ASYNC_SPD_MASK) != - (state->flags & ASYNC_SPD_MASK)) || - (old_state.custom_divisor != state->custom_divisor)) { - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) - info->tty->alt_speed = 57600; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) - info->tty->alt_speed = 115200; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) - info->tty->alt_speed = 230400; - if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) - info->tty->alt_speed = 460800; - change_speed(info); - } - } else - retval = startup(info); - return retval; -} - - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct async_struct * info, unsigned int *value) -{ - unsigned short status; - unsigned int result; - unsigned long flags; - - save_flags(flags); cli(); - status = serial_inw(info, VAC_UART_INT_STATUS); - restore_flags(flags); - result = ((status & VAC_UART_STATUS_TX_EMPTY) ? TIOCSER_TEMT : 0); - return put_user(result,value); -} - - -static int get_modem_info(struct async_struct * info, unsigned int *value) -{ - unsigned int result; - - result = TIOCM_CAR | TIOCM_DSR; - return put_user(result,value); -} - -static int set_modem_info(struct async_struct * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - - if (get_user(arg, value)) - return -EFAULT; - switch (cmd) { - default: - return -EINVAL; - } - return 0; -} - -static int do_autoconfig(struct async_struct * info) -{ - int retval; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (info->state->count > 1) - return -EBUSY; - - shutdown(info); - - autoconfig(info->state); - - retval = startup(info); - if (retval) - return retval; - return 0; -} - -/* - * rs_break() --- routine which turns the break handling on or off - */ -static void rs_break(struct tty_struct *tty, int break_state) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_break")) - return; - - if (!info->port) - return; - save_flags(flags); cli(); - if (break_state == -1) - serial_outp(info, VAC_UART_MODE, - serial_inp(info, VAC_UART_MODE) | \ - VAC_UART_MODE_SEND_BREAK); - else - serial_outp(info, VAC_UART_MODE, - serial_inp(info, VAC_UART_MODE) & \ - ~VAC_UART_MODE_SEND_BREAK); - restore_flags(flags); -} - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - int error; - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct async_icount cprev, cnow; /* kernel counter temps */ - struct serial_icounter_struct *p_cuser; /* user space */ - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERCONFIG: - return do_autoconfig(info); - - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct async_struct *) arg, - info, sizeof(struct async_struct))) - return -EFAULT; - return 0; - - /* - * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)to change - * - mask passed in arg for lines of interest - * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) - * Caller should use TIOCGICOUNT to see which one it was - */ - case TIOCMIWAIT: - save_flags(flags); cli(); - /* note the counters on entry */ - cprev = info->state->icount; - restore_flags(flags); - while (1) { - interruptible_sleep_on(&info->delta_msr_wait); - /* see if a signal did it */ - if (signal_pending(current)) - return -ERESTARTSYS; - save_flags(flags); cli(); - cnow = info->state->icount; /* atomic copy */ - restore_flags(flags); - if (cnow.rng == cprev.rng && - cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && - cnow.cts == cprev.cts) - return -EIO; /* no change => error */ - if ( ((arg & TIOCM_RNG) && - (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && - (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && - (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && - (cnow.cts != cprev.cts)) ) { - return 0; - } - cprev = cnow; - } - /* NOTREACHED */ - - /* - * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) - * Return: write counters to the user passed counter struct - * NB: both 1->0 and 0->1 transitions are counted except for - * RI where only 0->1 is counted. - */ - case TIOCGICOUNT: - save_flags(flags); cli(); - cnow = info->state->icount; - restore_flags(flags); - p_cuser = (struct serial_icounter_struct *) arg; - error = put_user(cnow.cts, &p_cuser->cts); - if (error) return error; - error = put_user(cnow.dsr, &p_cuser->dsr); - if (error) return error; - error = put_user(cnow.rng, &p_cuser->rng); - if (error) return error; - error = put_user(cnow.dcd, &p_cuser->dcd); - if (error) return error; - error = put_user(cnow.rx, &p_cuser->rx); - if (error) return error; - error = put_user(cnow.tx, &p_cuser->tx); - if (error) return error; - error = put_user(cnow.frame, &p_cuser->frame); - if (error) return error; - error = put_user(cnow.overrun, &p_cuser->overrun); - if (error) return error; - error = put_user(cnow.parity, &p_cuser->parity); - if (error) return error; - error = put_user(cnow.brk, &p_cuser->brk); - if (error) return error; - error = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); - - if (error) return error; - return 0; - - case TIOCSERGWILD: - case TIOCSERSWILD: - /* "setserial -W" is called in Debian boot */ - printk ("TIOCSER?WILD ioctl obsolete, ignored.\n"); - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct async_struct *info = (struct async_struct *)tty->driver_data; - unsigned int cflag = tty->termios->c_cflag; - - if ( (cflag == old_termios->c_cflag) - && ( RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_speed(info); - - /* Handle turning off CRTSCTS */ - if ((old_termios->c_cflag & CRTSCTS) && - !(cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } - -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * async structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - state = info->state; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - DBG_CNT("before DEC-hung"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_close ttys%d, count = %d\n", - info->line, state->count); -#endif - if ((tty->count == 1) && (state->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. state->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - baget_printk("rs_close: bad serial port count; " - "tty->count is 1, " - "state->count is %d\n", state->count); - state->count = 1; - } - if (--state->count < 0) { - baget_printk("rs_close: bad serial port count for " - "ttys%d: %d\n", - info->line, state->count); - state->count = 0; - } - if (state->count) { - DBG_CNT("before DEC-2"); - MOD_DEC_USE_COUNT; - restore_flags(flags); - return; - } - info->flags |= ASYNC_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - info->IER &= ~(VAC_UART_INT_RX_BREAK_CHANGE | VAC_UART_INT_RX_ERRS); - info->read_status_mask &= ~VAC_UART_STATUS_RX_READY; - if (info->flags & ASYNC_INITIALIZED) { - serial_outw(info, VAC_UART_INT_MASK, info->IER); - /* - * Before we drop DTR, make sure the UART transmitter - * has completely drained; this is especially - * important if there is a transmit FIFO! - */ - rs_wait_until_sent(tty, info->timeout); - } - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - wake_up_interruptible(&info->close_wait); - MOD_DEC_USE_COUNT; - restore_flags(flags); -} - -/* - * rs_wait_until_sent() --- wait until the transmitter is empty - */ -static void rs_wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - unsigned long orig_jiffies, char_time; - int lsr; - - if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent")) - return; - - if (info->state->type == PORT_UNKNOWN) - return; - - if (info->xmit_fifo_size == 0) - return; /* Just in case.... */ - - orig_jiffies = jiffies; - /* - * Set the check interval to be 1/5 of the estimated time to - * send a single character, and make it at least 1. The check - * interval should also be less than the timeout. - * - * Note: we have to use pretty tight timings here to satisfy - * the NIST-PCTS. - */ - char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; - char_time = char_time / 5; - if (char_time == 0) - char_time = 1; - if (timeout) - char_time = MIN(char_time, timeout); -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("In rs_wait_until_sent(%d) check=%lu...", - timeout, char_time); - baget_printk("jiff=%lu...", jiffies); -#endif - while (!((lsr = serial_inp(info, VAC_UART_INT_STATUS)) & \ - VAC_UART_STATUS_TX_EMPTY)) { -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("lsr = %d (jiff=%lu)...", lsr, jiffies); -#endif - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(char_time); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - current->state = TASK_RUNNING; -#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT - baget_printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); -#endif -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -static void rs_hangup(struct tty_struct *tty) -{ - struct async_struct * info = (struct async_struct *)tty->driver_data; - struct serial_state *state = info->state; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - state = info->state; - - rs_flush_buffer(tty); - shutdown(info); - info->event = 0; - state->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct async_struct *info) -{ - DECLARE_WAITQUEUE(wait, current); - struct serial_state *state = info->state; - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, state->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready before block: ttys%d, count = %d\n", - state->line, state->count); -#endif - save_flags(flags); cli(); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - state->count--; - } - restore_flags(flags); - info->blocked_open++; - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ASYNC_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ASYNC_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ASYNC_CLOSING)) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (extra_count) - state->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - baget_printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, state->count); -#endif - if (retval) - return retval; - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; -} - -static int get_async_struct(int line, struct async_struct **ret_info) -{ - struct async_struct *info; - struct serial_state *sstate; - - sstate = rs_table + line; - sstate->count++; - if (sstate->info) { - *ret_info = sstate->info; - return 0; - } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); - if (!info) { - sstate->count--; - return -ENOMEM; - } - memset(info, 0, sizeof(struct async_struct)); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->delta_msr_wait); - info->magic = SERIAL_MAGIC; - info->port = sstate->port; - info->flags = sstate->flags; - info->xmit_fifo_size = sstate->xmit_fifo_size; - info->line = line; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->state = sstate; - if (sstate->info) { - kfree(info); - *ret_info = sstate->info; - return 0; - } - *ret_info = sstate->info = info; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its async structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -static int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct async_struct *info; - int retval, line; - unsigned long page; - - MOD_INC_USE_COUNT; - line = tty->index; - if ((line < 0) || (line >= NR_PORTS)) { - MOD_DEC_USE_COUNT; - return -ENODEV; - } - retval = get_async_struct(line, &info); - if (retval) { - MOD_DEC_USE_COUNT; - return retval; - } - tty->driver_data = info; - info->tty = tty; - if (serial_paranoia_check(info, tty->name, "rs_open")) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return -ENODEV; - } - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open %s, count = %d\n", tty->name, - info->state->count); -#endif - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return -ENOMEM; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - - /* - * If the port is the middle of closing, bail out now - */ - if (tty_hung_up_p(filp) || - (info->flags & ASYNC_CLOSING)) { - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ -#ifdef SERIAL_DO_RESTART - return ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); -#else - return -EAGAIN; -#endif - } - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ - return retval; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - /* MOD_DEC_USE_COUNT; "info->tty" will cause this */ -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open returning after block_til_ready " - "with %d\n", - retval); -#endif - return retval; - } - -#ifdef CONFIG_SERIAL_CONSOLE - if (sercons.cflag && sercons.index == line) { - tty->termios->c_cflag = sercons.cflag; - sercons.cflag = 0; - change_speed(info); - } -#endif - -#ifdef SERIAL_DEBUG_OPEN - baget_printk("rs_open %s successful...", tty->name); -#endif - return 0; -} - -/* - * /proc fs routines.... - */ - -static inline int line_info(char *buf, struct serial_state *state) -{ - struct async_struct *info = state->info, scr_info; - int ret; - - ret = sprintf(buf, "%d: uart:%s port:%X irq:%d", - state->line, uart_config[state->type].name, - state->port, state->irq); - - if (!state->port || (state->type == PORT_UNKNOWN)) { - ret += sprintf(buf+ret, "\n"); - return ret; - } - - /* - * Figure out the current RS-232 lines - */ - if (!info) { - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - info->quot = 0; - info->tty = 0; - } - - if (info->quot) { - ret += sprintf(buf+ret, " baud:%d", - state->baud_base / info->quot); - } - - ret += sprintf(buf+ret, " tx:%d rx:%d", - state->icount.tx, state->icount.rx); - - if (state->icount.frame) - ret += sprintf(buf+ret, " fe:%d", state->icount.frame); - - if (state->icount.parity) - ret += sprintf(buf+ret, " pe:%d", state->icount.parity); - - if (state->icount.brk) - ret += sprintf(buf+ret, " brk:%d", state->icount.brk); - - if (state->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", state->icount.overrun); - - return ret; -} - -int rs_read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int i, len = 0, l; - off_t begin = 0; - - len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version); - for (i = 0; i < NR_PORTS && len < 4000; i++) { - l = line_info(page + len, &rs_table[i]); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - } - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * --------------------------------------------------------------------- - * rs_init() and friends - * - * rs_init() is called at boot-time to initialize the serial driver. - * --------------------------------------------------------------------- - */ - -/* - * This routine prints out the appropriate serial driver version - * number, and identifies which options were configured into this - * driver. - */ -static _INLINE_ void show_serial_version(void) -{ - printk(KERN_INFO "%s version %s with", serial_name, serial_version); -#ifdef CONFIG_SERIAL_SHARE_IRQ - printk(" SHARE_IRQ"); -#endif -#define SERIAL_OPT -#ifdef CONFIG_SERIAL_DETECT_IRQ - printk(" DETECT_IRQ"); -#endif -#ifdef SERIAL_OPT - printk(" enabled\n"); -#else - printk(" no serial options enabled\n"); -#endif -#undef SERIAL_OPT -} - - -/* - * This routine is called by rs_init() to initialize a specific serial - * port. It determines what type of UART chip this serial port is - * using: 8250, 16450, 16550, 16550A. The important question is - * whether or not this UART is a 16550A or not, since this will - * determine whether or not we can use its FIFO features or not. - */ - -/* - * Functionality of this function is reduced: we already know we have a VAC, - * but still need to perform some important actions (see code :-). - */ -static void autoconfig(struct serial_state * state) -{ - struct async_struct *info, scr_info; - unsigned long flags; - - /* Setting up important parameters */ - state->type = VAC_UART_TYPE; - state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size; - - info = &scr_info; /* This is just for serial_{in,out} */ - - info->magic = SERIAL_MAGIC; - info->port = state->port; - info->flags = state->flags; - - save_flags(flags); cli(); - - /* + Flush VAC input fifo */ - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - (void)serial_in(info, VAC_UART_RX); - - /* Disable interrupts */ - serial_outp(info, VAC_UART_INT_MASK, 0); - - restore_flags(flags); -} - -int register_serial(struct serial_struct *req); -void unregister_serial(int line); - -EXPORT_SYMBOL(register_serial); -EXPORT_SYMBOL(unregister_serial); - -/* - * Important function for VAC UART check and reanimation. - */ - -static void rs_timer(unsigned long dummy) -{ - static unsigned long last_strobe = 0; - struct async_struct *info; - unsigned int i; - unsigned long flags; - - if ((jiffies - last_strobe) >= RS_STROBE_TIME) { - for (i=1; i < NR_IRQS; i++) { - info = IRQ_ports[i]; - if (!info) - continue; - save_flags(flags); cli(); -#ifdef CONFIG_SERIAL_SHARE_IRQ - if (info->next_port) { - do { - serial_out(info, VAC_UART_INT_MASK, 0); - info->IER |= VAC_UART_INT_TX_EMPTY; - serial_out(info, VAC_UART_INT_MASK, - info->IER); - info = info->next_port; - } while (info); - rs_interrupt(i, NULL, NULL); - } else -#endif /* CONFIG_SERIAL_SHARE_IRQ */ - rs_interrupt_single(i, NULL, NULL); - restore_flags(flags); - } - } - last_strobe = jiffies; - mod_timer(&vacs_timer, jiffies + RS_STROBE_TIME); - - /* - * It looks this code for case we share IRQ with console... - */ - - if (IRQ_ports[0]) { - save_flags(flags); cli(); -#ifdef CONFIG_SERIAL_SHARE_IRQ - rs_interrupt(0, NULL, NULL); -#else - rs_interrupt_single(0, NULL, NULL); -#endif - restore_flags(flags); - - mod_timer(&vacs_timer, jiffies + IRQ_timeout[0] - 2); - } -} - -static struct tty_operations rs_ops = { - .open = rs_open, - .close = rs_close, - .write = rs_write, - .put_char = rs_put_char, - .flush_chars = rs_flush_chars, - .write_room = rs_write_room, - .chars_in_buffer = rs_chars_in_buffer, - .flush_buffer = rs_flush_buffer, - .ioctl = rs_ioctl, - .throttle = rs_throttle, - .unthrottle = rs_unthrottle, - .send_xchar = rs_send_xchar, - .set_termios = rs_set_termios, - .stop = rs_stop, - .start = rs_start, - .hangup = rs_hangup, - .break_ctl = rs_break, - .wait_until_sent = rs_wait_until_sent, - .read_proc = rs_read_proc, -}; - -/* - * The serial driver boot-time initialization code! - */ -int __init rs_init(void) -{ - int i; - struct serial_state * state; - extern void atomwide_serial_init (void); - extern void dualsp_serial_init (void); - -#ifdef CONFIG_ATOMWIDE_SERIAL - atomwide_serial_init (); -#endif -#ifdef CONFIG_DUALSP_SERIAL - dualsp_serial_init (); -#endif - - init_bh(SERIAL_BH, do_serial_bh); - init_timer(&vacs_timer); - vacs_timer.function = rs_timer; - vacs_timer.expires = 0; - - for (i = 0; i < NR_IRQS; i++) { - IRQ_ports[i] = 0; - IRQ_timeout[i] = 0; - } - - -/* - * It is not a good idea to share interrupts with console, - * but it looks we cannot avoid it. - */ -#if 0 - -#ifdef CONFIG_SERIAL_CONSOLE - /* - * The interrupt of the serial console port - * can't be shared. - */ - if (sercons.flags & CON_CONSDEV) { - for(i = 0; i < NR_PORTS; i++) - if (i != sercons.index && - rs_table[i].irq == rs_table[sercons.index].irq) - rs_table[i].irq = 0; - } -#endif - -#endif - serial_driver = alloc_tty_driver(NR_PORTS); - if (!serial_driver) - return -ENOMEM; - - show_serial_version(); - - /* Initialize the tty_driver structure */ - - serial_driver->driver_name = "serial"; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &rs_ops); - - if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); - - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - state->magic = SSTATE_MAGIC; - state->line = i; - state->type = PORT_UNKNOWN; - state->custom_divisor = 0; - state->close_delay = 5*HZ/10; - state->closing_wait = 30*HZ; - state->icount.cts = state->icount.dsr = - state->icount.rng = state->icount.dcd = 0; - state->icount.rx = state->icount.tx = 0; - state->icount.frame = state->icount.parity = 0; - state->icount.overrun = state->icount.brk = 0; - state->irq = state->irq; - if (check_region(state->port,8)) - continue; - if (state->flags & ASYNC_BOOT_AUTOCONF) - autoconfig(state); - } - - /* - * Detect the IRQ only once every port is initialised, - * because some 16450 do not reset to 0 the MCR register. - */ - for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) { - if (state->type == PORT_UNKNOWN) - continue; - printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n", - state->line, - (state->flags & ASYNC_FOURPORT) ? " FourPort" : "", - state->port, state->irq, - uart_config[state->type].name); - } - return 0; -} - -/* - * register_serial and unregister_serial allows for serial ports to be - * configured at run-time, to support PCMCIA modems. - */ -int register_serial(struct serial_struct *req) -{ - int i; - unsigned long flags; - struct serial_state *state; - - save_flags(flags); - cli(); - for (i = 0; i < NR_PORTS; i++) { - if (rs_table[i].port == req->port) - break; - } - if (i == NR_PORTS) { - for (i = 0; i < NR_PORTS; i++) - if ((rs_table[i].type == PORT_UNKNOWN) && - (rs_table[i].count == 0)) - break; - } - if (i == NR_PORTS) { - restore_flags(flags); - return -1; - } - state = &rs_table[i]; - if (rs_table[i].count) { - restore_flags(flags); - printk("Couldn't configure serial #%d (port=%d,irq=%d): " - "device already open\n", i, req->port, req->irq); - return -1; - } - state->irq = req->irq; - state->port = req->port; - state->flags = req->flags; - - autoconfig(state); - if (state->type == PORT_UNKNOWN) { - restore_flags(flags); - printk("register_serial(): autoconfig failed\n"); - return -1; - } - restore_flags(flags); - - printk(KERN_INFO "tty%02d at 0x%04x (irq = %d) is a %s\n", - state->line, state->port, state->irq, - uart_config[state->type].name); - return state->line; -} - -void unregister_serial(int line) -{ - unsigned long flags; - struct serial_state *state = &rs_table[line]; - - save_flags(flags); - cli(); - if (state->info && state->info->tty) - tty_hangup(state->info->tty); - state->type = PORT_UNKNOWN; - printk(KERN_INFO "tty%02d unloaded\n", state->line); - restore_flags(flags); -} - -#ifdef MODULE -int init_module(void) -{ - return rs_init(); -} - -void cleanup_module(void) -{ - unsigned long flags; - int e1, e2; - int i; - - printk("Unloading %s: version %s\n", serial_name, serial_version); - save_flags(flags); - cli(); - - del_timer_sync(&vacs_timer); - remove_bh(SERIAL_BH); - - if ((e1 = tty_unregister_driver(serial_driver))) - printk("SERIAL: failed to unregister serial driver (%d)\n", - e1); - restore_flags(flags); - put_tty_driver(serial_driver); - - for (i = 0; i < NR_PORTS; i++) { - if (rs_table[i].type != PORT_UNKNOWN) - release_region(rs_table[i].port, 8); - } - if (tmp_buf) { - free_page((unsigned long) tmp_buf); - tmp_buf = NULL; - } -} -#endif /* MODULE */ - - -/* - * ------------------------------------------------------------ - * Serial console driver - * ------------------------------------------------------------ - */ -#ifdef CONFIG_SERIAL_CONSOLE - -#define BOTH_EMPTY (VAC_UART_STATUS_TX_EMPTY | VAC_UART_STATUS_TX_EMPTY) - -/* - * Wait for transmitter & holding register to empty - */ -static inline void wait_for_xmitr(struct async_struct *info) -{ - int lsr; - unsigned int tmout = 1000000; - - do { - lsr = serial_inp(info, VAC_UART_INT_STATUS); - if (--tmout == 0) break; - } while ((lsr & BOTH_EMPTY) != BOTH_EMPTY); -} - -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - */ -static void serial_console_write(struct console *co, const char *s, - unsigned count) -{ - struct serial_state *ser; - int ier; - unsigned i; - struct async_struct scr_info; /* serial_{in,out} because HUB6 */ - - ser = rs_table + co->index; - scr_info.magic = SERIAL_MAGIC; - scr_info.port = ser->port; - scr_info.flags = ser->flags; - - /* - * First save the IER then disable the interrupts - */ - ier = serial_inp(&scr_info, VAC_UART_INT_MASK); - serial_outw(&scr_info, VAC_UART_INT_MASK, 0x00); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++, s++) { - wait_for_xmitr(&scr_info); - - /* - * Send the character out. - * If a LF, also do CR... - */ - serial_outp(&scr_info, VAC_UART_TX, (unsigned short)*s << 8); - if (*s == 10) { - wait_for_xmitr(&scr_info); - serial_outp(&scr_info, VAC_UART_TX, 13 << 8); - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - wait_for_xmitr(&scr_info); - serial_outp(&scr_info, VAC_UART_INT_MASK, ier); -} - -static struct tty_driver *serial_console_device(struct console *c, int *index) -{ - *index = c->index; - return serial_driver; -} - -/* - * Setup initial baud/bits/parity. We do two things here: - * - construct a cflag setting for the first rs_open() - * - initialize the serial port - * Return non-zero if we didn't find a serial port. - */ -static int __init serial_console_setup(struct console *co, char *options) -{ - struct serial_state *ser; - unsigned cval; - int baud = 9600; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - int quot = 0; - char *s; - struct async_struct scr_info; /* serial_{in,out} because HUB6 */ - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - co->cflag = cflag; - - /* - * Divisor, bytesize and parity - */ - ser = rs_table + co->index; - scr_info.magic = SERIAL_MAGIC; - scr_info.port = ser->port; - scr_info.flags = ser->flags; - - quot = ser->baud_base / baud; - cval = cflag & (CSIZE | CSTOPB); - - cval >>= 4; - - cval &= ~VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARENB) - cval |= VAC_UART_MODE_PARITY_ENABLE; - if (cflag & PARODD) - cval |= VAC_UART_MODE_PARITY_ODD; - - /* - * Disable UART interrupts, set DTR and RTS high - * and set speed. - */ - switch (baud) { - default: - case 9600: - cval |= VAC_UART_MODE_BAUD(7); - break; - case 4800: - cval |= VAC_UART_MODE_BAUD(6); - break; - case 2400: - cval |= VAC_UART_MODE_BAUD(5); - break; - case 1200: - cval |= VAC_UART_MODE_BAUD(4); - break; - case 600: - cval |= VAC_UART_MODE_BAUD(3); - break; - case 300: - cval |= VAC_UART_MODE_BAUD(2); - break; -#ifndef QUAD_UART_SPEED - case 150: -#else - case 38400: -#endif - cval |= VAC_UART_MODE_BAUD(1); - break; -#ifndef QUAD_UART_SPEED - case 75: -#else - case 19200: -#endif - cval |= VAC_UART_MODE_BAUD(0); - break; - } - - /* Baget VAC need some adjustments for computed value */ - cval = vac_uart_mode_fixup(cval); - - serial_outp(&scr_info, VAC_UART_MODE, cval); - serial_outp(&scr_info, VAC_UART_INT_MASK, 0); - - return 0; -} - -static struct console sercons = { - .name = "ttyS", - .write = serial_console_write, - .device = serial_console_device, - .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Register console. - */ -long __init serial_console_init(long kmem_start, long kmem_end) -{ - register_console(&sercons); - return kmem_start; -} -#endif - -#ifdef CONFIG_REMOTE_DEBUG -#undef PRINT_DEBUG_PORT_INFO - -/* - * This is the interface to the remote debugger stub. - * I've put that here to be able to control the serial - * device more directly. - */ - -static int initialized; - -static int rs_debug_init(struct async_struct *info) -{ - int quot; - - autoconfig(info); /* autoconfigure ttyS0, whatever that is */ - -#ifdef PRINT_DEBUG_PORT_INFO - baget_printk("kgdb debug interface:: tty%02d at 0x%04x", - info->line, info->port); - switch (info->type) { - case PORT_8250: - baget_printk(" is a 8250\n"); - break; - case PORT_16450: - baget_printk(" is a 16450\n"); - break; - case PORT_16550: - baget_printk(" is a 16550\n"); - break; - case PORT_16550A: - baget_printk(" is a 16550A\n"); - break; - case PORT_16650: - baget_printk(" is a 16650\n"); - break; - default: - baget_printk(" is of unknown type -- unusable\n"); - break; - } -#endif - - if (info->port == PORT_UNKNOWN) - return -1; - - /* - * Clear all interrupts - */ - - (void)serial_inp(info, VAC_UART_INT_STATUS); - (void)serial_inp(info, VAC_UART_RX); - - /* - * Now, initialize the UART - */ - serial_outp(info,VAC_UART_MODE,VAC_UART_MODE_INITIAL); /* reset DLAB */ - if (info->flags & ASYNC_FOURPORT) { - info->MCR = UART_MCR_DTR | UART_MCR_RTS; - info->MCR_noint = UART_MCR_DTR | UART_MCR_OUT1; - } else { - info->MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - info->MCR_noint = UART_MCR_DTR | UART_MCR_RTS; - } - - info->MCR = info->MCR_noint; /* no interrupts, please */ - /* - * and set the speed of the serial port - * (currently hardwired to 9600 8N1 - */ - - quot = info->baud_base / 9600; /* baud rate is fixed to 9600 */ - /* FIXME: if rs_debug interface is needed, we need to set speed here */ - - return 0; -} - -int putDebugChar(char c) -{ - struct async_struct *info = rs_table; - - if (!initialized) { /* need to init device first */ - if (rs_debug_init(info) == 0) - initialized = 1; - else - return 0; - } - - while ((serial_inw(info, VAC_UART_INT_STATUS) & \ - VAC_UART_STATUS_TX_EMPTY) == 0) - ; - serial_out(info, VAC_UART_TX, (unsigned short)c << 8); - - return 1; -} - -char getDebugChar(void) -{ - struct async_struct *info = rs_table; - - if (!initialized) { /* need to init device first */ - if (rs_debug_init(info) == 0) - initialized = 1; - else - return 0; - } - while (!(serial_inw(info, VAC_UART_INT_STATUS) & \ - VAC_UART_STATUS_RX_READY)) - ; - - return(serial_inp(info, VAC_UART_RX)); -} - -#endif /* CONFIG_REMOTE_DEBUG */ diff -Nru a/arch/mips/baget/wbflush.c b/arch/mips/baget/wbflush.c --- a/arch/mips/baget/wbflush.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,24 +0,0 @@ -/* - * Setup the right wbflush routine for Baget/MIPS. - * - * Copyright (C) 1999 Gleb Raiko & Vladimir Roganov - */ - -#include <linux/init.h> -#include <asm/bootinfo.h> - -void (*__wbflush) (void); - -static void wbflush_baget(void); - -void __init wbflush_setup(void) -{ - __wbflush = wbflush_baget; -} - -/* - * Baget/MIPS doesn't need to write back the WB. - */ -static void wbflush_baget(void) -{ -} diff -Nru a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile --- a/arch/mips/boot/Makefile Fri Jun 27 14:20:00 2003 +++ b/arch/mips/boot/Makefile Fri Jun 27 14:20:00 2003 @@ -3,11 +3,9 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1995, 1998, 2001 by Ralf Baechle +# Copyright (C) 1995, 1998, 2001, 2002 by Ralf Baechle # -OBJS = milo.o a.out.o - # # Some DECstations need all possible sections of an ECOFF executable # @@ -21,25 +19,33 @@ # Drop some uninteresting sections in the kernel. # This is only relevant for ELF kernels but doesn't hurt a.out # -drop-sections = .reginfo .mdebug +drop-sections = .reginfo .mdebug .comment .note strip-flags = $(addprefix --remove-section=,$(drop-sections)) all: vmlinux.ecoff addinitrd -vmlinux.ecoff: elf2ecoff $(TOPDIR)/vmlinux - ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS) +vmlinux.rm200: vmlinux + $(OBJCOPY) \ + --change-addresses=0xfffffffc \ + -O elf32-tradlittlemips \ + $(strip-flags) \ + $< $@ + +vmlinux.ecoff: $(obj)/elf2ecoff vmlinux + ./elf2ecoff vmlinux $(obj)/vmlinux.ecoff $(E2EFLAGS) -elf2ecoff: elf2ecoff.c +$(obj)/elf2ecoff: $(obj)/elf2ecoff.c $(HOSTCC) -o $@ $^ -addinitrd: addinitrd.c +$(obj)/addinitrd: $(obj)/addinitrd.c $(HOSTCC) -o $@ $^ -clean: - rm -f vmlinux.ecoff - rm -f zImage zImage.tmp - -mrproper: - rm -f vmlinux.ecoff - rm -f addinitrd - rm -f elf2ecoff +archhelp: + @echo '* vmlinux.rm200 - Bootable kernel image for RM200C' + +CLEAN_FILES += addinitrd \ + elf2ecoff \ + vmlinux.ecoff \ + vmlinux.rm200 \ + zImage.tmp \ + zImage diff -Nru a/arch/mips/boot/addinitrd.c b/arch/mips/boot/addinitrd.c --- a/arch/mips/boot/addinitrd.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/boot/addinitrd.c Fri Jun 27 14:19:59 2003 @@ -8,6 +8,8 @@ #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> +#include <stdio.h> +#include <netinet/in.h> #include "ecoff.h" @@ -44,7 +46,7 @@ char buf[1024]; unsigned long loadaddr; unsigned long initrd_header[2]; - int i; + int i,cnt; int swab = 0; if (argc != 4) { @@ -60,7 +62,6 @@ die ("read aout header"); if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs) die ("read section headers"); - /* * check whether the file is good for us */ @@ -81,7 +82,7 @@ die ("open initrd"); if (fstat (fd_initrd, &st) < 0) die ("fstat initrd"); - loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size) + loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size) + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8; if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size))) loadaddr += MIPS_PAGE_SIZE; @@ -98,9 +99,20 @@ die ("write aout header"); if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs) die ("write section headers"); - while ((i = read (fd_vmlinux, buf, sizeof buf)) > 0) + /* skip padding */ + if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1) + die ("lseek vmlinux"); + if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1) + die ("lseek outfile"); + /* copy text segment */ + cnt = SWAB(eaout.tsize); + while (cnt) { + if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0) + die ("read vmlinux"); if (write (fd_outfile, buf, i) != i) die ("write vmlinux"); + cnt -= i; + } if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header) die ("write initrd header"); while ((i = read (fd_initrd, buf, sizeof buf)) > 0) diff -Nru a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c --- a/arch/mips/boot/elf2ecoff.c Fri Jun 27 14:20:05 2003 +++ b/arch/mips/boot/elf2ecoff.c Fri Jun 27 14:20:05 2003 @@ -41,487 +41,114 @@ #include <unistd.h> #include <elf.h> #include <limits.h> +#include <netinet/in.h> +#include <stdlib.h> #include "ecoff.h" /* * Some extra ELF definitions */ -#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ /* -------------------------------------------------------------------- */ struct sect { - unsigned long vaddr; - unsigned long len; + unsigned long vaddr; + unsigned long len; }; -int phcmp (); -char *saveRead (int file, off_t offset, off_t len, char *name); -int copy (int, int, off_t, off_t); -int translate_syms (int, int, off_t, off_t, off_t, off_t); -void convert_elf_hdr (Elf32_Ehdr *); -void convert_elf_phdrs (Elf32_Phdr *, int); -void convert_elf_shdrs (Elf32_Shdr *, int); -void convert_ecoff_filehdr(struct filehdr *); -void convert_ecoff_aouthdr(struct aouthdr *); -void convert_ecoff_esecs(struct scnhdr *, int); -extern int errno; int *symTypeTable; int must_convert_endian = 0; int format_bigendian = 0; -main (int argc, char **argv, char **envp) +static void copy(int out, int in, off_t offset, off_t size) { - Elf32_Ehdr ex; - Elf32_Phdr *ph; - Elf32_Shdr *sh; - Elf32_Sym *symtab; - char *shstrtab; - int strtabix, symtabix; - int i, pad; - struct sect text, data, bss; - struct filehdr efh; - struct aouthdr eah; - struct scnhdr esecs [6]; - int infile, outfile; - unsigned long cur_vma = ULONG_MAX; - int addflag = 0; - int nosecs; - - text.len = data.len = bss.len = 0; - text.vaddr = data.vaddr = bss.vaddr = 0; - - /* Check args... */ - if (argc < 3 || argc > 4) - { - usage: - fprintf (stderr, - "usage: elf2aout <elf executable> <a.out executable> [-a]\n"); - exit (1); - } - if (argc == 4) - { - if (strcmp (argv [3], "-a")) - goto usage; - addflag = 1; - } - - /* Try the input file... */ - if ((infile = open (argv [1], O_RDONLY)) < 0) - { - fprintf (stderr, "Can't open %s for read: %s\n", - argv [1], strerror (errno)); - exit (1); - } - - /* Read the header, which is at the beginning of the file... */ - i = read (infile, &ex, sizeof ex); - if (i != sizeof ex) - { - fprintf (stderr, "ex: %s: %s.\n", - argv [1], i ? strerror (errno) : "End of file reached"); - exit (1); - } - - if (ex.e_ident[EI_DATA] == ELFDATA2MSB) - format_bigendian = 1; - - if (ntohs (0xaa55) == 0xaa55) { - if (!format_bigendian) - must_convert_endian = 1; - } else { - if (format_bigendian) - must_convert_endian = 1; - } - if (must_convert_endian) - convert_elf_hdr (&ex); - - /* Read the program headers... */ - ph = (Elf32_Phdr *)saveRead (infile, ex.e_phoff, - ex.e_phnum * sizeof (Elf32_Phdr), "ph"); - if (must_convert_endian) - convert_elf_phdrs (ph, ex.e_phnum); - /* Read the section headers... */ - sh = (Elf32_Shdr *)saveRead (infile, ex.e_shoff, - ex.e_shnum * sizeof (Elf32_Shdr), "sh"); - if (must_convert_endian) - convert_elf_shdrs (sh, ex.e_shnum); - /* Read in the section string table. */ - shstrtab = saveRead (infile, sh [ex.e_shstrndx].sh_offset, - sh [ex.e_shstrndx].sh_size, "shstrtab"); - - /* Figure out if we can cram the program header into an ECOFF - header... Basically, we can't handle anything but loadable - segments, but we can ignore some kinds of segments. We can't - handle holes in the address space. Segments may be out of order, - so we sort them first. */ - - qsort (ph, ex.e_phnum, sizeof (Elf32_Phdr), phcmp); - - for (i = 0; i < ex.e_phnum; i++) - { - /* Section types we can ignore... */ - if (ph [i].p_type == PT_NULL || ph [i].p_type == PT_NOTE || - ph [i].p_type == PT_PHDR || ph [i].p_type == PT_MIPS_REGINFO) - continue; - /* Section types we can't handle... */ - else if (ph [i].p_type != PT_LOAD) - { - fprintf (stderr, "Program header %d type %d can't be converted.\n"); - exit (1); - } - /* Writable (data) segment? */ - if (ph [i].p_flags & PF_W) - { - struct sect ndata, nbss; - - ndata.vaddr = ph [i].p_vaddr; - ndata.len = ph [i].p_filesz; - nbss.vaddr = ph [i].p_vaddr + ph [i].p_filesz; - nbss.len = ph [i].p_memsz - ph [i].p_filesz; - - combine (&data, &ndata, 0); - combine (&bss, &nbss, 1); - } - else - { - struct sect ntxt; - - ntxt.vaddr = ph [i].p_vaddr; - ntxt.len = ph [i].p_filesz; - - combine (&text, &ntxt, 0); - } - /* Remember the lowest segment start address. */ - if (ph [i].p_vaddr < cur_vma) - cur_vma = ph [i].p_vaddr; - } - - /* Sections must be in order to be converted... */ - if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr || - text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr) - { - fprintf (stderr, "Sections ordering prevents a.out conversion.\n"); - exit (1); - } - - /* If there's a data section but no text section, then the loader - combined everything into one section. That needs to be the - text section, so just make the data section zero length following - text. */ - if (data.len && !text.len) - { - text = data; - data.vaddr = text.vaddr + text.len; - data.len = 0; - } - - /* If there is a gap between text and data, we'll fill it when we copy - the data, so update the length of the text segment as represented in - a.out to reflect that, since a.out doesn't allow gaps in the program - address space. */ - if (text.vaddr + text.len < data.vaddr) - text.len = data.vaddr - text.vaddr; - - /* We now have enough information to cons up an a.out header... */ - eah.magic = OMAGIC; - eah.vstamp = 200; - eah.tsize = text.len; - eah.dsize = data.len; - eah.bsize = bss.len; - eah.entry = ex.e_entry; - eah.text_start = text.vaddr; - eah.data_start = data.vaddr; - eah.bss_start = bss.vaddr; - eah.gprmask = 0xf3fffffe; - memset (&eah.cprmask, '\0', sizeof eah.cprmask); - eah.gp_value = 0; /* unused. */ - - if (format_bigendian) - efh.f_magic = MIPSEBMAGIC; - else - efh.f_magic = MIPSELMAGIC; - if (addflag) - nosecs = 6; - else - nosecs = 3; - efh.f_nscns = nosecs; - efh.f_timdat = 0; /* bogus */ - efh.f_symptr = 0; - efh.f_nsyms = 0; - efh.f_opthdr = sizeof eah; - efh.f_flags = 0x100f; /* Stripped, not sharable. */ - - memset (esecs, 0, sizeof esecs); - strcpy (esecs [0].s_name, ".text"); - strcpy (esecs [1].s_name, ".data"); - strcpy (esecs [2].s_name, ".bss"); - if (addflag) { - strcpy (esecs [3].s_name, ".rdata"); - strcpy (esecs [4].s_name, ".sdata"); - strcpy (esecs [5].s_name, ".sbss"); - } - esecs [0].s_paddr = esecs [0].s_vaddr = eah.text_start; - esecs [1].s_paddr = esecs [1].s_vaddr = eah.data_start; - esecs [2].s_paddr = esecs [2].s_vaddr = eah.bss_start; - if (addflag) { - esecs [3].s_paddr = esecs [3].s_vaddr = 0; - esecs [4].s_paddr = esecs [4].s_vaddr = 0; - esecs [5].s_paddr = esecs [5].s_vaddr = 0; - } - esecs [0].s_size = eah.tsize; - esecs [1].s_size = eah.dsize; - esecs [2].s_size = eah.bsize; - if (addflag) { - esecs [3].s_size = 0; - esecs [4].s_size = 0; - esecs [5].s_size = 0; - } - esecs [0].s_scnptr = N_TXTOFF (efh, eah); - esecs [1].s_scnptr = N_DATOFF (efh, eah); -#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10 -#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1)) - esecs [2].s_scnptr = esecs [1].s_scnptr + - ECOFF_ROUND (esecs [1].s_size, ECOFF_SEGMENT_ALIGNMENT (&eah)); - if (addflag) { - esecs [3].s_scnptr = 0; - esecs [4].s_scnptr = 0; - esecs [5].s_scnptr = 0; - } - esecs [0].s_relptr = esecs [1].s_relptr - = esecs [2].s_relptr = 0; - esecs [0].s_lnnoptr = esecs [1].s_lnnoptr - = esecs [2].s_lnnoptr = 0; - esecs [0].s_nreloc = esecs [1].s_nreloc = esecs [2].s_nreloc = 0; - esecs [0].s_nlnno = esecs [1].s_nlnno = esecs [2].s_nlnno = 0; - if (addflag) { - esecs [3].s_relptr = esecs [4].s_relptr - = esecs [5].s_relptr = 0; - esecs [3].s_lnnoptr = esecs [4].s_lnnoptr - = esecs [5].s_lnnoptr = 0; - esecs [3].s_nreloc = esecs [4].s_nreloc = esecs [5].s_nreloc = 0; - esecs [3].s_nlnno = esecs [4].s_nlnno = esecs [5].s_nlnno = 0; - } - esecs [0].s_flags = 0x20; - esecs [1].s_flags = 0x40; - esecs [2].s_flags = 0x82; - if (addflag) { - esecs [3].s_flags = 0x100; - esecs [4].s_flags = 0x200; - esecs [5].s_flags = 0x400; - } - - /* Make the output file... */ - if ((outfile = open (argv [2], O_WRONLY | O_CREAT, 0777)) < 0) - { - fprintf (stderr, "Unable to create %s: %s\n", argv [2], strerror (errno)); - exit (1); - } - - if (must_convert_endian) - convert_ecoff_filehdr (&efh); - /* Write the headers... */ - i = write (outfile, &efh, sizeof efh); - if (i != sizeof efh) - { - perror ("efh: write"); - exit (1); - - for (i = 0; i < nosecs; i++) - { - printf ("Section %d: %s phys %x size %x file offset %x\n", - i, esecs [i].s_name, esecs [i].s_paddr, - esecs [i].s_size, esecs [i].s_scnptr); - } - } - fprintf (stderr, "wrote %d byte file header.\n", i); - - if (must_convert_endian) - convert_ecoff_aouthdr (&eah); - i = write (outfile, &eah, sizeof eah); - if (i != sizeof eah) - { - perror ("eah: write"); - exit (1); - } - fprintf (stderr, "wrote %d byte a.out header.\n", i); - - if (must_convert_endian) - convert_ecoff_esecs (&esecs[0], nosecs); - i = write (outfile, &esecs, nosecs * sizeof(struct scnhdr)); - if (i != nosecs * sizeof(struct scnhdr)) - { - perror ("esecs: write"); - exit (1); - } - fprintf (stderr, "wrote %d bytes of section headers.\n", i); - - if (pad = ((sizeof efh + sizeof eah + nosecs * sizeof(struct scnhdr)) & 15)) - { - pad = 16 - pad; - i = write (outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad); - if (i < 0) - { - perror ("ipad: write"); - exit (1); - } - fprintf (stderr, "wrote %d byte pad.\n", i); - } + char ibuf[4096]; + int remaining, cur, count; - /* Copy the loadable sections. Zero-fill any gaps less than 64k; - complain about any zero-filling, and die if we're asked to zero-fill - more than 64k. */ - for (i = 0; i < ex.e_phnum; i++) - { - /* Unprocessable sections were handled above, so just verify that - the section can be loaded before copying. */ - if (ph [i].p_type == PT_LOAD && ph [i].p_filesz) - { - if (cur_vma != ph [i].p_vaddr) - { - unsigned long gap = ph [i].p_vaddr - cur_vma; - char obuf [1024]; - if (gap > 65536) - { - fprintf (stderr, "Intersegment gap (%d bytes) too large.\n", - gap); - exit (1); + /* Go to the start of the ELF symbol table... */ + if (lseek(in, offset, SEEK_SET) < 0) { + perror("copy: lseek"); + exit(1); + } + + remaining = size; + while (remaining) { + cur = remaining; + if (cur > sizeof ibuf) + cur = sizeof ibuf; + remaining -= cur; + if ((count = read(in, ibuf, cur)) != cur) { + fprintf(stderr, "copy: read: %s\n", + count ? strerror(errno) : + "premature end of file"); + exit(1); } - fprintf (stderr, "Warning: %d byte intersegment gap.\n", gap); - memset (obuf, 0, sizeof obuf); - while (gap) - { - int count = write (outfile, obuf, (gap > sizeof obuf - ? sizeof obuf : gap)); - if (count < 0) - { - fprintf (stderr, "Error writing gap: %s\n", - strerror (errno)); - exit (1); - } - gap -= count; + if ((count = write(out, ibuf, cur)) != cur) { + perror("copy: write"); + exit(1); } - } -fprintf (stderr, "writing %d bytes...\n", ph [i].p_filesz); - copy (outfile, infile, ph [i].p_offset, ph [i].p_filesz); - cur_vma = ph [i].p_vaddr + ph [i].p_filesz; - } - } - - /* - * Write a page of padding for boot PROMS that read entire pages. - * Without this, they may attempt to read past the end of the - * data section, incur an error, and refuse to boot. - */ - { - char obuf[4096]; - memset(obuf, 0, sizeof obuf); - if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) { - fprintf(stderr, "Error writing PROM padding: %s\n", - strerror(errno)); - exit(1); - } - } - - /* Looks like we won... */ - exit (0); -} - -copy (out, in, offset, size) - int out, in; - off_t offset, size; -{ - char ibuf [4096]; - int remaining, cur, count; - - /* Go to the start of the ELF symbol table... */ - if (lseek (in, offset, SEEK_SET) < 0) - { - perror ("copy: lseek"); - exit (1); - } - - remaining = size; - while (remaining) - { - cur = remaining; - if (cur > sizeof ibuf) - cur = sizeof ibuf; - remaining -= cur; - if ((count = read (in, ibuf, cur)) != cur) - { - fprintf (stderr, "copy: read: %s\n", - count ? strerror (errno) : "premature end of file"); - exit (1); - } - if ((count = write (out, ibuf, cur)) != cur) - { - perror ("copy: write"); - exit (1); } - } } -/* Combine two segments, which must be contiguous. If pad is true, it's - okay for there to be padding between. */ -combine (base, new, pad) - struct sect *base, *new; - int pad; -{ - if (!base -> len) - *base = *new; - else if (new -> len) - { - if (base -> vaddr + base -> len != new -> vaddr) - { - if (pad) - base -> len = new -> vaddr - base -> vaddr; - else - { - fprintf (stderr, - "Non-contiguous data can't be converted.\n"); - exit (1); - } +/* + * Combine two segments, which must be contiguous. If pad is true, it's + * okay for there to be padding between. + */ +static void combine(struct sect *base, struct sect *new, int pad) +{ + if (!base->len) + *base = *new; + else if (new->len) { + if (base->vaddr + base->len != new->vaddr) { + if (pad) + base->len = new->vaddr - base->vaddr; + else { + fprintf(stderr, + "Non-contiguous data can't be converted.\n"); + exit(1); + } + } + base->len += new->len; } - base -> len += new -> len; - } } -phcmp (h1, h2) - Elf32_Phdr *h1, *h2; +static int phcmp(const void *v1, const void *v2) { - if (h1 -> p_vaddr > h2 -> p_vaddr) - return 1; - else if (h1 -> p_vaddr < h2 -> p_vaddr) - return -1; - else - return 0; + const Elf32_Phdr *h1 = v1; + const Elf32_Phdr *h2 = v2; + + if (h1->p_vaddr > h2->p_vaddr) + return 1; + else if (h1->p_vaddr < h2->p_vaddr) + return -1; + else + return 0; } -char *saveRead (int file, off_t offset, off_t len, char *name) +static char *saveRead(int file, off_t offset, off_t len, char *name) { - char *tmp; - int count; - off_t off; - if ((off = lseek (file, offset, SEEK_SET)) < 0) - { - fprintf (stderr, "%s: fseek: %s\n", name, strerror (errno)); - exit (1); - } - if (!(tmp = (char *)malloc (len))) - { - fprintf (stderr, "%s: Can't allocate %d bytes.\n", name, len); - exit (1); - } - count = read (file, tmp, len); - if (count != len) - { - fprintf (stderr, "%s: read: %s.\n", - name, count ? strerror (errno) : "End of file reached"); - exit (1); - } - return tmp; + char *tmp; + int count; + off_t off; + if ((off = lseek(file, offset, SEEK_SET)) < 0) { + fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno)); + exit(1); + } + if (!(tmp = (char *) malloc(len))) { + fprintf(stderr, "%s: Can't allocate %ld bytes.\n", name, + len); + exit(1); + } + count = read(file, tmp, len); + if (count != len) { + fprintf(stderr, "%s: read: %s.\n", + name, + count ? strerror(errno) : "End of file reached"); + exit(1); + } + return tmp; } #define swab16(x) \ @@ -536,101 +163,454 @@ (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \ (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) )) -void convert_elf_hdr (Elf32_Ehdr *e) +static void convert_elf_hdr(Elf32_Ehdr * e) { - e->e_type = swab16(e->e_type); - e->e_machine = swab16(e->e_machine); - e->e_version = swab32(e->e_version); - e->e_entry = swab32(e->e_entry); - e->e_phoff = swab32(e->e_phoff); - e->e_shoff = swab32(e->e_shoff); - e->e_flags = swab32(e->e_flags); - e->e_ehsize = swab16(e->e_ehsize); + e->e_type = swab16(e->e_type); + e->e_machine = swab16(e->e_machine); + e->e_version = swab32(e->e_version); + e->e_entry = swab32(e->e_entry); + e->e_phoff = swab32(e->e_phoff); + e->e_shoff = swab32(e->e_shoff); + e->e_flags = swab32(e->e_flags); + e->e_ehsize = swab16(e->e_ehsize); e->e_phentsize = swab16(e->e_phentsize); - e->e_phnum = swab16(e->e_phnum); + e->e_phnum = swab16(e->e_phnum); e->e_shentsize = swab16(e->e_shentsize); - e->e_shnum = swab16(e->e_shnum); - e->e_shstrndx = swab16(e->e_shstrndx); + e->e_shnum = swab16(e->e_shnum); + e->e_shstrndx = swab16(e->e_shstrndx); } -void convert_elf_phdrs (Elf32_Phdr *p, int num) +static void convert_elf_phdrs(Elf32_Phdr * p, int num) { int i; - for (i = 0; i < num; i++,p++) { - p->p_type = swab32(p->p_type); + for (i = 0; i < num; i++, p++) { + p->p_type = swab32(p->p_type); p->p_offset = swab32(p->p_offset); - p->p_vaddr = swab32(p->p_vaddr); - p->p_paddr = swab32(p->p_paddr); + p->p_vaddr = swab32(p->p_vaddr); + p->p_paddr = swab32(p->p_paddr); p->p_filesz = swab32(p->p_filesz); - p->p_memsz = swab32(p->p_memsz); - p->p_flags = swab32(p->p_flags); - p->p_align = swab32(p->p_align); + p->p_memsz = swab32(p->p_memsz); + p->p_flags = swab32(p->p_flags); + p->p_align = swab32(p->p_align); } } -void convert_elf_shdrs (Elf32_Shdr *s, int num) +static void convert_elf_shdrs(Elf32_Shdr * s, int num) { int i; - for (i = 0; i < num; i++,s++) { - s->sh_name = swab32(s->sh_name); - s->sh_type = swab32(s->sh_type); - s->sh_flags = swab32(s->sh_flags); - s->sh_addr = swab32(s->sh_addr); - s->sh_offset = swab32(s->sh_offset); - s->sh_size = swab32(s->sh_size); - s->sh_link = swab32(s->sh_link); - s->sh_info = swab32(s->sh_info); + for (i = 0; i < num; i++, s++) { + s->sh_name = swab32(s->sh_name); + s->sh_type = swab32(s->sh_type); + s->sh_flags = swab32(s->sh_flags); + s->sh_addr = swab32(s->sh_addr); + s->sh_offset = swab32(s->sh_offset); + s->sh_size = swab32(s->sh_size); + s->sh_link = swab32(s->sh_link); + s->sh_info = swab32(s->sh_info); s->sh_addralign = swab32(s->sh_addralign); - s->sh_entsize = swab32(s->sh_entsize); + s->sh_entsize = swab32(s->sh_entsize); } } -void convert_ecoff_filehdr(struct filehdr *f) +static void convert_ecoff_filehdr(struct filehdr *f) { - f->f_magic = swab16(f->f_magic); - f->f_nscns = swab16(f->f_nscns); + f->f_magic = swab16(f->f_magic); + f->f_nscns = swab16(f->f_nscns); f->f_timdat = swab32(f->f_timdat); f->f_symptr = swab32(f->f_symptr); - f->f_nsyms = swab32(f->f_nsyms); + f->f_nsyms = swab32(f->f_nsyms); f->f_opthdr = swab16(f->f_opthdr); - f->f_flags = swab16(f->f_flags); + f->f_flags = swab16(f->f_flags); } -void convert_ecoff_aouthdr(struct aouthdr *a) +static void convert_ecoff_aouthdr(struct aouthdr *a) { - a->magic = swab16(a->magic); - a->vstamp = swab16(a->vstamp); - a->tsize = swab32(a->tsize); - a->dsize = swab32(a->dsize); - a->bsize = swab32(a->bsize); - a->entry = swab32(a->entry); + a->magic = swab16(a->magic); + a->vstamp = swab16(a->vstamp); + a->tsize = swab32(a->tsize); + a->dsize = swab32(a->dsize); + a->bsize = swab32(a->bsize); + a->entry = swab32(a->entry); a->text_start = swab32(a->text_start); a->data_start = swab32(a->data_start); - a->bss_start = swab32(a->bss_start); - a->gprmask = swab32(a->gprmask); + a->bss_start = swab32(a->bss_start); + a->gprmask = swab32(a->gprmask); a->cprmask[0] = swab32(a->cprmask[0]); a->cprmask[1] = swab32(a->cprmask[1]); a->cprmask[2] = swab32(a->cprmask[2]); a->cprmask[3] = swab32(a->cprmask[3]); - a->gp_value = swab32(a->gp_value); + a->gp_value = swab32(a->gp_value); } -void convert_ecoff_esecs(struct scnhdr *s, int num) +static void convert_ecoff_esecs(struct scnhdr *s, int num) { int i; for (i = 0; i < num; i++, s++) { - s->s_paddr = swab32(s->s_paddr); - s->s_vaddr = swab32(s->s_vaddr); - s->s_size = swab32(s->s_size); - s->s_scnptr = swab32(s->s_scnptr); - s->s_relptr = swab32(s->s_relptr); + s->s_paddr = swab32(s->s_paddr); + s->s_vaddr = swab32(s->s_vaddr); + s->s_size = swab32(s->s_size); + s->s_scnptr = swab32(s->s_scnptr); + s->s_relptr = swab32(s->s_relptr); s->s_lnnoptr = swab32(s->s_lnnoptr); - s->s_nreloc = swab16(s->s_nreloc); - s->s_nlnno = swab16(s->s_nlnno); - s->s_flags = swab32(s->s_flags); + s->s_nreloc = swab16(s->s_nreloc); + s->s_nlnno = swab16(s->s_nlnno); + s->s_flags = swab32(s->s_flags); + } +} + +int main(int argc, char *argv[]) +{ + Elf32_Ehdr ex; + Elf32_Phdr *ph; + Elf32_Shdr *sh; + char *shstrtab; + int i, pad; + struct sect text, data, bss; + struct filehdr efh; + struct aouthdr eah; + struct scnhdr esecs[6]; + int infile, outfile; + unsigned long cur_vma = ULONG_MAX; + int addflag = 0; + int nosecs; + + text.len = data.len = bss.len = 0; + text.vaddr = data.vaddr = bss.vaddr = 0; + + /* Check args... */ + if (argc < 3 || argc > 4) { + usage: + fprintf(stderr, + "usage: elf2ecoff <elf executable> <ecoff executable> [-a]\n"); + exit(1); + } + if (argc == 4) { + if (strcmp(argv[3], "-a")) + goto usage; + addflag = 1; + } + + /* Try the input file... */ + if ((infile = open(argv[1], O_RDONLY)) < 0) { + fprintf(stderr, "Can't open %s for read: %s\n", + argv[1], strerror(errno)); + exit(1); + } + + /* Read the header, which is at the beginning of the file... */ + i = read(infile, &ex, sizeof ex); + if (i != sizeof ex) { + fprintf(stderr, "ex: %s: %s.\n", + argv[1], + i ? strerror(errno) : "End of file reached"); + exit(1); + } + + if (ex.e_ident[EI_DATA] == ELFDATA2MSB) + format_bigendian = 1; + + if (ntohs(0xaa55) == 0xaa55) { + if (!format_bigendian) + must_convert_endian = 1; + } else { + if (format_bigendian) + must_convert_endian = 1; + } + if (must_convert_endian) + convert_elf_hdr(&ex); + + /* Read the program headers... */ + ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff, + ex.e_phnum * sizeof(Elf32_Phdr), + "ph"); + if (must_convert_endian) + convert_elf_phdrs(ph, ex.e_phnum); + /* Read the section headers... */ + sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff, + ex.e_shnum * sizeof(Elf32_Shdr), + "sh"); + if (must_convert_endian) + convert_elf_shdrs(sh, ex.e_shnum); + /* Read in the section string table. */ + shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset, + sh[ex.e_shstrndx].sh_size, "shstrtab"); + + /* Figure out if we can cram the program header into an ECOFF + header... Basically, we can't handle anything but loadable + segments, but we can ignore some kinds of segments. We can't + handle holes in the address space. Segments may be out of order, + so we sort them first. */ + + qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp); + + for (i = 0; i < ex.e_phnum; i++) { + /* Section types we can ignore... */ + if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE || + ph[i].p_type == PT_PHDR + || ph[i].p_type == PT_MIPS_REGINFO) + continue; + /* Section types we can't handle... */ + else if (ph[i].p_type != PT_LOAD) { + fprintf(stderr, + "Program header %d type %d can't be converted.\n", + ex.e_phnum, ph[i].p_type); + exit(1); + } + /* Writable (data) segment? */ + if (ph[i].p_flags & PF_W) { + struct sect ndata, nbss; + + ndata.vaddr = ph[i].p_vaddr; + ndata.len = ph[i].p_filesz; + nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz; + nbss.len = ph[i].p_memsz - ph[i].p_filesz; + + combine(&data, &ndata, 0); + combine(&bss, &nbss, 1); + } else { + struct sect ntxt; + + ntxt.vaddr = ph[i].p_vaddr; + ntxt.len = ph[i].p_filesz; + + combine(&text, &ntxt, 0); + } + /* Remember the lowest segment start address. */ + if (ph[i].p_vaddr < cur_vma) + cur_vma = ph[i].p_vaddr; + } + + /* Sections must be in order to be converted... */ + if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr || + text.vaddr + text.len > data.vaddr + || data.vaddr + data.len > bss.vaddr) { + fprintf(stderr, + "Sections ordering prevents a.out conversion.\n"); + exit(1); + } + + /* If there's a data section but no text section, then the loader + combined everything into one section. That needs to be the + text section, so just make the data section zero length following + text. */ + if (data.len && !text.len) { + text = data; + data.vaddr = text.vaddr + text.len; + data.len = 0; + } + + /* If there is a gap between text and data, we'll fill it when we copy + the data, so update the length of the text segment as represented in + a.out to reflect that, since a.out doesn't allow gaps in the program + address space. */ + if (text.vaddr + text.len < data.vaddr) + text.len = data.vaddr - text.vaddr; + + /* We now have enough information to cons up an a.out header... */ + eah.magic = OMAGIC; + eah.vstamp = 200; + eah.tsize = text.len; + eah.dsize = data.len; + eah.bsize = bss.len; + eah.entry = ex.e_entry; + eah.text_start = text.vaddr; + eah.data_start = data.vaddr; + eah.bss_start = bss.vaddr; + eah.gprmask = 0xf3fffffe; + memset(&eah.cprmask, '\0', sizeof eah.cprmask); + eah.gp_value = 0; /* unused. */ + + if (format_bigendian) + efh.f_magic = MIPSEBMAGIC; + else + efh.f_magic = MIPSELMAGIC; + if (addflag) + nosecs = 6; + else + nosecs = 3; + efh.f_nscns = nosecs; + efh.f_timdat = 0; /* bogus */ + efh.f_symptr = 0; + efh.f_nsyms = 0; + efh.f_opthdr = sizeof eah; + efh.f_flags = 0x100f; /* Stripped, not sharable. */ + + memset(esecs, 0, sizeof esecs); + strcpy(esecs[0].s_name, ".text"); + strcpy(esecs[1].s_name, ".data"); + strcpy(esecs[2].s_name, ".bss"); + if (addflag) { + strcpy(esecs[3].s_name, ".rdata"); + strcpy(esecs[4].s_name, ".sdata"); + strcpy(esecs[5].s_name, ".sbss"); + } + esecs[0].s_paddr = esecs[0].s_vaddr = eah.text_start; + esecs[1].s_paddr = esecs[1].s_vaddr = eah.data_start; + esecs[2].s_paddr = esecs[2].s_vaddr = eah.bss_start; + if (addflag) { + esecs[3].s_paddr = esecs[3].s_vaddr = 0; + esecs[4].s_paddr = esecs[4].s_vaddr = 0; + esecs[5].s_paddr = esecs[5].s_vaddr = 0; + } + esecs[0].s_size = eah.tsize; + esecs[1].s_size = eah.dsize; + esecs[2].s_size = eah.bsize; + if (addflag) { + esecs[3].s_size = 0; + esecs[4].s_size = 0; + esecs[5].s_size = 0; } + esecs[0].s_scnptr = N_TXTOFF(efh, eah); + esecs[1].s_scnptr = N_DATOFF(efh, eah); +#define ECOFF_SEGMENT_ALIGNMENT(a) 0x10 +#define ECOFF_ROUND(s,a) (((s)+(a)-1)&~((a)-1)) + esecs[2].s_scnptr = esecs[1].s_scnptr + + ECOFF_ROUND(esecs[1].s_size, ECOFF_SEGMENT_ALIGNMENT(&eah)); + if (addflag) { + esecs[3].s_scnptr = 0; + esecs[4].s_scnptr = 0; + esecs[5].s_scnptr = 0; + } + esecs[0].s_relptr = esecs[1].s_relptr = esecs[2].s_relptr = 0; + esecs[0].s_lnnoptr = esecs[1].s_lnnoptr = esecs[2].s_lnnoptr = 0; + esecs[0].s_nreloc = esecs[1].s_nreloc = esecs[2].s_nreloc = 0; + esecs[0].s_nlnno = esecs[1].s_nlnno = esecs[2].s_nlnno = 0; + if (addflag) { + esecs[3].s_relptr = esecs[4].s_relptr + = esecs[5].s_relptr = 0; + esecs[3].s_lnnoptr = esecs[4].s_lnnoptr + = esecs[5].s_lnnoptr = 0; + esecs[3].s_nreloc = esecs[4].s_nreloc = esecs[5].s_nreloc = + 0; + esecs[3].s_nlnno = esecs[4].s_nlnno = esecs[5].s_nlnno = 0; + } + esecs[0].s_flags = 0x20; + esecs[1].s_flags = 0x40; + esecs[2].s_flags = 0x82; + if (addflag) { + esecs[3].s_flags = 0x100; + esecs[4].s_flags = 0x200; + esecs[5].s_flags = 0x400; + } + + /* Make the output file... */ + if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) { + fprintf(stderr, "Unable to create %s: %s\n", argv[2], + strerror(errno)); + exit(1); + } + + if (must_convert_endian) + convert_ecoff_filehdr(&efh); + /* Write the headers... */ + i = write(outfile, &efh, sizeof efh); + if (i != sizeof efh) { + perror("efh: write"); + exit(1); + + for (i = 0; i < nosecs; i++) { + printf + ("Section %d: %s phys %lx size %lx file offset %lx\n", + i, esecs[i].s_name, esecs[i].s_paddr, + esecs[i].s_size, esecs[i].s_scnptr); + } + } + fprintf(stderr, "wrote %d byte file header.\n", i); + + if (must_convert_endian) + convert_ecoff_aouthdr(&eah); + i = write(outfile, &eah, sizeof eah); + if (i != sizeof eah) { + perror("eah: write"); + exit(1); + } + fprintf(stderr, "wrote %d byte a.out header.\n", i); + + if (must_convert_endian) + convert_ecoff_esecs(&esecs[0], nosecs); + i = write(outfile, &esecs, nosecs * sizeof(struct scnhdr)); + if (i != nosecs * sizeof(struct scnhdr)) { + perror("esecs: write"); + exit(1); + } + fprintf(stderr, "wrote %d bytes of section headers.\n", i); + + pad = (sizeof(efh) + sizeof(eah) + nosecs * sizeof(struct scnhdr)) & 15; + if (pad) { + pad = 16 - pad; + i = write(outfile, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0", pad); + if (i < 0) { + perror("ipad: write"); + exit(1); + } + fprintf(stderr, "wrote %d byte pad.\n", i); + } + + /* + * Copy the loadable sections. Zero-fill any gaps less than 64k; + * complain about any zero-filling, and die if we're asked to zero-fill + * more than 64k. + */ + for (i = 0; i < ex.e_phnum; i++) { + /* Unprocessable sections were handled above, so just verify that + the section can be loaded before copying. */ + if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) { + if (cur_vma != ph[i].p_vaddr) { + unsigned long gap = + ph[i].p_vaddr - cur_vma; + char obuf[1024]; + if (gap > 65536) { + fprintf(stderr, + "Intersegment gap (%ld bytes) too large.\n", + gap); + exit(1); + } + fprintf(stderr, + "Warning: %ld byte intersegment gap.\n", + gap); + memset(obuf, 0, sizeof obuf); + while (gap) { + int count = + write(outfile, obuf, + (gap > + sizeof obuf ? sizeof + obuf : gap)); + if (count < 0) { + fprintf(stderr, + "Error writing gap: %s\n", + strerror(errno)); + exit(1); + } + gap -= count; + } + } + fprintf(stderr, "writing %d bytes...\n", + ph[i].p_filesz); + copy(outfile, infile, ph[i].p_offset, + ph[i].p_filesz); + cur_vma = ph[i].p_vaddr + ph[i].p_filesz; + } + } + + /* + * Write a page of padding for boot PROMS that read entire pages. + * Without this, they may attempt to read past the end of the + * data section, incur an error, and refuse to boot. + */ + { + char obuf[4096]; + memset(obuf, 0, sizeof obuf); + if (write(outfile, obuf, sizeof(obuf)) != sizeof(obuf)) { + fprintf(stderr, "Error writing PROM padding: %s\n", + strerror(errno)); + exit(1); + } + } + + /* Looks like we won... */ + exit(0); } diff -Nru a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,7 @@ +# +# Makefile for the Cobalt micro systems family specific parts of the kernel +# + +obj-y := irq.o int-handler.o reset.o setup.o via.o promcon.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/int-handler.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,104 @@ +/* + * Cobalt interrupt handler + * + * 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) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/cobalt/cobalt.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* + * cobalt_handle_int: Interrupt handler for Cobalt boards + */ + .text + .set noreorder + .set noat + .align 5 + NESTED(cobalt_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + /* + * Get pending Interrupts + */ + mfc0 s0,CP0_CAUSE # get raw irq status + mfc0 a0,CP0_STATUS # get irq mask + and s0,s0,a0 # compute masked irq status + + andi a0,s0,CAUSEF_IP2 /* Check for Galileo timer */ + beq a0,zero,1f + andi a0,s0,CAUSEF_IP6 /* Check for Via chip */ + + /* Galileo interrupt */ + jal galileo_irq + move a0,sp + j ret_from_irq + nop + +1: + beq a0,zero,1f /* Check IP6 */ + andi a0,s0,CAUSEF_IP3 + + /* Via interrupt */ + jal via_irq + move a0,sp + j ret_from_irq + nop + +1: + beq a0,zero,1f /* Check IP3 */ + andi a0,s0,CAUSEF_IP4 + + /* Ethernet 0 interrupt */ + li a0,COBALT_ETH0_IRQ + jal do_IRQ + move a1,sp + + j ret_from_irq + nop + +1: + beq a0,zero,1f /* Check IP4 */ + andi a0,s0,CAUSEF_IP5 + + /* Ethernet 1 interrupt */ + li a0,COBALT_ETH1_IRQ + jal do_IRQ + move a1,sp + + j ret_from_irq + nop +1: + beq a0,zero,1f /* Check IP5 */ + andi a0,s0,CAUSEF_IP7 + + /* Serial interrupt */ + li a0,COBALT_SERIAL_IRQ + jal do_IRQ + move a1,sp + + j ret_from_irq + nop +1: + beq a0,zero,1f /* Check IP7 */ + nop + + /* PCI interrupt */ + li a0,COBALT_QUBE_SLOT_IRQ + jal do_IRQ + move a1,sp + +1: + j ret_from_irq + nop + + END(cobalt_handle_int) + diff -Nru a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,143 @@ +/* + * IRQ vector handles + * + * 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) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + * + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/bootinfo.h> +#include <asm/i8259.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + +#include <asm/cobalt/cobalt.h> + +/* Cobalt Exception handler */ +extern void cobalt_handle_int(void); + +/* Via masking routines */ +extern void unmask_irq(unsigned int irqr); +extern void mask_irq(unsigned int irq); + + +/* + * We have two types of interrupts that we handle, ones that come + * in through the CPU interrupt lines, and ones that come in on + * the via chip. The CPU mappings are: + * 0,1 - S/W (ignored) + * 2 - Galileo chip (timer) + * 3 - Tulip 0 + NCR SCSI + * 4 - Tulip 1 + * 5 - 16550 UART + * 6 - VIA southbridge PIC + * 7 - unused + * + * The VIA chip is a master/slave 8259 setup and has the + * following interrupts + * 8 - RTC + * 9 - PCI + * 14 - IDE0 + * 15 - IDE1 + * + * In the table we use a 1 to indicate that we use a VIA interrupt + * line, and IE_IRQx to indicate that we use a CPU interrupt line + * + * We map all of these onto linux IRQ #s 0-15 and forget the rest + */ +#define NOINT_LINE 0 +#define CPUINT_LINE(x) IE_IRQ##x +#define VIAINT_LINE 1 + +#define COBALT_IRQS 16 + +static unsigned short irqnr_to_type[COBALT_IRQS] = +{ CPUINT_LINE(0), NOINT_LINE, VIAINT_LINE, NOINT_LINE, + CPUINT_LINE(1), NOINT_LINE, NOINT_LINE, CPUINT_LINE(3), + VIAINT_LINE, VIAINT_LINE, NOINT_LINE, NOINT_LINE, + NOINT_LINE, CPUINT_LINE(2), VIAINT_LINE, VIAINT_LINE }; + +/* + * Cobalt CPU irq + */ + +static void enable_cpu_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_status(irqnr_to_type[irq], irqnr_to_type[irq]); + local_irq_restore(flags); +} + +static unsigned startup_cpu_irq(unsigned int irq) +{ + enable_cpu_irq(irq); + + return 0; +} + +static void disable_cpu_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_status(irqnr_to_type[irq], ~(irqnr_to_type[irq])); + local_irq_restore(flags); +} + +#define shutdown_cpu_irq disable_cpu_irq +#define mask_and_ack_cpu_irq disable_cpu_irq + +static void end_cpu_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_cpu_irq(irq); +} + +static struct hw_interrupt_type cobalt_cpu_irq_type = { + "Cobalt CPU", + startup_cpu_irq, + shutdown_cpu_irq, + enable_cpu_irq, + disable_cpu_irq, + mask_and_ack_cpu_irq, + end_cpu_irq, + NULL +}; + +void __init init_IRQ(void) +{ + int i; + + /* Initialise all of the IRQ descriptors */ + init_i8259_irqs(); + + /* Map the irqnr to the type int we have */ + for (i=0; i < COBALT_IRQS; i++) { + if (irqnr_to_type[i] >= CPUINT_LINE(0)) + /* cobalt_cpu_irq_type */ + irq_desc[i].handler = &cobalt_cpu_irq_type; + } + + /* Mask all cpu interrupts + (except IE4, we already masked those at VIA level) */ + clear_c0_status(ST0_IM); + set_c0_status(IE_IRQ4); + + cli(); + + set_except_vector(0, cobalt_handle_int); +} diff -Nru a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/promcon.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +/* + * PROM console for Cobalt Raq2 + * + * 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) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + * + */ + +#include <linux/init.h> +#include <linux/console.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/serial_reg.h> + +#include <asm/delay.h> +#include <asm/serial.h> +#include <asm/io.h> + +static unsigned long port = 0xc800000; + +static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr) +{ + char lsr; + + do { + lsr = inb(ioaddr + UART_LSR); + } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE)); + outb(ch, ioaddr + UART_TX); +} + +static __inline__ char ns16550_cons_get_char(unsigned long ioaddr) +{ + while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0) + udelay(1); + return inb(ioaddr + UART_RX); +} + +void ns16550_console_write(struct console *co, const char *s, unsigned count) +{ + char lsr, ier; + unsigned i; + + ier = inb(port + UART_IER); + outb(0x00, port + UART_IER); + for (i=0; i < count; i++, s++) { + + if(*s == '\n') + ns16550_cons_put_char('\r', port); + ns16550_cons_put_char(*s, port); + } + + do { + lsr = inb(port + UART_LSR); + } while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE)); + + outb(ier, port + UART_IER); +} + +char getDebugChar(void) +{ + return ns16550_cons_get_char(port); +} + +void putDebugChar(char kgdb_char) +{ + ns16550_cons_put_char(kgdb_char, port); +} + +static kdev_t +ns16550_console_dev(struct console *c) +{ + return mk_kdev(TTY_MAJOR, 64 + c->index); +} + +static struct console ns16550_console = { + .name = "prom", + .setup = NULL, + .write = ns16550_console_write, + .device = ns16550_console_dev, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +void __init ns16550_setup_console(void) +{ + register_console(&ns16550_console); +} diff -Nru a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,68 @@ +/* + * Cobalt Reset operations + * + * 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) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv) + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/cacheflush.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/system.h> +#include <asm/mipsregs.h> + +void cobalt_machine_restart(char *command) +{ + *(volatile char *)0xbc000000 = 0x0f; + + /* + * Ouch, we're still alive ... This time we take the silver bullet ... + * ... and find that we leave the hardware in a state in which the + * kernel in the flush locks up somewhen during of after the PCI + * detection stuff. + */ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__( + "jr\t%0" + : + : "r" (0xbfc00000)); +} + +extern int led_state; +#define kLED 0xBC000000 +#define LEDSet(x) (*(volatile unsigned char *) kLED) = (( unsigned char)x) + +void cobalt_machine_halt(void) +{ + int mark; + + /* Blink our cute? little LED (number 3)... */ + while (1) { + led_state = led_state | ( 1 << 3 ); + LEDSet(led_state); + mark = jiffies; + while (jiffies<(mark+HZ)); + led_state = led_state & ~( 1 << 3 ); + LEDSet(led_state); + mark = jiffies; + while (jiffies<(mark+HZ)); + } +} + +/* + * This triggers the luser mode device driver for the power switch ;-) + */ +void cobalt_machine_power_off(void) +{ + printk("You can switch the machine off now.\n"); + cobalt_machine_halt(); +} diff -Nru a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,113 @@ +/* + * Setup pointers to hardware dependent routines. + * + * 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) 1996, 1997 by Ralf Baechle + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) + * + */ + +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/mc146818rtc.h> +#include <linux/init.h> +#include <linux/ide.h> + +#include <asm/bootinfo.h> +#include <asm/time.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/gt64120.h> + +#include <asm/cobalt/cobalt.h> + +extern void cobalt_machine_restart(char *command); +extern void cobalt_machine_halt(void); +extern void cobalt_machine_power_off(void); + +extern struct rtc_ops std_rtc_ops; +extern struct ide_ops std_ide_ops; + + +char arcs_cmdline[CL_SIZE] = { + "console=ttyS0,115200 " +#ifdef CONFIG_IP_PNP + "ip=on " +#endif +#ifdef CONFIG_ROOT_NFS + "root=/dev/nfs " +#else + "root=/dev/hda1 " +#endif + }; + +const char *get_system_type(void) +{ + return "MIPS Cobalt"; +} + + +static void __init cobalt_time_init(void) +{ + rtc_ops = &std_rtc_ops; +} + +static void __init cobalt_timer_setup(struct irqaction *irq) +{ + /* Load timer value for 150 Hz */ + GALILEO_OUTL(500000, GT_TC0_OFS); + + /* Register our timer interrupt */ + setup_irq(COBALT_TIMER_IRQ, irq); + + /* Enable timer ints */ + GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS); + /* Unmask timer int */ + GALILEO_OUTL(0x100, GT_INTRMASK_OFS); +} + + +void __init cobalt_setup(void) +{ + + _machine_restart = cobalt_machine_restart; + _machine_halt = cobalt_machine_halt; + _machine_power_off = cobalt_machine_power_off; + + board_time_init = cobalt_time_init; + board_timer_setup = cobalt_timer_setup; + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + set_io_port_base(KSEG1ADDR(0x10000000)); + + /* + * This is a prom style console. We just poke at the + * UART to make it talk. + * Only use this console if you really screw up and can't + * get to the stage of setting up a real serial console. + */ + /*ns16550_setup_console();*/ +} + +/* Prom init. We read our one and only communication with the + firmware. Grab the amount of installed memory */ +void __init prom_init(int argc) +{ + mips_machgroup = MACH_GROUP_COBALT; + + add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory(void) +{ + /* Nothing to do! */ +} diff -Nru a/arch/mips/cobalt/via.c b/arch/mips/cobalt/via.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/cobalt/via.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,67 @@ +/* + * VIA chipset irq handling + * + * 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) 1996, 1997 by Ralf Baechle + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) + * + */ + +#include <linux/irq.h> +#include <linux/kernel.h> + +#include <asm/gt64120.h> +#include <asm/ptrace.h> +#include <asm/io.h> + +#include <asm/cobalt/cobalt.h> + +asmlinkage void via_irq(struct pt_regs *regs) +{ + char mstat, sstat; + + /* Read Master Status */ + outb(0x0C, 0x20); + mstat = inb(0x20); + + if (mstat < 0) { + mstat &= 0x7f; + if (mstat != 2) { + do_IRQ(mstat, regs); + outb(mstat | 0x20, 0x20); + } else { + sstat = inb(0xA0); + + /* Slave interrupt */ + outb(0x0C, 0xA0); + sstat = inb(0xA0); + + if (sstat < 0) { + do_IRQ((sstat + 8) & 0x7f, regs); + outb(0x22, 0x20); + outb((sstat & 0x7f) | 0x20, 0xA0); + } else { + printk("Spurious slave interrupt...\n"); + } + } + } else + printk("Spurious master interrupt..."); +} + +asmlinkage void galileo_irq(struct pt_regs *regs) +{ + unsigned long irq_src; + + irq_src = GALILEO_INL(GT_INTRCAUSE_OFS); + + /* Check for timer irq ... */ + if (irq_src & GALILEO_T0EXP) { + /* Clear the int line */ + GALILEO_OUTL(0, GT_INTRCAUSE_OFS); + do_IRQ(COBALT_TIMER_IRQ, regs); + } else + printk("Spurious Galileo interrupt...\n"); +} diff -Nru a/arch/mips/ddb5074/Makefile b/arch/mips/ddb5074/Makefile --- a/arch/mips/ddb5074/Makefile Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,8 +0,0 @@ -# -# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines -# under Linux. -# - -EXTRA_AFLAGS := $(CFLAGS) - -obj-y := setup.o irq.o time.o prom.o pci.o int-handler.o nile4.o diff -Nru a/arch/mips/ddb5074/int-handler.S b/arch/mips/ddb5074/int-handler.S --- a/arch/mips/ddb5074/int-handler.S Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,120 +0,0 @@ -/* - * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler - * - * Based on arch/mips/sgi/kernel/indyIRQ.S - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -/* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the INDY look basically (barring software IRQs - * which we don't use at all) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Local IRQ level zero - * 3 Local IRQ level one - * 4 8254 Timer zero - * 5 8254 Timer one - * 6 Bus Error - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Local IRQ zero - * Local IRQ one - * Bus Error - * 8254 Timer zero - * Lowest ---- 8254 Timer one - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(ddbIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 s0, CP0_CAUSE # get irq mask - -#if 1 - mfc0 t2,CP0_STATUS # get enabled interrupts - and s0,t2 # isolate allowed ones -#endif - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one - - /* Wheee, local level zero interrupt. */ - jal ddb_local0_irqdispatch - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error - - /* Wheee, local level one interrupt. */ - move a0, sp - jal ddb_local1_irqdispatch - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, an asynchronous bus error... */ - move a0, sp - jal ddb_buserror_irq - nop - - j ret_from_irq - nop - -1: - /* Here by mistake? This is possible, what can happen - * is that by the time we take the exception the IRQ - * pin goes low, so just leave if this is the case. - */ - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) - beq a0, zero, 1f - - /* Must be one of the 8254 timers... */ - move a0, sp - jal ddb_8254timer_irq - nop -1: - j ret_from_irq - nop - END(ddbIRQ) diff -Nru a/arch/mips/ddb5074/irq.c b/arch/mips/ddb5074/irq.c --- a/arch/mips/ddb5074/irq.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,226 +0,0 @@ -/* - * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/ptrace.h> -#include <asm/nile4.h> -#include <asm/ddb5074.h> - - -extern void __init i8259_init(void); -extern void i8259_disable_irq(unsigned int irq_nr); -extern void i8259_enable_irq(unsigned int irq_nr); - -extern asmlinkage void ddbIRQ(void); -extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - - -void no_action(int cpl, void *dev_id, struct pt_regs *regs) -{ -} - - -#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ -#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ -#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ - -#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ -#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ -#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ - -#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ -#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ - -#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ -#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ - -#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ -#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ - - -static void m1543_irq_setup(void) -{ - /* - * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all - * the possible IO sources in the M1543 are in use by us. We will - * use the following mapping: - * - * IRQ1 - keyboard (default set by M1543) - * IRQ3 - reserved for UART B (default set by M1543) (note that - * the schematics for the DDB Vrc-5074 board seem to - * indicate that IRQ3 is connected to the DS1386 - * watchdog timer interrupt output so we might have - * a conflict) - * IRQ4 - reserved for UART A (default set by M1543) - * IRQ5 - parallel (default set by M1543) - * IRQ8 - DS1386 time of day (RTC) interrupt - * IRQ12 - mouse - */ - - /* - * Assing mouse interrupt to IRQ12 - */ - - /* Enter configuration mode */ - outb(0x51, M1543_PNP_CONFIG); - outb(0x23, M1543_PNP_CONFIG); - - /* Select logical device 7 (Keyboard) */ - outb(0x07, M1543_PNP_INDEX); - outb(0x07, M1543_PNP_DATA); - - /* Select IRQ12 */ - outb(0x72, M1543_PNP_INDEX); - outb(0x0c, M1543_PNP_DATA); - - /* Leave configration mode */ - outb(0xbb, M1543_PNP_CONFIG); - - - /* Initialize the 8259 PIC in the M1543 */ - i8259_init(); - - /* Enable the interrupt cascade */ - nile4_enable_irq(NILE4_INT_INTE); - - request_region(M1543_PNP_CONFIG, 2, "M1543 config"); - request_region(M1543_INT1_MASTER_ELCR, 2, "pic ELCR"); -} - -static void nile4_irq_setup(void) -{ - int i; - - /* Map all interrupts to CPU int #0 */ - nile4_map_irq_all(0); - - /* PCI INTA#-E# must be level triggered */ - nile4_set_pci_irq_level_or_edge(0, 1); - nile4_set_pci_irq_level_or_edge(1, 1); - nile4_set_pci_irq_level_or_edge(2, 1); - nile4_set_pci_irq_level_or_edge(3, 1); - nile4_set_pci_irq_level_or_edge(4, 1); - - /* PCI INTA#-D# must be active low, INTE# must be active high */ - nile4_set_pci_irq_polarity(0, 0); - nile4_set_pci_irq_polarity(1, 0); - nile4_set_pci_irq_polarity(2, 0); - nile4_set_pci_irq_polarity(3, 0); - nile4_set_pci_irq_polarity(4, 1); - - for (i = 0; i < 16; i++) - nile4_clear_irq(i); - - /* Enable CPU int #0 */ - nile4_enable_irq_output(0); - - request_mem_region(NILE4_BASE, NILE4_SIZE, "Nile 4"); -} - - -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL }; - - -void disable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_disable_irq(irq_nr); - else - nile4_disable_irq(irq_to_nile4(irq_nr)); -} - -void enable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_enable_irq(irq_nr); - else - nile4_enable_irq(irq_to_nile4(irq_nr)); -} - -int table[16] = { 0, }; - -void ddb_local0_irqdispatch(struct pt_regs *regs) -{ - u32 mask; - int nile4_irq; -#if 1 - volatile static int nesting = 0; - if (nesting++ == 0) - ddb5074_led_d3(1); - ddb5074_led_hex(nesting < 16 ? nesting : 15); -#endif - - mask = nile4_get_irq_stat(0); - nile4_clear_irq_mask(mask); - - /* Handle the timer interrupt first */ - if (mask & (1 << NILE4_INT_GPT)) { - nile4_disable_irq(NILE4_INT_GPT); - do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs); - nile4_enable_irq(NILE4_INT_GPT); - mask &= ~(1 << NILE4_INT_GPT); - } - for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) - if (mask & 1) { - nile4_disable_irq(nile4_irq); - if (nile4_irq == NILE4_INT_INTE) { - int i8259_irq = nile4_i8259_iack(); - i8259_do_irq(i8259_irq, regs); - } else - do_IRQ(nile4_to_irq(nile4_irq), regs); - nile4_enable_irq(nile4_irq); - } -#if 1 - if (--nesting == 0) - ddb5074_led_d3(0); - ddb5074_led_hex(nesting < 16 ? nesting : 15); -#endif -} - -void ddb_local1_irqdispatch(void) -{ - printk("ddb_local1_irqdispatch called\n"); -} - -void ddb_buserror_irq(void) -{ - printk("ddb_buserror_irq called\n"); -} - -void ddb_8254timer_irq(void) -{ - printk("ddb_8254timer_irq called\n"); -} - -void __init ddb_irq_setup(void) -{ -#ifdef CONFIG_REMOTE_DEBUG - if (remote_debug) - set_debug_traps(); - breakpoint(); /* you may move this line to whereever you want :-) */ -#endif - request_region(0x20, 0x20, "pic1"); - request_region(0xa0, 0x20, "pic2"); - i8259_setup_irq(2, &irq2); - - nile4_irq_setup(); - m1543_irq_setup(); - - set_except_vector(0, ddbIRQ); -} diff -Nru a/arch/mips/ddb5074/nile4.c b/arch/mips/ddb5074/nile4.c --- a/arch/mips/ddb5074/nile4.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,292 +0,0 @@ -/* - * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/kernel.h> -#include <linux/types.h> - -#include <asm/nile4.h> - - -/* - * Physical Device Address Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, - int on_memory_bus, int visible) -{ - u32 maskbits; - u32 widthbits; - - if (pdar > NILE4_BOOTCS || (pdar & 7)) { - printk("nile4_set_pdar: invalid pdar %d\n", pdar); - return; - } - if (pdar == NILE4_INTCS && size != 0x00200000) { - printk("nile4_set_pdar: INTCS size must be 2 MB\n"); - return; - } - switch (size) { -#if 0 /* We don't support 4 GB yet */ - case 0x100000000: /* 4 GB */ - maskbits = 4; - break; -#endif - case 0x80000000: /* 2 GB */ - maskbits = 5; - break; - case 0x40000000: /* 1 GB */ - maskbits = 6; - break; - case 0x20000000: /* 512 MB */ - maskbits = 7; - break; - case 0x10000000: /* 256 MB */ - maskbits = 8; - break; - case 0x08000000: /* 128 MB */ - maskbits = 9; - break; - case 0x04000000: /* 64 MB */ - maskbits = 10; - break; - case 0x02000000: /* 32 MB */ - maskbits = 11; - break; - case 0x01000000: /* 16 MB */ - maskbits = 12; - break; - case 0x00800000: /* 8 MB */ - maskbits = 13; - break; - case 0x00400000: /* 4 MB */ - maskbits = 14; - break; - case 0x00200000: /* 2 MB */ - maskbits = 15; - break; - case 0: /* OFF */ - maskbits = 0; - break; - default: - printk("nile4_set_pdar: unsupported size %p\n", (void *) size); - return; - } - switch (width) { - case 8: - widthbits = 0; - break; - case 16: - widthbits = 1; - break; - case 32: - widthbits = 2; - break; - case 64: - widthbits = 3; - break; - default: - printk("nile4_set_pdar: unsupported width %d\n", width); - return; - } - nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) | - (visible ? 0x20 : 0) | (widthbits << 6) | - (phys & 0xffe00000)); - nile4_out32(pdar + 4, 0); - /* - * When programming a PDAR, the register should be read immediately - * after writing it. This ensures that address decoders are properly - * configured. - */ - nile4_in32(pdar); - nile4_in32(pdar + 4); -} - - -/* - * PCI Master Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pmr(u32 pmr, u32 type, u32 addr) -{ - if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) { - printk("nile4_set_pmr: invalid pmr %d\n", pmr); - return; - } - switch (type) { - case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */ - case NILE4_PCICMD_IO: /* PCI I/O Space */ - case NILE4_PCICMD_MEM: /* PCI Memory Space */ - case NILE4_PCICMD_CFG: /* PCI Configuration Space */ - break; - default: - printk("nile4_set_pmr: invalid type %d\n", type); - return; - } - nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000)); - nile4_out32(pmr + 4, 0); -} - - -/* - * Interrupt Programming - */ -void nile4_map_irq(int nile4_irq, int cpu_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(7 << (nile4_irq * 4)); - t |= cpu_irq << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_map_irq_all(int cpu_irq) -{ - u32 all, t; - - all = cpu_irq; - all |= all << 4; - all |= all << 8; - all |= all << 16; - t = nile4_in32(NILE4_INTCTRL); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL, t); - t = nile4_in32(NILE4_INTCTRL + 4); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL + 4, t); -} - -void nile4_enable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t |= 8 << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_disable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(8 << (nile4_irq * 4)); - nile4_out32(offset, t); -} - -void nile4_disable_irq_all(void) -{ - nile4_out32(NILE4_INTCTRL, 0); - nile4_out32(NILE4_INTCTRL + 4, 0); -} - -u16 nile4_get_irq_stat(int cpu_irq) -{ - return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2); -} - -void nile4_enable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t |= 1 << (16 + cpu_irq); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_disable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t &= ~(1 << (16 + cpu_irq)); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_set_pci_irq_polarity(int pci_irq, int high) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (high) - t &= ~(1 << (pci_irq * 2)); - else - t |= 1 << (pci_irq * 2); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (level) - t |= 2 << (pci_irq * 2); - else - t &= ~(2 << (pci_irq * 2)); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_clear_irq(int nile4_irq) -{ - nile4_out32(NILE4_INTCLR, 1 << nile4_irq); -} - -void nile4_clear_irq_mask(u32 mask) -{ - nile4_out32(NILE4_INTCLR, mask); -} - -u8 nile4_i8259_iack(void) -{ - u8 irq; - - /* Set window 0 for interrupt acknowledge */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0); - irq = *(volatile u8 *) NILE4_PCI_IACK_BASE; - /* Set window 0 for PCI I/O space */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0); - return irq; -} - -#if 0 -void nile4_dump_irq_status(void) -{ - printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4), - (void *) nile4_in32(NILE4_CPUSTAT)); - printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4), - (void *) nile4_in32(NILE4_INTCTRL)); - printk("INTSTAT0 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT0 + 4), - (void *) nile4_in32(NILE4_INTSTAT0)); - printk("INTSTAT1 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT1 + 4), - (void *) nile4_in32(NILE4_INTSTAT1)); - printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4), - (void *) nile4_in32(NILE4_INTCLR)); - printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4), - (void *) nile4_in32(NILE4_INTPPES)); -} -#endif diff -Nru a/arch/mips/ddb5074/pci.c b/arch/mips/ddb5074/pci.c --- a/arch/mips/ddb5074/pci.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,366 +0,0 @@ -/* - * arch/mips/ddb5074/pci.c -- NEC DDB Vrc-5074 PCI access routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Albert Dorofeev <albert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/ioport.h> - -#include <asm/nile4.h> - - -static u32 nile4_pre_pci_access0(int slot_num) -{ - u32 pci_addr = 0; - u32 virt_addr = NILE4_PCI_CFG_BASE; - - /* Set window 1 address 8000000 - 64 bit - 2 MB (PCI config space) */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x00200000, 64, 0, - 0); - if (slot_num > 2) - pci_addr = 0x00040000 << slot_num; - else - virt_addr += 0x00040000 << slot_num; - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr); - return virt_addr; -} - -static void nile4_post_pci_access0(void) -{ - /* - * Set window 1 back to address 8000000 - 64 bit - 128 MB - * (PCI IO space) - */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE), - 0x08000000, 64, 1, 1); - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0); -} - - -static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) -{ - int status, slot_num, func_num; - u32 result, base; - - switch (size) { - case 4: - /* - * For starters let's do configuration cycle 0 only - * (one bus only) - */ - if (bus->number) - return PCIBIOS_FUNC_NOT_SUPPORTED; - - slot_num = PCI_SLOT(devfn); - func_num = PCI_FUNC(devfn); - if (slot_num == 5) { - /* - * This is Nile 4 and it will crash if we access it - * like other devices - */ - *val = nile4_in32(NILE4_PCI_BASE + where); - return PCIBIOS_SUCCESSFUL; - } - base = nile4_pre_pci_access0(slot_num); - *val = *((volatile u32 *) (base + (func_num << 8) + - (where & 0xfc))); - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; - - case 2: - status = nile4_pci_read(bus, devfn, where, 4, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - result >>= 16; - *val = (u16)(result & 0xffff); - break; - case 1: - status = nile4_pci_read(bus, devfn, where, 4, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 1) - result >>= 8; - if (where & 2) - result >>= 16; - *val = (u8)(result & 0xff); - break; - } - return PCIBIOS_SUCCESSFUL; -} - - -static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - int status, slot_num, func_num, shift = 0; - u32 result, base; - - switch (size) { - case 4: - /* - * For starters let's do configuration cycle 0 only - * (one bus only) - */ - if (bus->number) - return PCIBIOS_FUNC_NOT_SUPPORTED; - - slot_num = PCI_SLOT(devfn); - func_num = PCI_FUNC(devfn); - if (slot_num == 5) { - /* - * This is Nile 4 and it will crash if we access - * it like other devices - */ - nile4_out32(NILE4_PCI_BASE + where, val); - return PCIBIOS_SUCCESSFUL; - } - base = nile4_pre_pci_access0(slot_num); - *((volatile u32 *) (base + (func_num << 8) + - (where & 0xfc))) = val; - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; - - case 2: - status = nile4_pci_read(bus, devfn, where, 4, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - shift += 16; - result &= ~(0xffff << shift); - result |= (u16)(val << shift); - break; - case 1: - status = nile4_pci_read(bus, devfn, where, 4, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - if (where & 2) - shift += 16; - if (where & 1) - shift += 8; - result &= ~(0xff << shift); - result |= (u8)(val << shift); - break; - } - return nile4_pci_write(bus, devfn, where, 4, result); -} - -struct pci_ops nile4_pci_ops = { - .read = nile4_pci_read, - .write = nile4_pci_write, -}; - -struct { - struct resource ram; - struct resource flash; - struct resource isa_io; - struct resource pci_io; - struct resource isa_mem; - struct resource pci_mem; - struct resource nile4; - struct resource boot; -} ddb5074_resources = { - { "RAM", 0x00000000, 0x03ffffff, - IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64}, - { "Flash ROM", 0x04000000, 0x043fffff}, - { "Nile4 ISA I/O", 0x06000000, 0x060fffff}, - { "Nile4 PCI I/O", 0x06100000, 0x07ffffff}, - { "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, - { "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM}, - { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, - IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64}, - { "Boot ROM", 0x1fc00000, 0x1fffffff} -}; - -static void __init ddb5074_pci_fixup(void) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_NILE4) { - /* - * The first 64-bit PCI base register should point to - * the Nile4 control registers. Unfortunately this - * isn't the case, so we fix it ourselves. This allows - * the serial driver to find the UART. - */ - dev->resource[0] = ddb5074_resources.nile4; - request_resource(&iomem_resource, - &dev->resource[0]); - /* - * The second 64-bit PCI base register points to the - * first memory bank. Unfortunately the address is - * wrong, so we fix it (again). - */ - dev->resource[2] = ddb5074_resources.ram; - request_resource(&iomem_resource, - &dev->resource[2]); - } else if (dev->vendor == PCI_VENDOR_ID_AL - && dev->device == PCI_DEVICE_ID_AL_M7101) { - /* - * It's nice to have the LEDs on the GPIO pins - * available for debugging - */ - extern struct pci_dev *pci_pmu; - u8 t8; - - pci_pmu = dev; /* for LEDs D2 and D3 */ - /* Program the lines for LEDs D2 and D3 to output */ - nile4_pci_read_config_byte(dev, 0x7d, &t8); - t8 |= 0xc0; - nile4_pci_write_config_byte(dev, 0x7d, t8); - /* Turn LEDs D2 and D3 off */ - nile4_pci_read_config_byte(dev, 0x7e, &t8); - t8 |= 0xc0; - nile4_pci_write_config_byte(dev, 0x7e, t8); - } - } -} - -static void __init pcibios_fixup_irqs(void) -{ - struct pci_dev *dev = NULL; - int slot_num; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot_num = PCI_SLOT(dev->devfn); - switch (slot_num) { - case 0: - dev->irq = nile4_to_irq(NILE4_INT_INTE); - break; - case 1: - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 2: /* slot 1 */ - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 3: /* slot 2 */ - dev->irq = nile4_to_irq(NILE4_INT_INTB); - break; - case 4: /* slot 3 */ - dev->irq = nile4_to_irq(NILE4_INT_INTC); - break; - case 5: - /* - * Fixup so the serial driver can use the UART - */ - dev->irq = nile4_to_irq(NILE4_INT_UART); - break; - case 13: - dev->irq = nile4_to_irq(NILE4_INT_INTE); - break; - default: - break; - } - } -} - -void __init pcibios_init(void) -{ - printk("PCI: Probing PCI hardware\n"); - ioport_resource.end = 0x1ffffff; /* 32 MB */ - iomem_resource.end = 0x1fffffff; /* 512 MB */ - /* `ram' and `nile4' are requested through the Nile4 pci_dev */ - request_resource(&iomem_resource, &ddb5074_resources.flash); - request_resource(&iomem_resource, &ddb5074_resources.isa_io); - request_resource(&iomem_resource, &ddb5074_resources.pci_io); - request_resource(&iomem_resource, &ddb5074_resources.isa_mem); - request_resource(&iomem_resource, &ddb5074_resources.pci_mem); - request_resource(&iomem_resource, &ddb5074_resources.boot); - - pci_scan_bus(0, &nile4_pci_ops, NULL); - ddb5074_pci_fixup(); - pci_assign_unassigned_resources(); - pcibios_fixup_irqs(); -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - bus->resource[1] = &ddb5074_resources.pci_mem; -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - /* - * Don't touch the Nile 4 - */ - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_NILE4) return 0; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -struct pci_fixup pcibios_fixups[] = { }; diff -Nru a/arch/mips/ddb5074/prom.c b/arch/mips/ddb5074/prom.c --- a/arch/mips/ddb5074/prom.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/* - * arch/mips/ddb5074/prom.c -- NEC DDB Vrc-5074 PROM routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/bootmem.h> - -#include <asm/addrspace.h> -#include <asm/bootinfo.h> - - -char arcs_cmdline[COMMAND_LINE_SIZE]; - -void __init prom_init(const char *s) -{ - int i = 0; - - if (s != (void *) -1) - while (*s && i < sizeof(arcs_cmdline) - 1) - arcs_cmdline[i++] = *s++; - arcs_cmdline[i] = '\0'; - - mips_machgroup = MACH_GROUP_NEC_DDB; - mips_machtype = MACH_NEC_DDB5074; - - /* 64 MB non-upgradable */ - add_memory_region(0, 64 << 20, BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ -} diff -Nru a/arch/mips/ddb5074/setup.c b/arch/mips/ddb5074/setup.c --- a/arch/mips/ddb5074/setup.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,246 +0,0 @@ -/* - * arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kbd_ll.h> -#include <linux/kernel.h> -#include <linux/kdev_t.h> -#include <linux/types.h> -#include <linux/console.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/pc_keyb.h> -#include <linux/pci.h> -#include <linux/ide.h> - -#include <asm/addrspace.h> -#include <asm/bcache.h> -#include <asm/keyboard.h> -#include <asm/irq.h> -#include <asm/reboot.h> -#include <asm/gdb-stub.h> -#include <asm/nile4.h> -#include <asm/ddb5074.h> - - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -extern void breakpoint(void); -#endif - -#if defined(CONFIG_SERIAL_CONSOLE) -extern void console_setup(char *); -#endif - -extern struct ide_ops std_ide_ops; -extern struct rtc_ops ddb_rtc_ops; - -static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; - -static void ddb_machine_restart(char *command) -{ - u32 t; - - /* PCI cold reset */ - t = nile4_in32(NILE4_PCICTRL + 4); - t |= 0x40000000; - nile4_out32(NILE4_PCICTRL + 4, t); - /* CPU cold reset */ - t = nile4_in32(NILE4_CPUSTAT); - t |= 1; - nile4_out32(NILE4_CPUSTAT, t); - /* Call the PROM */ - back_to_prom(); -} - -static void ddb_machine_halt(void) -{ - printk("DDB Vrc-5074 halted.\n"); - do { - } while (1); -} - -static void ddb_machine_power_off(void) -{ - printk("DDB Vrc-5074 halted. Please turn off the power.\n"); - do { - } while (1); -} - -extern void ddb_irq_setup(void); - -void (*board_time_init) (struct irqaction * irq); - - -static void __init ddb_time_init(struct irqaction *irq) -{ - /* set the clock to 1 Hz */ - nile4_out32(NILE4_T2CTRL, 1000000); - /* enable the General-Purpose Timer */ - nile4_out32(NILE4_T2CTRL + 4, 0x00000001); - /* reset timer */ - nile4_out32(NILE4_T2CNTR, 0); - /* enable interrupt */ - nile4_enable_irq(NILE4_INT_GPT); - i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); - change_cp0_status(ST0_IM, - IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); -} - -void __init ddb_setup(void) -{ - extern int panic_timeout; - - irq_setup = ddb_irq_setup; - mips_io_port_base = NILE4_PCI_IO_BASE; - isa_slot_offset = NILE4_PCI_MEM_BASE; - request_region(0x00, 0x20, "dma1"); - request_region(0x40, 0x20, "timer"); - request_region(0x70, 0x10, "rtc"); - request_region(0x80, 0x10, "dma page reg"); - request_region(0xc0, 0x20, "dma2"); - board_time_init = ddb_time_init; - - _machine_restart = ddb_machine_restart; - _machine_halt = ddb_machine_halt; - _machine_power_off = ddb_machine_power_off; - -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - rtc_ops = &ddb_rtc_ops; - - /* Reboot on panic */ - panic_timeout = 180; -} - - -#define USE_NILE4_SERIAL 0 - -#if USE_NILE4_SERIAL -#define ns16550_in(reg) nile4_in8((reg)*8) -#define ns16550_out(reg, val) nile4_out8((reg)*8, (val)) -#else -#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8) -static inline u8 ns16550_in(u32 reg) -{ - return *(volatile u8 *) (NS16550_BASE + reg); -} - -static inline void ns16550_out(u32 reg, u8 val) -{ - *(volatile u8 *) (NS16550_BASE + reg) = val; -} -#endif - -#define NS16550_RBR 0 -#define NS16550_THR 0 -#define NS16550_DLL 0 -#define NS16550_IER 1 -#define NS16550_DLM 1 -#define NS16550_FCR 2 -#define NS16550_IIR 2 -#define NS16550_LCR 3 -#define NS16550_MCR 4 -#define NS16550_LSR 5 -#define NS16550_MSR 6 -#define NS16550_SCR 7 - -#define NS16550_LSR_DR 0x01 /* Data ready */ -#define NS16550_LSR_OE 0x02 /* Overrun */ -#define NS16550_LSR_PE 0x04 /* Parity error */ -#define NS16550_LSR_FE 0x08 /* Framing error */ -#define NS16550_LSR_BI 0x10 /* Break */ -#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */ -#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */ -#define NS16550_LSR_ERR 0x80 /* Error */ - - -void _serinit(void) -{ -#if USE_NILE4_SERIAL - ns16550_out(NS16550_LCR, 0x80); - ns16550_out(NS16550_DLM, 0x00); - ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */ - ns16550_out(NS16550_LCR, 0x00); - ns16550_out(NS16550_LCR, 0x03); - ns16550_out(NS16550_FCR, 0x47); -#else - /* done by PMON */ -#endif -} - -void _putc(char c) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, c); - if (c == '\n') { - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, '\r'); - } -} - -void _puts(const char *s) -{ - char c; - while ((c = *s++)) - _putc(c); -} - -char _getc(void) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR)); - return ns16550_in(NS16550_RBR); -} - -int _testc(void) -{ - return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0; -} - - -/* - * Hexadecimal 7-segment LED - */ -void ddb5074_led_hex(int hex) -{ - outb(hex, 0x80); -} - - -/* - * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543 - */ -struct pci_dev *pci_pmu = NULL; - -void ddb5074_led_d2(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0x7f; - else - t |= 0x80; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} - -void ddb5074_led_d3(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0xbf; - else - t |= 0x40; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} diff -Nru a/arch/mips/ddb5074/time.c b/arch/mips/ddb5074/time.c --- a/arch/mips/ddb5074/time.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,32 +0,0 @@ -/* - * arch/mips/ddb5074/time.c -- Timer routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/init.h> -#include <asm/mc146818rtc.h> - -static unsigned char ddb_rtc_read_data(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - - return inb_p(RTC_PORT(1)); -} - -static void ddb_rtc_write_data(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -static int ddb_rtc_bcd_mode(void) -{ - return 1; -} - -struct rtc_ops ddb_rtc_ops = { - ddb_rtc_read_data, - ddb_rtc_write_data, - ddb_rtc_bcd_mode -}; diff -Nru a/arch/mips/ddb5476/Makefile b/arch/mips/ddb5476/Makefile --- a/arch/mips/ddb5476/Makefile Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,10 +0,0 @@ -# -# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines -# under Linux. -# - -EXTRA_AFLAGS := $(CFLAGS) - -obj-y += setup.o irq.o time.o prom.o pci.o \ - int-handler.o nile4.o -obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o diff -Nru a/arch/mips/ddb5476/dbg_io.c b/arch/mips/ddb5476/dbg_io.c --- a/arch/mips/ddb5476/dbg_io.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,125 +0,0 @@ - -#include <linux/config.h> - -#if (defined(CONFIG_DDB5476) && defined(CONFIG_REMOTE_DEBUG)) - -/* --- CONFIG --- */ - -/* we need uint32 uint8 */ -/* #include "types.h" */ -typedef unsigned char uint8; -typedef unsigned int uint32; - -/* --- END OF CONFIG --- */ - -#define UART16550_BAUD_2400 2400 -#define UART16550_BAUD_4800 4800 -#define UART16550_BAUD_9600 9600 -#define UART16550_BAUD_19200 19200 -#define UART16550_BAUD_38400 38400 -#define UART16550_BAUD_57600 57600 -#define UART16550_BAUD_115200 115200 - -#define UART16550_PARITY_NONE 0 -#define UART16550_PARITY_ODD 0x08 -#define UART16550_PARITY_EVEN 0x18 -#define UART16550_PARITY_MARK 0x28 -#define UART16550_PARITY_SPACE 0x38 - -#define UART16550_DATA_5BIT 0x0 -#define UART16550_DATA_6BIT 0x1 -#define UART16550_DATA_7BIT 0x2 -#define UART16550_DATA_8BIT 0x3 - -#define UART16550_STOP_1BIT 0x0 -#define UART16550_STOP_2BIT 0x4 - -/* ----------------------------------------------------- */ - -/* === CONFIG === */ - -/* [jsun] we use the second serial port for kdb */ -#define BASE 0xa60002f8 -#define MAX_BAUD 115200 - -/* === END OF CONFIG === */ - -/* register offset */ -#define OFS_RCV_BUFFER 0 -#define OFS_TRANS_HOLD 0 -#define OFS_SEND_BUFFER 0 -#define OFS_INTR_ENABLE 1 -#define OFS_INTR_ID 2 -#define OFS_DATA_FORMAT 3 -#define OFS_LINE_CONTROL 3 -#define OFS_MODEM_CONTROL 4 -#define OFS_RS232_OUTPUT 4 -#define OFS_LINE_STATUS 5 -#define OFS_MODEM_STATUS 6 -#define OFS_RS232_INPUT 6 -#define OFS_SCRATCH_PAD 7 - -#define OFS_DIVISOR_LSB 0 -#define OFS_DIVISOR_MSB 1 - - -/* memory-mapped read/write of the port */ -#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) -#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) - -void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) -{ - /* disable interrupts */ - UART16550_WRITE(OFS_INTR_ENABLE, 0); - - /* set up buad rate */ - { - uint32 divisor; - - /* set DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x80); - - /* set divisor */ - divisor = MAX_BAUD / baud; - UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); - UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); - - /* clear DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x0); - } - - /* set data format */ - UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); -} - -static int remoteDebugInitialized = 0; - -uint8 getDebugChar(void) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_38400, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); - return UART16550_READ(OFS_RCV_BUFFER); -} - - -int putDebugChar(uint8 byte) -{ - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_9600, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); - UART16550_WRITE(OFS_SEND_BUFFER, byte); - return 1; -} - -#endif diff -Nru a/arch/mips/ddb5476/int-handler.S b/arch/mips/ddb5476/int-handler.S --- a/arch/mips/ddb5476/int-handler.S Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,136 +0,0 @@ -/* - * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler - * - * Based on arch/mips/sgi/kernel/indyIRQ.S - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -/* - * A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the INDY look basically (barring software IRQs - * which we don't use at all) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Local IRQ level zero - * 3 Local IRQ level one - * 4 8254 Timer zero - * 5 8254 Timer one - * 6 Bus Error - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Local IRQ zero - * Local IRQ one - * Bus Error - * 8254 Timer zero - * Lowest ---- 8254 Timer one - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(ddbIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 s1, CP0_CAUSE # get irq mask - -#if 1 - mfc0 t2,CP0_STATUS # get enabled interrupts - and s0, s1, t2 # isolate allowed ones -#endif - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP7 # cpu timer */ - bnez a0, cpu_timer_irq - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one - - /* Wheee, local level zero interrupt. */ - jal ddb_local0_irqdispatch - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error - - /* Wheee, local level one interrupt. */ - move a0, sp - jal ddb_local1_irqdispatch - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, an asynchronous bus error... */ - move a0, sp - jal ddb_buserror_irq - nop - - j ret_from_irq - nop - -1: - /* Here by mistake? This is possible, what can happen - * is that by the time we take the exception the IRQ - * pin goes low, so just leave if this is the case. - */ - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) - beq a0, zero, 1f - - /* Must be one of the 8254 timers... */ - move a0, sp - jal ddb_8254timer_irq - nop -1: - /* phamtom interrupt */ - move a0, s1 - jal ddb_phantom_irq - nop - j ret_from_irq - nop - -cpu_timer_irq: - li a0, 0 - move a1, sp - jal do_IRQ - /* jal ll_timer_interrupt */ - nop - j ret_from_irq - nop - END(ddbIRQ) diff -Nru a/arch/mips/ddb5476/irq.c b/arch/mips/ddb5476/irq.c --- a/arch/mips/ddb5476/irq.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,251 +0,0 @@ -/* - * arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/ptrace.h> -#include <asm/nile4.h> - -extern void __init i8259_init(void); -extern void i8259_disable_irq(unsigned int irq_nr); -extern void i8259_enable_irq(unsigned int irq_nr); - -extern asmlinkage void ddbIRQ(void); -extern asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs); -extern asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - - -void no_action(int cpl, void *dev_id, struct pt_regs *regs) -{ -} - - -#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ -#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ -#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ - -#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ -#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ -#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ - -#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ -#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ - -#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ -#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ - -#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ -#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ - -static struct { - struct resource m1543_config; - struct resource pic_elcr; -} m1543_ioport = { - { "M1543 config", M1543_PNP_CONFIG, M1543_PNP_CONFIG + 1, - IORESOURCE_BUSY}, - { "pic ELCR", M1543_INT1_MASTER_ELCR, M1543_INT1_MASTER_ELCR + 1, - IORESOURCE_BUSY} -}; - -static void m1543_irq_setup(void) -{ - /* - * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all - * the possible IO sources in the M1543 are in use by us. We will - * use the following mapping: - * - * IRQ1 - keyboard (default set by M1543) - * IRQ3 - reserved for UART B (default set by M1543) (note that - * the schematics for the DDB Vrc-5476 board seem to - * indicate that IRQ3 is connected to the DS1386 - * watchdog timer interrupt output so we might have - * a conflict) - * IRQ4 - reserved for UART A (default set by M1543) - * IRQ5 - parallel (default set by M1543) - * IRQ8 - DS1386 time of day (RTC) interrupt - * IRQ9 - USB (hardwired in ddb_setup) - * IRQ10 - PMU (hardwired in ddb_setup) - * IRQ12 - mouse - * IRQ14,15 - IDE controller (need to be confirmed, jsun) - */ - - /* - * Assing mouse interrupt to IRQ12 - */ - - /* Enter configuration mode */ - outb(0x51, M1543_PNP_CONFIG); - outb(0x23, M1543_PNP_CONFIG); - - /* Select logical device 7 (Keyboard) */ - outb(0x07, M1543_PNP_INDEX); - outb(0x07, M1543_PNP_DATA); - - /* Select IRQ12 */ - outb(0x72, M1543_PNP_INDEX); - outb(0x0c, M1543_PNP_DATA); - - /* Leave configration mode */ - outb(0xbb, M1543_PNP_CONFIG); - - - /* Initialize the 8259 PIC in the M1543 */ - i8259_init(); - - /* Enable the interrupt cascade from M1543 */ - nile4_enable_irq(NILE4_INT_INTC); - - /* request io ports */ - if (request_resource(&ioport_resource, &m1543_ioport.m1543_config) - || request_resource(&ioport_resource, &m1543_ioport.pic_elcr)) { - printk("m1543_irq_setup : requesting io ports failed.\n"); - for (;;); - } -} - -static void nile4_irq_setup(void) -{ - int i; - - /* Map all interrupts to CPU int #0 */ - nile4_map_irq_all(0); - - /* PCI INTA#-E# must be level triggered */ - nile4_set_pci_irq_level_or_edge(0, 1); - nile4_set_pci_irq_level_or_edge(1, 1); - nile4_set_pci_irq_level_or_edge(2, 1); - nile4_set_pci_irq_level_or_edge(3, 1); - - /* PCI INTA#, B#, D# must be active low, INTC# must be active high */ - nile4_set_pci_irq_polarity(0, 0); - nile4_set_pci_irq_polarity(1, 0); - nile4_set_pci_irq_polarity(2, 1); - nile4_set_pci_irq_polarity(3, 0); - - for (i = 0; i < 16; i++) - nile4_clear_irq(i); - - /* Enable CPU int #0 */ - nile4_enable_irq_output(0); - - /* memory resource acquire in ddb_setup */ -} - - -/* - * IRQ2 is cascade interrupt to second interrupt controller - */ -static struct irqaction irq2 = { no_action, 0, 0, "cascade", NULL, NULL }; - - -void disable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_disable_irq(irq_nr); - else - nile4_disable_irq(irq_to_nile4(irq_nr)); -} - -void enable_irq(unsigned int irq_nr) -{ - if (is_i8259_irq(irq_nr)) - i8259_enable_irq(irq_nr); - else - nile4_enable_irq(irq_to_nile4(irq_nr)); -} - -int table[16] = { 0, }; - -void ddb_local0_irqdispatch(struct pt_regs *regs) -{ - u32 mask; - int nile4_irq; -#if 0 - volatile static int nesting = 0; - if (nesting++ == 0) - ddb5476_led_d3(1); - ddb5476_led_hex(nesting < 16 ? nesting : 15); -#endif - - mask = nile4_get_irq_stat(0); - nile4_clear_irq_mask(mask); - - /* Handle the timer interrupt first */ - if (mask & (1 << NILE4_INT_GPT)) { - nile4_disable_irq(NILE4_INT_GPT); - do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs); - nile4_enable_irq(NILE4_INT_GPT); - mask &= ~(1 << NILE4_INT_GPT); - } - for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) - if (mask & 1) { - nile4_disable_irq(nile4_irq); - if (nile4_irq == NILE4_INT_INTC) { - int i8259_irq = nile4_i8259_iack(); - i8259_do_irq(i8259_irq, regs); - } else { - do_IRQ(nile4_to_irq(nile4_irq), regs); - } - nile4_enable_irq(nile4_irq); - } -#if 0 - if (--nesting == 0) - ddb5476_led_d3(0); - ddb5476_led_hex(nesting < 16 ? nesting : 15); -#endif -} - -void ddb_local1_irqdispatch(void) -{ - printk("ddb_local1_irqdispatch called\n"); -} - -void ddb_buserror_irq(void) -{ - printk("ddb_buserror_irq called\n"); -} - -void ddb_8254timer_irq(void) -{ - printk("ddb_8254timer_irq called\n"); -} - -void ddb_phantom_irq(unsigned long cause) -{ - printk("phantom interrupts detected : \n"); - printk("\tcause \t\t0x%08x\n", cause); - printk("\tcause reg\t0x%08x\n", - read_32bit_cp0_register(CP0_CAUSE)); - printk("\tstatus reg\t0x%08x\n", - read_32bit_cp0_register(CP0_STATUS)); -} - -void __init ddb_irq_setup(void) -{ -#ifdef CONFIG_REMOTE_DEBUG - printk("Wait for gdb client connection ...\n"); - set_debug_traps(); - breakpoint(); /* you may move this line to whereever you want :-) */ -#endif - i8259_setup_irq(2, &irq2); - - nile4_irq_setup(); - m1543_irq_setup(); - - /* we pin #0 - #4 (no internal timer) */ - change_cp0_status(ST0_IM, - IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); - - set_except_vector(0, ddbIRQ); -} diff -Nru a/arch/mips/ddb5476/nile4.c b/arch/mips/ddb5476/nile4.c --- a/arch/mips/ddb5476/nile4.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,293 +0,0 @@ -/* - * arch/mips/ddb5074/nile4.c -- NEC Vrc-5074 Nile 4 support routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/kernel.h> -#include <linux/types.h> - -#include <asm/nile4.h> - - -/* - * Physical Device Address Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pdar(u32 pdar, u32 phys, u32 size, int width, - int on_memory_bus, int visible) -{ - u32 maskbits; - u32 widthbits; - - if (pdar > NILE4_BOOTCS || (pdar & 7)) { - printk("nile4_set_pdar: invalid pdar %d\n", pdar); - return; - } - if (pdar == NILE4_INTCS && size != 0x00200000) { - printk("nile4_set_pdar: INTCS size must be 2 MB\n"); - return; - } - switch (size) { -#if 0 /* We don't support 4 GB yet */ - case 0x100000000: /* 4 GB */ - maskbits = 4; - break; -#endif - case 0x80000000: /* 2 GB */ - maskbits = 5; - break; - case 0x40000000: /* 1 GB */ - maskbits = 6; - break; - case 0x20000000: /* 512 MB */ - maskbits = 7; - break; - case 0x10000000: /* 256 MB */ - maskbits = 8; - break; - case 0x08000000: /* 128 MB */ - maskbits = 9; - break; - case 0x04000000: /* 64 MB */ - maskbits = 10; - break; - case 0x02000000: /* 32 MB */ - maskbits = 11; - break; - case 0x01000000: /* 16 MB */ - maskbits = 12; - break; - case 0x00800000: /* 8 MB */ - maskbits = 13; - break; - case 0x00400000: /* 4 MB */ - maskbits = 14; - break; - case 0x00200000: /* 2 MB */ - maskbits = 15; - break; - case 0: /* OFF */ - maskbits = 0; - break; - default: - printk("nile4_set_pdar: unsupported size %p\n", - (void *) size); - return; - } - switch (width) { - case 8: - widthbits = 0; - break; - case 16: - widthbits = 1; - break; - case 32: - widthbits = 2; - break; - case 64: - widthbits = 3; - break; - default: - printk("nile4_set_pdar: unsupported width %d\n", width); - return; - } - nile4_out32(pdar, maskbits | (on_memory_bus ? 0x10 : 0) | - (visible ? 0x20 : 0) | (widthbits << 6) | - (phys & 0xffe00000)); - nile4_out32(pdar + 4, 0); - /* - * When programming a PDAR, the register should be read immediately - * after writing it. This ensures that address decoders are properly - * configured. - */ - nile4_in32(pdar); - nile4_in32(pdar + 4); -} - - -/* - * PCI Master Registers - * - * Note: 32 bit addressing only! - */ -void nile4_set_pmr(u32 pmr, u32 type, u32 addr) -{ - if (pmr != NILE4_PCIINIT0 && pmr != NILE4_PCIINIT1) { - printk("nile4_set_pmr: invalid pmr %d\n", pmr); - return; - } - switch (type) { - case NILE4_PCICMD_IACK: /* PCI Interrupt Acknowledge */ - case NILE4_PCICMD_IO: /* PCI I/O Space */ - case NILE4_PCICMD_MEM: /* PCI Memory Space */ - case NILE4_PCICMD_CFG: /* PCI Configuration Space */ - break; - default: - printk("nile4_set_pmr: invalid type %d\n", type); - return; - } - nile4_out32(pmr, (type << 1) | 0x10 | (addr & 0xffe00000)); - nile4_out32(pmr + 4, 0); -} - - -/* - * Interrupt Programming - */ -void nile4_map_irq(int nile4_irq, int cpu_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(7 << (nile4_irq * 4)); - t |= cpu_irq << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_map_irq_all(int cpu_irq) -{ - u32 all, t; - - all = cpu_irq; - all |= all << 4; - all |= all << 8; - all |= all << 16; - t = nile4_in32(NILE4_INTCTRL); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL, t); - t = nile4_in32(NILE4_INTCTRL + 4); - t &= 0x88888888; - t |= all; - nile4_out32(NILE4_INTCTRL + 4, t); -} - -void nile4_enable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t |= 8 << (nile4_irq * 4); - nile4_out32(offset, t); -} - -void nile4_disable_irq(int nile4_irq) -{ - u32 offset, t; - - offset = NILE4_INTCTRL; - if (nile4_irq >= 8) { - offset += 4; - nile4_irq -= 8; - } - t = nile4_in32(offset); - t &= ~(8 << (nile4_irq * 4)); - nile4_out32(offset, t); -} - -void nile4_disable_irq_all(void) -{ - nile4_out32(NILE4_INTCTRL, 0); - nile4_out32(NILE4_INTCTRL + 4, 0); -} - -u16 nile4_get_irq_stat(int cpu_irq) -{ - return nile4_in16(NILE4_INTSTAT0 + cpu_irq * 2); -} - -void nile4_enable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t |= 1 << (16 + cpu_irq); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_disable_irq_output(int cpu_irq) -{ - u32 t; - - t = nile4_in32(NILE4_INTSTAT1 + 4); - t &= ~(1 << (16 + cpu_irq)); - nile4_out32(NILE4_INTSTAT1, t); -} - -void nile4_set_pci_irq_polarity(int pci_irq, int high) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (high) - t &= ~(1 << (pci_irq * 2)); - else - t |= 1 << (pci_irq * 2); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) -{ - u32 t; - - t = nile4_in32(NILE4_INTPPES); - if (level) - t |= 2 << (pci_irq * 2); - else - t &= ~(2 << (pci_irq * 2)); - nile4_out32(NILE4_INTPPES, t); -} - -void nile4_clear_irq(int nile4_irq) -{ - nile4_out32(NILE4_INTCLR, 1 << nile4_irq); -} - -void nile4_clear_irq_mask(u32 mask) -{ - nile4_out32(NILE4_INTCLR, mask); -} - -u8 nile4_i8259_iack(void) -{ - u8 irq; - - /* Set window 0 for interrupt acknowledge */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IACK, 0); - irq = *(volatile u8 *) NILE4_PCI_IACK_BASE; - /* Set window 0 for PCI I/O space */ - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0); - return irq; -} - -#if 0 -void nile4_dump_irq_status(void) -{ - printk("CPUSTAT = %p:%p\n", (void *) nile4_in32(NILE4_CPUSTAT + 4), - (void *) nile4_in32(NILE4_CPUSTAT)); - printk("INTCTRL = %p:%p\n", (void *) nile4_in32(NILE4_INTCTRL + 4), - (void *) nile4_in32(NILE4_INTCTRL)); - printk("INTSTAT0 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT0 + 4), - (void *) nile4_in32(NILE4_INTSTAT0)); - printk("INTSTAT1 = %p:%p\n", - (void *) nile4_in32(NILE4_INTSTAT1 + 4), - (void *) nile4_in32(NILE4_INTSTAT1)); - printk("INTCLR = %p:%p\n", (void *) nile4_in32(NILE4_INTCLR + 4), - (void *) nile4_in32(NILE4_INTCLR)); - printk("INTPPES = %p:%p\n", (void *) nile4_in32(NILE4_INTPPES + 4), - (void *) nile4_in32(NILE4_INTPPES)); -} -#endif diff -Nru a/arch/mips/ddb5476/pci.c b/arch/mips/ddb5476/pci.c --- a/arch/mips/ddb5476/pci.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,430 +0,0 @@ -/* - * arch/mips/ddb5476/pci.c -- NEC DDB Vrc-5074 PCI access routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Albert Dorofeev <albert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/ioport.h> - -#include <asm-mips/nile4.h> - -static u32 nile4_pre_pci_access0(int slot_num) -{ - u32 pci_addr = 0; - u32 virt_addr = NILE4_PCI_CFG_BASE; - - /* work around the bug for Vrc5476 */ - if (slot_num == 13) - return NILE4_BASE + NILE4_PCI_BASE; - - /* Set window 1 address 08000000 - 32 bit - 128 MB (PCI config space) */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(virt_addr), 0x08000000, 32, 0, - 0); - - // [jsun] we start scanning from addr:10, - // with 128M we can go up to addr:26 (slot 16) - if (slot_num <= 16) { - virt_addr += 0x00000400 << slot_num; - } else { - /* for high slot, we have to set higher PCI base addr */ - pci_addr = 0x00000400 << slot_num; - } - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, pci_addr); - return virt_addr; -} - -static void nile4_post_pci_access0(void) -{ - /* - * Set window 1 back to address 08000000 - 32 bit - 128 MB - * (PCI IO space) - */ - nile4_set_pdar(NILE4_PCIW1, PHYSADDR(NILE4_PCI_MEM_BASE), - 0x08000000, 32, 1, 1); - // nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0); - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000); -} - -static int nile4_pci_read(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 * val) -{ - int status, slot_num, func_num; - u32 result, base, addr; - - if(size == 4) { - /* Do we need to generate type 1 configure transaction? */ - if (bus->number) { - /* FIXME - not working yet */ - return PCIBIOS_FUNC_NOT_SUPPORTED; - /* - * the largest type 1 configuration addr is 16M, - * < 256M config space - */ - slot_num = 0; - addr = (bus->number << 16) | (devfn < 8) | where | 1; - } else { - slot_num = PCI_SLOT(devfn); - func_num = PCI_FUNC(devfn); - addr = (func_num << 8) + where; - } - base = nile4_pre_pci_access0(slot_num); - *val = *(volatile u32 *) (base + addr); - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; - } - - status = nile4_pci_read(bus, devfn, where & ~3, 4, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - switch (size) { - case 1: - if (where & 1) - result >>= 8; - if (where & 2) - result >>= 16; - *val = (u8)(result & 0xff); - break; - case 2: - if (where & 2) - result >>= 16; - *val = (u16)(result & 0xffff); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int nile4_pci_write(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 val) -{ - int status, slot_num, func_num, shift = 0; - u32 result, base, addr; - - status = nile4_pci_read(bus, devfn, where & ~3, 4, &result); - if (status != PCIBIOS_SUCCESSFUL) - return status; - switch (size) { - case 1: - if (where & 2) - shift += 16; - if (where & 1) - shift += 8; - result &= ~(0xff << shift); - result |= val << shift; - break; - case 2: - if (where & 2) - shift += 16; - result &= ~(0xffff << shift); - result |= val << shift; - break; - case 4: - /* Do we need to generate type 1 configure transaction? */ - if (bus->number) { - /* FIXME - not working yet */ - return PCIBIOS_FUNC_NOT_SUPPORTED; - - /* the largest type 1 configuration addr is 16M, - * < 256M config space */ - slot_num = 0; - addr = (bus->number << 16) | (devfn < 8) | - where | 1; - } else { - slot_num = PCI_SLOT(devfn); - func_num = PCI_FUNC(devfn); - addr = (func_num << 8) + where; - } - - base = nile4_pre_pci_access0(slot_num); - *(volatile u32 *) (base + addr) = val; - nile4_post_pci_access0(); - return PCIBIOS_SUCCESSFUL; - } - return nile4_pci_write(bus, devfn, where & ~3, 4, result); -} - -struct pci_ops nile4_pci_ops = { - .read = nile4_pci_read, - .write = nile4_pci_write, -}; - -struct { - struct resource ram; - struct resource flash; - struct resource isa_io; - struct resource pci_io; - struct resource isa_mem; - struct resource pci_mem; - struct resource nile4; - struct resource boot; -} ddb5476_resources = { - // { "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 }, - { - "RAM", 0x00000000, 0x03ffffff, IORESOURCE_MEM}, { - "Flash ROM", 0x04000000, 0x043fffff}, { - "Nile4 ISA I/O", 0x06000000, 0x060fffff}, { - "Nile4 PCI I/O", 0x06100000, 0x07ffffff}, { - "Nile4 ISA mem", 0x08000000, 0x08ffffff, IORESOURCE_MEM}, { - "Nile4 PCI mem", 0x09000000, 0x0fffffff, IORESOURCE_MEM}, - // { "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM | PCI_BASE_ADDRESS_MEM_TYPE_64 }, - { - "Nile4 ctrl", 0x1fa00000, 0x1fbfffff, IORESOURCE_MEM}, { - "Boot ROM", 0x1fc00000, 0x1fffffff} -}; - -struct resource M5229_resources[5] = { - {"M5229 BAR0", 0x1f0, 0x1f3, IORESOURCE_IO}, - {"M5229 BAR1", 0x3f4, 0x3f7, IORESOURCE_IO}, - {"M5229 BAR2", 0x170, 0x173, IORESOURCE_IO}, - {"M5229 BAR3", 0x374, 0x377, IORESOURCE_IO}, - {"M5229 BAR4", 0xf000, 0xf00f, IORESOURCE_IO} -}; - -static void __init ddb5476_pci_fixup(void) -{ - struct pci_dev *dev = NULL; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_VRC5476) { - /* - * The first 64-bit PCI base register should point to - * the Nile4 control registers. Unfortunately this - * isn't the case, so we fix it ourselves. This allows - * the serial driver to find the UART. - */ - dev->resource[0] = ddb5476_resources.nile4; - request_resource(&iomem_resource, - &dev->resource[0]); - /* - * The second 64-bit PCI base register points to the - * first memory bank. Unfortunately the address is - * wrong, so we fix it (again). - */ - - /* [jsun] We cannot request the resource anymore, - * because kernel/setup.c has already reserved "System - * RAM" resource at the same spot. - * The fundamental problem here is that PCI host - * controller should not put system RAM mapping in BAR - * and make subject to PCI resource assignement. - * Current fix is a total hack. We set parent to 1 so - * so that PCI resource assignement code is fooled to - * think the resource is assigned, and will not attempt - * to mess with it. - */ - dev->resource[2] = ddb5476_resources.ram; - if (request_resource(&iomem_resource, - &dev->resource[2]) ) { - dev->resource[2].parent = 0x1; - } - - } else if (dev->vendor == PCI_VENDOR_ID_AL - && dev->device == PCI_DEVICE_ID_AL_M7101) { - /* - * It's nice to have the LEDs on the GPIO pins - * available for debugging - */ - extern struct pci_dev *pci_pmu; - u8 t8; - - pci_pmu = dev; /* for LEDs D2 and D3 */ - /* Program the lines for LEDs D2 and D3 to output */ - nile4_pci_read(dev->bus, dev->devfn, 0x7d, 1, &t8); - t8 |= 0xc0; - nile4_pci_write(dev->bus, dev->devfn, 0x7d, 1, t8); - /* Turn LEDs D2 and D3 off */ - nile4_pci_read(dev->bus, dev->devfn, 0x7e, 1, &t8); - t8 |= 0xc0; - nile4_pci_write(dev->bus, dev->devfn, 0x7e, 1, t8); - } else if (dev->vendor == PCI_VENDOR_ID_AL && - dev->device == 0x5229) { - int i; - for (i = 0; i < 5; i++) { - dev->resource[i] = M5229_resources[i]; - request_resource(&ioport_resource, - &dev->resource[i]); - } - } - } -} - -static void __init pcibios_fixup_irqs(void) -{ - struct pci_dev *dev = NULL; - int slot_num; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot_num = PCI_SLOT(dev->devfn); - switch (slot_num) { - case 3: /* re-programmed to USB */ - dev->irq = 9; /* hard-coded; see irq.c */ - break; - case 4: /* re-programmed to PMU */ - dev->irq = 10; /* hard-coded; see irq.c */ - break; - case 6: /* on-board pci-pci bridge */ - dev->irq = 0xff; - break; - case 7: /* on-board ether */ - dev->irq = nile4_to_irq(NILE4_INT_INTB); - break; - case 8: /* ISA-PCI bridge */ - dev->irq = nile4_to_irq(NILE4_INT_INTC); - break; - case 9: /* ext slot #3 */ - dev->irq = nile4_to_irq(NILE4_INT_INTD); - break; - case 10: /* ext slot #4 */ - dev->irq = nile4_to_irq(NILE4_INT_INTA); - break; - case 13: /* Vrc5476 */ - dev->irq = 0xff; - break; - case 14: /* HD controller, M5229 */ - dev->irq = 14; - break; - default: - printk - ("JSUN : in pcibios_fixup_irqs - unkown slot %d\n", - slot_num); - panic - ("JSUN : in pcibios_fixup_irqs - unkown slot.\n"); - } - } -} - -void __init pcibios_init(void) -{ - printk("PCI: Emulate bios initialization \n"); - /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */ - *(long *) (NILE4_BASE + NILE4_BAR0) = 0x8; - - printk("PCI: Probing PCI hardware\n"); - ioport_resource.end = 0x1ffffff; /* 32 MB */ - iomem_resource.end = 0x1fffffff; /* 512 MB */ - - /* `ram' and `nile4' are requested through the Nile4 pci_dev */ - request_resource(&iomem_resource, &ddb5476_resources.flash); - request_resource(&iomem_resource, &ddb5476_resources.isa_io); - request_resource(&iomem_resource, &ddb5476_resources.pci_io); - request_resource(&iomem_resource, &ddb5476_resources.isa_mem); - request_resource(&iomem_resource, &ddb5476_resources.pci_mem); - request_resource(&iomem_resource, &ddb5476_resources.boot); - - pci_scan_bus(0, &nile4_pci_ops, NULL); - ddb5476_pci_fixup(); - pci_assign_unassigned_resources(); - pcibios_fixup_irqs(); -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - /* [jsun] we don't know how to fix sub-buses yet */ - if (bus->number == 0) { - bus->resource[1] = &ddb5476_resources.pci_mem; - } -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -#if 0 /* original DDB5074 code */ -void __devinit -pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) -{ - /* - * our caller figure out range by going through the dev structures. - * I guess this is the place to fix things up if the bus is using a - * different view of the addressing space. - */ - - if (bus->number == 0) { - ranges->io_start -= bus->resource[0]->start; - ranges->io_end -= bus->resource[0]->start; - ranges->mem_start -= bus->resource[1]->start; - ranges->mem_end -= bus->resource[1]->start; - } -} -#endif - -int pcibios_enable_resources(struct pci_dev *dev) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - /* - * Don't touch the Nile 4 - */ - if (dev->vendor == PCI_VENDOR_ID_NEC && - dev->device == PCI_DEVICE_ID_NEC_VRC5476) return 0; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx = 0; idx < 6; idx++) { - r = &dev->resource[idx]; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } - return 0; -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - return pcibios_enable_resources(dev); -} - -void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - struct pci_dev *dev = data; - - if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; - - /* We need to avoid collisions with `mirrored' VGA ports - and other strange ISA hardware, so we always want the - addresses kilobyte aligned. */ - if (size > 0x100) { - printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, - dev->resource - res, size); - } - - start = (start + 1024 - 1) & ~(1024 - 1); - res->start = start; - } -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -struct pci_fixup pcibios_fixups[] = { {0} }; diff -Nru a/arch/mips/ddb5476/prom.c b/arch/mips/ddb5476/prom.c --- a/arch/mips/ddb5476/prom.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,43 +0,0 @@ -/* - * arch/mips/ddb5476/prom.c -- NEC DDB Vrc-5476 PROM routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - * - * Jun Sun - modified for DDB5476. - */ -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/bootmem.h> - -#include <asm/addrspace.h> -#include <asm/bootinfo.h> - - -char arcs_cmdline[COMMAND_LINE_SIZE]; - -/* [jsun@junsun.net] PMON passes arguments in C main() style */ -void __init prom_init(int argc, const char **arg) -{ - int i; - - /* arg[0] is "g", the rest is boot parameters */ - arcs_cmdline[0] = '\0'; - for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) - >= sizeof(arcs_cmdline)) - break; - strcat(arcs_cmdline, arg[i]); - strcat(arcs_cmdline, " "); - } - - mips_machgroup = MACH_GROUP_NEC_DDB; - mips_machtype = MACH_NEC_DDB5476; - /* 64 MB non-upgradable */ - add_memory_region(0, 64 << 20, BOOT_MEM_RAM); -} - -void __init prom_free_prom_memory(void) -{ -} diff -Nru a/arch/mips/ddb5476/setup.c b/arch/mips/ddb5476/setup.c --- a/arch/mips/ddb5476/setup.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,393 +0,0 @@ -/* - * arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kbd_ll.h> -#include <linux/kernel.h> -#include <linux/kdev_t.h> -#include <linux/types.h> -#include <linux/console.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/pc_keyb.h> -#include <linux/pci.h> -#include <linux/ide.h> - -#include <asm/addrspace.h> -#include <asm/bcache.h> -#include <asm/keyboard.h> -#include <asm/irq.h> -#include <asm/reboot.h> -#include <asm/gdb-stub.h> -#include <asm/nile4.h> -#include <asm/time.h> - - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -extern void breakpoint(void); -#endif - -#if defined(CONFIG_SERIAL_CONSOLE) -extern void console_setup(char *); -#endif - -extern struct ide_ops std_ide_ops; -extern struct rtc_ops ddb_rtc_ops; -extern struct kbd_ops std_kbd_ops; - -static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; - -static void ddb_machine_restart(char *command) -{ - u32 t; - - /* PCI cold reset */ - t = nile4_in32(NILE4_PCICTRL + 4); - t |= 0x40000000; - nile4_out32(NILE4_PCICTRL + 4, t); - /* CPU cold reset */ - t = nile4_in32(NILE4_CPUSTAT); - t |= 1; - nile4_out32(NILE4_CPUSTAT, t); - /* Call the PROM */ - back_to_prom(); -} - -static void ddb_machine_halt(void) -{ - printk("DDB Vrc-5476 halted.\n"); - while (1); -} - -static void ddb_machine_power_off(void) -{ - printk("DDB Vrc-5476 halted. Please turn off the power.\n"); - while (1); -} - -extern void ddb_irq_setup(void); - -static void __init ddb_time_init(struct irqaction *irq) -{ - printk("ddb_time_init invoked.\n"); - mips_counter_frequency = 83000000; -} - -static void __init ddb_timer_setup(struct irqaction *irq) -{ - unsigned int count; - - /* we are using the cpu counter for timer interrupts */ - i8259_setup_irq(0, irq); - set_cp0_status(IE_IRQ5); - - /* to generate the first timer interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register(CP0_COMPARE, count + 1000); - -#if 0 /* the old way to do timer interrupt */ - /* set the clock to 100 Hz */ - nile4_out32(NILE4_T2CTRL, 830000); - /* enable the General-Purpose Timer */ - nile4_out32(NILE4_T2CTRL + 4, 0x00000001); - /* reset timer */ - nile4_out32(NILE4_T2CNTR, 0); - /* enable interrupt */ - nile4_enable_irq(NILE4_INT_GPT); - i8259_setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); -#endif -} - -static struct { - struct resource dma1; - struct resource pic1; - struct resource timer; - struct resource rtc; - struct resource dma_page_reg; - struct resource pic2; - struct resource dma2; -} ddb5476_ioport = { - { - "dma1", 0x00, 0x1f, IORESOURCE_BUSY}, { - "pic1", 0x20, 0x3f, IORESOURCE_BUSY}, { - "timer", 0x40, 0x5f, IORESOURCE_BUSY}, { - "rtc", 0x70, 0x7f, IORESOURCE_BUSY}, { - "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, { - "pic2", 0xa0, 0xbf, IORESOURCE_BUSY}, { - "dma2", 0xc0, 0xdf, IORESOURCE_BUSY} -}; - -static struct { - struct resource nile4; -} ddb5476_iomem = { - { "Nile 4", NILE4_BASE, NILE4_BASE + NILE4_SIZE - 1, IORESOURCE_BUSY} -}; - -void __init ddb_setup(void) -{ - extern int panic_timeout; - - irq_setup = ddb_irq_setup; - mips_io_port_base = NILE4_PCI_IO_BASE; - isa_slot_offset = NILE4_PCI_MEM_BASE; - - board_time_init = ddb_time_init; - board_timer_setup = ddb_timer_setup; - - _machine_restart = ddb_machine_restart; - _machine_halt = ddb_machine_halt; - _machine_power_off = ddb_machine_power_off; - - /* request io port/mem resources */ - if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) || - request_resource(&ioport_resource, &ddb5476_ioport.pic1) || - request_resource(&ioport_resource, &ddb5476_ioport.timer) || - request_resource(&ioport_resource, &ddb5476_ioport.rtc) || - request_resource(&ioport_resource, - &ddb5476_ioport.dma_page_reg) - || request_resource(&ioport_resource, &ddb5476_ioport.pic2) - || request_resource(&ioport_resource, &ddb5476_ioport.dma2) - || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) { - printk - ("ddb_setup - requesting oo port resources failed.\n"); - for (;;); - } -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif - rtc_ops = &ddb_rtc_ops; - -#ifdef CONFIG_PC_KEYB - kbd_ops = &std_kbd_ops; -#endif - - /* Reboot on panic */ - panic_timeout = 180; - - /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */ - /* *(long*)0xbfa00218 = 0x8; */ - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - - - /* board initialization stuff - non-fundamental, but need to be set - * before kernel runs */ - - /* setup I/O space */ - nile4_set_pdar(NILE4_PCIW0, - PHYSADDR(NILE4_PCI_IO_BASE), 0x02000000, 32, 0, 0); - nile4_set_pmr(NILE4_PCIINIT0, NILE4_PCICMD_IO, 0); - - /* map config space to 0xa8000000, 128MB */ - nile4_set_pdar(NILE4_PCIW1, - PHYSADDR(NILE4_PCI_CFG_BASE), 0x08000000, 32, 0, 0); - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_CFG, 0x0); - - /* ----- M1543 PCI setup ------ */ - - /* we know M1543 PCI-ISA controller is at addr:18 */ - /* xxxx1010 makes USB at addr:13 and PMU at addr:14 */ - *(volatile unsigned char *) 0xa8040072 &= 0xf0; - *(volatile unsigned char *) 0xa8040072 |= 0xa; - - /* setup USB interrupt to IRQ 9, (bit 0:3 - 0001) - * no IOCHRDY signal, (bit 7 - 1) - * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1) - * Bypass USB Master INTAJ level to edge conversion (bit 4 - 0) - */ - *(unsigned char *) 0xa8040074 = 0xc1; - - /* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011) - * SCI routing to IRQ 13 disabled (bit 7 - 1) - * SCI interrupt level to edge conversion bypassed (bit 4 - 0) - */ - *(unsigned char *) 0xa8040076 = 0x83; - - /* setup IDE controller - * enable IDE controller (bit 6 - 1) - * IDE IDSEL to be addr:24 (bit 4:5 - 11) - * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0) - * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0) - * primary IRQ is 14, secondary is 15 (bit 1:0 - 01 - */ - // *(unsigned char*)0xa8040058 = 0x71; - // *(unsigned char*)0xa8040058 = 0x79; - // *(unsigned char*)0xa8040058 = 0x74; // use SIRQ, primary tri-state - *(unsigned char *) 0xa8040058 = 0x75; // primary tri-state - -#if 0 - /* this is not necessary if M5229 does not use SIRQ */ - *(unsigned char *) 0xa8040044 = 0x0d; // primary to IRQ 14 - *(unsigned char *) 0xa8040075 = 0x0d; // secondary to IRQ 14 -#endif - - /* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */ - /* M5229 IDSEL is addr:24; see above setting */ - *(unsigned char *) 0xa9000050 |= 0x1; - - /* enable bus master (bit 2) and IO decoding (bit 0) */ - *(unsigned char *) 0xa9000004 |= 0x5; - - /* enable native, copied from arch/ppc/k2boot/head.S */ - /* TODO - need volatile, need to be portable */ - *(unsigned char *) 0xa9000009 = 0xff; - - /* ----- end of M1543 PCI setup ------ */ - - /* ----- reset on-board ether chip ------ */ - *((volatile u32 *) 0xa8020004) |= 1; /* decode I/O */ - *((volatile u32 *) 0xa8020010) = 0; /* set BAR address */ - - /* send reset command */ - *((volatile u32 *) 0xa6000000) = 1; /* do a soft reset */ - - /* disable ether chip */ - *((volatile u32 *) 0xa8020004) = 0; /* disable any decoding */ - - /* put it into sleep */ - *((volatile u32 *) 0xa8020040) = 0x80000000; - - /* ----- end of reset on-board ether chip ------ */ - - /* ----- set pci window 1 to pci memory space -------- */ - nile4_set_pdar(NILE4_PCIW1, - PHYSADDR(NILE4_PCI_MEM_BASE), 0x08000000, 32, 0, 0); - // nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0); - nile4_set_pmr(NILE4_PCIINIT1, NILE4_PCICMD_MEM, 0x08000000); - -} - -#define USE_NILE4_SERIAL 0 - -#if USE_NILE4_SERIAL -#define ns16550_in(reg) nile4_in8((reg)*8) -#define ns16550_out(reg, val) nile4_out8((reg)*8, (val)) -#else -#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8) -static inline u8 ns16550_in(u32 reg) -{ - return *(volatile u8 *) (NS16550_BASE + reg); -} - -static inline void ns16550_out(u32 reg, u8 val) -{ - *(volatile u8 *) (NS16550_BASE + reg) = val; -} -#endif - -#define NS16550_RBR 0 -#define NS16550_THR 0 -#define NS16550_DLL 0 -#define NS16550_IER 1 -#define NS16550_DLM 1 -#define NS16550_FCR 2 -#define NS16550_IIR 2 -#define NS16550_LCR 3 -#define NS16550_MCR 4 -#define NS16550_LSR 5 -#define NS16550_MSR 6 -#define NS16550_SCR 7 - -#define NS16550_LSR_DR 0x01 /* Data ready */ -#define NS16550_LSR_OE 0x02 /* Overrun */ -#define NS16550_LSR_PE 0x04 /* Parity error */ -#define NS16550_LSR_FE 0x08 /* Framing error */ -#define NS16550_LSR_BI 0x10 /* Break */ -#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */ -#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */ -#define NS16550_LSR_ERR 0x80 /* Error */ - - -void _serinit(void) -{ -#if USE_NILE4_SERIAL - ns16550_out(NS16550_LCR, 0x80); - ns16550_out(NS16550_DLM, 0x00); - ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */ - ns16550_out(NS16550_LCR, 0x00); - ns16550_out(NS16550_LCR, 0x03); - ns16550_out(NS16550_FCR, 0x47); -#else - /* done by PMON */ -#endif -} - -void _putc(char c) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, c); - if (c == '\n') { - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); - ns16550_out(NS16550_THR, '\r'); - } -} - -void _puts(const char *s) -{ - char c; - - while ((c = *s++)) - _putc(c); -} - -char _getc(void) -{ - while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR)); - - return ns16550_in(NS16550_RBR); -} - -int _testc(void) -{ - return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0; -} - - -/* - * Hexadecimal 7-segment LED - */ -void ddb5476_led_hex(int hex) -{ - outb(hex, 0x80); -} - - -/* - * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543 - */ -struct pci_dev *pci_pmu = NULL; - -void ddb5476_led_d2(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0x7f; - else - t |= 0x80; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} - -void ddb5476_led_d3(int on) -{ - u8 t; - - if (pci_pmu) { - pci_read_config_byte(pci_pmu, 0x7e, &t); - if (on) - t &= 0xbf; - else - t |= 0x40; - pci_write_config_byte(pci_pmu, 0x7e, t); - } -} diff -Nru a/arch/mips/ddb5476/time.c b/arch/mips/ddb5476/time.c --- a/arch/mips/ddb5476/time.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,32 +0,0 @@ -/* - * arch/mips/ddb5074/time.c -- Timer routines - * - * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> - * Sony Software Development Center Europe (SDCE), Brussels - */ -#include <linux/init.h> - -#include <asm/mc146818rtc.h> - -static unsigned char ddb_rtc_read_data(unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - return inb_p(RTC_PORT(1)); -} - -static void ddb_rtc_write_data(unsigned char data, unsigned long addr) -{ - outb_p(addr, RTC_PORT(0)); - outb_p(data, RTC_PORT(1)); -} - -static int ddb_rtc_bcd_mode(void) -{ - return 1; -} - -struct rtc_ops ddb_rtc_ops = { - ddb_rtc_read_data, - ddb_rtc_write_data, - ddb_rtc_bcd_mode -}; diff -Nru a/arch/mips/ddb5xxx/common/Makefile b/arch/mips/ddb5xxx/common/Makefile --- a/arch/mips/ddb5xxx/common/Makefile Fri Jun 27 14:20:04 2003 +++ b/arch/mips/ddb5xxx/common/Makefile Fri Jun 27 14:20:04 2003 @@ -2,4 +2,4 @@ # Makefile for the common code of NEC DDB-Vrc5xxx board # -obj-y += irq.o irq_cpu.o nile4.o prom.o pci.o pci_auto.o rtc_ds1386.o +obj-y += irq.o nile4.o prom.o rtc_ds1386.o diff -Nru a/arch/mips/ddb5xxx/common/irq.c b/arch/mips/ddb5xxx/common/irq.c --- a/arch/mips/ddb5xxx/common/irq.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/ddb5xxx/common/irq.c Fri Jun 27 14:19:59 2003 @@ -13,12 +13,13 @@ */ #include <linux/config.h> #include <linux/init.h> +#include <asm/irq.h> void (*irq_setup)(void); void __init init_IRQ(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern void set_debug_traps(void); @@ -26,6 +27,8 @@ set_debug_traps(); breakpoint(); #endif + /* set up default irq controller */ + init_generic_irq(); /* invoke board-specific irq setup */ irq_setup(); diff -Nru a/arch/mips/ddb5xxx/common/irq_cpu.c b/arch/mips/ddb5xxx/common/irq_cpu.c --- a/arch/mips/ddb5xxx/common/irq_cpu.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,115 +0,0 @@ -/*********************************************************************** - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/ddb5xxx/common/irq_cpu.c - * This file define the irq handler for MIPS CPU interrupts. - * - * 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. - *********************************************************************** - */ - -/* - * Almost all MIPS CPUs define 8 interrupt sources. They are typically - * level triggered (i.e., cannot be cleared from CPU; must be cleared from - * device). The first two are software interrupts. The last one is - * usually cpu timer interrupt if coutner register is present. - * - * This file exports one global function: - * mips_cpu_irq_init(u32 irq_base); - */ - -#include <linux/irq.h> -#include <linux/types.h> -#include <linux/kernel.h> - -#include <asm/mipsregs.h> - -/* [jsun] sooner or later we should move this debug stuff to MIPS common */ -#include <asm/ddb5xxx/debug.h> - -static int mips_cpu_irq_base=-1; - -static void -mips_cpu_irq_enable(unsigned int irq) -{ - MIPS_ASSERT(mips_cpu_irq_base != -1); - MIPS_ASSERT(irq >= mips_cpu_irq_base); - MIPS_ASSERT(irq < mips_cpu_irq_base+8); - - clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8)); - set_cp0_status(1 << (irq - mips_cpu_irq_base + 8)); -} - -static void -mips_cpu_irq_disable(unsigned int irq) -{ - MIPS_ASSERT(mips_cpu_irq_base != -1); - MIPS_ASSERT(irq >= mips_cpu_irq_base); - MIPS_ASSERT(irq < mips_cpu_irq_base+8); - - clear_cp0_status(1 << (irq - mips_cpu_irq_base + 8)); -} - -static unsigned int mips_cpu_irq_startup(unsigned int irq) -{ - mips_cpu_irq_enable(irq); - return 0; -} - -#define mips_cpu_irq_shutdown mips_cpu_irq_disable - -static void -mips_cpu_irq_ack(unsigned int irq) -{ - MIPS_ASSERT(mips_cpu_irq_base != -1); - MIPS_ASSERT(irq >= mips_cpu_irq_base); - MIPS_ASSERT(irq < mips_cpu_irq_base+8); - - /* although we attemp to clear the IP bit in cause reigster, I think - * usually it is cleared by device (irq source) - */ - clear_cp0_cause( 1 << (irq - mips_cpu_irq_base + 8)); - - /* I am not fully convinced that I should disable irq here */ -} - -static void -mips_cpu_irq_end(unsigned int irq) -{ - MIPS_ASSERT(mips_cpu_irq_base != -1); - MIPS_ASSERT(irq >= mips_cpu_irq_base); - MIPS_ASSERT(irq < mips_cpu_irq_base+8); - /* I am not fully convinced that I should enable irq here */ -} - -static hw_irq_controller mips_cpu_irq_controller = { - "CPU_irq", - mips_cpu_irq_startup, - mips_cpu_irq_shutdown, - mips_cpu_irq_enable, - mips_cpu_irq_disable, - mips_cpu_irq_ack, - mips_cpu_irq_end, - NULL /* no affinity stuff for UP */ -}; - - -void -mips_cpu_irq_init(u32 irq_base) -{ - extern irq_desc_t irq_desc[]; - u32 i; - - for (i= irq_base; i< irq_base+8; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].handler = &mips_cpu_irq_controller; - } - - mips_cpu_irq_base = irq_base; -} diff -Nru a/arch/mips/ddb5xxx/common/nile4.c b/arch/mips/ddb5xxx/common/nile4.c --- a/arch/mips/ddb5xxx/common/nile4.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/ddb5xxx/common/nile4.c Fri Jun 27 14:19:59 2003 @@ -1,4 +1,4 @@ -/*********************************************************************** +/* * * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net @@ -12,19 +12,14 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. - * - *********************************************************************** */ - -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <asm/ddb5xxx/ddb5xxx.h> -#include <asm/ddb5xxx/debug.h> u32 -ddb_calc_pdar(u32 phys, u32 size, int width, +ddb_calc_pdar(u32 phys, u32 size, int width, int on_memory_bus, int pci_visible) { u32 maskbits; @@ -73,7 +68,7 @@ maskbits = 0; break; default: - panic("nile4_set_pdar: unsupported size %p\n", (void *) size); + panic("nile4_set_pdar: unsupported size %p", (void *) size); } switch (width) { case 8: @@ -89,7 +84,7 @@ widthbits = 3; break; default: - panic("nile4_set_pdar: unsupported width %d\n", width); + panic("nile4_set_pdar: unsupported width %d", width); } return maskbits | (on_memory_bus ? 0x10 : 0) | @@ -128,7 +123,7 @@ case DDB_PCICMD_CFG: /* PCI Configuration Space */ break; default: - panic("nile4_set_pmr: invalid type %d\n", type); + panic("nile4_set_pmr: invalid type %d", type); } ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options ); ddb_out32(pmr + 4, 0); diff -Nru a/arch/mips/ddb5xxx/common/pci.c b/arch/mips/ddb5xxx/common/pci.c --- a/arch/mips/ddb5xxx/common/pci.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,172 +0,0 @@ -/*********************************************************************** - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/ddb5xxx/common/pci.c - * Common PCI routines for DDB5xxx - as a matter of fact, meant for all - * MIPS machines. - * - * 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 contains common PCI routines meant to be shared for - * all MIPS machines. - * - * Strategies: - * - * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) - * TODO: this should be optional for some machines where they do have - * a real "pcibios" that does resource assignment. - * - * . We then use pci_scan_bus() to "discover" all the resources for - * later use by Linux. - * - * . We finally reply on a board supplied function, pcibios_fixup_irq(), to - * to assign the interrupts. We may use setup-irq.c under drivers/pci - * later. - * - * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), - * because we assume all PCI devices should have the resources correctly - * assigned and recorded. - * - * Limitations: - * - * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus - * into a contiguous range. - * - * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical - * address space. - * - * . In the case of IO space, it starts from 0, and the beginning address - * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. - * - * . These are the current MIPS limitations (by ioremap, etc). In the - * future, we may remove them. - * - * Credits: - * Most of the code are derived from the pci routines from PPC and Alpha, - * which were mostly writtne by - * Cort Dougan, cort@fsmlabs.com - * Matt Porter, mporter@mvista.com - * Dave Rusling david.rusling@reo.mts.dec.com - * David Mosberger davidm@cs.arizona.edu - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/pci.h> - -#include <asm/ddb5xxx/pci.h> -#include <asm/ddb5xxx/debug.h> - - -struct pci_fixup pcibios_fixups[] = { {0} }; - - -extern int pciauto_assign_resources(int busno, struct pci_channel * hose); -void __init pcibios_init(void) -{ - struct pci_channel *p; - struct pci_bus *bus; - int busno; - - /* assign resources */ - busno=0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - busno = pciauto_assign_resources(busno, p) + 1; - } - - /* scan the buses */ - busno = 0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate+1; - } - - /* fixup irqs (board specific routines) */ - pcibios_fixup_irqs(); - - /* - * should we do a fixup of ioport_resource and iomem_resource - * based on mips_pci_channels? - * Let us wait and see if this is a common need and whether there - * are exceptions. Until then, each board should adjust them - * perhaps in their setup() function. - */ -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - /* pciauto_assign_resources() will enable all devices found */ - return 0; -} - -unsigned long __init -pci_bridge_check_io(struct pci_dev *bridge) -{ - u16 io; - - pci_read_config_word(bridge, PCI_IO_BASE, &io); - if (!io) { - pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); - pci_read_config_word(bridge, PCI_IO_BASE, &io); - pci_write_config_word(bridge, PCI_IO_BASE, 0x0); - } - if (io) - return IORESOURCE_IO; - printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", - bridge->name); - return 0; -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Propogate hose info into the subordinate devices. */ - - struct pci_channel *hose = bus->sysdata; - struct pci_dev *dev = bus->self; - - if (!dev) { - /* Root bus */ - bus->resource[0] = hose->io_resource; - bus->resource[1] = hose->mem_resource; - } else { - /* This is a bridge. Do not care how it's initialized, - just link its resources to the bus ones */ - int i; - - for(i=0; i<3; i++) { - bus->resource[i] = - &dev->resource[PCI_BRIDGE_RESOURCES+i]; - bus->resource[i]->name = bus->name; - } - bus->resource[0]->flags |= pci_bridge_check_io(dev); - bus->resource[1]->flags |= IORESOURCE_MEM; - /* For now, propagate hose limits to the bus; - we'll adjust them later. */ - bus->resource[0]->end = hose->io_resource->end; - bus->resource[1]->end = hose->mem_resource->end; - /* Turn off downstream PF memory address range by default */ - bus->resource[2]->start = 1024*1024; - bus->resource[2]->end = bus->resource[2]->start - 1; - } -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void -pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - /* this should not be called */ - MIPS_ASSERT(1 == 0); -} diff -Nru a/arch/mips/ddb5xxx/common/pci_auto.c b/arch/mips/ddb5xxx/common/pci_auto.c --- a/arch/mips/ddb5xxx/common/pci_auto.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,396 +0,0 @@ -/* - * arch/ppc/kernel/pci_auto.c - * - * PCI autoconfiguration library - * - * Author: Matt Porter <mporter@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. - */ - -/* - * Modified for MIPS by Jun Sun, jsun@mvista.com - * - * . Simplify the interface between pci_auto and the rest: a single function. - * . Assign resources from low address to upper address. - * . change most int to u32. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/pci.h> - -#include <asm/ddb5xxx/pci.h> -#include <asm/ddb5xxx/debug.h> - -#define DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* These are used for config access before all the PCI probing - has been done. */ -int early_read_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 *val); -int early_read_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 *val); -int early_read_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 *val); -int early_write_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 val); -int early_write_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 val); -int early_write_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 val); - -static u32 pciauto_lower_iospc; -static u32 pciauto_upper_iospc; - -static u32 pciauto_lower_memspc; -static u32 pciauto_upper_memspc; - -void __init -pciauto_setup_bars(struct pci_channel *hose, - int current_bus, - int pci_devfn) -{ - u32 bar_response, bar_size, bar_value; - u32 bar, addr_mask, bar_nr = 0; - u32 * upper_limit; - u32 * lower_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; - lower_limit = &pciauto_lower_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; - lower_limit = &pciauto_lower_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 = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; - MIPS_ASSERT(bar_value + bar_size <= *upper_limit); - - /* Write it out and update our limit */ - early_write_config_dword(hose, - current_bus, - pci_devfn, - bar, - bar_value); - - *lower_limit = bar_value + bar_size; - - /* - * 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 __init -pciauto_prescan_setup_bridge(struct pci_channel *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 __init -pciauto_postscan_setup_bridge(struct pci_channel *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); -} - -#define PCIAUTO_IDE_MODE_MASK 0x05 - -int __init -pciauto_bus_scan(struct pci_channel *hose, int current_bus) -{ - int sub_bus; - u32 pci_devfn, pci_class, cmdstat, found_multi=0; - unsigned short vid; - unsigned char header_type; - - sub_bus = current_bus; - - for (pci_devfn=0; pci_devfn<0xff; pci_devfn++) { - - 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) continue; - - 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; -} - -int __init -pciauto_assign_resources(int busno, struct pci_channel *hose) -{ - /* setup resource limits */ - pciauto_lower_iospc = hose->io_resource->start; - pciauto_upper_iospc = hose->io_resource->end + 1; - pciauto_lower_memspc = hose->mem_resource->start; - pciauto_upper_memspc = hose->mem_resource->end + 1; - - return pciauto_bus_scan(hose, busno); -} - - -/* - * These functions are used early on before PCI scanning is done - * and all of the pci_dev and pci_bus structures have been created. - */ -static struct pci_dev * -fake_pci_dev(struct pci_channel *hose, int busnr, int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.bus = &bus; - dev.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -int early_##rw##_config_##size(struct pci_channel *hose, int bus, \ - int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, word, u16 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, word, u16) -EARLY_PCI_OP(write, dword, u32) diff -Nru a/arch/mips/ddb5xxx/common/prom.c b/arch/mips/ddb5xxx/common/prom.c --- a/arch/mips/ddb5xxx/common/prom.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/ddb5xxx/common/prom.c Fri Jun 27 14:20:01 2003 @@ -22,8 +22,21 @@ #include <asm/addrspace.h> #include <asm/bootinfo.h> #include <asm/ddb5xxx/ddb5xxx.h> +#include <asm/debug.h> -char arcs_cmdline[COMMAND_LINE_SIZE]; +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + switch (mips_machtype) { + case MACH_NEC_DDB5074: return "NEC DDB Vrc-5074"; + case MACH_NEC_DDB5476: return "NEC DDB Vrc-5476"; + case MACH_NEC_DDB5477: return "NEC DDB Vrc-5477"; + case MACH_NEC_ROCKHOPPER: return "NEC Rockhopper"; + case MACH_NEC_ROCKHOPPERII: return "NEC RockhopperII"; + default: return "Unknown NEC board"; + } +} /* [jsun@junsun.net] PMON passes arguments in C main() style */ void __init prom_init(int argc, const char **arg) @@ -40,19 +53,91 @@ strcat(arcs_cmdline, " "); } + /* by default all these boards use dhcp/nfs root fs */ + strcat(arcs_cmdline, "ip=bootp"); + mips_machgroup = MACH_GROUP_NEC_DDB; #if defined(CONFIG_DDB5074) mips_machtype = MACH_NEC_DDB5074; + add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM); #elif defined(CONFIG_DDB5476) mips_machtype = MACH_NEC_DDB5476; + add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM); #elif defined(CONFIG_DDB5477) - mips_machtype = MACH_NEC_DDB5477; + ddb5477_runtime_detection(); + add_memory_region(0, board_ram_size, BOOT_MEM_RAM); #endif - - add_memory_region(0, DDB_SDRAM_SIZE, BOOT_MEM_RAM); } void __init prom_free_prom_memory(void) { } + +#if defined(CONFIG_DDB5477) + +#define DEFAULT_LCS1_BASE 0x19000000 +#define TESTVAL1 'K' +#define TESTVAL2 'S' + +int board_ram_size; +void ddb5477_runtime_detection(void) +{ + volatile char *test_offset; + char saved_test_byte; + + /* Determine if this is a DDB5477 board, or a BSB-VR0300 + base board. We can tell by checking for the location of + the NVRAM. It lives at the beginning of LCS1 on the DDB5477, + and the beginning of LCS1 on the BSB-VR0300 is flash memory. + The first 2K of the NVRAM are reserved, so don't we'll poke + around just after that. + */ + + /* We can only use the PCI bus to distinquish between + the Rockhopper and RockhopperII backplanes and this must + wait until ddb5477_board_init() in setup.c after the 5477 + is initialized. So, until then handle + both Rockhopper and RockhopperII backplanes as Rockhopper 1 + */ + + test_offset = (char *)KSEG1ADDR(DEFAULT_LCS1_BASE + 0x800); + saved_test_byte = *test_offset; + + *test_offset = TESTVAL1; + if (*test_offset != TESTVAL1) { + /* We couldn't set our test value, so it must not be NVRAM, + so it's a BSB_VR0300 */ + mips_machtype = MACH_NEC_ROCKHOPPER; + } else { + /* We may have gotten lucky, and the TESTVAL1 was already + stored at the test location, so we must check a second + test value */ + *test_offset = TESTVAL2; + if (*test_offset != TESTVAL2) { + /* OK, we couldn't set this value either, so it must + definately be a BSB_VR0300 */ + mips_machtype = MACH_NEC_ROCKHOPPER; + } else { + /* We could change the value twice, so it must be + NVRAM, so it's a DDB_VRC5477 */ + mips_machtype = MACH_NEC_DDB5477; + } + } + /* Restore the original byte */ + *test_offset = saved_test_byte; + + /* before we know a better way, we will trust PMON for getting + * RAM size + */ + board_ram_size = 1 << (36 - (ddb_in32(DDB_SDRAM0) & 0xf)); + + db_run(printk("DDB run-time detection : %s, %d MB RAM\n", + mips_machtype == MACH_NEC_DDB5477 ? + "DDB5477" : "Rockhopper", + board_ram_size >> 20)); + + /* we can't handle ram size > 128 MB */ + db_assert(board_ram_size <= (128 << 20)); +} +#endif diff -Nru a/arch/mips/ddb5xxx/common/rtc_ds1386.c b/arch/mips/ddb5xxx/common/rtc_ds1386.c --- a/arch/mips/ddb5xxx/common/rtc_ds1386.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/ddb5xxx/common/rtc_ds1386.c Fri Jun 27 14:20:00 2003 @@ -25,7 +25,8 @@ #include <asm/time.h> #include <asm/addrspace.h> -#include <asm/ddb5xxx/debug.h> +#include <asm/mc146818rtc.h> +#include <asm/debug.h> #define EPOCH 2000 @@ -36,7 +37,7 @@ static unsigned long rtc_ds1386_get_time(void) -{ +{ u8 byte; u8 temp; unsigned int year, month, day, hour, minute, second; @@ -73,7 +74,7 @@ return mktime(year, month, day, hour, minute, second); } -static int +static int rtc_ds1386_set_time(unsigned long t) { struct rtc_time tm; @@ -89,6 +90,7 @@ /* convert */ to_tm(t, &tm); + /* check each field one by one */ year = BIN2BCD(tm.tm_year - EPOCH); if (year != READ_RTC(0xA)) { @@ -96,7 +98,7 @@ } temp = READ_RTC(0x9); - month = BIN2BCD(tm.tm_mon); + month = BIN2BCD(tm.tm_mon+1); /* tm_mon starts from 0 to 11 */ if (month != (temp & 0x1f)) { WRITE_RTC( 0x9, (month & 0x1f) | (temp & ~0x1f) ); @@ -131,7 +133,7 @@ if (second != READ_RTC(0x1)) { WRITE_RTC(0x1, second); } - + return 0; } @@ -139,10 +141,10 @@ rtc_ds1386_init(unsigned long base) { unsigned char byte; - + /* remember the base */ rtc_base = base; - MIPS_ASSERT((rtc_base & 0xe0000000) == KSEG1); + db_assert((rtc_base & 0xe0000000) == KSEG1); /* turn on RTC if it is not on */ byte = READ_RTC(0x9); diff -Nru a/arch/mips/ddb5xxx/ddb5074/Makefile b/arch/mips/ddb5xxx/ddb5074/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5074/Makefile Fri Jun 27 14:19:53 2003 @@ -0,0 +1,8 @@ +# +# Makefile for the NEC DDB Vrc-5074 specific kernel interface routines +# under Linux. +# + +obj-y += setup.o irq.o int-handler.o nile4_pic.o time.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5074/int-handler.S Fri Jun 27 14:20:00 2003 @@ -0,0 +1,120 @@ +/* + * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler + * + * Based on arch/mips/sgi/kernel/indyIRQ.S + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* A lot of complication here is taken away because: + * + * 1) We handle one interrupt and return, sitting in a loop and moving across + * all the pending IRQ bits in the cause register is _NOT_ the answer, the + * common case is one pending IRQ so optimize in that direction. + * + * 2) We need not check against bits in the status register IRQ mask, that + * would make this routine slow as hell. + * + * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in + * between like BSD spl() brain-damage. + * + * Furthermore, the IRQs on the INDY look basically (barring software IRQs + * which we don't use at all) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Local IRQ level zero + * 3 Local IRQ level one + * 4 8254 Timer zero + * 5 8254 Timer one + * 6 Bus Error + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Local IRQ zero + * Local IRQ one + * Bus Error + * 8254 Timer zero + * Lowest ---- 8254 Timer one + * + * then we just return, if multiple IRQs are pending then we will just take + * another exception, big deal. + */ + + .text + .set noreorder + .set noat + .align 5 + NESTED(ddbIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 s0, CP0_CAUSE # get irq mask + +#if 1 + mfc0 t2,CP0_STATUS # get enabled interrupts + and s0,t2 # isolate allowed ones +#endif + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP3 # delay slot, check local level one + + /* Wheee, local level zero interrupt. */ + jal ddb_local0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP6 # delay slot, check bus error + + /* Wheee, local level one interrupt. */ + move a0, sp + jal ddb_local1_irqdispatch + nop + + j ret_from_irq + nop + +1: + beq a0, zero, 1f + nop + + /* Wheee, an asynchronous bus error... */ + move a0, sp + jal ddb_buserror_irq + nop + + j ret_from_irq + nop + +1: + /* Here by mistake? This is possible, what can happen + * is that by the time we take the exception the IRQ + * pin goes low, so just leave if this is the case. + */ + andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) + beq a0, zero, 1f + + /* Must be one of the 8254 timers... */ + move a0, sp + jal ddb_8254timer_irq + nop +1: + j ret_from_irq + nop + END(ddbIRQ) diff -Nru a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5074/irq.c Fri Jun 27 14:20:05 2003 @@ -0,0 +1,168 @@ +/* + * arch/mips/ddb5074/irq.c -- NEC DDB Vrc-5074 interrupt routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/i8259.h> +#include <asm/io.h> +#include <asm/irq_cpu.h> +#include <asm/ptrace.h> +#include <asm/nile4.h> +#include <asm/ddb5xxx/ddb5xxx.h> +#include <asm/ddb5xxx/ddb5074.h> + + +extern asmlinkage void ddbIRQ(void); + +static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; + +#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ +#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ +#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ + +#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ +#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ +#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ + +#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ +#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ + +#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ +#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ + +#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ +#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ + + +static void m1543_irq_setup(void) +{ + /* + * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all + * the possible IO sources in the M1543 are in use by us. We will + * use the following mapping: + * + * IRQ1 - keyboard (default set by M1543) + * IRQ3 - reserved for UART B (default set by M1543) (note that + * the schematics for the DDB Vrc-5074 board seem to + * indicate that IRQ3 is connected to the DS1386 + * watchdog timer interrupt output so we might have + * a conflict) + * IRQ4 - reserved for UART A (default set by M1543) + * IRQ5 - parallel (default set by M1543) + * IRQ8 - DS1386 time of day (RTC) interrupt + * IRQ12 - mouse + */ + + /* + * Assing mouse interrupt to IRQ12 + */ + + /* Enter configuration mode */ + outb(0x51, M1543_PNP_CONFIG); + outb(0x23, M1543_PNP_CONFIG); + + /* Select logical device 7 (Keyboard) */ + outb(0x07, M1543_PNP_INDEX); + outb(0x07, M1543_PNP_DATA); + + /* Select IRQ12 */ + outb(0x72, M1543_PNP_INDEX); + outb(0x0c, M1543_PNP_DATA); + + outb(0x30, M1543_PNP_INDEX); + printk("device 7, 0x30: %02x\n",inb(M1543_PNP_DATA)); + + outb(0x70, M1543_PNP_INDEX); + printk("device 7, 0x70: %02x\n",inb(M1543_PNP_DATA)); + + /* Leave configration mode */ + outb(0xbb, M1543_PNP_CONFIG); + + +} + +void ddb_local0_irqdispatch(struct pt_regs *regs) +{ + u32 mask; + int nile4_irq; + + mask = nile4_get_irq_stat(0); + + /* Handle the timer interrupt first */ +#if 0 + if (mask & (1 << NILE4_INT_GPT)) { + do_IRQ(nile4_to_irq(NILE4_INT_GPT), regs); + mask &= ~(1 << NILE4_INT_GPT); + } +#endif + for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) + if (mask & 1) { + if (nile4_irq == NILE4_INT_INTE) { + int i8259_irq; + + nile4_clear_irq(NILE4_INT_INTE); + i8259_irq = nile4_i8259_iack(); + do_IRQ(i8259_irq, regs); + } else + do_IRQ(nile4_to_irq(nile4_irq), regs); + + } +} + +void ddb_local1_irqdispatch(void) +{ + printk("ddb_local1_irqdispatch called\n"); +} + +void ddb_buserror_irq(void) +{ + printk("ddb_buserror_irq called\n"); +} + +void ddb_8254timer_irq(void) +{ + printk("ddb_8254timer_irq called\n"); +} + +void __init ddb_irq_setup(void) +{ +#ifdef CONFIG_KGDB + if (remote_debug) + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif + + /* setup cascade interrupts */ + setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); + setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); + + set_except_vector(0, ddbIRQ); + + nile4_irq_setup(NILE4_IRQ_BASE); + m1543_irq_setup(); + init_i8259_irqs(); + + + printk("CPU_IRQ_BASE: %d\n",CPU_IRQ_BASE); + + mips_cpu_irq_init(CPU_IRQ_BASE); + + printk("enabling 8259 cascade\n"); + + ddb5074_led_hex(0); + + /* Enable the interrupt cascade */ + nile4_enable_irq(NILE4_IRQ_BASE+IRQ_I8259_CASCADE); + + +} diff -Nru a/arch/mips/ddb5xxx/ddb5074/nile4_pic.c b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5074/nile4_pic.c Fri Jun 27 14:19:55 2003 @@ -0,0 +1,288 @@ +/* + * arch/mips/ddb5476/nile4.c -- + * low-level PIC code for NEC Vrc-5476 (Nile 4) + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + */ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> + +#include <asm/addrspace.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +static int irq_base; + +/* + * Interrupt Programming + */ +void nile4_map_irq(int nile4_irq, int cpu_irq) +{ + u32 offset, t; + + offset = DDB_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = ddb_in32(offset); + t &= ~(7 << (nile4_irq * 4)); + t |= cpu_irq << (nile4_irq * 4); + ddb_out32(offset, t); +} + +void nile4_map_irq_all(int cpu_irq) +{ + u32 all, t; + + all = cpu_irq; + all |= all << 4; + all |= all << 8; + all |= all << 16; + t = ddb_in32(DDB_INTCTRL); + t &= 0x88888888; + t |= all; + ddb_out32(DDB_INTCTRL, t); + t = ddb_in32(DDB_INTCTRL + 4); + t &= 0x88888888; + t |= all; + ddb_out32(DDB_INTCTRL + 4, t); +} + +void nile4_enable_irq(unsigned int nile4_irq) +{ + u32 offset, t; + + nile4_irq-=irq_base; + + ddb5074_led_hex(8); + + offset = DDB_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + ddb5074_led_hex(9); + t = ddb_in32(offset); + ddb5074_led_hex(0xa); + t |= 8 << (nile4_irq * 4); + ddb_out32(offset, t); + ddb5074_led_hex(0xb); +} + +void nile4_disable_irq(unsigned int nile4_irq) +{ + u32 offset, t; + + nile4_irq-=irq_base; + + offset = DDB_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = ddb_in32(offset); + t &= ~(8 << (nile4_irq * 4)); + ddb_out32(offset, t); +} + +void nile4_disable_irq_all(void) +{ + ddb_out32(DDB_INTCTRL, 0); + ddb_out32(DDB_INTCTRL + 4, 0); +} + +u16 nile4_get_irq_stat(int cpu_irq) +{ + return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2); +} + +void nile4_enable_irq_output(int cpu_irq) +{ + u32 t; + + t = ddb_in32(DDB_INTSTAT1 + 4); + t |= 1 << (16 + cpu_irq); + ddb_out32(DDB_INTSTAT1, t); +} + +void nile4_disable_irq_output(int cpu_irq) +{ + u32 t; + + t = ddb_in32(DDB_INTSTAT1 + 4); + t &= ~(1 << (16 + cpu_irq)); + ddb_out32(DDB_INTSTAT1, t); +} + +void nile4_set_pci_irq_polarity(int pci_irq, int high) +{ + u32 t; + + t = ddb_in32(DDB_INTPPES); + if (high) + t &= ~(1 << (pci_irq * 2)); + else + t |= 1 << (pci_irq * 2); + ddb_out32(DDB_INTPPES, t); +} + +void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) +{ + u32 t; + + t = ddb_in32(DDB_INTPPES); + if (level) + t |= 2 << (pci_irq * 2); + else + t &= ~(2 << (pci_irq * 2)); + ddb_out32(DDB_INTPPES, t); +} + +void nile4_clear_irq(int nile4_irq) +{ + nile4_irq-=irq_base; + ddb_out32(DDB_INTCLR, 1 << nile4_irq); +} + +void nile4_clear_irq_mask(u32 mask) +{ + ddb_out32(DDB_INTCLR, mask); +} + +u8 nile4_i8259_iack(void) +{ + u8 irq; + u32 reg; + + /* Set window 0 for interrupt acknowledge */ + reg = ddb_in32(DDB_PCIINIT0); + + ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32); + irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE); + /* restore window 0 for PCI I/O space */ + // ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32); + ddb_out32(DDB_PCIINIT0, reg); + + /* i8269.c set the base vector to be 0x0 */ + return irq ; +} + +static unsigned int nile4_irq_startup(unsigned int irq) { + + nile4_enable_irq(irq); + return 0; + +} + +static void nile4_ack_irq(unsigned int irq) { + + ddb5074_led_hex(4); + + nile4_clear_irq(irq); + ddb5074_led_hex(2); + nile4_disable_irq(irq); + + ddb5074_led_hex(0); +} + +static void nile4_irq_end(unsigned int irq) { + + ddb5074_led_hex(3); + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + ddb5074_led_hex(5); + nile4_enable_irq(irq); + ddb5074_led_hex(7); + } + + ddb5074_led_hex(1); +} + +#define nile4_irq_shutdown nile4_disable_irq + +static hw_irq_controller nile4_irq_controller = { + "nile4", + nile4_irq_startup, + nile4_irq_shutdown, + nile4_enable_irq, + nile4_disable_irq, + nile4_ack_irq, + nile4_irq_end, + NULL +}; + +void nile4_irq_setup(u32 base) { + + int i; + extern irq_desc_t irq_desc[]; + + irq_base=base; + + /* Map all interrupts to CPU int #0 */ + nile4_map_irq_all(0); + + /* PCI INTA#-E# must be level triggered */ + nile4_set_pci_irq_level_or_edge(0, 1); + nile4_set_pci_irq_level_or_edge(1, 1); + nile4_set_pci_irq_level_or_edge(2, 1); + nile4_set_pci_irq_level_or_edge(3, 1); + nile4_set_pci_irq_level_or_edge(4, 1); + + /* PCI INTA#-D# must be active low, INTE# must be active high */ + nile4_set_pci_irq_polarity(0, 0); + nile4_set_pci_irq_polarity(1, 0); + nile4_set_pci_irq_polarity(2, 0); + nile4_set_pci_irq_polarity(3, 0); + nile4_set_pci_irq_polarity(4, 1); + + + for (i = 0; i < 16; i++) { + nile4_clear_irq(i); + nile4_disable_irq(i); + } + + /* Enable CPU int #0 */ + nile4_enable_irq_output(0); + + for (i= base; i< base + NUM_NILE4_INTERRUPTS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &nile4_irq_controller; + } + +} + +#if defined(CONFIG_RUNTIME_DEBUG) +void nile4_dump_irq_status(void) +{ + printk(KERN_DEBUG " + CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4), + (void *) ddb_in32(DDB_CPUSTAT)); + printk(KERN_DEBUG " + INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4), + (void *) ddb_in32(DDB_INTCTRL)); + printk(KERN_DEBUG + "INTSTAT0 = %p:%p\n", + (void *) ddb_in32(DDB_INTSTAT0 + 4), + (void *) ddb_in32(DDB_INTSTAT0)); + printk(KERN_DEBUG + "INTSTAT1 = %p:%p\n", + (void *) ddb_in32(DDB_INTSTAT1 + 4), + (void *) ddb_in32(DDB_INTSTAT1)); + printk(KERN_DEBUG + "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4), + (void *) ddb_in32(DDB_INTCLR)); + printk(KERN_DEBUG + "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4), + (void *) ddb_in32(DDB_INTPPES)); +} + +#endif diff -Nru a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5074/setup.c Fri Jun 27 14:20:00 2003 @@ -0,0 +1,265 @@ +/* + * arch/mips/ddb5074/setup.c -- NEC DDB Vrc-5074 setup routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kbd_ll.h> +#include <linux/kernel.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/sched.h> +#include <linux/mc146818rtc.h> +#include <linux/pci.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/irq.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/gdb-stub.h> +#include <asm/time.h> +#include <asm/nile4.h> +#include <asm/ddb5xxx/ddb5074.h> +#include <asm/ddb5xxx/ddb5xxx.h> + + +#ifdef CONFIG_KGDB +extern void rs_kgdb_hook(int); +extern void breakpoint(void); +#endif + +#if defined(CONFIG_SERIAL_CONSOLE) +extern void console_setup(char *); +#endif + +extern struct ide_ops std_ide_ops; +extern struct kbd_ops std_kbd_ops; +extern struct rtc_ops ddb_rtc_ops; + +static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; + +static void ddb_machine_restart(char *command) +{ + u32 t; + + /* PCI cold reset */ + t = nile4_in32(NILE4_PCICTRL + 4); + t |= 0x40000000; + nile4_out32(NILE4_PCICTRL + 4, t); + /* CPU cold reset */ + t = nile4_in32(NILE4_CPUSTAT); + t |= 1; + nile4_out32(NILE4_CPUSTAT, t); + /* Call the PROM */ + back_to_prom(); +} + +static void ddb_machine_halt(void) +{ + printk("DDB Vrc-5074 halted.\n"); + do { + } while (1); +} + +static void ddb_machine_power_off(void) +{ + printk("DDB Vrc-5074 halted. Please turn off the power.\n"); + do { + } while (1); +} + +extern void ddb_irq_setup(void); +extern void rtc_ds1386_init(unsigned long base); + +extern void (*board_timer_setup) (struct irqaction * irq); + +static void __init ddb_timer_init(struct irqaction *irq) +{ + /* set the clock to 1 Hz */ + nile4_out32(NILE4_T2CTRL, 1000000); + /* enable the General-Purpose Timer */ + nile4_out32(NILE4_T2CTRL + 4, 0x00000001); + /* reset timer */ + nile4_out32(NILE4_T2CNTR, 0); + /* enable interrupt */ + setup_irq(nile4_to_irq(NILE4_INT_GPT), irq); + nile4_enable_irq(nile4_to_irq(NILE4_INT_GPT)); + change_c0_status(ST0_IM, + IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); + +} + +static void __init ddb_time_init(void) +{ + /* we have ds1396 RTC chip */ + rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE)); +} + + + +void __init ddb_setup(void) +{ + extern int panic_timeout; + + irq_setup = ddb_irq_setup; + set_io_port_base(NILE4_PCI_IO_BASE); + isa_slot_offset = NILE4_PCI_MEM_BASE; + board_timer_setup = ddb_timer_init; + board_time_init = ddb_time_init; + + + _machine_restart = ddb_machine_restart; + _machine_halt = ddb_machine_halt; + _machine_power_off = ddb_machine_power_off; + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + rtc_ops = &ddb_rtc_ops; + + ddb_out32(DDB_BAR0, 0); + + ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, 0x10); + ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE , 0x10); + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + /* Reboot on panic */ + panic_timeout = 180; +} + + +#define USE_NILE4_SERIAL 0 + +#if USE_NILE4_SERIAL +#define ns16550_in(reg) nile4_in8((reg)*8) +#define ns16550_out(reg, val) nile4_out8((reg)*8, (val)) +#else +#define NS16550_BASE (NILE4_PCI_IO_BASE+0x03f8) +static inline u8 ns16550_in(u32 reg) +{ + return *(volatile u8 *) (NS16550_BASE + reg); +} + +static inline void ns16550_out(u32 reg, u8 val) +{ + *(volatile u8 *) (NS16550_BASE + reg) = val; +} +#endif + +#define NS16550_RBR 0 +#define NS16550_THR 0 +#define NS16550_DLL 0 +#define NS16550_IER 1 +#define NS16550_DLM 1 +#define NS16550_FCR 2 +#define NS16550_IIR 2 +#define NS16550_LCR 3 +#define NS16550_MCR 4 +#define NS16550_LSR 5 +#define NS16550_MSR 6 +#define NS16550_SCR 7 + +#define NS16550_LSR_DR 0x01 /* Data ready */ +#define NS16550_LSR_OE 0x02 /* Overrun */ +#define NS16550_LSR_PE 0x04 /* Parity error */ +#define NS16550_LSR_FE 0x08 /* Framing error */ +#define NS16550_LSR_BI 0x10 /* Break */ +#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */ +#define NS16550_LSR_TEMT 0x40 /* Xmitter empty */ +#define NS16550_LSR_ERR 0x80 /* Error */ + + +void _serinit(void) +{ +#if USE_NILE4_SERIAL + ns16550_out(NS16550_LCR, 0x80); + ns16550_out(NS16550_DLM, 0x00); + ns16550_out(NS16550_DLL, 0x36); /* 9600 baud */ + ns16550_out(NS16550_LCR, 0x00); + ns16550_out(NS16550_LCR, 0x03); + ns16550_out(NS16550_FCR, 0x47); +#else + /* done by PMON */ +#endif +} + +void _putc(char c) +{ + while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); + ns16550_out(NS16550_THR, c); + if (c == '\n') { + while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_THRE)); + ns16550_out(NS16550_THR, '\r'); + } +} + +void _puts(const char *s) +{ + char c; + while ((c = *s++)) + _putc(c); +} + +char _getc(void) +{ + while (!(ns16550_in(NS16550_LSR) & NS16550_LSR_DR)); + return ns16550_in(NS16550_RBR); +} + +int _testc(void) +{ + return (ns16550_in(NS16550_LSR) & NS16550_LSR_DR) != 0; +} + + +/* + * Hexadecimal 7-segment LED + */ +void ddb5074_led_hex(int hex) +{ + outb(hex, 0x80); +} + + +/* + * LEDs D2 and D3, connected to the GPIO pins of the PMU in the ALi M1543 + */ +struct pci_dev *pci_pmu = NULL; + +void ddb5074_led_d2(int on) +{ + u8 t; + + if (pci_pmu) { + pci_read_config_byte(pci_pmu, 0x7e, &t); + if (on) + t &= 0x7f; + else + t |= 0x80; + pci_write_config_byte(pci_pmu, 0x7e, t); + } +} + +void ddb5074_led_d3(int on) +{ + u8 t; + + if (pci_pmu) { + pci_read_config_byte(pci_pmu, 0x7e, &t); + if (on) + t &= 0xbf; + else + t |= 0x40; + pci_write_config_byte(pci_pmu, 0x7e, t); + } +} diff -Nru a/arch/mips/ddb5xxx/ddb5074/time.c b/arch/mips/ddb5xxx/ddb5074/time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5074/time.c Fri Jun 27 14:19:56 2003 @@ -0,0 +1,33 @@ +/* + * arch/mips/ddb5074/time.c -- Timer routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + * + */ +#include <linux/init.h> +#include <asm/mc146818rtc.h> +#include <asm/ddb5xxx/ddb5074.h> +#include <asm/ddb5xxx/ddb5xxx.h> + + +static unsigned char ddb_rtc_read_data(unsigned long addr) +{ + return *(volatile unsigned char *)(KSEG1ADDR(DDB_PCI_MEM_BASE)+addr); +} + +static void ddb_rtc_write_data(unsigned char data, unsigned long addr) +{ + *(volatile unsigned char *)(KSEG1ADDR(DDB_PCI_MEM_BASE)+addr)=data; +} + +static int ddb_rtc_bcd_mode(void) +{ + return 1; +} + +struct rtc_ops ddb_rtc_ops = { + ddb_rtc_read_data, + ddb_rtc_write_data, + ddb_rtc_bcd_mode +}; diff -Nru a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/Makefile Fri Jun 27 14:19:59 2003 @@ -0,0 +1,9 @@ +# +# Makefile for the NEC DDB Vrc-5476 specific kernel interface routines +# under Linux. +# + +obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o +obj-$(CONFIG_KGDB) += dbg_io.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/ddb5xxx/ddb5476/dbg_io.c b/arch/mips/ddb5xxx/ddb5476/dbg_io.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/dbg_io.c Fri Jun 27 14:19:57 2003 @@ -0,0 +1,136 @@ +/* + * kgdb io functions for DDB5476. We use the second serial port. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +/* ======================= CONFIG ======================== */ + +/* [jsun] we use the second serial port for kdb */ +#define BASE 0xa60002f8 +#define MAX_BAUD 115200 + +/* distance in bytes between two serial registers */ +#define REG_OFFSET 1 + +/* + * 0 - kgdb does serial init + * 1 - kgdb skip serial init + */ +static int remoteDebugInitialized = 0; + +/* + * the default baud rate *if* kgdb does serial init + */ +#define BAUD_DEFAULT UART16550_BAUD_38400 + +/* ======================= END OF CONFIG ======================== */ + +typedef unsigned char uint8; +typedef unsigned int uint32; + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) + +void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + + +uint8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(BAUD_DEFAULT, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); +} + + +int putDebugChar(uint8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(BAUD_DEFAULT, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} diff -Nru a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/int-handler.S Fri Jun 27 14:19:55 2003 @@ -0,0 +1,112 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * First-level interrupt dispatcher for ddb5476 + * + * 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 <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +#include <asm/ddb5xxx/ddb5476.h> + +/* + * first level interrupt dispatcher for ocelot board - + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + NESTED(ddb5476_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + .set noreorder + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cpu_ip7 + andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */ + bnez t1, ll_cpu_ip2 + andi t1, t0, STATUSF_IP3 + bnez t1, ll_cpu_ip3 + andi t1, t0, STATUSF_IP4 + bnez t1, ll_cpu_ip4 + andi t1, t0, STATUSF_IP5 + bnez t1, ll_cpu_ip5 + andi t1, t0, STATUSF_IP6 + bnez t1, ll_cpu_ip6 + andi t1, t0, STATUSF_IP0 /* software int 0 */ + bnez t1, ll_cpu_ip0 + andi t1, t0, STATUSF_IP1 /* software int 1 */ + bnez t1, ll_cpu_ip1 + nop + + .set reorder + + /* wrong alarm or masked ... */ + // j spurious_interrupt + move a0, sp + jal vrc5476_irq_dispatch + j ret_from_irq + nop + + .align 5 + +ll_cpu_ip0: + li a0, CPU_IRQ_BASE + 0 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpu_ip1: + li a0, CPU_IRQ_BASE + 1 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpu_ip2: /* jump to second-level dispatching */ + move a0, sp + jal vrc5476_irq_dispatch + j ret_from_irq + +ll_cpu_ip3: + li a0, CPU_IRQ_BASE + 3 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpu_ip4: + li a0, CPU_IRQ_BASE + 4 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpu_ip5: + li a0, CPU_IRQ_BASE + 5 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpu_ip6: + li a0, CPU_IRQ_BASE + 6 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpu_ip7: + li a0, CPU_IRQ_BASE + 7 + move a1, sp + jal do_IRQ + j ret_from_irq + + END(ddb5476_handle_int) diff -Nru a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/irq.c Fri Jun 27 14:20:00 2003 @@ -0,0 +1,143 @@ +/* + * arch/mips/ddb5476/irq.c -- NEC DDB Vrc-5476 interrupt routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + * + * Re-write the whole thing to use new irq.c file. + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + */ +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> + +#include <asm/i8259.h> +#include <asm/io.h> +#include <asm/ptrace.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ +#define M1543_PNP_INDEX 0x03f0 /* PnP Index Port */ +#define M1543_PNP_DATA 0x03f1 /* PnP Data Port */ + +#define M1543_PNP_ALT_CONFIG 0x0370 /* Alternative PnP Config Port */ +#define M1543_PNP_ALT_INDEX 0x0370 /* Alternative PnP Index Port */ +#define M1543_PNP_ALT_DATA 0x0371 /* Alternative PnP Data Port */ + +#define M1543_INT1_MASTER_CTRL 0x0020 /* INT_1 (master) Control Register */ +#define M1543_INT1_MASTER_MASK 0x0021 /* INT_1 (master) Mask Register */ + +#define M1543_INT1_SLAVE_CTRL 0x00a0 /* INT_1 (slave) Control Register */ +#define M1543_INT1_SLAVE_MASK 0x00a1 /* INT_1 (slave) Mask Register */ + +#define M1543_INT1_MASTER_ELCR 0x04d0 /* INT_1 (master) Edge/Level Control */ +#define M1543_INT1_SLAVE_ELCR 0x04d1 /* INT_1 (slave) Edge/Level Control */ + +static void m1543_irq_setup(void) +{ + /* + * The ALI M1543 has 13 interrupt inputs, IRQ1..IRQ13. Not all + * the possible IO sources in the M1543 are in use by us. We will + * use the following mapping: + * + * IRQ1 - keyboard (default set by M1543) + * IRQ3 - reserved for UART B (default set by M1543) (note that + * the schematics for the DDB Vrc-5476 board seem to + * indicate that IRQ3 is connected to the DS1386 + * watchdog timer interrupt output so we might have + * a conflict) + * IRQ4 - reserved for UART A (default set by M1543) + * IRQ5 - parallel (default set by M1543) + * IRQ8 - DS1386 time of day (RTC) interrupt + * IRQ9 - USB (hardwired in ddb_setup) + * IRQ10 - PMU (hardwired in ddb_setup) + * IRQ12 - mouse + * IRQ14,15 - IDE controller (need to be confirmed, jsun) + */ + + /* + * Assing mouse interrupt to IRQ12 + */ + + /* Enter configuration mode */ + outb(0x51, M1543_PNP_CONFIG); + outb(0x23, M1543_PNP_CONFIG); + + /* Select logical device 7 (Keyboard) */ + outb(0x07, M1543_PNP_INDEX); + outb(0x07, M1543_PNP_DATA); + + /* Select IRQ12 */ + outb(0x72, M1543_PNP_INDEX); + outb(0x0c, M1543_PNP_DATA); + + /* Leave configration mode */ + outb(0xbb, M1543_PNP_CONFIG); +} + +static void nile4_irq_setup(void) +{ + int i; + + /* Map all interrupts to CPU int #0 (IP2) */ + nile4_map_irq_all(0); + + /* PCI INTA#-E# must be level triggered */ + nile4_set_pci_irq_level_or_edge(0, 1); + nile4_set_pci_irq_level_or_edge(1, 1); + nile4_set_pci_irq_level_or_edge(2, 1); + nile4_set_pci_irq_level_or_edge(3, 1); + + /* PCI INTA#, B#, D# must be active low, INTC# must be active high */ + nile4_set_pci_irq_polarity(0, 0); + nile4_set_pci_irq_polarity(1, 0); + nile4_set_pci_irq_polarity(2, 1); + nile4_set_pci_irq_polarity(3, 0); + + for (i = 0; i < 16; i++) + nile4_clear_irq(i); + + /* Enable CPU int #0 */ + nile4_enable_irq_output(0); + + /* memory resource acquire in ddb_setup */ +} + +static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; +static struct irqaction irq_error = { no_action, 0, 0, "error", NULL, NULL }; + +extern asmlinkage void ddb5476_handle_int(void); +extern int setup_irq(unsigned int irq, struct irqaction *irqaction); +extern void mips_cpu_irq_init(u32 irq_base); +extern void vrc5476_irq_init(u32 irq_base); + +void __init ddb5476_irq_setup(void) +{ + /* hardware initialization */ + nile4_irq_setup(); + m1543_irq_setup(); + + /* controller setup */ + init_i8259_irqs(); + vrc5476_irq_init(VRC5476_IRQ_BASE); + mips_cpu_irq_init(CPU_IRQ_BASE); + + /* setup cascade interrupts */ + setup_irq(VRC5476_IRQ_BASE + VRC5476_I8259_CASCADE, &irq_cascade); + setup_irq(CPU_IRQ_BASE + CPU_VRC5476_CASCADE, &irq_cascade); + + /* setup error interrupts for debugging */ + setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CPCE, &irq_error); + setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_CNTD, &irq_error); + setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_MCE, &irq_error); + setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); + setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); + setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); + + /* setup the grandpa intr vector */ + set_except_vector(0, ddb5476_handle_int); +} diff -Nru a/arch/mips/ddb5xxx/ddb5476/nile4_pic.c b/arch/mips/ddb5xxx/ddb5476/nile4_pic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/nile4_pic.c Fri Jun 27 14:19:59 2003 @@ -0,0 +1,190 @@ +/* + * arch/mips/ddb5476/nile4.c -- + * low-level PIC code for NEC Vrc-5476 (Nile 4) + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <asm/addrspace.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + + +/* + * Interrupt Programming + */ +void nile4_map_irq(int nile4_irq, int cpu_irq) +{ + u32 offset, t; + + offset = DDB_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = ddb_in32(offset); + t &= ~(7 << (nile4_irq * 4)); + t |= cpu_irq << (nile4_irq * 4); + ddb_out32(offset, t); +} + +void nile4_map_irq_all(int cpu_irq) +{ + u32 all, t; + + all = cpu_irq; + all |= all << 4; + all |= all << 8; + all |= all << 16; + t = ddb_in32(DDB_INTCTRL); + t &= 0x88888888; + t |= all; + ddb_out32(DDB_INTCTRL, t); + t = ddb_in32(DDB_INTCTRL + 4); + t &= 0x88888888; + t |= all; + ddb_out32(DDB_INTCTRL + 4, t); +} + +void nile4_enable_irq(int nile4_irq) +{ + u32 offset, t; + + offset = DDB_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = ddb_in32(offset); + t |= 8 << (nile4_irq * 4); + ddb_out32(offset, t); +} + +void nile4_disable_irq(int nile4_irq) +{ + u32 offset, t; + + offset = DDB_INTCTRL; + if (nile4_irq >= 8) { + offset += 4; + nile4_irq -= 8; + } + t = ddb_in32(offset); + t &= ~(8 << (nile4_irq * 4)); + ddb_out32(offset, t); +} + +void nile4_disable_irq_all(void) +{ + ddb_out32(DDB_INTCTRL, 0); + ddb_out32(DDB_INTCTRL + 4, 0); +} + +u16 nile4_get_irq_stat(int cpu_irq) +{ + return ddb_in16(DDB_INTSTAT0 + cpu_irq * 2); +} + +void nile4_enable_irq_output(int cpu_irq) +{ + u32 t; + + t = ddb_in32(DDB_INTSTAT1 + 4); + t |= 1 << (16 + cpu_irq); + ddb_out32(DDB_INTSTAT1, t); +} + +void nile4_disable_irq_output(int cpu_irq) +{ + u32 t; + + t = ddb_in32(DDB_INTSTAT1 + 4); + t &= ~(1 << (16 + cpu_irq)); + ddb_out32(DDB_INTSTAT1, t); +} + +void nile4_set_pci_irq_polarity(int pci_irq, int high) +{ + u32 t; + + t = ddb_in32(DDB_INTPPES); + if (high) + t &= ~(1 << (pci_irq * 2)); + else + t |= 1 << (pci_irq * 2); + ddb_out32(DDB_INTPPES, t); +} + +void nile4_set_pci_irq_level_or_edge(int pci_irq, int level) +{ + u32 t; + + t = ddb_in32(DDB_INTPPES); + if (level) + t |= 2 << (pci_irq * 2); + else + t &= ~(2 << (pci_irq * 2)); + ddb_out32(DDB_INTPPES, t); +} + +void nile4_clear_irq(int nile4_irq) +{ + ddb_out32(DDB_INTCLR, 1 << nile4_irq); +} + +void nile4_clear_irq_mask(u32 mask) +{ + ddb_out32(DDB_INTCLR, mask); +} + +u8 nile4_i8259_iack(void) +{ + u8 irq; + u32 reg; + + /* Set window 0 for interrupt acknowledge */ + reg = ddb_in32(DDB_PCIINIT0); + + ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32); + irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE); + /* restore window 0 for PCI I/O space */ + // ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32); + ddb_out32(DDB_PCIINIT0, reg); + + /* i8269.c set the base vector to be 0x0 */ + return irq + I8259_IRQ_BASE; +} + +#if defined(CONFIG_RUNTIME_DEBUG) +void nile4_dump_irq_status(void) +{ + printk(KERN_DEBUG " + CPUSTAT = %p:%p\n", (void *) ddb_in32(DDB_CPUSTAT + 4), + (void *) ddb_in32(DDB_CPUSTAT)); + printk(KERN_DEBUG " + INTCTRL = %p:%p\n", (void *) ddb_in32(DDB_INTCTRL + 4), + (void *) ddb_in32(DDB_INTCTRL)); + printk(KERN_DEBUG + "INTSTAT0 = %p:%p\n", + (void *) ddb_in32(DDB_INTSTAT0 + 4), + (void *) ddb_in32(DDB_INTSTAT0)); + printk(KERN_DEBUG + "INTSTAT1 = %p:%p\n", + (void *) ddb_in32(DDB_INTSTAT1 + 4), + (void *) ddb_in32(DDB_INTSTAT1)); + printk(KERN_DEBUG + "INTCLR = %p:%p\n", (void *) ddb_in32(DDB_INTCLR + 4), + (void *) ddb_in32(DDB_INTCLR)); + printk(KERN_DEBUG + "INTPPES = %p:%p\n", (void *) ddb_in32(DDB_INTPPES + 4), + (void *) ddb_in32(DDB_INTPPES)); +} +#endif diff -Nru a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/setup.c Fri Jun 27 14:19:59 2003 @@ -0,0 +1,326 @@ +/* + * arch/mips/ddb5476/setup.c -- NEC DDB Vrc-5476 setup routines + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kbd_ll.h> +#include <linux/kernel.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/sched.h> +#include <linux/mc146818rtc.h> +#include <linux/pci.h> +#include <linux/ide.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/gdb-stub.h> +#include <asm/time.h> +#include <asm/debug.h> +#include <asm/traps.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +// #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ + +#ifdef USE_CPU_COUNTER_TIMER + +#define CPU_COUNTER_FREQUENCY 83000000 +#else +/* otherwise we use general purpose timer */ +#define TIMER_FREQUENCY 83000000 +#define TIMER_BASE DDB_T2CTRL +#define TIMER_IRQ (VRC5476_IRQ_BASE + VRC5476_IRQ_GPT) +#endif + +#ifdef CONFIG_KGDB +extern void breakpoint(void); +#endif + +extern struct ide_ops std_ide_ops; +extern struct kbd_ops std_kbd_ops; + +static void (*back_to_prom) (void) = (void (*)(void)) 0xbfc00000; + +static void ddb_machine_restart(char *command) +{ + u32 t; + + /* PCI cold reset */ + t = ddb_in32(DDB_PCICTRL + 4); + t |= 0x40000000; + ddb_out32(DDB_PCICTRL + 4, t); + /* CPU cold reset */ + t = ddb_in32(DDB_CPUSTAT); + t |= 1; + ddb_out32(DDB_CPUSTAT, t); + /* Call the PROM */ + back_to_prom(); +} + +static void ddb_machine_halt(void) +{ + printk(KERN_NOTICE "DDB Vrc-5476 halted.\n"); + while (1); +} + +static void ddb_machine_power_off(void) +{ + printk(KERN_NOTICE "DDB Vrc-5476 halted. Please turn off the power.\n"); + while (1); +} + +extern void ddb_irq_setup(void); +extern void rtc_ds1386_init(unsigned long base); + +static void __init ddb_time_init(void) +{ +#if defined(USE_CPU_COUNTER_TIMER) + mips_counter_frequency = CPU_COUNTER_FREQUENCY; +#endif + + /* we have ds1396 RTC chip */ + rtc_ds1386_init(KSEG1ADDR(DDB_PCI_MEM_BASE)); +} + + +extern int setup_irq(unsigned int irq, struct irqaction *irqaction); +static void __init ddb_timer_setup(struct irqaction *irq) +{ +#if defined(USE_CPU_COUNTER_TIMER) + + unsigned int count; + + /* we are using the cpu counter for timer interrupts */ + setup_irq(CPU_IRQ_BASE + 7, irq); + + /* to generate the first timer interrupt */ + count = read_c0_count(); + write_c0_compare(count + 1000); + +#else + + ddb_out32(TIMER_BASE, TIMER_FREQUENCY/HZ); + ddb_out32(TIMER_BASE+4, 0x1); /* enable timer */ + setup_irq(TIMER_IRQ, irq); +#endif +} + +static struct { + struct resource dma1; + struct resource pic1; + struct resource timer; + struct resource rtc; + struct resource dma_page_reg; + struct resource pic2; + struct resource dma2; +} ddb5476_ioport = { + { + "dma1", 0x00, 0x1f, IORESOURCE_BUSY}, { + "pic1", 0x20, 0x3f, IORESOURCE_BUSY}, { + "timer", 0x40, 0x5f, IORESOURCE_BUSY}, { + "rtc", 0x70, 0x7f, IORESOURCE_BUSY}, { + "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY}, { + "pic2", 0xa0, 0xbf, IORESOURCE_BUSY}, { + "dma2", 0xc0, 0xdf, IORESOURCE_BUSY} +}; + +static struct { + struct resource nile4; +} ddb5476_iomem = { + { "Nile 4", DDB_BASE, DDB_BASE + DDB_SIZE - 1, IORESOURCE_BUSY} +}; + + +static void ddb5476_board_init(void); +extern void ddb5476_irq_setup(void); +extern void (*irq_setup)(void); + +void __init +ddb_setup(void) +{ + extern int panic_timeout; + + irq_setup = ddb5476_irq_setup; + set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE)); + + board_time_init = ddb_time_init; + board_timer_setup = ddb_timer_setup; + + _machine_restart = ddb_machine_restart; + _machine_halt = ddb_machine_halt; + _machine_power_off = ddb_machine_power_off; + + /* request io port/mem resources */ + if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) || + request_resource(&ioport_resource, &ddb5476_ioport.pic1) || + request_resource(&ioport_resource, &ddb5476_ioport.timer) || + request_resource(&ioport_resource, &ddb5476_ioport.rtc) || + request_resource(&ioport_resource, + &ddb5476_ioport.dma_page_reg) + || request_resource(&ioport_resource, &ddb5476_ioport.pic2) + || request_resource(&ioport_resource, &ddb5476_ioport.dma2) + || request_resource(&iomem_resource, &ddb5476_iomem.nile4)) { + printk + ("ddb_setup - requesting oo port resources failed.\n"); + for (;;); + } +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + /* Reboot on panic */ + panic_timeout = 180; + + /* [jsun] we need to set BAR0 so that SDRAM 0 appears at 0x0 in PCI */ + /* *(long*)0xbfa00218 = 0x8; */ + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + /* board initialization stuff */ + ddb5476_board_init(); +} + +/* + * We don't trust bios. We essentially does hardware re-initialization + * as complete as possible, as far as we know we can safely do. + */ +static void ddb5476_board_init(void) +{ + /* ----------- setup PDARs ------------ */ + /* check SDRAM0, whether we are on MEM bus does not matter */ + db_assert((ddb_in32(DDB_SDRAM0) & 0xffffffef) == + ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1)); + + /* SDRAM1 should be turned off. What is this for anyway ? */ + db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0); + + /* flash 1&2, DDB status, DDB control */ + ddb_set_pdar(DDB_DCS2, DDB_DCS2_BASE, DDB_DCS2_SIZE, 16, 0, 0); + ddb_set_pdar(DDB_DCS3, DDB_DCS3_BASE, DDB_DCS3_SIZE, 16, 0, 0); + ddb_set_pdar(DDB_DCS4, DDB_DCS4_BASE, DDB_DCS4_SIZE, 8, 0, 0); + ddb_set_pdar(DDB_DCS5, DDB_DCS5_BASE, DDB_DCS5_SIZE, 8, 0, 0); + + /* shut off other pdar so they don't accidentally get into the way */ + ddb_set_pdar(DDB_DCS6, 0xffffffff, 0, 32, 0, 0); + ddb_set_pdar(DDB_DCS7, 0xffffffff, 0, 32, 0, 0); + ddb_set_pdar(DDB_DCS8, 0xffffffff, 0, 32, 0, 0); + + /* verify VRC5477 base addr */ + /* don't care about some details */ + db_assert((ddb_in32(DDB_INTCS) & 0xffffff0f) == + ddb_calc_pdar(DDB_INTCS_BASE, DDB_INTCS_SIZE, 8, 0, 0)); + + /* verify BOOT ROM addr */ + /* don't care about some details */ + db_assert((ddb_in32(DDB_BOOTCS) & 0xffffff0f) == + ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0)); + + /* setup PCI windows - window1 for MEM/config, window0 for IO */ + ddb_set_pdar(DDB_PCIW0, DDB_PCI_IO_BASE, DDB_PCI_IO_SIZE, 32, 0, 1); + ddb_set_pmr(DDB_PCIINIT0, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32); + + ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1); + ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32); + + /* ----------- setup PDARs ------------ */ + /* this is problematic - it will reset Aladin which cause we loose + * serial port, and we don't know how to set up Aladin chip again. + */ + // ddb_pci_reset_bus(); + + ddb_out32(DDB_BAR0, 0x00000008); + + ddb_out32(DDB_BARC, 0xffffffff); + ddb_out32(DDB_BARB, 0xffffffff); + ddb_out32(DDB_BAR1, 0xffffffff); + ddb_out32(DDB_BAR2, 0xffffffff); + ddb_out32(DDB_BAR3, 0xffffffff); + ddb_out32(DDB_BAR4, 0xffffffff); + ddb_out32(DDB_BAR5, 0xffffffff); + ddb_out32(DDB_BAR6, 0xffffffff); + ddb_out32(DDB_BAR7, 0xffffffff); + ddb_out32(DDB_BAR8, 0xffffffff); + + /* ----------- switch PCI1 to PCI CONFIG space ------------ */ + ddb_set_pdar(DDB_PCIW1, DDB_PCI_CONFIG_BASE, DDB_PCI_CONFIG_SIZE, 32, 0, 1); + ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_CFG, 0x0, DDB_PCI_ACCESS_32); + + /* ----- M1543 PCI setup ------ */ + + /* we know M1543 PCI-ISA controller is at addr:18 */ + /* xxxx1010 makes USB at addr:13 and PMU at addr:14 */ + *(volatile unsigned char *) 0xa8040072 &= 0xf0; + *(volatile unsigned char *) 0xa8040072 |= 0xa; + + /* setup USB interrupt to IRQ 9, (bit 0:3 - 0001) + * no IOCHRDY signal, (bit 7 - 1) + * M1543C & M7101 VID and Subsys Device ID are read-only (bit 6 - 1) + * Make USB Master INTAJ level to edge conversion (bit 4 - 1) + */ + *(unsigned char *) 0xa8040074 = 0xd1; + + /* setup PMU(SCI to IRQ 10 (bit 0:3 - 0011) + * SCI routing to IRQ 13 disabled (bit 7 - 1) + * SCI interrupt level to edge conversion bypassed (bit 4 - 0) + */ + *(unsigned char *) 0xa8040076 = 0x83; + + /* setup IDE controller + * enable IDE controller (bit 6 - 1) + * IDE IDSEL to be addr:24 (bit 4:5 - 11) + * no IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0) + * no IDE ATA Primary Bus Signal Pad Control (bit 2 - 0) + * primary IRQ is 14, secondary is 15 (bit 1:0 - 01 + */ + // *(unsigned char*)0xa8040058 = 0x71; + // *(unsigned char*)0xa8040058 = 0x79; + // *(unsigned char*)0xa8040058 = 0x74; // use SIRQ, primary tri-state + *(unsigned char *) 0xa8040058 = 0x75; // primary tri-state + +#if 0 + /* this is not necessary if M5229 does not use SIRQ */ + *(unsigned char *) 0xa8040044 = 0x0d; // primary to IRQ 14 + *(unsigned char *) 0xa8040075 = 0x0d; // secondary to IRQ 14 +#endif + + /* enable IDE in the M5229 config register 0x50 (bit 0 - 1) */ + /* M5229 IDSEL is addr:24; see above setting */ + *(unsigned char *) 0xa9000050 |= 0x1; + + /* enable bus master (bit 2) and IO decoding (bit 0) */ + *(unsigned char *) 0xa9000004 |= 0x5; + + /* enable native, copied from arch/ppc/k2boot/head.S */ + /* TODO - need volatile, need to be portable */ + *(unsigned char *) 0xa9000009 = 0xff; + + /* ----- end of M1543 PCI setup ------ */ + + /* ----- reset on-board ether chip ------ */ + *((volatile u32 *) 0xa8020004) |= 1; /* decode I/O */ + *((volatile u32 *) 0xa8020010) = 0; /* set BAR address */ + + /* send reset command */ + *((volatile u32 *) 0xa6000000) = 1; /* do a soft reset */ + + /* disable ether chip */ + *((volatile u32 *) 0xa8020004) = 0; /* disable any decoding */ + + /* put it into sleep */ + *((volatile u32 *) 0xa8020040) = 0x80000000; + + /* ----- end of reset on-board ether chip ------ */ + + /* ----------- switch PCI1 back to PCI MEM space ------------ */ + ddb_set_pdar(DDB_PCIW1, DDB_PCI_MEM_BASE, DDB_PCI_MEM_SIZE, 32, 0, 1); + ddb_set_pmr(DDB_PCIINIT1, DDB_PCICMD_MEM, DDB_PCI_MEM_BASE, DDB_PCI_ACCESS_32); +} diff -Nru a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,113 @@ +/* + * The irq controller for vrc5476. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/types.h> +#include <linux/ptrace.h> + +#include <asm/system.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +static int irq_base; + +static void vrc5476_irq_enable(uint irq) +{ + nile4_enable_irq(irq - irq_base); +} + +static void vrc5476_irq_disable(uint irq) +{ + nile4_disable_irq(irq - irq_base); +} + +static unsigned int vrc5476_irq_startup(uint irq) +{ + nile4_enable_irq(irq - irq_base); + return 0; +} + +#define vrc5476_irq_shutdown vrc5476_irq_disable + +static void vrc5476_irq_ack(uint irq) +{ + nile4_clear_irq(irq - irq_base); + nile4_disable_irq(irq - irq_base); +} + +static void vrc5476_irq_end(uint irq) +{ + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + vrc5476_irq_enable(irq); +} + +static hw_irq_controller vrc5476_irq_controller = { + "vrc5476", + vrc5476_irq_startup, + vrc5476_irq_shutdown, + vrc5476_irq_enable, + vrc5476_irq_disable, + vrc5476_irq_ack, + vrc5476_irq_end, + NULL /* no affinity stuff for UP */ +}; + +void __init +vrc5476_irq_init(u32 base) +{ + extern irq_desc_t irq_desc[]; + u32 i; + + irq_base = base; + for (i= base; i< base + NUM_VRC5476_IRQ; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &vrc5476_irq_controller; + } +} + + +asmlinkage void +vrc5476_irq_dispatch(struct pt_regs *regs) +{ + extern void spurious_interrupt(void); + + u32 mask; + int nile4_irq; + + mask = nile4_get_irq_stat(0); + + /* quick check for possible time interrupt */ + if (mask & (1 << VRC5476_IRQ_GPT)) { + do_IRQ(VRC5476_IRQ_BASE + VRC5476_IRQ_GPT, regs); + return; + } + + /* check for i8259 interrupts */ + if (mask & (1 << VRC5476_I8259_CASCADE)) { + int i8259_irq = nile4_i8259_iack(); + do_IRQ(I8259_IRQ_BASE + i8259_irq, regs); + return; + } + + /* regular nile4 interrupts (we should not really have any */ + for (nile4_irq = 0; mask; nile4_irq++, mask >>= 1) { + if (mask & 1) { + do_IRQ(VRC5476_IRQ_BASE + nile4_irq, regs); + return; + } + } + spurious_interrupt(); +} diff -Nru a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile --- a/arch/mips/ddb5xxx/ddb5477/Makefile Fri Jun 27 14:19:54 2003 +++ b/arch/mips/ddb5xxx/ddb5477/Makefile Fri Jun 27 14:19:54 2003 @@ -2,10 +2,9 @@ # Makefile for NEC DDB-Vrc5477 board # -EXTRA_AFLAGS := $(CFLAGS) +obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o -obj-y += int-handler.o irq.o irq_5477.o setup.o pci.o pci_ops.o +obj-$(CONFIG_RUNTIME_DEBUG) += debug.o +obj-$(CONFIG_KGDB) += kgdb_io.o -obj-$(CONFIG_LL_DEBUG) += debug.o -obj-$(CONFIG_REMOTE_DEBUG) += kgdb_io.o -obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/ddb5xxx/ddb5477/debug.c b/arch/mips/ddb5xxx/ddb5477/debug.c --- a/arch/mips/ddb5xxx/ddb5477/debug.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/ddb5xxx/ddb5477/debug.c Fri Jun 27 14:19:54 2003 @@ -15,8 +15,6 @@ */ #include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/signal.h> /* SA_INTERRUPT */ #include <asm/mipsregs.h> #include <asm/ddb5xxx/ddb5xxx.h> @@ -32,9 +30,9 @@ printk("\nshow regs: %s\n", name); for(i=0;regs[i].regname!= NULL; i++) { - printk("%-16s= %08x\t\t(@%08x)\n", - regs[i].regname, - *(unsigned *)(regs[i].regaddr), + printk("%-16s= %08x\t\t(@%08x)\n", + regs[i].regname, + *(unsigned *)(regs[i].regaddr), regs[i].regaddr); } } @@ -58,15 +56,15 @@ void vrc5477_show_int_regs() { jsun_show_regs("interrupt registers", int_regs); - printk("CPU CAUSE = %08x\n", read_32bit_cp0_register(CP0_CAUSE)); - printk("CPU STATUS = %08x\n", read_32bit_cp0_register(CP0_STATUS)); + printk("CPU CAUSE = %08x\n", read_c0_cause()); + printk("CPU STATUS = %08x\n", read_c0_status()); } static Register pdar_regs[] = { {"DDB_SDRAM0", DDB_BASE + DDB_SDRAM0}, {"DDB_SDRAM1", DDB_BASE + DDB_SDRAM1}, - {"DDB_LDCS0", DDB_BASE + DDB_LDCS0}, - {"DDB_LDCS1", DDB_BASE + DDB_LDCS1}, - {"DDB_LDCS2", DDB_BASE + DDB_LDCS2}, + {"DDB_LCS0", DDB_BASE + DDB_LCS0}, + {"DDB_LCS1", DDB_BASE + DDB_LCS1}, + {"DDB_LCS2", DDB_BASE + DDB_LCS2}, {"DDB_INTCS", DDB_BASE + DDB_INTCS}, {"DDB_BOOTCS", DDB_BASE + DDB_BOOTCS}, {"DDB_PCIW0", DDB_BASE + DDB_PCIW0}, diff -Nru a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S --- a/arch/mips/ddb5xxx/ddb5477/int-handler.S Fri Jun 27 14:19:59 2003 +++ b/arch/mips/ddb5xxx/ddb5477/int-handler.S Fri Jun 27 14:19:59 2003 @@ -9,13 +9,12 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include <linux/config.h> - #include <asm/asm.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> #include <asm/regdef.h> #include <asm/stackframe.h> +#include <asm/ddb5xxx/ddb5477.h> /* * first level interrupt dispatcher for ocelot board - @@ -28,14 +27,14 @@ CLI .set at .set noreorder - mfc0 t0, CP0_CAUSE + mfc0 t0, CP0_CAUSE mfc0 t2, CP0_STATUS and t0, t2 - + andi t1, t0, STATUSF_IP7 /* cpu timer */ bnez t1, ll_cputimer_irq - andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) + andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) bnez t1, ll_vrc5477_irq andi t1, t0, STATUSF_IP0 /* software int 0 */ bnez t1, ll_cpu_ip0 @@ -51,26 +50,26 @@ .align 5 -ll_vrc5477_irq: +ll_vrc5477_irq: move a0, sp jal vrc5477_irq_dispatch j ret_from_irq ll_cputimer_irq: - li a0, 7 + li a0, CPU_IRQ_BASE + 7 move a1, sp jal do_IRQ j ret_from_irq -ll_cpu_ip0: - li a0, 0 +ll_cpu_ip0: + li a0, CPU_IRQ_BASE + 0 move a1, sp jal do_IRQ j ret_from_irq -ll_cpu_ip1: - li a0, 1 +ll_cpu_ip1: + li a0, CPU_IRQ_BASE + 1 move a1, sp jal do_IRQ j ret_from_irq diff -Nru a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c --- a/arch/mips/ddb5xxx/ddb5477/irq.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/ddb5xxx/ddb5477/irq.c Fri Jun 27 14:19:53 2003 @@ -12,16 +12,20 @@ */ #include <linux/config.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/irq.h> #include <linux/types.h> #include <linux/ptrace.h> +#include <asm/i8259.h> #include <asm/system.h> #include <asm/mipsregs.h> +#include <asm/debug.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + #include <asm/ddb5xxx/ddb5xxx.h> -/* [jsun] sooner or later we should move this debug stuff to MIPS common */ -#include <asm/ddb5xxx/debug.h> /* * IRQ mapping @@ -37,7 +41,7 @@ * 7 - cpu timer (used by default) * * 8-39: 32 Vrc5477 interrupt sources - * (refer to the Vrc5477 manual) + * (refer to the Vrc5477 manual) */ #define PCI0 DDB_INTPPES0 @@ -55,7 +59,7 @@ #define INTD 3 #define INTE 4 -static inline void +static inline void set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger) { u32 reg_value; @@ -63,7 +67,7 @@ reg_value = ddb_in32(pci); reg_bitmask = 0x3 << (intn * 2); - + reg_value &= ~reg_bitmask; reg_value |= (active | trigger) << (intn * 2); ddb_out32(pci, reg_value); @@ -72,26 +76,31 @@ extern void vrc5477_irq_init(u32 base); extern void mips_cpu_irq_init(u32 base); extern asmlinkage void ddb5477_handle_int(void); +extern int setup_irq(unsigned int irq, struct irqaction *irqaction); +static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; void ddb5477_irq_setup(void) { - MIPS_DEBUG(printk("ddb5477_irq_setup invoked.\n")); + db_run(printk("ddb5477_irq_setup invoked.\n")); - /* by default, we disable all interrupts and route all vrc5477 + /* by default, we disable all interrupts and route all vrc5477 * interrupts to pin 0 (irq 2) */ ddb_out32(DDB_INTCTRL0, 0); ddb_out32(DDB_INTCTRL1, 0); ddb_out32(DDB_INTCTRL2, 0); ddb_out32(DDB_INTCTRL3, 0); - clear_cp0_status(0xff00); - set_cp0_status(0x0400); + clear_c0_status(0xff00); + set_c0_status(0x0400); /* setup PCI interrupt attributes */ set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE); - set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE); + if (mips_machtype == MACH_NEC_ROCKHOPPERII) + set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE); + else + set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE); @@ -101,9 +110,9 @@ set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE); set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE); - /* + /* * for debugging purpose, we enable several error interrupts - * and route them to pin 1. (IP3) + * and route them to pin 1. (IP3) */ /* cpu parity check - 0 */ ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0); @@ -121,13 +130,34 @@ ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31); /* init all controllers */ - mips_cpu_irq_init(0); - vrc5477_irq_init(8); + init_i8259_irqs(); + mips_cpu_irq_init(CPU_IRQ_BASE); + vrc5477_irq_init(VRC5477_IRQ_BASE); + + + /* setup cascade interrupts */ + setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); + setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); /* hook up the first-level interrupt handler */ set_except_vector(0, ddb5477_handle_int); } +u8 i8259_interrupt_ack(void) +{ + u8 irq; + u32 reg; + + /* Set window 0 for interrupt acknowledge */ + reg = ddb_in32(DDB_PCIINIT10); + + ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32); + irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE); + ddb_out32(DDB_PCIINIT10, reg); + + /* i8259.c set the base vector to be 0x0 */ + return irq + I8259_IRQ_BASE; +} /* * the first level int-handler will jump here if it is a vrc5477 irq */ @@ -135,29 +165,38 @@ asmlinkage void vrc5477_irq_dispatch(struct pt_regs *regs) { - extern unsigned int do_IRQ(int irq, struct pt_regs *regs); - u32 intStatus; u32 bitmask; u32 i; - MIPS_ASSERT(ddb_in32(DDB_INT2STAT) == 0); - MIPS_ASSERT(ddb_in32(DDB_INT3STAT) == 0); - MIPS_ASSERT(ddb_in32(DDB_INT4STAT) == 0); - MIPS_ASSERT(ddb_in32(DDB_NMISTAT) == 0); + db_assert(ddb_in32(DDB_INT2STAT) == 0); + db_assert(ddb_in32(DDB_INT3STAT) == 0); + db_assert(ddb_in32(DDB_INT4STAT) == 0); + db_assert(ddb_in32(DDB_NMISTAT) == 0); if (ddb_in32(DDB_INT1STAT) != 0) { -#if defined(CONFIG_LL_DEBUG) +#if defined(CONFIG_RUNTIME_DEBUG) vrc5477_show_int_regs(); #endif - panic("error interrupt has happened.\n"); + panic("error interrupt has happened."); } intStatus = ddb_in32(DDB_INT0STAT); + + if (mips_machtype == MACH_NEC_ROCKHOPPERII) { + /* check for i8259 interrupts */ + if (intStatus & (1 << VRC5477_I8259_CASCADE)) { + int i8259_irq = i8259_interrupt_ack(); + do_IRQ(I8259_IRQ_BASE + i8259_irq, regs); + return; + } + } + for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) { /* do we need to "and" with the int mask? */ if (intStatus & bitmask) { - do_IRQ(8 + i, regs); + do_IRQ(VRC5477_IRQ_BASE + i, regs); + return; } } } diff -Nru a/arch/mips/ddb5xxx/ddb5477/irq_5477.c b/arch/mips/ddb5xxx/ddb5477/irq_5477.c --- a/arch/mips/ddb5xxx/ddb5477/irq_5477.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/ddb5xxx/ddb5477/irq_5477.c Fri Jun 27 14:19:54 2003 @@ -1,4 +1,4 @@ -/*********************************************************************** +/* * Copyright 2001 MontaVista Software Inc. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net * @@ -9,7 +9,7 @@ * 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. - *********************************************************************** + * */ /* @@ -19,37 +19,36 @@ * vrc5477_irq_init(u32 irq_base); */ -#include <linux/irq.h> +#include <linux/interrupt.h> #include <linux/types.h> #include <linux/ptrace.h> -#include <asm/ddb5xxx/ddb5xxx.h> +#include <asm/debug.h> -/* [jsun] sooner or later we should move this debug stuff to MIPS common */ -#include <asm/ddb5xxx/debug.h> +#include <asm/ddb5xxx/ddb5xxx.h> /* number of total irqs supported by Vrc5477 */ #define NUM_5477_IRQ 32 -static int vrc5477_irq_base=-1; +static int vrc5477_irq_base = -1; -static void +static void vrc5477_irq_enable(unsigned int irq) { - MIPS_ASSERT(vrc5477_irq_base != -1); - MIPS_ASSERT(irq >= vrc5477_irq_base); - MIPS_ASSERT(irq < vrc5477_irq_base+ NUM_5477_IRQ); + db_assert(vrc5477_irq_base != -1); + db_assert(irq >= vrc5477_irq_base); + db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ); ll_vrc5477_irq_enable(irq - vrc5477_irq_base); } -static void +static void vrc5477_irq_disable(unsigned int irq) { - MIPS_ASSERT(vrc5477_irq_base != -1); - MIPS_ASSERT(irq >= vrc5477_irq_base); - MIPS_ASSERT(irq < vrc5477_irq_base + NUM_5477_IRQ); + db_assert(vrc5477_irq_base != -1); + db_assert(irq >= vrc5477_irq_base); + db_assert(irq < vrc5477_irq_base + NUM_5477_IRQ); ll_vrc5477_irq_disable(irq - vrc5477_irq_base); } @@ -65,9 +64,9 @@ static void vrc5477_irq_ack(unsigned int irq) { - MIPS_ASSERT(vrc5477_irq_base != -1); - MIPS_ASSERT(irq >= vrc5477_irq_base); - MIPS_ASSERT(irq < vrc5477_irq_base+ NUM_5477_IRQ); + db_assert(vrc5477_irq_base != -1); + db_assert(irq >= vrc5477_irq_base); + db_assert(irq < vrc5477_irq_base+ NUM_5477_IRQ); /* clear the interrupt bit */ /* some irqs require the driver to clear the sources */ @@ -82,11 +81,12 @@ static void vrc5477_irq_end(unsigned int irq) { - MIPS_ASSERT(vrc5477_irq_base != -1); - MIPS_ASSERT(irq >= vrc5477_irq_base); - MIPS_ASSERT(irq < vrc5477_irq_base + NUM_5477_IRQ); + db_assert(vrc5477_irq_base != -1); + db_assert(irq >= vrc5477_irq_base); + db_assert(irq < vrc5477_irq_base + NUM_5477_IRQ); - ll_vrc5477_irq_enable( irq - vrc5477_irq_base); + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_vrc5477_irq_enable( irq - vrc5477_irq_base); } hw_irq_controller vrc5477_irq_controller = { @@ -100,7 +100,7 @@ NULL /* no affinity stuff for UP */ }; -void +void vrc5477_irq_init(u32 irq_base) { extern irq_desc_t irq_desc[]; @@ -112,17 +112,8 @@ irq_desc[i].depth = 1; irq_desc[i].handler = &vrc5477_irq_controller; } - - vrc5477_irq_base = irq_base; -} - -int vrc5477_irq_to_irq(int irq) -{ - MIPS_ASSERT(irq >= 0); - MIPS_ASSERT(irq < NUM_5477_IRQ); - - return irq + vrc5477_irq_base; + vrc5477_irq_base = irq_base; } void ll_vrc5477_irq_route(int vrc5477_irq, int ip) @@ -131,10 +122,10 @@ u32 reg_bitmask; u32 reg_index; - MIPS_ASSERT(vrc5477_irq >= 0); - MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ); - MIPS_ASSERT(ip >= 0); - MIPS_ASSERT((ip < 5) || (ip == 6)); + db_assert(vrc5477_irq >= 0); + db_assert(vrc5477_irq < NUM_5477_IRQ); + db_assert(ip >= 0); + db_assert((ip < 5) || (ip == 6)); reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4; reg_value = ddb_in32(reg_index); @@ -150,13 +141,13 @@ u32 reg_bitmask; u32 reg_index; - MIPS_ASSERT(vrc5477_irq >= 0); - MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ); + db_assert(vrc5477_irq >= 0); + db_assert(vrc5477_irq < NUM_5477_IRQ); reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4; reg_value = ddb_in32(reg_index); reg_bitmask = 8 << (vrc5477_irq % 8 * 4); - MIPS_ASSERT((reg_value & reg_bitmask) == 0); + db_assert((reg_value & reg_bitmask) == 0); ddb_out32(reg_index, reg_value | reg_bitmask); } @@ -166,14 +157,14 @@ u32 reg_bitmask; u32 reg_index; - MIPS_ASSERT(vrc5477_irq >= 0); - MIPS_ASSERT(vrc5477_irq < NUM_5477_IRQ); + db_assert(vrc5477_irq >= 0); + db_assert(vrc5477_irq < NUM_5477_IRQ); reg_index = DDB_INTCTRL0 + vrc5477_irq/8*4; reg_value = ddb_in32(reg_index); reg_bitmask = 8 << (vrc5477_irq % 8 * 4); /* we assert that the interrupt is enabled (perhaps over-zealous) */ - MIPS_ASSERT( (reg_value & reg_bitmask) != 0); + db_assert( (reg_value & reg_bitmask) != 0); ddb_out32(reg_index, reg_value & ~reg_bitmask); } diff -Nru a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c --- a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c Fri Jun 27 14:19:59 2003 @@ -1,17 +1,41 @@ +/* + * kgdb io functions for DDB5477. We use the second serial port (upper one). + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ -#include <linux/config.h> +/* ======================= CONFIG ======================== */ -#if (defined(CONFIG_DDB5477) && defined(CONFIG_REMOTE_DEBUG)) +/* [jsun] we use the second serial port for kdb */ +#define BASE 0xbfa04240 +#define MAX_BAUD 115200 -/* --- CONFIG --- */ +/* distance in bytes between two serial registers */ +#define REG_OFFSET 8 + +/* + * 0 - kgdb does serial init + * 1 - kgdb skip serial init + */ +static int remoteDebugInitialized = 0; + +/* + * the default baud rate *if* kgdb does serial init + */ +#define BAUD_DEFAULT UART16550_BAUD_38400 + +/* ======================= END OF CONFIG ======================== */ -/* we need uint32 uint8 */ -/* #include "types.h" */ typedef unsigned char uint8; typedef unsigned int uint32; -/* --- END OF CONFIG --- */ - #define UART16550_BAUD_2400 2400 #define UART16550_BAUD_4800 4800 #define UART16550_BAUD_9600 9600 @@ -34,21 +58,10 @@ #define UART16550_STOP_1BIT 0x0 #define UART16550_STOP_2BIT 0x4 -/* ----------------------------------------------------- */ - -/* === CONFIG === */ - -/* [jsun] we use the second serial port for kdb */ -#define BASE 0xbfa04240 -#define MAX_BAUD 115200 -#define REG_OFFSET 8 - -/* === END OF CONFIG === */ - /* register offset */ -#define OFS_RCV_BUFFER (0*REG_OFFSET) -#define OFS_TRANS_HOLD (0*REG_OFFSET) -#define OFS_SEND_BUFFER (0*REG_OFFSET) +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 #define OFS_INTR_ENABLE (1*REG_OFFSET) #define OFS_INTR_ID (2*REG_OFFSET) #define OFS_DATA_FORMAT (3*REG_OFFSET) @@ -70,73 +83,54 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) { - /* disable interrupts */ - UART16550_WRITE(OFS_INTR_ENABLE, 0); + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ - { - uint32 divisor; - - /* set DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x80); - - /* set divisor */ - divisor = MAX_BAUD / baud; - UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); - UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); - - /* clear DIAB bit */ - UART16550_WRITE(OFS_LINE_CONTROL, 0x0); - } + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } - /* set data format */ - UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); } -static int remoteDebugInitialized = 0; - -int debug_state = -1; uint8 getDebugChar(void) { - uint8 c; - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_38400, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(BAUD_DEFAULT, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } - while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); - c= UART16550_READ(OFS_RCV_BUFFER); -/* - if (state != 1) { - state = 1; - debug_out("\ngetDebugChar: ", 15); - } - debug_out(&c, 1); -*/ - return c; + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); } int putDebugChar(uint8 byte) { - if (!remoteDebugInitialized) { - remoteDebugInitialized = 1; - debugInit(UART16550_BAUD_9600, - UART16550_DATA_8BIT, - UART16550_PARITY_NONE, UART16550_STOP_1BIT); - } - - while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); - UART16550_WRITE(OFS_SEND_BUFFER, byte); - if (debug_state != 2) { - debug_state = 2; - // debug_out("\nputDebugChar: ", 15); - } - // debug_out(&byte, 1); - return 1; + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(BAUD_DEFAULT, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; } - -#endif diff -Nru a/arch/mips/ddb5xxx/ddb5477/lcd44780.c b/arch/mips/ddb5xxx/ddb5477/lcd44780.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5477/lcd44780.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,92 @@ +/* + * lcd44780.c + * Simple "driver" for a memory-mapped 44780-style LCD display. + * + * Copyright 2001 Bradley D. LaRonde <brad@ltc.com> + * + * 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 LCD44780_COMMAND ((volatile unsigned char *)0xbe020000) +#define LCD44780_DATA ((volatile unsigned char *)0xbe020001) + +#define LCD44780_4BIT_1LINE 0x20 +#define LCD44780_4BIT_2LINE 0x28 +#define LCD44780_8BIT_1LINE 0x30 +#define LCD44780_8BIT_2LINE 0x38 +#define LCD44780_MODE_DEC 0x04 +#define LCD44780_MODE_DEC_SHIFT 0x05 +#define LCD44780_MODE_INC 0x06 +#define LCD44780_MODE_INC_SHIFT 0x07 +#define LCD44780_SCROLL_LEFT 0x18 +#define LCD44780_SCROLL_RIGHT 0x1e +#define LCD44780_CURSOR_UNDERLINE 0x0e +#define LCD44780_CURSOR_BLOCK 0x0f +#define LCD44780_CURSOR_OFF 0x0c +#define LCD44780_CLEAR 0x01 +#define LCD44780_BLANK 0x08 +#define LCD44780_RESTORE 0x0c // Same as CURSOR_OFF +#define LCD44780_HOME 0x02 +#define LCD44780_LEFT 0x10 +#define LCD44780_RIGHT 0x14 + +void lcd44780_wait(void) +{ + int i, j; + for(i=0; i < 400; i++) + for(j=0; j < 10000; j++); +} + +void lcd44780_command(unsigned char c) +{ + *LCD44780_COMMAND = c; + lcd44780_wait(); +} + +void lcd44780_data(unsigned char c) +{ + *LCD44780_DATA = c; + lcd44780_wait(); +} + +void lcd44780_puts(const char* s) +{ + int i,j; + int pos = 0; + + lcd44780_command(LCD44780_CLEAR); + while(*s) { + lcd44780_data(*s); + s++; + pos++; + if (pos == 8) { + /* We must write 32 of spaces to get cursor to 2nd line */ + for (j=0; j<32; j++) { + lcd44780_data(' '); + } + } + if (pos == 16) { + /* We have filled all 16 character positions, so stop + outputing data */ + break; + } + } +#ifdef LCD44780_PUTS_PAUSE + for(i = 1; i < 2000; i++) + lcd44780_wait(); +#endif +} + +void lcd44780_init(void) +{ + // The display on the RockHopper is physically a single + // 16 char line (two 8 char lines concatenated). bdl + lcd44780_command(LCD44780_8BIT_2LINE); + lcd44780_command(LCD44780_MODE_INC); + lcd44780_command(LCD44780_CURSOR_BLOCK); + lcd44780_command(LCD44780_CLEAR); +} diff -Nru a/arch/mips/ddb5xxx/ddb5477/lcd44780.h b/arch/mips/ddb5xxx/ddb5477/lcd44780.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ddb5xxx/ddb5477/lcd44780.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,15 @@ +/* + * lcd44780.h + * Simple "driver" for a memory-mapped 44780-style LCD display. + * + * Copyright 2001 Bradley D. LaRonde <brad@ltc.com> + * + * 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. + * + */ + +void lcd44780_puts(const char* s); +void lcd44780_init(void); diff -Nru a/arch/mips/ddb5xxx/ddb5477/pci.c b/arch/mips/ddb5xxx/ddb5477/pci.c --- a/arch/mips/ddb5xxx/ddb5477/pci.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,147 +0,0 @@ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/pci.h> - -#include <asm/ddb5xxx/ddb5xxx.h> -#include <asm/ddb5xxx/debug.h> -#include <asm/ddb5xxx/pci.h> - -static struct resource extpci_io_resource = { - "ext pci IO space", - DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE, - DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE -1, - IORESOURCE_IO}; - -static struct resource extpci_mem_resource = { - "ext pci memory space", - DDB_PCI0_MEM_BASE, - DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE -1, - IORESOURCE_MEM}; - -static struct resource iopci_io_resource = { - "io pci IO space", - DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE, - DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE -1, - IORESOURCE_IO}; - -static struct resource iopci_mem_resource = { - "ext pci memory space", - DDB_PCI1_MEM_BASE, - DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE -1, - IORESOURCE_MEM}; - -extern struct pci_ops ddb5477_ext_pci_ops; -extern struct pci_ops ddb5477_io_pci_ops; - -struct pci_channel mips_pci_channels[] = { - { &ddb5477_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource }, - { &ddb5477_io_pci_ops, &iopci_io_resource, &iopci_mem_resource }, - { NULL, NULL, NULL} -}; - - -/* - * we fix up irqs based on the slot number. - * The first entry is at AD:11. - * Fortunately this works because, although we have two pci buses, - * they all have different slot numbers. - * - * This does not work for devices on sub-buses. - * - * Note that the irq number in the array is relative number in vrc5477. - * We need to translate it to global irq number. - */ - -/* - * irq mapping : PCI int # -> vrc5477 irq # - * based on vrc5477 manual page 46 - */ -#define PCI_EXT_INTA 8 -#define PCI_EXT_INTB 9 -#define PCI_EXT_INTC 10 -#define PCI_EXT_INTD 11 -#define PCI_EXT_INTE 12 - -#define PCI_IO_INTA 16 -#define PCI_IO_INTB 17 -#define PCI_IO_INTC 18 -#define PCI_IO_INTD 19 - -/* - * irq mapping : device -> pci int #, - * ddb5477 board manual page 4 and vrc5477 manual page 46 - */ -#define INT_ONBOARD_TULIP PCI_EXT_INTA -#define INT_SLOT1 PCI_EXT_INTB -#define INT_SLOT2 PCI_EXT_INTC -#define INT_SLOT3 PCI_EXT_INTD -#define INT_SLOT4 PCI_EXT_INTE - -#define INT_USB_HOST PCI_IO_INTA -#define INT_USB_PERI PCI_IO_INTB -#define INT_AC97 PCI_IO_INTC - -/* - * based on ddb5477 manual page 11 - */ -#define MAX_SLOT_NUM 21 -static unsigned char irq_map[MAX_SLOT_NUM] = { - /* AD:11 */ 0xff, 0xff, 0xff, 0xff, - /* AD:15 */ INT_ONBOARD_TULIP, INT_SLOT1, INT_SLOT2, INT_SLOT3, - /* AD:19 */ INT_SLOT4, 0xff, 0xff, 0xff, - /* AD:23 */ 0xff, 0xff, 0xff, 0xff, - /* AD:27 */ 0xff, 0xff, INT_AC97, INT_USB_PERI, - /* AD:31 */ INT_USB_HOST -}; - -extern int vrc5477_irq_to_irq(int irq); -void __init pcibios_fixup_irqs(void) -{ - struct pci_dev *dev = NULL; - int slot_num; - - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - slot_num = PCI_SLOT(dev->devfn); - MIPS_ASSERT(slot_num < MAX_SLOT_NUM); - MIPS_ASSERT(irq_map[slot_num] != 0xff); - - pci_write_config_byte(dev, - PCI_INTERRUPT_LINE, - irq_map[slot_num]); - dev->irq = vrc5477_irq_to_irq(irq_map[slot_num]); - } -} - -#if defined(CONFIG_LL_DEBUG) -extern void jsun_scan_pci_bus(void); -extern void jsun_assign_pci_resource(void); -#endif -void __init ddb_pci_reset_bus(void) -{ - u32 temp; - - /* - * I am not sure about the "official" procedure, the following - * steps work as far as I know: - * We first set PCI cold reset bit (bit 31) in PCICTRL-H. - * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. - * The same is true for both PCI channels. - */ - temp = ddb_in32(DDB_PCICTL0_H); - temp |= 0x80000000; - ddb_out32(DDB_PCICTL0_H, temp); - temp &= ~0xc0000000; - ddb_out32(DDB_PCICTL0_H, temp); - - temp = ddb_in32(DDB_PCICTL1_H); - temp |= 0x80000000; - ddb_out32(DDB_PCICTL1_H, temp); - temp &= ~0xc0000000; - ddb_out32(DDB_PCICTL1_H, temp); -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} diff -Nru a/arch/mips/ddb5xxx/ddb5477/pci_ops.c b/arch/mips/ddb5xxx/ddb5477/pci_ops.c --- a/arch/mips/ddb5xxx/ddb5477/pci_ops.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,381 +0,0 @@ -/*********************************************************************** - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * arch/mips/ddb5xxx/ddb5477/pci_ops.c - * Define the pci_ops for DB5477. - * - * Much of the code is derived from the original DDB5074 port by - * Geert Uytterhoeven <geert@sonycom.com> - * - * 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. - *********************************************************************** - */ - -/* - * DDB5477 has two PCI channels, external PCI and IOPIC (internal) - * Therefore we provide two sets of pci_ops. - */ - -#include <linux/config.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/types.h> - -#include <asm/addrspace.h> -#include <asm/ddb5xxx/debug.h> -#include <asm/ddb5xxx/ddb5xxx.h> - -/* - * config_swap structure records what set of pdar/pmr are used - * to access pci config space. It also provides a place hold the - * original values for future restoring. - */ -struct pci_config_swap { - u32 pdar; - u32 pmr; - u32 config_base; - u32 config_size; - u32 pdar_backup; - u32 pmr_backup; -}; - -/* - * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI. - */ -struct pci_config_swap ext_pci_swap = { - DDB_PCIW0, - DDB_PCIINIT00, - DDB_PCI0_CONFIG_BASE, - DDB_PCI0_CONFIG_SIZE -}; -struct pci_config_swap io_pci_swap = { - DDB_IOPCIW0, - DDB_PCIINIT01, - DDB_PCI1_CONFIG_BASE, - DDB_PCI1_CONFIG_SIZE -}; - - -/* - * access config space - */ -static inline u32 ddb_access_config_base(struct pci_config_swap *swap, - u32 bus,/* 0 means top level bus */ - u32 slot_num) -{ - u32 pci_addr = 0; - u32 pciinit_offset = 0; - u32 virt_addr = swap->config_base; - u32 option; - - /* [jsun] hack for testing */ - // if (slot_num == 4) slot_num = 0; - - /* minimum pdar (window) size is 2MB */ - MIPS_ASSERT(swap->config_size >= (2 << 20)); - - MIPS_ASSERT(slot_num < (1 << 5)); - MIPS_ASSERT(bus < (1 << 8)); - - /* backup registers */ - swap->pdar_backup = ddb_in32(swap->pdar); - swap->pmr_backup = ddb_in32(swap->pmr); - - /* set the pdar (pci window) register */ - ddb_set_pdar(swap->pdar, - swap->config_base, - swap->config_size, - 32, /* 32 bit wide */ - 0, /* not on local memory bus */ - 0); /* not visible from PCI bus (N/A) */ - - /* - * calcuate the absolute pci config addr; - * according to the spec, we start scanning from adr:11 (0x800) - */ - if (bus == 0) { - /* type 0 config */ - pci_addr = 0x800 << slot_num; - } else { - /* type 1 config */ - pci_addr = (bus << 16) | (slot_num << 11); - panic("ddb_access_config_base: we don't support type 1 config Yet"); - } - - /* - * if pci_addr is less than pci config window size, we set - * pciinit_offset to 0 and adjust the virt_address. - * Otherwise we will try to adjust pciinit_offset. - */ - if (pci_addr < swap->config_size) { - virt_addr = KSEG1ADDR(swap->config_base + pci_addr); - pciinit_offset = 0; - } else { - MIPS_ASSERT( (pci_addr & (swap->config_size - 1)) == 0); - virt_addr = KSEG1ADDR(swap->config_base); - pciinit_offset = pci_addr; - } - - /* set the pmr register */ - option = DDB_PCI_ACCESS_32; - if (bus != 0) option |= DDB_PCI_CFGTYPE1; - ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option); - - return virt_addr; -} - -static inline void ddb_close_config_base(struct pci_config_swap *swap) -{ - ddb_out32(swap->pdar, swap->pdar_backup); - ddb_out32(swap->pmr, swap->pmr_backup); -} - -static int read_config(struct pci_config_swap *swap, - struct pci_bus *bus, - unsigned int devfn, - u32 where, - int size, - u32 *val) -{ - u32 busnum, slot_num, func_num, base, result; - int status - - switch (size) { - case 4: - MIPS_ASSERT((where & 3) == 0); - MIPS_ASSERT(where < (1 << 8)); - - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busnum = bus->number; - MIPS_ASSERT(busnum != 0); - } else { - busnum = 0; - } - - slot_num = PCI_SLOT(devfn); - func_num = PCI_FUNC(devfn); - base = ddb_access_config_base(swap, busnum, slot_num); - *val = *(volatile u32*) (base + (func_num << 8) + where); - ddb_close_config_base(swap); - return PCIBIOS_SUCCESSFUL; - - case 2: - MIPS_ASSERT((where & 1) == 0); - - status = read_config(swap, bus, devfn, where & ~3, 4, - &result); - if (where & 2) result >>= 16; - *val = (u16)(result & 0xffff); - return status; - - case 1: - status = read_config(swap, bus, devfn, where & ~3, 4, - &result); - if (where & 1) result >>= 8; - if (where & 2) result >>= 16; - *val = (u8)(result & 0xff); - return status; - } -} - -static int write_config(struct pci_config_swap *swap, - struct pci_bus *bus, - unsigned int devfn, - u32 where, - int size, - u32 val) -{ - u32 busnum, slot_num, func_num, base, results; - int status, shift = 0; - - switch (size) { - case 4: - MIPS_ASSERT((where & 3) == 0); - MIPS_ASSERT(where < (1 << 8)); - - /* check if the bus is top-level */ - if (bus->parent != NULL) { - busnum = bus->number; - MIPS_ASSERT(busnum != 0); - } else { - busnum = 0; - } - - slot_num = PCI_SLOT(devfn); - func_num = PCI_FUNC(devfn); - base = ddb_access_config_base(swap, busnum, slot_num); - *(volatile u32*) (base + (func_num << 8) + where) = val; - ddb_close_config_base(swap); - return PCIBIOS_SUCCESSFUL; - - case 2: - MIPS_ASSERT((where & 1) == 0); - - status = read_config(swap, bus, devfn, where & ~3, 4, - &result); - if (status != PCIBIOS_SUCCESSFUL) return status; - - if (where & 2) - shift += 16; - result &= ~(0xffff << shift); - result |= (u16)(val << shift); - return write_config(swap, bus, devfn, where & ~3, size, - result); - - case 1: - status = read_config(swap, bus, devfn, where & ~3, 4, - &result); - if (status != PCIBIOS_SUCCESSFUL) return status; - - if (where & 2) - shift += 16; - if (where & 1) - shift += 8; - result &= ~(0xff << shift); - result |= (u8)(val << shift); - return write_config(swap, bus, devfn, where & ~3, size, - result); - } -} - -#define MAKE_PCI_OPS(prefix, rw, pciswap) \ -static int prefix##_##rw##_config(struct pci_bus *bus, unsigned int devfn, \ - int where, int size, u32 val) \ -{ \ - return rw##_config(pciswap, bus, devfn, \ - where, size, val); \ -} - -MAKE_PCI_OPS(extpci, read, &ext_pci_swap) -MAKE_PCI_OPS(extpci, write, &ext_pci_swap) - -MAKE_PCI_OPS(iopci, read, &io_pci_swap) -MAKE_PCI_OPS(iopci, write, &io_pci_swap) - -struct pci_ops ddb5477_ext_pci_ops ={ - .read = extpci_read_config, - .write = extpci_write_config, -}; - - -struct pci_ops ddb5477_io_pci_ops ={ - .read = iopci_read_config, - .write = iopci_write_config, -}; - -#if defined(CONFIG_LL_DEBUG) -void jsun_scan_pci_bus(void) -{ - struct pci_bus bus; - struct pci_dev dev; - unsigned int devfn; - int j; - - bus.parent = NULL; /* we scan the top level only */ - dev.bus = &bus; - dev.sysdata = NULL; - - /* scan ext pci bus and io pci bus*/ - for (j=0; j< 2; j++) { - if (j == 0) { - printk("scan ddb5477 external PCI bus:\n"); - bus.ops = &ddb5477_ext_pci_ops; - } else { - printk("scan ddb5477 IO PCI bus:\n"); - bus.ops = &ddb5477_io_pci_ops; - } - - for (devfn = 0; devfn < 0x100; devfn += 8) { - u32 temp; - u16 temp16; - u8 temp8; - int i; - - dev.devfn = devfn; - MIPS_VERIFY(pci_read_config_dword(&dev, 0, &temp), - == PCIBIOS_SUCCESSFUL); - if (temp == 0xffffffff) continue; - - printk("slot %d: (addr %d) \n", devfn/8, 11+devfn/8); - - /* verify read word and byte */ - MIPS_VERIFY(pci_read_config_word(&dev, 2, &temp16), - == PCIBIOS_SUCCESSFUL); - MIPS_ASSERT(temp16 == (temp >> 16)); - MIPS_VERIFY(pci_read_config_byte(&dev, 3, &temp8), - == PCIBIOS_SUCCESSFUL); - MIPS_ASSERT(temp8 == (temp >> 24)); - MIPS_VERIFY(pci_read_config_byte(&dev, 1, &temp8), - == PCIBIOS_SUCCESSFUL); - MIPS_ASSERT(temp8 == ((temp >> 8) & 0xff)); - - for (i=0; i < 16; i++) { - MIPS_VERIFY(pci_read_config_dword(&dev, i*4, &temp), - == PCIBIOS_SUCCESSFUL); - printk("\t%08X", temp); - if ((i%4) == 3) printk("\n"); - } - } - } -} - - -static void jsun_hardcode_pci_resources_eepro(void) -{ - struct pci_bus bus; - struct pci_dev dev; - u32 temp; - - bus.parent = NULL; /* we scan the top level only */ - bus.ops = &ddb5477_ext_pci_ops; - dev.bus = &bus; - dev.sysdata = NULL; - - /* for slot 5 (ext pci 1) eepro card */ - dev.devfn = 5*8; - pci_read_config_dword(&dev, 0, &temp); - MIPS_ASSERT(temp == 0x12298086); - - pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, DDB_PCI0_MEM_BASE); - pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, 0); - pci_write_config_dword(&dev, PCI_BASE_ADDRESS_2, DDB_PCI0_MEM_BASE+0x100000); - pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 17); -} - -static void jsun_hardcode_pci_resources_onboard_tulip(void) -{ - struct pci_bus bus; - struct pci_dev dev; - u32 temp; - - bus.parent = NULL; /* we scan the top level only */ - bus.ops = &ddb5477_ext_pci_ops; - dev.bus = &bus; - dev.sysdata = NULL; - - /* for slot 4 on board ether chip */ - dev.devfn = 4*8; - pci_read_config_dword(&dev, 0, &temp); - MIPS_ASSERT(temp == 0x00191011); - - pci_write_config_dword(&dev, PCI_BASE_ADDRESS_0, 0x1000); - pci_write_config_dword(&dev, PCI_BASE_ADDRESS_1, DDB_PCI0_MEM_BASE); - pci_write_config_dword(&dev, PCI_INTERRUPT_LINE, 16); -} - -static void jsun_hardcode_pci_resources(void) -{ - jsun_hardcode_pci_resources_onboard_tulip(); -} - -void jsun_assign_pci_resource(void) -{ - jsun_hardcode_pci_resources(); -} - -#endif diff -Nru a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c --- a/arch/mips/ddb5xxx/ddb5477/setup.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/ddb5xxx/ddb5477/setup.c Fri Jun 27 14:20:01 2003 @@ -1,4 +1,4 @@ -/*********************************************************************** +/* * * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net @@ -10,14 +10,10 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. - * - *********************************************************************** */ - #include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/kdev_t.h> #include <linux/types.h> #include <linux/console.h> #include <linux/sched.h> @@ -26,29 +22,35 @@ #include <linux/fs.h> #include <linux/ioport.h> #include <linux/param.h> /* for HZ */ +#include <linux/major.h> +#include <linux/kdev_t.h> #include <linux/root_dev.h> +#include <asm/cpu.h> +#include <asm/bootinfo.h> #include <asm/addrspace.h> #include <asm/time.h> #include <asm/bcache.h> #include <asm/irq.h> #include <asm/reboot.h> #include <asm/gdb-stub.h> +#include <asm/traps.h> +#include <asm/debug.h> +#ifdef CONFIG_PC_KEYB +#include <asm/keyboard.h> +#endif #include <asm/ddb5xxx/ddb5xxx.h> +#include "lcd44780.h" #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ -#ifdef USE_CPU_COUNTER_TIMER -#define CPU_COUNTER_FREQUENCY 83000000 -#else -/* otherwise we use special timer 1 */ -#define SP_TIMER_FREQUENCY 83000000 #define SP_TIMER_BASE DDB_SPT1CTRL_L -#define SP_TIMER_IRQ (8 + 6) -#endif +#define SP_TIMER_IRQ VRC5477_IRQ_SPT1 + +static int bus_frequency = CONFIG_DDB5477_BUS_FREQUENCY*1000; static void ddb_machine_restart(char *command) { @@ -61,7 +63,7 @@ /* CPU cold reset */ t = ddb_in32(DDB_CPUSTAT); - MIPS_ASSERT((t&1)); + db_assert((t&1)); ddb_out32(DDB_CPUSTAT, t); /* Call the PROM */ @@ -81,44 +83,89 @@ } extern void rtc_ds1386_init(unsigned long base); + +static unsigned int __init detect_bus_frequency(unsigned long rtc_base) +{ + unsigned int freq; + unsigned char c; + unsigned int t1, t2; + unsigned i; + + ddb_out32(SP_TIMER_BASE, 0xffffffff); + ddb_out32(SP_TIMER_BASE+4, 0x1); + ddb_out32(SP_TIMER_BASE+8, 0xffffffff); + + /* check if rtc is running */ + c= *(volatile unsigned char*)rtc_base; + for(i=0; (c == *(volatile unsigned char*)rtc_base) && (i<100000000); i++); + if (c == *(volatile unsigned char*)rtc_base) { + printk("Failed to detect bus frequency. Use default 83.3MHz.\n"); + return 83333000; + } + + c= *(volatile unsigned char*)rtc_base; + while (c == *(volatile unsigned char*)rtc_base); + /* we are now at the turn of 1/100th second, if no error. */ + t1 = ddb_in32(SP_TIMER_BASE+8); + + for (i=0; i< 10; i++) { + c= *(volatile unsigned char*)rtc_base; + while (c == *(volatile unsigned char*)rtc_base); + /* we are now at the turn of another 1/100th second */ + t2 = ddb_in32(SP_TIMER_BASE+8); + } + + ddb_out32(SP_TIMER_BASE+4, 0x0); /* disable it again */ + + freq = (t1 - t2)*10; + printk("DDB bus frequency detection : %u \n", freq); + return freq; +} + static void __init ddb_time_init(void) { -#if defined(USE_CPU_COUNTER_TIMER) - mips_counter_frequency = CPU_COUNTER_FREQUENCY; -#endif + unsigned long rtc_base; + unsigned int i; /* we have ds1396 RTC chip */ - rtc_ds1386_init(KSEG1ADDR(DDB_LCS1_BASE)); + if (mips_machtype == MACH_NEC_ROCKHOPPER + || mips_machtype == MACH_NEC_ROCKHOPPERII) { + rtc_base = KSEG1ADDR(DDB_LCS2_BASE); + } else { + rtc_base = KSEG1ADDR(DDB_LCS1_BASE); + } + rtc_ds1386_init(rtc_base); + + /* do we need to do run-time detection of bus speed? */ + if (bus_frequency == 0) { + bus_frequency = detect_bus_frequency(rtc_base); + } + + /* mips_counter_frequency is 1/2 of the cpu core freq */ + i = (read_32bit_cp0_register(CP0_CONFIG) >> 28 ) & 7; + if ((current_cpu_data.cputype == CPU_R5432) && (i == 3)) + i = 4; + mips_counter_frequency = bus_frequency*(i+4)/4; } -#if defined(CONFIG_LL_DEBUG) -int board_init_done_flag = 0; -#endif - extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + static void __init ddb_timer_setup(struct irqaction *irq) { #if defined(USE_CPU_COUNTER_TIMER) unsigned int count; /* we are using the cpu counter for timer interrupts */ - setup_irq(7, irq); - - /* to generate the first timer interrupt */ - count = read_32bit_cp0_register(CP0_COUNT); - write_32bit_cp0_register(CP0_COMPARE, count + 1000); + setup_irq(CPU_IRQ_BASE + 7, irq); #else - /* if we don't use Special purpose timer 1 */ - ddb_out32(SP_TIMER_BASE, SP_TIMER_FREQUENCY/HZ); + /* if we use Special purpose timer 1 */ + ddb_out32(SP_TIMER_BASE, bus_frequency/HZ); ddb_out32(SP_TIMER_BASE+4, 0x1); setup_irq(SP_TIMER_IRQ, irq); #endif - - /* this is the last board dependent code */ - MIPS_DEBUG(board_init_done_flag = 1); } static void ddb5477_board_init(void); @@ -126,14 +173,20 @@ #if defined(CONFIG_BLK_DEV_INITRD) extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end; -#endif +#endif void __init ddb_setup(void) { extern int panic_timeout; +#ifdef CONFIG_BLK_DEV_IDE + extern struct ide_ops std_ide_ops; +#endif + + /* initialize board - we don't trust the loader */ + ddb5477_board_init(); irq_setup = ddb5477_irq_setup; - mips_io_port_base = KSEG1ADDR(DDB_PCI_IO_BASE); + set_io_port_base(KSEG1ADDR(DDB_PCI_IO_BASE)); board_time_init = ddb_time_init; board_timer_setup = ddb_timer_setup; @@ -145,47 +198,69 @@ /* setup resource limits */ ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1; iomem_resource.end = 0xffffffff; - + /* Reboot on panic */ panic_timeout = 180; - /* initialize board - we don't trust the loader */ - ddb5477_board_init(); +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif #if defined(CONFIG_BLK_DEV_INITRD) ROOT_DEV = Root_RAM0; initrd_start = (unsigned long)&__rd_start; initrd_end = (unsigned long)&__rd_end; #endif - } -static void __init ddb5477_board_init() +static void __init ddb5477_board_init(void) { +#ifdef CONFIG_PC_KEYB + extern struct kbd_ops std_kbd_ops; +#endif /* ----------- setup PDARs ------------ */ /* SDRAM should have been set */ - MIPS_ASSERT(ddb_in32(DDB_SDRAM0) == - ddb_calc_pdar(DDB_SDRAM_BASE, DDB_SDRAM_SIZE, 32, 0, 1)); + db_assert(ddb_in32(DDB_SDRAM0) == + ddb_calc_pdar(DDB_SDRAM_BASE, board_ram_size, 32, 0, 1)); /* SDRAM1 should be turned off. What is this for anyway ? */ - MIPS_ASSERT( (ddb_in32(DDB_SDRAM1) & 0xf) == 0); + db_assert( (ddb_in32(DDB_SDRAM1) & 0xf) == 0); - /* Set LDCSs */ - /* flash */ + /* Setup local bus. */ + + /* Flash U12 PDAR and timing. */ ddb_set_pdar(DDB_LCS0, DDB_LCS0_BASE, DDB_LCS0_SIZE, 16, 0, 0); - /* misc */ - ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 8, 0, 0); - /* mezzanie (?) */ - ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 16, 0, 0); + ddb_out32(DDB_LCST0, 0x00090842); + + /* We need to setup LCS1 and LCS2 differently based on the + board_version */ + if (mips_machtype == MACH_NEC_ROCKHOPPER) { + /* Flash U13 PDAR and timing. */ + ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 16, 0, 0); + ddb_out32(DDB_LCST1, 0x00090842); + + /* EPLD (NVRAM, switch, LCD, and mezzanie). */ + ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 8, 0, 0); + } else { + /* misc */ + ddb_set_pdar(DDB_LCS1, DDB_LCS1_BASE, DDB_LCS1_SIZE, 8, 0, 0); + /* mezzanie (?) */ + ddb_set_pdar(DDB_LCS2, DDB_LCS2_BASE, DDB_LCS2_SIZE, 16, 0, 0); + } /* verify VRC5477 base addr */ - MIPS_ASSERT(ddb_in32(DDB_VRC5477) == - ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1)); - + db_assert(ddb_in32(DDB_VRC5477) == + ddb_calc_pdar(DDB_VRC5477_BASE, DDB_VRC5477_SIZE, 32, 0, 1)); + /* verify BOOT ROM addr */ - MIPS_ASSERT(ddb_in32(DDB_BOOTCS) == - ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0)); + db_assert(ddb_in32(DDB_BOOTCS) == + ddb_calc_pdar(DDB_BOOTCS_BASE, DDB_BOOTCS_SIZE, 8, 0, 0)); /* setup PCI windows - window0 for MEM/config, window1 for IO */ ddb_set_pdar(DDB_PCIW0, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1); @@ -219,7 +294,7 @@ ddb_out32(DDB_BAR51, 0xffffffff); ddb_out32(DDB_BARB1, 0xffffffff); - /* + /* * We use pci master register 0 for memory space / config space * And we use register 1 for IO space. * Note that for memory space, we bump up the pci base address @@ -227,26 +302,133 @@ * For PCI IO space, it starts from 0 in PCI IO space but with * DDB_xx_IO_BASE in CPU physical address space. */ - ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE, + ddb_set_pmr(DDB_PCIINIT00, DDB_PCICMD_MEM, DDB_PCI0_MEM_BASE, DDB_PCI_ACCESS_32); ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IO, 0, DDB_PCI_ACCESS_32); - ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE, + ddb_set_pmr(DDB_PCIINIT01, DDB_PCICMD_MEM, DDB_PCI1_MEM_BASE, DDB_PCI_ACCESS_32); - ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE, + ddb_set_pmr(DDB_PCIINIT11, DDB_PCICMD_IO, DDB_PCI0_IO_SIZE, DDB_PCI_ACCESS_32); - + /* PCI cross window should be set properly */ ddb_set_pdar(DDB_BARP00, DDB_PCI1_MEM_BASE, DDB_PCI1_MEM_SIZE, 32, 0, 1); ddb_set_pdar(DDB_BARP10, DDB_PCI1_IO_BASE, DDB_PCI1_IO_SIZE, 32, 0, 1); ddb_set_pdar(DDB_BARP01, DDB_PCI0_MEM_BASE, DDB_PCI0_MEM_SIZE, 32, 0, 1); ddb_set_pdar(DDB_BARP11, DDB_PCI0_IO_BASE, DDB_PCI0_IO_SIZE, 32, 0, 1); + if (mips_machtype == MACH_NEC_ROCKHOPPER + || mips_machtype == MACH_NEC_ROCKHOPPERII) { + /* Disable bus diagnostics. */ + ddb_out32(DDB_PCICTL0_L, 0); + ddb_out32(DDB_PCICTL0_H, 0); + ddb_out32(DDB_PCICTL1_L, 0); + ddb_out32(DDB_PCICTL1_H, 0); + } + + if (mips_machtype == MACH_NEC_ROCKHOPPER) { + u16 vid; + struct pci_bus bus; + struct pci_dev dev_m1533; + extern struct pci_ops ddb5477_ext_pci_ops; + + bus.parent = NULL; /* we scan the top level only */ + bus.ops = &ddb5477_ext_pci_ops; + dev_m1533.bus = &bus; + dev_m1533.sysdata = NULL; + dev_m1533.devfn = 7*8; // slot 7: M1533 SouthBridge. + pci_read_config_word(&dev_m1533, 0, &vid); + if (vid == PCI_VENDOR_ID_AL) { + printk("Changing mips_machtype to MACH_NEC_ROCKHOPPERII\n"); + mips_machtype = MACH_NEC_ROCKHOPPERII; + } + } + /* enable USB input buffers */ ddb_out32(DDB_PIBMISC, 0x00000007); /* For dual-function pins, make them all non-GPIO */ ddb_out32(DDB_GIUFUNSEL, 0x0); // ddb_out32(DDB_GIUFUNSEL, 0xfe0fcfff); /* NEC recommanded value */ + + if (mips_machtype == MACH_NEC_ROCKHOPPERII) { +#ifdef CONFIG_PC_KEYB + printk("kdb_ops is std\n"); + kbd_ops = &std_kbd_ops; +#endif + } + + if (mips_machtype == MACH_NEC_ROCKHOPPERII) { + + /* enable IDE controller on Ali chip (south bridge) */ + u8 temp8; + struct pci_bus bus; + struct pci_dev dev_m1533; + struct pci_dev dev_m5229; + extern struct pci_ops ddb5477_ext_pci_ops; + + /* Setup M1535 registers */ + bus.parent = NULL; /* we scan the top level only */ + bus.ops = &ddb5477_ext_pci_ops; + dev_m1533.bus = &bus; + dev_m1533.sysdata = NULL; + dev_m1533.devfn = 7*8; // slot 7: M1533 SouthBridge. + + /* setup IDE controller + * enable IDE controller (bit 6 - 1) + * IDE IDSEL to be addr:A15 (bit 4:5 - 11) + * disable IDE ATA Secondary Bus Signal Pad Control (bit 3 - 0) + * enable IDE ATA Primary Bus Signal Pad Control (bit 2 - 1) + */ + pci_write_config_byte(&dev_m1533, 0x58, 0x74); + + /* + * positive decode (bit6 -0) + * enable IDE controler interrupt (bit 4 -1) + * setup SIRQ to point to IRQ 14 (bit 3:0 - 1101) + */ + pci_write_config_byte(&dev_m1533, 0x44, 0x1d); + + /* Setup M5229 registers */ + dev_m5229.bus = &bus; + dev_m5229.sysdata = NULL; + dev_m5229.devfn = 4*8; // slot 4 (AD15): M5229 IDE + + /* + * enable IDE in the M5229 config register 0x50 (bit 0 - 1) + * M5229 IDSEL is addr:15; see above setting + */ + pci_read_config_byte(&dev_m5229, 0x50, &temp8); + pci_write_config_byte(&dev_m5229, 0x50, temp8 | 0x1); + + /* + * enable bus master (bit 2) and IO decoding (bit 0) + */ + pci_read_config_byte(&dev_m5229, 0x04, &temp8); + pci_write_config_byte(&dev_m5229, 0x04, temp8 | 0x5); + + /* + * enable native, copied from arch/ppc/k2boot/head.S + * TODO - need volatile, need to be portable + */ + pci_write_config_byte(&dev_m5229, 0x09, 0xef); + + /* Set Primary Channel Command Block Timing */ + pci_write_config_byte(&dev_m5229, 0x59, 0x31); + + /* + * Enable primary channel 40-pin cable + * M5229 register 0x4a (bit 0) + */ + pci_read_config_byte(&dev_m5229, 0x4a, &temp8); + pci_write_config_byte(&dev_m5229, 0x4a, temp8 | 0x1); + } + + if (mips_machtype == MACH_NEC_ROCKHOPPER + || mips_machtype == MACH_NEC_ROCKHOPPERII) { + printk("lcd44780: initializing\n"); + lcd44780_init(); + lcd44780_puts("MontaVista Linux"); + } } diff -Nru a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile --- a/arch/mips/dec/Makefile Fri Jun 27 14:19:54 2003 +++ b/arch/mips/dec/Makefile Fri Jun 27 14:19:54 2003 @@ -2,6 +2,10 @@ # Makefile for the DECstation family specific parts of the kernel # -obj-y := int-handler.o setup.o irq.o time.o reset.o rtc-dec.o wbflush.o +obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn02-irq.o reset.o \ + rtc-dec.o setup.o time.o obj-$(CONFIG_PROM_CONSOLE) += promcon.o +obj-$(CONFIG_CPU_HAS_WB) += wbflush.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/dec/boot/Makefile b/arch/mips/dec/boot/Makefile --- a/arch/mips/dec/boot/Makefile Fri Jun 27 14:19:57 2003 +++ b/arch/mips/dec/boot/Makefile Fri Jun 27 14:19:57 2003 @@ -3,8 +3,8 @@ # netboot: all - mipsel-linux-ld -N -G 0 -T ld.ecoff ../../boot/zImage \ - built-in.o ramdisk.img -o nbImage + $(LD) -N -G 0 -T ld.ecoff ../../boot/zImage \ + dec_boot.o ramdisk.img -o nbImage obj-y := decstation.o diff -Nru a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/dec/ecc-berr.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,280 @@ +/* + * linux/arch/mips/dec/ecc-berr.c + * + * Bus error event handling code for systems equipped with ECC + * handling logic, i.e. DECstation/DECsystem 5000/200 (KN02), + * 5000/240 (KN03), 5000/260 (KN05) and DECsystem 5900 (KN03), + * 5900/260 (KN05) systems. + * + * Copyright (c) 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <asm/traps.h> + +#include <asm/dec/ecc.h> +#include <asm/dec/kn02.h> +#include <asm/dec/kn03.h> +#include <asm/dec/kn05.h> + +static volatile u32 *kn0x_erraddr; +static volatile u32 *kn0x_chksyn; + +static inline void dec_ecc_be_ack(void) +{ + *kn0x_erraddr = 0; /* any write clears the IRQ */ + iob(); +} + +static int dec_ecc_be_backend(struct pt_regs *regs, int is_fixup, int invoker) +{ + static const char excstr[] = "exception"; + static const char intstr[] = "interrupt"; + static const char cpustr[] = "CPU"; + static const char dmastr[] = "DMA"; + static const char readstr[] = "read"; + static const char mreadstr[] = "memory read"; + static const char writestr[] = "write"; + static const char mwritstr[] = "partial memory write"; + static const char timestr[] = "timeout"; + static const char overstr[] = "overrun"; + static const char eccstr[] = "ECC error"; + + const char *kind, *agent, *cycle, *event; + const char *status = "", *xbit = "", *fmt = ""; + dma_addr_t address; + u16 syn = 0, sngl; + + int i = 0; + + u32 erraddr = *kn0x_erraddr; + u32 chksyn = *kn0x_chksyn; + int action = MIPS_BE_FATAL; + + /* For non-ECC ack ASAP, so any subsequent errors get caught. */ + if ((erraddr & (KN0X_EAR_VALID | KN0X_EAR_ECCERR)) == KN0X_EAR_VALID) + dec_ecc_be_ack(); + + kind = invoker ? intstr : excstr; + + if (!(erraddr & KN0X_EAR_VALID)) { + /* No idea what happened. */ + printk(KERN_ALERT "Unindentified bus error %s.\n", kind); + return action; + } + + agent = (erraddr & KN0X_EAR_CPU) ? cpustr : dmastr; + + if (erraddr & KN0X_EAR_ECCERR) { + /* An ECC error on a CPU or DMA transaction. */ + cycle = (erraddr & KN0X_EAR_WRITE) ? mwritstr : mreadstr; + event = eccstr; + } else { + /* A CPU timeout or a DMA overrun. */ + cycle = (erraddr & KN0X_EAR_WRITE) ? writestr : readstr; + event = (erraddr & KN0X_EAR_CPU) ? timestr : overstr; + } + + address = erraddr & KN0X_EAR_ADDRESS; + /* For ECC errors on reads adjust for MT pipelining. */ + if ((erraddr & (KN0X_EAR_WRITE | KN0X_EAR_ECCERR)) == KN0X_EAR_ECCERR) + address = (address & ~0xfffLL) | ((address - 5) & 0xfffLL); + address <<= 2; + + /* Only CPU errors are fixable. */ + if (erraddr & KN0X_EAR_CPU && is_fixup) + action = MIPS_BE_FIXUP; + + if (erraddr & KN0X_EAR_ECCERR) { + static const u8 data_sbit[32] = { + 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, + 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34, + 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, + 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75, + }; + static const u8 data_mbit[25] = { + 0x07, 0x0d, 0x1f, + 0x2f, 0x32, 0x37, 0x38, 0x3b, 0x3d, 0x3e, + 0x43, 0x45, 0x46, 0x49, 0x4c, 0x51, 0x5e, + 0x61, 0x6e, 0x73, 0x76, 0x79, 0x7a, 0x7c, 0x7f, + }; + static const char sbestr[] = "corrected single"; + static const char dbestr[] = "uncorrectable double"; + static const char mbestr[] = "uncorrectable multiple"; + + if (!(address & 0x4)) + syn = chksyn; /* Low bank. */ + else + syn = chksyn >> 16; /* High bank. */ + + if (!(syn & KN0X_ESR_VLDLO)) { + /* Ack now, no rewrite will happen. */ + dec_ecc_be_ack(); + + fmt = KERN_ALERT "%s" "invalid.\n"; + } else { + sngl = syn & KN0X_ESR_SNGLO; + syn &= KN0X_ESR_SYNLO; + + /* + * Multibit errors may be tagged incorrectly; + * check the syndrome explicitly. + */ + for (i = 0; i < 25; i++) + if (syn == data_mbit[i]) + break; + + if (i < 25) { + status = mbestr; + } else if (!sngl) { + status = dbestr; + } else { + volatile u32 *ptr = (void *)KSEG1ADDR(address); + + *ptr = *ptr; /* Rewrite. */ + iob(); + + status = sbestr; + action = MIPS_BE_DISCARD; + } + + /* Ack now, now we've rewritten (or not). */ + dec_ecc_be_ack(); + + if (syn && syn == (syn & -syn)) { + if (syn == 0x01) { + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error " + "at check bit C%s.\n"; + xbit = "X"; + } else { + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error " + "at check bit C%s%u.\n"; + } + i = syn >> 2; + } else { + for (i = 0; i < 32; i++) + if (syn == data_sbit[i]) + break; + if (i < 32) + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error " + "at data bit D%s%u.\n"; + else + fmt = KERN_ALERT "%s" + "%#04x -- %s bit error.\n"; + } + } + } + + if (action != MIPS_BE_FIXUP) + printk(KERN_ALERT "Bus error %s: %s %s %s at %#010lx.\n", + kind, agent, cycle, event, address); + + if (action != MIPS_BE_FIXUP && erraddr & KN0X_EAR_ECCERR) + printk(fmt, " ECC syndrome ", syn, status, xbit, i); + + return action; +} + +int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup) +{ + return dec_ecc_be_backend(regs, is_fixup, 0); +} + +void dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int action = dec_ecc_be_backend(regs, 0, 1); + + if (action == MIPS_BE_DISCARD) + return; + + /* + * FIXME: Find affected processes and kill them, otherwise we + * must die. + * + * The interrupt is asynchronously delivered thus EPC and RA + * may be irrelevant, but are printed for a reference. + */ + printk(KERN_ALERT "Fatal bus interrupt, epc == %08lx, ra == %08lx\n", + regs->cp0_epc, regs->regs[31]); + die("Unrecoverable bus error", regs); +} + + +/* + * Initialization differs a bit between KN02 and KN03/KN05, so we + * need two variants. Once set up, all systems can be handled the + * same way. + */ +static inline void dec_kn02_be_init(void) +{ + volatile u32 *csr = (void *)KN02_CSR_BASE; + unsigned long flags; + + kn0x_erraddr = (void *)(KN02_SLOT_BASE + KN02_ERRADDR); + kn0x_chksyn = (void *)(KN02_SLOT_BASE + KN02_CHKSYN); + + spin_lock_irqsave(&kn02_lock, flags); + + /* Preset write-only bits of the Control Register cache. */ + cached_kn02_csr = *csr | KN03_CSR_LEDS; + + /* Set normal ECC detection and generation. */ + cached_kn02_csr &= ~(KN02_CSR_DIAGCHK | KN02_CSR_DIAGGEN); + /* Enable ECC correction. */ + cached_kn02_csr |= KN02_CSR_CORRECT; + *csr = cached_kn02_csr; + iob(); + + spin_unlock_irqrestore(&kn02_lock, flags); +} + +static inline void dec_kn03_be_init(void) +{ + volatile u32 *mcr = (void *)(KN03_SLOT_BASE + IOASIC_MCR); + volatile u32 *mbcs = (void *)(KN03_SLOT_BASE + KN05_MB_CSR); + + kn0x_erraddr = (void *)(KN03_SLOT_BASE + IOASIC_ERRADDR); + kn0x_chksyn = (void *)(KN03_SLOT_BASE + IOASIC_CHKSYN); + + /* + * Set normal ECC detection and generation, enable ECC correction. + * For KN05 we also need to make sure EE (?) is enabled in the MB. + * Otherwise DBE/IBE exceptions would be masked but bus error + * interrupts would still arrive, resulting in an inevitable crash + * if get_dbe() triggers one. + */ + *mcr = (*mcr & ~(KN03_MCR_DIAGCHK | KN03_MCR_DIAGGEN)) | + KN03_MCR_CORRECT; + if (current_cpu_data.cputype == CPU_R4400SC) + *mbcs |= KN05_MB_CSR_EE; + fast_iob(); +} + +void __init dec_ecc_be_init(void) +{ + if (mips_machtype == MACH_DS5000_200) + dec_kn02_be_init(); + else + dec_kn03_be_init(); + + /* Clear any leftover errors from the firmware. */ + dec_ecc_be_ack(); +} diff -Nru a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S --- a/arch/mips/dec/int-handler.S Fri Jun 27 14:19:59 2003 +++ b/arch/mips/dec/int-handler.S Fri Jun 27 14:19:59 2003 @@ -2,7 +2,7 @@ * arch/mips/dec/int-handler.S * * Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen - * Copyright (C) 2000 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki * * Written by Ralf Baechle and Andreas Busse, modified for DECStation * support by Paul Antoine and Harald Koerfgen. @@ -10,6 +10,8 @@ * completly rewritten: * Copyright (C) 1998 Harald Koerfgen * + * Rewritten extensively for controller-driven IRQ support + * by Maciej W. Rozycki. */ #include <asm/asm.h> #include <asm/regdef.h> @@ -17,12 +19,13 @@ #include <asm/stackframe.h> #include <asm/addrspace.h> +#include <asm/dec/interrupts.h> +#include <asm/dec/ioasic_addrs.h> +#include <asm/dec/ioasic_ints.h> #include <asm/dec/kn01.h> #include <asm/dec/kn02.h> #include <asm/dec/kn02xa.h> #include <asm/dec/kn03.h> -#include <asm/dec/ioasic_addrs.h> -#include <asm/dec/interrupts.h> .text @@ -84,7 +87,7 @@ * 4 TurboChannel Slot 2 * 5 TurboChannel Slot 3 (ASIC) * 6 Halt button - * 7 FPU + * 7 FPU/R4k timer * * DS5000/2x's, aka kn02ca, aka maxine: * @@ -97,7 +100,7 @@ * 4 I/O write timeout * 5 TurboChannel (ASIC) * 6 Halt Keycode from Access.Bus keyboard (CTRL-ALT-ENTER) - * 7 FPU + * 7 FPU/R4k timer * * DS5000/2xx's, aka kn03, aka 3maxplus: * @@ -110,22 +113,11 @@ * 4 Reserved * 5 Memory * 6 Halt Button - * 7 FPU - * - * We handle the IRQ according to _our_ priority. - * Priority is: - * - * Highest ---- RTC - * SCSI (if separate from TC) - * Ethernet (if separate from TC) - * Serial (if separate from TC) - * TurboChannel (if there is one!) - * Memory Controller (execept kmin) - * Lowest ---- Halt (if there is one!) - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. + * 7 FPU/R4k timer * + * We handle the IRQ according to _our_ priority (see setup.c), + * then we just return. If multiple IRQs are pending then we will + * just take another exception, big deal. */ .align 5 NESTED(decstation_handle_int, PT_SIZE, ra) @@ -139,226 +131,166 @@ * Get pending Interrupts */ mfc0 t0,CP0_CAUSE # get pending interrupts - mfc0 t2,CP0_STATUS - la t1,cpu_mask_tbl - and t0,t2 # isolate allowed ones + mfc0 t1,CP0_STATUS +#ifdef CONFIG_MIPS32 + lw t2,cpu_fpu_mask +#endif + andi t0,ST0_IM # CAUSE.CE may be non-zero! + and t0,t1 # isolate allowed ones beqz t0,spurious +#ifdef CONFIG_MIPS32 + and t2,t0 + bnez t2,fpu # handle FPU immediately +#endif + /* * Find irq with highest priority */ -1: lw t2,(t1) - move t3,t0 - and t3,t2 - beq t3,zero,1b - addu t1,PTRSIZE # delay slot + PTR_LA t1,cpu_mask_nr_tbl +1: lw t2,(t1) + nop + and t2,t0 + beqz t2,1b + addu t1,2*PTRSIZE # delay slot /* * Do the low-level stuff */ - lw a0,%lo(cpu_irq_nr-cpu_mask_tbl-PTRSIZE)(t1) - lw t0,%lo(cpu_ivec_tbl-cpu_mask_tbl-PTRSIZE)(t1) - bgez a0, handle_it # irq_nr >= 0? - # irq_nr < 0: t0 contains an address + lw a0,(-PTRSIZE)(t1) + nop + bgez a0,handle_it # irq_nr >= 0? + # irq_nr < 0: it is an address nop - jr t0 - nop # delay slot + jr a0 + # a trick to save a branch: + lui t2,(KN03_IOASIC_BASE>>16)&0xffff + # upper part of IOASIC Address /* * Handle "IRQ Controller" Interrupts * Masked Interrupts are still visible and have to be masked "by hand". */ - EXPORT(kn02_io_int) -kn02_io_int: # 3max - lui t0,KN02_CSR_ADDR>>16 # get interrupt status and mask + FEXPORT(kn02_io_int) # 3max + lui t0,(KN02_CSR_BASE>>16)&0xffff + # get interrupt status and mask lw t0,(t0) - la t1,asic_mask_tbl - move t3,t0 - sll t3,16 # shift interrupt status - b find_int - and t0,t3 # mask out allowed ones - - EXPORT(kn03_io_int) -kn03_io_int: # 3max+ - lui t2,KN03_IOASIC_BASE>>16 # upper part of IOASIC Address - lw t0,SIR(t2) # get status: IOASIC isr - lw t3,SIMR(t2) # get mask: IOASIC isrm - la t1,asic_mask_tbl - b find_int - and t0,t3 # mask out allowed ones - - EXPORT(kn02xa_io_int) -kn02xa_io_int: # 3min/maxine - lui t2,KN02XA_IOASIC_BASE>>16 + nop + andi t1,t0,KN02_IRQ_ALL + b 1f + srl t0,16 # shift interrupt mask + + FEXPORT(kn02xa_io_int) # 3min/maxine + lui t2,(KN02XA_IOASIC_BASE>>16)&0xffff # upper part of IOASIC Address - lw t0,SIR(t2) # get status: IOASIC isr - lw t3,SIMR(t2) # get mask: IOASIC isrm - la t1,asic_mask_tbl - and t0,t3 + + FEXPORT(kn03_io_int) # 3max+ (t2 loaded earlier) + lw t0,IO_REG_SIR(t2) # get status: IOASIC sir + lw t1,IO_REG_SIMR(t2) # get mask: IOASIC simr + nop + +1: and t0,t1 # mask out allowed ones + + beqz t0,spurious /* * Find irq with highest priority */ -find_int: beqz t0,spurious - -1: lw t2,(t1) - move t3,t0 - and t3,t2 - beq zero,t3,1b - addu t1,PTRSIZE # delay slot + PTR_LA t1,asic_mask_nr_tbl +2: lw t2,(t1) + nop + and t2,t0 + beq zero,t2,2b + addu t1,2*PTRSIZE # delay slot /* * Do the low-level stuff */ - lw a0,%lo(asic_irq_nr-asic_mask_tbl-PTRSIZE)(t1) - nop + lw a0,%lo(-PTRSIZE)(t1) + nop + bgez a0,handle_it # irq_nr >= 0? + # irq_nr < 0: it is an address + nop + jr a0 + nop # delay slot + +/* + * Dispatch low-priority interrupts. We reconsider all status + * bits again, which looks like a lose, but it makes the code + * simple and O(log n), so it gets compensated. + */ + FEXPORT(cpu_all_int) # HALT, timers, software junk + li a0,DEC_CPU_IRQ_BASE + srl t0,CAUSEB_IP + li t1,CAUSEF_IP>>CAUSEB_IP # mask + b 1f + li t2,4 # nr of bits / 2 + + FEXPORT(kn02_all_int) # impossible ? + li a0,KN02_IRQ_BASE + li t1,KN02_IRQ_ALL # mask + b 1f + li t2,4 # nr of bits / 2 + + FEXPORT(asic_all_int) # various I/O ASIC junk + li a0,IO_IRQ_BASE + li t1,IO_IRQ_ALL # mask + b 1f + li t2,8 # nr of bits / 2 + +/* + * Dispatch DMA interrupts -- O(log n). + */ + FEXPORT(asic_dma_int) # I/O ASIC DMA events + li a0,IO_IRQ_BASE+IO_INR_DMA + srl t0,IO_INR_DMA + li t1,IO_IRQ_DMA>>IO_INR_DMA # mask + li t2,8 # nr of bits / 2 + + /* + * Find irq with highest priority. + * Highest irq number takes precedence. + */ +1: srlv t3,t1,t2 +2: xor t1,t3 + and t3,t0,t1 + beqz t3,3f + nop + move t0,t3 + addu a0,t2 +3: srl t2,1 + bnez t2,2b + srlv t3,t1,t2 -handle_it: jal do_IRQ +handle_it: + jal do_IRQ move a1,sp + j ret_from_irq nop +#ifdef CONFIG_MIPS32 +fpu: + j handle_fpe_int + nop +#endif + spurious: j spurious_interrupt nop END(decstation_handle_int) -/* - * Interrupt routines common to all DECStations first. - */ - EXPORT(dec_intr_fpu) -dec_intr_fpu: PANIC("Unimplemented FPU interrupt handler") /* - * Generic unimplemented interrupt routines - ivec_tbl is initialised to - * point all interrupts here. The table is then filled in by machine-specific - * initialisation in dec_setup(). + * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl + * and asic_mask_nr_tbl are initialized to point all interrupts here. + * The tables are then filled in by machine-specific initialisation + * in dec_setup(). */ - EXPORT(dec_intr_unimplemented) -dec_intr_unimplemented: - mfc0 a1,CP0_CAUSE # cheats way of printing an arg! - nop # to be sure... - PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%x"); - - EXPORT(asic_intr_unimplemented) -asic_intr_unimplemented: + FEXPORT(dec_intr_unimplemented) move a1,t0 # cheats way of printing an arg! - PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%x"); + PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x"); -/* - * FIXME: This interrupt vector table is experimental. It is initialised with - * *_intr_unimplemented and filled in with the addresses of - * machine-specific interrupt routines in dec_setup() Paul 10/5/97. - * - * The mask_tbls contain the interrupt masks which are used. It is - * initialised with all possible interrupt status bits set, so that - * unused Interrupts are catched. Harald - */ - .data - EXPORT(cpu_mask_tbl) -cpu_mask_tbl: - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 # these two are unlikely - .word 0x00000000 # to be used - .word 0x0000ff00 # End of list - - EXPORT(cpu_irq_nr) -cpu_irq_nr: - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 - .word 0x00000000 # these two are unlikely - .word 0x00000000 # to be used - .word 0x00ffffff # End of list - - EXPORT(cpu_ivec_tbl) -cpu_ivec_tbl: - PTR dec_intr_unimplemented - PTR dec_intr_unimplemented - PTR dec_intr_unimplemented - PTR dec_intr_unimplemented - PTR dec_intr_unimplemented - PTR dec_intr_unimplemented - PTR dec_intr_unimplemented # these two are unlikely - PTR dec_intr_unimplemented # to be used - PTR dec_intr_unimplemented # EOL - - EXPORT(asic_mask_tbl) -asic_mask_tbl: - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0xffffffff # EOL - - EXPORT(asic_irq_nr) -asic_irq_nr: - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0 - .word 0xffffffff # EOL + FEXPORT(asic_intr_unimplemented) + move a1,t0 # cheats way of printing an arg! + PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x"); diff -Nru a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/dec/ioasic-irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,157 @@ +/* + * linux/arch/mips/dec/ioasic-irq.c + * + * DEC I/O ASIC interrupts. + * + * Copyright (c) 2002, 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <asm/dec/ioasic.h> +#include <asm/dec/ioasic_addrs.h> +#include <asm/dec/ioasic_ints.h> + + +static spinlock_t ioasic_lock = SPIN_LOCK_UNLOCKED; + +static int ioasic_irq_base; + + +static inline void unmask_ioasic_irq(unsigned int irq) +{ + u32 simr; + + simr = ioasic_read(IO_REG_SIMR); + simr |= (1 << (irq - ioasic_irq_base)); + ioasic_write(IO_REG_SIMR, simr); +} + +static inline void mask_ioasic_irq(unsigned int irq) +{ + u32 simr; + + simr = ioasic_read(IO_REG_SIMR); + simr &= ~(1 << (irq - ioasic_irq_base)); + ioasic_write(IO_REG_SIMR, simr); +} + +static inline void clear_ioasic_irq(unsigned int irq) +{ + u32 sir; + + sir = ~(1 << (irq - ioasic_irq_base)); + ioasic_write(IO_REG_SIR, sir); +} + +static inline void enable_ioasic_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&ioasic_lock, flags); + unmask_ioasic_irq(irq); + spin_unlock_irqrestore(&ioasic_lock, flags); +} + +static inline void disable_ioasic_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&ioasic_lock, flags); + mask_ioasic_irq(irq); + spin_unlock_irqrestore(&ioasic_lock, flags); +} + + +static inline unsigned int startup_ioasic_irq(unsigned int irq) +{ + enable_ioasic_irq(irq); + return 0; +} + +#define shutdown_ioasic_irq disable_ioasic_irq + +static inline void ack_ioasic_irq(unsigned int irq) +{ + spin_lock(&ioasic_lock); + mask_ioasic_irq(irq); + spin_unlock(&ioasic_lock); + fast_iob(); +} + +static inline void end_ioasic_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_ioasic_irq(irq); +} + +static struct hw_interrupt_type ioasic_irq_type = { + .typename = "IO-ASIC", + .startup = startup_ioasic_irq, + .shutdown = shutdown_ioasic_irq, + .enable = enable_ioasic_irq, + .disable = disable_ioasic_irq, + .ack = ack_ioasic_irq, + .end = end_ioasic_irq, +}; + + +#define startup_ioasic_dma_irq startup_ioasic_irq + +#define shutdown_ioasic_dma_irq shutdown_ioasic_irq + +#define enable_ioasic_dma_irq enable_ioasic_irq + +#define disable_ioasic_dma_irq disable_ioasic_irq + +#define ack_ioasic_dma_irq ack_ioasic_irq + +static inline void end_ioasic_dma_irq(unsigned int irq) +{ + clear_ioasic_irq(irq); + fast_iob(); + end_ioasic_irq(irq); +} + +static struct hw_interrupt_type ioasic_dma_irq_type = { + .typename = "IO-ASIC-DMA", + .startup = startup_ioasic_dma_irq, + .shutdown = shutdown_ioasic_dma_irq, + .enable = enable_ioasic_dma_irq, + .disable = disable_ioasic_dma_irq, + .ack = ack_ioasic_dma_irq, + .end = end_ioasic_dma_irq, +}; + + +void __init init_ioasic_irqs(int base) +{ + int i; + + /* Mask interrupts. */ + ioasic_write(IO_REG_SIMR, 0); + fast_iob(); + + for (i = base; i < base + IO_INR_DMA; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &ioasic_irq_type; + } + for (; i < base + IO_IRQ_LINES; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &ioasic_dma_irq_type; + } + + ioasic_irq_base = base; +} diff -Nru a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c --- a/arch/mips/dec/irq.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,302 +0,0 @@ -/* - * Code to handle DECstation IRQs plus some generic interrupt stuff. - * - * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997, 2000 Ralf Baechle - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/seq_file.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/mipsregs.h> -#include <asm/system.h> - -#include <asm/dec/interrupts.h> - -extern void dec_init_kn01(void); -extern void dec_init_kn230(void); -extern void dec_init_kn02(void); -extern void dec_init_kn02ba(void); -extern void dec_init_kn02ca(void); -extern void dec_init_kn03(void); - -extern asmlinkage void decstation_handle_int(void); - -unsigned long spurious_count = 0; - -static inline void mask_irq(unsigned int irq_nr) -{ - unsigned int dummy; - - if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC interrupt */ - *imr &= ~dec_interrupt[irq_nr].iemask; - dummy = *imr; - dummy = *imr; - } else /* This is a cpu interrupt */ - change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) & ~dec_interrupt[irq_nr].cpu_mask); -} - -static inline void unmask_irq(unsigned int irq_nr) -{ - unsigned int dummy; - - if (dec_interrupt[irq_nr].iemask) { /* This is an ASIC interrupt */ - *imr |= dec_interrupt[irq_nr].iemask; - dummy = *imr; - dummy = *imr; - } - change_cp0_status(ST0_IM, read_32bit_cp0_register(CP0_STATUS) | dec_interrupt[irq_nr].cpu_mask); -} - -void disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - mask_irq(irq_nr); - restore_flags(flags); -} - -void enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - unmask_irq(irq_nr); - restore_flags(flags); -} - -/* - * Pointers to the low-level handlers: first the general ones, then the - * fast ones, then the bad ones. - */ -extern void interrupt(void); - -static struct irqaction *irq_action[32] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - struct irqaction *action; - unsigned long flags; - - for (i = 0; i < 32; i++) { - local_irq_save(flags); - action = irq_action[i]; - if (!action) - goto skip; - seq_printf(p, "%2d: %8d %c %s", - i, kstat_cpu(0).irqs[i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action = action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_putc(p, '\n'); -skip: - local_irq_restore(flags); - } - return 0; -} - -/* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. - */ -asmlinkage void do_IRQ(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat_cpu(cpu).irqs[irq]++; - - mask_irq(irq); - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - local_irq_disable(); - unmask_irq(irq); - } - irq_exit(cpu, irq); - - /* unmasking and bottom half handling is done magically for us. */ -} - -/* - * Idea is to put all interrupts - * in a single table and differenciate them just by number. - */ -int setup_dec_irq(int irq, struct irqaction *new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; - - p = irq_action + irq; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - return -EBUSY; - - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_and_cli(flags); - *p = new; - - if (!shared) { - unmask_irq(irq); - } - restore_flags(flags); - return 0; -} - -int request_irq(unsigned int irq, - void (*handler) (int, void *, struct pt_regs *), - unsigned long irqflags, - const char *devname, - void *dev_id) -{ - int retval; - struct irqaction *action; - - if (irq >= 32) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - retval = setup_dec_irq(irq, action); - - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *action, **p; - unsigned long flags; - - if (irq > 39) { - printk("Trying to free IRQ%d\n", irq); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - if (!irq[irq_action]) - mask_irq(irq); - restore_flags(flags); - kfree(action); - return; - } - printk("Trying to free free IRQ%d\n", irq); -} - -unsigned long probe_irq_on(void) -{ - /* TODO */ - return 0; -} - -int probe_irq_off(unsigned long irqs) -{ - /* TODO */ - return 0; -} - -void __init init_IRQ(void) -{ - switch (mips_machtype) { - case MACH_DS23100: - dec_init_kn01(); - break; - case MACH_DS5100: /* DS5100 MIPSMATE */ - dec_init_kn230(); - break; - case MACH_DS5000_200: /* DS5000 3max */ - dec_init_kn02(); - break; - case MACH_DS5000_1XX: /* DS5000/100 3min */ - dec_init_kn02ba(); - break; - case MACH_DS5000_2X0: /* DS5000/240 3max+ */ - dec_init_kn03(); - break; - case MACH_DS5000_XX: /* Personal DS5000/2x */ - dec_init_kn02ca(); - break; - case MACH_DS5800: /* DS5800 Isis */ - panic("Don't know how to set this up!"); - break; - case MACH_DS5400: /* DS5400 MIPSfair */ - panic("Don't know how to set this up!"); - break; - case MACH_DS5500: /* DS5500 MIPSfair-2 */ - panic("Don't know how to set this up!"); - break; - } - set_except_vector(0, decstation_handle_int); -} diff -Nru a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/dec/kn02-irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,127 @@ +/* + * linux/arch/mips/dec/kn02-irq.c + * + * DECstation 5000/200 (KN02) Control and Status Register + * interrupts. + * + * Copyright (c) 2002, 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <asm/dec/kn02.h> + + +/* + * Bits 7:0 of the Control Register are write-only -- the + * corresponding bits of the Status Register have a different + * meaning. Hence we use a cache. It speeds up things a bit + * as well. + * + * There is no default value -- it has to be initialized. + */ +u32 cached_kn02_csr; +spinlock_t kn02_lock = SPIN_LOCK_UNLOCKED; + + +static int kn02_irq_base; + + +static inline void unmask_kn02_irq(unsigned int irq) +{ + volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE; + + cached_kn02_csr |= (1 << (irq - kn02_irq_base + 16)); + *csr = cached_kn02_csr; +} + +static inline void mask_kn02_irq(unsigned int irq) +{ + volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE; + + cached_kn02_csr &= ~(1 << (irq - kn02_irq_base + 16)); + *csr = cached_kn02_csr; +} + +static inline void enable_kn02_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&kn02_lock, flags); + unmask_kn02_irq(irq); + spin_unlock_irqrestore(&kn02_lock, flags); +} + +static inline void disable_kn02_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&kn02_lock, flags); + mask_kn02_irq(irq); + spin_unlock_irqrestore(&kn02_lock, flags); +} + + +static unsigned int startup_kn02_irq(unsigned int irq) +{ + enable_kn02_irq(irq); + return 0; +} + +#define shutdown_kn02_irq disable_kn02_irq + +static void ack_kn02_irq(unsigned int irq) +{ + spin_lock(&kn02_lock); + mask_kn02_irq(irq); + spin_unlock(&kn02_lock); + iob(); +} + +static void end_kn02_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_kn02_irq(irq); +} + +static struct hw_interrupt_type kn02_irq_type = { + .typename = "KN02-CSR", + .startup = startup_kn02_irq, + .shutdown = shutdown_kn02_irq, + .enable = enable_kn02_irq, + .disable = disable_kn02_irq, + .ack = ack_kn02_irq, + .end = end_kn02_irq, +}; + + +void __init init_kn02_irqs(int base) +{ + volatile u32 *csr = (volatile u32 *)KN02_CSR_BASE; + unsigned long flags; + int i; + + /* Mask interrupts. */ + spin_lock_irqsave(&kn02_lock, flags); + cached_kn02_csr &= ~KN03_CSR_IOINTEN; + *csr = cached_kn02_csr; + iob(); + spin_unlock_irqrestore(&kn02_lock, flags); + + for (i = base; i < base + KN02_IRQ_LINES; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &kn02_irq_type; + } + + kn02_irq_base = base; +} diff -Nru a/arch/mips/dec/prom/Makefile b/arch/mips/dec/prom/Makefile --- a/arch/mips/dec/prom/Makefile Fri Jun 27 14:19:55 2003 +++ b/arch/mips/dec/prom/Makefile Fri Jun 27 14:19:55 2003 @@ -1,11 +1,11 @@ -# $Id: Makefile,v 1.1 1999/01/17 03:49:44 ralf Exp $ +# # Makefile for the DECstation prom monitor library routines # under Linux. # -lib-y := init.o memory.o cmdline.o identify.o locore.o +lib-y += init.o memory.o cmdline.o identify.o -EXTRA_AFLAGS := $(CFLAGS) +lib-$(CONFIG_MIPS32) += locore.o +lib-$(CONFIG_MIPS64) += call_o32.o -dep: - $(CPP) $(CPPFLAGS) -M *.c > .depend +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/dec/prom/call_o32.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +/* + * arch/mips/dec/call_o32.S + * + * O32 interface for the 64 (or N32) ABI. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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 <asm/asm.h> +#include <asm/regdef.h> + +/* Maximum number of arguments supported. Must be even! */ +#define O32_ARGC 32 +/* Number of static registers we save. */ +#define O32_STATC 11 +/* Frame size for both of the above. */ +#define O32_FRAMESZ (4 * O32_ARGC + SZREG * O32_STATC) + + .text + +/* + * O32 function call dispatcher, for interfacing 32-bit ROM routines. + * + * The standard 64 (N32) calling sequence is supported, with a0 + * holding a function pointer, a1-a7 -- its first seven arguments + * and the stack -- remaining ones (up to O32_ARGC, including a1-a7). + * Static registers, gp and fp are preserved, v0 holds a result. + * This code relies on the called o32 function for sp and ra + * restoration and thus both this dispatcher and the current stack + * have to be placed in a KSEGx (or KUSEG) address space. Any + * pointers passed have to point to addresses within one of these + * spaces as well. + */ +NESTED(call_o32, O32_FRAMESZ, ra) + REG_SUBU sp,O32_FRAMESZ + + REG_S ra,O32_FRAMESZ-1*SZREG(sp) + REG_S fp,O32_FRAMESZ-2*SZREG(sp) + REG_S gp,O32_FRAMESZ-3*SZREG(sp) + REG_S s7,O32_FRAMESZ-4*SZREG(sp) + REG_S s6,O32_FRAMESZ-5*SZREG(sp) + REG_S s5,O32_FRAMESZ-6*SZREG(sp) + REG_S s4,O32_FRAMESZ-7*SZREG(sp) + REG_S s3,O32_FRAMESZ-8*SZREG(sp) + REG_S s2,O32_FRAMESZ-9*SZREG(sp) + REG_S s1,O32_FRAMESZ-10*SZREG(sp) + REG_S s0,O32_FRAMESZ-11*SZREG(sp) + + move jp,a0 + + sll a0,a1,zero + sll a1,a2,zero + sll a2,a3,zero + sll a3,a4,zero + sw a5,0x10(sp) + sw a6,0x14(sp) + sw a7,0x18(sp) + + PTR_LA t0,O32_FRAMESZ(sp) + PTR_LA t1,0x1c(sp) + li t2,O32_ARGC-7 +1: + lw t3,(t0) + REG_ADDU t0,SZREG + sw t3,(t1) + REG_SUBU t2,1 + REG_ADDU t1,4 + bnez t2,1b + + jalr jp + + REG_L s0,O32_FRAMESZ-11*SZREG(sp) + REG_L s1,O32_FRAMESZ-10*SZREG(sp) + REG_L s2,O32_FRAMESZ-9*SZREG(sp) + REG_L s3,O32_FRAMESZ-8*SZREG(sp) + REG_L s4,O32_FRAMESZ-7*SZREG(sp) + REG_L s5,O32_FRAMESZ-6*SZREG(sp) + REG_L s6,O32_FRAMESZ-5*SZREG(sp) + REG_L s7,O32_FRAMESZ-4*SZREG(sp) + REG_L gp,O32_FRAMESZ-3*SZREG(sp) + REG_L fp,O32_FRAMESZ-2*SZREG(sp) + REG_L ra,O32_FRAMESZ-1*SZREG(sp) + + REG_ADDU sp,O32_FRAMESZ + jr ra +END(call_o32) diff -Nru a/arch/mips/dec/prom/cmdline.c b/arch/mips/dec/prom/cmdline.c --- a/arch/mips/dec/prom/cmdline.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/dec/prom/cmdline.c Fri Jun 27 14:20:00 2003 @@ -6,32 +6,30 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h> +#include <linux/types.h> #include <asm/bootinfo.h> - -#include "prom.h" +#include <asm/dec/prom.h> #undef PROM_DEBUG -#ifdef PROM_DEBUG -extern int (*prom_printf)(char *, ...); -#endif - -char arcs_cmdline[COMMAND_LINE_SIZE]; +char arcs_cmdline[CL_SIZE]; -void __init prom_init_cmdline(int argc, char **argv, unsigned long magic) +void __init prom_init_cmdline(s32 argc, s32 *argv, u32 magic) { + char *arg; int start_arg, i; /* * collect args and prepare cmd_line */ - if (magic != REX_PROM_MAGIC) + if (!prom_is_rex(magic)) start_arg = 1; else start_arg = 2; for (i = start_arg; i < argc; i++) { - strcat(arcs_cmdline, argv[i]); + arg = (void *)(long)(argv[i]); + strcat(arcs_cmdline, arg); if (i < (argc - 1)) strcat(arcs_cmdline, " "); } @@ -39,6 +37,4 @@ #ifdef PROM_DEBUG prom_printf("arcs_cmdline: %s\n", &(arcs_cmdline[0])); #endif - } - diff -Nru a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c --- a/arch/mips/dec/prom/identify.c Fri Jun 27 14:20:04 2003 +++ b/arch/mips/dec/prom/identify.c Fri Jun 27 14:20:04 2003 @@ -2,32 +2,104 @@ * identify.c: machine identification code. * * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine - * - * $Id: identify.c,v 1.2 1999/10/09 00:00:58 ralf Exp $ + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include <linux/init.h> #include <linux/kernel.h> +#include <linux/mc146818rtc.h> #include <linux/string.h> +#include <linux/types.h> #include <asm/bootinfo.h> +#include <asm/dec/ioasic.h> +#include <asm/dec/ioasic_addrs.h> +#include <asm/dec/kn01.h> +#include <asm/dec/kn02.h> +#include <asm/dec/kn02ba.h> +#include <asm/dec/kn02ca.h> +#include <asm/dec/kn03.h> +#include <asm/dec/kn230.h> +#include <asm/dec/prom.h> #include "dectypes.h" -#include "prom.h" - -extern char *(*prom_getenv)(char *); -extern int (*prom_printf)(char *, ...); -extern int (*rex_getsysid)(void); extern unsigned long mips_machgroup; extern unsigned long mips_machtype; -void __init prom_identify_arch (unsigned int magic) +static const char *dec_system_strings[] = { + [MACH_DSUNKNOWN] "unknown DECstation", + [MACH_DS23100] "DECstation 2100/3100", + [MACH_DS5100] "DECsystem 5100", + [MACH_DS5000_200] "DECstation 5000/200", + [MACH_DS5000_1XX] "DECstation 5000/1xx", + [MACH_DS5000_XX] "Personal DECstation 5000/xx", + [MACH_DS5000_2X0] "DECstation 5000/2x0", + [MACH_DS5400] "DECsystem 5400", + [MACH_DS5500] "DECsystem 5500", + [MACH_DS5800] "DECsystem 5800", + [MACH_DS5900] "DECsystem 5900", +}; + +const char *get_system_type(void) { - unsigned char dec_cpunum, dec_firmrev, dec_etc; - int dec_systype; - unsigned long dec_sysid; +#define STR_BUF_LEN 64 + static char system[STR_BUF_LEN]; + static int called = 0; + + if (called == 0) { + called = 1; + snprintf(system, STR_BUF_LEN, "Digital %s", + dec_system_strings[mips_machtype]); + } + + return system; +} + - if (magic != REX_PROM_MAGIC) { +/* + * Setup essential system-specific memory addresses. We need them + * early. Semantically the functions belong to prom/init.c, but they + * are compact enough we want them inlined. --macro + */ +static inline void prom_init_kn01(void) +{ + dec_rtc_base = (void *)KN01_RTC_BASE; + dec_kn_slot_size = KN01_SLOT_SIZE; +} + +static inline void prom_init_kn230(void) +{ + dec_rtc_base = (void *)KN01_RTC_BASE; + dec_kn_slot_size = KN01_SLOT_SIZE; +} + +static inline void prom_init_kn02(void) +{ + dec_rtc_base = (void *)KN02_RTC_BASE; + dec_kn_slot_size = KN02_SLOT_SIZE; +} + +static inline void prom_init_kn02xa(void) +{ + ioasic_base = (void *)KN02XA_IOASIC_BASE; + dec_rtc_base = (void *)KN02XA_RTC_BASE; + dec_kn_slot_size = IOASIC_SLOT_SIZE; +} + +static inline void prom_init_kn03(void) +{ + ioasic_base = (void *)KN03_IOASIC_BASE; + dec_rtc_base = (void *)KN03_RTC_BASE; + dec_kn_slot_size = IOASIC_SLOT_SIZE; +} + + +void __init prom_identify_arch(u32 magic) +{ + unsigned char dec_cpunum, dec_firmrev, dec_etc, dec_systype; + u32 dec_sysid; + + if (!prom_is_rex(magic)) { dec_sysid = simple_strtoul(prom_getenv("systype"), (char **)0, 0); } else { dec_sysid = rex_getsysid(); @@ -49,50 +121,52 @@ * FIXME: This may not be an exhaustive list of DECStations/Servers! * Put all model-specific initialisation calls here. */ - prom_printf("This DECstation is a "); - switch (dec_systype) { case DS2100_3100: - prom_printf("DS2100/3100\n"); mips_machtype = MACH_DS23100; + prom_init_kn01(); break; case DS5100: /* DS5100 MIPSMATE */ - prom_printf("DS5100\n"); mips_machtype = MACH_DS5100; + prom_init_kn230(); break; case DS5000_200: /* DS5000 3max */ - prom_printf("DS5000/200\n"); mips_machtype = MACH_DS5000_200; + prom_init_kn02(); break; case DS5000_1XX: /* DS5000/100 3min */ - prom_printf("DS5000/1xx\n"); mips_machtype = MACH_DS5000_1XX; + prom_init_kn02xa(); break; - case DS5000_2X0: /* DS5000/240 3max+ */ - prom_printf("DS5000/2x0\n"); + case DS5000_2X0: /* DS5000/240 3max+ or DS5900 bigmax */ mips_machtype = MACH_DS5000_2X0; + prom_init_kn03(); + if (!(ioasic_read(IO_REG_SIR) & KN03_IO_INR_3MAXP)) + mips_machtype = MACH_DS5900; break; - case DS5000_XX: /* Personal DS5000/2x */ - prom_printf("Personal DS5000/xx\n"); + case DS5000_XX: /* Personal DS5000/xx maxine */ mips_machtype = MACH_DS5000_XX; + prom_init_kn02xa(); break; case DS5800: /* DS5800 Isis */ - prom_printf("DS5800\n"); mips_machtype = MACH_DS5800; break; case DS5400: /* DS5400 MIPSfair */ - prom_printf("DS5400\n"); mips_machtype = MACH_DS5400; break; case DS5500: /* DS5500 MIPSfair-2 */ - prom_printf("DS5500\n"); mips_machtype = MACH_DS5500; break; default: - prom_printf("unknown, id is %x", dec_systype); mips_machtype = MACH_DSUNKNOWN; break; } -} - + if (mips_machtype == MACH_DSUNKNOWN) + prom_printf("This is an %s, id is %x\n", + dec_system_strings[mips_machtype], + dec_systype); + else + prom_printf("This is a %s\n", + dec_system_strings[mips_machtype]); +} diff -Nru a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c --- a/arch/mips/dec/prom/init.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/dec/prom/init.c Fri Jun 27 14:19:57 2003 @@ -2,98 +2,103 @@ * init.c: PROM library initialisation code. * * Copyright (C) 1998 Harald Koerfgen + * Copyright (C) 2002 Maciej W. Rozycki */ -#include <linux/init.h> #include <linux/config.h> +#include <linux/init.h> +#include <linux/smp.h> +#include <linux/types.h> + #include <asm/bootinfo.h> #include <asm/cpu.h> -#include "prom.h" +#include <asm/processor.h> + +#include <asm/dec/prom.h> + + +int (*__rex_bootinit)(void); +int (*__rex_bootread)(void); +int (*__rex_getbitmap)(memmap *); +unsigned long *(*__rex_slot_address)(int); +void *(*__rex_gettcinfo)(void); +int (*__rex_getsysid)(void); +void (*__rex_clear_cache)(void); + +int (*__prom_getchar)(void); +char *(*__prom_getenv)(char *); +int (*__prom_printf)(char *, ...); + +int (*__pmax_open)(char*, int); +int (*__pmax_lseek)(int, long, int); +int (*__pmax_read)(int, void *, int); +int (*__pmax_close)(int); -/* - * PROM Interface (whichprom.c) - */ -typedef struct { - int pagesize; - unsigned char bitmap[0]; -} memmap; - -int (*rex_bootinit)(void); -int (*rex_bootread)(void); -int (*rex_getbitmap)(memmap *); -unsigned long *(*rex_slot_address)(int); -void *(*rex_gettcinfo)(void); -int (*rex_getsysid)(void); -void (*rex_clear_cache)(void); - -int (*prom_getchar)(void); -char *(*prom_getenv)(char *); -int (*prom_printf)(char *, ...); - -int (*pmax_open)(char*, int); -int (*pmax_lseek)(int, long, int); -int (*pmax_read)(int, void *, int); -int (*pmax_close)(int); - -extern void prom_meminit(unsigned int); -extern void prom_identify_arch(unsigned int); -extern void prom_init_cmdline(int, char **, unsigned long); /* * Detect which PROM's the DECSTATION has, and set the callback vectors * appropriately. */ -void __init which_prom(unsigned long magic, int *prom_vec) +void __init which_prom(s32 magic, s32 *prom_vec) { /* * No sign of the REX PROM's magic number means we assume a non-REX * machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx) */ - if (magic == REX_PROM_MAGIC) - { + if (prom_is_rex(magic)) { /* * Set up prom abstraction structure with REX entry points. */ - rex_bootinit = (int (*)(void)) *(prom_vec + REX_PROM_BOOTINIT); - rex_bootread = (int (*)(void)) *(prom_vec + REX_PROM_BOOTREAD); - rex_getbitmap = (int (*)(memmap *)) *(prom_vec + REX_PROM_GETBITMAP); - prom_getchar = (int (*)(void)) *(prom_vec + REX_PROM_GETCHAR); - prom_getenv = (char *(*)(char *)) *(prom_vec + REX_PROM_GETENV); - rex_getsysid = (int (*)(void)) *(prom_vec + REX_PROM_GETSYSID); - rex_gettcinfo = (void *(*)(void)) *(prom_vec + REX_PROM_GETTCINFO); - prom_printf = (int (*)(char *, ...)) *(prom_vec + REX_PROM_PRINTF); - rex_slot_address = (unsigned long *(*)(int)) *(prom_vec + REX_PROM_SLOTADDR); - rex_clear_cache = (void (*)(void)) * (prom_vec + REX_PROM_CLEARCACHE); - } - else - { + __rex_bootinit = + (void *)(long)*(prom_vec + REX_PROM_BOOTINIT); + __rex_bootread = + (void *)(long)*(prom_vec + REX_PROM_BOOTREAD); + __rex_getbitmap = + (void *)(long)*(prom_vec + REX_PROM_GETBITMAP); + __prom_getchar = + (void *)(long)*(prom_vec + REX_PROM_GETCHAR); + __prom_getenv = + (void *)(long)*(prom_vec + REX_PROM_GETENV); + __rex_getsysid = + (void *)(long)*(prom_vec + REX_PROM_GETSYSID); + __rex_gettcinfo = + (void *)(long)*(prom_vec + REX_PROM_GETTCINFO); + __prom_printf = + (void *)(long)*(prom_vec + REX_PROM_PRINTF); + __rex_slot_address = + (void *)(long)*(prom_vec + REX_PROM_SLOTADDR); + __rex_clear_cache = + (void *)(long)*(prom_vec + REX_PROM_CLEARCACHE); + } else { /* * Set up prom abstraction structure with non-REX entry points. */ - prom_getchar = (int (*)(void)) PMAX_PROM_GETCHAR; - prom_getenv = (char *(*)(char *)) PMAX_PROM_GETENV; - prom_printf = (int (*)(char *, ...)) PMAX_PROM_PRINTF; - pmax_open = (int (*)(char *, int)) PMAX_PROM_OPEN; - pmax_lseek = (int (*)(int, long, int)) PMAX_PROM_LSEEK; - pmax_read = (int (*)(int, void *, int)) PMAX_PROM_READ; - pmax_close = (int (*)(int)) PMAX_PROM_CLOSE; + __prom_getchar = (void *)PMAX_PROM_GETCHAR; + __prom_getenv = (void *)PMAX_PROM_GETENV; + __prom_printf = (void *)PMAX_PROM_PRINTF; + __pmax_open = (void *)PMAX_PROM_OPEN; + __pmax_lseek = (void *)PMAX_PROM_LSEEK; + __pmax_read = (void *)PMAX_PROM_READ; + __pmax_close = (void *)PMAX_PROM_CLOSE; } -} +} -int __init prom_init(int argc, char **argv, - unsigned long magic, int *prom_vec) +int __init prom_init(s32 argc, s32 *argv, u32 magic, s32 *prom_vec) { extern void dec_machine_halt(void); - /* Determine which PROM's we have (and therefore which machine we're on!) */ + /* + * Determine which PROM's we have + * (and therefore which machine we're on!) + */ which_prom(magic, prom_vec); - if (magic == REX_PROM_MAGIC) + if (prom_is_rex(magic)) rex_clear_cache(); /* Were we compiled with the right CPU option? */ #if defined(CONFIG_CPU_R3000) - if ((mips_cpu.cputype == CPU_R4000SC) || - (mips_cpu.cputype == CPU_R4400SC)) { + if ((current_cpu_data.cputype == CPU_R4000SC) || + (current_cpu_data.cputype == CPU_R4400SC)) { prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n"); prom_printf("Please recompile with \"CONFIG_CPU_R4x00 = y\"\n"); dec_machine_halt(); @@ -101,8 +106,8 @@ #endif #if defined(CONFIG_CPU_R4X00) - if ((mips_cpu.cputype == CPU_R3000) || - (mips_cpu.cputype == CPU_R3000A)) { + if ((current_cpu_data.cputype == CPU_R3000) || + (current_cpu_data.cputype == CPU_R3000A)) { prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n"); prom_printf("Please recompile with \"CONFIG_CPU_R3000 = y\"\n"); dec_machine_halt(); @@ -115,4 +120,3 @@ return 0; } - diff -Nru a/arch/mips/dec/prom/locore.S b/arch/mips/dec/prom/locore.S --- a/arch/mips/dec/prom/locore.S Fri Jun 27 14:19:52 2003 +++ b/arch/mips/dec/prom/locore.S Fri Jun 27 14:19:52 2003 @@ -19,11 +19,11 @@ mfc0 k0, CP0_STATUS la k1, mem_err - sw k0,0(k1) + sw k0, 0(k1) mfc0 k0, CP0_EPC nop - addiu k0,4 # skip the causing instruction + addiu k0, 4 # skip the causing instruction jr k0 rfe END(genexcept_early) diff -Nru a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c --- a/arch/mips/dec/prom/memory.c Fri Jun 27 14:19:30 2003 +++ b/arch/mips/dec/prom/memory.c Fri Jun 27 14:19:30 2003 @@ -2,37 +2,22 @@ * memory.c: memory initialisation code. * * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine - * Copyright (C) 2000 Maciej W. Rozycki - * - * $Id: memory.c,v 1.3 1999/10/09 00:00:58 ralf Exp $ + * Copyright (C) 2000, 2002 Maciej W. Rozycki */ -#include <linux/init.h> #include <linux/config.h> +#include <linux/init.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/bootmem.h> +#include <linux/types.h> #include <asm/addrspace.h> -#include <asm/page.h> - #include <asm/bootinfo.h> - #include <asm/dec/machtype.h> +#include <asm/dec/prom.h> +#include <asm/page.h> +#include <asm/sections.h> -#include "prom.h" - -typedef struct { - int pagesize; - unsigned char bitmap[0]; -} memmap; - -extern int (*rex_getbitmap)(memmap *); - -#undef PROM_DEBUG - -#ifdef PROM_DEBUG -extern int (*prom_printf)(char *, ...); -#endif volatile unsigned long mem_err = 0; /* So we know an error occurred */ @@ -43,10 +28,10 @@ #define CHUNK_SIZE 0x400000 -static void __init pmax_setup_memory_region(void) +static inline void pmax_setup_memory_region(void) { volatile unsigned char *memory_page, dummy; - char old_handler[0x80]; + char old_handler[0x80]; extern char genexcept_early; /* Install exception handler */ @@ -73,14 +58,14 @@ * Use the REX prom calls to get hold of the memory bitmap, and thence * determine memory size. */ -static void __init rex_setup_memory_region(void) +static inline void rex_setup_memory_region(void) { int i, bitmap_size; unsigned long mem_start = 0, mem_size = 0; memmap *bm; /* some free 64k */ - bm = (memmap *) 0x80028000; + bm = (memmap *)KSEG0ADDR(0x28000); bitmap_size = rex_getbitmap(bm); @@ -100,9 +85,9 @@ add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); } -void __init prom_meminit(unsigned int magic) +void __init prom_meminit(u32 magic) { - if (magic != REX_PROM_MAGIC) + if (!prom_is_rex(magic)) pmax_setup_memory_region(); else rex_setup_memory_region(); @@ -111,14 +96,13 @@ void __init prom_free_prom_memory (void) { unsigned long addr, end; - extern char _ftext; /* * Free everything below the kernel itself but leave * the first page reserved for the exception handlers. */ -#ifdef CONFIG_DECLANCE +#if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE) /* * Leave 128 KB reserved for Lance memory for * IOASIC DECstations. @@ -126,10 +110,10 @@ * XXX: save this address for use in dec_lance.c? */ if (IOASIC) - end = __pa(&_ftext) - 0x00020000; + end = __pa(&_text) - 0x00020000; else #endif - end = __pa(&_ftext); + end = __pa(&_text); addr = PAGE_SIZE; while (addr < end) { diff -Nru a/arch/mips/dec/prom/prom.h b/arch/mips/dec/prom/prom.h --- a/arch/mips/dec/prom/prom.h Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,51 +0,0 @@ -/* - * Miscellaneous definitions used to call the routines contained in the boot - * PROMs on various models of DECSTATION's. - * the rights to redistribute these changes. - */ - -#ifndef __ASM_DEC_PROM_H -#define __ASM_DEC_PROM_H - -/* - * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's. Many of - * these will work for MIPSen as well! - */ -#define VEC_RESET 0xBFC00000 /* Prom base address */ -#define PMAX_PROM_ENTRY(x) (VEC_RESET+((x)*8)) /* Prom jump table */ - -#define PMAX_PROM_HALT PMAX_PROM_ENTRY(2) /* valid on MIPSen */ -#define PMAX_PROM_AUTOBOOT PMAX_PROM_ENTRY(5) /* valid on MIPSen */ -#define PMAX_PROM_OPEN PMAX_PROM_ENTRY(6) -#define PMAX_PROM_READ PMAX_PROM_ENTRY(7) -#define PMAX_PROM_CLOSE PMAX_PROM_ENTRY(10) -#define PMAX_PROM_LSEEK PMAX_PROM_ENTRY(11) -#define PMAX_PROM_GETCHAR PMAX_PROM_ENTRY(12) -#define PMAX_PROM_PUTCHAR PMAX_PROM_ENTRY(13) /* 12 on MIPSen */ -#define PMAX_PROM_GETS PMAX_PROM_ENTRY(15) -#define PMAX_PROM_PRINTF PMAX_PROM_ENTRY(17) -#define PMAX_PROM_GETENV PMAX_PROM_ENTRY(33) /* valid on MIPSen */ - -/* - * Magic number indicating REX PROM available on DECSTATION. Found in - * register a2 on transfer of control to program from PROM. - */ -#define REX_PROM_MAGIC 0x30464354 - -/* - * 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's, and - * DS5000/2x0. - */ -#define REX_PROM_GETBITMAP 0x84/4 /* get mem bitmap */ -#define REX_PROM_GETCHAR 0x24/4 /* getch() */ -#define REX_PROM_GETENV 0x64/4 /* get env. variable */ -#define REX_PROM_GETSYSID 0x80/4 /* get system id */ -#define REX_PROM_GETTCINFO 0xa4/4 -#define REX_PROM_PRINTF 0x30/4 /* printf() */ -#define REX_PROM_SLOTADDR 0x6c/4 /* slotaddr */ -#define REX_PROM_BOOTINIT 0x54/4 /* open() */ -#define REX_PROM_BOOTREAD 0x58/4 /* read() */ -#define REX_PROM_CLEARCACHE 0x7c/4 - -#endif /* __ASM_DEC_PROM_H */ - diff -Nru a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c --- a/arch/mips/dec/promcon.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/dec/promcon.c Fri Jun 27 14:19:57 2003 @@ -2,7 +2,7 @@ * Wrap-around code for a console using the * DECstation PROM io-routines. * - * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 1998 Harald Koerfgen */ #include <linux/tty.h> @@ -12,50 +12,45 @@ #include <linux/console.h> #include <linux/fs.h> -extern int (*prom_getchar) (void); -extern int (*prom_printf) (char *,...); +#include <asm/dec/prom.h> static void prom_console_write(struct console *co, const char *s, unsigned count) { - unsigned i; + unsigned i; - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - if (*s == 10) - prom_printf("%c", 13); - prom_printf("%c", *s++); - } + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + if (*s == 10) + prom_printf("%c", 13); + prom_printf("%c", *s++); + } } static int __init prom_console_setup(struct console *co, char *options) { - return 0; -} - -static kdev_t prom_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); + return 0; } static struct console sercons = { - .name = "ttyS", - .write = prom_console_write, - .device = prom_console_device, - .setup = prom_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "ttyS", + .write = prom_console_write, + .setup = prom_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, }; /* * Register console. */ -long __init prom_console_init(long kmem_start, long kmem_end) +static int __init prom_console_init(void) { - register_console(&sercons); - return kmem_start; + register_console(&sercons); + + return 0; } +console_initcall(prom_console_init); diff -Nru a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c --- a/arch/mips/dec/reset.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/dec/reset.c Fri Jun 27 14:20:00 2003 @@ -1,11 +1,14 @@ /* - * $Id: $ - * - * Reset a DECstation machine. + * Reset a DECstation machine. * + * Copyright (C) 199x the Anonymous + * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki */ -void (*back_to_prom)(void) = (void (*)(void))0xBFC00000; +#include <asm/addrspace.h> +#include <asm/ptrace.h> + +#define back_to_prom() (((void (*)(void))KSEG1ADDR(0x1fc00000))()) void dec_machine_restart(char *command) { diff -Nru a/arch/mips/dec/rtc-dec.c b/arch/mips/dec/rtc-dec.c --- a/arch/mips/dec/rtc-dec.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/dec/rtc-dec.c Fri Jun 27 14:19:54 2003 @@ -3,33 +3,38 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * RTC routines for DECstation style attached Dallas chip. + * RTC routines for DECstation style attached Dallas DS1287 chip. * * Copyright (C) 1998, 2001 by Ralf Baechle * Copyright (C) 1998 by Harald Koerfgen + * Copyright (C) 2002 Maciej W. Rozycki */ + #include <linux/mc146818rtc.h> +#include <linux/module.h> +#include <linux/types.h> -extern char *dec_rtc_base; +volatile u8 *dec_rtc_base; static unsigned char dec_rtc_read_data(unsigned long addr) { - return (dec_rtc_base[addr * 4]); + return dec_rtc_base[addr * 4]; } static void dec_rtc_write_data(unsigned char data, unsigned long addr) { - dec_rtc_base[addr * 4] = data; + dec_rtc_base[addr * 4] = data; } static int dec_rtc_bcd_mode(void) { - return 0; + return 0; } -struct rtc_ops dec_rtc_ops = -{ - &dec_rtc_read_data, - &dec_rtc_write_data, - &dec_rtc_bcd_mode +struct rtc_ops dec_rtc_ops = { + &dec_rtc_read_data, + &dec_rtc_write_data, + &dec_rtc_bcd_mode }; + +EXPORT_SYMBOL(dec_rtc_base); diff -Nru a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c --- a/arch/mips/dec/setup.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/dec/setup.c Fri Jun 27 14:19:55 2003 @@ -6,478 +6,768 @@ * for more details. * * Copyright (C) 1998 Harald Koerfgen - * Copyright (C) 2000 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003 Maciej W. Rozycki */ +#include <linux/config.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/mc146818rtc.h> #include <linux/param.h> #include <linux/console.h> -#include <asm/mipsregs.h> -#include <asm/bootinfo.h> #include <linux/init.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> #include <asm/irq.h> +#include <asm/irq_cpu.h> +#include <asm/mipsregs.h> #include <asm/reboot.h> +#include <asm/traps.h> +#include <asm/wbflush.h> #include <asm/dec/interrupts.h> -#include <asm/dec/kn01.h> -#include <asm/dec/kn02.h> -#include <asm/dec/kn02xa.h> -#include <asm/dec/kn03.h> #include <asm/dec/ioasic.h> #include <asm/dec/ioasic_addrs.h> #include <asm/dec/ioasic_ints.h> +#include <asm/dec/kn01.h> +#include <asm/dec/kn02.h> +#include <asm/dec/kn02ba.h> +#include <asm/dec/kn02ca.h> +#include <asm/dec/kn03.h> +#include <asm/dec/kn230.h> -char *dec_rtc_base = (void *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */ - -volatile unsigned int *ioasic_base; - -decint_t dec_interrupt[NR_INTS]; - -/* - * Information regarding the IRQ Controller - */ - -volatile unsigned int *isr = 0L; /* address of the interrupt status register */ -volatile unsigned int *imr = 0L; /* address of the interrupt mask register */ - extern void dec_machine_restart(char *command); extern void dec_machine_halt(void); extern void dec_machine_power_off(void); extern void dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); -extern void wbflush_setup(void); +extern asmlinkage void decstation_handle_int(void); -extern struct rtc_ops dec_rtc_ops; +spinlock_t ioasic_ssr_lock; -extern int setup_dec_irq(int, struct irqaction *); +volatile u32 *ioasic_base; +unsigned long dec_kn_slot_size; -void (*board_time_init) (struct irqaction * irq); +/* + * IRQ routing and priority tables. Priorites are set as follows: + * + * KN01 KN230 KN02 KN02-BA KN02-CA KN03 + * + * MEMORY CPU CPU CPU ASIC CPU CPU + * RTC CPU CPU CPU ASIC CPU CPU + * DMA - - - ASIC ASIC ASIC + * SERIAL0 CPU CPU CSR ASIC ASIC ASIC + * SERIAL1 - - - ASIC - ASIC + * SCSI CPU CPU CSR ASIC ASIC ASIC + * ETHERNET CPU * CSR ASIC ASIC ASIC + * other - - - ASIC - - + * TC2 - - CSR CPU ASIC ASIC + * TC1 - - CSR CPU ASIC ASIC + * TC0 - - CSR CPU ASIC ASIC + * other - CPU - CPU ASIC ASIC + * other - - - - CPU CPU + * + * * -- shared with SCSI + */ + +int dec_interrupt[DEC_NR_INTS] = { + [0 ... DEC_NR_INTS - 1] = -1 +}; +int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2] = { + { { .i = ~0 }, { .p = dec_intr_unimplemented } }, +}; +int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = { + { { .i = ~0 }, { .p = asic_intr_unimplemented } }, +}; +int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU); + +static struct irqaction ioirq = { + .handler = no_action, + .name = "cascade", +}; +static struct irqaction fpuirq = { + .handler = no_action, + .name = "fpu", +}; + +static struct irqaction busirq = { + .flags = SA_INTERRUPT, + .name = "bus error", +}; + +static struct irqaction haltirq = { + .handler = dec_intr_halt, + .name = "halt", +}; + + +void (*board_time_init)(struct irqaction *irq); -static struct irqaction irq10 = {dec_intr_halt, 0, 0, "halt", NULL, NULL}; /* * enable the periodic interrupts */ static void __init dec_time_init(struct irqaction *irq) { - /* - * Here we go, enable periodic rtc interrupts. - */ + /* + * Here we go, enable periodic rtc interrupts. + */ #ifndef LOG_2_HZ # define LOG_2_HZ 7 #endif - CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); - CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B); - setup_dec_irq(CLOCK, irq); + CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - LOG_2_HZ), RTC_REG_A); + CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B); + setup_irq(dec_interrupt[DEC_IRQ_RTC], irq); } + /* - * Enable the halt interrupt. + * Bus error (DBE/IBE exceptions and bus interrupts) handling setup. */ -static void __init dec_halt_init(struct irqaction *irq) +void __init dec_be_init(void) { - setup_dec_irq(HALT, irq); + switch (mips_machtype) { + case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */ + busirq.flags |= SA_SHIRQ; + break; + case MACH_DS5000_200: /* DS5000/200 3max */ + case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + case MACH_DS5900: /* DS5900 bigmax */ + board_be_handler = dec_ecc_be_handler; + busirq.handler = dec_ecc_be_interrupt; + dec_ecc_be_init(); + break; + } } + void __init decstation_setup(void) { - board_time_init = dec_time_init; + board_be_init = dec_be_init; + board_time_init = dec_time_init; - wbflush_setup(); + wbflush_setup(); - _machine_restart = dec_machine_restart; - _machine_halt = dec_machine_halt; - _machine_power_off = dec_machine_power_off; + _machine_restart = dec_machine_restart; + _machine_halt = dec_machine_halt; + _machine_power_off = dec_machine_power_off; #ifdef CONFIG_FB - conswitchp = &dummy_con; + conswitchp = &dummy_con; #endif - rtc_ops = &dec_rtc_ops; + rtc_ops = &dec_rtc_ops; } + /* - * Machine-specific initialisation for kn01, aka Pmax, aka DS2100, DS3100, - * and possibly also the DS5100. + * Machine-specific initialisation for KN01, aka DS2100 (aka Pmin) + * or DS3100 (aka Pmax). */ +static int kn01_interrupt[DEC_NR_INTS] __initdata = { + [DEC_IRQ_CASCADE] = -1, + [DEC_IRQ_AB_RECV] = -1, + [DEC_IRQ_AB_XMIT] = -1, + [DEC_IRQ_DZ11] = DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11), + [DEC_IRQ_ASC] = -1, + [DEC_IRQ_FLOPPY] = -1, + [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU), + [DEC_IRQ_HALT] = -1, + [DEC_IRQ_ISDN] = -1, + [DEC_IRQ_LANCE] = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS), + [DEC_IRQ_PSU] = -1, + [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC), + [DEC_IRQ_SCC0] = -1, + [DEC_IRQ_SCC1] = -1, + [DEC_IRQ_SII] = DEC_CPU_IRQ_NR(KN01_CPU_INR_SII), + [DEC_IRQ_TC0] = -1, + [DEC_IRQ_TC1] = -1, + [DEC_IRQ_TC2] = -1, + [DEC_IRQ_TIMER] = -1, + [DEC_IRQ_VIDEO] = DEC_CPU_IRQ_NR(KN01_CPU_INR_VIDEO), + [DEC_IRQ_ASC_MERR] = -1, + [DEC_IRQ_ASC_ERR] = -1, + [DEC_IRQ_ASC_DMA] = -1, + [DEC_IRQ_FLOPPY_ERR] = -1, + [DEC_IRQ_ISDN_ERR] = -1, + [DEC_IRQ_ISDN_RXDMA] = -1, + [DEC_IRQ_ISDN_TXDMA] = -1, + [DEC_IRQ_LANCE_MERR] = -1, + [DEC_IRQ_SCC0A_RXERR] = -1, + [DEC_IRQ_SCC0A_RXDMA] = -1, + [DEC_IRQ_SCC0A_TXERR] = -1, + [DEC_IRQ_SCC0A_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, + [DEC_IRQ_SCC1A_RXERR] = -1, + [DEC_IRQ_SCC1A_RXDMA] = -1, + [DEC_IRQ_SCC1A_TXERR] = -1, + [DEC_IRQ_SCC1A_TXDMA] = -1, +}; + +static int_ptr kn01_cpu_mask_nr_tbl[][2] __initdata = { + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_DZ11) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_DZ11) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_SII) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_SII) } }, + { { .i = DEC_CPU_IRQ_MASK(KN01_CPU_INR_LANCE) }, + { .i = DEC_CPU_IRQ_NR(KN01_CPU_INR_LANCE) } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, +}; + void __init dec_init_kn01(void) { - /* - * Setup some memory addresses. - */ - dec_rtc_base = (char *) KN01_RTC_BASE; - - /* - * Setup interrupt structure - */ - dec_interrupt[CLOCK].cpu_mask = IE_IRQ3; - dec_interrupt[CLOCK].iemask = 0; - cpu_mask_tbl[0] = IE_IRQ3; - cpu_irq_nr[0] = CLOCK; - - dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0; - dec_interrupt[SCSI_INT].iemask = 0; - cpu_mask_tbl[1] = IE_IRQ0; - cpu_irq_nr[1] = SCSI_INT; - - dec_interrupt[ETHER].cpu_mask = IE_IRQ1; - dec_interrupt[ETHER].iemask = 0; - cpu_mask_tbl[2] = IE_IRQ1; - cpu_irq_nr[2] = ETHER; - - dec_interrupt[SERIAL].cpu_mask = IE_IRQ2; - dec_interrupt[SERIAL].iemask = 0; - cpu_mask_tbl[3] = IE_IRQ2; - cpu_irq_nr[3] = SERIAL; - - dec_interrupt[MEMORY].cpu_mask = IE_IRQ4; - dec_interrupt[MEMORY].iemask = 0; - cpu_mask_tbl[4] = IE_IRQ4; - cpu_irq_nr[4] = MEMORY; - - dec_interrupt[FPU].cpu_mask = IE_IRQ5; - dec_interrupt[FPU].iemask = 0; - cpu_mask_tbl[5] = IE_IRQ5; - cpu_irq_nr[5] = FPU; + /* IRQ routing. */ + memcpy(&dec_interrupt, &kn01_interrupt, + sizeof(kn01_interrupt)); + + /* CPU IRQ priorities. */ + memcpy(&cpu_mask_nr_tbl, &kn01_cpu_mask_nr_tbl, + sizeof(kn01_cpu_mask_nr_tbl)); + + mips_cpu_irq_init(DEC_CPU_IRQ_BASE); + } /* dec_init_kn01 */ + /* - * Machine-specific initialisation for kn230, aka MIPSmate, aka DS5100 - * - * There are a lot of experiments to do, this is definitely incomplete. + * Machine-specific initialisation for KN230, aka DS5100, aka MIPSmate. */ +static int kn230_interrupt[DEC_NR_INTS] __initdata = { + [DEC_IRQ_CASCADE] = -1, + [DEC_IRQ_AB_RECV] = -1, + [DEC_IRQ_AB_XMIT] = -1, + [DEC_IRQ_DZ11] = DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11), + [DEC_IRQ_ASC] = -1, + [DEC_IRQ_FLOPPY] = -1, + [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU), + [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN230_CPU_INR_HALT), + [DEC_IRQ_ISDN] = -1, + [DEC_IRQ_LANCE] = DEC_CPU_IRQ_NR(KN230_CPU_INR_LANCE), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS), + [DEC_IRQ_PSU] = -1, + [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC), + [DEC_IRQ_SCC0] = -1, + [DEC_IRQ_SCC1] = -1, + [DEC_IRQ_SII] = DEC_CPU_IRQ_NR(KN230_CPU_INR_SII), + [DEC_IRQ_TC0] = -1, + [DEC_IRQ_TC1] = -1, + [DEC_IRQ_TC2] = -1, + [DEC_IRQ_TIMER] = -1, + [DEC_IRQ_VIDEO] = -1, + [DEC_IRQ_ASC_MERR] = -1, + [DEC_IRQ_ASC_ERR] = -1, + [DEC_IRQ_ASC_DMA] = -1, + [DEC_IRQ_FLOPPY_ERR] = -1, + [DEC_IRQ_ISDN_ERR] = -1, + [DEC_IRQ_ISDN_RXDMA] = -1, + [DEC_IRQ_ISDN_TXDMA] = -1, + [DEC_IRQ_LANCE_MERR] = -1, + [DEC_IRQ_SCC0A_RXERR] = -1, + [DEC_IRQ_SCC0A_RXDMA] = -1, + [DEC_IRQ_SCC0A_TXERR] = -1, + [DEC_IRQ_SCC0A_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, + [DEC_IRQ_SCC1A_RXERR] = -1, + [DEC_IRQ_SCC1A_RXDMA] = -1, + [DEC_IRQ_SCC1A_TXERR] = -1, + [DEC_IRQ_SCC1A_TXDMA] = -1, +}; + +static int_ptr kn230_cpu_mask_nr_tbl[][2] __initdata = { + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_DZ11) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_DZ11) } }, + { { .i = DEC_CPU_IRQ_MASK(KN230_CPU_INR_SII) }, + { .i = DEC_CPU_IRQ_NR(KN230_CPU_INR_SII) } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, +}; + void __init dec_init_kn230(void) { - /* - * Setup some memory addresses. - */ - dec_rtc_base = (char *) KN01_RTC_BASE; - - /* - * Setup interrupt structure - */ - dec_interrupt[CLOCK].cpu_mask = IE_IRQ2; - dec_interrupt[CLOCK].iemask = 0; - cpu_mask_tbl[0] = IE_IRQ2; - cpu_irq_nr[0] = CLOCK; - - dec_interrupt[FPU].cpu_mask = IE_IRQ5; - dec_interrupt[FPU].iemask = 0; - cpu_mask_tbl[5] = IE_IRQ5; - cpu_irq_nr[5] = FPU; + /* IRQ routing. */ + memcpy(&dec_interrupt, &kn230_interrupt, + sizeof(kn230_interrupt)); + + /* CPU IRQ priorities. */ + memcpy(&cpu_mask_nr_tbl, &kn230_cpu_mask_nr_tbl, + sizeof(kn230_cpu_mask_nr_tbl)); + + mips_cpu_irq_init(DEC_CPU_IRQ_BASE); + } /* dec_init_kn230 */ + /* - * Machine-specific initialisation for kn02, aka 3max, aka DS5000/2xx. + * Machine-specific initialisation for KN02, aka DS5000/200, aka 3max. */ +static int kn02_interrupt[DEC_NR_INTS] __initdata = { + [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN02_CPU_INR_CASCADE), + [DEC_IRQ_AB_RECV] = -1, + [DEC_IRQ_AB_XMIT] = -1, + [DEC_IRQ_DZ11] = KN02_IRQ_NR(KN02_CSR_INR_DZ11), + [DEC_IRQ_ASC] = KN02_IRQ_NR(KN02_CSR_INR_ASC), + [DEC_IRQ_FLOPPY] = -1, + [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU), + [DEC_IRQ_HALT] = -1, + [DEC_IRQ_ISDN] = -1, + [DEC_IRQ_LANCE] = KN02_IRQ_NR(KN02_CSR_INR_LANCE), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS), + [DEC_IRQ_PSU] = -1, + [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC), + [DEC_IRQ_SCC0] = -1, + [DEC_IRQ_SCC1] = -1, + [DEC_IRQ_SII] = -1, + [DEC_IRQ_TC0] = KN02_IRQ_NR(KN02_CSR_INR_TC0), + [DEC_IRQ_TC1] = KN02_IRQ_NR(KN02_CSR_INR_TC1), + [DEC_IRQ_TC2] = KN02_IRQ_NR(KN02_CSR_INR_TC2), + [DEC_IRQ_TIMER] = -1, + [DEC_IRQ_VIDEO] = -1, + [DEC_IRQ_ASC_MERR] = -1, + [DEC_IRQ_ASC_ERR] = -1, + [DEC_IRQ_ASC_DMA] = -1, + [DEC_IRQ_FLOPPY_ERR] = -1, + [DEC_IRQ_ISDN_ERR] = -1, + [DEC_IRQ_ISDN_RXDMA] = -1, + [DEC_IRQ_ISDN_TXDMA] = -1, + [DEC_IRQ_LANCE_MERR] = -1, + [DEC_IRQ_SCC0A_RXERR] = -1, + [DEC_IRQ_SCC0A_RXDMA] = -1, + [DEC_IRQ_SCC0A_TXERR] = -1, + [DEC_IRQ_SCC0A_TXDMA] = -1, + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, + [DEC_IRQ_SCC1A_RXERR] = -1, + [DEC_IRQ_SCC1A_RXDMA] = -1, + [DEC_IRQ_SCC1A_TXERR] = -1, + [DEC_IRQ_SCC1A_TXDMA] = -1, +}; + +static int_ptr kn02_cpu_mask_nr_tbl[][2] __initdata = { + { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN02_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02_CPU_INR_CASCADE) }, + { .p = kn02_io_int } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, +}; + +static int_ptr kn02_asic_mask_nr_tbl[][2] __initdata = { + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_DZ11) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_DZ11) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_ASC) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_ASC) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_LANCE) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_LANCE) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC2) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_TC2) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC1) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_TC1) } }, + { { .i = KN02_IRQ_MASK(KN02_CSR_INR_TC0) }, + { .i = KN02_IRQ_NR(KN02_CSR_INR_TC0) } }, + { { .i = KN02_IRQ_ALL }, + { .p = kn02_all_int } }, +}; + void __init dec_init_kn02(void) { - /* - * Setup some memory addresses. FIXME: probably incomplete! - */ - dec_rtc_base = (char *) KN02_RTC_BASE; - isr = (void *) KN02_CSR_ADDR; - imr = (void *) KN02_CSR_ADDR; - - /* - * Setup IOASIC interrupt - */ - cpu_ivec_tbl[1] = kn02_io_int; - cpu_mask_tbl[1] = IE_IRQ0; - cpu_irq_nr[1] = -1; - *imr = *imr & 0xff00ff00; - - /* - * Setup interrupt structure - */ - dec_interrupt[CLOCK].cpu_mask = IE_IRQ1; - dec_interrupt[CLOCK].iemask = 0; - cpu_mask_tbl[0] = IE_IRQ1; - cpu_irq_nr[0] = CLOCK; - - dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0; - dec_interrupt[SCSI_INT].iemask = KN02_SLOT5; - asic_mask_tbl[0] = KN02_SLOT5; - asic_irq_nr[0] = SCSI_INT; - - dec_interrupt[ETHER].cpu_mask = IE_IRQ0; - dec_interrupt[ETHER].iemask = KN02_SLOT6; - asic_mask_tbl[1] = KN02_SLOT6; - asic_irq_nr[1] = ETHER; - - dec_interrupt[SERIAL].cpu_mask = IE_IRQ0; - dec_interrupt[SERIAL].iemask = KN02_SLOT7; - asic_mask_tbl[2] = KN02_SLOT7; - asic_irq_nr[2] = SERIAL; - - dec_interrupt[TC0].cpu_mask = IE_IRQ0; - dec_interrupt[TC0].iemask = KN02_SLOT0; - asic_mask_tbl[3] = KN02_SLOT0; - asic_irq_nr[3] = TC0; - - dec_interrupt[TC1].cpu_mask = IE_IRQ0; - dec_interrupt[TC1].iemask = KN02_SLOT1; - asic_mask_tbl[4] = KN02_SLOT1; - asic_irq_nr[4] = TC1; - - dec_interrupt[TC2].cpu_mask = IE_IRQ0; - dec_interrupt[TC2].iemask = KN02_SLOT2; - asic_mask_tbl[5] = KN02_SLOT2; - asic_irq_nr[5] = TC2; - - dec_interrupt[MEMORY].cpu_mask = IE_IRQ3; - dec_interrupt[MEMORY].iemask = 0; - cpu_mask_tbl[2] = IE_IRQ3; - cpu_irq_nr[2] = MEMORY; - - dec_interrupt[FPU].cpu_mask = IE_IRQ5; - dec_interrupt[FPU].iemask = 0; - cpu_mask_tbl[3] = IE_IRQ5; - cpu_irq_nr[3] = FPU; + /* IRQ routing. */ + memcpy(&dec_interrupt, &kn02_interrupt, + sizeof(kn02_interrupt)); + + /* CPU IRQ priorities. */ + memcpy(&cpu_mask_nr_tbl, &kn02_cpu_mask_nr_tbl, + sizeof(kn02_cpu_mask_nr_tbl)); + + /* KN02 CSR IRQ priorities. */ + memcpy(&asic_mask_nr_tbl, &kn02_asic_mask_nr_tbl, + sizeof(kn02_asic_mask_nr_tbl)); + + mips_cpu_irq_init(DEC_CPU_IRQ_BASE); + init_kn02_irqs(KN02_IRQ_BASE); } /* dec_init_kn02 */ + /* - * Machine-specific initialisation for kn02ba, aka 3min, aka DS5000/1xx. + * Machine-specific initialisation for KN02-BA, aka DS5000/1xx + * (xx = 20, 25, 33), aka 3min. Also applies to KN04(-BA), aka + * DS5000/150, aka 4min. */ +static int kn02ba_interrupt[DEC_NR_INTS] __initdata = { + [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_CASCADE), + [DEC_IRQ_AB_RECV] = -1, + [DEC_IRQ_AB_XMIT] = -1, + [DEC_IRQ_DZ11] = -1, + [DEC_IRQ_ASC] = IO_IRQ_NR(KN02BA_IO_INR_ASC), + [DEC_IRQ_FLOPPY] = -1, + [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU), + [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_HALT), + [DEC_IRQ_ISDN] = -1, + [DEC_IRQ_LANCE] = IO_IRQ_NR(KN02BA_IO_INR_LANCE), + [DEC_IRQ_BUS] = IO_IRQ_NR(KN02BA_IO_INR_BUS), + [DEC_IRQ_PSU] = IO_IRQ_NR(KN02BA_IO_INR_PSU), + [DEC_IRQ_RTC] = IO_IRQ_NR(KN02BA_IO_INR_RTC), + [DEC_IRQ_SCC0] = IO_IRQ_NR(KN02BA_IO_INR_SCC0), + [DEC_IRQ_SCC1] = IO_IRQ_NR(KN02BA_IO_INR_SCC1), + [DEC_IRQ_SII] = -1, + [DEC_IRQ_TC0] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0), + [DEC_IRQ_TC1] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1), + [DEC_IRQ_TC2] = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2), + [DEC_IRQ_TIMER] = -1, + [DEC_IRQ_VIDEO] = -1, + [DEC_IRQ_ASC_MERR] = IO_IRQ_NR(IO_INR_ASC_MERR), + [DEC_IRQ_ASC_ERR] = IO_IRQ_NR(IO_INR_ASC_ERR), + [DEC_IRQ_ASC_DMA] = IO_IRQ_NR(IO_INR_ASC_DMA), + [DEC_IRQ_FLOPPY_ERR] = -1, + [DEC_IRQ_ISDN_ERR] = -1, + [DEC_IRQ_ISDN_RXDMA] = -1, + [DEC_IRQ_ISDN_TXDMA] = -1, + [DEC_IRQ_LANCE_MERR] = IO_IRQ_NR(IO_INR_LANCE_MERR), + [DEC_IRQ_SCC0A_RXERR] = IO_IRQ_NR(IO_INR_SCC0A_RXERR), + [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA), + [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR), + [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA), + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, + [DEC_IRQ_SCC1A_RXERR] = IO_IRQ_NR(IO_INR_SCC1A_RXERR), + [DEC_IRQ_SCC1A_RXDMA] = IO_IRQ_NR(IO_INR_SCC1A_RXDMA), + [DEC_IRQ_SCC1A_TXERR] = IO_IRQ_NR(IO_INR_SCC1A_TXERR), + [DEC_IRQ_SCC1A_TXDMA] = IO_IRQ_NR(IO_INR_SCC1A_TXDMA), +}; + +static int_ptr kn02ba_cpu_mask_nr_tbl[][2] __initdata = { + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_CASCADE) }, + { .p = kn02xa_io_int } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC2) }, + { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC2) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC1) }, + { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC1) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02BA_CPU_INR_TC0) }, + { .i = DEC_CPU_IRQ_NR(KN02BA_CPU_INR_TC0) } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, +}; + +static int_ptr kn02ba_asic_mask_nr_tbl[][2] __initdata = { + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_BUS) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_BUS) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_RTC) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_RTC) } }, + { { .i = IO_IRQ_DMA }, + { .p = asic_dma_int } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC0) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_SCC0) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_SCC1) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_SCC1) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_ASC) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_ASC) } }, + { { .i = IO_IRQ_MASK(KN02BA_IO_INR_LANCE) }, + { .i = IO_IRQ_NR(KN02BA_IO_INR_LANCE) } }, + { { .i = IO_IRQ_ALL }, + { .p = asic_all_int } }, +}; + void __init dec_init_kn02ba(void) { - /* - * Setup some memory addresses. - */ - ioasic_base = (void *) KN02XA_IOASIC_BASE; - dec_rtc_base = (char *) KN02XA_RTC_BASE; - isr = (void *) KN02XA_IOASIC_REG(SIR); - imr = (void *) KN02XA_IOASIC_REG(SIMR); - - /* - * Setup IOASIC interrupt - */ - cpu_mask_tbl[0] = IE_IRQ3; - cpu_irq_nr[0] = -1; - cpu_ivec_tbl[0] = kn02xa_io_int; - *imr = 0; - - /* - * Setup interrupt structure - */ - dec_interrupt[CLOCK].cpu_mask = IE_IRQ3; - dec_interrupt[CLOCK].iemask = KMIN_CLOCK; - asic_mask_tbl[0] = KMIN_CLOCK; - asic_irq_nr[0] = CLOCK; - - dec_interrupt[SCSI_DMA_INT].cpu_mask = IE_IRQ3; - dec_interrupt[SCSI_DMA_INT].iemask = SCSI_DMA_INTS; - asic_mask_tbl[1] = SCSI_DMA_INTS; - asic_irq_nr[1] = SCSI_DMA_INT; - - dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ3; - dec_interrupt[SCSI_INT].iemask = SCSI_CHIP; - asic_mask_tbl[2] = SCSI_CHIP; - asic_irq_nr[2] = SCSI_INT; - - dec_interrupt[ETHER].cpu_mask = IE_IRQ3; - dec_interrupt[ETHER].iemask = LANCE_INTS; - asic_mask_tbl[3] = LANCE_INTS; - asic_irq_nr[3] = ETHER; - - dec_interrupt[SERIAL].cpu_mask = IE_IRQ3; - dec_interrupt[SERIAL].iemask = SERIAL_INTS; - asic_mask_tbl[4] = SERIAL_INTS; - asic_irq_nr[4] = SERIAL; - - dec_interrupt[MEMORY].cpu_mask = IE_IRQ3; - dec_interrupt[MEMORY].iemask = KMIN_TIMEOUT; - asic_mask_tbl[5] = KMIN_TIMEOUT; - asic_irq_nr[5] = MEMORY; - - dec_interrupt[TC0].cpu_mask = IE_IRQ0; - dec_interrupt[TC0].iemask = 0; - cpu_mask_tbl[1] = IE_IRQ0; - cpu_irq_nr[1] = TC0; - - dec_interrupt[TC1].cpu_mask = IE_IRQ1; - dec_interrupt[TC1].iemask = 0; - cpu_mask_tbl[2] = IE_IRQ1; - cpu_irq_nr[2] = TC1; - - dec_interrupt[TC2].cpu_mask = IE_IRQ2; - dec_interrupt[TC2].iemask = 0; - cpu_mask_tbl[3] = IE_IRQ2; - cpu_irq_nr[3] = TC2; - - dec_interrupt[HALT].cpu_mask = IE_IRQ4; - dec_interrupt[HALT].iemask = 0; - cpu_mask_tbl[4] = IE_IRQ4; - cpu_irq_nr[4] = HALT; - - dec_interrupt[FPU].cpu_mask = IE_IRQ5; - dec_interrupt[FPU].iemask = 0; - cpu_mask_tbl[5] = IE_IRQ5; - cpu_irq_nr[5] = FPU; + /* IRQ routing. */ + memcpy(&dec_interrupt, &kn02ba_interrupt, + sizeof(kn02ba_interrupt)); + + /* CPU IRQ priorities. */ + memcpy(&cpu_mask_nr_tbl, &kn02ba_cpu_mask_nr_tbl, + sizeof(kn02ba_cpu_mask_nr_tbl)); + + /* I/O ASIC IRQ priorities. */ + memcpy(&asic_mask_nr_tbl, &kn02ba_asic_mask_nr_tbl, + sizeof(kn02ba_asic_mask_nr_tbl)); + + mips_cpu_irq_init(DEC_CPU_IRQ_BASE); + init_ioasic_irqs(IO_IRQ_BASE); - dec_halt_init(&irq10); } /* dec_init_kn02ba */ + /* - * Machine-specific initialisation for kn02ca, aka maxine, aka DS5000/2x. + * Machine-specific initialisation for KN02-CA, aka DS5000/xx, + * (xx = 20, 25, 33), aka MAXine. Also applies to KN04(-CA), aka + * DS5000/50, aka 4MAXine. */ +static int kn02ca_interrupt[DEC_NR_INTS] __initdata = { + [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_CASCADE), + [DEC_IRQ_AB_RECV] = IO_IRQ_NR(KN02CA_IO_INR_AB_RECV), + [DEC_IRQ_AB_XMIT] = IO_IRQ_NR(KN02CA_IO_INR_AB_XMIT), + [DEC_IRQ_DZ11] = -1, + [DEC_IRQ_ASC] = IO_IRQ_NR(KN02CA_IO_INR_ASC), + [DEC_IRQ_FLOPPY] = IO_IRQ_NR(KN02CA_IO_INR_FLOPPY), + [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU), + [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_HALT), + [DEC_IRQ_ISDN] = IO_IRQ_NR(KN02CA_IO_INR_ISDN), + [DEC_IRQ_LANCE] = IO_IRQ_NR(KN02CA_IO_INR_LANCE), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS), + [DEC_IRQ_PSU] = -1, + [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC), + [DEC_IRQ_SCC0] = IO_IRQ_NR(KN02CA_IO_INR_SCC0), + [DEC_IRQ_SCC1] = -1, + [DEC_IRQ_SII] = -1, + [DEC_IRQ_TC0] = IO_IRQ_NR(KN02CA_IO_INR_TC0), + [DEC_IRQ_TC1] = IO_IRQ_NR(KN02CA_IO_INR_TC1), + [DEC_IRQ_TC2] = -1, + [DEC_IRQ_TIMER] = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_TIMER), + [DEC_IRQ_VIDEO] = IO_IRQ_NR(KN02CA_IO_INR_VIDEO), + [DEC_IRQ_ASC_MERR] = IO_IRQ_NR(IO_INR_ASC_MERR), + [DEC_IRQ_ASC_ERR] = IO_IRQ_NR(IO_INR_ASC_ERR), + [DEC_IRQ_ASC_DMA] = IO_IRQ_NR(IO_INR_ASC_DMA), + [DEC_IRQ_FLOPPY_ERR] = IO_IRQ_NR(IO_INR_FLOPPY_ERR), + [DEC_IRQ_ISDN_ERR] = IO_IRQ_NR(IO_INR_ISDN_ERR), + [DEC_IRQ_ISDN_RXDMA] = IO_IRQ_NR(IO_INR_ISDN_RXDMA), + [DEC_IRQ_ISDN_TXDMA] = IO_IRQ_NR(IO_INR_ISDN_TXDMA), + [DEC_IRQ_LANCE_MERR] = IO_IRQ_NR(IO_INR_LANCE_MERR), + [DEC_IRQ_SCC0A_RXERR] = IO_IRQ_NR(IO_INR_SCC0A_RXERR), + [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA), + [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR), + [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA), + [DEC_IRQ_AB_RXERR] = IO_IRQ_NR(IO_INR_AB_RXERR), + [DEC_IRQ_AB_RXDMA] = IO_IRQ_NR(IO_INR_AB_RXDMA), + [DEC_IRQ_AB_TXERR] = IO_IRQ_NR(IO_INR_AB_TXERR), + [DEC_IRQ_AB_TXDMA] = IO_IRQ_NR(IO_INR_AB_TXDMA), + [DEC_IRQ_SCC1A_RXERR] = -1, + [DEC_IRQ_SCC1A_RXDMA] = -1, + [DEC_IRQ_SCC1A_TXERR] = -1, + [DEC_IRQ_SCC1A_TXDMA] = -1, +}; + +static int_ptr kn02ca_cpu_mask_nr_tbl[][2] __initdata = { + { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN02CA_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN02CA_CPU_INR_CASCADE) }, + { .p = kn02xa_io_int } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, +}; + +static int_ptr kn02ca_asic_mask_nr_tbl[][2] __initdata = { + { { .i = IO_IRQ_DMA }, + { .p = asic_dma_int } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_SCC0) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_SCC0) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_ASC) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_ASC) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_LANCE) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_LANCE) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC1) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_TC1) } }, + { { .i = IO_IRQ_MASK(KN02CA_IO_INR_TC0) }, + { .i = IO_IRQ_NR(KN02CA_IO_INR_TC0) } }, + { { .i = IO_IRQ_ALL }, + { .p = asic_all_int } }, +}; + void __init dec_init_kn02ca(void) { - /* - * Setup some memory addresses. FIXME: probably incomplete! - */ - ioasic_base = (void *) KN02XA_IOASIC_BASE; - dec_rtc_base = (char *) KN02XA_RTC_BASE; - isr = (void *) KN02XA_IOASIC_REG(SIR); - imr = (void *) KN02XA_IOASIC_REG(SIMR); - - /* - * Setup IOASIC interrupt - */ - cpu_ivec_tbl[1] = kn02xa_io_int; - cpu_irq_nr[1] = -1; - cpu_mask_tbl[1] = IE_IRQ3; - *imr = 0; - - /* - * Setup interrupt structure - */ - dec_interrupt[CLOCK].cpu_mask = IE_IRQ1; - dec_interrupt[CLOCK].iemask = 0; - cpu_mask_tbl[0] = IE_IRQ1; - cpu_irq_nr[0] = CLOCK; - - dec_interrupt[SCSI_DMA_INT].cpu_mask = IE_IRQ3; - dec_interrupt[SCSI_DMA_INT].iemask = SCSI_DMA_INTS; - asic_mask_tbl[0] = SCSI_DMA_INTS; - asic_irq_nr[0] = SCSI_DMA_INT; - - dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ3; - dec_interrupt[SCSI_INT].iemask = SCSI_CHIP; - asic_mask_tbl[1] = SCSI_CHIP; - asic_irq_nr[1] = SCSI_INT; - - dec_interrupt[ETHER].cpu_mask = IE_IRQ3; - dec_interrupt[ETHER].iemask = LANCE_INTS; - asic_mask_tbl[2] = LANCE_INTS; - asic_irq_nr[2] = ETHER; - - dec_interrupt[SERIAL].cpu_mask = IE_IRQ3; - dec_interrupt[SERIAL].iemask = XINE_SERIAL_INTS; - asic_mask_tbl[3] = XINE_SERIAL_INTS; - asic_irq_nr[3] = SERIAL; - - dec_interrupt[TC0].cpu_mask = IE_IRQ3; - dec_interrupt[TC0].iemask = MAXINE_TC0; - asic_mask_tbl[4] = MAXINE_TC0; - asic_irq_nr[4] = TC0; - - dec_interrupt[TC1].cpu_mask = IE_IRQ3; - dec_interrupt[TC1].iemask = MAXINE_TC1; - asic_mask_tbl[5] = MAXINE_TC1; - asic_irq_nr[5] = TC1; - - dec_interrupt[MEMORY].cpu_mask = IE_IRQ2; - dec_interrupt[MEMORY].iemask = 0; - cpu_mask_tbl[2] = IE_IRQ2; - cpu_irq_nr[2] = MEMORY; - - dec_interrupt[HALT].cpu_mask = IE_IRQ4; - dec_interrupt[HALT].iemask = 0; - cpu_mask_tbl[3] = IE_IRQ4; - cpu_irq_nr[3] = HALT; - - dec_interrupt[FPU].cpu_mask = IE_IRQ5; - dec_interrupt[FPU].iemask = 0; - cpu_mask_tbl[4] = IE_IRQ5; - cpu_irq_nr[4] = FPU; + /* IRQ routing. */ + memcpy(&dec_interrupt, &kn02ca_interrupt, + sizeof(kn02ca_interrupt)); + + /* CPU IRQ priorities. */ + memcpy(&cpu_mask_nr_tbl, &kn02ca_cpu_mask_nr_tbl, + sizeof(kn02ca_cpu_mask_nr_tbl)); + + /* I/O ASIC IRQ priorities. */ + memcpy(&asic_mask_nr_tbl, &kn02ca_asic_mask_nr_tbl, + sizeof(kn02ca_asic_mask_nr_tbl)); + + mips_cpu_irq_init(DEC_CPU_IRQ_BASE); + init_ioasic_irqs(IO_IRQ_BASE); - dec_halt_init(&irq10); } /* dec_init_kn02ca */ + /* - * Machine-specific initialisation for kn03, aka 3max+, aka DS5000/240. + * Machine-specific initialisation for KN03, aka DS5000/240, + * aka 3max+ and DS5900, aka BIGmax. Also applies to KN05, aka + * DS5000/260, aka 4max+ and DS5900/260. */ +static int kn03_interrupt[DEC_NR_INTS] __initdata = { + [DEC_IRQ_CASCADE] = DEC_CPU_IRQ_NR(KN03_CPU_INR_CASCADE), + [DEC_IRQ_AB_RECV] = -1, + [DEC_IRQ_AB_XMIT] = -1, + [DEC_IRQ_DZ11] = -1, + [DEC_IRQ_ASC] = IO_IRQ_NR(KN03_IO_INR_ASC), + [DEC_IRQ_FLOPPY] = -1, + [DEC_IRQ_FPU] = DEC_CPU_IRQ_NR(DEC_CPU_INR_FPU), + [DEC_IRQ_HALT] = DEC_CPU_IRQ_NR(KN03_CPU_INR_HALT), + [DEC_IRQ_ISDN] = -1, + [DEC_IRQ_LANCE] = IO_IRQ_NR(KN03_IO_INR_LANCE), + [DEC_IRQ_BUS] = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS), + [DEC_IRQ_PSU] = IO_IRQ_NR(KN03_IO_INR_PSU), + [DEC_IRQ_RTC] = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC), + [DEC_IRQ_SCC0] = IO_IRQ_NR(KN03_IO_INR_SCC0), + [DEC_IRQ_SCC1] = IO_IRQ_NR(KN03_IO_INR_SCC1), + [DEC_IRQ_SII] = -1, + [DEC_IRQ_TC0] = IO_IRQ_NR(KN03_IO_INR_TC0), + [DEC_IRQ_TC1] = IO_IRQ_NR(KN03_IO_INR_TC1), + [DEC_IRQ_TC2] = IO_IRQ_NR(KN03_IO_INR_TC2), + [DEC_IRQ_TIMER] = -1, + [DEC_IRQ_VIDEO] = -1, + [DEC_IRQ_ASC_MERR] = IO_IRQ_NR(IO_INR_ASC_MERR), + [DEC_IRQ_ASC_ERR] = IO_IRQ_NR(IO_INR_ASC_ERR), + [DEC_IRQ_ASC_DMA] = IO_IRQ_NR(IO_INR_ASC_DMA), + [DEC_IRQ_FLOPPY_ERR] = -1, + [DEC_IRQ_ISDN_ERR] = -1, + [DEC_IRQ_ISDN_RXDMA] = -1, + [DEC_IRQ_ISDN_TXDMA] = -1, + [DEC_IRQ_LANCE_MERR] = IO_IRQ_NR(IO_INR_LANCE_MERR), + [DEC_IRQ_SCC0A_RXERR] = IO_IRQ_NR(IO_INR_SCC0A_RXERR), + [DEC_IRQ_SCC0A_RXDMA] = IO_IRQ_NR(IO_INR_SCC0A_RXDMA), + [DEC_IRQ_SCC0A_TXERR] = IO_IRQ_NR(IO_INR_SCC0A_TXERR), + [DEC_IRQ_SCC0A_TXDMA] = IO_IRQ_NR(IO_INR_SCC0A_TXDMA), + [DEC_IRQ_AB_RXERR] = -1, + [DEC_IRQ_AB_RXDMA] = -1, + [DEC_IRQ_AB_TXERR] = -1, + [DEC_IRQ_AB_TXDMA] = -1, + [DEC_IRQ_SCC1A_RXERR] = IO_IRQ_NR(IO_INR_SCC1A_RXERR), + [DEC_IRQ_SCC1A_RXDMA] = IO_IRQ_NR(IO_INR_SCC1A_RXDMA), + [DEC_IRQ_SCC1A_TXERR] = IO_IRQ_NR(IO_INR_SCC1A_TXERR), + [DEC_IRQ_SCC1A_TXDMA] = IO_IRQ_NR(IO_INR_SCC1A_TXDMA), +}; + +static int_ptr kn03_cpu_mask_nr_tbl[][2] __initdata = { + { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_BUS) }, + { .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_BUS) } }, + { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_RTC) }, + { .i = DEC_CPU_IRQ_NR(KN03_CPU_INR_RTC) } }, + { { .i = DEC_CPU_IRQ_MASK(KN03_CPU_INR_CASCADE) }, + { .p = kn03_io_int } }, + { { .i = DEC_CPU_IRQ_ALL }, + { .p = cpu_all_int } }, +}; + +static int_ptr kn03_asic_mask_nr_tbl[][2] __initdata = { + { { .i = IO_IRQ_DMA }, + { .p = asic_dma_int } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_SCC0) }, + { .i = IO_IRQ_NR(KN03_IO_INR_SCC0) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_SCC1) }, + { .i = IO_IRQ_NR(KN03_IO_INR_SCC1) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_ASC) }, + { .i = IO_IRQ_NR(KN03_IO_INR_ASC) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_LANCE) }, + { .i = IO_IRQ_NR(KN03_IO_INR_LANCE) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_TC2) }, + { .i = IO_IRQ_NR(KN03_IO_INR_TC2) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_TC1) }, + { .i = IO_IRQ_NR(KN03_IO_INR_TC1) } }, + { { .i = IO_IRQ_MASK(KN03_IO_INR_TC0) }, + { .i = IO_IRQ_NR(KN03_IO_INR_TC0) } }, + { { .i = IO_IRQ_ALL }, + { .p = asic_all_int } }, +}; + void __init dec_init_kn03(void) { - /* - * Setup some memory addresses. FIXME: probably incomplete! - */ - ioasic_base = (void *) KN03_IOASIC_BASE; - dec_rtc_base = (char *) KN03_RTC_BASE; - isr = (void *) KN03_IOASIC_REG(SIR); - imr = (void *) KN03_IOASIC_REG(SIMR); - - /* - * Setup IOASIC interrupt - */ - cpu_ivec_tbl[1] = kn03_io_int; - cpu_mask_tbl[1] = IE_IRQ0; - cpu_irq_nr[1] = -1; - *imr = 0; - - /* - * Setup interrupt structure - */ - dec_interrupt[CLOCK].cpu_mask = IE_IRQ1; - dec_interrupt[CLOCK].iemask = 0; - cpu_mask_tbl[0] = IE_IRQ1; - cpu_irq_nr[0] = CLOCK; - - dec_interrupt[SCSI_DMA_INT].cpu_mask = IE_IRQ0; - dec_interrupt[SCSI_DMA_INT].iemask = SCSI_DMA_INTS; - asic_mask_tbl[0] = SCSI_DMA_INTS; - asic_irq_nr[0] = SCSI_DMA_INT; - - dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0; - dec_interrupt[SCSI_INT].iemask = SCSI_CHIP; - asic_mask_tbl[1] = SCSI_CHIP; - asic_irq_nr[1] = SCSI_INT; - - dec_interrupt[ETHER].cpu_mask = IE_IRQ0; - dec_interrupt[ETHER].iemask = LANCE_INTS; - asic_mask_tbl[2] = LANCE_INTS; - asic_irq_nr[2] = ETHER; - - dec_interrupt[SERIAL].cpu_mask = IE_IRQ0; - dec_interrupt[SERIAL].iemask = SERIAL_INTS; - asic_mask_tbl[3] = SERIAL_INTS; - asic_irq_nr[3] = SERIAL; - - dec_interrupt[TC0].cpu_mask = IE_IRQ0; - dec_interrupt[TC0].iemask = KN03_TC0; - asic_mask_tbl[4] = KN03_TC0; - asic_irq_nr[4] = TC0; - - dec_interrupt[TC1].cpu_mask = IE_IRQ0; - dec_interrupt[TC1].iemask = KN03_TC1; - asic_mask_tbl[5] = KN03_TC1; - asic_irq_nr[5] = TC1; - - dec_interrupt[TC2].cpu_mask = IE_IRQ0; - dec_interrupt[TC2].iemask = KN03_TC2; - asic_mask_tbl[6] = KN03_TC2; - asic_irq_nr[6] = TC2; - - dec_interrupt[MEMORY].cpu_mask = IE_IRQ3; - dec_interrupt[MEMORY].iemask = 0; - cpu_mask_tbl[2] = IE_IRQ3; - cpu_irq_nr[2] = MEMORY; - - dec_interrupt[HALT].cpu_mask = IE_IRQ4; - dec_interrupt[HALT].iemask = 0; - cpu_mask_tbl[3] = IE_IRQ4; - cpu_irq_nr[3] = HALT; - - dec_interrupt[FPU].cpu_mask = IE_IRQ5; - dec_interrupt[FPU].iemask = 0; - cpu_mask_tbl[4] = IE_IRQ5; - cpu_irq_nr[4] = FPU; + /* IRQ routing. */ + memcpy(&dec_interrupt, &kn03_interrupt, + sizeof(kn03_interrupt)); + + /* CPU IRQ priorities. */ + memcpy(&cpu_mask_nr_tbl, &kn03_cpu_mask_nr_tbl, + sizeof(kn03_cpu_mask_nr_tbl)); + + /* I/O ASIC IRQ priorities. */ + memcpy(&asic_mask_nr_tbl, &kn03_asic_mask_nr_tbl, + sizeof(kn03_asic_mask_nr_tbl)); + + mips_cpu_irq_init(DEC_CPU_IRQ_BASE); + init_ioasic_irqs(IO_IRQ_BASE); - dec_halt_init(&irq10); } /* dec_init_kn03 */ + + +void __init init_IRQ(void) +{ + switch (mips_machtype) { + case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */ + dec_init_kn01(); + break; + case MACH_DS5100: /* DS5100 MIPSmate */ + dec_init_kn230(); + break; + case MACH_DS5000_200: /* DS5000/200 3max */ + dec_init_kn02(); + break; + case MACH_DS5000_1XX: /* DS5000/1xx 3min */ + dec_init_kn02ba(); + break; + case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + case MACH_DS5900: /* DS5900 bigmax */ + dec_init_kn03(); + break; + case MACH_DS5000_XX: /* Personal DS5000/xx */ + dec_init_kn02ca(); + break; + case MACH_DS5800: /* DS5800 Isis */ + panic("Don't know how to set this up!"); + break; + case MACH_DS5400: /* DS5400 MIPSfair */ + panic("Don't know how to set this up!"); + break; + case MACH_DS5500: /* DS5500 MIPSfair-2 */ + panic("Don't know how to set this up!"); + break; + } + set_except_vector(0, decstation_handle_int); + + /* Free the FPU interrupt if the exception is present. */ + if (!cpu_has_nofpuex) { + cpu_fpu_mask = 0; + dec_interrupt[DEC_IRQ_FPU] = -1; + } + + /* Register board interrupts: FPU and cascade. */ + if (dec_interrupt[DEC_IRQ_FPU] >= 0) + setup_irq(dec_interrupt[DEC_IRQ_FPU], &fpuirq); + if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) + setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq); + + /* Register the bus error interrupt. */ + if (dec_interrupt[DEC_IRQ_BUS] >= 0 && busirq.handler) + setup_irq(dec_interrupt[DEC_IRQ_BUS], &busirq); + + /* Register the HALT interrupt. */ + if (dec_interrupt[DEC_IRQ_HALT] >= 0) + setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq); +} + +EXPORT_SYMBOL(ioasic_base); +EXPORT_SYMBOL(dec_kn_slot_size); +EXPORT_SYMBOL(dec_interrupt); diff -Nru a/arch/mips/dec/time.c b/arch/mips/dec/time.c --- a/arch/mips/dec/time.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/dec/time.c Fri Jun 27 14:20:00 2003 @@ -2,12 +2,14 @@ * linux/arch/mips/dec/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * Copyright (C) 2000 Maciej W. Rozycki + * Copyright (C) 2000, 2003 Maciej W. Rozycki * * This file contains the time handling details for PC-style clocks as * found in some MIPS systems. * */ +#include <linux/bcd.h> +#include <linux/types.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/sched.h> @@ -45,7 +47,9 @@ /* This is for machines which generate the exact clock. */ #define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff) +#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) + +#define TICK_SIZE (tick_nsec / 1000) /* Cycle counter value at the previous timer interrupt.. */ @@ -99,7 +103,7 @@ } } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -110,7 +114,7 @@ : "r" (count), "r" (quotient)); /* - * Due to possible jiffies inconsistencies, we need to check + * Due to possible jiffies inconsistencies, we need to check * the result so that we'll get a timer that is monotonic. */ if (res >= USECS_PER_JIFFY) @@ -140,7 +144,7 @@ } } /* Get last timer tick in absolute kernel time */ - count = ioasic_read(FCTR); + count = ioasic_read(IO_REG_FCTR); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -160,9 +164,9 @@ return res; } -/* This function must be called with interrupts disabled +/* This function must be called with interrupts disabled * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs - * + * * However, the pc-audio speaker driver changes the divisor so that * it gets interrupted rather more often - it loads 64 into the * counter rather than 11932! This has an adverse impact on @@ -176,7 +180,7 @@ * using either the RTC or the 8253 timer. The decision would be * based on whether there was any other device around that needed * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz, - * and then do some jiggery to have a version of do_timer that + * and then do some jiggery to have a version of do_timer that * advanced the clock by 1/1024 s. Every time that reached over 1/100 * of a second, then do all the old code. If the time was kept correct * then do_gettimeoffset could just return 0 - there is no low order @@ -187,13 +191,11 @@ * often than every 120 us or so. * * Anyway, this needs more thought.... pjsg (1993-08-28) - * + * * If you are really that interested, you should be reading * comp.protocols.time.ntp! */ -#define TICK_SIZE tick - static unsigned long do_slow_gettimeoffset(void) { /* @@ -206,57 +208,58 @@ static unsigned long (*do_gettimeoffset) (void) = do_slow_gettimeoffset; /* - * This version of gettimeofday has near microsecond resolution. + * This version of gettimeofday has microsecond resolution + * and better than microsecond precision on fast x86 machines with TSC. */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; unsigned long seq; + unsigned long usec, sec; do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - + seq = read_seqbegin(&xtime_lock); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry(&xtime_lock, seq)); - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + while (usec >= 1000000) { + usec -= 1000000; + sec++; } + + tv->tv_sec = sec; + tv->tv_usec = usec; } void do_settimeofday(struct timeval *tv) { write_seqlock_irq(&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } - xtime = *tv; + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = (tv->tv_usec * 1000); time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - write_sequnlock_irq(&xtime_lock); } @@ -281,7 +284,7 @@ cmos_minutes = CMOS_READ(RTC_MINUTES); if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); + cmos_minutes = BCD2BIN(cmos_minutes); /* * since we're only adjusting minutes and seconds, @@ -297,8 +300,8 @@ if (abs(real_minutes - cmos_minutes) < 30) { if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); + real_seconds = BIN2BCD(real_seconds); + real_minutes = BIN2BCD(real_minutes); } CMOS_WRITE(real_seconds, RTC_SECONDS); CMOS_WRITE(real_minutes, RTC_MINUTES); @@ -366,8 +369,8 @@ if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - tick / 2 - && xtime.tv_usec <= 500000 + tick / 2) { + && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 + && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else @@ -381,7 +384,7 @@ rigged to be safe on the 386 - basically it's a hack, so don't look closely for now.. */ /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */ - + write_sequnlock(&xtime_lock); } static void r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) @@ -392,7 +395,7 @@ * The cycle counter is only 32 bit which is good for about * a minute at current count rates of upto 150MHz or so. */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -402,7 +405,7 @@ * update the timer[hi]/[lo] to make do_fast_gettimeoffset() * quotient calc still valid. -arca */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); timerhi = timerlo = 0; } @@ -417,7 +420,7 @@ * The free-running counter is 32 bit which is good for about * 2 minutes, 50 seconds at possible count rates of upto 25MHz. */ - count = ioasic_read(FCTR); + count = ioasic_read(IO_REG_FCTR); timerhi += (count < timerlo); /* Wrap around */ timerlo = count; @@ -427,15 +430,18 @@ * update the timer[hi]/[lo] to make do_fast_gettimeoffset() * quotient calc still valid. -arca */ - ioasic_write(FCTR, 0); + ioasic_write(IO_REG_FCTR, 0); timerhi = timerlo = 0; } timer_interrupt(irq, dev_id, regs); } -struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; +struct irqaction irq0 = { + .handler = timer_interrupt, + .flags = SA_INTERRUPT, + .name = "timer", +}; void __init time_init(void) { @@ -463,12 +469,12 @@ year = CMOS_READ(RTC_YEAR); } while (sec != CMOS_READ(RTC_SECONDS)); if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || 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); + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + day = BCD2BIN(day); + mon = BCD2BIN(mon); + year = BCD2BIN(year); } /* * The PROM will reset the year to either '72 or '73. @@ -480,15 +486,15 @@ write_seqlock_irq(&xtime_lock); xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_usec = 0; + xtime.tv_nsec = 0; write_sequnlock_irq(&xtime_lock); - if (mips_cpu.options & MIPS_CPU_COUNTER) { - write_32bit_cp0_register(CP0_COUNT, 0); + if (cpu_has_counter) { + write_c0_count(0); do_gettimeoffset = do_fast_gettimeoffset; irq0.handler = r4k_timer_interrupt; } else if (IOASIC) { - ioasic_write(FCTR, 0); + ioasic_write(IO_REG_FCTR, 0); do_gettimeoffset = do_ioasic_gettimeoffset; irq0.handler = ioasic_timer_interrupt; } diff -Nru a/arch/mips/dec/wbflush.c b/arch/mips/dec/wbflush.c --- a/arch/mips/dec/wbflush.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/dec/wbflush.c Fri Jun 27 14:20:00 2003 @@ -11,15 +11,18 @@ * for more details. * * Copyright (C) 1998 Harald Koerfgen + * Copyright (C) 2002 Maciej W. Rozycki */ -#include <asm/bootinfo.h> #include <linux/init.h> +#include <asm/bootinfo.h> +#include <asm/system.h> +#include <asm/wbflush.h> + static void wbflush_kn01(void); static void wbflush_kn210(void); -static void wbflush_kn02ba(void); -static void wbflush_kn03(void); +static void wbflush_mips(void); void (*__wbflush) (void); @@ -27,28 +30,24 @@ { switch (mips_machtype) { case MACH_DS23100: - __wbflush = wbflush_kn01; - break; - case MACH_DS5100: /* DS5100 MIPSMATE */ - __wbflush = wbflush_kn210; - break; case MACH_DS5000_200: /* DS5000 3max */ - __wbflush = wbflush_kn01; - break; + __wbflush = wbflush_kn01; + break; + case MACH_DS5100: /* DS5100 MIPSMATE */ + __wbflush = wbflush_kn210; + break; case MACH_DS5000_1XX: /* DS5000/100 3min */ - __wbflush = wbflush_kn02ba; - break; - case MACH_DS5000_2X0: /* DS5000/240 3max+ */ - __wbflush = wbflush_kn03; - break; case MACH_DS5000_XX: /* Personal DS5000/2x */ - __wbflush = wbflush_kn02ba; - break; + case MACH_DS5000_2X0: /* DS5000/240 3max+ */ + case MACH_DS5900: /* DS5900 bigmax */ + default: + __wbflush = wbflush_mips; + break; } } /* - * For the DS3100 and DS5000/200 the writeback buffer functions + * For the DS3100 and DS5000/200 the R2020/R3220 writeback buffer functions * as part of Coprocessor 0. */ static void wbflush_kn01(void) @@ -78,29 +77,16 @@ "mtc0\t$2,$12\n\t" "nop\n\t" ".set\tpop" - : : :"$2", "$3"); -} - -/* - * Looks like some magic with the System Interrupt Mask Register - * in the famous IOASIC for kmins and maxines. - */ -static void wbflush_kn02ba(void) -{ - asm(".set\tpush\n\t" - ".set\tnoreorder\n\t" - "lui\t$2,0xbc04\n\t" - "lw\t$3,0x120($2)\n\t" - "lw\t$3,0x120($2)\n\t" - ".set\tpop" - : : :"$2", "$3"); + : : : "$2", "$3"); } /* - * The DS500/2x0 doesn't need to write back the WB. + * I/O ASIC systems use a standard writeback buffer that gets flushed + * upon an uncached read. */ -static void wbflush_kn03(void) +static void wbflush_mips(void) { + __fast_iob(); } #include <linux/module.h> diff -Nru a/arch/mips/defconfig b/arch/mips/defconfig --- a/arch/mips/defconfig Fri Jun 27 14:19:53 2003 +++ b/arch/mips/defconfig Fri Jun 27 14:19:53 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,89 +11,123 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set CONFIG_SGI_IP22=y +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_ARC=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 CONFIG_ARC32=y +# CONFIG_FB is not set +CONFIG_ARC_CONSOLE=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y -CONFIG_PC_KEYB=y -CONFIG_SGI=y -CONFIG_NEW_IRQ=y -CONFIG_OLD_TIME_C=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_PCI is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set CONFIG_CPU_R5000=y # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +# CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ISA is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats # -# CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -CONFIG_BINFMT_IRIX=y -CONFIG_FORWARD_KEYBOARD=y -# CONFIG_ARC_CONSOLE is not set -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +CONFIG_BINFMT_IRIX=y # # Memory Technology Devices (MTD) @@ -105,41 +140,90 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SGIWD93_SCSI=y +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set @@ -153,20 +237,24 @@ # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -179,87 +267,10 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_SR_EXTRA_DEVS=2 -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -CONFIG_SGIWD93_SCSI=y -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -270,33 +281,16 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set CONFIG_SGISEEQ=y # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -306,11 +300,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -331,21 +322,69 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input device support +# +CONFIG_INPUT=y + # -# CONFIG_CD_NO_IDESCSI is not set +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IP22_ZILOG=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -355,36 +394,58 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +CONFIG_INDYDOG=y +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -392,6 +453,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -399,89 +462,92 @@ # CONFIG_VIDEO_DEV is not set # -# SGI Character devices +# Digital Video Broadcasting Devices # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -# CONFIG_PSMOUSE is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_DVB is not set # # File systems # +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -498,22 +564,33 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +# CONFIG_EFI_PARTITION is not set # -# Console drivers +# Graphics support +# + +# +# Console display driver support # # CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FONT_8x16=y # -# Frame-buffer support +# Logo configuration # -# CONFIG_FB is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_SGI_CLUT224=y # # Sound @@ -521,124 +598,48 @@ # CONFIG_SOUND is not set # -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set - -# # USB support # -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_GADGET is not set # -# USB Multimedia devices +# Bluetooth support # +# CONFIG_BT is not set # -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-atlas b/arch/mips/defconfig-atlas --- a/arch/mips/defconfig-atlas Fri Jun 27 14:19:55 2003 +++ b/arch/mips/defconfig-atlas Fri Jun 27 14:19:55 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,82 +11,116 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set CONFIG_MIPS_ATLAS=y -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_PCI=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_MIPS_BOARDS_GEN=y CONFIG_SWAP_IO_SPACE=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set # # CPU selection # +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set -CONFIG_CPU_R5000=y +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +# CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y -CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats # -# CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -CONFIG_BINFMT_IRIX=y -# CONFIG_FORWARD_KEYBOARD is not set -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_PCI_NAMES is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +# CONFIG_BINFMT_IRIX is not set # # Memory Technology Devices (MTD) @@ -98,91 +133,36 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set # -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -# CONFIG_PACKET is not set -# CONFIG_NETLINK is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# SCSI device support # CONFIG_SCSI=y @@ -190,7 +170,6 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set @@ -199,8 +178,8 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set @@ -208,53 +187,115 @@ # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # -# Network device support +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support # +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -265,39 +306,43 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set +# CONFIG_MII is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -307,9 +352,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -332,21 +376,65 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input Device Drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -356,36 +444,35 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set -CONFIG_RTC=y +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -393,6 +480,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -400,86 +489,94 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -CONFIG_EFS_FS=y -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +# CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set + +# +# Graphics support +# # # Sound @@ -490,116 +587,30 @@ # USB support # # CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices +# Bluetooth support # +# CONFIG_BT is not set # -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_LL_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-capcella b/arch/mips/defconfig-capcella --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-capcella Fri Jun 27 14:20:06 2003 @@ -0,0 +1,612 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +CONFIG_ZAO_CAPCELLA=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +CONFIG_NEW_PCI=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_IDEPCI is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-cobalt b/arch/mips/defconfig-cobalt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-cobalt Fri Jun 27 14:20:06 2003 @@ -0,0 +1,576 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +CONFIG_MIPS_COBALT=y +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_I8259=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_COBALT_LCD=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +CONFIG_CPU_NEVADA=y +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_IDEPCI is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=16 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +CONFIG_HANGCHECK_TIMER=y + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-ddb5476 b/arch/mips/defconfig-ddb5476 --- a/arch/mips/defconfig-ddb5476 Fri Jun 27 14:20:05 2003 +++ b/arch/mips/defconfig-ddb5476 Fri Jun 27 14:20:05 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,90 +11,113 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set CONFIG_DDB5476=y # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_ISA=y -CONFIG_PCI=y -CONFIG_PC_KEYB=y -CONFIG_ROTTEN_IRQ=y +CONFIG_I8259=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_DDB5XXX_COMMON=y +CONFIG_NEW_PCI=y +CONFIG_FB=y CONFIG_HAVE_STD_PC_SERIAL_PORT=y -CONFIG_NEW_TIME_C=y -CONFIG_EISA=y -# CONFIG_I8259 is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set CONFIG_CPU_R5432=y -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) # -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_PCI_NAMES is not set +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y # -# Plug and Play configuration +# Executable file formats # -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set -# CONFIG_PNPBIOS is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set # # Memory Technology Devices (MTD) @@ -106,39 +130,93 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_IDEPCI is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK is not set +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -148,22 +226,27 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -176,84 +259,9 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_IDEPCI_SHARE_IRQ is not set -# CONFIG_BLK_DEV_IDEDMA_PCI is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_AMD74XX_OVERRIDE is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -264,70 +272,43 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set +# CONFIG_MII is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_TULIP=y -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=y -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -CONFIG_NE2K_PCI=y -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_LAN_SAA9730 is not set -# CONFIG_NET_POCKET is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -337,10 +318,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -362,22 +341,67 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input I/O drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # CONFIG_VT=y # CONFIG_VT_CONSOLE is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -387,39 +411,35 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -427,6 +447,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -434,238 +456,157 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Console drivers -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set # -# Frame-buffer support +# Graphics support # -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FB_RIVA is not set -# CONFIG_FB_CLGEN is not set +# CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_E1355 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set -# CONFIG_FB_ATY is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set # CONFIG_FB_SIS is not set -CONFIG_FB_3DFX=y +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_E1356 is not set # CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_CFB32=y -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -# CONFIG_FBCON_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Sound -# -# CONFIG_SOUND is not set # -# USB support -# -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - +# Console display driver support # -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set # -# USB Multimedia devices +# Logo configuration # +# CONFIG_LOGO is not set # -# Video4Linux support is needed for USB Multimedia device support +# Sound # -# CONFIG_USB_DABUSB is not set +# CONFIG_SOUND is not set # -# USB Network adaptors +# USB support # -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# USB port drivers +# Bluetooth support # -# CONFIG_USB_USS720 is not set +# CONFIG_BT is not set # -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_LL_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-ddb5477 b/arch/mips/defconfig-ddb5477 --- a/arch/mips/defconfig-ddb5477 Fri Jun 27 14:19:54 2003 +++ b/arch/mips/defconfig-ddb5477 Fri Jun 27 14:19:54 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,82 +11,114 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set CONFIG_DDB5477=y +CONFIG_DDB5477_BUS_FREQUENCY=0 +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_I8259=y +CONFIG_NONCOHERENT_IO=y CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_PCI=y -CONFIG_NEW_TIME_C=y -CONFIG_NEW_IRQ=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +CONFIG_IRQ_CPU=y +CONFIG_DUMMY_KEYB=y +CONFIG_DDB5XXX_COMMON=y +CONFIG_NEW_PCI=y +# CONFIG_FB is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set CONFIG_CPU_R5432=y -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats # -CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_PCI_NAMES is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y # # Memory Technology Devices (MTD) @@ -98,39 +131,71 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK is not set +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -140,22 +205,27 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -168,27 +238,9 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -199,67 +251,43 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set +# CONFIG_MII is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_TULIP=y -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -# CONFIG_EEPRO100 is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_LAN_SAA9730 is not set -# CONFIG_NET_POCKET is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -269,10 +297,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -294,22 +320,67 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input device support # -# CONFIG_CD_NO_IDESCSI is not set +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_UNIX98_PTYS is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 # # I2C support @@ -317,36 +388,35 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -354,6 +424,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -361,206 +433,158 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set # -# Sound +# Graphics support # -# CONFIG_SOUND is not set # -# USB support -# -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices +# Sound # -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +CONFIG_SOUND=y # -# USB Multimedia devices +# Advanced Linux Sound Architecture # +# CONFIG_SND is not set # -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set +# Open Sound System +# +CONFIG_SOUND_PRIME=y +# CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_MAESTRO3 is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_RME96XX is not set +# CONFIG_SOUND_SONICVIBES is not set +CONFIG_SOUND_VRC5477=y +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +# CONFIG_SOUND_OSS is not set # -# USB Network adaptors +# USB support # -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# USB port drivers +# Bluetooth support # -# CONFIG_USB_USS720 is not set +# CONFIG_BT is not set # -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -CONFIG_LL_DEBUG=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation --- a/arch/mips/defconfig-decstation Fri Jun 27 14:20:06 2003 +++ b/arch/mips/defconfig-decstation Fri Jun 27 14:20:06 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,81 +11,113 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set CONFIG_DECSTATION=y -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_PCI is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=4 +# CONFIG_FB is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set CONFIG_CPU_R3000=y -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_ADVANCED is not set -# CONFIG_CPU_HAS_LLSC is not set -# CONFIG_CPU_HAS_LLDSCD is not set -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_WB=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_TC=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats # -CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_TC=y # # Memory Technology Devices (MTD) @@ -97,39 +130,90 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SCSI_DECNCR=y +# CONFIG_SCSI_DECSII is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK is not set +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -139,22 +223,27 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -167,122 +256,30 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -CONFIG_SCSI_DECNCR=y -# CONFIG_SCSI_DECSII is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set CONFIG_DECLANCE=y # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -292,11 +289,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -317,21 +311,64 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y # -# Old CD-ROM drivers (not SCSI, not IDE) +# Userland interfaces # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_DZ=y +CONFIG_SERIAL_DZ_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -341,36 +378,35 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -378,6 +414,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -385,90 +423,81 @@ # CONFIG_VIDEO_DEV is not set # -# DECStation Character devices +# Digital Video Broadcasting Devices # -# CONFIG_VT is not set -CONFIG_SERIAL=y -# CONFIG_DZ is not set -CONFIG_ZS=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_RTC is not set +# CONFIG_DVB is not set # # File systems # +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set # CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set +# CONFIG_EXPORTFS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -485,126 +514,48 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set CONFIG_ULTRIX_PARTITION=y # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# USB support -# -# CONFIG_USB is not set +# CONFIG_EFI_PARTITION is not set # -# USB Controllers +# Graphics support # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set # -# USB Device Class drivers +# Sound # -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_SOUND is not set # -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors +# USB support # -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set +# CONFIG_USB_GADGET is not set # -# USB port drivers +# Bluetooth support # -# CONFIG_USB_USS720 is not set +# CONFIG_BT is not set # -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_LL_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-e55 b/arch/mips/defconfig-e55 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-e55 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,564 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +CONFIG_CASIO_E55=y +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-eagle b/arch/mips/defconfig-eagle --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-eagle Fri Jun 27 14:20:06 2003 @@ -0,0 +1,728 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +CONFIG_NEC_EAGLE=y +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +CONFIG_VRC4173=y +CONFIG_NEW_PCI=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=y +# CONFIG_YENTA is not set +# CONFIG_I82092 is not set +# CONFIG_TCIC is not set +# CONFIG_PCMCIA_VRC4173 is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_CONCAT is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x1c000000 +CONFIG_MTD_PHYSMAP_LEN=0x2000000 +CONFIG_MTD_PHYSMAP_BUSWIDTH=4 + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=y +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_IDEPCI is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +# CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +CONFIG_PCMCIA_FMVJ18X=y +CONFIG_PCMCIA_PCNET=m +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_CS is not set +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=y +CONFIG_JFFS_FS_VERBOSE=0 +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +CONFIG_CRYPTO_TWOFISH=y +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-ev64120 b/arch/mips/defconfig-ev64120 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-ev64120 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,571 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_KMOD is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +CONFIG_MIPS_EV64120=y +# CONFIG_EVB_PCI1 is not set +CONFIG_SYSCLK_100=y +# CONFIG_SYSCLK_75 is not set +# CONFIG_SYSCLK_83 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_CONFIG_GT64120=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_MIPS_GT64120=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_BINFMT_IRIX is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +# CONFIG_PPP_DEFLATE is not set +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-ev96100 b/arch/mips/defconfig-ev96100 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-ev96100 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,523 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +# CONFIG_KMOD is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +CONFIG_MIPS_EV96100=y +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_NEW_PCI=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_GT96100=y +# CONFIG_FB is not set +CONFIG_BOARD_SCACHE=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_BINFMT_IRIX is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MIPS_GT96100ETH=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22 --- a/arch/mips/defconfig-ip22 Fri Jun 27 14:20:05 2003 +++ b/arch/mips/defconfig-ip22 Fri Jun 27 14:20:05 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,89 +11,123 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set CONFIG_SGI_IP22=y +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_ARC=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 CONFIG_ARC32=y +# CONFIG_FB is not set +CONFIG_ARC_CONSOLE=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y -CONFIG_PC_KEYB=y -CONFIG_SGI=y -CONFIG_NEW_IRQ=y -CONFIG_OLD_TIME_C=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_PCI is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set CONFIG_CPU_R5000=y # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set +# CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_LLDSCD=y -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ISA is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats # -# CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -CONFIG_BINFMT_IRIX=y -CONFIG_FORWARD_KEYBOARD=y -# CONFIG_ARC_CONSOLE is not set -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +CONFIG_BINFMT_IRIX=y # # Memory Technology Devices (MTD) @@ -105,41 +140,90 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SGIWD93_SCSI=y +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set @@ -153,20 +237,24 @@ # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -179,87 +267,10 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_SR_EXTRA_DEVS=2 -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -CONFIG_SGIWD93_SCSI=y -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -270,33 +281,16 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set CONFIG_SGISEEQ=y # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -306,11 +300,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -331,21 +322,69 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input device support +# +CONFIG_INPUT=y + # -# CONFIG_CD_NO_IDESCSI is not set +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IP22_ZILOG=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -355,36 +394,58 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +CONFIG_INDYDOG=y +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -392,6 +453,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -399,89 +462,92 @@ # CONFIG_VIDEO_DEV is not set # -# SGI Character devices +# Digital Video Broadcasting Devices # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SGI_NEWPORT_CONSOLE=y -CONFIG_FONT_8x16=y -# CONFIG_PSMOUSE is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_DVB is not set # # File systems # +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -498,22 +564,33 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +# CONFIG_EFI_PARTITION is not set # -# Console drivers +# Graphics support +# + +# +# Console display driver support # # CONFIG_VGA_CONSOLE is not set # CONFIG_MDA_CONSOLE is not set +CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_FONT_8x16=y # -# Frame-buffer support +# Logo configuration # -# CONFIG_FB is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_SGI_CLUT224=y # # Sound @@ -521,124 +598,48 @@ # CONFIG_SOUND is not set # -# SGI devices -# -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set - -# # USB support # -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +# CONFIG_USB_GADGET is not set # -# USB Multimedia devices +# Bluetooth support # +# CONFIG_BT is not set # -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-jmr3927 b/arch/mips/defconfig-jmr3927 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-jmr3927 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,598 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +CONFIG_TOSHIBA_JMR3927=y +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_NEW_PCI=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_FB=y +CONFIG_TOSHIBA_BOARDS=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +CONFIG_CPU_TX39XX=y +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +CONFIG_RTC_DS1742=y + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_BINFMT_IRIX is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +# CONFIG_SERIAL_TX3912 is not set +CONFIG_TXX927_SERIAL=y +CONFIG_TXX927_SERIAL_CONSOLE=y +# CONFIG_SERIAL_TXX9 is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_E1356 is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-lasat200 b/arch/mips/defconfig-lasat200 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-lasat200 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,679 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +CONFIG_LASAT=y +# CONFIG_LASAT_100 is not set +CONFIG_LASAT_200=y +CONFIG_PICVUE=y +CONFIG_PICVUE_PROC=y +CONFIG_DS1603=y +CONFIG_LASAT_SYSCTL=y +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_FB is not set +CONFIG_BOARD_SCACHE=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_R5000_CPU_SCACHE=y +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_NAMES is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_LASAT=y +# CONFIG_MTD_UCLINUX is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDE_TCQ is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +CONFIG_BLK_DEV_ADMA=y +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_BLK_DEV_IDE_MODES=y + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC32=y diff -Nru a/arch/mips/defconfig-malta b/arch/mips/defconfig-malta --- a/arch/mips/defconfig-malta Fri Jun 27 14:19:54 2003 +++ b/arch/mips/defconfig-malta Fri Jun 27 14:19:54 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,82 +11,120 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -CONFIG_MIPS_MALTA=y -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +CONFIG_MIPS_MALTA=y +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_GENERIC_ISA_DMA=y CONFIG_I8259=y -CONFIG_PCI=y -CONFIG_HAVE_STD_PC_SERIAL_PORT=y -CONFIG_NEW_IRQ=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_BOARDS_GEN=y CONFIG_SWAP_IO_SPACE=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set +CONFIG_HAVE_STD_PC_SERIAL_PORT=y # # CPU selection # +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS64 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +# CONFIG_64BIT_PHYS_ADDR is not set # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y -# CONFIG_CPU_HAS_LLDSCD is not set -# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats # -CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_PCI_NAMES is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set # # Memory Technology Devices (MTD) @@ -98,14 +137,19 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y @@ -113,49 +157,98 @@ # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y # # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK is not set +CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -168,162 +261,29 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -CONFIG_PCNET32=y -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -# CONFIG_EEPRO100 is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_LAN_SAA9730 is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -333,11 +293,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -358,21 +315,64 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input Device Drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -382,36 +382,34 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -419,6 +417,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -426,206 +426,130 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set CONFIG_EFS_FS=y -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set # -# Sound +# Graphics support # -# CONFIG_SOUND is not set # -# USB support -# -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support +# Sound # -# CONFIG_USB_DABUSB is not set +# CONFIG_SOUND is not set # -# USB Network adaptors +# USB support # -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set +# CONFIG_USB_GADGET is not set # -# USB port drivers +# Bluetooth support # -# CONFIG_USB_USS720 is not set +# CONFIG_BT is not set # -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_LL_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-mpc30x b/arch/mips/defconfig-mpc30x --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-mpc30x Fri Jun 27 14:20:06 2003 @@ -0,0 +1,543 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +CONFIG_VICTOR_MPC30X=y +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +CONFIG_VRC4173=y +CONFIG_NEW_PCI=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +CONFIG_CRYPTO_TWOFISH=y +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-nino b/arch/mips/defconfig-nino --- a/arch/mips/defconfig-nino Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,416 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_MIPS=y -# CONFIG_SMP is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Machine selection -# -# CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set -# CONFIG_BAGET_MIPS is not set -# CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -CONFIG_NINO=y -# CONFIG_NINO_4MB is not set -CONFIG_NINO_8MB=y -# CONFIG_NINO_16MB is not set -# CONFIG_MIPS_MAGNUM_4000 is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_DDB5476 is not set -# CONFIG_DDB5477 is not set -# CONFIG_OLIVETTI_M700 is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_PB1000 is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_PC_KEYB=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_PCI is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y - -# -# CPU selection -# -CONFIG_CPU_R3000=y -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_SB1 is not set -# CONFIG_CPU_MIPS32 is not set -# CONFIG_CPU_MIPS64 is not set -# CONFIG_CPU_ADVANCED is not set -# CONFIG_CPU_HAS_LLSC is not set -# CONFIG_CPU_HAS_LLDSCD is not set -# CONFIG_CPU_HAS_WB is not set - -# -# General setup -# -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -# CONFIG_NET is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=2048 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# ISDN subsystem -# - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_COMPUTONE is not set -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_DIGIEPCA is not set -# CONFIG_DIGI is not set -# CONFIG_ESPSERIAL is not set -# CONFIG_MOXA_INTELLIO is not set -# CONFIG_MOXA_SMARTIO is not set -# CONFIG_ISI is not set -# CONFIG_SYNCLINK is not set -# CONFIG_N_HDLC is not set -# CONFIG_RISCOM8 is not set -# CONFIG_SPECIALIX is not set -# CONFIG_SX is not set -# CONFIG_RIO is not set -# CONFIG_STALDRV is not set -CONFIG_SERIAL_TX3912=y -CONFIG_SERIAL_TX3912_CONSOLE=y -# CONFIG_AU1000_UART is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_SMB_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# USB Controllers -# -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# - -# -# Networking support is needed for USB Networking device support -# - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# Miscellaneous USB drivers -# -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Kernel hacking -# -CONFIG_CROSSCOMPILE=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set diff -Nru a/arch/mips/defconfig-pb1000 b/arch/mips/defconfig-pb1000 --- a/arch/mips/defconfig-pb1000 Fri Jun 27 14:19:55 2003 +++ b/arch/mips/defconfig-pb1000 Fri Jun 27 14:19:55 2003 @@ -2,7 +2,8 @@ # Automatically generated make config: don't edit # CONFIG_MIPS=y -# CONFIG_SMP is not set +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set # # Code maturity level options @@ -10,85 +11,183 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Machine selection # # CONFIG_ACER_PICA_61 is not set -# CONFIG_ALGOR_P4032 is not set # CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set # CONFIG_DECSTATION is not set -# CONFIG_DDB5074 is not set -# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set # CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_NINO is not set # CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set # CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set # CONFIG_DDB5476 is not set # CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set # CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set # CONFIG_SNI_RM200_PCI is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_IVR is not set -CONFIG_MIPS_PB1000=y +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_MIPS_AU1000=y -CONFIG_NEW_IRQ=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_PCI is not set -# CONFIG_I8259 is not set - -# -# Loadable module support -# -# CONFIG_MODULES is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_FB=y # # CPU selection # +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set # CONFIG_CPU_R3000 is not set -# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set -# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS64 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y CONFIG_CPU_ADVANCED=y CONFIG_CPU_HAS_LLSC=y # CONFIG_CPU_HAS_LLDSCD is not set CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_MMU=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_TCIC is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats # -CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_KCORE_ELF=y -CONFIG_ELF_KERNEL=y -# CONFIG_BINFMT_AOUT is not set CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set -CONFIG_NET=y -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_UCLINUX is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set # # Parallel port support @@ -96,39 +195,83 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK is not set +# CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set @@ -138,22 +281,27 @@ # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -166,69 +314,29 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MIPS_AU1000_ENET=y -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -238,11 +346,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -251,6 +356,19 @@ # CONFIG_WAN is not set # +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# # Amateur Radio support # # CONFIG_HAMRADIO is not set @@ -258,44 +376,131 @@ # # IrDA (infrared) support # -# CONFIG_IRDA is not set +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRTTY_OLD is not set +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# +# CONFIG_DONGLE_OLD is not set + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_OLD is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input Device Drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # -# CONFIG_VT is not set -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set # CONFIG_CYCLADES is not set # CONFIG_DIGIEPCA is not set # CONFIG_DIGI is not set -# CONFIG_ESPSERIAL is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set # CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set # CONFIG_SX is not set # CONFIG_RIO is not set # CONFIG_STALDRV is not set -# CONFIG_SERIAL_TX3912 is not set -# CONFIG_SERIAL_TX3912_CONSOLE is not set -CONFIG_AU1000_UART=y -CONFIG_AU1000_SERIAL_CONSOLE=y + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -305,36 +510,35 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -344,223 +548,168 @@ # CONFIG_DRM is not set # +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types # -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set +# CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Sound -# -# CONFIG_SOUND is not set # -# USB support +# Graphics support # -# CONFIG_USB is not set +# CONFIG_FB_VIRTUAL is not set # -# USB Controllers +# Console display driver support # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set # -# USB Device Class drivers +# Logo configuration # -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set +# CONFIG_LOGO is not set # -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices +# Sound # -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set +CONFIG_SOUND=y # -# USB Multimedia devices +# Advanced Linux Sound Architecture # +# CONFIG_SND is not set # -# Video4Linux support is needed for USB Multimedia device support +# Open Sound System # -# CONFIG_USB_DABUSB is not set +# CONFIG_SOUND_PRIME is not set # -# USB Network adaptors +# USB support # -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set +# CONFIG_USB_GADGET is not set # -# USB port drivers +# Bluetooth support # -# CONFIG_USB_USS720 is not set +# CONFIG_BT is not set # -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_GDB_CONSOLE is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-pb1100 b/arch/mips/defconfig-pb1100 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-pb1100 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,789 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_FB=y + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +CONFIG_64BIT_PHYS_ADDR=y +CONFIG_CPU_ADVANCED=y +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +CONFIG_CPU_HAS_WB=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_MMU=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_TCIC is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_UCLINUX is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +CONFIG_BLK_DEV_IDECS=m +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +CONFIG_IRDA=y + +# +# IrDA protocols +# +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRTTY_OLD is not set +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# +# CONFIG_DONGLE_OLD is not set + +# +# FIR device drivers +# +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_OLD is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS_FS=m +CONFIG_JFFS_FS_VERBOSE=0 +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Graphics support +# +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/mips/defconfig-pb1500 b/arch/mips/defconfig-pb1500 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-pb1500 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,664 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +CONFIG_SOC_AU1X00=y +# CONFIG_SOC_AU1000 is not set +# CONFIG_SOC_AU1100 is not set +CONFIG_SOC_AU1500=y +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +CONFIG_MIPS_PB1500=y +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NEW_PCI=y +# CONFIG_AU1000_USB_DEVICE is not set +# CONFIG_FB is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +CONFIG_PCMCIA=m +# CONFIG_TCIC is not set + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_MIPS_AU1X00_ENET=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# PCMCIA network device support +# +CONFIG_NET_PCMCIA=y +CONFIG_PCMCIA_3C589=m +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +# CONFIG_PCMCIA_PCNET is not set +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set +# CONFIG_PCMCIA_AXNET is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_AU1X00_GPIO is not set +# CONFIG_TS_AU1X00_ADS7846 is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_AU1X00=y +CONFIG_SERIAL_AU1X00_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS4_FS=m + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +CONFIG_CRYPTO_TWOFISH=y +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +CONFIG_CRC32=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-sb1250-swarm b/arch/mips/defconfig-sb1250-swarm --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-sb1250-swarm Fri Jun 27 14:20:06 2003 @@ -0,0 +1,613 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +CONFIG_SIBYTE_SB1xxx_SOC=y +CONFIG_SIBYTE_SB1250=y +# CONFIG_SIMULATION is not set +CONFIG_SIBYTE_CFE=y +# CONFIG_SIBYTE_CFE_CONSOLE is not set +# CONFIG_SIBYTE_BUS_WATCHER is not set +# CONFIG_SIBYTE_SB1250_PROF is not set +# CONFIG_SIBYTE_TBPROF is not set +CONFIG_SIBYTE_SWARM=y +CONFIG_SIBYTE_BOARD=y +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_DUMMY_KEYB=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +CONFIG_CPU_SB1=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_VTAG_ICACHE=y +CONFIG_CPU_SB1_PASS_1=y +# CONFIG_CPU_SB1_PASS_2 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_SB1_PASS_1_WORKAROUNDS=y +CONFIG_SB1_CACHE_ERROR=y +CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y +# CONFIG_SB1_CERR_SPIN is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_HIGHMEM is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_BINFMT_IRIX is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=9220 +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_NET_SB1250_MAC=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +CONFIG_SIBYTE_SB1250_DUART=y +CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y +CONFIG_SERIAL_CONSOLE=y + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips/defconfig-sead b/arch/mips/defconfig-sead --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-sead Fri Jun 27 14:20:06 2003 @@ -0,0 +1,393 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +CONFIG_MIPS_SEAD=y +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_BOARDS_GEN=y +CONFIG_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=18432 +CONFIG_BLK_DEV_INITRD=y + +# +# MIPS initrd options +# +CONFIG_EMBEDDED_RAMDISK=y +CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz" + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +# CONFIG_NET is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/defconfig-tb0226 b/arch/mips/defconfig-tb0226 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-tb0226 Fri Jun 27 14:20:07 2003 @@ -0,0 +1,667 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +CONFIG_TANBAC_TB0226=y +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +CONFIG_NEW_PCI=y +CONFIG_FB=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDESCSI=y +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=m +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_NAT=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_TOS=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=m +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp932" +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=m +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Graphics support +# +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + +# +# Logo configuration +# +# CONFIG_LOGO is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +# CONFIG_SND is not set + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/mips/defconfig-tb0229 b/arch/mips/defconfig-tb0229 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-tb0229 Fri Jun 27 14:20:06 2003 @@ -0,0 +1,657 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +CONFIG_TANBAC_TB0229=y +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +CONFIG_NEW_PCI=y +# CONFIG_FB is not set +CONFIG_TANBAC_TB0219=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK_DEV=m +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_NAT=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_TOS=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +CONFIG_DUMMY=m +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +CONFIG_SLIP_MODE_SLIP6=y + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=y +# CONFIG_XFS_RT is not set +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=m +# CONFIG_QUOTA is not set +CONFIG_QUOTACTL=y +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=m +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +CONFIG_SMB_FS=m +CONFIG_SMB_NLS_DEFAULT=y +CONFIG_SMB_NLS_REMOTE="cp932" +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +CONFIG_SMB_NLS=y +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_CODEPAGE_932=m +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m diff -Nru a/arch/mips/defconfig-workpad b/arch/mips/defconfig-workpad --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/defconfig-workpad Fri Jun 27 14:20:06 2003 @@ -0,0 +1,568 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +CONFIG_IBM_WORKPAD=y +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SOC_AU1X00 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_VR41XX_TIME_C=y +CONFIG_DUMMY_KEYB=y +CONFIG_VR41XX_COMMON=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +CONFIG_CPU_VR41XX=y +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECD is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_IDE_TASK_IOCTL is not set +CONFIG_IDE_TASKFILE_IO=y + +# +# IDE chipset support/bugfixes +# + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips/galileo-boards/ev64120/Makefile b/arch/mips/galileo-boards/ev64120/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,12 @@ +# +# Copyright 2000 RidgeRun, Inc. +# Author: RidgeRun, Inc. +# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com +# +# Makefile for the Galileo EV64120 board. +# + +obj-y := serialGT.o int-handler.o promcon.o reset.o setup.o irq.o \ + irq-handler.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/galileo-boards/ev64120/README b/arch/mips/galileo-boards/ev64120/README --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/README Fri Jun 27 14:20:06 2003 @@ -0,0 +1,2 @@ +The compressed boot code was such a mess I deleted it. Feel free to +reimplement it -- Ralf diff -Nru a/arch/mips/galileo-boards/ev64120/dma.c b/arch/mips/galileo-boards/ev64120/dma.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/dma.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,168 @@ +/* DMA.C - DMA functions and definitions */ + +/* Copyright Galileo Technology. */ + +/* +DESCRIPTION +This file gives the user a complete interface to the powerful DMA engines, +including functions for controling the priority mechanism. +To fully understand the capabilities of the DMA engines please spare some +time to go trough the spec. +*/ + +/* includes */ + +#ifdef __linux__ +#include <asm/galileo/evb64120A/core.h> +#include <asm/galileo/evb64120A/dma.h> +#else +#include "Core.h" +#include "DMA.h" +#endif +/******************************************************************** +* dmaCommand - Write a command to a DMA channel +* +* Inputs: DMA_ENGINE channel - choosing one of the four engine. +* unsigned int command - The command to be written to the control register. +* Returns: false if one of the parameters is erroneous else returns true. +*********************************************************************/ + +bool dmaCommand(DMA_ENGINE channel, unsigned int command) +{ + if (channel > LAST_DMA_ENGINE) + return false; + GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command); + return true; +} + +/******************************************************************** +* dmaTransfer - transfer data from sourceAddr to destAddr on DMA channel +* Inputs: +* DMA_RECORED *nextRecoredPointer: If we are using chain mode DMA transfer, +* then this pointer should point to the next recored,otherwise it should be +* NULL. +* VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes +* aligned, the function will take care of that for you, but you need to +* allocate one more record for that, meaning: if you are having 3 records , +* declare 4 (see the example bellow) and start using the second one. +* Example: +* Performing a chain mode DMA transfer(Copy a 1/4 mega of data using +* chain mode DMA): +* DMA_RECORED dmaRecoredArray[4]; +* dmaRecoredArray[1].ByteCnt = _64KB; +* dmaRecoredArray[1].DestAdd = destAddress + _64KB; +* dmaRecoredArray[1].SrcAdd = sourceAddress + _64KB; +* dmaRecoredArray[1].NextRecPtr = &dmaRecoredArray[2]; +* dmaRecoredArray[2].ByteCnt = _64KB; +* dmaRecoredArray[2].DestAdd = destAddress + 2*_64KB; +* dmaRecoredArray[2].SrcAdd = sourceAddress + 2*_64KB; +* dmaRecoredArray[2].NextRecPtr = &dmaRecoredArray[3]; +* dmaRecoredArray[3].ByteCnt = _64KB; +* dmaRecoredArray[3].DestAdd = destAddress + 3*_64KB; +* dmaRecoredArray[3].SrcAdd = sourceAddress + 3*_64KB; +* dmaRecoredArray[3].NextRecPtr = NULL; +* performCmDma(0,sourceAddress,destAddress,_64KB,PLAIN,WAIT_TO_END, +* &dmaRecoredArray[1]); +* Returns: NO_SUCH_CHANNEL if channel does not exist, CHANNEL_BUSY if channel +* is active and true if the transfer ended successfully +*********************************************************************/ + +DMA_STATUS dmaTransfer(DMA_ENGINE channel, unsigned int sourceAddr, + unsigned int destAddr, unsigned int numOfBytes, + unsigned int command, + DMA_RECORED * nextRecoredPointer) +{ + unsigned int tempData, checkBits, alignmentOffset = 0; + DMA_RECORED *next = nextRecoredPointer; + + if (channel > LAST_DMA_ENGINE) + return NO_SUCH_CHANNEL; + if (numOfBytes > 0xffff) + return GENERAL_ERROR; + if (isDmaChannelActive(channel)) + return CHANNEL_BUSY; + if (next != NULL) { /* case of chain Mode */ + alignmentOffset = ((unsigned int) next % 16); + } + checkBits = command & 0x6000000; + if (checkBits == 0) { + while (next != NULL) { + WRITE_WORD((unsigned int) next - alignmentOffset, + next->ByteCnt); + tempData = (unsigned int) next->SrcAdd; + WRITE_WORD((unsigned int) next + 4 - + alignmentOffset, tempData & 0x5fffffff); + tempData = (unsigned int) next->DestAdd; + WRITE_WORD((unsigned int) next + 8 - + alignmentOffset, tempData & 0x5fffffff); + tempData = (unsigned int) next->NextRecPtr; + WRITE_WORD((unsigned int) next + 12 - + alignmentOffset, + tempData & 0x5fffffff - + alignmentOffset); + next = (DMA_RECORED *) tempData; + if (next == nextRecoredPointer) + next = NULL; + } + } + GT_REG_WRITE(CHANNEL0_DMA_BYTE_COUNT + channel * 4, numOfBytes); + tempData = sourceAddr; + GT_REG_WRITE(CHANNEL0_DMA_SOURCE_ADDRESS + channel * 4, + tempData & 0x5fffffff); + tempData = destAddr; + GT_REG_WRITE(CHANNEL0_DMA_DESTINATION_ADDRESS + channel * 4, + tempData & 0x5fffffff); + if (nextRecoredPointer != NULL) { + tempData = + (unsigned int) nextRecoredPointer - alignmentOffset; + GT_REG_WRITE(CHANNEL0NEXT_RECORD_POINTER + 4 * channel, + tempData & 0x5fffffff); + command = command | CHANNEL_ENABLE; + } else { + command = command | CHANNEL_ENABLE | NON_CHAIN_MOD; + } + /* Activate DMA engine By writting to dmaControlRegister */ + GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command); + + return DMA_OK; +} + +/******************************************************************** +* isDmaChannelActive - check if channel is busy +* +* Inputs: channel number +* RETURNS: True if the channel is busy, false otherwise. +*********************************************************************/ + +bool isDmaChannelActive(DMA_ENGINE channel) +{ + unsigned int data; + + if (channel > LAST_DMA_ENGINE) + return false; + GT_REG_READ(CHANNEL0CONTROL + 4 * channel, &data); + if (data & DMA_ACTIVITY_STATUS) + return true; + else + return false; +} + + +/******************************************************************** +* changeDmaPriority - update the arbiter`s priority for channels 0-3 +* +* Inputs: priority for channels 0-1, priority for channels 2-3, + priority for groups and other priority options +* RETURNS: false if one of the parameters is erroneous and true else +*********************************************************************/ + +bool changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23, + PRIO_GROUP prioGrp, PRIO_OPT prioOpt) +{ + unsigned int prioReg = 0; + + prioReg = (prio_01 & 0x3) + ((prio_23 & 0x3) << 2) + + ((prioGrp & 0x3) << 4) + (prioOpt << 6); + GT_REG_WRITE(ARBITER_CONTROL, prioReg); + return true; +} diff -Nru a/arch/mips/galileo-boards/ev64120/i2o.c b/arch/mips/galileo-boards/ev64120/i2o.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/i2o.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,689 @@ +/* i2o.c - Drivers for the I2O */ + +/* Copyright - Galileo technology. */ + +/*includes*/ + +#include <linux/module.h> + +#ifdef __linux__ +#include <asm/galileo-boards/evb64120A/core.h> +#include <asm/galileo-boards/evb64120A/i2o.h> +#else +#include "Core.h" +#include "i2o.h" +#endif + +/******************************************************************** +* getInBoundMessage - When the GT is configured for I2O support +* it can receive a message from an agent on the pci bus. +* This message is a 32 bit wide and can be read by +* the CPU. +* The messaging unit contains two sets of registers +* so, actually it can receive a 64 bit message. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: Data received from the remote agent. +*********************************************************************/ +unsigned int getInBoundMessage(I2O_MESSAGE_REG messageRegNum) +{ + unsigned int regValue; + + GT_REG_READ(INBOUND_MESSAGE_REGISTER0_CPU_SIDE + 4 * messageRegNum, + ®Value); + return (regValue); +} + + +/******************************************************************** +* checkInboundIntAndClear - When a message is received an interrupt is +* generated, to enable polling instead the use of +* an interrupt handler the user can use this fuction. +* You will need to mask the incomming interrupt for +* proper use. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: true if the corresponding bit in the cause register is set otherwise +* false. +*********************************************************************/ +bool checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum) +{ + unsigned int regValue; + + GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Value); + /* clears bit 0 for message register 0 or bit 1 for message register 1 */ + GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, + BIT1 * messageRegNum); + switch (messageRegNum) { + case MESSAGE_REG_0: + if (regValue & BIT0) + return true; + break; + case MESSAGE_REG_1: + if (regValue & BIT1) + return true; + break; + } + return false; +} + +/******************************************************************** +* sendOutBoundMessage - When the GT is configured for I2O support +* it can send a message to an agent on the pci bus. +* This message is a 32 bit wide and can be read by +* the PCI agent. +* The messaging unit contains two sets of registers +* so, actually it can send a 64 bit message. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* unsigned int message - Message to be sent. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool sendOutBoundMessage(I2O_MESSAGE_REG messageRegNum, + unsigned int message) +{ + GT_REG_WRITE(OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE + + 4 * messageRegNum, message); + return true; +} + +/******************************************************************** +* checkOutboundInt - When the CPU sends a message to the Outbound +* register it generates an interrupt which is refelcted on +* the Outbound Interrupt cause register, the interrupt can +* be cleard only by the PCI agent which read the message. +* After sending the message you can acknowledge it by +* monitoring the corresponding bit in the cause register. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: true if the corresponding bit in the cause register is set otherwise +* false. +*********************************************************************/ +bool outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum) +{ + unsigned int regValue; + + GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Value); + switch (messageRegNum) { + case MESSAGE_REG_0: + if (regValue & BIT0) + return true; + break; + case MESSAGE_REG_1: + if (regValue & BIT1) + return true; + break; + } + return false; +} + +/******************************************************************** +* maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking +* the interrupt you can work in polling mode +* using the checkInboundIntAndClear function. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) +{ + switch (messageRegNum) { + case MESSAGE_REG_0: + SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT0); + break; + case MESSAGE_REG_1: + SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT1); + break; + } + return true; +} + +/******************************************************************** +* enableInBoundMessageInterrupt - unMask the inbound interrupt. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) +{ + switch (messageRegNum) { + case MESSAGE_REG_0: + RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT0); + break; + case MESSAGE_REG_1: + RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT1); + break; + } + return true; +} + +/******************************************************************** +* maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so +* the PCI agent needs to poll on the interrupt +* cause register to monitor an incoming message. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) +{ + switch (messageRegNum) { + case MESSAGE_REG_0: + SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT0); + break; + case MESSAGE_REG_1: + SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT1); + break; + } + return true; +} + +/******************************************************************** +* enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so +* the PCI agent needs to poll on the interrupt +* cause register to monitor an incoming message. +* +* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum) +{ + switch (messageRegNum) { + case MESSAGE_REG_0: + RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT0); + break; + case MESSAGE_REG_1: + RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + BIT1); + break; + } + return true; +} + +/******************************************************************** +* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the +* CPU generates a PCI interrupt (if it is not masked by +* the Outbound interrupt Mask register) +* Only the PCI agent which recieved the interrupt can +* clear it, only after clearing all the bits the +* interrupt will be de-asserted. +* +* INPUTS: unsigned int data - Requested interrupt bits. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool initiateOutBoundDoorBellInt(unsigned int data) +{ + GT_REG_WRITE(OUTBOUND_DOORBELL_REGISTER_CPU_SIDE, data); + return true; +} + +/******************************************************************** +* readInBoundDoorBellInt - Read the in bound door bell interrupt cause +* register. +* +* OUTPUT: N/A. +* RETURNS: The 32 bit interrupt cause register. +*********************************************************************/ +unsigned int readInBoundDoorBellInt() +{ + unsigned int regData; + GT_REG_READ(INBOUND_DOORBELL_REGISTER_CPU_SIDE, ®Data); + return regData; +} + +/******************************************************************** +* clearInBoundDoorBellInt - An interrupt generated by a PCI agent through +* the in bound door bell mechanisem can be cleared +* only by the CPU. The interrupt will be de-asserted +* only if all the bits which where set by the PCI +* agent are cleared. +* +* INPUTS: unsigned int data - Bits to be cleared. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool clearInBoundDoorBellInt(unsigned int data) +{ + GT_REG_WRITE(INBOUND_DOORBELL_REGISTER_CPU_SIDE, data); + return true; +} + +/******************************************************************** +* isInBoundDoorBellInterruptSet - Check if Inbound Doorbell Interrupt is set, +* can be used for polling mode. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true if the corresponding bit in the cause register is set otherwise +* false. +*********************************************************************/ +bool isInBoundDoorBellInterruptSet() +{ + unsigned int regData; + + GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); + return (regData & BIT2); +} + +/******************************************************************** +* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is +* set, can be used for acknowledging interrupt +* handling by the agent who recieived the +* interrupt. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true if the corresponding bit in the cause register is set otherwise +* false. +*********************************************************************/ +bool isOutBoundDoorBellInterruptSet() +{ + unsigned int regData; + + GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); + return (regData & BIT2); +} + +/******************************************************************** +* maskInboundDoorBellInterrupt - Mask the Inbound Doorbell Interrupt. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool maskInBoundDoorBellInterrupt() +{ + SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); + return true; +} + +/******************************************************************** +* enableInboundDoorBellInterrupt - unMask the Inbound Doorbell Interrupt. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool enableInBoundDoorBellInterrupt() +{ + RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); + return true; +} + +/******************************************************************** +* maskOutboundDoorBellInterrupt - Mask the Outbound Doorbell Interrupt. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool maskOutBoundDoorBellInterrupt() +{ + SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); + return true; +} + +/******************************************************************** +* enableOutboundDoorBellInterrupt - unMask the Outbound Doorbell Interrupt. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool enableOutBoundDoorBellInterrupt() +{ + RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2); + return true; +} + +/******************************************************************** +* circularQueueEnable - Initialize the I2O messaging mechanism. +* +* INPUTS: CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the: +* Queue Control Register, Offset 0x50 (0x1c50). +* Defines the queues size (refer to the data sheet +* for more information) +* unsigned int queueBaseAddr - The base address for the first queue. +* The other queues base Address will be determined as follows: +* Inbound Free = queueBaseAddr +* Inbound Post = queueBaseAddr + cirQueSize +* Outbound Post = queueBaseAddr + cirQueSize +* +* OUTPUT: N/A. +* RETURNS: true. +* +* The Circular Queue Starting Addresses as written in the spec: +* ---------------------------------------- +* | Queue | Starting Address | +* |----------------|---------------------| +* | Inbound Free | QBAR | +* | Inbound Post | QBAR + Queue Size | +* | Outbound Post | QBAR + 2*Queue Size | +* | Outbound Free | QBAR + 3*Queue Size | +* ---------------------------------------- +*********************************************************************/ +bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize, + unsigned int queueBaseAddr) +{ + unsigned int regData; + + regData = BIT0 | (cirQueSize << 1); + /* Enable Queue Operation */ + GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData); + /* Writing The base Address for the 4 Queues */ + GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr); + /* Update The Inbound Free Queue Base Address, offset=0 */ + GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0); + GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0); + /* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */ + GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, + _16K * cirQueSize); + GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, + _16K * cirQueSize); + /* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */ + GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, + 2 * _16K * cirQueSize); + GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, + 2 * _16K * cirQueSize); + /* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */ + GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, + 3 * _16K * cirQueSize); + GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, + 3 * _16K * cirQueSize); + return true; +} + +/******************************************************************** +* inBoundPostQueuePop - Two actions are being taken upon pop: +* 1) Getting out the data from the Queue`s head. +* 2) Increment the tail pointer in a cyclic way (The HEAD is +* incremented automaticaly by the GT) +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: Data pointed by tail. +*********************************************************************/ +unsigned int inBoundPostQueuePop() +{ + unsigned int tailAddrPointer; + unsigned int data; + unsigned int cirQueSize; + unsigned int qBar; + unsigned int inBoundPostQbase; + + /* Gets the Inbound Post TAIL pointer */ + GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, + &tailAddrPointer); + /* Gets the Data From the pointer Address */ + READ_WORD(tailAddrPointer, &data); + /* incrementing head process: */ + /* Gets the fifo's base Address */ + GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); + qBar = qBar & 0xfff00000; + /* Gets the fifo's size */ + GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); + cirQueSize = 0x1f && (cirQueSize >> 1); + /* calculating The Inbound Post Queue Base Address */ + inBoundPostQbase = qBar + 1 * cirQueSize * _16K; + /* incrementing Inbound Post queue TAIL in a cyclic loop */ + tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) % + (_16K * cirQueSize)); + /* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */ + GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE, + tailAddrPointer); + return data; +} + +/******************************************************************** +* isInBoundPostQueueInterruptSet - Check if in bound interrupt is set. +* can be used for polling mode. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true if the corresponding bit in the cause register is set otherwise +* false. +*********************************************************************/ +bool isInBoundPostQueueInterruptSet() +{ + unsigned int regData; + + GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, ®Data); + return (regData & BIT4); /* if set return '1' (true), else '0' (false) */ +} + +/******************************************************************** +* clearInBoundPostQueueInterrupt - Clears the Post queue interrupt. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool clearInBoundPostQueueInterrupt() +{ + GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4); + return true; +} + +/******************************************************************** +* maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking +* the interrupt you can work in polling mode. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: +*********************************************************************/ +void maskInBoundPostQueueInterrupt() +{ + unsigned int regData; + + GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); + GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + regData | BIT4); + +} + +/******************************************************************** +* enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new +* message from the PCI agent. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: +*********************************************************************/ +void enableInBoundPostQueueInterrupt() +{ + unsigned int regData; + + GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, ®Data); + GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, + regData & 0xfffffffb); +} + +/******************************************************************** +* inBoundFreeQueuePush - Two actions are being taken upon push: +* 1) Place the user`s data on the Queue`s head. +* 2) Increment the haed pointer in a cyclic way (The tail is +* decremented automaticaly by the GT) +* +* INPUTS: unsigned int data - Data to be placed in the queue. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool inBoundFreeQueuePush(unsigned int data) +{ + unsigned int headPointer; + unsigned int cirQueSize; + unsigned int qBar; + unsigned int inBoundFreeQbase; + + GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, + &headPointer); + /* placing the data in the queue */ + WRITE_WORD(headPointer, data); + /* incrementing head process: */ + /* Gets the fifo's base Address */ + GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); + qBar = qBar & 0xfff00000; + /* Gets the fifo's size */ + GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); + cirQueSize = 0x1f && (cirQueSize >> 1); + /* calculating The Inbound Free Queue Base Address */ + inBoundFreeQbase = qBar; + /* incrementing Inbound Free queue HEAD in a cyclic loop */ + headPointer = + inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize)); + /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ + GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, + headPointer); + return true; +} + +/******************************************************************** +* isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty. +* Can be used for acknowledging the messages +* being sent by us to the PCI agent. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true if the queue is empty , otherwise false. +*********************************************************************/ +bool isInBoundFreeQueueEmpty() +{ + unsigned int inBoundFreeQueHead; + unsigned int inBoundFreeQueTail; + + GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, + &inBoundFreeQueHead); + GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, + &inBoundFreeQueTail); + if (inBoundFreeQueHead == inBoundFreeQueTail) { + return true; + } else + return false; +} + +/******************************************************************** +* outBoundPostQueuePush - Two actions are being taken upon push: +* 1) Place the user`s data on the Queue`s head. +* 2) Increment the haed pointer in a cyclic way (The tail is +* decremented automaticaly by the GT when the Agent on the +* PCI have read data from the Outbound Port). +* +* INPUTS: unsigned int data - Data to be placed in the queue`s head. +* OUTPUT: N/A. +* RETURNS: true. +*********************************************************************/ +bool outBoundPostQueuePush(unsigned int data) +{ + unsigned int headPointer; + unsigned int cirQueSize; + unsigned int qBar; + unsigned int outBoundPostQbase; + + GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, + &headPointer); + /* placing the data in the queue (where the head point to..) */ + WRITE_WORD(headPointer, data); + /* incrementing head process: */ + /* Gets the fifo's base Address */ + GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); + qBar = qBar & 0xfff00000; + /* Gets the fifo's size */ + GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); + cirQueSize = 0x1f && (cirQueSize >> 1); + /* calculating The Outbound Post Queue Base Address */ + outBoundPostQbase = qBar + 2 * cirQueSize * _16K; + /* incrementing Outbound Post queue in a cyclic loop */ + headPointer = + outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize)); + /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */ + GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE, + headPointer); + return true; +} + +/******************************************************************** +* isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty. +* Can be used for acknowledging the messages +* being sent by us to the PCI agent. +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: true if the queue is empty , otherwise false. +*********************************************************************/ +bool isOutBoundPostQueueEmpty() +{ + unsigned int outBoundPostQueHead; + unsigned int outBoundPostQueTail; + + GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, + &outBoundPostQueHead); + GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, + &outBoundPostQueTail); + if (outBoundPostQueHead == outBoundPostQueTail) { + return true; + } else + return false; +} + +/******************************************************************** +* outBoundFreeQueuePop - Two actions are being taken upon pop: +* 1) Getting out the data from the Queue`s head. +* 2) Increment the tail pointer in a cyclic way (The HEAD is +* incremented automaticaly by the GT) +* +* INPUTS: N/A. +* OUTPUT: N/A. +* RETURNS: Data pointed by tail. +*********************************************************************/ +unsigned int outBoundFreeQueuePop() +{ + unsigned int tailAddrPointer; + unsigned int data; + unsigned int cirQueSize; + unsigned int qBar; + unsigned int outBoundFreeQbase; + + /* Gets the Inbound Post TAIL pointer */ + GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, + &tailAddrPointer); + /* Gets the Data From the pointer Address */ + READ_WORD(tailAddrPointer, &data); + /* incrementing head process: */ + /* Gets the fifo's base Address */ + GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar); + qBar = qBar & 0xfff00000; + /* Gets the fifo's size */ + GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize); + cirQueSize = 0x1f && (cirQueSize >> 1); + /* calculating The Inbound Post Queue Base Address */ + outBoundFreeQbase = qBar + 3 * cirQueSize * _16K; + /* incrementing Outbound Free queue TAlL in a cyclic loop */ + tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) % + (_16K * cirQueSize)); + /* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */ + GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, + tailAddrPointer); + return data; +} + + +EXPORT_SYMBOL(isInBoundDoorBellInterruptSet); +EXPORT_SYMBOL(initiateOutBoundDoorBellInt); +EXPORT_SYMBOL(clearInBoundDoorBellInt); diff -Nru a/arch/mips/galileo-boards/ev64120/int-handler.S b/arch/mips/galileo-boards/ev64120/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/int-handler.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,85 @@ +/* + * int-handler.S + * + * Based on the cobalt handler. + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + .set reorder + .set noat + NESTED(galileo_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + .set noreorder + andi t1, t0, STATUSF_IP4 /* int2 hardware line (timer) */ + andi t2, t0, STATUSF_IP2 /* int0 hardware line */ + bnez t1, ll_galileo_irq + andi t1, t0, STATUSF_IP5 /* int3 hardware line */ + bnez t2, ll_pci_intA + andi t2, t0, STATUSF_IP6 /* int4 hardware line */ + bnez t1, ll_pci_intD + andi t1, t0, STATUSF_IP7 /* compare int */ + bnez t2, ll_serial_irq + nop + bnez t1, ll_compare_irq + nop + .set reorder + + j spurious_interrupt + END(galileo_handle_int) + + .align 5 +ll_galileo_irq: li a0, 4 + move a1, sp + jal do_IRQ + j ret_from_irq + + .align 5 +ll_compare_irq: li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + + .align 5 +ll_pci_intA: move a0, sp + jal pci_intA + j ret_from_irq + +#if 0 + .align 5 +ll_pci_intB: move a0, sp + jal pci_intB + j ret_from_irq + + .align 5 +ll_pci_intC: move a0, sp + jal pci_intC + j ret_from_irq +#endif + + .align 5 +ll_pci_intD: move a0, sp + jal pci_intD + j ret_from_irq + + .align 5 +ll_serial_irq: li a0, 6 + move a1, sp + jal do_IRQ + j ret_from_irq diff -Nru a/arch/mips/galileo-boards/ev64120/irq-handler.c b/arch/mips/galileo-boards/ev64120/irq-handler.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/irq-handler.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,270 @@ +/* + * Galileo Technology chip interrupt handler + * + * Modified by RidgeRun, Inc. + */ +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <asm/ptrace.h> +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <asm/io.h> +#include <asm/gt64120.h> +#include <asm/galileo-boards/ev64120.h> +#include <asm/galileo-boards/ev64120int.h> + +/* + * These are interrupt handlers for the GT on-chip interrupts. They all come + * in to the MIPS on a single interrupt line, and have to be handled and ack'ed + * differently than other MIPS interrupts. + */ + +#if CURRENTLY_UNUSED + +struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; +void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); + +/* + * hook_irq_handler + * + * Hooks IRQ handler to the system. When the system is interrupted + * the interrupt service routine is called. + * + * Inputs : + * int_cause - The interrupt cause number. In EVB64120 two parameters + * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. + * bit_num - Indicates which bit number in the cause register + * isr_ptr - Pointer to the interrupt service routine + * + * Outputs : + */ +void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) +{ + irq_handlers[int_cause][bit_num].routine = isr_ptr; +} + + +/* + * enable_galileo_irq + * + * Enables the IRQ on Galileo Chip + * + * Inputs : + * int_cause - The interrupt cause number. In EVB64120 two parameters + * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. + * bit_num - Indicates which bit number in the cause register + * + * Outputs : + * 1 if succesful, 0 if failure + */ +int enable_galileo_irq(int int_cause, int bit_num) +{ + if (int_cause == INT_CAUSE_MAIN) + SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num)); + else if (int_cause == INT_CAUSE_HIGH) + SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, + (1 << bit_num)); + else + return 0; + return 1; +} + +/* + * disable_galileo_irq + * + * Disables the IRQ on Galileo Chip + * + * Inputs : + * int_cause - The interrupt cause number. In EVB64120 two parameters + * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. + * bit_num - Indicates which bit number in the cause register + * + * Outputs : + * 1 if succesful, 0 if failure + */ +int disable_galileo_irq(int int_cause, int bit_num) +{ + if (int_cause == INT_CAUSE_MAIN) + RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, + (1 << bit_num)); + else if (int_cause == INT_CAUSE_HIGH) + RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, + (1 << bit_num)); + else + return 0; + return 1; +} + +#endif /* UNUSED */ + +/* + * galileo_irq - + * + * Interrupt handler for interrupts coming from the Galileo chip. + * It could be timer interrupt, built in ethernet ports etc... + * + * Inputs : + * + * Outputs : + * + */ +static void galileo_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int irq_src, int_high_src, irq_src_mask, + int_high_src_mask; + int handled; + unsigned int count; + static int counter = 0; + + GT_READ(GT_INTRCAUSE_OFS, &irq_src); + GT_READ(GT_INTRMASK_OFS, &irq_src_mask); + GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); + GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); + irq_src = irq_src & irq_src_mask; + int_high_src = int_high_src & int_high_src_mask; + + handled = 0; + + /* Execute all interrupt handlers */ + /* Check for timer interrupt */ + if (irq_src & 0x00000800) { + handled = 1; + irq_src &= ~0x00000800; + // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); + do_timer(regs); + } + + if (irq_src) { + printk(KERN_INFO + "Other Galileo interrupt received irq_src %x\n", + irq_src); +#if CURRENTLY_UNUSED + for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { + if (irq_src & (1 << count)) { + if (irq_handlers[INT_CAUSE_MAIN][count]. + routine) { + queue_task(&irq_handlers + [INT_CAUSE_MAIN][count], + &tq_immediate); + mark_bh(IMMEDIATE_BH); + handled = 1; + } + } + } +#endif /* UNUSED */ + } + GT_WRITE(GT_INTRCAUSE_OFS, 0); + GT_WRITE(GT_HINTRCAUSE_OFS, 0); + +#undef GALILEO_I2O +#ifdef GALILEO_I2O + /* + Future I2O support. We currently attach I2O interrupt handlers to the + Galileo interrupt (int 4) and handle them in do_IRQ. + */ + if (isInBoundDoorBellInterruptSet()) { + printk(KERN_INFO "I2O doorbell interrupt received.\n"); + handled = 1; + } + + if (isInBoundPostQueueInterruptSet()) { + printk(KERN_INFO "I2O Queue interrupt received.\n"); + handled = 1; + } + + /* + This normally would be outside of the ifdef, but since + we're handling I2O outside of this handler, this + printk shows up every time we get a valid I2O + interrupt. So turn this off for now. + */ + if (handled == 0) { + if (counter < 50) { + printk("Spurious Galileo interrupt...\n"); + counter++; + } + } +#endif +} + +/* + * galileo_time_init - + * + * Initializes timer using galileo's built in timer. + * + * + * Inputs : + * irq - number of irq to be used by the timer + * + * Outpus : + * + */ +#ifdef CONFIG_SYSCLK_100 +#define Sys_clock (100 * 1000000) // 100 MHz +#endif +#ifdef CONFIG_SYSCLK_83 +#define Sys_clock (83.333 * 1000000) // 83.333 MHz +#endif +#ifdef CONFIG_SYSCLK_75 +#define Sys_clock (75 * 1000000) // 75 MHz +#endif + +/* + * This will ignore the standard MIPS timer interrupt handler that is passed + * in as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt + * handling. + */ +void galileo_time_init(struct irqaction *irq) +{ + extern irq_desc_t irq_desc[NR_IRQS]; + static struct irqaction timer; + + /* Disable timer first */ + GT_WRITE(GT_TC_CONTROL_OFS, 0); + /* Load timer value for 100 Hz */ + GT_WRITE(GT_TC3_OFS, Sys_clock / 100); + + /* + * Create the IRQ structure entry for the timer. Since we're too early + * in the boot process to use the "request_irq()" call, we'll hard-code + * the values to the correct interrupt line. + */ + timer.handler = &galileo_irq; + timer.flags = SA_SHIRQ; + timer.name = "timer"; + timer.dev_id = NULL; + timer.next = NULL; + timer.mask = 0; + irq_desc[TIMER].action = &timer; + + /* Enable timer ints */ + GT_WRITE(GT_TC_CONTROL_OFS, 0xc0); + /* clear Cause register first */ + GT_WRITE(GT_INTRCAUSE_OFS, 0x0); + /* Unmask timer int */ + GT_WRITE(GT_INTRMASK_OFS, 0x800); + /* Clear High int register */ + GT_WRITE(GT_HINTRCAUSE_OFS, 0x0); + /* Mask All interrupts at High cause interrupt */ + GT_WRITE(GT_HINTRMASK_OFS, 0x0); + +} + +void galileo_irq_init(void) +{ +#if CURRENTLY_UNUSED + int i, j; + + /* Reset irq handlers pointers to NULL */ + for (i = 0; i < MAX_CAUSE_REGS; i++) { + for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) { + irq_handlers[i][j].next = NULL; + irq_handlers[i][j].sync = 0; + irq_handlers[i][j].routine = NULL; + irq_handlers[i][j].data = NULL; + } + } +#endif +} diff -Nru a/arch/mips/galileo-boards/ev64120/irq.c b/arch/mips/galileo-boards/ev64120/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,184 @@ +/* + * BRIEF MODULE DESCRIPTION + * Code to handle irqs on GT64120A boards + * Derived from mips/orion and Cort <cort@fsmlabs.com> + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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 <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/galileo-boards/ev64120int.h> + +#define MAX_AGENTS_PER_INT 21 /* Random number */ +unsigned char pci_int_irq[MAX_AGENTS_PER_INT]; +static int max_interrupts = 0; + +asmlinkage void pci_intA(struct pt_regs *regs) +{ + unsigned int count = 0; + + /* This must be a joke - Ralf */ + for (count = 0; count < max_interrupts; count++) + do_IRQ(pci_int_irq[count], regs); +} + +asmlinkage void pci_intD(struct pt_regs *regs) +{ + unsigned int count = 0; + + /* Encore une fois - This must be a joke - Ralf */ + for (count = 0; count < max_interrupts; count++) + do_IRQ(pci_int_irq[count], regs); +} + +/* + * Now this is scarry. A disable_irq(2) or disable_irq(5) would just + * accidently disable a pci irq. It shouldn't happen but may just leaving + * these always enabled or use some reference counting wouldn't be such a + * bad thing. + */ +static void disable_ev64120_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + if (irq_nr >= 8) { + /* All PCI interrupts are on line 5 or 2 */ + clear_c0_status(IE_IRQ0 | IE_IRQ3); + } else { + clear_c0_status(0x100 << irq_nr); + } + local_irq_restore(flags); +} + +#define mask_and_ack_ev64120_irq disable_ev64120_irq + +static inline void enable_ev64120_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + if (irq_nr >= 8) { + /* All PCI interrupts are on line 5 or 2 */ + set_c0_status(IE_IRQ0 | IE_IRQ3); + } else { + set_c0_status(IE_SW0 << irq_nr); + } + local_irq_restore(flags); +} + +static unsigned int startup_ev64120_irq(unsigned int irq) +{ + if (irq >= 8) { + // NOTE: Add error-handling if > max + pci_int_irq[max_interrupts++] = irq; + } + enable_ev64120_irq(irq); + + return 0; +} + +static void shutdown_ev64120_irq(unsigned int irq) +{ + int count, tmp; + + /* + * Remove PCI interrupts from the pci_int_irq list. Make sure + * that some handler was removed before decrementing max_interrupts. + */ + if (irq >= 8) { + for (count = 0; count < max_interrupts; count++) { + if (pci_int_irq[count] == irq) { + for (tmp = count; tmp < max_interrupts; tmp++) { + pci_int_irq[tmp] = + pci_int_irq[tmp + 1]; + } + } + } + max_interrupts--; + } +} + +static void end_ev64120_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_ev64120_irq(irq); +} + +static struct hw_interrupt_type ev64120_irq_type = { + "EV64120", + startup_ev64120_irq, + shutdown_ev64120_irq, + enable_ev64120_irq, + disable_ev64120_irq, + mask_and_ack_ev64120_irq, + end_ev64120_irq +}; + +/* + * galileo_irq_setup - Initializes CPU interrupts + */ +void __init init_IRQ(void) +{ + extern asmlinkage void galileo_handle_int(void); + int i; + + init_generic_irq(); + + /* Yes, how many interrupts does this beast actually have? -- Ralf */ + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &ev64120_irq_type; + } + + /* + * Clear all of the interrupts while we change the able around a bit. + * Enable timer. Other interrupts will be enabled as they are + * registered. + */ + change_c0_status(ST0_IM | IE_IRQ2, IE_IRQ2); + + /* Sets the exception_handler array. */ + set_except_vector(0, galileo_handle_int); +} diff -Nru a/arch/mips/galileo-boards/ev64120/promcon.c b/arch/mips/galileo-boards/ev64120/promcon.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/promcon.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,70 @@ +/* + * Wrap-around code for a console using the + * SGI PROM io-routines. + * + * Copyright (c) 1999 Ulf Carlsson + * + * Derived from DECstation promcon.c + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 2002 Ralf Baechle + */ + +#include <linux/tty.h> +#include <linux/major.h> +#include <linux/ptrace.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/fs.h> +/* +#include <asm/sgialib.h> +*/ + +static void prom_console_write(struct console *co, const char *s, + unsigned count) +{ + extern int CONSOLE_CHANNEL; // The default serial port + unsigned i; + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + if (*s == 10) + serial_putc(CONSOLE_CHANNEL, 13); + serial_putc(CONSOLE_CHANNEL, *s++); + } +} +int prom_getchar(void) +{ + return 0; +} +static int __init prom_console_setup(struct console *co, char *options) +{ + return 0; +} + +static kdev_t prom_console_device(struct console *c) +{ + return mk_kdev(TTY_MAJOR, 64 + c->index); +} + +static struct console sercons = { + .name = "ttyS", + .write = prom_console_write, + .device = prom_console_device, + .setup = prom_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + + +/* + * Register console. + */ + +void gal_serial_console_init(void) +{ + // serial_init(); + //serial_set(115200); + + register_console(&sercons); +} diff -Nru a/arch/mips/galileo-boards/ev64120/reset.c b/arch/mips/galileo-boards/ev64120/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,45 @@ +/* + * 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) 1997, 2002 Ralf Baechle + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/io.h> +#include <asm/cacheflush.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/system.h> + +void galileo_machine_restart(char *command) +{ + *(volatile char *) 0xbc000000 = 0x0f; + /* + * Ouch, we're still alive ... This time we take the silver bullet ... + * ... and find that we leave the hardware in a state in which the + * kernel in the flush locks up somewhen during of after the PCI + * detection stuff. + */ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +} + +void galileo_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); + +} + +void galileo_machine_power_off(void) +{ + galileo_machine_halt(); +} diff -Nru a/arch/mips/galileo-boards/ev64120/serialGT.c b/arch/mips/galileo-boards/ev64120/serialGT.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/serialGT.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,212 @@ +/* + * serialGT.c + * + * BRIEF MODULE DESCRIPTION + * Low Level Serial Port control for use + * with the Galileo EVB64120A MIPS eval board and + * its on board two channel 16552 Uart. + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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. + * + */ + +// Note: +// Serial CHANNELS - 0 is the bottom connector of evb64120A. +// (The one that maps to the "B" channel of the +// board's uart) +// 1 is the top connector of evb64120A. +// (The one that maps to the "A" channel of the +// board's uart) +int DEBUG_CHANNEL = 0; // See Note Above +int CONSOLE_CHANNEL = 1; // See Note Above + +#define DUART 0xBD000000 /* Base address of Uart. */ +#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA + register set of the 16552 Uart device. + DUART+0 gets you to the ChanB register set. + */ +#define DUART_DELTA 0x4 +#define FIFO_ENABLE 0x07 +#define INT_ENABLE 0x04 /* default interrupt mask */ + +#define RBR 0x00 +#define THR 0x00 +#define DLL 0x00 +#define IER 0x01 +#define DLM 0x01 +#define IIR 0x02 +#define FCR 0x02 +#define LCR 0x03 +#define MCR 0x04 +#define LSR 0x05 +#define MSR 0x06 +#define SCR 0x07 + +#define LCR_DLAB 0x80 +#define XTAL 1843200 +#define LSR_THRE 0x20 +#define LSR_BI 0x10 +#define LSR_DR 0x01 +#define MCR_LOOP 0x10 +#define ACCESS_DELAY 0x10000 + +/****************************** + Routine: + Description: + ******************************/ +int inreg(int channel, int reg) +{ + int val; + val = + *((volatile unsigned char *) DUART + + (channel * CHANNELOFFSET) + (reg * DUART_DELTA)); + return val; +} + +/****************************** + Routine: + Description: + ******************************/ +void outreg(int channel, int reg, unsigned char val) +{ + *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET) + + (reg * DUART_DELTA)) = val; +} + +/****************************** + Routine: + Description: + Initialize the device driver. + ******************************/ +void serial_init(int channel) +{ + /* + * Configure active port, (CHANNELOFFSET already set.) + * + * Set 8 bits, 1 stop bit, no parity. + * + * LCR<7> 0 divisor latch access bit + * LCR<6> 0 break control (1=send break) + * LCR<5> 0 stick parity (0=space, 1=mark) + * LCR<4> 0 parity even (0=odd, 1=even) + * LCR<3> 0 parity enable (1=enabled) + * LCR<2> 0 # stop bits (0=1, 1=1.5) + * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8) + */ + outreg(channel, LCR, 0x3); + + outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */ + + outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */ +} + +/****************************** + Routine: + Description: + Set the baud rate. + ******************************/ +void serial_set(int channel, unsigned long baud) +{ + unsigned char sav_lcr; + + /* + * Enable access to the divisor latches by setting DLAB in LCR. + * + */ + sav_lcr = inreg(channel, LCR); + +#if 0 + /* + * Set baud rate + */ + outreg(channel, LCR, LCR_DLAB | sav_lcr); + // outreg(DLL,(XTAL/(16*2*(baud))-2)); + outreg(channel, DLL, XTAL / (16 * baud)); + // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8); + outreg(channel, DLM, (XTAL / (16 * baud)) >> 8); +#else + /* + * Note: Set baud rate, hardcoded here for rate of 115200 + * since became unsure of above "buad rate" algorithm (??). + */ + outreg(channel, LCR, 0x83); + outreg(channel, DLM, 0x00); // See note above + outreg(channel, DLL, 0x02); // See note above. + outreg(channel, LCR, 0x03); +#endif + + /* + * Restore line control register + */ + outreg(channel, LCR, sav_lcr); +} + + +/****************************** + Routine: + Description: + Transmit a character. + ******************************/ +void serial_putc(int channel, int c) +{ + while ((inreg(channel, LSR) & LSR_THRE) == 0); + outreg(channel, THR, c); +} + +/****************************** + Routine: + Description: + Read a received character if one is + available. Return -1 otherwise. + ******************************/ +int serial_getc(int channel) +{ + if (inreg(channel, LSR) & LSR_DR) { + return inreg(channel, RBR); + } + return -1; +} + +/****************************** + Routine: + Description: + Used by embedded gdb client. (example; gdb-stub.c) + ******************************/ +char getDebugChar() +{ + int val; + while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in. + return (char) val; +} + +/****************************** + Routine: + Description: + Used by embedded gdb target. (example; gdb-stub.c) + ******************************/ +void putDebugChar(char c) +{ + serial_putc(DEBUG_CHANNEL, (int) c); +} diff -Nru a/arch/mips/galileo-boards/ev64120/setup.c b/arch/mips/galileo-boards/ev64120/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev64120/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,176 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo Evaluation Boards - board dependent boot routines + * + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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 <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <linux/version.h> + +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/mc146818rtc.h> +#include <asm/traps.h> + +extern struct rtc_ops no_rtc_ops; + +/* These functions are used for rebooting or halting the machine*/ +extern void galileo_machine_restart(char *command); +extern void galileo_machine_halt(void); +extern void galileo_machine_power_off(void); +/* + *This structure holds pointers to the pci configuration space accesses + *and interrupts allocating routine for device over the PCI + */ +extern struct pci_ops galileo_pci_ops; + +extern unsigned long mips_machgroup; + +char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 " + "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal " + "ip=192.168.1.211:192.168.1.1:::gt::" +}; + +//struct eeprom_parameters eeprom_param; + +/* + * This function is added because arch/mips/mm/init.c needs it + * basically it does nothing + */ +void prom_free_prom_memory(void) +{ +} + +extern void (*board_time_init) (struct irqaction * irq); + +static unsigned char galileo_rtc_read_data(unsigned long addr) +{ + return 0; +} + +static void galileo_rtc_write_data(unsigned char data, unsigned long addr) +{ +} + +static int galileo_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops galileo_rtc_ops = { + &galileo_rtc_read_data, + &galileo_rtc_write_data, + &galileo_rtc_bcd_mode +}; + +/******************************************************************** + *ev64120_setup - + * + *Initializes basic routines and structures pointers, memory size (as + *given by the bios and saves the command line. + * + * + *Inputs : + * + *Outpus : + * + *********************************************************************/ +extern void galileo_time_init(); + +void __init ev64120_setup(void) +{ + _machine_restart = galileo_machine_restart; + _machine_halt = galileo_machine_halt; + _machine_power_off = galileo_machine_power_off; + + rtc_ops = &galileo_rtc_ops; + + board_time_init = galileo_time_init; + set_io_port_base(KSEG1); + +#ifdef CONFIG_L2_L3_CACHE +#error "external cache not implemented yet" + config_register = read_c0_config(); + printk("\n\n\nchecking second level cache cp0_config = %08lx\n", + config_register); + if (config_register & CONF_SC) { // second/third level cache available + config_register = config_register & (1 << 12); + write_c0_config(config_register); + printk + ("\n\n\nchecking second level cache c0_config = %08lx\n", + config_register); + } +#endif +} + +const char *get_system_type(void) +{ + return "Galileo EV64120A"; +} + +/* + * SetUpBootInfo - + * + * This function is called at very first stages of kernel startup. + * It specifies for the kernel the evaluation board that the linux + * is running on. Then it saves the eprom parameters that holds the + * command line, memory size etc... + * + * Inputs : + * argc - nothing + * argv - holds a pointer to the eprom parameters + * envp - nothing + */ + +void SetUpBootInfo(int argc, char **argv, char **envp) +{ + mips_machgroup = MACH_GROUP_GALILEO; + mips_machtype = MACH_EV64120A; +} + +void __init prom_init(int a, char **b, char **c, int *d) +{ + mips_machgroup = MACH_GROUP_GALILEO; + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} diff -Nru a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,11 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Galileo EV96100 board. +# + +obj-y += init.o time.o irq.o int-handler.o setup.o puts.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/galileo-boards/ev96100/init.c b/arch/mips/galileo-boards/ev96100/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,174 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/generic.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <linux/string.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +#include <asm/galileo-boards/ev96100.h> + + +/* Environment variable */ + +typedef struct { + char *name; + char *val; +} t_env_var; + +int prom_argc; +char **prom_argv, **prom_envp; +char arcs_cmdline[CL_SIZE]; + +int init_debug = 0; + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void prom_free_prom_memory (void) +{ +} + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +char *prom_getenv(char *envname) +{ + /* + * Return a pointer to the given environment variable. + */ + + t_env_var *env = (t_env_var *) prom_envp; + int i; + + i = strlen(envname); + + while (env->name) { + if (strncmp(envname, env->name, i) == 0) { + return (env->val); + } + env++; + } + return (NULL); +} + +static inline unsigned char str2hexnum(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; /* foo */ +} + +static inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for (i = 0; i < 6; i++) { + unsigned char num; + + if ((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + + if (init_debug > 1) { + int i; + printk("get_ethernet_addr: "); + for (i = 0; i < 5; i++) + printk("%02x:", + (unsigned char) *(ethernet_addr + i)); + printk("%02x\n", *(ethernet_addr + i)); + } + + return 0; +} + +const char *get_system_type(void) +{ + return "Galileo EV96100"; +} + +void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + volatile unsigned char *uart; + char ppbuf[8]; + + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_GALILEO; + mips_machtype = MACH_EV96100; + + prom_init_cmdline(); + + /* 32 MB upgradable */ + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} diff -Nru a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/int-handler.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,32 @@ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + .set noat + .align 5 + +NESTED(ev96100IRQ, PT_SIZE, sp) + SAVE_ALL + CLI # Important: mark KERNEL mode ! + + mfc0 t0, CP0_CAUSE # get pending interrupts + mfc0 t1, CP0_STATUS # get enabled interrupts + and t0, t1 # isolate allowed ones + + # FIX ME add R7000 extensions + andi t0,0xff00 # isolate pending bits + andi a0, t0, CAUSEF_IP7 + beq a0, zero, 1f + move a0, sp + jal mips_timer_interrupt + j ret_from_irq + +1: beqz t0, 3f # spurious interrupt + move a0, t0 + move a1, sp # delay slot + jal ev96100_cpu_irq + j ret_from_irq + +3: j spurious_interrupt + END(ev96100IRQ) diff -Nru a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,133 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_int.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/irq.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> + +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/galileo-boards/ev96100int.h> + +extern void mips_timer_interrupt(int irq, struct pt_regs *regs); +extern asmlinkage void ev96100IRQ(void); + +static void disable_ev96100_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + clear_c0_status(0x100 << irq_nr); + local_irq_restore(flags); +} + +static inline void enable_ev96100_irq(unsigned int irq_nr) +{ + unsigned long flags; + + local_irq_save(flags); + set_c0_status(0x100 << irq_nr); + local_irq_restore(flags); +} + +static unsigned int startup_ev96100_irq(unsigned int irq) +{ + enable_ev96100_irq(irq); + + return 0; /* never anything pending */ +} + +#define shutdown_ev96100_irq disable_ev96100_irq +#define mask_and_ack_ev96100_irq disable_ev96100_irq + +static void end_ev96100_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_ev96100_irq(irq); +} + +static inline unsigned int ffz8(unsigned int word) +{ + unsigned long k; + + k = 7; + if (word & 0x0fUL) { k -= 4; word <<= 4; } + if (word & 0x30UL) { k -= 2; word <<= 2; } + if (word & 0x40UL) { k -= 1; } + + return k; +} + +asmlinkage void ev96100_cpu_irq(unsigned long cause, struct pt_regs * regs) +{ + if (!(cause & 0xff00)) + return; + + do_IRQ(ffz8((cause >> 8) & 0xff), regs); +} + +static struct hw_interrupt_type ev96100_irq_type = { + "EV96100", + startup_ev96100_irq, + shutdown_ev96100_irq, + enable_ev96100_irq, + disable_ev96100_irq, + mask_and_ack_ev96100_irq, + end_ev96100_irq +}; + +void __init init_IRQ(void) +{ + int i; + + set_except_vector(0, ev96100IRQ); + init_generic_irq(); + + for (i = 0; i < 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &ev96100_irq_type; + } +} diff -Nru a/arch/mips/galileo-boards/ev96100/puts.c b/arch/mips/galileo-boards/ev96100/puts.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/puts.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,144 @@ + +/* + * Debug routines which directly access the uart. + */ + +#include <linux/types.h> +#include <asm/galileo-boards/ev96100.h> + + +//#define SERIAL_BASE EV96100_UART0_REGS_BASE +#define SERIAL_BASE 0xBD000020 +#define NS16550_BASE SERIAL_BASE + +#define SERA_CMD 0x0D +#define SERA_DATA 0x08 +//#define SERB_CMD 0x05 +#define SERB_CMD 20 +#define SERB_DATA 0x00 +#define TX_BUSY 0x20 + +#define TIMEOUT 0xffff +#undef SLOW_DOWN + +static const char digits[16] = "0123456789abcdef"; +static volatile unsigned char * const com1 = (unsigned char *)SERIAL_BASE; + + +#ifdef SLOW_DOWN +static inline void slow_down() +{ + int k; + for (k=0; k<10000; k++); +} +#else +#define slow_down() +#endif + +void +putch(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void +putchar(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void +puts(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } + putch('\r'); + putch('\n'); +} + +void +fputs(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } +} + + +void +put64(uint64_t ul) +{ + int cnt; + unsigned ch; + + cnt = 16; /* 16 nibbles in a 64 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char)(ul >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} + +void +put32(unsigned u) +{ + int cnt; + unsigned ch; + + cnt = 8; /* 8 nibbles in a 32 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char)(u >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} diff -Nru a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,206 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_setup.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/mc146818rtc.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <linux/pci.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/mipsregs.h> +#include <asm/irq.h> +#include <asm/delay.h> +#include <asm/gt64120.h> +#include <asm/galileo-boards/ev96100.h> +#include <asm/galileo-boards/ev96100int.h> + + +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) +extern void console_setup(char *, int *); +char serial_console[20]; +#endif + +extern char * __init prom_getcmdline(void); + +extern void mips_reboot_setup(void); +extern struct rtc_ops no_rtc_ops; +extern struct resource ioport_resource; + +unsigned char mac_0_1[12]; + +void __init ev96100_setup(void) +{ + unsigned long config = read_c0_config(); + unsigned long status = read_c0_status(); + unsigned long info = read_c0_info(); + u32 tmp; + + char *argptr; + + clear_c0_status(ST0_FR); + + if (config & 0x8) { + printk("Secondary cache is enabled\n"); + } + else { + printk("Secondary cache is disabled\n"); + } + + if (status & (1<<27)) { + printk("User-mode cache ops enabled\n"); + } + else { + printk("User-mode cache ops disabled\n"); + } + + printk("CP0 info reg: %x\n", (unsigned)info); + if (info & (1<<28)) { + printk("burst mode Scache RAMS\n"); + } + else { + printk("pipelined Scache RAMS\n"); + } + + if ((info & (0x3<<26)) >> 26 == 0) { + printk("67 percent drive strength\n"); + } + else if ((info & (0x3<<26)) >> 26 == 1) { + printk("50 percent drive strength\n"); + } + else if ((info & (0x3<<26)) >> 26 == 2) { + printk("100 percent drive strength\n"); + } + else if ((info & (0x3<<26)) >> 26 == 3) { + printk("83 percent drive strength\n"); + } + + + if ((info & (0x3<<23)) >> 23 == 0) { + printk("Write Protocol: R4000 compatible\n"); + } + else if ((info & (0x3<<23)) >> 23 == 1) { + printk("Write Protocol: Reserved\n"); + } + else if ((info & (0x3<<23)) >> 23 == 2) { + printk("Write Protocol: Pipelined\n"); + } + else if ((info & (0x3<<23)) >> 23 == 3) { + printk("Write Protocol: Write re-issue\n"); + } + + if (info & 0x1) { + printk("Atomic Enable is set\n"); + } + + argptr = prom_getcmdline(); +#ifdef CONFIG_SERIAL_CONSOLE + if (strstr(argptr, "console=") == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + + rtc_ops = &no_rtc_ops; + mips_reboot_setup(); + set_io_port_base(KSEG1); + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; +#endif + + + /* + * setup gt controller master bit so we can do config cycles + */ + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + + tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + *(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS) = cpu_to_le32(tmp); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); +} + +unsigned short get_gt_devid(void) +{ + u32 gt_devid; + + /* Figure out if this is a gt96100 or gt96100A */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(4); + gt_devid = le32_to_cpu(*(volatile u32 *) + (MIPS_GT_BASE+GT_PCI0_CFGDATA_OFS)); + return (unsigned short)(gt_devid>>16); +} diff -Nru a/arch/mips/galileo-boards/ev96100/time.c b/arch/mips/galileo-boards/ev96100/time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/ev96100/time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,276 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 rtc routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_rtc.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/sched.h> +#include <linux/spinlock.h> + +#include <asm/mipsregs.h> +#include <asm/ptrace.h> + +#include <linux/timex.h> + + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) + +extern volatile unsigned long wall_jiffies; +unsigned long missed_heart_beats = 0; + +static unsigned long r4k_offset; /* Amount to increment compare reg each time */ +static unsigned long r4k_cur; /* What counter should be at next timer irq */ + +static inline void ack_r4ktimer(unsigned long newval) +{ + write_c0_compare(newval); +} + +static int set_rtc_mmss(unsigned long nowtime) +{ + /* EV96100 does not have a real time clock */ + int retval = 0; + + return retval; +} + + + +/* + * Figure out the r4k offset, the amount to increment the compare + * register for each time tick. + * Use the RTC to calculate offset. + */ +static unsigned long __init cal_r4koff(void) +{ + unsigned long count; + count = 300000000/2; + return (count / HZ); +} + + +static unsigned long __init get_mips_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + + year = 2000; + mon = 10; + day = 31; + hour = 0; + min = 0; + sec = 0; + return mktime(year, mon, day, hour, min, sec); +} + + +/* + * called from start_kernel() + */ +void __init time_init(void) +{ + + unsigned int est_freq; + + r4k_offset = cal_r4koff(); + + est_freq = 2*r4k_offset*HZ; + est_freq += 5000; /* round */ + est_freq -= est_freq%10000; + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000); + r4k_cur = (read_c0_count() + r4k_offset); + + write_c0_compare(r4k_cur); + + change_c0_status(ST0_IM, IE_IRQ5); /* FIX ME */ +} + +/* This is for machines which generate the exact clock. */ +#define USECS_PER_JIFFY (1000000/HZ) + +/* Cycle counter value at the previous timer interrupt.. */ + +static unsigned int timerhi = 0, timerlo = 0; + +/* + * FIXME: Does playing with the RP bit in c0_status interfere with this code? + */ +static unsigned long do_fast_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + + /* Last jiffy when do_fast_gettimeoffset() was called. */ + static unsigned long last_jiffies=0; + unsigned long quotient; + + /* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ + static unsigned long cached_quotient=0; + + tmp = jiffies; + + quotient = cached_quotient; + + if (tmp && last_jiffies != tmp) { + last_jiffies = tmp; + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "lwu\t%0,%2\n\t" + "dsll32\t$1,%1,0\n\t" + "or\t$1,$1,%0\n\t" + "ddivu\t$0,$1,%3\n\t" + "mflo\t$1\n\t" + "dsll32\t%0,%4,0\n\t" + "nop\n\t" + "ddivu\t$0,%0,$1\n\t" + "mflo\t%0\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=&r" (quotient) + :"r" (timerhi), + "m" (timerlo), + "r" (tmp), + "r" (USECS_PER_JIFFY)); + cached_quotient = quotient; + } + + /* Get last timer tick in absolute kernel time */ + count = read_c0_count(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu\t%1,%2\n\t" + "mfhi\t%0" + :"=r" (res) + :"r" (count), + "r" (quotient)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + + return res; +} + +/* + * This version of gettimeofday has microsecond resolution + * and better than microsecond precision on fast x86 machines with TSC. + */ +void do_gettimeofday(struct timeval *tv) +{ + unsigned long seq; + unsigned long usec, sec; + + do { + seq = read_seqbegin(&xtime_lock); + + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry(&xtime_lock, seq)); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +void do_settimeofday(struct timeval *tv) +{ + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! + */ + tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); + + while (tv->tv_usec < 0) { + tv->tv_usec += 1000000; + tv->tv_sec--; + } + + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = (tv->tv_usec * 1000); + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + write_sequnlock_irq(&xtime_lock); +} + +/* + * There are a lot of conceptually broken versions of the MIPS timer interrupt + * handler floating around. This one is rather different, but the algorithm + * is probably more robust. + */ +void mips_timer_interrupt(struct pt_regs *regs) +{ + int irq = 7; /* FIX ME */ + + if (r4k_offset == 0) { + goto null; + } + + do { + kstat_cpu(0).irqs[irq]++; + do_timer(regs); + r4k_cur += r4k_offset; + ack_r4ktimer(r4k_cur); + + } while (((unsigned long)read_c0_count() + - r4k_cur) < 0x7fffffff); + return; + +null: + ack_r4ktimer(0); +} diff -Nru a/arch/mips/galileo-boards/generic/Makefile b/arch/mips/galileo-boards/generic/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/generic/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,25 @@ +# +# Carsten Langgaard, carstenl@mips.com +# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. +# +# ######################################################################## +# +# This program is free software; you can distribute it and/or modify it +# under the terms of the GNU General Public License (Version 2) as +# published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# ####################################################################### +# +# Makefile for the MIPS boards generic routines under Linux. +# + +obj-y := reset.o diff -Nru a/arch/mips/galileo-boards/generic/reset.c b/arch/mips/galileo-boards/generic/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/galileo-boards/generic/reset.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,72 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 reset routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/reset.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/sched.h> +#include <linux/mm.h> +#include <asm/cacheflush.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/system.h> + +#include <asm/reboot.h> +#include <asm/galileo-boards/ev96100.h> + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); + while (1); +} + +static void mips_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; +} diff -Nru a/arch/mips/jmr3927/common/Makefile b/arch/mips/jmr3927/common/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/common/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,5 @@ +# +# Makefile for the common code of TOSHIBA JMR-TX3927 board +# + +obj-y += prom.o puts.o rtc_ds1742.o diff -Nru a/arch/mips/jmr3927/common/prom.c b/arch/mips/jmr3927/common/prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/common/prom.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,88 @@ +/* + * BRIEF MODULE DESCRIPTION + * PROM library initialisation code, assuming a version of + * pmon is the boot code. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Based on arch/mips/au1000/common/prom.c + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/xx files. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/kernel.h> +#include <linux/init.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> + +/* #define DEBUG_CMDLINE */ + +char arcs_cmdline[CL_SIZE]; +extern int prom_argc; +extern char **prom_argv, **prom_envp; + +typedef struct +{ + char *name; +/* char *val; */ +}t_env_var; + + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +int __init page_is_ram(unsigned long pagenr) +{ + return 1; +} + +void prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/jmr3927/common/puts.c b/arch/mips/jmr3927/common/puts.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/common/puts.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,168 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Low level uart routines to directly access a TX[34]927 SIO. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com or source@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Based on arch/mips/au1000/common/puts.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/types.h> +#include <asm/jmr3927/txx927.h> +#include <asm/jmr3927/tx3927.h> +#include <asm/jmr3927/jmr3927.h> + +#define TIMEOUT 0xffffff +#define SLOW_DOWN + +static const char digits[16] = "0123456789abcdef"; + +#ifdef SLOW_DOWN +#define slow_down() { int k; for (k=0; k<10000; k++); } +#else +#define slow_down() +#endif + +void +putch(const unsigned char c) +{ + int i = 0; + + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); + tx3927_sioptr(1)->tfifo = c; + return; +} + +unsigned char getch(void) +{ + int i = 0; + int dicr; + char c; + + /* diable RX int. */ + dicr = tx3927_sioptr(1)->dicr; + tx3927_sioptr(1)->dicr = 0; + + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (tx3927_sioptr(1)->disr & TXx927_SIDISR_UVALID) + ; + c = tx3927_sioptr(1)->rfifo; + + /* clear RX int. status */ + tx3927_sioptr(1)->disr &= ~TXx927_SIDISR_RDIS; + /* enable RX int. */ + tx3927_sioptr(1)->dicr = dicr; + + return c; +} +void +do_jmr3927_led_set(char n) +{ + /* and with current leds */ + jmr3927_led_and_set(n); +} + +void +puts(unsigned char *cp) +{ + int i = 0; + + while (*cp) { + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); + tx3927_sioptr(1)->tfifo = *cp++; + } + putch('\r'); + putch('\n'); +} + +void +fputs(unsigned char *cp) +{ + int i = 0; + + while (*cp) { + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (!(tx3927_sioptr(1)->cisr & TXx927_SICISR_TXALS)); + tx3927_sioptr(1)->tfifo = *cp++; + } +} + + +void +put64(uint64_t ul) +{ + int cnt; + unsigned ch; + + cnt = 16; /* 16 nibbles in a 64 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char)(ul >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} + +void +put32(unsigned u) +{ + int cnt; + unsigned ch; + + cnt = 8; /* 8 nibbles in a 32 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char)(u >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} diff -Nru a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/common/rtc_ds1742.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,165 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * arch/mips/jmr3927/common/rtc_ds1742.c + * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c + * low-level RTC hookups for s for Dallas 1742 chip. + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 exports a function, rtc_ds1386_init(), which expects an + * uncached base address as the argument. It will set the two function + * pointers expected by the MIPS generic timer code. + */ + +#include <linux/bcd.h> +#include <linux/types.h> +#include <linux/time.h> +#include <linux/rtc.h> + +#include <asm/time.h> +#include <asm/addrspace.h> + +#include <asm/jmr3927/ds1742rtc.h> +#include <asm/debug.h> + +#define EPOCH 2000 + +static unsigned long rtc_base; + +static unsigned long +rtc_ds1742_get_time(void) +{ + unsigned int year, month, day, hour, minute, second; + unsigned int century; + + CMOS_WRITE(RTC_READ, RTC_CONTROL); + second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); + minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); + hour = BCD2BIN(CMOS_READ(RTC_HOURS)); + day = BCD2BIN(CMOS_READ(RTC_DATE)); + month = BCD2BIN(CMOS_READ(RTC_MONTH)); + year = BCD2BIN(CMOS_READ(RTC_YEAR)); + century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); + CMOS_WRITE(0, RTC_CONTROL); + + year += century * 100; + + return mktime(year, month, day, hour, minute, second); +} +extern void to_tm(unsigned long tim, struct rtc_time * tm); + +static int +rtc_ds1742_set_time(unsigned long t) +{ + struct rtc_time tm; + u8 year, month, day, hour, minute, second; + u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; + int cmos_century; + + CMOS_WRITE(RTC_READ, RTC_CONTROL); + cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); + cmos_minute = (u8)CMOS_READ(RTC_MINUTES); + cmos_hour = (u8)CMOS_READ(RTC_HOURS); + cmos_day = (u8)CMOS_READ(RTC_DATE); + cmos_month = (u8)CMOS_READ(RTC_MONTH); + cmos_year = (u8)CMOS_READ(RTC_YEAR); + cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; + + CMOS_WRITE(RTC_WRITE, RTC_CONTROL); + + /* convert */ + to_tm(t, &tm); + + /* check each field one by one */ + year = BIN2BCD(tm.tm_year - EPOCH); + if (year != cmos_year) { + CMOS_WRITE(year,RTC_YEAR); + } + + month = BIN2BCD(tm.tm_mon); + if (month != (cmos_month & 0x1f)) { + CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); + } + + day = BIN2BCD(tm.tm_mday); + if (day != cmos_day) { + + CMOS_WRITE(day, RTC_DATE); + } + + if (cmos_hour & 0x40) { + /* 12 hour format */ + hour = 0x40; + if (tm.tm_hour > 12) { + hour |= 0x20 | (BIN2BCD(hour-12) & 0x1f); + } else { + hour |= BIN2BCD(tm.tm_hour); + } + } else { + /* 24 hour format */ + hour = BIN2BCD(tm.tm_hour) & 0x3f; + } + if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); + + minute = BIN2BCD(tm.tm_min); + if (minute != cmos_minute) { + CMOS_WRITE(minute, RTC_MINUTES); + } + + second = BIN2BCD(tm.tm_sec); + if (second != cmos_second) { + CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); + } + + /* RTC_CENTURY and RTC_CONTROL share same address... */ + CMOS_WRITE(cmos_century, RTC_CONTROL); + + return 0; +} + +void +rtc_ds1742_init(unsigned long base) +{ + u8 cmos_second; + + /* remember the base */ + rtc_base = base; + db_assert((rtc_base & 0xe0000000) == KSEG1); + + /* set the function pointers */ + rtc_get_time = rtc_ds1742_get_time; + rtc_set_time = rtc_ds1742_set_time; + + /* clear oscillator stop bit */ + CMOS_WRITE(RTC_READ, RTC_CONTROL); + cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); + CMOS_WRITE(RTC_WRITE, RTC_CONTROL); + CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ + CMOS_WRITE(0, RTC_CONTROL); +} diff -Nru a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,9 @@ +# +# Makefile for TOSHIBA JMR-TX3927 board +# + +obj-y += init.o int-handler.o irq.o setup.o rtc.o +obj-$(CONFIG_RUNTIME_DEBUG) += debug.o +obj-$(CONFIG_KGDB) += kgdb_io.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/jmr3927/rbhma3100/init.c b/arch/mips/jmr3927/rbhma3100/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,80 @@ +/*********************************************************************** + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * arch/mips/jmr3927/common/init.c + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/config.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/mipsregs.h> +#include <asm/jmr3927/jmr3927.h> + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); +unsigned long mips_nofpu = 0; + +const char *get_system_type(void) +{ + return "Toshiba" +#ifdef CONFIG_TOSHIBA_JMR3927 + " JMR_TX3927" +#endif + ; +} + +extern void puts(unsigned char *cp); +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ +#ifdef CONFIG_TOSHIBA_JMR3927 + /* CCFG */ + if ((tx3927_ccfgptr->ccfg & TX3927_CCFG_TLBOFF) == 0) + puts("Warning: TX3927 TLB off\n"); +#endif + prom_argc = argc; + prom_argv = argv; + prom_envp = envp; + + mips_machgroup = MACH_GROUP_TOSHIBA; + +#ifdef CONFIG_TOSHIBA_JMR3927 + mips_machtype = MACH_TOSHIBA_JMR3927; +#endif + + prom_init_cmdline(); + add_memory_region(0, JMR3927_SDRAM_SIZE, BOOT_MEM_RAM); + return 0; +} diff -Nru a/arch/mips/jmr3927/rbhma3100/int-handler.S b/arch/mips/jmr3927/rbhma3100/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/int-handler.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,74 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Based on arch/mips/tsdb/kernel/int-handler.S + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/jmr3927/jmr3927.h> + + /* A lot of complication here is taken away because: + * + * 1) We handle one interrupt and return, sitting in a loop + * and moving across all the pending IRQ bits in the cause + * register is _NOT_ the answer, the common case is one + * pending IRQ so optimize in that direction. + * + * 2) We need not check against bits in the status register + * IRQ mask, that would make this routine slow as hell. + * + * 3) Linux only thinks in terms of all IRQs on or all IRQs + * off, nothing in between like BSD spl() brain-damage. + * + */ + +/* Flush write buffer (needed?) + * NOTE: TX39xx performs "non-blocking load", so explicitly use the target + * register of LBU to flush immediately. + */ +#define FLUSH_WB(tmp) \ + la tmp, JMR3927_IOC_REV_ADDR; \ + lbu tmp, (tmp); \ + move tmp, zero; + + .text + .set noreorder + .set noat + .align 5 + NESTED(jmr3927_IRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + jal jmr3927_irc_irqdispatch + move a0, sp + FLUSH_WB(t0) + j ret_from_irq + nop + END(jmr3927_IRQ) diff -Nru a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,514 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * 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) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/config.h> +#include <linux/init.h> + +#include <linux/errno.h> +#include <linux/irq.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> + +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + +#include <asm/ptrace.h> +#include <asm/processor.h> +#include <asm/jmr3927/irq.h> +#include <asm/debug.h> +#include <asm/jmr3927/jmr3927.h> + +#if JMR3927_IRQ_END > NR_IRQS +#error JMR3927_IRQ_END > NR_IRQS +#endif + +struct tb_irq_space* tb_irq_spaces; + +unsigned int local_bh_count[NR_CPUS]; +unsigned int local_irq_count[NR_CPUS]; + +static int jmr3927_irq_base=-1; + +#ifdef CONFIG_PCI +static int jmr3927_gen_iack(void) +{ + /* generate ACK cycle */ +#ifdef __BIG_ENDIAN + return (tx3927_pcicptr->iiadp >> 24) & 0xff; +#else + return tx3927_pcicptr->iiadp & 0xff; +#endif +} +#endif + +extern asmlinkage void jmr3927_IRQ(void); + +#define irc_dlevel 0 +#define irc_elevel 1 +static unsigned char irc_level[TX3927_NUM_IR] = { + 5, 5, 5, 5, 5, 5, /* INT[5:0] */ + 7, 7, /* SIO */ + 5, 5, 5, 0, 0, /* DMA, PIO, PCI */ + 6, 6, 6 /* TMR */ +}; + +static inline void mask_irq(unsigned int irq_nr) +{ + struct tb_irq_space* sp; + for (sp = tb_irq_spaces; sp; sp = sp->next) { + if (sp->start_irqno <= irq_nr && + irq_nr < sp->start_irqno + sp->nr_irqs) { + if (sp->mask_func) + sp->mask_func(irq_nr - sp->start_irqno, + sp->space_id); + break; + } + } +} + +static inline void unmask_irq(unsigned int irq_nr) +{ + struct tb_irq_space* sp; + for (sp = tb_irq_spaces; sp; sp = sp->next) { + if (sp->start_irqno <= irq_nr && + irq_nr < sp->start_irqno + sp->nr_irqs) { + if (sp->unmask_func) + sp->unmask_func(irq_nr - sp->start_irqno, + sp->space_id); + break; + } + } +} + +static void jmr3927_irq_disable(unsigned int irq_nr); +static void jmr3927_irq_enable(unsigned int irq_nr); + +static unsigned int jmr3927_irq_startup(unsigned int irq) +{ + jmr3927_irq_enable(irq); + return 0; +} + +#define jmr3927_irq_shutdown jmr3927_irq_disable + +static void jmr3927_irq_ack(unsigned int irq) +{ + db_assert(jmr3927_irq_base != -1); + db_assert(irq >= jmr3927_irq_base); + db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); + + if (irq == JMR3927_IRQ_IRC_TMR0) { + jmr3927_tmrptr->tisr = 0; /* ack interrupt */ + } + + jmr3927_irq_disable(irq); +} + +static void jmr3927_irq_end(unsigned int irq) +{ + db_assert(jmr3927_irq_base != -1); + db_assert(irq >= jmr3927_irq_base); + db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); + + jmr3927_irq_enable(irq); +} + +static void jmr3927_irq_disable(unsigned int irq_nr) +{ + unsigned long flags; + + db_assert(jmr3927_irq_base != -1); + db_assert(irq >= jmr3927_irq_base); + db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); + + local_irq_save(flags); + mask_irq(irq_nr); + local_irq_restore(flags); +} + +static void jmr3927_irq_enable(unsigned int irq_nr) +{ + unsigned long flags; + + db_assert(jmr3927_irq_base != -1); + db_assert(irq >= jmr3927_irq_base); + db_assert(irq < jmr3927_irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC); + + local_irq_save(flags); + unmask_irq(irq_nr); + local_irq_restore(flags); +} + +/* + * CP0_STATUS is a thread's resource (saved/restored on context switch). + * So disable_irq/enable_irq MUST handle IOC/ISAC/IRC registers. + */ +static void mask_irq_isac(int irq_nr, int space_id) +{ + /* 0: mask */ + unsigned char imask = + jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR); + unsigned int bit = 1 << irq_nr; + jmr3927_isac_reg_out(imask & ~bit, JMR3927_ISAC_INTM_ADDR); + /* flush write buffer */ + (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); +} +static void unmask_irq_isac(int irq_nr, int space_id) +{ + /* 0: mask */ + unsigned char imask = + jmr3927_isac_reg_in(JMR3927_ISAC_INTM_ADDR); + unsigned int bit = 1 << irq_nr; + jmr3927_isac_reg_out(imask | bit, JMR3927_ISAC_INTM_ADDR); + /* flush write buffer */ + (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); +} + +static void mask_irq_ioc(int irq_nr, int space_id) +{ + /* 0: mask */ + unsigned char imask = + jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); + unsigned int bit = 1 << irq_nr; + jmr3927_ioc_reg_out(imask & ~bit, JMR3927_IOC_INTM_ADDR); + /* flush write buffer */ + (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); +} +static void unmask_irq_ioc(int irq_nr, int space_id) +{ + /* 0: mask */ + unsigned char imask = + jmr3927_ioc_reg_in(JMR3927_IOC_INTM_ADDR); + unsigned int bit = 1 << irq_nr; + jmr3927_ioc_reg_out(imask | bit, JMR3927_IOC_INTM_ADDR); + /* flush write buffer */ + (void)jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR); +} + +static void mask_irq_irc(int irq_nr, int space_id) +{ + volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; + if (irq_nr & 1) + *ilrp = (*ilrp & 0x00ff) | (irc_dlevel << 8); + else + *ilrp = (*ilrp & 0xff00) | irc_dlevel; + /* update IRCSR */ + tx3927_ircptr->imr = 0; + tx3927_ircptr->imr = irc_elevel; +} +static void unmask_irq_irc(int irq_nr, int space_id) +{ + volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2]; + if (irq_nr & 1) + *ilrp = (*ilrp & 0x00ff) | (irc_level[irq_nr] << 8); + else + *ilrp = (*ilrp & 0xff00) | irc_level[irq_nr]; + /* update IRCSR */ + tx3927_ircptr->imr = 0; + tx3927_ircptr->imr = irc_elevel; +} + +struct tb_irq_space jmr3927_isac_irqspace = { + .next = NULL, + .start_irqno = JMR3927_IRQ_ISAC, + nr_irqs : JMR3927_NR_IRQ_ISAC, + .mask_func = mask_irq_isac, + .unmask_func = unmask_irq_isac, + .name = "ISAC", + .space_id = 0, + can_share : 0 +}; +struct tb_irq_space jmr3927_ioc_irqspace = { + .next = NULL, + .start_irqno = JMR3927_IRQ_IOC, + nr_irqs : JMR3927_NR_IRQ_IOC, + .mask_func = mask_irq_ioc, + .unmask_func = unmask_irq_ioc, + .name = "IOC", + .space_id = 0, + can_share : 1 +}; +struct tb_irq_space jmr3927_irc_irqspace = { + .next = NULL, + .start_irqno = JMR3927_IRQ_IRC, + nr_irqs : JMR3927_NR_IRQ_IRC, + .mask_func = mask_irq_irc, + .unmask_func = unmask_irq_irc, + .name = "on-chip", + .space_id = 0, + can_share : 0 +}; + +void jmr3927_spurious(struct pt_regs *regs) +{ +#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND + tx_branch_likely_bug_fixup(regs); +#endif + printk(KERN_WARNING "spurious interrupt (cause 0x%lx, pc 0x%lx, ra 0x%lx).\n", + regs->cp0_cause, regs->cp0_epc, regs->regs[31]); +} + +void jmr3927_irc_irqdispatch(struct pt_regs *regs) +{ + int irq; + +#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND + tx_branch_likely_bug_fixup(regs); +#endif + if ((regs->cp0_cause & CAUSEF_IP7) == 0) { +#if 0 + jmr3927_spurious(regs); +#endif + return; + } + irq = (regs->cp0_cause >> CAUSEB_IP2) & 0x0f; + + do_IRQ(irq + JMR3927_IRQ_IRC, regs); +} + +static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR); + int i; + + for (i = 0; i < JMR3927_NR_IRQ_IOC; i++) { + if (istat & (1 << i)) { + irq = JMR3927_IRQ_IOC + i; + do_IRQ(irq, regs); + } + } +} + +static struct irqaction ioc_action = { + jmr3927_ioc_interrupt, 0, 0, "IOC", NULL, NULL, +}; + +static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR); + int i; + + for (i = 0; i < JMR3927_NR_IRQ_ISAC; i++) { + if (istat & (1 << i)) { + irq = JMR3927_IRQ_ISAC + i; + do_IRQ(irq, regs); + } + } +} + +static struct irqaction isac_action = { + jmr3927_isac_interrupt, 0, 0, "ISAC", NULL, NULL, +}; + + +static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs) +{ + printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq); +} +static struct irqaction isaerr_action = { + jmr3927_isaerr_interrupt, 0, 0, "ISA error", NULL, NULL, +}; + +static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs) +{ + printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq); + printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n", + tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat); +} +static struct irqaction pcierr_action = { + jmr3927_pcierr_interrupt, 0, 0, "PCI error", NULL, NULL, +}; + +int jmr3927_ether1_irq = 0; + +void jmr3927_irq_init(u32 irq_base); +void jmr3927_irq_setup(void) +{ + /* look for io board's presence */ + int have_isac = jmr3927_have_isac(); + + /* Now, interrupt control disabled, */ + /* all IRC interrupts are masked, */ + /* all IRC interrupt mode are Low Active. */ + + if (have_isac) { + + /* ETHER1 (NE2000 compatible 10M-Ether) parameter setup */ + /* temporary enable interrupt control */ + tx3927_ircptr->cer = 1; + /* ETHER1 Int. Is High-Active. */ + if (tx3927_ircptr->ssr & (1 << 0)) + jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT0; +#if 0 /* INT3 may be asserted by ether0 (even after reboot...) */ + else if (tx3927_ircptr->ssr & (1 << 3)) + jmr3927_ether1_irq = JMR3927_IRQ_IRC_INT3; +#endif + /* disable interrupt control */ + tx3927_ircptr->cer = 0; + + /* Ether1: High Active */ + if (jmr3927_ether1_irq) { + int ether1_irc = jmr3927_ether1_irq - JMR3927_IRQ_IRC; + tx3927_ircptr->cr[ether1_irc / 8] |= + TX3927_IRCR_HIGH << ((ether1_irc % 8) * 2); + } + } + + /* mask all IOC interrupts */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_INTM_ADDR); + /* setup IOC interrupt mode (SOFT:High Active, Others:Low Active) */ + jmr3927_ioc_reg_out(JMR3927_IOC_INTF_SOFT, JMR3927_IOC_INTP_ADDR); + + if (have_isac) { + /* mask all ISAC interrupts */ + jmr3927_isac_reg_out(0, JMR3927_ISAC_INTM_ADDR); + /* setup ISAC interrupt mode (ISAIRQ3,ISAIRQ5:Low Active ???) */ + jmr3927_isac_reg_out(JMR3927_ISAC_INTF_IRQ3|JMR3927_ISAC_INTF_IRQ5, JMR3927_ISAC_INTP_ADDR); + } + + /* clear PCI Soft interrupts */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_INTS1_ADDR); + /* clear PCI Reset interrupts */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + + /* enable interrupt control */ + tx3927_ircptr->cer = TX3927_IRCER_ICE; + tx3927_ircptr->imr = irc_elevel; + + jmr3927_irq_init(NR_ISA_IRQS); + + set_except_vector(0, jmr3927_IRQ); + + /* setup irq space */ + add_tb_irq_space(&jmr3927_isac_irqspace); + add_tb_irq_space(&jmr3927_ioc_irqspace); + add_tb_irq_space(&jmr3927_irc_irqspace); + + /* setup IOC interrupt 1 (PCI, MODEM) */ + setup_irq(JMR3927_IRQ_IOCINT, &ioc_action); + + if (have_isac) { + setup_irq(JMR3927_IRQ_ISACINT, &isac_action); + setup_irq(JMR3927_IRQ_ISAC_ISAER, &isaerr_action); + } + +#ifdef CONFIG_PCI + setup_irq(JMR3927_IRQ_IRC_PCI, &pcierr_action); +#endif + + /* enable all CPU interrupt bits. */ + set_c0_status(ST0_IM); /* IE bit is still 0. */ +} + +void (*irq_setup)(void); +void __init init_IRQ(void) +{ + +#ifdef CONFIG_KGDB + extern void breakpoint(void); + extern void set_debug_traps(void); + + puts("Wait for gdb client connection ...\n"); + set_debug_traps(); + breakpoint(); +#endif + + /* invoke board-specific irq setup */ + irq_setup(); +} + +hw_irq_controller jmr3927_irq_controller = { + "jmr3927_irq", + jmr3927_irq_startup, + jmr3927_irq_shutdown, + jmr3927_irq_enable, + jmr3927_irq_disable, + jmr3927_irq_ack, + jmr3927_irq_end, + NULL /* no affinity stuff for UP */ +}; + +void +jmr3927_irq_init(u32 irq_base) +{ + extern irq_desc_t irq_desc[]; + u32 i; + + for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &jmr3927_irq_controller; + } + + jmr3927_irq_base = irq_base; +} + +#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND +static int tx_branch_likely_bug_count = 0; +static int have_tx_branch_likely_bug = 0; +void tx_branch_likely_bug_fixup(struct pt_regs *regs) +{ + /* TX39/49-BUG: Under this condition, the insn in delay slot + of the branch likely insn is executed (not nullified) even + the branch condition is false. */ + if (!have_tx_branch_likely_bug) + return; + if ((regs->cp0_epc & 0xfff) == 0xffc && + KSEGX(regs->cp0_epc) != KSEG0 && + KSEGX(regs->cp0_epc) != KSEG1) { + unsigned int insn = *(unsigned int*)(regs->cp0_epc - 4); + /* beql,bnel,blezl,bgtzl */ + /* bltzl,bgezl,blezall,bgezall */ + /* bczfl, bcztl */ + if ((insn & 0xf0000000) == 0x50000000 || + (insn & 0xfc0e0000) == 0x04020000 || + (insn & 0xf3fe0000) == 0x41020000) { + regs->cp0_epc -= 4; + tx_branch_likely_bug_count++; + printk(KERN_INFO + "fix branch-likery bug in %s (insn %08x)\n", + current->comm, insn); + } + } +} +#endif diff -Nru a/arch/mips/jmr3927/rbhma3100/kgdb_io.c b/arch/mips/jmr3927/rbhma3100/kgdb_io.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/kgdb_io.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,155 @@ +/* + * BRIEF MODULE DESCRIPTION + * Low level uart routines to directly access a TX[34]927 SIO. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com or source@mvista.com + * + * Based on arch/mips/ddb5xxx/ddb5477/kgdb_io.c + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/types.h> +#include <asm/jmr3927/txx927.h> +#include <asm/jmr3927/tx3927.h> +#include <asm/jmr3927/jmr3927.h> + +#define TIMEOUT 0xffffff +#define SLOW_DOWN + +static const char digits[16] = "0123456789abcdef"; + +#ifdef SLOW_DOWN +#define slow_down() { int k; for (k=0; k<10000; k++); } +#else +#define slow_down() +#endif + +static int remoteDebugInitialized = 0; + +int putDebugChar(unsigned char c) +{ + int i = 0; + + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(38400); + } + + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (!(tx3927_sioptr(0)->cisr & TXx927_SICISR_TXALS)); + tx3927_sioptr(0)->tfifo = c; + + return 1; +} + +unsigned char getDebugChar(void) +{ + int i = 0; + int dicr; + char c; + + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(38400); + } + + /* diable RX int. */ + dicr = tx3927_sioptr(0)->dicr; + tx3927_sioptr(0)->dicr = 0; + + do { + slow_down(); + i++; + if (i>TIMEOUT) { + break; + } + } while (tx3927_sioptr(0)->disr & TXx927_SIDISR_UVALID) + ; + c = tx3927_sioptr(0)->rfifo; + + /* clear RX int. status */ + tx3927_sioptr(0)->disr &= ~TXx927_SIDISR_RDIS; + /* enable RX int. */ + tx3927_sioptr(0)->dicr = dicr; + + return c; +} + +void debugInit(int baud) +{ + /* + volatile unsigned long lcr; + volatile unsigned long dicr; + volatile unsigned long disr; + volatile unsigned long cisr; + volatile unsigned long fcr; + volatile unsigned long flcr; + volatile unsigned long bgr; + volatile unsigned long tfifo; + volatile unsigned long rfifo; + */ + + tx3927_sioptr(0)->lcr = 0x020; + tx3927_sioptr(0)->dicr = 0; + tx3927_sioptr(0)->disr = 0x4100; + tx3927_sioptr(0)->cisr = 0x014; + tx3927_sioptr(0)->fcr = 0; + tx3927_sioptr(0)->flcr = 0x02; + tx3927_sioptr(0)->bgr = ((JMR3927_BASE_BAUD + baud / 2) / baud) | + TXx927_SIBGR_BCLK_T0; +#if 0 + /* + * Reset the UART. + */ + tx3927_sioptr(0)->fcr = TXx927_SIFCR_SWRST; + while (tx3927_sioptr(0)->fcr & TXx927_SIFCR_SWRST) + ; + + /* + * and set the speed of the serial port + * (currently hardwired to 9600 8N1 + */ + + tx3927_sioptr(0)->lcr = TXx927_SILCR_UMODE_8BIT | + TXx927_SILCR_USBL_1BIT | + TXx927_SILCR_SCS_IMCLK_BG; + tx3927_sioptr(0)->bgr = + ((JMR3927_BASE_BAUD + baud / 2) / baud) | + TXx927_SIBGR_BCLK_T0; + + /* HW RTS/CTS control */ + if (ser->flags & ASYNC_HAVE_CTS_LINE) + tx3927_sioptr(0)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES | + TXx927_SIFLCR_RTSTL_MAX /* 15 */; + /* Enable RX/TX */ + tx3927_sioptr(0)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE); +#endif +} diff -Nru a/arch/mips/jmr3927/rbhma3100/rtc.c b/arch/mips/jmr3927/rbhma3100/rtc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/rtc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,56 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * RTC routines for Dallas chip. + * + * 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) 200-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <asm/mc146818rtc.h> /* bad name... */ +#include <asm/jmr3927/jmr3927.h> + +static unsigned char jmr3927_rtc_read_data(unsigned long addr) +{ + return jmr3927_nvram_in(addr); +} + +static void jmr3927_rtc_write_data(unsigned char data, unsigned long addr) +{ + jmr3927_nvram_out(data, addr); +} + +static int jmr3927_rtc_bcd_mode(void) +{ + return 1; +} + +struct rtc_ops jmr3927_rtc_ops = { + &jmr3927_rtc_read_data, + &jmr3927_rtc_write_data, + &jmr3927_rtc_bcd_mode +}; diff -Nru a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/jmr3927/rbhma3100/setup.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,528 @@ +/*********************************************************************** + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Based on arch/mips/ddb5xxx/ddb5477/setup.c + * + * Setup file for JMR3927. + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/sched.h> +#include <linux/pci.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/param.h> /* for HZ */ +#include <linux/delay.h> + +#include <asm/addrspace.h> +#include <asm/time.h> +#include <asm/bcache.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/gdb-stub.h> +#include <asm/jmr3927/jmr3927.h> +#include <asm/mipsregs.h> +#include <asm/traps.h> + +/* Tick Timer divider */ +#define JMR3927_TIMER_CCD 0 /* 1/2 */ +#define JMR3927_TIMER_CLK (JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD)) + +unsigned char led_state = 0xf; + +struct { + struct resource ram0; + struct resource ram1; + struct resource pcimem; + struct resource iob; + struct resource ioc; + struct resource pciio; + struct resource jmy1394; + struct resource rom1; + struct resource rom0; + struct resource sio0; + struct resource sio1; +} jmr3927_resources = { + { "RAM0", 0, 0x01FFFFFF, IORESOURCE_MEM }, + { "RAM1", 0x02000000, 0x03FFFFFF, IORESOURCE_MEM }, + { "PCIMEM", 0x08000000, 0x07FFFFFF, IORESOURCE_MEM }, + { "IOB", 0x10000000, 0x13FFFFFF }, + { "IOC", 0x14000000, 0x14FFFFFF }, + { "PCIIO", 0x15000000, 0x15FFFFFF }, + { "JMY1394", 0x1D000000, 0x1D3FFFFF }, + { "ROM1", 0x1E000000, 0x1E3FFFFF }, + { "ROM0", 0x1FC00000, 0x1FFFFFFF }, + { "SIO0", 0xFFFEF300, 0xFFFEF3FF }, + { "SIO1", 0xFFFEF400, 0xFFFEF4FF }, +}; + +/* don't enable - see errata */ +int jmr3927_ccfg_toeon = 0; + +static inline void do_reset(void) +{ +#ifdef CONFIG_TC35815 + extern void tc35815_killall(void); + tc35815_killall(); +#endif +#if 1 /* Resetting PCI bus */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, JMR3927_IOC_RESET_ADDR); + (void)jmr3927_ioc_reg_in(JMR3927_IOC_RESET_ADDR); /* flush WB */ + mdelay(1); + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); +#endif + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_CPU, JMR3927_IOC_RESET_ADDR); +} + +static void jmr3927_machine_restart(char *command) +{ + cli(); + puts("Rebooting..."); + do_reset(); +} + +static void jmr3927_machine_halt(void) +{ + puts("JMR-TX3927 halted.\n"); + while (1); +} + +static void jmr3927_machine_power_off(void) +{ + puts("JMR-TX3927 halted. Please turn off the power.\n"); + while (1); +} + +#define USE_RTC_DS1742 +#ifdef USE_RTC_DS1742 +extern void rtc_ds1742_init(unsigned long base); +#endif +static void __init jmr3927_time_init(void) +{ +#ifdef USE_RTC_DS1742 + if (jmr3927_have_nvram()) { + rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); + } +#endif +} + +unsigned long jmr3927_do_gettimeoffset(void); +extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + +static void __init jmr3927_timer_setup(struct irqaction *irq) +{ + do_gettimeoffset = jmr3927_do_gettimeoffset; + + jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; + jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; + jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; + jmr3927_tmrptr->tcr = + TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL; + + setup_irq(JMR3927_IRQ_TICK, irq); +} + +#define USECS_PER_JIFFY (1000000/HZ) + +unsigned long jmr3927_do_gettimeoffset(void) +{ + unsigned long count; + unsigned long res = 0; + + /* MUST read TRR before TISR. */ + count = jmr3927_tmrptr->trr; + + if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { + /* timer interrupt is pending. use Max value. */ + res = USECS_PER_JIFFY - 1; + } else { + /* convert to usec */ + /* res = count / (JMR3927_TIMER_CLK / 1000000); */ + res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + } + + return res; +} + + +#if defined(CONFIG_BLK_DEV_INITRD) +extern unsigned long __rd_start, __rd_end, initrd_start, initrd_end; +#endif + +//#undef DO_WRITE_THROUGH +#define DO_WRITE_THROUGH +#define DO_ENABLE_CACHE + +extern char * __init prom_getcmdline(void); +static void jmr3927_board_init(void); +extern void jmr3927_irq_setup(void); +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void __init jmr3927_setup(void) +{ + extern int panic_timeout; + char *argptr; + + irq_setup = jmr3927_irq_setup; + set_io_port_base(JMR3927_PORT_BASE + JMR3927_PCIIO); + + board_time_init = jmr3927_time_init; + board_timer_setup = jmr3927_timer_setup; + + _machine_restart = jmr3927_machine_restart; + _machine_halt = jmr3927_machine_halt; + _machine_power_off = jmr3927_machine_power_off; + + /* + * IO/MEM resources. + */ + ioport_resource.start = pci_io_resource.start; + ioport_resource.end = pci_io_resource.end; + iomem_resource.start = pci_mem_resource.start; + iomem_resource.end = pci_mem_resource.end; + + /* Reboot on panic */ + panic_timeout = 180; + + { + unsigned int conf; + conf = read_c0_conf(); + } + +#if 1 + /* cache setup */ + { + unsigned int conf; +#ifdef DO_ENABLE_CACHE + int mips_ic_disable = 0, mips_dc_disable = 0; +#else + int mips_ic_disable = 1, mips_dc_disable = 1; +#endif +#ifdef DO_WRITE_THROUGH + int mips_config_cwfon = 0; + int mips_config_wbon = 0; +#else + int mips_config_cwfon = 1; + int mips_config_wbon = 1; +#endif + + conf = read_c0_conf(); + conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE | TX39_CONF_WBON | TX39_CONF_CWFON); + conf |= mips_ic_disable ? 0 : TX39_CONF_ICE; + conf |= mips_dc_disable ? 0 : TX39_CONF_DCE; + conf |= mips_config_wbon ? TX39_CONF_WBON : 0; + conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0; + + write_c0_conf(conf); + write_c0_cache(0); + } +#endif + + /* initialize board */ + jmr3927_board_init(); + + argptr = prom_getcmdline(); + + if ((argptr = strstr(argptr, "toeon")) != NULL) { + jmr3927_ccfg_toeon = 1; + } + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "ip=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " ip=bootp"); + } + +#ifdef CONFIG_TXX927_SERIAL_CONSOLE + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "console=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS1,115200"); + } +#endif +} + + +static void tx3927_setup(void); + +#ifdef CONFIG_PCI +unsigned long mips_pci_io_base; +unsigned long mips_pci_io_size; +unsigned long mips_pci_mem_base; +unsigned long mips_pci_mem_size; +/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ +unsigned long mips_pci_io_pciaddr = 0; +#endif + +extern struct rtc_ops *rtc_ops; +extern struct rtc_ops jmr3927_rtc_ops; + +static void __init jmr3927_board_init(void) +{ + char *argptr; + +#ifdef CONFIG_PCI + mips_pci_io_base = JMR3927_PCIIO; + mips_pci_io_size = JMR3927_PCIIO_SIZE; + mips_pci_mem_base = JMR3927_PCIMEM; + mips_pci_mem_size = JMR3927_PCIMEM_SIZE; +#endif + + tx3927_setup(); + +#ifdef CONFIG_VT + conswitchp = &dummy_con; +#endif + + if (jmr3927_have_isac()) { + +#ifdef CONFIG_FB_E1355 + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "video=")) == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " video=e1355fb:crt16h"); + } +#endif + +#ifdef CONFIG_BLK_DEV_IDE + /* overrides PCI-IDE */ +#endif + } +#ifdef USE_RTC_DS1742 + if (jmr3927_have_nvram()) { + rtc_ops = &jmr3927_rtc_ops; + } +#endif + + /* SIO0 DTR on */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_DTR_ADDR); + + jmr3927_led_set(0); + + + if (jmr3927_have_isac()) + jmr3927_io_led_set(0); + printk("JMR-TX3927 (Rev %d) --- IOC(Rev %d) DIPSW:%d,%d,%d,%d\n", + jmr3927_ioc_reg_in(JMR3927_IOC_BREV_ADDR) & JMR3927_REV_MASK, + jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_REV_MASK, + jmr3927_dipsw1(), jmr3927_dipsw2(), + jmr3927_dipsw3(), jmr3927_dipsw4()); + if (jmr3927_have_isac()) + printk("JMI-3927IO2 --- ISAC(Rev %d) DIPSW:%01x\n", + jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_REV_MASK, + jmr3927_io_dipsw()); +} + +static void __init tx3927_setup(void) +{ + int i; + + /* SDRAMC are configured by PROM */ + + /* ROMC */ + tx3927_romcptr->cr[1] = JMR3927_ROMCE1 | 0x00030048; + tx3927_romcptr->cr[2] = JMR3927_ROMCE2 | 0x000064c8; + tx3927_romcptr->cr[3] = JMR3927_ROMCE3 | 0x0003f698; + tx3927_romcptr->cr[5] = JMR3927_ROMCE5 | 0x0000f218; + + /* CCFG */ + /* enable Timeout BusError */ + if (jmr3927_ccfg_toeon) + tx3927_ccfgptr->ccfg |= TX3927_CCFG_TOE; + + /* clear BusErrorOnWrite flag */ + tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_BEOW; + /* Disable PCI snoop */ + tx3927_ccfgptr->ccfg &= ~TX3927_CCFG_PSNP; + +#ifdef DO_WRITE_THROUGH + /* Enable PCI SNOOP - with write through only */ + tx3927_ccfgptr->ccfg |= TX3927_CCFG_PSNP; +#endif + + /* Pin selection */ + tx3927_ccfgptr->pcfg &= ~TX3927_PCFG_SELALL; + tx3927_ccfgptr->pcfg |= + TX3927_PCFG_SELSIOC(0) | TX3927_PCFG_SELSIO_ALL | + (TX3927_PCFG_SELDMA_ALL & ~TX3927_PCFG_SELDMA(1)); + + printk("TX3927 -- CRIR:%08lx CCFG:%08lx PCFG:%08lx\n", + tx3927_ccfgptr->crir, + tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg); + + /* IRC */ + /* disable interrupt control */ + tx3927_ircptr->cer = 0; + /* mask all IRC interrupts */ + tx3927_ircptr->imr = 0; + for (i = 0; i < TX3927_NUM_IR / 2; i++) { + tx3927_ircptr->ilr[i] = 0; + } + /* setup IRC interrupt mode (Low Active) */ + for (i = 0; i < TX3927_NUM_IR / 8; i++) { + tx3927_ircptr->cr[i] = 0; + } + + /* TMR */ + /* disable all timers */ + for (i = 0; i < TX3927_NR_TMR; i++) { + tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE; + tx3927_tmrptr(i)->tisr = 0; + tx3927_tmrptr(i)->cpra = 0xffffffff; + tx3927_tmrptr(i)->itmr = 0; + tx3927_tmrptr(i)->ccdr = 0; + tx3927_tmrptr(i)->pgmr = 0; + } + + /* DMA */ + tx3927_dmaptr->mcr = 0; + for (i = 0; i < sizeof(tx3927_dmaptr->ch) / sizeof(tx3927_dmaptr->ch[0]); i++) { + /* reset channel */ + tx3927_dmaptr->ch[i].ccr = TX3927_DMA_CCR_CHRST; + tx3927_dmaptr->ch[i].ccr = 0; + } + /* enable DMA */ +#ifdef __BIG_ENDIAN + tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN; +#else + tx3927_dmaptr->mcr = TX3927_DMA_MCR_MSTEN | TX3927_DMA_MCR_LE; +#endif + +#ifdef CONFIG_PCI + /* PCIC */ + printk("TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:", + tx3927_pcicptr->did, tx3927_pcicptr->vid, + tx3927_pcicptr->rid); + if (!(tx3927_ccfgptr->ccfg & TX3927_CCFG_PCIXARB)) { + printk("External\n"); + /* XXX */ + } else { + printk("Internal\n"); + + /* Reset PCI Bus */ + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(JMR3927_IOC_RESET_PCI, + JMR3927_IOC_RESET_ADDR); + udelay(100); + jmr3927_ioc_reg_out(0, JMR3927_IOC_RESET_ADDR); + + + /* Disable External PCI Config. Access */ + tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD; +#ifdef __BIG_ENDIAN + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE | + TX3927_PCIC_LBC_TIBSE | + TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE; +#endif + /* LB->PCI mappings */ + tx3927_pcicptr->iomas = ~(mips_pci_io_size - 1); + tx3927_pcicptr->ilbioma = mips_pci_io_base; + tx3927_pcicptr->ipbioma = mips_pci_io_pciaddr; + tx3927_pcicptr->mmas = ~(mips_pci_mem_size - 1); + tx3927_pcicptr->ilbmma = mips_pci_mem_base; + tx3927_pcicptr->ipbmma = mips_pci_mem_base; + /* PCI->LB mappings */ + tx3927_pcicptr->iobas = 0xffffffff; + tx3927_pcicptr->ioba = 0; + tx3927_pcicptr->tlbioma = 0; + tx3927_pcicptr->mbas = ~(mips_pci_mem_size - 1); + tx3927_pcicptr->mba = 0; + tx3927_pcicptr->tlbmma = 0; +#ifndef JMR3927_INIT_INDIRECT_PCI + /* Enable Direct mapping Address Space Decoder */ + tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE; +#endif + + /* Clear All Local Bus Status */ + tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL; + /* Enable All Local Bus Interrupts */ + tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL; + /* Clear All PCI Status Error */ + tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL; + /* Enable All PCI Status Error Interrupts */ + tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL; + + /* PCIC Int => IRC IRQ10 */ + tx3927_pcicptr->il = TX3927_IR_PCI; +#if 1 + /* Target Control (per errata) */ + tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E; +#endif + + /* Enable Bus Arbiter */ +#if 0 + tx3927_pcicptr->req_trace = 0x73737373; +#endif + tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN; + + tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | +#if 1 + PCI_COMMAND_IO | +#endif + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + } +#endif /* CONFIG_PCI */ + + /* PIO */ + /* PIO[15:12] connected to LEDs */ + tx3927_pioptr->dir = 0x0000f000; + tx3927_pioptr->maskcpu = 0; + tx3927_pioptr->maskext = 0; + { + unsigned int conf; + + conf = read_c0_conf(); + if (!(conf & TX39_CONF_ICE)) + printk("TX3927 I-Cache disabled.\n"); + if (!(conf & TX39_CONF_DCE)) + printk("TX3927 D-Cache disabled.\n"); + else if (!(conf & TX39_CONF_WBON)) + printk("TX3927 D-Cache WriteThrough.\n"); + else if (!(conf & TX39_CONF_CWFON)) + printk("TX3927 D-Cache WriteBack.\n"); + else + printk("TX3927 D-Cache WriteBack (CWF) .\n"); + } +} diff -Nru a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile --- a/arch/mips/kernel/Makefile Fri Jun 27 14:19:55 2003 +++ b/arch/mips/kernel/Makefile Fri Jun 27 14:19:55 2003 @@ -2,45 +2,45 @@ # Makefile for the Linux/MIPS kernel. # -# EXTRA_AFLAGS = -mips3 -mcpu=r4000 # not used? +extra-y := head.o init_task.o + +obj-y += branch.o cpu-probe.o process.o signal.o entry.o traps.o \ + ptrace.o irq.o reset.o semaphore.o setup.o syscall.o \ + sysmips.o ipc.o scall_o32.o time.o unaligned.o -extra-y := head.o init_task.o -obj-y += branch.o process.o signal.o entry.o \ - traps.o ptrace.o vm86.o ioport.o reset.o \ - semaphore.o setup.o syscall.o sysmips.o \ - ipc.o scall_o32.o unaligned.o obj-$(CONFIG_MODULES) += mips_ksyms.o -ifdef CONFIG_CPU_R3000 -obj-y += r2300_misc.o r2300_fpu.o r2300_switch.o -else -obj-y += r4k_misc.o r4k_switch.o -ifdef CONFIG_CPU_R6000 -obj-y += r6000_fpu.o -else -obj-y += r4k_fpu.o -endif -endif +obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o +obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o +obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_NEVADA) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R10000) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o obj-$(CONFIG_SMP) += smp.o -# Old style irq support, going to die in 2.5. -obj-$(CONFIG_NEW_IRQ) += irq.o -obj-$(CONFIG_ROTTEN_IRQ) += old-irq.o obj-$(CONFIG_I8259) += i8259.o - -# transition from old time.c to new time.c -# some boards uses old-time.c, some use time.c, and some use their own ones -obj-$(CONFIG_OLD_TIME_C) += old-time.o -obj-$(CONFIG_NEW_TIME_C) += time.o +obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_BINFMT_IRIX) += irixelf.o irixioctl.o irixsig.o sysirix.o \ irixinv.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb-low.o gdb-stub.o -obj-$(CONFIG_PCI) += pci-dma.o +obj-$(CONFIG_KGDB) += gdb-low.o gdb-stub.o obj-$(CONFIG_PROC_FS) += proc.o -ifdef CONFIG_PCI -obj-$(CONFIG_NEW_PCI) += pci.o -obj-$(CONFIG_PCI_AUTO) += pci_auto.o +ifndef CONFIG_MAPPED_PCI_IO +obj-y += pci-dma.o endif + +obj-$(CONFIG_MODULES) += module.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c --- a/arch/mips/kernel/branch.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/kernel/branch.c Fri Jun 27 14:19:56 2003 @@ -16,7 +16,6 @@ #include <asm/inst.h> #include <asm/ptrace.h> #include <asm/uaccess.h> -#include <asm/bootinfo.h> #include <asm/processor.h> /* @@ -164,10 +163,10 @@ * And now the FPA/cp1 branch instructions. */ case cop1_op: - if(!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) fcr31 = current->thread.fpu.soft.sr; else - asm ("cfc1\t%0,$31":"=r" (fcr31)); + asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -Nru a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/kernel/cpu-probe.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,509 @@ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/stddef.h> +#include <asm/bugs.h> +#include <asm/cpu.h> +#include <asm/fpu.h> +#include <asm/mipsregs.h> + +/* + * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, + * the implementation of the "wait" feature differs between CPU families. This + * points to the function that implements CPU specific wait. + * The wait instruction stops the pipeline and reduces the power consumption of + * the CPU very much. + */ +void (*cpu_wait)(void) = NULL; + +static void r3081_wait(void) +{ + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); +} + +static void r39xx_wait(void) +{ + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); +} + +static void r4k_wait(void) +{ + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void au1k_wait(void) +{ +#ifdef CONFIG_PM + /* using the wait instruction makes CP0 counter unusable */ + __asm__(".set\tmips3\n\t" + "wait\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tmips0"); +#else + __asm__("nop\n\t" + "nop"); +#endif +} + +static inline void check_wait(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("Checking for 'wait' instruction... "); + switch (c->cputype) { + case CPU_R3081: + case CPU_R3081E: + cpu_wait = r3081_wait; + printk(" available.\n"); + break; + case CPU_TX3927: + cpu_wait = r39xx_wait; + printk(" available.\n"); + break; + case CPU_R4200: +/* case CPU_R4300: */ + case CPU_R4600: + case CPU_R4640: + case CPU_R4650: + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + case CPU_RM7000: + case CPU_TX49XX: + case CPU_4KC: + case CPU_4KEC: + case CPU_4KSC: + case CPU_5KC: +/* case CPU_20KC:*/ + cpu_wait = r4k_wait; + printk(" available.\n"); + break; + case CPU_AU1000: + case CPU_AU1100: + case CPU_AU1500: + cpu_wait = au1k_wait; + printk(" available.\n"); + break; + default: + printk(" unavailable.\n"); + break; + } +} + +void __init check_bugs(void) +{ + check_wait(); +} + +/* + * Probe whether cpu has config register by trying to play with + * alternate cache bit and see whether it matters. + * It's used by cpu_probe to distinguish between R3000A and R3081. + */ +static inline int cpu_has_confreg(void) +{ +#ifdef CONFIG_CPU_R3000 + extern unsigned long r3k_cache_size(unsigned long); + unsigned long size1, size2; + unsigned long cfg = read_c0_conf(); + + size1 = r3k_cache_size(ST0_ISC); + write_c0_conf(cfg ^ R30XX_CONF_AC); + size2 = r3k_cache_size(ST0_ISC); + write_c0_conf(cfg); + return size1 != size2; +#else + return 0; +#endif +} + +/* + * Get the FPU Implementation/Revision. + */ +static inline unsigned long cpu_get_fpu_id(void) +{ + unsigned long tmp, fpu_id; + + tmp = read_c0_status(); + __enable_fpu(); + fpu_id = read_32bit_cp1_register(CP1_REVISION); + write_c0_status(tmp); + return fpu_id; +} + +/* + * Check the CPU has an FPU the official way. + */ +static inline int __cpu_has_fpu(void) +{ + return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); +} + +#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ + | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) + +__init void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long config0 = read_c0_config(); + unsigned long config1; + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + + if (config0 & (1 << 31)) { + /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); + if (config1 & (1 << 3)) + c->options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + c->options |= MIPS_CPU_MIPS16; + if (config1 & (1 << 1)) + c->options |= MIPS_CPU_EJTAG; + if (config1 & 1) { + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; + } + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { + case PRID_COMP_LEGACY: + switch (c->processor_id & 0xff00) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_IMP_R3000: + if ((c->processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else + c->cputype = CPU_R3000A; + else + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_IMP_R4000: + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_VR41XX: + switch (c->processor_id & 0xf0) { +#ifndef CONFIG_VR4181 + case PRID_REV_VR4111: + c->cputype = CPU_VR4111; + break; +#else + case PRID_REV_VR4181: + c->cputype = CPU_VR4181; + break; +#endif + case PRID_REV_VR4121: + c->cputype = CPU_VR4121; + break; + case PRID_REV_VR4122: + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; + else + c->cputype = CPU_VR4181A; + break; + case PRID_REV_VR4131: + c->cputype = CPU_VR4131; + break; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + c->cputype = CPU_VR41XX; + break; + } + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; + break; + case PRID_IMP_R4300: + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R4600: + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #if 0 + case PRID_IMP_R4650: + /* + * This processor doesn't have an MMU, so it's not + * "real easy" to run Linux on it. It is left purely + * for documentation. Commented out because it shares + * it's c0_prid id number with the TX3900. + */ + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #endif + case PRID_IMP_TX39: + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; + + if ((c->processor_id & 0xf0) == + (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + c->tlbsize = 64; + } else { + switch (c->processor_id & 0xff) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + c->tlbsize = 32; + break; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + } + break; + case PRID_IMP_R4700: + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_TX49: + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5000: + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5432: + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5500: + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_NEVADA: + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R6000: + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R6000A: + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_RM7000: + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Undocumented RM7000: Bit 29 in the info register of + * the RM7000 v2.0 indicates if the TLB has 48 or 64 + * entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_R8000: + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ + break; + case PRID_IMP_R10000: + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + case PRID_IMP_R12000: + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + case PRID_COMP_MIPS: + switch (c->processor_id & 0xff00) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KEC: + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KSC: + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_5KC: + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_20KC: + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + case PRID_COMP_ALCHEMY: + switch (c->processor_id & 0xff00) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: + switch ((c->processor_id >> 24) & 0xff) { + case 0: + c->cputype = CPU_AU1000; + break; + case 1: + c->cputype = CPU_AU1500; + break; + case 2: + c->cputype = CPU_AU1100; + break; + default: + panic("Unknown Au Core!"); + break; + } + c->isa_level = MIPS_CPU_ISA_M32; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + case PRID_COMP_SIBYTE: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + /* FPU in pass1 is known to have issues. */ + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; +#endif + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + + case PRID_COMP_SANDCRAFT: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + default: + c->cputype = CPU_UNKNOWN; + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + if (c->options & MIPS_CPU_FPU) + c->fpu_id = cpu_get_fpu_id(); +} + +__init void cpu_report(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("CPU revision is: %08x\n", c->processor_id); + if (c->options & MIPS_CPU_FPU) + printk("FPU revision is: %08x\n", c->fpu_id); +} diff -Nru a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S --- a/arch/mips/kernel/entry.S Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/entry.S Fri Jun 27 14:19:54 2003 @@ -1,5 +1,4 @@ /* -/* * 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. @@ -9,79 +8,155 @@ * Copyright (C) 2001 MIPS Technologies, Inc. */ #include <linux/config.h> +#include <linux/init.h> #include <linux/sys.h> #include <asm/addrspace.h> #include <asm/asm.h> -#include <asm/current.h> +#include <asm/cacheops.h> #include <asm/errno.h> #include <asm/mipsregs.h> #include <asm/page.h> -#include <asm/pgtable.h> +#include <asm/pgtable-bits.h> +#include <asm/regdef.h> #include <asm/stackframe.h> #include <asm/processor.h> -#include <asm/regdef.h> #include <asm/fpregdef.h> #include <asm/unistd.h> #include <asm/isadep.h> +#include <asm/thread_info.h> -/* This duplicates the definition from <linux/sched.h> */ -#define PT_TRACESYS 0x00000002 /* tracing system calls */ +#ifdef CONFIG_PREEMPT + .macro preempt_stop + cli + .endm + .macro init_ret_intr temp + mfc0 t0, CP0_STATUS # cli + ori t0, t0, 1 + xori t0, t0, 1 + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + lw \temp, TI_PRE_COUNT($28) + subu \temp, \temp, 1 + sw \temp, TI_PRE_COUNT($28) + .endm +#else + .macro preempt_stop + .endm + + .macro init_ret_intr + .endm + +#define resume_kernel restore_all +#endif .text - .align 4 + .align 5 .set push .set reorder -EXPORT(ret_from_fork) - move a0, v0 # prev - jal schedule_tail -#error lw t0, TASK_PTRACE($28) # syscall tracing enabled? - andi t0, PT_TRACESYS - bnez t0, tracesys_exit - j ret_from_sys_call - -tracesys_exit: jal syscall_trace - b ret_from_sys_call - -EXPORT(ret_from_irq) -EXPORT(ret_from_exception) +FEXPORT(ret_from_irq) +FEXPORT(ret_from_exception) lw t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER - bnez t0, ret_from_sys_call + beqz t0, resume_kernel + +FEXPORT(resume_userspace) + mfc0 t0, CP0_STATUS # make sure we dont miss an + ori t0, t0, 1 # interrupt setting need_resched + xori t0, t0, 1 # between sampling and return + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) + andi a2, _TIF_WORK_MASK # current->work (ignoring + # syscall_trace) + bnez a2, work_pending j restore_all -reschedule: jal schedule +#ifdef CONFIG_PREEMPT +ENTRY(resume_kernel) + lw t0, TI_PRE_COUNT($28) + bnez t0, restore_all + LONG_L t0, TI_FLAGS($28) + andi t1, t0, _TIF_NEED_RESCHED + beqz restore_all +#ifdef CONFIG_SMP + lw t0, TI_CPU($28) + la t1, irq_stat + sll t0, 5 # *sizeof(irq_cpustat_t) + addu t0, t1 + lw t1, local_bh_count(t0) + addl t0, local_irq_count(t0) +#else + lw t1, irq_stat+local_bh_count + addl t0, irq_stat+local_irq_count +#endif + addu t0, t1 + bnez t0, restore_all + lw t0, TI_PRE_COUNT($28) + addiu t0, 1 + sw t0, TI_PRE_COUNT($28) + sti + movl t0, TI_TASK($28) # ti->task + sw zero, TASK_STATE(t0) # current->state = TASK_RUNNING + jal schedule + j ret_from_intr +#endif -EXPORT(ret_from_sys_call) - .type ret_from_irq,@function +FEXPORT(ret_from_fork) + jal schedule_tail - mfc0 t0, CP0_STATUS # need_resched and signals atomic test - ori t0, t0, 1 - xori t0, t0, 1 +FEXPORT(syscall_exit) + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return mtc0 t0, CP0_STATUS - nop; nop; nop + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) # current->work + bnez a2, syscall_exit_work -#error lw v0, TASK_NEED_RESCHED($28) -#error lw v1, TASK_SIGPENDING($28) - bnez v0, reschedule - bnez v1, signal_return -restore_all: .set noat +FEXPORT(restore_all) + .set noat RESTORE_ALL_AND_RET .set at -/* Put this behind restore_all for the sake of the branch prediction. */ -signal_return: - .type signal_return, @function - - mfc0 t0, CP0_STATUS - ori t0, t0, 1 +FEXPORT(work_pending) + andi t0, a2, _TIF_NEED_RESCHED + bnez t0, work_notifysig +work_resched: + jal schedule + + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP - move a0, zero - move a1, sp -#error jal do_signal - b restore_all + LONG_L a2, TI_FLAGS($28) + andi a2, _TIF_WORK_MASK # is there any work to be done + # other than syscall tracing? + beqz a2, restore_all + andi t0, a2, _TIF_NEED_RESCHED + bnez t0, work_resched + +work_notifysig: # deal with pending signals and + # notify-resume requests + move a0, sp + li a1, 0 + jal do_notify_resume # a2 already loaded + j restore_all + +FEXPORT(syscall_exit_work) + LONG_L t0, TI_FLAGS($28) + bgez t0, work_pending # trace bit is set + mfc0 t0, CP0_STATUS # could let do_syscall_trace() + ori t0, t0, 1 # call schedule() instead + mtc0 t0, CP0_STATUS + jal do_syscall_trace + b resume_userspace /* * Common spurious interrupt handler. @@ -93,25 +168,105 @@ * Someone tried to fool us by sending an interrupt but we * couldn't find a cause for it. */ - lui t1,%hi(spurious_count) - .set reorder - lw t0,%lo(spurious_count)(t1) - .set noreorder + lui t1,%hi(irq_err_count) + lw t0,%lo(irq_err_count)(t1) addiu t0,1 - sw t0,%lo(spurious_count)(t1) + sw t0,%lo(irq_err_count)(t1) j ret_from_irq END(spurious_interrupt) + __INIT + + .set reorder + + NESTED(except_vec1_generic, 0, sp) + PANIC("Exception vector 1 called") + END(except_vec1_generic) + + /* + * General exception vector. Used for all CPUs except R4000 + * and R4400 SC and MC versions. + */ + NESTED(except_vec3_generic, 0, sp) +#if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX +#endif + mfc0 k1, CP0_CAUSE + la k0, exception_handlers + andi k1, k1, 0x7c + addu k0, k0, k1 + lw k0, (k0) + jr k0 + END(except_vec3_generic) + .set at + + /* General exception vector R4000 version. */ + NESTED(except_vec3_r4000, 0, sp) + .set push + .set mips3 + .set noat + mfc0 k1, CP0_CAUSE + li k0, 31<<2 + andi k1, k1, 0x7c + .set noreorder + beq k1, k0, handle_vced + li k0, 14<<2 + beq k1, k0, handle_vcei + lui k0, %hi(exception_handlers) + addiu k0, %lo(exception_handlers) + .set reorder + addu k0, k0, k1 + lw k0, (k0) + jr k0 + + /* + * Big shit, we now may have two dirty primary cache lines for + * the same physical address. We can savely invalidate the + * line pointed to by c0_badvaddr because after return from + * this exception handler the load / store will be re-executed. + */ +handle_vced: + mfc0 k0, CP0_BADVADDR + li k1, -4 + and k0, k1 + mtc0 zero, CP0_TAGLO + cache Index_Store_Tag_D,(k0) + cache Hit_Writeback_Inv_SD,(k0) +#ifdef CONFIG_PROC_FS + lui k0, %hi(vced_count) + lw k1, %lo(vced_count)(k0) + addiu k1, 1 + sw k1, %lo(vced_count)(k0) +#endif + eret + +handle_vcei: + mfc0 k0, CP0_BADVADDR + cache Hit_Writeback_Inv_SD, (k0) # also cleans pi +#ifdef CONFIG_PROC_FS + lui k0, %hi(vcei_count) + lw k1, %lo(vcei_count)(k0) + addiu k1, 1 + sw k1, %lo(vcei_count)(k0) +#endif + eret + .set pop + END(except_vec3_r4000) + + __FINIT + /* * Build a default exception handler for the exceptions that don't need * special handlers. If you didn't know yet - I *like* playing games with * the C preprocessor ... */ #define __BUILD_clear_none(exception) -#define __BUILD_clear_sti(exception) \ +#define __BUILD_clear_sti(exception) \ STI -#define __BUILD_clear_cli(exception) \ +#define __BUILD_clear_cli(exception) \ CLI +#define __BUILD_clear_kmode(exception) \ + KMODE #define __BUILD_clear_fpe(exception) \ cfc1 a1,fcr31; \ li a2,~(0x3f<<12); \ @@ -148,6 +303,7 @@ NESTED(handle_##exception, PT_SIZE, sp); \ .set noat; \ SAVE_ALL; \ + FEXPORT(handle_##exception##_int); \ __BUILD_clear_##clear(exception); \ .set at; \ __BUILD_##verbose(exception); \ @@ -159,16 +315,18 @@ BUILD_HANDLER(adel,ade,ade,silent) /* #4 */ BUILD_HANDLER(ades,ade,ade,silent) /* #5 */ - BUILD_HANDLER(ibe,ibe,cli,verbose) /* #6 */ - BUILD_HANDLER(dbe,dbe,cli,silent) /* #7 */ - BUILD_HANDLER(bp,bp,sti,silent) /* #9 */ - BUILD_HANDLER(ri,ri,sti,silent) /* #10 */ - BUILD_HANDLER(cpu,cpu,sti,silent) /* #11 */ - BUILD_HANDLER(ov,ov,sti,silent) /* #12 */ - BUILD_HANDLER(tr,tr,sti,silent) /* #13 */ + BUILD_HANDLER(ibe,be,cli,silent) /* #6 */ + BUILD_HANDLER(dbe,be,cli,silent) /* #7 */ + BUILD_HANDLER(bp,bp,kmode,silent) /* #9 */ + BUILD_HANDLER(ri,ri,kmode,silent) /* #10 */ + BUILD_HANDLER(cpu,cpu,kmode,silent) /* #11 */ + BUILD_HANDLER(ov,ov,kmode,silent) /* #12 */ + BUILD_HANDLER(tr,tr,kmode,silent) /* #13 */ BUILD_HANDLER(fpe,fpe,fpe,silent) /* #15 */ - BUILD_HANDLER(watch,watch,sti,verbose) /* #23 */ - BUILD_HANDLER(reserved,reserved,sti,verbose) /* others */ + BUILD_HANDLER(mdmx,mdmx,sti,silent) /* #22 */ + BUILD_HANDLER(watch,watch,sti,silent) /* #23 */ + BUILD_HANDLER(mcheck,mcheck,cli,silent) /* #24 */ + BUILD_HANDLER(reserved,reserved,kmode,silent) /* others */ .set pop diff -Nru a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S --- a/arch/mips/kernel/gdb-low.S Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/gdb-low.S Fri Jun 27 14:19:54 2003 @@ -14,6 +14,16 @@ #include <asm/gdb-stub.h> /* + * [jsun] We reserves about 2x GDB_FR_SIZE in stack. The lower (addressed) + * part is used to store registers and passed to exception handler. + * The upper part is reserved for "call func" feature where gdb client + * saves some of the regs, setups call frame and passes args. + * + * A trace shows about 200 bytes are used to store about half of all regs. + * The rest should be big enough for frame setup and passing args. + */ + +/* * The low level trap handler */ .align 5 @@ -38,7 +48,7 @@ nop 1: move k0,sp - subu sp,k1,GDB_FR_SIZE + subu sp,k1,GDB_FR_SIZE*2 # see comment above sw k0,GDB_FR_REG29(sp) sw v0,GDB_FR_REG2(sp) @@ -97,7 +107,7 @@ sw ra,GDB_FR_REG31(sp) CLI /* disable interrupts */ - + /* * Followed by the floating point registers */ @@ -145,9 +155,9 @@ * FPU control registers */ - mfc1 v0,CP1_STATUS + cfc1 v0,CP1_STATUS sw v0,GDB_FR_FSR(sp) - mfc1 v0,CP1_REVISION + cfc1 v0,CP1_REVISION sw v0,GDB_FR_FIR(sp) /* @@ -211,7 +221,7 @@ lw v0,GDB_FR_CP0_CONTEXT(sp) mtc0 v1,CP0_INDEX mtc0 v0,CP0_CONTEXT - + /* * Next, the floating point registers @@ -304,7 +314,7 @@ lw v1,GDB_FR_REG3(sp) lw v0,GDB_FR_REG2(sp) lw $1,GDB_FR_REG1(sp) -#ifdef CONFIG_CPU_R3000 +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) lw k0, GDB_FR_EPC(sp) lw sp, GDB_FR_REG29(sp) /* Deallocate stack */ jr k0 @@ -321,11 +331,7 @@ END(trap_low) LEAF(kgdb_read_byte) - .set push - .set noreorder - .set nomacro 4: lb t0, (a0) - .set pop sb t0, (a1) li v0, 0 jr ra @@ -335,11 +341,7 @@ END(kgdb_read_byte) LEAF(kgdb_write_byte) - .set push - .set noreorder - .set nomacro 5: sb a0, (a1) - .set pop li v0, 0 jr ra .section __ex_table,"a" @@ -349,6 +351,7 @@ .type kgdbfault@function .ent kgdbfault + kgdbfault: li v0, -EFAULT jr ra .end kgdbfault diff -Nru a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c --- a/arch/mips/kernel/gdb-stub.c Fri Jun 27 14:20:05 2003 +++ b/arch/mips/kernel/gdb-stub.c Fri Jun 27 14:20:05 2003 @@ -11,8 +11,6 @@ * Send complaints, suggestions etc. to <andy@waldorf-gmbh.de> * * Copyright (C) 1995 Andreas Busse - * - * $Id: gdb-stub.c,v 1.6 1999/05/01 22:40:35 ralf Exp $ */ /* @@ -64,7 +62,7 @@ * Host: Reply: * $m0,10#2a +$00010203040506070809101112131415#42 * - * + * * ============== * MORE EXAMPLES: * ============== @@ -74,11 +72,11 @@ * going. In this scenario the host machine was a PC and the * target platform was a Galileo EVB64120A MIPS evaluation * board. - * + * * Step 1: * First download gdb-5.0.tar.gz from the internet. * and then build/install the package. - * + * * Example: * $ tar zxf gdb-5.0.tar.gz * $ cd gdb-5.0 @@ -87,40 +85,39 @@ * $ install * $ which mips-linux-elf-gdb * /usr/local/bin/mips-linux-elf-gdb - * + * * Step 2: * Configure linux for remote debugging and build it. - * + * * Example: * $ cd ~/linux * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging> * $ make dep; make vmlinux - * + * * Step 3: * Download the kernel to the remote target and start - * the kernel running. It will promptly halt and wait + * the kernel running. It will promptly halt and wait * for the host gdb session to connect. It does this - * since the "Kernel Hacking" option has defined - * CONFIG_REMOTE_DEBUG which in turn enables your calls + * since the "Kernel Hacking" option has defined + * CONFIG_KGDB which in turn enables your calls * to: * set_debug_traps(); * breakpoint(); - * + * * Step 4: * Start the gdb session on the host. - * + * * Example: * $ mips-linux-elf-gdb vmlinux * (gdb) set remotebaud 115200 * (gdb) target remote /dev/ttyS1 - * ...at this point you are connected to + * ...at this point you are connected to * the remote target and can use gdb - * in the normal fasion. Setting + * in the normal fasion. Setting * breakpoints, single stepping, * printing variables, etc. - * */ - +#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/signal.h> @@ -128,6 +125,8 @@ #include <linux/mm.h> #include <linux/console.h> #include <linux/init.h> +#include <linux/slab.h> +#include <linux/reboot.h> #include <asm/asm.h> #include <asm/mipsregs.h> @@ -176,8 +175,8 @@ /* Used to prevent crashes in memory access. Note that they'll crash anyway if we haven't set up fault handlers yet... */ -int kgdb_read_byte(unsigned *address, unsigned *dest); -int kgdb_write_byte(unsigned val, unsigned *dest); +int kgdb_read_byte(unsigned char *address, unsigned char *dest); +int kgdb_write_byte(unsigned char val, unsigned char *dest); /* * Convert ch from a hex digit to an int @@ -214,7 +213,7 @@ checksum = 0; xmitcsum = -1; count = 0; - + /* * now, read until a # or end of buffer is found */ @@ -376,10 +375,10 @@ unsigned long flags; unsigned char c; - save_and_cli(flags); + local_irq_save(flags); for (ht = hard_trap_info; ht->tt && ht->signo; ht++) saved_vectors[ht->tt] = set_except_vector(ht->tt, trap_low); - + putDebugChar('+'); /* 'hello world' */ /* * In case GDB is started before us, ack any packets @@ -392,7 +391,7 @@ putDebugChar('+'); /* ack it */ initialized = 1; - restore_flags(flags); + local_irq_restore(flags); } /* @@ -548,7 +547,7 @@ targ += 4 + (insn.i_format.simmediate << 2); break; } - + if (is_branch) { i = 0; if (is_cond && targ != (regs->cp0_epc + 8)) { @@ -568,7 +567,7 @@ /* * If asynchronously interrupted by gdb, then we need to set a breakpoint - * at the interrupted instruction so that we wind up stopped with a + * at the interrupted instruction so that we wind up stopped with a * reasonable stack frame. */ static struct gdb_bp_save async_bp; @@ -578,7 +577,7 @@ async_bp.addr = epc; async_bp.val = *(unsigned *)epc; *(unsigned *)epc = BP; - flush_cache_all(); + __flush_cache_all(); } @@ -596,31 +595,11 @@ char *ptr; unsigned long *stack; -#if 0 - printk("in handle_exception()\n"); - show_gdbregs(regs); -#endif - - /* - * First check trap type. If this is CPU_UNUSABLE and CPU_ID is 1, - * the simply switch the FPU on and return since this is no error - * condition. kernel/traps.c does the same. - * FIXME: This doesn't work yet, so we don't catch CPU_UNUSABLE - * traps for now. - */ - trap = (regs->cp0_cause & 0x7c) >> 2; -/* printk("trap=%d\n",trap); */ - if (trap == 11) { - if (((regs->cp0_cause >> CAUSEB_CE) & 3) == 1) { - regs->cp0_status |= ST0_CU1; - return; - } - } - /* * If we're in breakpoint() increment the PC */ - if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) + trap = (regs->cp0_cause & 0x7c) >> 2; + if (trap == 9 && regs->cp0_epc == (unsigned long)breakinst) regs->cp0_epc += 4; /* @@ -630,7 +609,7 @@ if (step_bp[0].addr) { *(unsigned *)step_bp[0].addr = step_bp[0].val; step_bp[0].addr = 0; - + if (step_bp[1].addr) { *(unsigned *)step_bp[1].addr = step_bp[1].val; step_bp[1].addr = 0; @@ -708,6 +687,11 @@ output_buffer[3] = 0; break; + case 'D': + /* detach; let CPU run */ + putpacket(output_buffer); + return; + case 'd': /* toggle debug flag */ break; @@ -724,29 +708,24 @@ ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*4, 0); /* frp */ ptr = mem2hex((char *)®s->cp0_index, ptr, 16*4, 0); /* cp0 */ break; - + /* * set the value of the CPU registers - return OK - * FIXME: Needs to be written */ case 'G': { -#if 0 - unsigned long *newsp, psr; - ptr = &input_buffer[1]; - hex2mem(ptr, (char *)registers, 16 * 4, 0); /* G & O regs */ - - /* - * See if the stack pointer has moved. If so, then copy the - * saved locals and ins to the new location. - */ - - newsp = (unsigned long *)registers[SP]; - if (sp != newsp) - sp = memcpy(newsp, sp, 16 * 4); - -#endif + hex2mem(ptr, (char *)®s->reg0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp0_status, 6*4, 0); + ptr += 6*8; + hex2mem(ptr, (char *)®s->fpr0, 32*4, 0); + ptr += 32*8; + hex2mem(ptr, (char *)®s->cp1_fsr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->frame_ptr, 2*4, 0); + ptr += 2*8; + hex2mem(ptr, (char *)®s->cp0_index, 16*4, 0); strcpy(output_buffer,"OK"); } break; @@ -770,7 +749,7 @@ /* * MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - case 'M': + case 'M': ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr) @@ -789,13 +768,13 @@ /* * cAA..AA Continue at address AA..AA(optional) */ - case 'c': + case 'c': /* try to read optional parameter, pc unchanged if no parm */ ptr = &input_buffer[1]; if (hexToInt(&ptr, &addr)) regs->cp0_epc = addr; - + /* * Need to flush the instruction cache here, as we may * have deposited a breakpoint, and the icache probably @@ -805,26 +784,21 @@ * NB: We flush both caches, just to be sure... */ - flush_cache_all(); + __flush_cache_all(); return; /* NOTREACHED */ break; /* - * kill the program - */ - case 'k' : - break; /* do nothing */ - - - /* - * Reset the whole machine (FIXME: system dependent) + * kill the program; let us try to restart the machine + * Reset the whole machine. */ + case 'k': case 'r': + machine_restart("kgdb restarts machine"); break; - /* * Step to next instruction */ @@ -834,7 +808,7 @@ * use breakpoints and continue, instead. */ single_step(regs); - flush_cache_all(); + __flush_cache_all(); return; /* NOTREACHED */ @@ -844,7 +818,7 @@ */ case 'b': { -#if 0 +#if 0 int baudrate; extern void set_timer_3(); @@ -904,30 +878,43 @@ if (!initialized) return; - __asm__ __volatile__(" - .globl breakinst - .set noreorder - nop -breakinst: break - nop - .set reorder - "); + __asm__ __volatile__( + ".globl breakinst\n\t" + ".set\tnoreorder\n\t" + "nop\n\t" + "breakinst:\tbreak\n\t" + "nop\n\t" + ".set\treorder" + ); } void adel(void) { - __asm__ __volatile__(" - .globl adel - la $8,0x80000001 - lw $9,0($8) - "); + __asm__ __volatile__( + ".globl\tadel\n\t" + "la\t$8,0x80000001\n\t" + "lw\t$9,0($8)\n\t" + ); +} + +/* + * malloc is needed by gdb client in "call func()", even a private one + * will make gdb happy + */ +static void *malloc(size_t size) +{ + return kmalloc(size, GFP_ATOMIC); +} + +static void free(void *where) +{ + kfree(where); } #ifdef CONFIG_GDB_CONSOLE -void gdb_puts(const char *str) +void gdb_putsn(const char *str, int l) { - int l = strlen(str); char outbuf[18]; outbuf[0]='O'; @@ -936,7 +923,7 @@ int i = (l>8)?8:l; mem2hex((char *)str, &outbuf[1], i, 0); outbuf[(i*2)+1]=0; - putpacket(outbuf); + putpacket(outbuf); str += i; l -= i; } @@ -944,7 +931,7 @@ static void gdb_console_write(struct console *con, const char *s, unsigned n) { - gdb_puts(s); + gdb_putsn(s, n); } static struct console gdb_console = { @@ -958,5 +945,5 @@ { register_console(&gdb_console); } - + #endif diff -Nru a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S --- a/arch/mips/kernel/head.S Fri Jun 27 14:19:59 2003 +++ b/arch/mips/kernel/head.S Fri Jun 27 14:19:59 2003 @@ -1,6 +1,4 @@ /* - * arch/mips/kernel/head.S - * * 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. @@ -13,550 +11,224 @@ * Further modifications by David S. Miller and Harald Koerfgen * Copyright (C) 1999 Silicon Graphics, Inc. * - * Head.S contains the MIPS exception handler and startup code. - * - ************************************************************************** - * 9 Nov, 2000. - * Added Cache Error exception handler and SBDDP EJTAG debug exception. - * - * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - ************************************************************************** + * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ #include <linux/config.h> +#include <linux/init.h> #include <linux/threads.h> #include <asm/asm.h> -#include <asm/cacheops.h> -#include <asm/current.h> #include <asm/offset.h> +#include <asm/pgtable-bits.h> #include <asm/processor.h> #include <asm/regdef.h> #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/stackframe.h> -#include <asm/bootinfo.h> - - .text - /* - * Reserved space for exception handlers. - * Necessary for machines which link their kernels at KSEG0. - * FIXME: Use the initcode feature to get rid of unused handler - * variants. - */ - .fill 0x280 -/* - * This is space for the interrupt handlers. - * After trap_init() they are located at virtual address KSEG0. - * - * These handlers much be written in a relocatable manner - * because based upon the cpu type an arbitrary one of the - * following pieces of code will be copied to the KSEG0 - * vector location. - */ - /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ - .set noreorder - .set noat - LEAF(except_vec0_r4000) - .set mips3 -#ifdef CONFIG_SMP - mfc0 k1, CP0_CONTEXT - la k0, current_pgd - srl k1, 23 - sll k1, 2 - addu k1, k0, k1 - lw k1, (k1) -#else - lw k1, current_pgd # get pgd pointer -#endif - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, 22 # get pgd only bits - - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - mfc0 k0, CP0_CONTEXT # get context reg - lw k1, (k1) -#if defined(CONFIG_CPU_VR41XX) - srl k0, k0, 3 # get pte offset -#else - srl k0, k0, 1 # get pte offset -#endif - and k0, k0, 0xff8 - addu k1, k1, k0 # add in offset - lw k0, 0(k1) # get even pte - lw k1, 4(k1) # get odd pte - srl k0, k0, 6 # convert to entrylo0 - mtc0 k0, CP0_ENTRYLO0 # load it - srl k1, k1, 6 # convert to entrylo1 - mtc0 k1, CP0_ENTRYLO1 # load it - b 1f - tlbwr # write random tlb entry -1: - nop - eret # return from trap - END(except_vec0_r4000) - - /* TLB refill, EXL == 0, R4600 version */ - LEAF(except_vec0_r4600) - .set mips3 - mfc0 k0, CP0_BADVADDR - srl k0, k0, 22 - lw k1, current_pgd # get pgd pointer - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - srl k0, k0, 1 - and k0, k0, 0xff8 - addu k1, k1, k0 - lw k0, 0(k1) - lw k1, 4(k1) - srl k0, k0, 6 - mtc0 k0, CP0_ENTRYLO0 - srl k1, k1, 6 - mtc0 k1, CP0_ENTRYLO1 - nop - tlbwr - nop - eret - END(except_vec0_r4600) - - /* TLB refill, EXL == 0, R52x0 "Nevada" version */ - /* - * This version has a bug workaround for the Nevada. It seems - * as if under certain circumstances the move from cp0_context - * might produce a bogus result when the mfc0 instruction and - * it's consumer are in a different cacheline or a load instruction, - * probably any memory reference, is between them. This is - * potencially slower than the R4000 version, so we use this - * special version. - */ - .set noreorder - .set noat - LEAF(except_vec0_nevada) - .set mips3 - mfc0 k0, CP0_BADVADDR # Get faulting address - srl k0, k0, 22 # get pgd only bits - lw k1, current_pgd # get pgd pointer - sll k0, k0, 2 - addu k1, k1, k0 # add in pgd offset - lw k1, (k1) - mfc0 k0, CP0_CONTEXT # get context reg - srl k0, k0, 1 # get pte offset - and k0, k0, 0xff8 - addu k1, k1, k0 # add in offset - lw k0, 0(k1) # get even pte - lw k1, 4(k1) # get odd pte - srl k0, k0, 6 # convert to entrylo0 - mtc0 k0, CP0_ENTRYLO0 # load it - srl k1, k1, 6 # convert to entrylo1 - mtc0 k1, CP0_ENTRYLO1 # load it - nop # QED specified nops - nop - tlbwr # write random tlb entry - nop # traditional nop - eret # return from trap - END(except_vec0_nevada) - - /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ - LEAF(except_vec0_r45k_bvahwbug) - .set mips3 - mfc0 k0, CP0_BADVADDR - srl k0, k0, 22 - lw k1, current_pgd # get pgd pointer - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - srl k0, k0, 1 - and k0, k0, 0xff8 - addu k1, k1, k0 - lw k0, 0(k1) - lw k1, 4(k1) - nop /* XXX */ - tlbp - srl k0, k0, 6 - mtc0 k0, CP0_ENTRYLO0 - srl k1, k1, 6 - mfc0 k0, CP0_INDEX - mtc0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r45k_bvahwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ - LEAF(except_vec0_r4k_mphwbug) - .set mips3 - mfc0 k0, CP0_BADVADDR - srl k0, k0, 22 - lw k1, current_pgd # get pgd pointer - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - srl k0, k0, 1 - and k0, k0, 0xff8 - addu k1, k1, k0 - lw k0, 0(k1) - lw k1, 4(k1) - nop /* XXX */ - tlbp - srl k0, k0, 6 - mtc0 k0, CP0_ENTRYLO0 - srl k1, k1, 6 - mfc0 k0, CP0_INDEX - mtc0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_mphwbug) -#endif - - /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ - LEAF(except_vec0_r4k_250MHZhwbug) - .set mips3 - mfc0 k0, CP0_BADVADDR - srl k0, k0, 22 - lw k1, current_pgd # get pgd pointer - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - srl k0, k0, 1 - and k0, k0, 0xff8 - addu k1, k1, k0 - lw k0, 0(k1) - lw k1, 4(k1) - srl k0, k0, 6 - mtc0 zero, CP0_ENTRYLO0 - mtc0 k0, CP0_ENTRYLO0 - srl k1, k1, 6 - mtc0 zero, CP0_ENTRYLO1 - mtc0 k1, CP0_ENTRYLO1 - b 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_250MHZhwbug) - -#ifdef CONFIG_SMP - /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ - LEAF(except_vec0_r4k_MP250MHZhwbug) - .set mips3 - mfc0 k0, CP0_BADVADDR - srl k0, k0, 22 - lw k1, current_pgd # get pgd pointer - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - srl k0, k0, 1 - and k0, k0, 0xff8 - addu k1, k1, k0 - lw k0, 0(k1) - lw k1, 4(k1) - nop /* XXX */ - tlbp - srl k0, k0, 6 - mtc0 zero, CP0_ENTRYLO0 - mtc0 k0, CP0_ENTRYLO0 - mfc0 k0, CP0_INDEX - srl k1, k1, 6 - mtc0 zero, CP0_ENTRYLO1 - mtc0 k1, CP0_ENTRYLO1 - bltzl k0, 1f - tlbwr -1: - nop - eret - END(except_vec0_r4k_MP250MHZhwbug) -#endif - - /* TLB refill, R[23]00 version */ - LEAF(except_vec0_r2300) - .set noat - .set mips1 - mfc0 k0, CP0_BADVADDR - lw k1, current_pgd # get pgd pointer - srl k0, k0, 22 - sll k0, k0, 2 - addu k1, k1, k0 - mfc0 k0, CP0_CONTEXT - lw k1, (k1) - and k0, k0, 0xffc - addu k1, k1, k0 - lw k0, (k1) - nop - mtc0 k0, CP0_ENTRYLO0 - mfc0 k1, CP0_EPC - tlbwr - jr k1 - rfe - END(except_vec0_r2300) - - - /* XTLB refill, EXL == 0, R4xx0 cpus only use this... */ - NESTED(except_vec1_generic, 0, sp) - .set noat - .set mips3 - /* Register saving is delayed as long as we don't know - * which registers really need to be saved. - */ - mfc0 k1, CP0_CONTEXT - dsra k1, 1 - lwu k0, (k1) # May cause another exception - lwu k1, 4(k1) - dsrl k0, 6 # Convert to EntryLo format - dsrl k1, 6 # Convert to EntryLo format - dmtc0 k0, CP0_ENTRYLO0 - dmtc0 k1, CP0_ENTRYLO1 - nop # Needed for R4[04]00 pipeline - tlbwr - nop # Needed for R4[04]00 pipeline - nop - nop - eret - nop /* Workaround for R4000 bug. */ - eret - END(except_vec1_generic) - - /* Cache Error */ - LEAF(except_vec2_generic) - .set noat - .set mips0 - /* - * This is a very bad place to be. Our cache error - * detection has triggered. If we have write-back data - * in the cache, we may not be able to recover. As a - * first-order desperate measure, turn off KSEG0 cacheing. - */ - mfc0 k0,CP0_CONFIG - li k1,~CONF_CM_CMASK - and k0,k0,k1 - ori k0,k0,CONF_CM_UNCACHED - mtc0 k0,CP0_CONFIG - /* Give it a few cycles to sink in... */ - nop - nop - nop - - j cache_parity_error - nop - END(except_vec2_generic) - - /* General exception vector R4000 version. */ - NESTED(except_vec3_r4000, 0, sp) - .set noat - mfc0 k1, CP0_CAUSE - andi k1, k1, 0x7c - li k0, 31<<2 - beq k1, k0, handle_vced - li k0, 14<<2 - beq k1, k0, handle_vcei - la k0, exception_handlers - addu k0, k0, k1 - lw k0, (k0) - nop - jr k0 - nop -/* - * Big shit, we now may have two dirty primary cache lines for the same - * physical address. We can savely invalidate the line pointed to by - * c0_badvaddr because after return from this exception handler the load / - * store will be re-executed. - */ - .set mips3 -handle_vced: - mfc0 k0, CP0_BADVADDR - li k1, -4 - and k0, k1 - mtc0 zero, CP0_TAGLO - cache Index_Store_Tag_D,(k0) - cache Hit_Writeback_Inv_SD,(k0) -#ifdef CONFIG_PROC_FS - lui k0, %hi(vced_count) - lw k1, %lo(vced_count)(k0) - addiu k1, 1 - sw k1, %lo(vced_count)(k0) -#endif - eret - -handle_vcei: - mfc0 k0, CP0_BADVADDR - cache Hit_Writeback_Inv_SD,(k0) # also cleans pi -#ifdef CONFIG_PROC_FS - lui k0, %hi(vcei_count) - lw k1, %lo(vcei_count)(k0) - addiu k1, 1 - sw k1, %lo(vcei_count)(k0) -#endif - eret - - END(except_vec3_r4000) - .set at - - /* General exception vector. */ - NESTED(except_vec3_generic, 0, sp) - .set noat - .set mips0 - mfc0 k1, CP0_CAUSE - la k0, exception_handlers - andi k1, k1, 0x7c - addu k0, k0, k1 - lw k0, (k0) - nop - jr k0 - nop - END(except_vec3_generic) - .set at - - /* - * Special interrupt vector for embedded MIPS. This is a - * dedicated interrupt vector which reduces interrupt processing - * overhead. The jump instruction will be inserted here at - * initialization time. This handler may only be 8 bytes in size! - */ - NESTED(except_vec4, 0, sp) -1: j 1b /* Dummy, will be replaced */ - nop - END(except_vec4) - - /* - * SBDDP EJTAG debug exception handler. - * The EJTAG debug exception entry point is 0xbfc00480, which - * normally is in the boot PROM, so the boot PROM must do a - * unconditional jump to this vector. - */ - NESTED(except_vec_ejtag_debug, 0, sp) - j ejtag_debug_handler - nop - END(except_vec_ejtag_debug) - - /* - * EJTAG debug exception handler. - */ - NESTED(ejtag_debug_handler, PT_SIZE, sp) - .set noat - .set noreorder - SAVE_ALL - PRINT("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); - mfc0 k0, $23 # Get EJTAG Debug register. - mfc0 k1, $24 # Get DEPC register. - bgez k0, 1f - addiu k1, k1, 4 # SBDDP inst. in delay slot. - addiu k1, k1, 4 -1: mtc0 k1, $24 - RESTORE_ALL - .word 0x4200001f # deret, return EJTAG debug exception. - nop - .set at - END(ejtag_debug_handler) - - -/* - * Kernel entry point - */ -NESTED(kernel_entry, 16, sp) - .set noreorder - /* The following two symbols are used for kernel profiling. */ - EXPORT(stext) - EXPORT(_stext) - - /* - * Stack for kernel and init, current variable - */ - la $28, init_task_union - addiu t0, $28, KERNEL_STACK_SIZE-32 - subu sp, t0, 4*SZREG - - sw t0, kernelsp - /* The firmware/bootloader passes argc/argp/envp - * to us as arguments. But clear bss first because - * the romvec and other important info is stored there - * by prom_init(). - */ - la t0, _edata - sw zero, (t0) - la t1, (_end - 4) -1: - addiu t0, 4 - bne t0, t1, 1b - sw zero, (t0) - - jal init_arch - nop - END(kernel_entry) + .text + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. + */ + .fill 0x400 + + /* The following two symbols are used for kernel profiling. */ + EXPORT(stext) + EXPORT(_stext) + + __INIT + + /* Cache Error */ + LEAF(except_vec2_generic) + .set noreorder + .set noat + .set mips0 + /* + * This is a very bad place to be. Our cache error + * detection has triggered. If we have write-back data + * in the cache, we may not be able to recover. As a + * first-order desperate measure, turn off KSEG0 cacheing. + */ + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + /* Give it a few cycles to sink in... */ + nop + nop + nop + + j cache_parity_error + nop + END(except_vec2_generic) + + .set at + + /* + * Special interrupt vector for embedded MIPS. This is a + * dedicated interrupt vector which reduces interrupt processing + * overhead. The jump instruction will be inserted here at + * initialization time. This handler may only be 8 bytes in + * size! + */ + NESTED(except_vec4, 0, sp) +1: j 1b /* Dummy, will be replaced */ + nop + END(except_vec4) + + /* + * EJTAG debug exception handler. + * The EJTAG debug exception entry point is 0xbfc00480, which + * normally is in the boot PROM, so the boot PROM must do a + * unconditional jump to this vector. + */ + NESTED(except_vec_ejtag_debug, 0, sp) + j ejtag_debug_handler + nop + END(except_vec_ejtag_debug) + + __FINIT + + /* + * EJTAG debug exception handler. + */ + NESTED(ejtag_debug_handler, PT_SIZE, sp) + .set noat + .set noreorder + mtc0 k0, CP0_DESAVE + mfc0 k0, CP0_DEBUG + + sll k0, k0, 30 # Check for SDBBP. + bgez k0, ejtag_return + + la k0, ejtag_debug_buffer + sw k1, 0(k0) + SAVE_ALL + jal ejtag_exception_handler + move a0, sp + RESTORE_ALL + la k0, ejtag_debug_buffer + lw k1, 0(k0) + +ejtag_return: + mfc0 k0, CP0_DESAVE + .set mips32 + deret + .set mips0 + nop + .set at + END(ejtag_debug_handler) + + __INIT + + /* + * NMI debug exception handler for MIPS reference boards. + * The NMI debug exception entry point is 0xbfc00000, which + * normally is in the boot PROM, so the boot PROM must do a + * unconditional jump to this vector. + */ + NESTED(except_vec_nmi, 0, sp) + j nmi_handler + nop + END(except_vec_nmi) + + __FINIT + + NESTED(nmi_handler, PT_SIZE, sp) + .set noat + .set noreorder + .set mips3 + SAVE_ALL + jal nmi_exception_handler + move a0, sp + RESTORE_ALL + eret + .set at + .set mips0 + END(nmi_handler) + + __INIT + + /* + * Kernel entry point + */ + NESTED(kernel_entry, 16, sp) + .set noreorder + + /* + * Stack for kernel and init, current variable + */ + la $28, init_thread_union + addiu t0, $28, KERNEL_STACK_SIZE-32 + subu sp, t0, 4*SZREG + sw t0, kernelsp + + /* The firmware/bootloader passes argc/argp/envp + * to us as arguments. But clear bss first because + * the romvec and other important info is stored there + * by prom_init(). + */ + la t0, __bss_start + sw zero, (t0) + la t1, __bss_stop - 4 +1: + addiu t0, 4 + bne t0, t1, 1b + sw zero, (t0) + + jal init_arch + nop + END(kernel_entry) #ifdef CONFIG_SMP /* - * SMP slave cpus entry point. Board specific code - * for bootstrap calls this function after setting up - * the stack and gp registers. - */ - LEAF(smp_bootstrap) - .set push - .set noreorder - mtc0 zero, CP0_WIRED - CLI - mfc0 t0, CP0_STATUS - li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); - and t0, t1 - or t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR); - addiu a0, zero, 0 - jal start_secondary - mtc0 t0, CP0_STATUS - .set pop - END(smp_bootstrap) -#endif - -/* - * This buffer is reserved for the use of the cache error handler. + * SMP slave cpus entry point. Board specific code for bootstrap calls this + * function after setting up the stack and gp registers. */ + LEAF(smp_bootstrap) + .set push + .set noreorder + mtc0 zero, CP0_WIRED + CLI + mfc0 t0, CP0_STATUS + li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX) + and t0, t1 + or t0, (ST0_CU0); + jal start_secondary + mtc0 t0, CP0_STATUS + .set pop + END(smp_bootstrap) +#endif + + __FINIT + + /* + * This buffer is reserved for the use of the EJTAG debug + * handler. + */ .data - EXPORT(cache_error_buffer) - .fill 32*4,1,0 - -#ifndef CONFIG_SMP -EXPORT(kernelsp) - PTR 0 -EXPORT(current_pgd) - PTR 0 -#else - /* There's almost certainly a better way to do this with the macros...*/ - .globl kernelsp - .comm kernelsp, NR_CPUS * 8, 8 - .globl current_pgd - .comm current_pgd, NR_CPUS * 8, 8 -#endif - .text - .org 0x1000 -EXPORT(swapper_pg_dir) - - .org 0x2000 -EXPORT(empty_bad_page) + EXPORT(ejtag_debug_buffer) + .fill 4 - .org 0x3000 -EXPORT(empty_bad_page_table) + .comm kernelsp, NR_CPUS * 8, 8 + .comm pgd_current, NR_CPUS * 8, 8 - .org 0x4000 -EXPORT(invalid_pte_table) - - .org 0x5000 -/* XXX This label is required to keep GAS trying to be too clever ... - Bug? */ -dummy: -/* - * Align to 8kb boundary for init_task_union which follows in the - * .text segment. - */ - .align 13 + .macro page name, order=0 + .globl \name +\name: .size \name, (_PAGE_SIZE << \order) + .org . + (_PAGE_SIZE << \order) + .type \name, @object + .endm + + .data + .align PAGE_SHIFT + + page swapper_pg_dir, _PGD_ORDER + page empty_bad_page, 0 + page empty_bad_page_table, 0 + page invalid_pte_table, 0 diff -Nru a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c --- a/arch/mips/kernel/i8259.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/i8259.c Fri Jun 27 14:19:54 2003 @@ -11,11 +11,12 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/ioport.h> -#include <linux/irq.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/spinlock.h> +#include <linux/sysdev.h> +#include <asm/i8259.h> #include <asm/io.h> void enable_8259A_irq(unsigned int irq); @@ -30,11 +31,12 @@ * moves to arch independent land */ -spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; static void end_8259A_irq (unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irq_desc[irq].action) enable_8259A_irq(irq); } @@ -43,7 +45,7 @@ void mask_and_ack_8259A(unsigned int); static unsigned int startup_8259A_irq(unsigned int irq) -{ +{ enable_8259A_irq(irq); return 0; /* never anything pending */ @@ -69,9 +71,8 @@ */ static unsigned int cached_irq_mask = 0xffff; -#define __byte(x,y) (((unsigned char *)&(y))[x]) -#define cached_21 (__byte(0,cached_irq_mask)) -#define cached_A1 (__byte(1,cached_irq_mask)) +#define cached_21 (cached_irq_mask) +#define cached_A1 (cached_irq_mask >> 8) void disable_8259A_irq(unsigned int irq) { @@ -211,7 +212,7 @@ printk("spurious 8259A interrupt: IRQ%d.\n", irq); spurious_irq_mask |= irqmask; } - irq_err_count++; + atomic_inc(&irq_err_count); /* * Theoretically we do not have to handle this IRQ, * but in Linux this does not cause problems and is @@ -221,6 +222,32 @@ } } +static int i8259A_resume(struct sys_device *dev) +{ + init_8259A(0); + return 0; +} + +static struct sysdev_class i8259_sysdev_class = { + set_kset_name("i8259"), + .resume = i8259A_resume, +}; + +static struct sys_device device_i8259A = { + .id = 0, + .cls = &i8259_sysdev_class, +}; + +static int __init i8259A_init_sysfs(void) +{ + int error = sysdev_class_register(&i8259_sysdev_class); + if (!error) + error = sys_device_register(&device_i8259A); + return error; +} + +device_initcall(i8259A_init_sysfs); + void __init init_8259A(int auto_eoi) { unsigned long flags; @@ -234,7 +261,7 @@ * outb_p - this has to work on a wide range of PC hardware. */ outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ - outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ + outb_p(0x00, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */ outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ if (auto_eoi) outb_p(0x03, 0x21); /* master does Auto EOI */ @@ -242,7 +269,7 @@ outb_p(0x01, 0x21); /* master expects normal EOI */ outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ - outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ + outb_p(0x08, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */ outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode is to be investigated) */ diff -Nru a/arch/mips/kernel/init_task.c b/arch/mips/kernel/init_task.c --- a/arch/mips/kernel/init_task.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/init_task.c Fri Jun 27 14:19:54 2003 @@ -1,17 +1,19 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/init_task.h> +#include <linux/fs.h> #include <asm/uaccess.h> #include <asm/pgtable.h> static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); /* - * Initial task structure. + * Initial thread structure. * * We need to make sure that this is 8192-byte aligned due to the * way process stacks are handled. This is done by making sure @@ -20,6 +22,13 @@ * * The things we do for performance.. */ -union task_union init_task_union - __attribute__((__section__(".text"))) = - { INIT_TASK(init_task_union.task) }; +union thread_union init_thread_union + __attribute__((__section__(".data.init_task"))) = + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); diff -Nru a/arch/mips/kernel/ioport.c b/arch/mips/kernel/ioport.c --- a/arch/mips/kernel/ioport.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,34 +0,0 @@ -/* - * linux/arch/mips/kernel/ioport.c - */ -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/types.h> -#include <linux/ioport.h> - -/* - * This changes the io permissions bitmap in the current task. - */ -asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) -{ - return -ENOSYS; -} - -/* - * sys_iopl has to be used when you want to access the IO ports - * beyond the 0x3ff range: to get the full 65536 ports bitmapped - * you'd need 8kB of bitmaps/process, which is a bit excessive. - * - * Here we just change the eflags value on the stack: we allow - * only the super-user to do it. This depends on the stack-layout - * on system-call entry - see also fork() and the signal handling - * code. - */ -asmlinkage int sys_iopl(long ebx,long ecx,long edx, - long esi, long edi, long ebp, long eax, long ds, - long es, long fs, long gs, long orig_eax, - long eip,long cs,long eflags,long esp,long ss) -{ - return -ENOSYS; -} diff -Nru a/arch/mips/kernel/ipc.c b/arch/mips/kernel/ipc.c --- a/arch/mips/kernel/ipc.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/ipc.c Fri Jun 27 14:19:54 2003 @@ -45,7 +45,7 @@ } case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, + return sys_msgsnd (first, (struct msgbuf *) ptr, second, third); case MSGRCV: switch (version) { @@ -53,9 +53,9 @@ struct ipc_kludge tmp; if (!ptr) return -EINVAL; - + if (copy_from_user(&tmp, - (struct ipc_kludge *) ptr, + (struct ipc_kludge *) ptr, sizeof (tmp))) return -EFAULT; return sys_msgrcv (first, tmp.msgp, second, @@ -85,7 +85,7 @@ return -EINVAL; return sys_shmat (first, (char *) ptr, second, (ulong *) third); } - case SHMDT: + case SHMDT: return sys_shmdt ((char *)ptr); case SHMGET: return sys_shmget (first, second, third); @@ -93,6 +93,6 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } diff -Nru a/arch/mips/kernel/irix5sys.h b/arch/mips/kernel/irix5sys.h --- a/arch/mips/kernel/irix5sys.h Fri Jun 27 14:19:52 2003 +++ b/arch/mips/kernel/irix5sys.h Fri Jun 27 14:19:52 2003 @@ -1,5 +1,4 @@ -/* $Id: irix5sys.h,v 1.2 1998/08/17 10:16:25 ralf Exp $ - * +/* * irix5sys.h: 32-bit IRIX5 ABI system call table. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff -Nru a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c --- a/arch/mips/kernel/irixelf.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/kernel/irixelf.c Fri Jun 27 14:20:06 2003 @@ -45,7 +45,6 @@ static int load_irix_library(struct file *); static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file); -extern int dump_fpu (elf_fpregset_t *); static struct linux_binfmt irix_format = { NULL, THIS_MODULE, load_irix_binary, load_irix_library, @@ -127,7 +126,7 @@ { start = PAGE_ALIGN(start); end = PAGE_ALIGN(end); - if (end <= start) + if (end <= start) return; do_brk(start, end - start); } @@ -157,7 +156,7 @@ elf_addr_t *argv; elf_addr_t *envp; elf_addr_t *sp, *csp; - + #ifdef DEBUG_ELF printk("create_irix_tables: p[%p] argc[%d] envc[%d] " "load_addr[%08x] interp_load_addr[%08x]\n", @@ -246,7 +245,7 @@ elf_bss = 0; last_bss = 0; error = load_addr = 0; - + #ifdef DEBUG_ELF print_elfhdr(interp_elf_ex); #endif @@ -267,7 +266,7 @@ return 0xffffffff; } - elf_phdata = (struct elf_phdr *) + elf_phdata = (struct elf_phdr *) kmalloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, GFP_KERNEL); @@ -393,7 +392,7 @@ return -ENOEXEC; /* First of all, some simple consistency checks */ - if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || + if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || !irix_elf_check_arch(ehp) || !bprm->file->f_op->mmap) { return -ENOEXEC; } @@ -557,7 +556,7 @@ } /* - * IRIX maps a page at 0x200000 that holds information about the + * IRIX maps a page at 0x200000 that holds information about the * process and the system, here we map the page and fill the * structure */ @@ -567,20 +566,20 @@ struct prda *pp; v = do_brk (PRDA_ADDRESS, PAGE_SIZE); - + if (v < 0) return; pp = (struct prda *) v; pp->prda_sys.t_pid = current->pid; - pp->prda_sys.t_prid = read_32bit_cp0_register (CP0_PRID); + pp->prda_sys.t_prid = read_c0_prid(); pp->prda_sys.t_rpid = current->pid; /* We leave the rest set to zero */ } - - + + /* These are the functions used to load ELF style executables and shared * libraries. There is no binary dependent code anywhere else. */ @@ -595,7 +594,7 @@ int retval, has_interp, has_ephdr, size, i; char *elf_interpreter; mm_segment_t old_fs; - + load_addr = 0; has_interp = has_ephdr = 0; elf_ihdr = elf_ephdr = 0; @@ -684,7 +683,7 @@ current->mm->mmap = NULL; current->flags &= ~PF_FORKNOEXEC; elf_entry = (unsigned int) elf_ex.e_entry; - + /* Do this so that we can load the interpreter, if need be. We will * change some of these later. */ @@ -723,7 +722,7 @@ set_binfmt(&irix_format); compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; - bprm->p = (unsigned long) + bprm->p = (unsigned long) create_irix_tables((char *)bprm->p, bprm->argc, bprm->envc, (elf_interpreter ? &elf_ex : NULL), load_addr, interp_load_addr, regs, elf_ephdr); @@ -811,30 +810,30 @@ if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || !irix_elf_check_arch(&elf_ex) || !file->f_op->mmap) return -ENOEXEC; - + /* Now read in all of the header information. */ if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE) return -ENOEXEC; - - elf_phdata = (struct elf_phdr *) + + elf_phdata = (struct elf_phdr *) kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL); if (elf_phdata == NULL) return -ENOMEM; - + retval = kernel_read(file, elf_ex.e_phoff, (char *) elf_phdata, sizeof(struct elf_phdr) * elf_ex.e_phnum); - + j = 0; for(i=0; i<elf_ex.e_phnum; i++) if((elf_phdata + i)->p_type == PT_LOAD) j++; - + if(j != 1) { kfree(elf_phdata); return -ENOEXEC; } - + while(elf_phdata->p_type != PT_LOAD) elf_phdata++; - + /* Now use mmap to map the library into memory. */ down_write(¤t->mm->mmap_sem); error = do_mmap(file, @@ -862,7 +861,7 @@ kfree(elf_phdata); return 0; } - + /* Called through irix_syssgi() to map an elf image given an FD, * a phdr ptr USER_PHDRP in userspace, and a count CNT telling how many * phdrs there are in the USER_PHDRP array. We return the vaddr the @@ -1025,7 +1024,7 @@ DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ DUMP_WRITE(men->data, men->datasz); DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ - + return 1; end_coredump: @@ -1071,13 +1070,13 @@ if (maydump(vma)) { int sz = vma->vm_end-vma->vm_start; - + if (size+sz >= limit) break; else size += sz; } - + segs++; } #ifdef DEBUG @@ -1104,7 +1103,7 @@ elf.e_shentsize = 0; elf.e_shnum = 0; elf.e_shstrndx = 0; - + fs = get_fs(); set_fs(KERNEL_DS); @@ -1129,24 +1128,24 @@ prstatus.pr_sigpend = current->pending.signal.sig[0]; prstatus.pr_sighold = current->blocked.sig[0]; psinfo.pr_pid = prstatus.pr_pid = current->pid; - psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; + psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp; psinfo.pr_sid = prstatus.pr_sid = current->session; - prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime); - prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime); - prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime); - prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime); - prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime); - prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime); - prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime); - prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime); + prstatus.pr_utime.tv_sec = CT_TO_SECS(current->utime); + prstatus.pr_utime.tv_usec = CT_TO_USECS(current->utime); + prstatus.pr_stime.tv_sec = CT_TO_SECS(current->stime); + prstatus.pr_stime.tv_usec = CT_TO_USECS(current->stime); + prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->cutime); + prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->cutime); + prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->cstime); + prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->cstime); if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) { printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) " "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs)); } else { *(struct pt_regs *)&prstatus.pr_reg = *regs; } - + notes[1].name = "CORE"; notes[1].type = NT_PRPSINFO; notes[1].datasz = sizeof(psinfo); @@ -1155,7 +1154,7 @@ psinfo.pr_state = i; psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i]; psinfo.pr_zomb = psinfo.pr_sname == 'Z'; - psinfo.pr_nice = current->nice; + psinfo.pr_nice = task_nice(current); psinfo.pr_flag = current->flags; psinfo.pr_uid = current->uid; psinfo.pr_gid = current->gid; @@ -1163,7 +1162,7 @@ int i, len; set_fs(fs); - + len = current->mm->arg_end - current->mm->arg_start; len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len; copy_from_user(&psinfo.pr_psargs, @@ -1183,7 +1182,7 @@ notes[2].data = current; /* Try to dump the FPU. */ - prstatus.pr_fpvalid = dump_fpu (&fpu); + prstatus.pr_fpvalid = dump_fpu (regs, &fpu); if (!prstatus.pr_fpvalid) { numnote--; } else { @@ -1200,7 +1199,7 @@ for(i = 0; i < numnote; i++) sz += notesize(¬es[i]); - + phdr.p_type = PT_NOTE; phdr.p_offset = offset; phdr.p_vaddr = 0; @@ -1216,7 +1215,7 @@ /* Page-align dumped data. */ dataoff = offset = roundup(offset, PAGE_SIZE); - + /* Write program headers for segments dump. */ for(vma = current->mm->mmap, i = 0; i < segs && vma != NULL; vma = vma->vm_next) { @@ -1226,7 +1225,7 @@ i++; sz = vma->vm_end - vma->vm_start; - + phdr.p_type = PT_LOAD; phdr.p_offset = offset; phdr.p_vaddr = vma->vm_start; @@ -1245,17 +1244,17 @@ for(i = 0; i < numnote; i++) if (!writenote(¬es[i], file)) goto end_coredump; - + set_fs(fs); DUMP_SEEK(dataoff); - + for(i = 0, vma = current->mm->mmap; i < segs && vma != NULL; vma = vma->vm_next) { unsigned long addr = vma->vm_start; unsigned long len = vma->vm_end - vma->vm_start; - + if (!maydump(vma)) continue; i++; diff -Nru a/arch/mips/kernel/irixinv.c b/arch/mips/kernel/irixinv.c --- a/arch/mips/kernel/irixinv.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/kernel/irixinv.c Fri Jun 27 14:19:53 2003 @@ -1,11 +1,9 @@ /* * Support the inventory interface for IRIX binaries * This is invoked before the mm layer is working, so we do not - * use the linked lists for the inventory yet. + * use the linked lists for the inventory yet. * * Miguel de Icaza, 1997. - * - * $Id: irixinv.c,v 1.3 1998/04/05 11:23:51 ralf Exp $ */ #include <linux/mm.h> #include <linux/init.h> @@ -18,14 +16,13 @@ static inventory_t inventory [MAX_INVENTORY]; -void -add_to_inventory (int class, int type, int controller, int unit, int state) +void add_to_inventory (int class, int type, int controller, int unit, int state) { inventory_t *ni = &inventory [inventory_items]; if (inventory_items == MAX_INVENTORY) return; - + ni->inv_class = class; ni->inv_type = type; ni->inv_controller = controller; @@ -35,8 +32,7 @@ inventory_items++; } -int -dump_inventory_to_user (void *userbuf, int size) +int dump_inventory_to_user (void *userbuf, int size) { inventory_t *inv = &inventory [0]; inventory_t *user = userbuf; @@ -53,13 +49,13 @@ return inventory_items * sizeof (inventory_t); } -void __init init_inventory (void) +static int __init init_inventory(void) { - /* gross hack while we put the right bits all over the kernel + /* + * gross hack while we put the right bits all over the kernel * most likely this will not let just anyone run the X server * until we put the right values all over the place */ - add_to_inventory (10, 3, 0, 0, 16400); add_to_inventory (1, 1, 150, -1, 12); add_to_inventory (1, 3, 0, 0, 8976); @@ -78,4 +74,8 @@ add_to_inventory (2, 2, 0, 2, 0); add_to_inventory (2, 2, 0, 1, 0); add_to_inventory (7, 14, 0, 0, 6); + + return 0; } + +module_init(init_inventory); diff -Nru a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c --- a/arch/mips/kernel/irixioctl.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/kernel/irixioctl.c Fri Jun 27 14:19:59 2003 @@ -10,6 +10,7 @@ #include <linux/mm.h> #include <linux/smp.h> #include <linux/smp_lock.h> +#include <linux/sockios.h> #include <linux/tty.h> #include <linux/file.h> diff -Nru a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c --- a/arch/mips/kernel/irixsig.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/kernel/irixsig.c Fri Jun 27 14:20:01 2003 @@ -17,7 +17,7 @@ #include <asm/ptrace.h> #include <asm/uaccess.h> -extern asmlinkage void syscall_trace(void); +extern asmlinkage void do_syscall_trace(void); #undef DEBUG_SIG @@ -117,7 +117,8 @@ regs->regs[5] = 0; /* XXX sigcode XXX */ regs->regs[6] = regs->regs[29] = sp; regs->regs[7] = (unsigned long) ka->sa.sa_handler; - regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa.sa_restorer; + regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; + return; segv_and_exit: @@ -134,27 +135,11 @@ do_exit(SIGSEGV); } -static inline void handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) +static inline void handle_signal(unsigned long sig, siginfo_t *info, + sigset_t *oldset, struct pt_regs * regs) { - if (ka->sa.sa_flags & SA_SIGINFO) - setup_irix_rt_frame(ka, regs, sig, oldset, info); - else - setup_irix_frame(ka, regs, sig, oldset); + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; - if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sigmask_lock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); - } -} - -static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) -{ switch(regs->regs[0]) { case ERESTARTNOHAND: regs->regs[2] = EINTR; @@ -170,111 +155,34 @@ } regs->regs[0] = 0; /* Don't deal with this again. */ + + if (ka->sa.sa_flags & SA_SIGINFO) + setup_irix_rt_frame(ka, regs, sig, oldset, info); + else + setup_irix_frame(ka, regs, sig, oldset); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } } asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) { - struct k_sigaction *ka; siginfo_t info; + int signr; if (!oldset) oldset = ¤t->blocked; - for (;;) { - unsigned long signr; - - spin_lock_irq(¤t->sigmask_lock); - signr = dequeue_signal(current, ¤t->blocked, &info); - spin_unlock_irq(¤t->sigmask_lock); - - if (!signr) - break; - - if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { - /* Let the debugger run. */ - current->exit_code = signr; - current->state = TASK_STOPPED; - notify_parent(current, SIGCHLD); - schedule(); - - /* We're back. Did the debugger cancel the sig? */ - if (!(signr = current->exit_code)) - continue; - current->exit_code = 0; - - /* The debugger continued. Ignore SIGSTOP. */ - if (signr == SIGSTOP) - continue; - - /* Update the siginfo structure. Is this good? */ - if (signr != info.si_signo) { - info.si_signo = signr; - info.si_errno = 0; - info.si_code = SI_USER; - info.si_pid = current->p_pptr->pid; - info.si_uid = current->p_pptr->uid; - } - - /* If the (new) signal is now blocked, requeue it. */ - if (sigismember(¤t->blocked, signr)) { - send_sig_info(signr, &info, current); - continue; - } - } - - ka = ¤t->sig->action[signr-1]; - if (ka->sa.sa_handler == SIG_IGN) { - if (signr != SIGCHLD) - continue; - /* Check for SIGCHLD: it's special. */ - while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) - /* nothing */; - continue; - } - - if (ka->sa.sa_handler == SIG_DFL) { - int exit_code = signr; - - /* Init gets no signals it doesn't want. */ - if (current->pid == 1) - continue; - - switch (signr) { - case SIGCONT: case SIGCHLD: case SIGWINCH: - continue; - - case SIGTSTP: case SIGTTIN: case SIGTTOU: - if (is_orphaned_pgrp(current->pgrp)) - continue; - /* FALLTHRU */ - - case SIGSTOP: - current->state = TASK_STOPPED; - current->exit_code = signr; - if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) - notify_parent(current, SIGCHLD); - schedule(); - continue; - - case SIGQUIT: case SIGILL: case SIGTRAP: - case SIGABRT: case SIGFPE: case SIGSEGV: - if (do_coredump(signr, regs)) - exit_code |= 0x80; - /* FALLTHRU */ - - default: - sigaddset(¤t->pending.signal, signr); - recalc_sigpending(); - current->flags |= PF_SIGNALED; - do_exit(exit_code); - /* NOTREACHED */ - } - } - - if (regs->regs[0]) - syscall_restart(regs, ka); - /* Whee! Actually deliver the signal. */ - handle_signal(signr, ka, &info, oldset, regs); + signr = get_signal_to_deliver(&info, regs, NULL); + if (signr > 0) { + handle_signal(signr, &info, oldset, regs); return 1; } @@ -343,19 +251,19 @@ goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = blocked; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); /* * Don't let your children do this ... */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); + if (current_thread_info()->flags & TIF_SYSCALL_TRACE) + do_syscall_trace(); __asm__ __volatile__( "move\t$29,%0\n\t" - "j\tret_from_sys_call" + "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ @@ -380,7 +288,7 @@ } #endif -asmlinkage int +asmlinkage int irix_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, void *trampoline) { @@ -408,7 +316,7 @@ * value for all invocations of sigaction. Will have to * investigate. POSIX POSIX, die die die... */ - new_ka.sa.sa_restorer = trampoline; + new_ka.sa_restorer = trampoline; } /* XXX Implement SIG_SETMASK32 for IRIX compatibility */ @@ -443,7 +351,7 @@ __copy_from_user(&newbits, new, sizeof(unsigned long)*4); sigdelsetmask(&newbits, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); oldbits = current->blocked; switch(how) { @@ -466,7 +374,7 @@ return -EINVAL; } recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); } if(old) { error = verify_area(VERIFY_WRITE, old, sizeof(*old)); @@ -487,11 +395,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); regs->regs[2] = -EINTR; while (1) { @@ -640,7 +548,9 @@ { int flag, retval; DECLARE_WAITQUEUE(wait, current); + struct task_struct *tsk; struct task_struct *p; + struct list_head *_p; if (!info) { retval = -EINVAL; @@ -667,7 +577,9 @@ flag = 0; current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock); - for (p = current->p_cptr; p; p = p->p_osptr) { + tsk = current; + list_for_each(_p,&tsk->children) { + p = list_entry(_p,struct task_struct,sibling); if ((type == P_PID) && p->pid != pid) continue; if ((type == P_PGID) && p->pgrp != pid) @@ -676,50 +588,63 @@ continue; flag = 1; switch (p->state) { - case TASK_STOPPED: - if (!p->exit_code) - continue; - if (!(options & (W_TRAPPED|W_STOPPED)) && - !(p->ptrace & PT_PTRACED)) - continue; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - __put_user(SIGCHLD, &info->sig); - __put_user(0, &info->code); - __put_user(p->pid, &info->stuff.procinfo.pid); - __put_user((p->exit_code >> 8) & 0xff, + case TASK_STOPPED: + if (!p->exit_code) + continue; + if (!(options & (W_TRAPPED|W_STOPPED)) && + !(p->ptrace & PT_PTRACED)) + continue; + read_unlock(&tasklist_lock); + + /* move to end of parent's list to avoid starvation */ + write_lock_irq(&tasklist_lock); + remove_parent(p); + add_parent(p, p->parent); + write_unlock_irq(&tasklist_lock); + retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0; + if (!retval && ru) { + retval |= __put_user(SIGCHLD, &info->sig); + retval |= __put_user(0, &info->code); + retval |= __put_user(p->pid, &info->stuff.procinfo.pid); + retval |= __put_user((p->exit_code >> 8) & 0xff, &info->stuff.procinfo.procdata.child.status); - __put_user(p->times.tms_utime, &info->stuff.procinfo.procdata.child.utime); - __put_user(p->times.tms_stime, &info->stuff.procinfo.procdata.child.stime); + retval |= __put_user(p->utime, &info->stuff.procinfo.procdata.child.utime); + retval |= __put_user(p->stime, &info->stuff.procinfo.procdata.child.stime); + } + if (!retval) { p->exit_code = 0; - retval = 0; - goto end_waitsys; - case TASK_ZOMBIE: - current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime; - current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime; - if (ru != NULL) - getrusage(p, RUSAGE_BOTH, ru); - __put_user(SIGCHLD, &info->sig); - __put_user(1, &info->code); /* CLD_EXITED */ - __put_user(p->pid, &info->stuff.procinfo.pid); - __put_user((p->exit_code >> 8) & 0xff, - &info->stuff.procinfo.procdata.child.status); - __put_user(p->times.tms_utime, - &info->stuff.procinfo.procdata.child.utime); - __put_user(p->times.tms_stime, - &info->stuff.procinfo.procdata.child.stime); - retval = 0; - if (p->p_opptr != p->p_pptr) { - REMOVE_LINKS(p); - p->p_pptr = p->p_opptr; - SET_LINKS(p); - notify_parent(p, SIGCHLD); - } else - release_task(p); - goto end_waitsys; - default: - continue; + } + goto end_waitsys; + + case TASK_ZOMBIE: + current->cutime += p->utime + p->cutime; + current->cstime += p->stime + p->cstime; + if (ru != NULL) + getrusage(p, RUSAGE_BOTH, ru); + __put_user(SIGCHLD, &info->sig); + __put_user(1, &info->code); /* CLD_EXITED */ + __put_user(p->pid, &info->stuff.procinfo.pid); + __put_user((p->exit_code >> 8) & 0xff, + &info->stuff.procinfo.procdata.child.status); + __put_user(p->utime, + &info->stuff.procinfo.procdata.child.utime); + __put_user(p->stime, + &info->stuff.procinfo.procdata.child.stime); + retval = 0; + if (p->real_parent != p->parent) { + write_lock_irq(&tasklist_lock); + remove_parent(p); + p->parent = p->real_parent; + add_parent(p, p->parent); + do_notify_parent(p, SIGCHLD); + write_unlock_irq(&tasklist_lock); + } else + release_task(p); + goto end_waitsys; + default: + continue; } + tsk = next_thread(tsk); } read_unlock(&tasklist_lock); if (flag) { diff -Nru a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c --- a/arch/mips/kernel/irq.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/kernel/irq.c Fri Jun 27 14:19:53 2003 @@ -8,18 +8,24 @@ * Copyright (C) 1992 Linus Torvalds * Copyright (C) 1994 - 2000 Ralf Baechle */ +#include <linux/config.h> #include <linux/kernel.h> -#include <linux/irq.h> +#include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/proc_fs.h> #include <linux/slab.h> #include <linux/mm.h> #include <linux/random.h> #include <linux/sched.h> #include <linux/seq_file.h> +#include <linux/kallsyms.h> +#include <asm/atomic.h> #include <asm/system.h> +#include <asm/uaccess.h> /* * Controller mappings for all interrupt sources: @@ -31,11 +37,14 @@ } }; +static void register_irq_proc (unsigned int irq); + /* * Special irq handlers. */ -void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } +irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) +{ return IRQ_NONE; } /* * Generic no controller code @@ -68,7 +77,7 @@ end_none }; -volatile unsigned long irq_err_count, spurious_count; +atomic_t irq_err_count; /* * Generic, controller-independent functions: @@ -76,35 +85,53 @@ int show_interrupts(struct seq_file *p, void *v) { + int i, j; struct irqaction * action; unsigned long flags; - int i; - - seq_puts(p, " "); - for (i=0; i < 1 /*smp_num_cpus*/; i++) - seq_printf(p, "CPU%d ", i); + + seq_printf(p, " "); + for (j=0; j<NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "CPU%d ",j); seq_putc(p, '\n'); for (i = 0 ; i < NR_IRQS ; i++) { spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) - goto unlock; + goto skip; seq_printf(p, "%3d: ",i); +#ifndef CONFIG_SMP seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); +#endif seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); + seq_putc(p, '\n'); -unlock: +skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); } - seq_printf(p, "ERR: %10lu\n", irq_err_count); + seq_putc(p, '\n'); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + return 0; } +#ifdef CONFIG_SMP +inline void synchronize_irq(unsigned int irq) +{ + while (irq_desc[irq].status & IRQ_INPROGRESS) + cpu_relax(); +} +#endif + /* * This should really return information about whether * we should do bottom half handling etc. Right now we @@ -114,37 +141,112 @@ */ int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) { - int status; - int cpu = smp_processor_id(); - - irq_enter(cpu, irq); - - status = 1; /* Force the "do bottom halves" bit */ + int status = 1; /* Force the "do bottom halves" bit */ + int retval = 0; if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); do { status |= action->flags; - action->handler(irq, action->dev_id, regs); + retval |= action->handler(irq, action->dev_id, regs); action = action->next; } while (action); if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); local_irq_disable(); - irq_exit(cpu, irq); + return retval; +} + +static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret) +{ + struct irqaction *action; + + if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) { + printk(KERN_ERR "irq event %d: bogus return value %x\n", + irq, action_ret); + } else { + printk(KERN_ERR "irq %d: nobody cared!\n", irq); + } + dump_stack(); + printk(KERN_ERR "handlers:\n"); + action = desc->action; + do { + printk(KERN_ERR "[<%p>]", action->handler); + print_symbol(" (%s)", + (unsigned long)action->handler); + printk("\n"); + action = action->next; + } while (action); +} + +static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret) +{ + static int count = 100; + + if (count) { + count--; + __report_bad_irq(irq, desc, action_ret); + } +} + +static int noirqdebug; - return status; +static int __init noirqdebug_setup(char *str) +{ + noirqdebug = 1; + printk("IRQ lockup detection disabled\n"); + return 1; +} + +__setup("noirqdebug", noirqdebug_setup); + +/* + * If 99,900 of the previous 100,000 interrupts have not been handled then + * assume that the IRQ is stuck in some manner. Drop a diagnostic and try to + * turn the IRQ off. + * + * (The other 100-of-100,000 interrupts may have been a correctly-functioning + * device sharing an IRQ with the failing one) + * + * Called under desc->lock + */ +static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret) +{ + if (action_ret != IRQ_HANDLED) { + desc->irqs_unhandled++; + if (action_ret != IRQ_NONE) + report_bad_irq(irq, desc, action_ret); + } + + desc->irq_count++; + if (desc->irq_count < 100000) + return; + + desc->irq_count = 0; + if (desc->irqs_unhandled > 99900) { + /* + * The interrupt is stuck + */ + __report_bad_irq(irq, desc, action_ret); + /* + * Now kill the IRQ + */ + printk(KERN_EMERG "Disabling IRQ #%d\n", irq); + desc->status |= IRQ_DISABLED; + desc->handler->disable(irq); + } + desc->irqs_unhandled = 0; } /* * Generic enable/disable code: this just calls * down into the PIC-specific version for the actual * hardware disable after having gotten the irq - * controller lock. + * controller lock. */ - + /** * disable_irq_nosync - disable an irq without waiting * @irq: Interrupt to disable @@ -155,7 +257,7 @@ * * This function may be called from IRQ context. */ - + void inline disable_irq_nosync(unsigned int irq) { irq_desc_t *desc = irq_desc + irq; @@ -181,16 +283,11 @@ * * This function may be called - with care - from IRQ context. */ - + void disable_irq(unsigned int irq) { disable_irq_nosync(irq); - - if (!local_irq_count(smp_processor_id())) { - do { - barrier(); - } while (irq_desc[irq].status & IRQ_INPROGRESS); - } + synchronize_irq(irq); } /** @@ -202,7 +299,7 @@ * * This function may be called from IRQ context. */ - + void enable_irq(unsigned int irq) { irq_desc_t *desc = irq_desc + irq; @@ -237,7 +334,7 @@ */ asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs) { - /* + /* * We ack quickly, we don't want the irq controller * thinking we're snobs just because some other CPU has * disabled global interrupts (we have already done the @@ -252,6 +349,7 @@ struct irqaction * action; unsigned int status; + irq_enter(); kstat_cpu(cpu).irqs[irq]++; spin_lock(&desc->lock); desc->handler->ack(irq); @@ -267,7 +365,7 @@ * use the action we have. */ action = NULL; - if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { action = desc->action; status &= ~IRQ_PENDING; /* we commit to handling */ status |= IRQ_INPROGRESS; /* we are handling it */ @@ -280,7 +378,7 @@ a different instance of this same irq, the other processor will take care of it. */ - if (!action) + if (unlikely(!action)) goto out; /* @@ -294,15 +392,19 @@ * SMP environment. */ for (;;) { + irqreturn_t action_ret; + spin_unlock(&desc->lock); - handle_IRQ_event(irq, regs, action); + action_ret = handle_IRQ_event(irq, ®s, action); spin_lock(&desc->lock); - - if (!(desc->status & IRQ_PENDING)) + if (!noirqdebug) + note_interrupt(irq, desc, action_ret); + if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; } desc->status &= ~IRQ_INPROGRESS; + out: /* * The ->end() handler has to deal with interrupts which got @@ -311,8 +413,8 @@ desc->handler->end(irq); spin_unlock(&desc->lock); - if (softirq_pending(cpu)) - do_softirq(); + irq_exit(); + return 1; } @@ -327,7 +429,7 @@ * This call allocates interrupt resources and enables the * interrupt line and IRQ handling. From the point this * call is made your handler function may be invoked. Since - * your handler function must clear any interrupt the board + * your handler function must clear any interrupt the board * raises, you must take care both to initialise your hardware * and to set up the interrupt handler in the right order. * @@ -347,10 +449,10 @@ * SA_SAMPLE_RANDOM The interrupt can be used for entropy * */ - -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, + +int request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, const char * devname, void *dev_id) { @@ -376,7 +478,7 @@ return -EINVAL; action = (struct irqaction *) - kmalloc(sizeof(struct irqaction), GFP_KERNEL); + kmalloc(sizeof(struct irqaction), GFP_ATOMIC); if (!action) return -ENOMEM; @@ -405,12 +507,9 @@ * does not return until any executing interrupts for this IRQ * have completed. * - * This function may be called from interrupt context. - * - * Bugs: Attempting to free an irq in a handler for the same irq hangs - * the machine. + * This function must not be called from interrupt context. */ - + void free_irq(unsigned int irq, void *dev_id) { irq_desc_t *desc; @@ -439,11 +538,8 @@ } spin_unlock_irqrestore(&desc->lock,flags); -#ifdef CONFIG_SMP /* Wait to make sure it's not being used on another CPU */ - while (desc->status & IRQ_INPROGRESS) - barrier(); -#endif + synchronize_irq(irq); kfree(action); return; } @@ -471,7 +567,7 @@ * and a mask of potential interrupt lines is returned. * */ - + unsigned long probe_irq_on(void) { unsigned int i; @@ -480,22 +576,22 @@ unsigned long delay; down(&probe_sem); - /* + /* * something may have generated an irq long ago and we want to - * flush such a longstanding irq before considering it as spurious. + * flush such a longstanding irq before considering it as spurious. */ for (i = NR_IRQS-1; i > 0; i--) { desc = irq_desc + i; spin_lock_irq(&desc->lock); - if (!irq_desc[i].action) + if (!irq_desc[i].action) irq_desc[i].handler->startup(i); spin_unlock_irq(&desc->lock); } /* Wait for longstanding interrupts to trigger. */ for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) - /* about 20ms delay */ synchronize_irq(); + /* about 20ms delay */ barrier(); /* * enable any unassigned irqs @@ -518,7 +614,7 @@ * Wait for spurious interrupts to trigger */ for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) - /* about 100ms delay */ synchronize_irq(); + /* about 100ms delay */ barrier(); /* * Now filter out any obviously spurious interrupts @@ -550,7 +646,7 @@ * Return a mask of triggered interrupts (this * can handle only legacy ISA interrupts). */ - + /** * probe_irq_mask - scan a bitmap of interrupt lines * @val: mask of interrupts to consider @@ -612,7 +708,7 @@ * nothing prevents two IRQ probe callers from overlapping. The * results of this are non-optimal. */ - + int probe_irq_off(unsigned long val) { int i, irq_found, nr_irqs; @@ -693,12 +789,12 @@ if (!shared) { desc->depth = 0; - desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); desc->handler->startup(irq); } spin_unlock_irqrestore(&desc->lock,flags); - /* register_irq_proc(irq); */ + register_irq_proc(irq); return 0; } @@ -712,4 +808,177 @@ irq_desc[i].depth = 1; irq_desc[i].handler = &no_irq_type; } +} + +EXPORT_SYMBOL(disable_irq_nosync); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(probe_irq_mask); + +static struct proc_dir_entry * root_irq_dir; +static struct proc_dir_entry * irq_dir [NR_IRQS]; + +#define HEX_DIGITS 8 + +static unsigned int parse_hex_value (const char *buffer, + unsigned long count, unsigned long *ret) +{ + unsigned char hexnum [HEX_DIGITS]; + unsigned long value; + int i; + + if (!count) + return -EINVAL; + if (count > HEX_DIGITS) + count = HEX_DIGITS; + if (copy_from_user(hexnum, buffer, count)) + return -EFAULT; + + /* + * Parse the first 8 characters as a hex string, any non-hex char + * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + */ + value = 0; + + for (i = 0; i < count; i++) { + unsigned int c = hexnum[i]; + + switch (c) { + case '0' ... '9': c -= '0'; break; + case 'a' ... 'f': c -= 'a'-10; break; + case 'A' ... 'F': c -= 'A'-10; break; + default: + goto out; + } + value = (value << 4) | c; + } +out: + *ret = value; + return 0; +} + +#ifdef CONFIG_SMP + +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; + +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static int irq_affinity_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + if (count < HEX_DIGITS+1) + return -EINVAL; + return sprintf (page, "%08lx\n", irq_affinity[(long)data]); +} + +static int irq_affinity_write_proc (struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int irq = (long) data, full_count = count, err; + unsigned long new_value; + + if (!irq_desc[irq].handler->set_affinity) + return -EIO; + + err = parse_hex_value(buffer, count, &new_value); + + /* + * Do not allow disabling IRQs completely - it's a too easy + * way to make the system unusable accidentally :-) At least + * one online CPU still has to be targeted. + */ + if (!(new_value & cpu_online_map)) + return -EINVAL; + + irq_affinity[irq] = new_value; + irq_desc[irq].handler->set_affinity(irq, new_value); + + return full_count; +} + +#endif + +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + unsigned long *mask = (unsigned long *) data; + if (count < HEX_DIGITS+1) + return -EINVAL; + return sprintf (page, "%08lx\n", *mask); +} + +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long *mask = (unsigned long *) data, full_count = count, err; + unsigned long new_value; + + err = parse_hex_value(buffer, count, &new_value); + if (err) + return err; + + *mask = new_value; + return full_count; +} + +#define MAX_NAMELEN 10 + +static void register_irq_proc (unsigned int irq) +{ + char name [MAX_NAMELEN]; + + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) || + irq_dir[irq]) + return; + + memset(name, 0, MAX_NAMELEN); + sprintf(name, "%d", irq); + + /* create /proc/irq/1234 */ + irq_dir[irq] = proc_mkdir(name, root_irq_dir); + +#ifdef CONFIG_SMP + { + struct proc_dir_entry *entry; + + /* create /proc/irq/1234/smp_affinity */ + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); + + if (entry) { + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + } + + smp_affinity_entry[irq] = entry; + } +#endif +} + +unsigned long prof_cpu_mask = -1; + +void init_irq_proc (void) +{ + struct proc_dir_entry *entry; + int i; + + /* create /proc/irq */ + root_irq_dir = proc_mkdir("irq", 0); + + /* create /proc/irq/prof_cpu_mask */ + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); + + if (!entry) + return; + + entry->nlink = 1; + entry->data = (void *)&prof_cpu_mask; + entry->read_proc = prof_cpu_mask_read_proc; + entry->write_proc = prof_cpu_mask_write_proc; + + /* + * Create entries for all existing IRQs. + */ + for (i = 0; i < NR_IRQS; i++) + register_irq_proc(i); } diff -Nru a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/kernel/irq_cpu.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,117 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2001 Ralf Baechle + * + * This file define the irq handler for MIPS CPU interrupts. + * + * 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. + */ + +/* + * Almost all MIPS CPUs define 8 interrupt sources. They are typically + * level triggered (i.e., cannot be cleared from CPU; must be cleared from + * device). The first two are software interrupts which we don't really + * use or support. The last one is usually the CPU timer interrupt if + * counter register is present or, for CPUs with an external FPU, by + * convention it's the FPU exception interrupt. + * + * Don't even think about using this on SMP. You have been warned. + * + * This file exports one global function: + * void mips_cpu_irq_init(int irq_base); + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> + +#include <asm/irq_cpu.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + +static int mips_cpu_irq_base; + +static inline void unmask_mips_irq(unsigned int irq) +{ + clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); + set_c0_status(0x100 << (irq - mips_cpu_irq_base)); +} + +static inline void mask_mips_irq(unsigned int irq) +{ + clear_c0_status(0x100 << (irq - mips_cpu_irq_base)); +} + +static inline void mips_cpu_irq_enable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + unmask_mips_irq(irq); + local_irq_restore(flags); +} + +static void mips_cpu_irq_disable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + mask_mips_irq(irq); + local_irq_restore(flags); +} + +static unsigned int mips_cpu_irq_startup(unsigned int irq) +{ + mips_cpu_irq_enable(irq); + + return 0; +} + +#define mips_cpu_irq_shutdown mips_cpu_irq_disable + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for mips_cpu_irq_end. + */ +static void mips_cpu_irq_ack(unsigned int irq) +{ + /* Only necessary for soft interrupts */ + clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8)); + + mask_mips_irq(irq); +} + +static void mips_cpu_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_mips_irq(irq); +} + +static hw_irq_controller mips_cpu_irq_controller = { + "MIPS", + mips_cpu_irq_startup, + mips_cpu_irq_shutdown, + mips_cpu_irq_enable, + mips_cpu_irq_disable, + mips_cpu_irq_ack, + mips_cpu_irq_end, + NULL /* no affinity stuff for UP */ +}; + +void __init mips_cpu_irq_init(int irq_base) +{ + int i; + + for (i = irq_base; i < irq_base + 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &mips_cpu_irq_controller; + } + + mips_cpu_irq_base = irq_base; +} diff -Nru a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c --- a/arch/mips/kernel/mips_ksyms.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/mips_ksyms.c Fri Jun 27 14:19:54 2003 @@ -12,9 +12,9 @@ #include <linux/string.h> #include <linux/mm.h> #include <linux/interrupt.h> -#include <asm/irq.h> #include <linux/in6.h> #include <linux/pci.h> +#include <linux/tty.h> #include <linux/ide.h> #include <asm/bootinfo.h> @@ -24,7 +24,7 @@ #include <asm/page.h> #include <asm/pgalloc.h> #include <asm/semaphore.h> -#include <asm/sgi/sgihpc.h> +#include <asm/softirq.h> #include <asm/uaccess.h> #ifdef CONFIG_BLK_DEV_FD #include <asm/floppy.h> @@ -41,7 +41,9 @@ extern long __strnlen_user_asm(const char *s); EXPORT_SYMBOL(mips_machtype); +#ifdef CONFIG_EISA EXPORT_SYMBOL(EISA_bus); +#endif /* * String functions @@ -58,11 +60,8 @@ EXPORT_SYMBOL_NOVERS(strnlen); EXPORT_SYMBOL_NOVERS(strrchr); EXPORT_SYMBOL_NOVERS(strstr); -EXPORT_SYMBOL_NOVERS(strsep); EXPORT_SYMBOL(_clear_page); -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(kernel_thread); /* @@ -77,15 +76,6 @@ EXPORT_SYMBOL_NOVERS(__strnlen_user_nocheck_asm); EXPORT_SYMBOL_NOVERS(__strnlen_user_asm); - -/* - * Functions to control caches. - */ -EXPORT_SYMBOL(_flush_page_to_ram); -EXPORT_SYMBOL(_flush_cache_all); -EXPORT_SYMBOL(_dma_cache_wback_inv); -EXPORT_SYMBOL(_dma_cache_inv); - EXPORT_SYMBOL(invalid_pte_table); /* @@ -97,32 +87,11 @@ EXPORT_SYMBOL(__up); /* - * Base address of ports for Intel style I/O. - */ -EXPORT_SYMBOL(mips_io_port_base); - -/* - * Architecture specific stuff. - */ -#ifdef CONFIG_MIPS_JAZZ -EXPORT_SYMBOL(vdma_alloc); -EXPORT_SYMBOL(vdma_free); -EXPORT_SYMBOL(vdma_log2phys); -#endif - -#ifdef CONFIG_SGI_IP22 -EXPORT_SYMBOL(hpc3c0); -#endif - -/* * Kernel hacking ... */ #include <asm/branch.h> #include <linux/sched.h> -int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)); -int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)); - #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif @@ -132,4 +101,3 @@ #endif EXPORT_SYMBOL(get_wchan); -EXPORT_SYMBOL(flush_tlb_page); diff -Nru a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/kernel/module.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,242 @@ +/* Kernel module help for MIPS. + Copyright (C) 2001 Rusty Russell. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include <linux/moduleloader.h> +#include <linux/elf.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/string.h> +#include <linux/kernel.h> + +struct mips_hi16 { + struct mips_hi16 *next; + Elf32_Addr *addr; + Elf32_Addr value; +}; + +static struct mips_hi16 *mips_hi16_list; + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(fmt , ...) +#endif + +void *module_alloc(unsigned long size) +{ + if (size == 0) + return NULL; + return vmalloc(size); +} + + +/* Free memory returned from module_alloc */ +void module_free(struct module *mod, void *module_region) +{ + vfree(module_region); + /* FIXME: If module_region == mod->init_region, trim exception + table entries. */ +} + +/* We don't need anything special. */ +long module_core_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + struct module *module) +{ + return module->core_size; +} + +long module_init_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + struct module *module) +{ + return module->init_size; +} + +int module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) +{ + return 0; +} + +int apply_relocate(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + unsigned int i; + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_offset; + Elf32_Sym *sym; + uint32_t *location; + Elf32_Addr v; + + DEBUGP("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { + /* This is where to make the change */ + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset + + rel[i].r_offset; + /* This is the symbol it is referring to */ + sym = (Elf32_Sym *)sechdrs[symindex].sh_offset + + ELF32_R_SYM(rel[i].r_info); + if (!sym->st_value) { + printk(KERN_WARNING "%s: Unknown symbol %s\n", + me->name, strtab + sym->st_name); + return -ENOENT; + } + + v = sym->st_value; + + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_MIPS_NONE: + break; + + case R_MIPS_32: + *location += v; + break; + + case R_MIPS_26: + if (v % 4) + printk(KERN_ERR + "module %s: dangerous relocation\n", + me->name); + return -ENOEXEC; + if ((v & 0xf0000000) != + (((unsigned long)location + 4) & 0xf0000000)) + printk(KERN_ERR + "module %s: relocation overflow\n", + me->name); + return -ENOEXEC; + *location = (*location & ~0x03ffffff) | + ((*location + (v >> 2)) & 0x03ffffff); + break; + + case R_MIPS_HI16: { + struct mips_hi16 *n; + + /* + * We cannot relocate this one now because we don't + * know the value of the carry we need to add. Save + * the information, and let LO16 do the actual + * relocation. + */ + n = (struct mips_hi16 *) kmalloc(sizeof *n, GFP_KERNEL); + n->addr = location; + n->value = v; + n->next = mips_hi16_list; + mips_hi16_list = n; + break; + } + + case R_MIPS_LO16: { + unsigned long insnlo = *location; + Elf32_Addr val, vallo; + + /* Sign extend the addend we extract from the lo insn. */ + vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; + + if (mips_hi16_list != NULL) { + struct mips_hi16 *l; + + l = mips_hi16_list; + while (l != NULL) { + struct mips_hi16 *next; + unsigned long insn; + + /* + * The value for the HI16 had best be + * the same. + */ + printk(KERN_ERR "module %s: dangerous " + "relocation\n", me->name); + return -ENOEXEC; + + /* + * Do the HI16 relocation. Note that + * we actually don't need to know + * anything about the LO16 itself, + * except where to find the low 16 bits + * of the addend needed by the LO16. + */ + insn = *l->addr; + val = ((insn & 0xffff) << 16) + vallo; + val += v; + + /* + * Account for the sign extension that + * will happen in the low bits. + */ + val = ((val >> 16) + ((val & 0x8000) != + 0)) & 0xffff; + + insn = (insn & ~0xffff) | val; + *l->addr = insn; + + next = l->next; + kfree(l); + l = next; + } + + mips_hi16_list = NULL; + } + + /* + * Ok, we're done with the HI16 relocs. Now deal with + * the LO16. + */ + val = v + vallo; + insnlo = (insnlo & ~0xffff) | (val & 0xffff); + *location = insnlo; + break; + } + + default: + printk(KERN_ERR "module %s: Unknown relocation: %u\n", + me->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } + } + return 0; +} + +int apply_relocate_add(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", + me->name); + return -ENOEXEC; +} + +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ +} diff -Nru a/arch/mips/kernel/offset.c b/arch/mips/kernel/offset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/kernel/offset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,207 @@ +/* + * offset.c: Calculate pt_regs and task_struct offsets. + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * + * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. + */ +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/interrupt.h> + +#include <asm/ptrace.h> +#include <asm/processor.h> + +#define text(t) __asm__("\n@@@" t) +#define _offset(type, member) (&(((type *)NULL)->member)) + +#define offset(string, ptr, member) \ + __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) +#define constant(string, member) \ + __asm__("\n@@@" string "%x0" : : "i" (member)) +#define size(string, size) \ + __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) +#define linefeed text("") + +void output_ptreg_defines(void) +{ + text("/* MIPS pt_regs offsets. */"); + offset("#define PT_R0 ", struct pt_regs, regs[0]); + offset("#define PT_R1 ", struct pt_regs, regs[1]); + offset("#define PT_R2 ", struct pt_regs, regs[2]); + offset("#define PT_R3 ", struct pt_regs, regs[3]); + offset("#define PT_R4 ", struct pt_regs, regs[4]); + offset("#define PT_R5 ", struct pt_regs, regs[5]); + offset("#define PT_R6 ", struct pt_regs, regs[6]); + offset("#define PT_R7 ", struct pt_regs, regs[7]); + offset("#define PT_R8 ", struct pt_regs, regs[8]); + offset("#define PT_R9 ", struct pt_regs, regs[9]); + offset("#define PT_R10 ", struct pt_regs, regs[10]); + offset("#define PT_R11 ", struct pt_regs, regs[11]); + offset("#define PT_R12 ", struct pt_regs, regs[12]); + offset("#define PT_R13 ", struct pt_regs, regs[13]); + offset("#define PT_R14 ", struct pt_regs, regs[14]); + offset("#define PT_R15 ", struct pt_regs, regs[15]); + offset("#define PT_R16 ", struct pt_regs, regs[16]); + offset("#define PT_R17 ", struct pt_regs, regs[17]); + offset("#define PT_R18 ", struct pt_regs, regs[18]); + offset("#define PT_R19 ", struct pt_regs, regs[19]); + offset("#define PT_R20 ", struct pt_regs, regs[20]); + offset("#define PT_R21 ", struct pt_regs, regs[21]); + offset("#define PT_R22 ", struct pt_regs, regs[22]); + offset("#define PT_R23 ", struct pt_regs, regs[23]); + offset("#define PT_R24 ", struct pt_regs, regs[24]); + offset("#define PT_R25 ", struct pt_regs, regs[25]); + offset("#define PT_R26 ", struct pt_regs, regs[26]); + offset("#define PT_R27 ", struct pt_regs, regs[27]); + offset("#define PT_R28 ", struct pt_regs, regs[28]); + offset("#define PT_R29 ", struct pt_regs, regs[29]); + offset("#define PT_R30 ", struct pt_regs, regs[30]); + offset("#define PT_R31 ", struct pt_regs, regs[31]); + offset("#define PT_LO ", struct pt_regs, lo); + offset("#define PT_HI ", struct pt_regs, hi); + offset("#define PT_EPC ", struct pt_regs, cp0_epc); + offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); + offset("#define PT_STATUS ", struct pt_regs, cp0_status); + offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); + size("#define PT_SIZE ", struct pt_regs); + linefeed; +} + +void output_task_defines(void) +{ + text("/* MIPS task_struct offsets. */"); + offset("#define TASK_STATE ", struct task_struct, state); + offset("#define TASK_THREAD_INFO ", struct task_struct, thread_info); + offset("#define TASK_FLAGS ", struct task_struct, flags); + offset("#define TASK_MM ", struct task_struct, mm); + offset("#define TASK_PID ", struct task_struct, pid); + size( "#define TASK_STRUCT_SIZE ", struct task_struct); + linefeed; +} + +void output_thread_info_defines(void) +{ + text("/* MIPS thread_info offsets. */"); + offset("#define TI_TASK ", struct thread_info, task); + offset("#define TI_EXEC_DOMAIN ", struct thread_info, exec_domain); + offset("#define TI_FLAGS ", struct thread_info, flags); + offset("#define TI_CPU ", struct thread_info, cpu); + offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count); + offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); + offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); + linefeed; +} + +void output_thread_defines(void) +{ + text("/* MIPS specific thread_struct offsets. */"); + offset("#define THREAD_REG16 ", struct task_struct, thread.reg16); + offset("#define THREAD_REG17 ", struct task_struct, thread.reg17); + offset("#define THREAD_REG18 ", struct task_struct, thread.reg18); + offset("#define THREAD_REG19 ", struct task_struct, thread.reg19); + offset("#define THREAD_REG20 ", struct task_struct, thread.reg20); + offset("#define THREAD_REG21 ", struct task_struct, thread.reg21); + offset("#define THREAD_REG22 ", struct task_struct, thread.reg22); + offset("#define THREAD_REG23 ", struct task_struct, thread.reg23); + offset("#define THREAD_REG29 ", struct task_struct, thread.reg29); + offset("#define THREAD_REG30 ", struct task_struct, thread.reg30); + offset("#define THREAD_REG31 ", struct task_struct, thread.reg31); + offset("#define THREAD_STATUS ", struct task_struct, \ + thread.cp0_status); + offset("#define THREAD_FPU ", struct task_struct, thread.fpu); + offset("#define THREAD_BVADDR ", struct task_struct, \ + thread.cp0_badvaddr); + offset("#define THREAD_BUADDR ", struct task_struct, \ + thread.cp0_baduaddr); + offset("#define THREAD_ECODE ", struct task_struct, \ + thread.error_code); + offset("#define THREAD_TRAPNO ", struct task_struct, thread.trap_no); + offset("#define THREAD_MFLAGS ", struct task_struct, thread.mflags); + offset("#define THREAD_TRAMP ", struct task_struct, \ + thread.irix_trampoline); + offset("#define THREAD_OLDCTX ", struct task_struct, \ + thread.irix_oldctx); + linefeed; +} + +void output_mm_defines(void) +{ + text("/* Linux mm_struct offsets. */"); + offset("#define MM_USERS ", struct mm_struct, mm_users); + offset("#define MM_PGD ", struct mm_struct, pgd); + offset("#define MM_CONTEXT ", struct mm_struct, context); + linefeed; + constant("#define _PAGE_SIZE ", PAGE_SIZE); + constant("#define _PGD_ORDER ", PGD_ORDER); + constant("#define _PGDIR_SHIFT ", PGDIR_SHIFT); + linefeed; +} + +void output_sc_defines(void) +{ + text("/* Linux sigcontext offsets. */"); + offset("#define SC_REGS ", struct sigcontext, sc_regs); + offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); + offset("#define SC_MDHI ", struct sigcontext, sc_mdhi); + offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); + offset("#define SC_PC ", struct sigcontext, sc_pc); + offset("#define SC_STATUS ", struct sigcontext, sc_status); + offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); + offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); + offset("#define SC_CAUSE ", struct sigcontext, sc_cause); + offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); + linefeed; +} + +void output_signal_defined(void) +{ + text("/* Linux signal numbers. */"); + constant("#define _SIGHUP ", SIGHUP); + constant("#define _SIGINT ", SIGINT); + constant("#define _SIGQUIT ", SIGQUIT); + constant("#define _SIGILL ", SIGILL); + constant("#define _SIGTRAP ", SIGTRAP); + constant("#define _SIGIOT ", SIGIOT); + constant("#define _SIGABRT ", SIGABRT); + constant("#define _SIGEMT ", SIGEMT); + constant("#define _SIGFPE ", SIGFPE); + constant("#define _SIGKILL ", SIGKILL); + constant("#define _SIGBUS ", SIGBUS); + constant("#define _SIGSEGV ", SIGSEGV); + constant("#define _SIGSYS ", SIGSYS); + constant("#define _SIGPIPE ", SIGPIPE); + constant("#define _SIGALRM ", SIGALRM); + constant("#define _SIGTERM ", SIGTERM); + constant("#define _SIGUSR1 ", SIGUSR1); + constant("#define _SIGUSR2 ", SIGUSR2); + constant("#define _SIGCHLD ", SIGCHLD); + constant("#define _SIGPWR ", SIGPWR); + constant("#define _SIGWINCH ", SIGWINCH); + constant("#define _SIGURG ", SIGURG); + constant("#define _SIGIO ", SIGIO); + constant("#define _SIGSTOP ", SIGSTOP); + constant("#define _SIGTSTP ", SIGTSTP); + constant("#define _SIGCONT ", SIGCONT); + constant("#define _SIGTTIN ", SIGTTIN); + constant("#define _SIGTTOU ", SIGTTOU); + constant("#define _SIGVTALRM ", SIGVTALRM); + constant("#define _SIGPROF ", SIGPROF); + constant("#define _SIGXCPU ", SIGXCPU); + constant("#define _SIGXFSZ ", SIGXFSZ); + linefeed; +} + +void output_irq_cpustat_t_defines(void) +{ + text("/* Linux irq_cpustat_t offsets. */"); + offset("#define IC_SOFTIRQ_PENDING ", irq_cpustat_t, __softirq_pending); + offset("#define IC_SYSCALL_COUNT ", irq_cpustat_t, __syscall_count); + offset("#define IC_KSOFTIRQD_TASK ", irq_cpustat_t, __ksoftirqd_task); + size("#define IC_IRQ_CPUSTAT_T ", irq_cpustat_t); + linefeed; +} diff -Nru a/arch/mips/kernel/old-irq.c b/arch/mips/kernel/old-irq.c --- a/arch/mips/kernel/old-irq.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,410 +0,0 @@ -/* - * 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. - * - * Code to handle x86 style IRQs plus some generic interrupt stuff. - * - * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994 - 2001 Ralf Baechle - * - * Old rotten IRQ code. To be killed as soon as everybody had converted or - * in 2.5.0, whatever comes first. - */ -#include <linux/config.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/module.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/seq_file.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/nile4.h> - -/* - * The board specific setup routine sets irq_setup to point to a board - * specific setup routine. - */ -void (*irq_setup)(void); - -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -/* - * This contains the irq mask for both 8259A irq controllers, it's an - * int so we can deal with the third PIC in some systems like the RM300. - * (XXX This is broken for big endian.) - */ -static unsigned int cached_irq_mask = 0xffff; - -#define __byte(x,y) (((unsigned char *)&(y))[x]) -#define __word(x,y) (((unsigned short *)&(y))[x]) -#define __long(x,y) (((unsigned int *)&(y))[x]) - -#define cached_21 (__byte(0,cached_irq_mask)) -#define cached_A1 (__byte(1,cached_irq_mask)) - -unsigned long spurious_count = 0; - -/* - * (un)mask_irq, disable_irq() and enable_irq() only handle (E)ISA and - * PCI devices. Other onboard hardware needs specific routines. - */ -static inline void mask_irq(unsigned int irq) -{ - cached_irq_mask |= 1 << irq; - if (irq & 8) { - outb(cached_A1, 0xa1); - } else { - outb(cached_21, 0x21); - } -} - -static inline void unmask_irq(unsigned int irq) -{ - cached_irq_mask &= ~(1 << irq); - if (irq & 8) { - outb(cached_A1, 0xa1); - } else { - outb(cached_21, 0x21); - } -} - -void i8259_disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - mask_irq(irq_nr); - restore_flags(flags); -} - -void i8259_enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - save_and_cli(flags); - unmask_irq(irq_nr); - restore_flags(flags); -} - -static struct irqaction *irq_action[NR_IRQS] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - struct irqaction * action; - unsigned long flags; - - for (i = 0 ; i < 32 ; i++) { - local_irq_save(flags); - action = irq_action[i]; - if (!action) - goto skip; - seq_printf(p, "%2d: %8d %c %s", - i, kstat_cpu(0).irqs[i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_putc(p, '\n'); -skip: - local_irq_restore(flags); - } - return 0; -} - -static inline void i8259_mask_and_ack_irq(int irq) -{ - cached_irq_mask |= 1 << irq; - - if (irq & 8) { - inb(0xa1); - outb(cached_A1, 0xa1); - outb(0x62, 0x20); /* Specific EOI to cascade */ - outb(0x20, 0xa0); - } else { - inb(0x21); - outb(cached_21, 0x21); - outb(0x20, 0x20); - } -} - -asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - - if (irq >= 16) - goto out; - - i8259_mask_and_ack_irq(irq); - - kstat_cpu(cpu).irqs[irq]++; - - action = *(irq + irq_action); - if (!action) - goto out; - - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - local_irq_disable(); - unmask_irq (irq); - -out: - irq_exit(cpu, irq); -} - -/* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. - */ -asmlinkage void do_IRQ(int irq, struct pt_regs * regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat_cpu(cpu).irqs[irq]++; - - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - local_irq_disable(); - } - irq_exit(cpu, irq); - - if (softirq_pending(cpu)) - do_softirq(); - - /* unmasking and bottom half handling is done magically for us. */ -} - -int i8259_setup_irq(int irq, struct irqaction * new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; - - p = irq_action + irq; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - return -EBUSY; - - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_and_cli(flags); - *p = new; - - if (!shared) { - if (is_i8259_irq(irq)) - unmask_irq(irq); -#if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476)) - else - nile4_enable_irq(irq_to_nile4(irq)); -#endif - } - restore_flags(flags); - return 0; -} - -/* - * Request_interrupt and free_interrupt ``sort of'' handle interrupts of - * non i8259 devices. They will have to be replaced by architecture - * specific variants. For now we still use this as broken as it is because - * it used to work ... - */ -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, void *dev_id) -{ - int retval; - struct irqaction * action; - - if (irq >= 32) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - retval = i8259_setup_irq(irq, action); - - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction * action, **p; - unsigned long flags; - - if (irq > 31) { - printk("Trying to free IRQ%d\n",irq); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - if (!irq[irq_action]) - mask_irq(irq); - restore_flags(flags); - kfree(action); - return; - } - printk("Trying to free free IRQ%d\n",irq); -} - -unsigned long probe_irq_on (void) -{ - unsigned int i, irqs = 0; - unsigned long delay; - - /* first, enable any unassigned (E)ISA irqs */ - for (i = 15; i > 0; i--) { - if (!irq_action[i]) { - i8259_enable_irq(i); - irqs |= (1 << i); - } - } - - /* wait for spurious interrupts to mask themselves out again */ - for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) - /* about 100ms delay */; - - /* now filter out any obviously spurious interrupts */ - return irqs & ~cached_irq_mask; -} - -int probe_irq_off (unsigned long irqs) -{ - unsigned int i; - -#ifdef DEBUG - printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask); -#endif - irqs &= cached_irq_mask; - if (!irqs) - return 0; - i = ffz(~irqs); - if (irqs != (irqs & (1 << i))) - i = -i; - return i; -} - -void __init i8259_init(void) -{ - /* Init master interrupt controller */ - outb(0x11, 0x20); /* Start init sequence */ - outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0x21); /* Select 8086 mode */ - outb(0xff, 0x21); /* Mask all */ - - /* Init slave interrupt controller */ - outb(0x11, 0xa0); /* Start init sequence */ - outb(0x08, 0xa1); /* Vector base */ - outb(0x02, 0xa1); /* edge triggered, Cascade (slave) on IRQ2 */ - outb(0x01, 0xa1); /* Select 8086 mode */ - outb(0xff, 0xa1); /* Mask all */ - - outb(cached_A1, 0xa1); - outb(cached_21, 0x21); -} - -void __init init_IRQ(void) -{ - /* i8259_init(); */ - irq_setup(); -} diff -Nru a/arch/mips/kernel/old-time.c b/arch/mips/kernel/old-time.c --- a/arch/mips/kernel/old-time.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,518 +0,0 @@ -/* - * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * Copyright (C) 1996 - 2000 Ralf Baechle - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * Don't use. Deprecated. Dead meat. - */ -#include <linux/config.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <linux/bcd.h> - -#include <asm/bootinfo.h> -#include <asm/cpu.h> -#include <asm/mipsregs.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/ddb5074.h> - -#include <linux/mc146818rtc.h> -#include <linux/timex.h> - -extern volatile unsigned long wall_jiffies; -unsigned long r4k_interval; -extern rwlock_t xtime_lock; - -/* - * Change this if you have some constant time drift - */ -/* This is the value for the PC-style PICs. */ -/* #define USECS_PER_JIFFY (1000020/HZ) */ - -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) - -/* Cycle counter value at the previous timer interrupt.. */ - -static unsigned int timerhi, timerlo; - -/* - * On MIPS only R4000 and better have a cycle counter. - * - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ -static unsigned long do_fast_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies; - unsigned long quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY) - :"$1"); - cached_quotient = quotient; - } - - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -/* This function must be called with interrupts disabled - * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs - * - * However, the pc-audio speaker driver changes the divisor so that - * it gets interrupted rather more often - it loads 64 into the - * counter rather than 11932! This has an adverse impact on - * do_gettimeoffset() -- it stops working! What is also not - * good is that the interval that our timer function gets called - * is no longer 10.0002 ms, but 9.9767 ms. To get around this - * would require using a different timing source. Maybe someone - * could use the RTC - I know that this can interrupt at frequencies - * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix - * it so that at startup, the timer code in sched.c would select - * using either the RTC or the 8253 timer. The decision would be - * based on whether there was any other device around that needed - * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz, - * and then do some jiggery to have a version of do_timer that - * advanced the clock by 1/1024 s. Every time that reached over 1/100 - * of a second, then do all the old code. If the time was kept correct - * then do_gettimeoffset could just return 0 - there is no low order - * divider that can be accessed. - * - * Ideally, you would be able to use the RTC for the speaker driver, - * but it appears that the speaker driver really needs interrupt more - * often than every 120 us or so. - * - * Anyway, this needs more thought.... pjsg (1993-08-28) - * - * If you are really that interested, you should be reading - * comp.protocols.time.ntp! - */ - -#define TICK_SIZE tick - -static unsigned long do_slow_gettimeoffset(void) -{ - int count; - - static int count_p = LATCH; /* for the first call after boot */ - static unsigned long jiffies_p; - - /* - * cache volatile jiffies temporarily; we have IRQs turned off. - */ - unsigned long jiffies_t; - - /* timer count may underflow right here */ - outb_p(0x00, 0x43); /* latch the count ASAP */ - - count = inb_p(0x40); /* read the latched count */ - - /* - * We do this guaranteed double memory access instead of a _p - * postfix in the previous port access. Wheee, hackady hack - */ - jiffies_t = jiffies; - - count |= inb_p(0x40) << 8; - - /* - * avoiding timer inconsistencies (they are rare, but they happen)... - * there are two kinds of problems that must be avoided here: - * 1. the timer counter underflows - * 2. hardware problem with the timer, not giving us continuous time, - * the counter does small "jumps" upwards on some Pentium systems, - * (see c't 95/10 page 335 for Neptun bug.) - */ - - if( jiffies_t == jiffies_p ) { - if( count > count_p ) { - /* the nutcase */ - - outb_p(0x0A, 0x20); - - /* assumption about timer being IRQ1 */ - if (inb(0x20) & 0x01) { - /* - * We cannot detect lost timer interrupts ... - * well, that's why we call them lost, don't we? :) - * [hmm, on the Pentium and Alpha we can ... sort of] - */ - count -= LATCH; - } else { - printk("do_slow_gettimeoffset(): hardware timer problem?\n"); - } - } - } else - jiffies_p = jiffies_t; - - count_p = count; - - count = ((LATCH-1) - count) * TICK_SIZE; - count = (count + LATCH/2) / LATCH; - - return count; -} - -static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; - -/* - * This version of gettimeofday has near microsecond resolution. - */ -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - - read_lock_irqsave (&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - read_unlock_irqrestore (&xtime_lock, flags); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } -} - -void do_settimeofday(struct timeval *tv) -{ - write_lock_irq (&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ - tv->tv_usec -= do_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; - - write_unlock_irq (&xtime_lock); -} - -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you won't notice until after reboot! - */ -static int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - -/* last time the cmos clock got updated */ -static long last_rtc_update; - -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ -static void inline -timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ -#ifdef CONFIG_DDB5074 - static unsigned cnt, period, dist; - - if (cnt == 0 || cnt == dist) - ddb5074_led_d2(1); - else if (cnt == 7 || cnt == dist+7) - ddb5074_led_d2(0); - - if (++cnt > period) { - cnt = 0; - /* The hyperbolic function below modifies the heartbeat period - * length in dependency of the current (5min) load. It goes - * through the points f(0)=126, f(1)=86, f(5)=51, - * f(inf)->30. */ - period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30; - dist = period / 4; - } -#endif - if(!user_mode(regs)) { - if (prof_buffer && current->pid) { - extern int _stext; - unsigned long pc = regs->cp0_epc; - - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - /* - * Dont ignore out-of-bounds pc values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - if (pc > prof_len-1) - pc = prof_len-1; - atomic_inc((atomic_t *)&prof_buffer[pc]); - } - } - do_timer(regs); - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - read_lock (&xtime_lock); - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && - xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } - /* As we return to user mode fire off the other CPU schedulers.. this is - basically because we don't yet share IRQ's around. This message is - rigged to be safe on the 386 - basically it's a hack, so don't look - closely for now.. */ - /*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */ - read_unlock (&xtime_lock); -} - -static inline void -r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - unsigned int count; - - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - -#ifdef CONFIG_SGI_IP22 - /* Since we don't get anything but r4k timer interrupts, we need to - * set this up so that we'll get one next time. Fortunately since we - * have timerhi/timerlo, we don't care so much if we miss one. So - * we need only ask for the next in r4k_interval counts. On other - * archs we have a real timer, so we don't want this. - */ - write_32bit_cp0_register (CP0_COMPARE, - (unsigned long) (count + r4k_interval)); - kstat_cpu(0).irqs[irq]++; -#endif - - timer_interrupt(irq, dev_id, regs); - - if (!jiffies) - { - /* - * If jiffies has overflowed in this timer_interrupt we must - * update the timer[hi]/[lo] to make do_fast_gettimeoffset() - * quotient calc still valid. -arca - */ - timerhi = timerlo = 0; - } -} - -void indy_r4k_timer_interrupt (struct pt_regs *regs) -{ - static const int INDY_R4K_TIMER_IRQ = 7; - int cpu = smp_processor_id(); - - r4k_timer_interrupt (INDY_R4K_TIMER_IRQ, NULL, regs); - - if (softirq_pending(cpu)) - do_softirq(); -} - -struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; - - -void (*board_time_init)(struct irqaction *irq); - -void __init time_init(void) -{ - unsigned int epoch = 0, year, mon, day, hour, min, sec; - int i; - - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || 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); - } - - /* Attempt to guess the epoch. This is the same heuristic as in rtc.c so - no stupid things will happen to timekeeping. Who knows, maybe Ultrix - also uses 1952 as epoch ... */ - if (year > 10 && year < 44) { - epoch = 1980; - } else if (year < 96) { - epoch = 1952; - } - year += epoch; - - write_lock_irq (&xtime_lock); - xtime.tv_sec = mktime(year, mon, day, hour, min, sec); - xtime.tv_usec = 0; - write_unlock_irq (&xtime_lock); - - if (mips_cpu.options & MIPS_CPU_COUNTER) { - write_32bit_cp0_register(CP0_COUNT, 0); - do_gettimeoffset = do_fast_gettimeoffset; - irq0.handler = r4k_timer_interrupt; - } - - board_time_init(&irq0); -} diff -Nru a/arch/mips/kernel/pci-dma.c b/arch/mips/kernel/pci-dma.c --- a/arch/mips/kernel/pci-dma.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips/kernel/pci-dma.c Fri Jun 27 14:19:58 2003 @@ -10,6 +10,7 @@ #include <linux/config.h> #include <linux/types.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/string.h> #include <linux/pci.h> @@ -20,18 +21,23 @@ { void *ret; int gfp = GFP_ATOMIC; + struct pci_bus *bus = NULL; +#ifdef CONFIG_ISA if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) gfp |= GFP_DMA; +#endif ret = (void *) __get_free_pages(gfp, get_order(size)); if (ret != NULL) { memset(ret, 0, size); -#ifndef CONFIG_COHERENT_IO + if (hwdev) + bus = hwdev->bus; + *dma_handle = bus_to_baddr(bus, __pa(ret)); +#ifdef CONFIG_NONCOHERENT_IO dma_cache_wback_inv((unsigned long) ret, size); - ret = KSEG1ADDR(ret); + ret = UNCAC_ADDR(ret); #endif - *dma_handle = virt_to_bus(ret); } return ret; @@ -42,8 +48,11 @@ { unsigned long addr = (unsigned long) vaddr; -#ifndef CONFIG_COHERENT_IO - addr = KSEG0ADDR(addr); +#ifdef CONFIG_NONCOHERENT_IO + addr = CAC_ADDR(addr); #endif free_pages(addr, get_order(size)); } + +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); diff -Nru a/arch/mips/kernel/pci.c b/arch/mips/kernel/pci.c --- a/arch/mips/kernel/pci.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,168 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net - * - * Modified to be mips generic, ppopov@mvista.com - * arch/mips/kernel/pci.c - * Common MIPS PCI routines. - * - * 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 contains common PCI routines meant to be shared for - * all MIPS machines. - * - * Strategies: - * - * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) - * TODO: this should be optional for some machines where they do have - * a real "pcibios" that does resource assignment. - * - * . We then use pci_scan_bus() to "discover" all the resources for - * later use by Linux. - * - * . We finally reply on a board supplied function, pcibios_fixup_irq(), to - * to assign the interrupts. We may use setup-irq.c under drivers/pci - * later. - * - * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), - * because we assume all PCI devices should have the resources correctly - * assigned and recorded. - * - * Limitations: - * - * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus - * into a contiguous range. - * - * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical - * address space. - * - * . In the case of IO space, it starts from 0, and the beginning address - * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. - * - * . These are the current MIPS limitations (by ioremap, etc). In the - * future, we may remove them. - * - * Credits: - * Most of the code are derived from the pci routines from PPC and Alpha, - * which were mostly writtne by - * Cort Dougan, cort@fsmlabs.com - * Matt Porter, mporter@mvista.com - * Dave Rusling david.rusling@reo.mts.dec.com - * David Mosberger davidm@cs.arizona.edu - */ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/pci.h> - -#include <asm/pci_channel.h> - -extern void pcibios_fixup(void); -extern void pcibios_fixup_irqs(void); - -struct pci_fixup pcibios_fixups[] = { - { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, - { 0 } -}; - -extern int pciauto_assign_resources(int busno, struct pci_channel * hose); - -void __init pcibios_init(void) -{ - struct pci_channel *p; - struct pci_bus *bus; - int busno; - -#ifdef CONFIG_PCI_AUTO - /* assign resources */ - busno=0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - busno = pciauto_assign_resources(busno, p) + 1; - } -#endif - - /* scan the buses */ - busno = 0; - for (p= mips_pci_channels; p->pci_ops != NULL; p++) { - bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate+1; - } - - /* machine dependent fixups */ - pcibios_fixup(); - /* fixup irqs (board specific routines) */ - pcibios_fixup_irqs(); -} - -int pcibios_enable_device(struct pci_dev *dev) -{ - /* pciauto_assign_resources() will enable all devices found */ - return 0; -} - -unsigned long __init pci_bridge_check_io(struct pci_dev *bridge) -{ - u16 io; - - pci_read_config_word(bridge, PCI_IO_BASE, &io); - if (!io) { - pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); - pci_read_config_word(bridge, PCI_IO_BASE, &io); - pci_write_config_word(bridge, PCI_IO_BASE, 0x0); - } - if (io) - return IORESOURCE_IO; - printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", - bridge->name); - return 0; -} - -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - /* Propogate hose info into the subordinate devices. */ - - struct pci_channel *hose = bus->sysdata; - struct pci_dev *dev = bus->self; - - if (!dev) { - /* Root bus */ - bus->resource[0] = hose->io_resource; - bus->resource[1] = hose->mem_resource; - } else { - /* This is a bridge. Do not care how it's initialized, - just link its resources to the bus ones */ - int i; - - for(i=0; i<3; i++) { - bus->resource[i] = - &dev->resource[PCI_BRIDGE_RESOURCES+i]; - bus->resource[i]->name = bus->name; - } - bus->resource[0]->flags |= pci_bridge_check_io(dev); - bus->resource[1]->flags |= IORESOURCE_MEM; - /* For now, propagate hose limits to the bus; - we'll adjust them later. */ - bus->resource[0]->end = hose->io_resource->end; - bus->resource[1]->end = hose->mem_resource->end; - /* Turn off downstream PF memory address range by default */ - bus->resource[2]->start = 1024*1024; - bus->resource[2]->end = bus->resource[2]->start - 1; - } -} - -char *pcibios_setup(char *str) -{ - return str; -} - -void -pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ - /* this should not be called */ -} diff -Nru a/arch/mips/kernel/pci_auto.c b/arch/mips/kernel/pci_auto.c --- a/arch/mips/kernel/pci_auto.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,323 +0,0 @@ -/* - * PCI autoconfiguration library - * - * Author: Matt Porter <mporter@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. - */ - -/* - * Modified for MIPS by Jun Sun, jsun@mvista.com - * - * . Simplify the interface between pci_auto and the rest: a single function. - * . Assign resources from low address to upper address. - * . change most int to u32. - * - * Further modified to include it as mips generic code, ppopov@mvista.com. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/types.h> -#include <linux/pci.h> - -#include <asm/pci_channel.h> - -#define DEBUG -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* These are used for config access before all the PCI probing has been done. */ -int early_read_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 *val); -int early_read_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 *val); -int early_read_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 *val); -int early_write_config_byte(struct pci_channel *hose, int bus, int dev_fn, int where, u8 val); -int early_write_config_word(struct pci_channel *hose, int bus, int dev_fn, int where, u16 val); -int early_write_config_dword(struct pci_channel *hose, int bus, int dev_fn, int where, u32 val); - -static u32 pciauto_lower_iospc; -static u32 pciauto_upper_iospc; - -static u32 pciauto_lower_memspc; -static u32 pciauto_upper_memspc; - -void __init -pciauto_setup_bars(struct pci_channel *hose, - int current_bus, - int pci_devfn) -{ - u32 bar_response, bar_size, bar_value; - u32 bar, addr_mask, bar_nr = 0; - u32 * upper_limit; - u32 * lower_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; - lower_limit = &pciauto_lower_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; - lower_limit = &pciauto_lower_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 = ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; - - /* Write it out and update our limit */ - early_write_config_dword(hose, current_bus, pci_devfn, - bar, bar_value); - - *lower_limit = bar_value + bar_size; - - /* - * 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 __init -pciauto_prescan_setup_bridge(struct pci_channel *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 __init -pciauto_postscan_setup_bridge(struct pci_channel *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); -} - -#define PCIAUTO_IDE_MODE_MASK 0x05 - -int __init -pciauto_bus_scan(struct pci_channel *hose, int current_bus) -{ - int sub_bus; - u32 pci_devfn, pci_class, cmdstat, found_multi=0; - unsigned short vid; - unsigned char header_type; - int devfn_start = 0; - int devfn_stop = 0xff; - - sub_bus = current_bus; - - if (hose->first_devfn) - devfn_start = hose->first_devfn; - if (hose->last_devfn) - devfn_stop = hose->last_devfn; - - for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { - - 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) continue; - - 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; -} - -int __init -pciauto_assign_resources(int busno, struct pci_channel *hose) -{ - /* setup resource limits */ - pciauto_lower_iospc = hose->io_resource->start; - pciauto_upper_iospc = hose->io_resource->end + 1; - pciauto_lower_memspc = hose->mem_resource->start; - pciauto_upper_memspc = hose->mem_resource->end + 1; - - return pciauto_bus_scan(hose, busno); -} - - -/* - * These functions are used early on before PCI scanning is done - * and all of the pci_dev and pci_bus structures have been created. - */ -static struct pci_dev *fake_pci_dev(struct pci_channel *hose, int busnr, - int devfn) -{ - static struct pci_dev dev; - static struct pci_bus bus; - - dev.bus = &bus; - dev.sysdata = hose; - dev.devfn = devfn; - bus.number = busnr; - bus.ops = hose->pci_ops; - - return &dev; -} - -#define EARLY_PCI_OP(rw, size, type) \ -int early_##rw##_config_##size(struct pci_channel *hose, int bus, \ - int devfn, int offset, type value) \ -{ \ - return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \ - offset, value); \ -} - -EARLY_PCI_OP(read, byte, u8 *) -EARLY_PCI_OP(read, word, u16 *) -EARLY_PCI_OP(read, dword, u32 *) -EARLY_PCI_OP(write, byte, u8) -EARLY_PCI_OP(write, word, u16) -EARLY_PCI_OP(write, dword, u32) diff -Nru a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c --- a/arch/mips/kernel/proc.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/proc.c Fri Jun 27 14:19:54 2003 @@ -8,102 +8,136 @@ #include <linux/delay.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/seq_file.h> #include <asm/bootinfo.h> #include <asm/cpu.h> #include <asm/mipsregs.h> #include <asm/processor.h> #include <asm/watch.h> -extern unsigned long unaligned_instructions; unsigned int vced_count, vcei_count; -#ifndef CONFIG_CPU_HAS_LLSC -unsigned long ll_ops, sc_ops; -#endif -/* - * BUFFER is PAGE_SIZE bytes long. - * - * Currently /proc/cpuinfo is being abused to print data about the - * number of date/instruction cacheflushes. - */ -int get_cpuinfo(char *buffer) +static const char *cpu_name[] = { + [CPU_UNKNOWN] "unknown", + [CPU_R2000] "R2000", + [CPU_R3000] "R3000", + [CPU_R3000A] "R3000A", + [CPU_R3041] "R3041", + [CPU_R3051] "R3051", + [CPU_R3052] "R3052", + [CPU_R3081] "R3081", + [CPU_R3081E] "R3081E", + [CPU_R4000PC] "R4000PC", + [CPU_R4000SC] "R4000SC", + [CPU_R4000MC] "R4000MC", + [CPU_R4200] "R4200", + [CPU_R4400PC] "R4400PC", + [CPU_R4400SC] "R4400SC", + [CPU_R4400MC] "R4400MC", + [CPU_R4600] "R4600", + [CPU_R6000] "R6000", + [CPU_R6000A] "R6000A", + [CPU_R8000] "R8000", + [CPU_R10000] "R10000", + [CPU_R4300] "R4300", + [CPU_R4650] "R4650", + [CPU_R4700] "R4700", + [CPU_R5000] "R5000", + [CPU_R5000A] "R5000A", + [CPU_R4640] "R4640", + [CPU_NEVADA] "Nevada", + [CPU_RM7000] "RM7000", + [CPU_R5432] "R5432", + [CPU_4KC] "MIPS 4Kc", + [CPU_5KC] "MIPS 5Kc", + [CPU_R4310] "R4310", + [CPU_SB1] "SiByte SB1", + [CPU_TX3912] "TX3912", + [CPU_TX3922] "TX3922", + [CPU_TX3927] "TX3927", + [CPU_AU1000] "Au1000", + [CPU_AU1500] "Au1500", + [CPU_4KEC] "MIPS 4KEc", + [CPU_4KSC] "MIPS 4KSc", + [CPU_VR41XX] "NEC Vr41xx", + [CPU_R5500] "R5500", + [CPU_TX49XX] "TX49xx", + [CPU_20KC] "MIPS 20Kc", + [CPU_VR4111] "NEC VR4111", + [CPU_VR4121] "NEC VR4121", + [CPU_VR4122] "NEC VR4122", + [CPU_VR4131] "NEC VR4131", + [CPU_VR4181] "NEC VR4181", + [CPU_VR4181A] "NEC VR4181A", + [CPU_SR71000] "Sandcraft SR71000" +}; + + +static int show_cpuinfo(struct seq_file *m, void *v) { + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; + unsigned long n = (unsigned long) v - 1; char fmt [64]; - const char *cpu_name[] = CPU_NAMES; - const char *mach_group_names[] = GROUP_NAMES; - const char *mach_unknown_names[] = GROUP_UNKNOWN_NAMES; - const char *mach_jazz_names[] = GROUP_JAZZ_NAMES; - const char *mach_dec_names[] = GROUP_DEC_NAMES; - const char *mach_arc_names[] = GROUP_ARC_NAMES; - const char *mach_sni_rm_names[] = GROUP_SNI_RM_NAMES; - const char *mach_acn_names[] = GROUP_ACN_NAMES; - const char *mach_sgi_names[] = GROUP_SGI_NAMES; - const char *mach_cobalt_names[] = GROUP_COBALT_NAMES; - const char *mach_nec_ddb_names[] = GROUP_NEC_DDB_NAMES; - const char *mach_baget_names[] = GROUP_BAGET_NAMES; - const char *mach_cosine_names[] = GROUP_COSINE_NAMES; - const char *mach_galileo_names[] = GROUP_GALILEO_NAMES; - const char *mach_momenco_names[] = GROUP_MOMENCO_NAMES; - const char *mach_ite_names[] = GROUP_ITE_NAMES; - const char *mach_philips_names[] = GROUP_PHILIPS_NAMES; - const char *mach_globespan_names[] = GROUP_GLOBESPAN_NAMES; - const char *mach_sibyte_names[] = GROUP_SIBYTE_NAMES; - const char *mach_toshiba_names[] = GROUP_TOSHIBA_NAMES; - const char *mach_alchemy_names[] = GROUP_ALCHEMY_NAMES; - const char **mach_group_to_name[] = { mach_unknown_names, - mach_jazz_names, mach_dec_names, mach_arc_names, - mach_sni_rm_names, mach_acn_names, mach_sgi_names, - mach_cobalt_names, mach_nec_ddb_names, mach_baget_names, - mach_cosine_names, mach_galileo_names, mach_momenco_names, - mach_ite_names, mach_philips_names, mach_globespan_names, - mach_sibyte_names, mach_toshiba_names, mach_alchemy_names}; - unsigned int version = read_32bit_cp0_register(CP0_PRID); - int len; - - len = sprintf(buffer, "cpu\t\t\t: MIPS\n"); - len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n", - cpu_name[mips_cpu.cputype <= CPU_LAST ? - mips_cpu.cputype : CPU_UNKNOWN], - (version >> 4) & 0x0f, version & 0x0f); - len += sprintf(buffer + len, "system type\t\t: %s %s\n", - mach_group_names[mips_machgroup], - mach_group_to_name[mips_machgroup][mips_machtype]); - len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n", - loops_per_jiffy/(500000/HZ), - (loops_per_jiffy/(5000/HZ)) % 100); -#if defined (__MIPSEB__) - len += sprintf(buffer + len, "byteorder\t\t: big endian\n"); -#endif -#if defined (__MIPSEL__) - len += sprintf(buffer + len, "byteorder\t\t: little endian\n"); +#ifdef CONFIG_SMP + if (!CPUMASK_TSTB(cpu_online_map, n)) + return 0; #endif - len += sprintf(buffer + len, "unaligned accesses\t: %lu\n", - unaligned_instructions); - len += sprintf(buffer + len, "wait instruction\t: %s\n", - cpu_wait ? "yes" : "no"); - len += sprintf(buffer + len, "microsecond timers\t: %s\n", - (mips_cpu.options & MIPS_CPU_COUNTER) ? "yes" : "no"); - len += sprintf(buffer + len, "extra interrupt vector\t: %s\n", - (mips_cpu.options & MIPS_CPU_DIVEC) ? "yes" : "no"); - len += sprintf(buffer + len, "hardware watchpoint\t: %s\n", - watch_available ? "yes" : "no"); + + /* + * For the first processor also print the system type + */ + if (n == 0) + seq_printf(m, "system type\t\t: %s\n", get_system_type()); + + seq_printf(m, "processor\t\t: %ld\n", n); + sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], + (version >> 4) & 0x0f, version & 0x0f, + (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); + seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", + loops_per_jiffy / (500000/HZ), + (loops_per_jiffy / (5000/HZ)) % 100); + seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); + seq_printf(m, "microsecond timers\t: %s\n", + cpu_has_counter ? "yes" : "no"); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); + seq_printf(m, "extra interrupt vector\t: %s\n", + cpu_has_divec ? "yes" : "no"); + seq_printf(m, "hardware watchpoint\t: %s\n", + cpu_has_watch ? "yes" : "no"); sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", - (mips_cpu.options & MIPS_CPU_VCE) ? "%d" : "not available"); - len += sprintf(buffer + len, fmt, 'D', vced_count); - len += sprintf(buffer + len, fmt, 'I', vcei_count); - -#ifndef CONFIG_CPU_HAS_LLSC - len += sprintf(buffer + len, "ll emulations\t\t: %lu\n", - ll_ops); - len += sprintf(buffer + len, "sc emulations\t\t: %lu\n", - sc_ops); -#endif - return len; + cpu_has_vce ? "%d" : "not available"); + seq_printf(m, fmt, 'D', vced_count); + seq_printf(m, fmt, 'I', vcei_count); + + return 0; } -void init_irq_proc(void) +static void *c_start(struct seq_file *m, loff_t *pos) { - /* Nothing, for now. */ + unsigned long i = *pos; + + return i < NR_CPUS ? (void *) (i + 1) : NULL; } + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; diff -Nru a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c --- a/arch/mips/kernel/process.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/kernel/process.c Fri Jun 27 14:19:55 2003 @@ -6,86 +6,95 @@ * Copyright (C) 1994 - 2000 by Ralf Baechle and others. * Copyright (C) 1999 Silicon Graphics, Inc. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/stddef.h> #include <linux/unistd.h> -#include <linux/ptrace.h> +#include <linux/personality.h> #include <linux/slab.h> #include <linux/mman.h> #include <linux/sys.h> #include <linux/user.h> #include <linux/a.out.h> +#include <linux/init.h> +#include <linux/completion.h> #include <asm/bootinfo.h> #include <asm/cpu.h> +#include <asm/fpu.h> #include <asm/pgtable.h> #include <asm/system.h> #include <asm/mipsregs.h> #include <asm/processor.h> -#include <asm/stackframe.h> +#include <asm/ptrace.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/elf.h> #include <asm/isadep.h> +#include <asm/inst.h> -void cpu_idle(void) +/* + * We use this if we don't have any better idle routine.. + * (This to kill: kernel/platform.c. + */ +void default_idle (void) +{ +} + +/* + * The idle thread. There's no useful work to be done, so just try to conserve + * power and have a low exit latency (ie sit in a loop waiting for somebody to + * say that they'd like to reschedule) + */ +ATTRIB_NORET void cpu_idle(void) { /* endless idle loop with no priority at all */ - current->nice = 20; - init_idle(); while (1) { while (!need_resched()) if (cpu_wait) (*cpu_wait)(); schedule(); - check_pgt_cache(); } } -struct task_struct *last_task_used_math = NULL; - asmlinkage void ret_from_fork(void); +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + regs->cp0_status &= ~(ST0_CU0|ST0_KSU|ST0_CU1); + regs->cp0_status |= KU_USER; + current->used_math = 0; + loose_fpu(); + regs->cp0_epc = pc; + regs->regs[29] = sp; + current_thread_info()->addr_limit = USER_DS; +} + void exit_thread(void) { - /* Forget lazy fpu state */ - if (last_task_used_math == current) { - set_cp0_status(ST0_CU1); - __asm__ __volatile__("cfc1\t$0,$31"); - last_task_used_math = NULL; - } } void flush_thread(void) { - /* Forget lazy fpu state */ - if (last_task_used_math == current) { - set_cp0_status(ST0_CU1); - __asm__ __volatile__("cfc1\t$0,$31"); - last_task_used_math = NULL; - } } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct * p, struct pt_regs * regs) { + struct thread_info *ti = p->thread_info; struct pt_regs * childregs; long childksp; - extern void save_fp(void*); - childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; + childksp = (unsigned long)ti + KERNEL_STACK_SIZE - 32; + + if (is_fpu_owner()) { + save_fp(p); + } - if (last_task_used_math == current) - if (mips_cpu.options & MIPS_CPU_FPU) { - set_cp0_status(ST0_CU1); - save_fp(p); - } /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; @@ -101,12 +110,12 @@ regs->regs[3] = 0; } if (childregs->cp0_status & ST0_CU0) { - childregs->regs[28] = (unsigned long) p; + childregs->regs[28] = (unsigned long) ti; childregs->regs[29] = childksp; - p->thread.current_ds = KERNEL_DS; + ti->addr_limit = KERNEL_DS; } else { childregs->regs[29] = usp; - p->thread.current_ds = USER_DS; + ti->addr_limit = USER_DS; } p->thread.reg29 = (unsigned long) childregs; p->thread.reg31 = (unsigned long) ret_from_fork; @@ -115,9 +124,10 @@ * New tasks lose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ - p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1|KU_MASK); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); + p->set_child_tid = p->clear_child_tid = NULL; return 0; } @@ -125,29 +135,8 @@ /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if(regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - return 0; /* Task didn't use the fpu at all. */ -} - -/* Fill in the user structure for a core dump.. */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; - dump->start_data = current->mm->start_data; - dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - dump->start_code) >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) >> PAGE_SHIFT; - dump->u_ssize = - (current->mm->start_stack - dump->start_stack + PAGE_SIZE - 1) >> PAGE_SHIFT; - memcpy(&dump->regs[0], regs, sizeof(struct pt_regs)); - memcpy(&dump->regs[EF_SIZE/4], ¤t->thread.fpu, sizeof(current->thread.fpu)); + memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } /* @@ -158,35 +147,107 @@ long retval; __asm__ __volatile__( - ".set noreorder \n" - " move $6,$sp \n" - " move $4,%5 \n" - " li $2,%1 \n" - " syscall \n" - " beq $6,$sp,1f \n" - " subu $sp,32 \n" /* delay slot */ - " jalr %4 \n" - " move $4,%3 \n" /* delay slot */ - " move $4,$2 \n" - " li $2,%2 \n" - " syscall \n" - "1: addiu $sp,32 \n" - " move %0,$2 \n" - ".set reorder" - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), - "r" (arg), "r" (fn), - "r" (flags | CLONE_VM | CLONE_UNTRACED) + " .set noreorder \n" + " move $6, $sp \n" + " move $4, %5 \n" + " li $2, %1 \n" + " syscall \n" + " beq $6, $sp, 1f \n" + " subu $sp, 32 \n" + " jalr %4 \n" + " move $4, %3 \n" + " move $4, $2 \n" + " li $2, %2 \n" + " syscall \n" + "1: addiu $sp, 32 \n" + " move %0, $2 \n" + " .set reorder" + : "=r" (retval) + : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), + "r" (flags | CLONE_VM | CLONE_UNTRACED) /* * The called subroutine might have destroyed any of the * at, result, argument or temporary registers ... */ - :"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9","$10","$11","$12","$13","$14","$15","$24","$25", "$31"); return retval; } +struct mips_frame_info { + int frame_offset; + int pc_offset; +}; +static struct mips_frame_info schedule_frame; +static struct mips_frame_info schedule_timeout_frame; +static struct mips_frame_info sleep_on_frame; +static struct mips_frame_info sleep_on_timeout_frame; +static struct mips_frame_info wait_for_completion_frame; +static int mips_frame_info_initialized; +static int __init get_frame_info(struct mips_frame_info *info, void *func) +{ + int i; + union mips_instruction *ip = (union mips_instruction *)func; + info->pc_offset = -1; + info->frame_offset = -1; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; + if (ip->i_format.opcode == sw_op && + ip->i_format.rs == 29) { + /* sw $ra, offset($sp) */ + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + break; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sw $s8, offset($sp) */ + if (ip->i_format.rt == 30) { + if (info->frame_offset != -1) + break; + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } + } + } + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_offset = -1; + return -1; + } + + return 0; +} +void __init frame_info_init(void) +{ + mips_frame_info_initialized = + !get_frame_info(&schedule_frame, schedule) && + !get_frame_info(&schedule_timeout_frame, schedule_timeout) && + !get_frame_info(&sleep_on_frame, sleep_on) && + !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && + !get_frame_info(&wait_for_completion_frame, wait_for_completion); +} + +unsigned long thread_saved_pc(struct thread_struct *t) +{ + extern void ret_from_fork(void); + + /* New born processes are a special case */ + if (t->reg31 == (unsigned long) ret_from_fork) + return t->reg31; + + if (schedule_frame.pc_offset < 0) + return 0; + return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; +} + /* * These bracket the sleeping functions.. */ @@ -195,7 +256,7 @@ #define first_sched ((unsigned long) scheduling_functions_start_here) #define last_sched ((unsigned long) scheduling_functions_end_here) -/* get_wchan - a maintenance nightmare ... */ +/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { unsigned long frame, pc; @@ -203,6 +264,8 @@ if (!p || p == current || p->state == TASK_RUNNING) return 0; + if (!mips_frame_info_initialized) + return 0; pc = thread_saved_pc(&p->thread); if (pc < first_sched || pc >= last_sched) { return pc; @@ -216,26 +279,33 @@ goto schedule_timeout_caller; if (pc >= (unsigned long)interruptible_sleep_on) goto schedule_caller; + if (pc >= (unsigned long)wait_for_completion) + goto schedule_caller; goto schedule_timeout_caller; schedule_caller: - frame = ((unsigned long *)p->thread.reg30)[9]; - pc = ((unsigned long *)frame)[11]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + if (pc >= (unsigned long) sleep_on) + pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; + else + pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; return pc; schedule_timeout_caller: - /* Must be schedule_timeout ... */ - pc = ((unsigned long *)p->thread.reg30)[10]; - frame = ((unsigned long *)p->thread.reg30)[9]; - - /* The schedule_timeout frame ... */ - pc = ((unsigned long *)frame)[14]; - frame = ((unsigned long *)frame)[13]; + /* + * The schedule_timeout frame + */ + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + + /* + * frame now points to sleep_on_timeout's frame + */ + pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; if (pc >= first_sched && pc < last_sched) { - /* schedule_timeout called by interruptible_sleep_on_timeout */ - pc = ((unsigned long *)frame)[11]; - frame = ((unsigned long *)frame)[10]; + /* schedule_timeout called by [interruptible_]sleep_on_timeout */ + frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; + pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; } return pc; diff -Nru a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c --- a/arch/mips/kernel/ptrace.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/kernel/ptrace.c Fri Jun 27 14:20:06 2003 @@ -11,6 +11,7 @@ * Copyright (C) 1999 MIPS Technologies, Inc. */ #include <linux/config.h> +#include <linux/compiler.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> @@ -19,8 +20,8 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/user.h> +#include <linux/security.h> -#include <asm/fp.h> #include <asm/mipsregs.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -28,6 +29,7 @@ #include <asm/uaccess.h> #include <asm/bootinfo.h> #include <asm/cpu.h> +#include <asm/fpu.h> /* * Called by kernel/ptrace.c when detaching.. @@ -42,27 +44,27 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; - int res; - extern void save_fp(struct task_struct *); + int ret; - lock_kernel(); #if 0 printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n", (int) request, (int) pid, (unsigned long) addr, (unsigned long) data); #endif + lock_kernel(); + ret = -EPERM; if (request == PTRACE_TRACEME) { /* are we already being traced? */ - if (current->ptrace & PT_PTRACED) { - res = -EPERM; + if (current->ptrace & PT_PTRACED) + goto out; + if ((ret = security_ptrace(current->parent, current))) goto out; - } /* set the ptrace bit in the process flags. */ current->ptrace |= PT_PTRACED; - res = 0; + ret = 0; goto out; } - res = -ESRCH; + ret = -ESRCH; read_lock(&tasklist_lock); child = find_task_by_pid(pid); if (child) @@ -71,36 +73,31 @@ if (!child) goto out; - res = -EPERM; + ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { - res = ptrace_attach(child); - goto out_tsk; - } - res = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) + ret = ptrace_attach(child); goto out_tsk; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out_tsk; } - if (child->p_pptr != current) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; + switch (request) { - case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp; int copied; copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); - res = -EIO; + ret = -EIO; if (copied != sizeof(tmp)) break; - res = put_user(tmp,(unsigned long *) data); - - goto out; + ret = put_user(tmp,(unsigned long *) data); + break; } /* Read the word at location addr in the USER area. */ @@ -108,7 +105,7 @@ struct pt_regs *regs; unsigned long tmp; - regs = (struct pt_regs *) ((unsigned long) child + + regs = (struct pt_regs *) ((unsigned long) child->thread_info + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); tmp = 0; /* Default return value. */ @@ -118,30 +115,12 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; - if(!(mips_cpu.options & MIPS_CPU_FPU)) { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } else - if (last_task_used_math == child) { - enable_cp1(); - save_fp(child); - disable_cp1(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } + unsigned long long *fregs = get_fpu_regs(child); /* * The odd registers are actually the high * order bits of the values stored in the even * registers - unless we're using r2k_switch.S. */ -#ifdef CONFIG_CPU_R3000 - if (mips_cpu.options & MIPS_CPU_FPU) - tmp = *(unsigned long *)(fregs + addr); - else -#endif if (addr & 1) tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); else @@ -166,7 +145,7 @@ tmp = regs->lo; break; case FPC_CSR: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) tmp = child->thread.fpu.soft.sr; else tmp = child->thread.fpu.hard.control; @@ -174,34 +153,37 @@ case FPC_EIR: { /* implementation / version register */ unsigned int flags; - local_save_flags(flags); - enable_cp1(); + if (!cpu_has_fpu) + break; + + flags = read_c0_status(); + __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); - local_irq_restore(flags); + write_c0_status(flags); break; } default: tmp = 0; - res = -EIO; - goto out; + ret = -EIO; + goto out_tsk; } - res = put_user(tmp, (unsigned long *) data); - goto out; + ret = put_user(tmp, (unsigned long *) data); + break; } case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: - res = 0; + ret = 0; if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) break; - res = -EIO; - goto out; + ret = -EIO; + break; case PTRACE_POKEUSR: { struct pt_regs *regs; - res = 0; - regs = (struct pt_regs *) ((unsigned long) child + + ret = 0; + regs = (struct pt_regs *) ((unsigned long) child->thread_info + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); switch (addr) { @@ -210,21 +192,8 @@ break; case FPR_BASE ... FPR_BASE + 31: { unsigned long long *fregs; - fregs = (unsigned long long *)&child->thread.fpu.hard.fp_regs[0]; - if (child->used_math) { - if (last_task_used_math == child) { - if(!(mips_cpu.options & MIPS_CPU_FPU)) { - fregs = (unsigned long long *) - child->thread.fpu.soft.regs; - } else { - enable_cp1(); - save_fp(child); - disable_cp1(); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } - } - } else { + fregs = (unsigned long long *)get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); @@ -235,11 +204,6 @@ * of the values stored in the even registers - unless * we're using r2k_switch.S. */ -#ifdef CONFIG_CPU_R3000 - if (mips_cpu.options & MIPS_CPU_FPU) - *(unsigned long *)(fregs + addr) = data; - else -#endif if (addr & 1) { fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; @@ -259,14 +223,14 @@ regs->lo = data; break; case FPC_CSR: - if (!(mips_cpu.options & MIPS_CPU_FPU)) + if (!cpu_has_fpu) child->thread.fpu.soft.sr = data; else child->thread.fpu.hard.control = data; break; default: /* The rest are not allowed. */ - res = -EIO; + ret = -EIO; break; } break; @@ -274,26 +238,28 @@ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ - res = -EIO; + ret = -EIO; if ((unsigned long) data > _NSIG) break; - if (request == PTRACE_SYSCALL) - child->ptrace |= PT_TRACESYS; - else - child->ptrace &= ~PT_TRACESYS; + if (request == PTRACE_SYSCALL) { + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + } + else { + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + } child->exit_code = data; wake_up_process(child); - res = 0; + ret = 0; break; } /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to * exit. */ case PTRACE_KILL: - res = 0; + ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ break; child->exit_code = SIGKILL; @@ -301,32 +267,40 @@ break; case PTRACE_DETACH: /* detach a process that was attached. */ - res = ptrace_detach(child, data); + ret = ptrace_detach(child, data); break; default: - res = ptrace_request(child, request, addr, data); - goto out; + ret = ptrace_request(child, request, addr, data); + break; } out_tsk: - free_task_struct(child); + put_task_struct(child); out: unlock_kernel(); - return res; + return ret; } -asmlinkage void syscall_trace(void) +/* + * Notification of system call entry/exit + * - triggered by current->work.syscall_trace + */ +asmlinkage void do_syscall_trace(void) { - if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) - != (PT_PTRACED|PT_TRACESYS)) + if (!test_thread_flag(TIF_SYSCALL_TRACE)) return; + if (!(current->ptrace & PT_PTRACED)) + return; + /* The 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0); + preempt_disable(); current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); + preempt_enable(); /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the diff -Nru a/arch/mips/kernel/r2300_misc.S b/arch/mips/kernel/r2300_misc.S --- a/arch/mips/kernel/r2300_misc.S Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,199 +0,0 @@ -/* $Id: r2300_misc.S,v 1.8 1999/12/08 22:05:10 harald Exp $ - * misc.S: Misc. exception handling code for R3000/R2000. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-CPU abstraction reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * Further modifications to make this work: - * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov - */ -#include <asm/asm.h> -#include <asm/current.h> -#include <asm/bootinfo.h> -#include <asm/cachectl.h> -#include <asm/fpregdef.h> -#include <asm/mipsregs.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/regdef.h> -#include <asm/segment.h> -#include <asm/stackframe.h> - - .text - .set mips1 - .set noreorder - -#undef NOTLB_OPTIMIZE /* If you are paranoid, define this. */ - - /* ABUSE of CPP macros 101. */ - - /* After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ -#define LOAD_PTE(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, current_pgd; \ - srl pte, pte, 22; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_CONTEXT; \ - lw ptr, (ptr); \ - andi pte, pte, 0xffc; \ - addu ptr, ptr, pte; \ - lw pte, (ptr); \ - nop; - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr) \ - lw ptr, (ptr) ; \ - nop ; \ - mtc0 ptr, CP0_ENTRYLO0; \ - nop; - -#define DO_FAULT(write) \ - .set noat; \ - .set macro; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - STI; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_sys_call; \ - nop; \ - .set noat; \ - .set nomacro; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with its original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - sw pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - .set push; \ - .set reorder; \ - lw pte, (ptr); \ - .set pop; - - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - sw pte, (ptr); - -/* - * The index register may have the probe fail bit set, - * because we would trap on access kseg2, i.e. without refill. - */ -#define TLB_WRITE(reg) \ - mfc0 reg, CP0_INDEX; \ - nop; \ - bltz reg, 1f; \ - nop; \ - tlbwi; \ - j 2f; \ - nop; \ -1: tlbwr; \ -2: - -#define RET(reg) \ - mfc0 reg, CP0_EPC; \ - nop; \ - jr reg; \ - rfe - - .set noreorder - - .align 5 -NESTED(handle_tlbl, PT_SIZE, sp) - .set noat - -#ifndef NOTLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbl: -#endif - - DO_FAULT(0) -END(handle_tlbl) - -NESTED(handle_tlbs, PT_SIZE, sp) - .set noat - -#ifndef NOTLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1) - TLB_WRITE(k0) - RET(k0) -nopage_tlbs: -#endif - - DO_FAULT(1) -END(handle_tlbs) - - .align 5 -NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifndef NOTLB_OPTIMIZE - LOAD_PTE(k0, k1) - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - .set push - .set reorder - lw k0, (k1) - .set pop - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1) - tlbwi - RET(k0) -#endif - -nowrite_mod: - DO_FAULT(1) -END(handle_mod) diff -Nru a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S --- a/arch/mips/kernel/r2300_switch.S Fri Jun 27 14:20:01 2003 +++ b/arch/mips/kernel/r2300_switch.S Fri Jun 27 14:20:01 2003 @@ -10,18 +10,17 @@ * Further modifications to make this work: * Copyright (c) 1998-2000 Harald Koerfgen */ +#include <linux/config.h> #include <asm/asm.h> -#include <asm/bootinfo.h> #include <asm/cachectl.h> -#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsregs.h> #include <asm/offset.h> #include <asm/page.h> -#include <asm/pgtable.h> #include <asm/processor.h> #include <asm/regdef.h> #include <asm/stackframe.h> +#include <asm/thread_info.h> #include <asm/asmmacro.h> @@ -29,8 +28,24 @@ .align 5 /* - * task_struct *resume(task_struct *prev, - * task_struct *next) + * Offset to the current process status flags, the first 32 bytes of the + * stack are not used. + */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * FPU context is saved iff the process has used it's FPU in the current + * time slice as indicated by TIF_USEDFPU. In any case, the CU1 bit for user + * space STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + +/* + * task_struct *resume(task_struct *prev, task_struct *next, + * struct thread_info *next_ti) ) */ LEAF(resume) #ifndef CONFIG_CPU_HAS_LLSC @@ -41,84 +56,81 @@ CPU_SAVE_NONSCRATCH(a0) sw ra, THREAD_REG31(a0) + /* + * check if we need to save FPU registers + */ + lw t3, TASK_THREAD_INFO(a0) + lw t0, TI_FLAGS(t3) + li t1, TIF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + and t0, t0, t1 + sw t0, TI_FLAGS(t3) + + /* + * clear saved user stack CU1 bit + */ + lw t0, ST_OFF(t3) + li t1, ~ST0_CU1 + and t0, t0, t1 + sw t0, ST_OFF(t3) + + FPU_SAVE_SINGLE(a0, t0) # clobbers t0 + +1: /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. */ - move $28, a1 - CPU_RESTORE_NONSCRATCH($28) - addiu t0, $28, KERNEL_STACK_SIZE-32 - sw t0, kernelsp + move $28, a2 + CPU_RESTORE_NONSCRATCH(a1) + + addiu t1, $28, KERNEL_STACK_SIZE-32 + sw t1, kernelsp + mfc0 t1, CP0_STATUS /* Do we really need this? */ li a3, 0xff00 and t1, a3 - lw a2, THREAD_STATUS($28) + lw a2, THREAD_STATUS(a1) nor a3, $0, a3 and a2, a3 or a2, t1 mtc0 a2, CP0_STATUS - .set noreorder + move v0, a0 jr ra - move v0, a0 - .set reorder END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, 0x20000000 - or t0, t3 - mtc0 t0, CP0_STATUS - - .set noreorder - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - .set reorder - lw t1, ST_OFF(a0) # last thread loses fpu - and t1, t3 - sw t1, ST_OFF(a0) - FPU_SAVE_SINGLE(a0, t1) # clobbers t1 - -2: - FPU_RESTORE_SINGLE($28, t0) # clobbers t0 - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ -LEAF(save_fp) +LEAF(_save_fp) FPU_SAVE_SINGLE(a0, t1) # clobbers t1 jr ra - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) FPU_RESTORE_SINGLE(a0, t1) # clobbers t1 jr ra - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has * the property that no matter whether considered as single or as double - * precission represents signaling NANS. + * precision represents signaling NANS. * * We initialize fcr31 to rounding to nearest, no exceptions. */ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) mfc0 t0, CP0_STATUS - li t1, 0x20000000 + li t1, ST0_CU1 or t0, t1 mtc0 t0, CP0_STATUS @@ -158,8 +170,6 @@ mtc1 t0, $f28 mtc1 t0, $f29 mtc1 t0, $f30 - .set noreorder + mtc1 t0, $f31 jr ra - mtc1 t0, $f31 - .set reorder - END(init_fpu) + END(_init_fpu) diff -Nru a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S --- a/arch/mips/kernel/r4k_misc.S Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,236 +0,0 @@ -/* $Id: r4k_misc.S,v 1.8 1999/10/09 00:00:58 ralf Exp $ - * - * r4k_misc.S: Misc. exception handling code for r4k. - * - * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse - * - * Multi-cpu abstraction and reworking: - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -/************************************************************************** - * 14 Nov, 2000. - * Made support for MIPS32 CPUs. - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - *************************************************************************/ -#include <asm/asm.h> -#include <asm/current.h> -#include <asm/offset.h> -#include <asm/bootinfo.h> -#include <asm/cachectl.h> -#include <asm/fpregdef.h> -#include <asm/mipsregs.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/processor.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -#undef NOTLB_OPTIMIZE /* If you are paranoid, define this. */ - - /* ABUSE of CPP macros 101. */ - - /* After this macro runs, the pte faulted on is - * in register PTE, a ptr into the table in which - * the pte belongs is in PTR. - */ - -#ifdef CONFIG_SMP -#define GET_PGD(scratch, ptr) \ - mfc0 ptr, CP0_CONTEXT; \ - la scratch, current_pgd;\ - srl ptr, 23; \ - sll ptr, 2; \ - addu ptr, scratch, ptr; \ - lw ptr, (ptr); -#else -#define GET_PGD(scratch, ptr) \ - lw ptr, current_pgd; -#endif - - -#define LOAD_PTE(pte, ptr) \ - GET_PGD(pte, ptr) \ - mfc0 pte, CP0_BADVADDR; \ - srl pte, pte, 22; \ - sll pte, pte, 2; \ - addu ptr, ptr, pte; \ - mfc0 pte, CP0_BADVADDR; \ - lw ptr, (ptr); \ - srl pte, pte, 10; \ - and pte, pte, 0xffc; \ - addu ptr, ptr, pte; \ - lw pte, (ptr); - - /* This places the even/odd pte pair in the page - * table at PTR into ENTRYLO0 and ENTRYLO1 using - * TMP as a scratch register. - */ -#define PTE_RELOAD(ptr, tmp) \ - ori ptr, ptr, 0x4; \ - xori ptr, ptr, 0x4; \ - lw tmp, 4(ptr); \ - lw ptr, 0(ptr); \ - srl tmp, tmp, 6; \ - mtc0 tmp, CP0_ENTRYLO1; \ - srl ptr, ptr, 6; \ - mtc0 ptr, CP0_ENTRYLO0; - -#define DO_FAULT(write) \ - .set noat; \ - SAVE_ALL; \ - mfc0 a2, CP0_BADVADDR; \ - STI; \ - .set at; \ - move a0, sp; \ - jal do_page_fault; \ - li a1, write; \ - j ret_from_sys_call; \ - nop; \ - .set noat; - - /* Check is PTE is present, if not then jump to LABEL. - * PTR points to the page table where this PTE is located, - * when the macro is done executing PTE will be restored - * with its original value. - */ -#define PTE_PRESENT(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ - bnez pte, label; \ - lw pte, (ptr); - - /* Make PTE valid, store result in PTR. */ -#define PTE_MAKEVALID(pte, ptr) \ - ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ - sw pte, (ptr); - - /* Check if PTE can be written to, if not branch to LABEL. - * Regardless restore PTE with value from PTR when done. - */ -#define PTE_WRITABLE(pte, ptr, label) \ - andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ - bnez pte, label; \ - lw pte, (ptr); - - /* Make PTE writable, update software status bits as well, - * then store at PTR. - */ -#define PTE_MAKEWRITE(pte, ptr) \ - ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ - _PAGE_VALID | _PAGE_DIRTY); \ - sw pte, (ptr); - - .set noreorder - -/* - * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: - * 2. A timing hazard exists for the TLBP instruction. - * - * stalling_instruction - * TLBP - * - * The JTLB is being read for the TLBP throughout the stall generated by the - * previous instruction. This is not really correct as the stalling instruction - * can modify the address used to access the JTLB. The failure symptom is that - * the TLBP instruction will use an address created for the stalling instruction - * and not the address held in C0_ENHI and thus report the wrong results. - * - * The software work-around is to not allow the instruction preceding the TLBP - * to stall - make it an NOP or some other instruction guaranteed not to stall. - * - * Errata 2 will not be fixed. This errata is also on the R5000. - * - * As if we MIPS hackers wouldn't know how to nop pipelines happy ... - */ -#define R5K_HAZARD nop - - /* - * Note for many R4k variants tlb probes cannot be executed out - * of the instruction cache else you get bogus results. - */ - .align 5 - NESTED(handle_tlbl, PT_SIZE, sp) - .set noat -invalid_tlbl: -#ifndef NOTLB_OPTIMIZE - /* Test present bit in entry. */ - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp - PTE_PRESENT(k0, k1, nopage_tlbl) - PTE_MAKEVALID(k0, k1) - PTE_RELOAD(k1, k0) - nop - b 1f - tlbwi -1: - nop - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbl: - DO_FAULT(0) - END(handle_tlbl) - - .align 5 - NESTED(handle_tlbs, PT_SIZE, sp) - .set noat -#ifndef NOTLB_OPTIMIZE - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - PTE_WRITABLE(k0, k1, nopage_tlbs) - PTE_MAKEWRITE(k0, k1) - PTE_RELOAD(k1, k0) - nop - b 1f - tlbwi -1: - nop - .set mips3 - eret - .set mips0 -#endif - -nopage_tlbs: - DO_FAULT(1) - END(handle_tlbs) - - .align 5 - NESTED(handle_mod, PT_SIZE, sp) - .set noat -#ifndef NOTLB_OPTIMIZE - LOAD_PTE(k0, k1) - R5K_HAZARD - tlbp # find faulting entry - andi k0, k0, _PAGE_WRITE - beqz k0, nowrite_mod - lw k0, (k1) - - /* Present and writable bits set, set accessed and dirty bits. */ - PTE_MAKEWRITE(k0, k1) -#if 0 - ori k0, k0, (_PAGE_ACCESSED | _PAGE_DIRTY) - sw k0, (k1) -#endif - - /* Now reload the entry into the tlb. */ - PTE_RELOAD(k1, k0) - nop - b 1f - tlbwi -1: - nop - .set mips3 - eret - .set mips0 -#endif - -nowrite_mod: - DO_FAULT(1) - END(handle_mod) diff -Nru a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S --- a/arch/mips/kernel/r4k_switch.S Fri Jun 27 14:20:04 2003 +++ b/arch/mips/kernel/r4k_switch.S Fri Jun 27 14:20:04 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996, 1998, 1999 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002 by Ralf Baechle * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1994, 1995, 1996, by Andreas Busse * Copyright (C) 1999 Silicon Graphics, Inc. @@ -12,24 +12,35 @@ */ #include <linux/config.h> #include <asm/asm.h> -#include <asm/bootinfo.h> #include <asm/cachectl.h> -#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsregs.h> #include <asm/offset.h> #include <asm/page.h> -#include <asm/pgtable.h> +#include <asm/pgtable-bits.h> #include <asm/processor.h> #include <asm/regdef.h> #include <asm/stackframe.h> +#include <asm/thread_info.h> #include <asm/asmmacro.h> +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * FPU context is saved iff the process has used it's FPU in the current + * time slice as indicated by TIF_USEDFPU. In any case, the CU1 bit for user + * space STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* - * task_struct *r4xx0_resume(task_struct *prev, task_struct *next) + * task_struct *r4xx0_resume(task_struct *prev, task_struct *next, + * struct thread_info *next_ti) */ - .set noreorder .align 5 LEAF(resume) #ifndef CONFIG_CPU_HAS_LLSC @@ -40,79 +51,76 @@ CPU_SAVE_NONSCRATCH(a0) sw ra, THREAD_REG31(a0) + /* + * check if we need to save FPU registers + */ + lw t3, TASK_THREAD_INFO(a0) + lw t0, TI_FLAGS(t3) + li t1, _TIF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + and t0, t0, t1 + sw t0, TI_FLAGS(t3) + + /* + * clear saved user stack CU1 bit + */ + lw t0, ST_OFF(t3) + li t1, ~ST0_CU1 + and t0, t0, t1 + sw t0, ST_OFF(t3) + + FPU_SAVE_DOUBLE(a0, t0) # clobbers t0 + +1: /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. */ - move $28, a1 - CPU_RESTORE_NONSCRATCH($28) + move $28, a2 + CPU_RESTORE_NONSCRATCH(a1) + addiu t0, $28, KERNEL_STACK_SIZE-32 -#ifdef CONFIG_SMP +#ifdef CONFIG_SMP mfc0 a3, CP0_CONTEXT la t1, kernelsp srl a3, 23 sll a3, 2 addu t1, a3, t1 - sw t0, (t1) + sw t0, (t1) #else sw t0, kernelsp -#endif +#endif + mfc0 t1, CP0_STATUS /* Do we really need this? */ li a3, 0xff00 and t1, a3 - lw a2, THREAD_STATUS($28) + lw a2, THREAD_STATUS(a1) nor a3, $0, a3 and a2, a3 or a2, t1 mtc0 a2, CP0_STATUS + move v0, a0 jr ra - move v0, a0 END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. - */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, 0x20000000 - or t0, t3 - mtc0 t0, CP0_STATUS - - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - - lw t1, ST_OFF(a0) # last thread loses fpu - and t1, t3 - sw t1, ST_OFF(a0) - - - FPU_SAVE_DOUBLE(a0, t1) # clobbers t1 -2: - - .set reorder - FPU_RESTORE_DOUBLE($28, t0) # clobbers t0 - jr ra - END(lazy_fpu_switch) - -/* * Save a thread's fp context. */ -LEAF(save_fp) +LEAF(_save_fp) FPU_SAVE_DOUBLE(a0, t1) # clobbers t1 jr ra - END(save_fp) + END(_save_fp) /* * Restore a thread's fp context. */ -LEAF(restore_fp) +LEAF(_restore_fp) FPU_RESTORE_DOUBLE(a0, t1) # clobbers t1 jr ra - END(restore_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has @@ -124,12 +132,13 @@ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) .set mips3 mfc0 t0, CP0_STATUS - li t1, 0x20000000 + li t1, ST0_CU1 or t0, t1 mtc0 t0, CP0_STATUS + FPU_ENABLE_HAZARD li t1, FPU_DEFAULT ctc1 t1, fcr31 @@ -151,9 +160,6 @@ dmtc1 t0, $f24 dmtc1 t0, $f26 dmtc1 t0, $f28 - .set noreorder + dmtc1 t0, $f30 jr ra - dmtc1 t0, $f30 - .set reorder - END(init_fpu) - + END(_init_fpu) diff -Nru a/arch/mips/kernel/scall_o32.S b/arch/mips/kernel/scall_o32.S --- a/arch/mips/kernel/scall_o32.S Fri Jun 27 14:20:00 2003 +++ b/arch/mips/kernel/scall_o32.S Fri Jun 27 14:20:00 2003 @@ -3,124 +3,107 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle + * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. */ -#include <asm/asm.h> +#include <linux/config.h> #include <linux/errno.h> -#include <asm/current.h> +#include <asm/asm.h> #include <asm/mipsregs.h> #include <asm/regdef.h> #include <asm/stackframe.h> #include <asm/isadep.h> +#include <asm/sysmips.h> #include <asm/unistd.h> - -/* This duplicates the definition from <linux/sched.h> */ -#define PT_TRACESYS 0x00000002 /* tracing system calls */ - -/* This duplicates the definition from <asm/signal.h> */ -#define SIGILL 4 /* Illegal instruction (ANSI). */ +#include <asm/offset.h> /* Highest syscall used of any syscall flavour */ #define MAX_SYSCALL_NO __NR_Linux + __NR_Linux_syscalls .align 5 NESTED(handle_sys, PT_SIZE, sp) - .set noat - SAVE_SOME - STI - .set at - - lw t1, PT_EPC(sp) # skip syscall on return - - sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number - addiu t1, 4 # skip to next instruction - beqz t0, illegal_syscall - sw t1, PT_EPC(sp) - - /* XXX Put both in one cacheline, should save a bit. */ - sll t0, v0, 2 - lw t2, sys_call_table(t0) # syscall routine - lbu t3, sys_narg_table(v0) # number of arguments - beqz t2, illegal_syscall; - - subu t0, t3, 5 # 5 or more arguments? - sw a3, PT_R26(sp) # save a3 for syscall restarting - bgez t0, stackargs + .set noat + SAVE_SOME + STI + .set at + + lw t1, PT_EPC(sp) # skip syscall on return + + sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number + addiu t1, 4 # skip to next instruction + beqz t0, illegal_syscall + sw t1, PT_EPC(sp) + + /* XXX Put both in one cacheline, should save a bit. */ + sll t0, v0, 2 + lw t2, sys_call_table(t0) # syscall routine + lbu t3, sys_narg_table(v0) # number of arguments + beqz t2, illegal_syscall; + + subu t0, t3, 5 # 5 or more arguments? + sw a3, PT_R26(sp) # save a3 for syscall restarting + bgez t0, stackargs stack_done: - sw a3, PT_R26(sp) # save for syscall restart -#error lw t0, TASK_PTRACE($28) # syscall tracing enabled? - andi t0, PT_TRACESYS - bnez t0, trace_a_syscall - - jalr t2 # Do The Real Thing (TM) - - li t0, -EMAXERRNO - 1 # error? - sltu t0, t0, v0 - sw t0, PT_R7(sp) # set error flag - beqz t0, 1f - - negu v0 # error - sw v0, PT_R0(sp) # set flag for syscall restarting -1: sw v0, PT_R2(sp) # result - -EXPORT(o32_ret_from_sys_call) - mfc0 t0, CP0_STATUS # need_resched and signals atomic test - ori t0, t0, 1 - xori t0, t0, 1 - mtc0 t0, CP0_STATUS - -#error lw t2, TASK_NEED_RESCHED($28) - bnez t2, o32_reschedule -#error lw v0, TASK_SIGPENDING($28) - bnez v0, signal_return -restore_all: - RESTORE_SOME - RESTORE_SP_AND_RET - -/* Put this behind restore_all for the sake of the branch prediction. */ -signal_return: - .type signal_return, @function - - mfc0 t0, CP0_STATUS - ori t0, t0, 1 - mtc0 t0, CP0_STATUS - - move a0, zero - move a1, sp -#error jal do_signal - b restore_all - -o32_reschedule: - SAVE_STATIC - jal schedule - b o32_ret_from_sys_call + sw a3, PT_R26(sp) # save for syscall restart + LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? + bltz t0, syscall_trace_entry # -> yes + + jalr t2 # Do The Real Thing (TM) + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sw t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sw v0, PT_R0(sp) # set flag for syscall + # restarting +1: sw v0, PT_R2(sp) # result + +EXPORT(o32_syscall_exit) + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) # current->work + bnez a2, o32_syscall_exit_work + +o32_restore_all: + RESTORE_SOME + RESTORE_SP_AND_RET + +o32_syscall_exit_work: + SAVE_STATIC + j syscall_exit_work /* ------------------------------------------------------------------------ */ -trace_a_syscall: - SAVE_STATIC - sw t2, PT_R1(sp) -#error jal syscall_trace - lw t2, PT_R1(sp) - - lw a0, PT_R4(sp) # Restore argument registers - lw a1, PT_R5(sp) - lw a2, PT_R6(sp) - lw a3, PT_R7(sp) - jalr t2 - - li t0, -EMAXERRNO - 1 # error? - sltu t0, t0, v0 - sw t0, PT_R7(sp) # set error flag - beqz t0, 1f - - negu v0 # error - sw v0, PT_R0(sp) # set flag for syscall restarting -1: sw v0, PT_R2(sp) # result +syscall_trace_entry: + SAVE_STATIC + sw t2, PT_R1(sp) + jal do_syscall_trace + lw t2, PT_R1(sp) + + lw a0, PT_R4(sp) # Restore argument registers + lw a1, PT_R5(sp) + lw a2, PT_R6(sp) + lw a3, PT_R7(sp) + jalr t2 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sw t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sw v0, PT_R0(sp) # set flag for syscall + # restarting +1: sw v0, PT_R2(sp) # result -#error jal syscall_trace - j ret_from_sys_call + j syscall_exit /* ------------------------------------------------------------------------ */ @@ -139,7 +122,7 @@ bltz t0, bad_stack # -> sp is bad lw t0, PT_R29(sp) # get old user stack pointer - la t1, 3f # copy 1 to 2 arguments + PTR_LA t1, 3f # copy 1 to 2 arguments sll t3, t3, 4 subu t1, t3 jr t1 @@ -153,6 +136,7 @@ */ .set push .set noreorder + .set nomacro 1: lw t1, 20(t0) # argument #6 from usp nop sw t1, 20(sp) @@ -161,9 +145,9 @@ nop sw t1, 16(sp) nop - .set pop +3: .set pop -3: j stack_done # go back + j stack_done # go back .section __ex_table,"a" PTR 1b,bad_stack @@ -180,7 +164,7 @@ sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) - j ret_from_sys_call + j o32_syscall_exit /* * The system call does not exist in this kernel @@ -190,5 +174,147 @@ sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) - j ret_from_sys_call + j o32_syscall_exit END(handle_sys) + + LEAF(mips_atomic_set) + andi v0, a1, 3 # must be word aligned + bnez v0, bad_alignment + + lw v1, TI_ADDR_LIMIT($28) # in legal address range? + addiu a0, a1, 4 + or a0, a0, a1 + and a0, a0, v1 + bltz a0, bad_address + +#ifdef CONFIG_CPU_HAS_LLSC + /* Ok, this is the ll/sc case. World is sane :-) */ +1: ll v0, (a1) + move a0, a2 +2: sc a0, (a1) + beqz a0, 1b + + .section __ex_table,"a" + PTR 1b, bad_stack + PTR 2b, bad_stack + .previous +#else + sw a1, 16(sp) + sw a2, 20(sp) + + move a0, sp + move a2, a1 + li a1, 1 + jal do_page_fault + + lw a1, 16(sp) + lw a2, 20(sp) + + /* + * At this point the page should be readable and writable unless + * there was no more memory available. + */ +1: lw v0, (a1) +2: sw a2, (a1) + + .section __ex_table,"a" + PTR 1b, no_mem + PTR 2b, no_mem + .previous +#endif + + sw v0, PT_R2(sp) # result +1: + + /* Success, so skip usual error handling garbage. */ + LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? + bltz t0, 1f + b o32_syscall_exit + +1: SAVE_STATIC + jal do_syscall_trace + li a3, 0 # success + j syscall_exit + +no_mem: li v0, -ENOMEM + jr ra + +bad_address: + li v0, -EFAULT + jr ra + +bad_alignment: + li v0, -EINVAL + jr ra + END(mips_atomic_set) + + LEAF(sys_sysmips) + beq a0, MIPS_ATOMIC_SET, mips_atomic_set + j _sys_sysmips + END(sys_sysmips) + + LEAF(sys_syscall) + lw t0, PT_R29(sp) # user sp + + sltu v0, a0, __NR_Linux + __NR_Linux_syscalls + 1 + beqz v0, enosys + + sll v0, a0, 2 + la v1, sys_syscall + lw t2, sys_call_table(v0) # function pointer + lbu t4, sys_narg_table(a0) # number of arguments + + li v0, -EINVAL + beq t2, v1, out # do not recurse + + beqz t2, enosys # null function pointer? + + andi v0, t0, 0x3 # unaligned stack pointer? + bnez v0, sigsegv + + addu v0, t0, 16 # v0 = usp + 16 + addu t1, v0, 12 # 3 32-bit arguments + lw v1, TI_ADDR_LIMIT($28) + or v0, v0, t1 + and v1, v1, v0 + bltz v1, efault + + move a0, a1 # shift argument registers + move a1, a2 + move a2, a3 + +1: lw a3, 16(t0) +2: lw t3, 20(t0) +3: lw t4, 24(t0) + + .section __ex_table, "a" + .word 1b, efault + .word 2b, efault + .word 3b, efault + .previous + + sw t3, 16(sp) # put into new stackframe + sw t4, 20(sp) + + bnez t4, 1f # zero arguments? + addu a0, sp, 32 # then pass sp in a0 +1: + + sw t3, 16(sp) + sw v1, 20(sp) + jr t2 + /* Unreached */ + +enosys: li v0, -ENOSYS + b out + +sigsegv: + li a0, _SIGSEGV + move a1, $28 + jal force_sig + /* Fall through */ + +efault: li v0, -EFAULT + +out: jr ra + END(sys_syscall) diff -Nru a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c --- a/arch/mips/kernel/setup.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/setup.c Fri Jun 27 14:19:54 2003 @@ -4,9 +4,10 @@ * for more details. * * Copyright (C) 1995 Linus Torvalds - * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Ralf Baechle + * Copyright (C) 1995 Waldorf Electronics + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle * Copyright (C) 1996 Stoned Elipot - * Copyright (C) 2000 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002 Maciej W. Rozycki */ #include <linux/config.h> #include <linux/errno.h> @@ -16,10 +17,10 @@ #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/stddef.h> #include <linux/string.h> #include <linux/unistd.h> -#include <linux/ptrace.h> #include <linux/slab.h> #include <linux/user.h> #include <linux/utsname.h> @@ -29,6 +30,8 @@ #include <linux/initrd.h> #include <linux/ide.h> #include <linux/timex.h> +#include <linux/major.h> +#include <linux/kdev_t.h> #include <linux/root_dev.h> #include <asm/asm.h> @@ -36,23 +39,11 @@ #include <asm/cachectl.h> #include <asm/cpu.h> #include <asm/io.h> -#include <asm/stackframe.h> +#include <asm/ptrace.h> +#include <asm/sections.h> #include <asm/system.h> -#ifdef CONFIG_SGI_IP22 -#include <asm/sgialib.h> -#endif - -struct mips_cpuinfo boot_cpu_data = { 0, NULL, NULL, 0 }; - -/* - * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, - * the implementation of the "wait" feature differs between CPU families. This - * points to the function that implements CPU specific wait. - * The wait instruction stops the pipeline and reduces the power consumption of - * the CPU very much. - */ -void (*cpu_wait)(void) = NULL; +struct cpuinfo_mips cpu_data[NR_CPUS]; /* * There are several bus types available for MIPS machines. "RISC PC" @@ -61,7 +52,9 @@ * boxes ... * This flag is set if a EISA slots are available. */ +#ifdef CONFIG_EISA int EISA_bus = 0; +#endif struct screen_info screen_info; @@ -78,11 +71,6 @@ extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; -#ifdef CONFIG_PC_KEYB -extern struct kbd_ops no_kbd_ops; -struct kbd_ops *kbd_ops; -#endif - /* * Setup information * @@ -94,333 +82,59 @@ struct boot_mem_map boot_mem_map; unsigned char aux_device_present; -extern char _ftext, _etext, _fdata, _edata, _end; -static char command_line[COMMAND_LINE_SIZE]; - char saved_command_line[COMMAND_LINE_SIZE]; -extern char arcs_cmdline[COMMAND_LINE_SIZE]; +static char command_line[CL_SIZE]; + char saved_command_line[CL_SIZE]; +extern char arcs_cmdline[CL_SIZE]; /* * mips_io_port_base is the begin of the address space to which x86 style * I/O ports are mapped. */ -unsigned long mips_io_port_base; +const unsigned long mips_io_port_base = -1; +EXPORT_SYMBOL(mips_io_port_base); + /* - * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped + * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ unsigned long isa_slot_offset; +EXPORT_SYMBOL(isa_slot_offset); -extern void sgi_sysinit(void); extern void SetUpBootInfo(void); -extern void loadmmu(void); +extern void load_mmu(void); extern asmlinkage void start_kernel(void); extern void prom_init(int, char **, char **, int *); static struct resource code_resource = { "Kernel code" }; static struct resource data_resource = { "Kernel data" }; -/* - * Probe whether cpu has config register by trying to play with - * alternate cache bit and see whether it matters. - * It's used by cpu_probe to distinguish between R3000A and R3081. - */ -static inline int cpu_has_confreg(void) -{ -#ifdef CONFIG_CPU_R3000 - extern unsigned long r3k_cache_size(unsigned long); - unsigned long size1, size2; - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - - size1 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg^CONF_AC); - size2 = r3k_cache_size(ST0_ISC); - write_32bit_cp0_register(CP0_CONF, cfg); - return size1 != size2; -#else - return 0; -#endif -} - -/* declaration of the global struct */ -struct mips_cpu mips_cpu = {PRID_IMP_UNKNOWN, CPU_UNKNOWN, 0, 0, 0, - {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}; - -/* Shortcut for assembler access to mips_cpu.options */ -int *cpuoptions = &mips_cpu.options; - -#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ - | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) - -static inline void cpu_probe(void) -{ - -#ifdef CONFIG_CPU_MIPS32 - unsigned long config1; -#endif - - mips_cpu.processor_id = read_32bit_cp0_register(CP0_PRID); - switch (mips_cpu.processor_id & 0xff0000) { - case PRID_COMP_LEGACY: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_R2000: - mips_cpu.cputype = CPU_R2000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; - mips_cpu.tlbsize = 64; - break; - case PRID_IMP_R3000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R3000A) - if (cpu_has_confreg()) - mips_cpu.cputype = CPU_R3081E; - else - mips_cpu.cputype = CPU_R3000A; - else - mips_cpu.cputype = CPU_R3000; - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; - mips_cpu.tlbsize = 64; - break; - case PRID_IMP_R4000: - if ((mips_cpu.processor_id & 0xff) == PRID_REV_R4400) - mips_cpu.cputype = CPU_R4400SC; - else - mips_cpu.cputype = CPU_R4000SC; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_WATCH | MIPS_CPU_VCE; - mips_cpu.tlbsize = 48; - break; - case PRID_IMP_VR41XX: - mips_cpu.cputype = CPU_VR41XX; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS; - mips_cpu.tlbsize = 32; - break; - case PRID_IMP_R4600: - mips_cpu.cputype = CPU_R4600; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; - break; -/* - * This processor doesn't have an MMU, so it's not "real easy" to - * run Linux on it. It is left purely for documentation. - * case PRID_IMP_R4650: - mips_cpu.cputype = CPU_R4650; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU; - mips_cpu.tlbsize = 48; - break; -*/ - case PRID_IMP_TX39: - mips_cpu.isa_level = MIPS_CPU_ISA_I; - mips_cpu.options = MIPS_CPU_TLB; - - switch (mips_cpu.processor_id & 0xff) { - case PRID_REV_TX3912: - mips_cpu.cputype = CPU_TX3912; - mips_cpu.tlbsize = 32; - break; - case PRID_REV_TX3922: - mips_cpu.cputype = CPU_TX3922; - mips_cpu.tlbsize = 64; - break; - case PRID_REV_TX3927: - mips_cpu.cputype = CPU_TX3927; - mips_cpu.tlbsize = 64; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } - break; - case PRID_IMP_R4700: - mips_cpu.cputype = CPU_R4700; - mips_cpu.isa_level = MIPS_CPU_ISA_III; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - break; - case PRID_IMP_R5000: - mips_cpu.cputype = CPU_R5000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - break; - case PRID_IMP_R5432: - mips_cpu.cputype = CPU_R5432; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 48; - break; - case PRID_IMP_NEVADA: - mips_cpu.cputype = CPU_NEVADA; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_DIVEC; - mips_cpu.tlbsize = 48; - mips_cpu.icache.ways = 2; - mips_cpu.dcache.ways = 2; - break; - case PRID_IMP_R6000: - mips_cpu.cputype = CPU_R6000; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; - break; - case PRID_IMP_R6000A: - mips_cpu.cputype = CPU_R6000A; - mips_cpu.isa_level = MIPS_CPU_ISA_II; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_FPU; - mips_cpu.tlbsize = 32; - break; - case PRID_IMP_RM7000: - mips_cpu.cputype = CPU_RM7000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR; - break; - case PRID_IMP_R8000: - mips_cpu.cputype = CPU_R8000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR; - mips_cpu.tlbsize = 384; /* has weird TLB: 3-way x 128 */ - break; - case PRID_IMP_R10000: - mips_cpu.cputype = CPU_R10000; - mips_cpu.isa_level = MIPS_CPU_ISA_IV; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_FPU | MIPS_CPU_32FPR | - MIPS_CPU_COUNTER | MIPS_CPU_WATCH; - mips_cpu.tlbsize = 64; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } - break; -#ifdef CONFIG_CPU_MIPS32 - case PRID_COMP_MIPS: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_4KC: - mips_cpu.cputype = CPU_4KC; - goto cpu_4kc; - case PRID_IMP_4KEC: - mips_cpu.cputype = CPU_4KEC; - goto cpu_4kc; - case PRID_IMP_4KSC: - mips_cpu.cputype = CPU_4KSC; -cpu_4kc: - /* Why do we set all these options by default, THEN query them?? */ - mips_cpu.cputype = MIPS_CPU_ISA_M32; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | - MIPS_CPU_DIVEC | MIPS_CPU_WATCH; - config1 = read_mips32_cp0_config1(); - if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; - if (config1 & 1) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; - break; - case PRID_IMP_5KC: - mips_cpu.cputype = CPU_5KC; - mips_cpu.cputype = MIPS_CPU_ISA_M64; - /* See comment above about querying options */ - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | - MIPS_CPU_DIVEC | MIPS_CPU_WATCH; - config1 = read_mips32_cp0_config1(); - if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; - if (config1 & 1) - mips_cpu.options |= MIPS_CPU_FPU; - break; - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } - break; -#endif - case PRID_COMP_ALCHEMY: - switch (mips_cpu.processor_id & 0xff00) { -#ifdef CONFIG_CPU_MIPS32 - case PRID_IMP_AU1000: - mips_cpu.cputype = CPU_AU1000; - mips_cpu.isa_level = MIPS_CPU_ISA_M32; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | - MIPS_CPU_DIVEC | MIPS_CPU_WATCH; - config1 = read_mips32_cp0_config1(); - if (config1 & (1 << 3)) - mips_cpu.options |= MIPS_CPU_WATCH; - if (config1 & (1 << 2)) - mips_cpu.options |= MIPS_CPU_MIPS16; - if (config1 & 1) - mips_cpu.options |= MIPS_CPU_FPU; - mips_cpu.scache.flags = MIPS_CACHE_NOT_PRESENT; - break; -#endif - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } - break; - case PRID_COMP_SIBYTE: - switch (mips_cpu.processor_id & 0xff00) { - case PRID_IMP_SB1: - mips_cpu.cputype = CPU_SB1; - mips_cpu.options = MIPS_CPU_TLB | MIPS_CPU_4KEX | - MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | MIPS_CPU_FPU | - MIPS_CPU_VCE; - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - break; - } - break; - default: - mips_cpu.cputype = CPU_UNKNOWN; - } -} - asmlinkage void __init init_arch(int argc, char **argv, char **envp, int *prom_vec) { - unsigned int s; - /* Determine which MIPS variant we are running on. */ cpu_probe(); prom_init(argc, argv, envp, prom_vec); -#ifdef CONFIG_SGI_IP22 - sgi_sysinit(); -#endif + cpu_report(); /* * Determine the mmu/cache attached to this machine, * then flush the tlb and caches. On the r4xx0 * variants this also sets CP0_WIRED to zero. */ - loadmmu(); + load_mmu(); - /* Disable coprocessors and set FPU for 16 FPRs */ - s = read_32bit_cp0_register(CP0_STATUS); - s &= ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); - s |= ST0_CU0; - write_32bit_cp0_register(CP0_STATUS, s); + /* Disable coprocessors and set FPU for 16/32 FPR register model */ + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR); + set_c0_status(ST0_CU0); start_kernel(); } -void __init add_memory_region(unsigned long start, unsigned long size, +void __init add_memory_region(phys_t start, phys_t size, long type) { int x = boot_mem_map.nr_map; @@ -441,8 +155,10 @@ int i; for (i = 0; i < boot_mem_map.nr_map; i++) { - printk(" memory: %08lx @ %08lx ", - boot_mem_map.map[i].size, boot_mem_map.map[i].addr); + printk(" memory: %08Lx @ %08Lx ", + (u64) boot_mem_map.map[i].size, + (u64) boot_mem_map.map[i].addr); + switch (boot_mem_map.map[i].type) { case BOOT_MEM_RAM: printk("(usable)\n"); @@ -460,7 +176,7 @@ } } -static inline void parse_mem_cmdline(void) +static inline void parse_cmdline_early(void) { char c = ' ', *to = command_line, *from = saved_command_line; unsigned long start_at, mem_size; @@ -499,7 +215,7 @@ c = *(from++); if (!c) break; - if (COMMAND_LINE_SIZE <= ++len) + if (CL_SIZE <= ++len) break; *(to++) = c; } @@ -511,143 +227,41 @@ } } -void __init setup_arch(char **cmdline_p) -{ - void atlas_setup(void); - void baget_setup(void); - void ddb_setup(void); - void decstation_setup(void); - void deskstation_setup(void); - void jazz_setup(void); - void sni_rm200_pci_setup(void); - void sgi_setup(void); - void ev96100_setup(void); - void malta_setup(void); - void momenco_ocelot_setup(void); - void nino_setup(void); - - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn, first_usable_pfn; - int i; - -#ifdef CONFIG_BLK_DEV_FD - fd_ops = &no_fd_ops; -#endif +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &no_ide_ops; -#endif +#define MAXMEM HIGHMEM_START +#define MAXMEM_PFN PFN_DOWN(MAXMEM) -#ifdef CONFIG_PC_KEYB - kbd_ops = &no_kbd_ops; +static inline void bootmem_init(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long tmp; + unsigned long *initrd_header; #endif - - rtc_ops = &no_rtc_ops; + unsigned long bootmap_size; + unsigned long start_pfn, max_low_pfn, first_usable_pfn; + int i; - switch(mips_machgroup) - { -#ifdef CONFIG_BAGET_MIPS - case MACH_GROUP_BAGET: - baget_setup(); - break; -#endif -#ifdef CONFIG_DECSTATION - case MACH_GROUP_DEC: - decstation_setup(); - break; -#endif -#ifdef CONFIG_MIPS_ATLAS - case MACH_GROUP_UNKNOWN: - atlas_setup(); - break; -#endif -#ifdef CONFIG_MIPS_JAZZ - case MACH_GROUP_JAZZ: - jazz_setup(); - break; -#endif -#ifdef CONFIG_MIPS_MALTA - case MACH_GROUP_UNKNOWN: - malta_setup(); - break; -#endif -#ifdef CONFIG_MOMENCO_OCELOT - case MACH_GROUP_MOMENCO: - momenco_ocelot_setup(); - break; -#endif -#ifdef CONFIG_SGI_IP22 - /* As of now this is only IP22. */ - case MACH_GROUP_SGI: - sgi_setup(); - break; -#endif -#ifdef CONFIG_SNI_RM200_PCI - case MACH_GROUP_SNI_RM: - sni_rm200_pci_setup(); - break; -#endif -#ifdef CONFIG_DDB5074 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_DDB5476 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_DDB5477 - case MACH_GROUP_NEC_DDB: - ddb_setup(); - break; -#endif -#ifdef CONFIG_MIPS_EV96100 - case MACH_GROUP_GALILEO: - ev96100_setup(); - break; -#endif -#ifdef CONFIG_MIPS_EV64120 - case MACH_GROUP_GALILEO: - ev64120_setup(); - break; -#endif -#if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172) - case MACH_GROUP_ITE: - case MACH_GROUP_GLOBESPAN: - it8172_setup(); - break; -#endif -#ifdef CONFIG_NINO - case MACH_GROUP_PHILIPS: - nino_setup(); - break; -#endif -#ifdef CONFIG_MIPS_PB1000 - case MACH_GROUP_ALCHEMY: - au1000_setup(); - break; -#endif - default: - panic("Unsupported architecture"); +#ifdef CONFIG_BLK_DEV_INITRD + tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; + if (tmp < (unsigned long)&_end) + tmp += PAGE_SIZE; + initrd_header = (unsigned long *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; } - - strlcpy(command_line, arcs_cmdline, sizeof command_line); - strlcpy(saved_command_line, command_line, sizeof saved_command_line); - *cmdline_p = command_line; - - parse_mem_cmdline(); - -#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) - + start_pfn = PFN_UP(__pa((&_end)+(initrd_end - initrd_start) + PAGE_SIZE)); +#else /* * Partially used pages are not usable - thus * we are rounding upwards. */ start_pfn = PFN_UP(__pa(&_end)); +#endif /* CONFIG_BLK_DEV_INITRD */ /* Find the highest page frame number we have available. */ max_pfn = 0; @@ -674,9 +288,36 @@ } } } - - /* Initialize the boot-time allocator. */ - bootmap_size = init_bootmem(first_usable_pfn, max_pfn); + + /* + * Determine low and high memory ranges + */ + max_low_pfn = max_pfn; + if (max_low_pfn > MAXMEM_PFN) { + max_low_pfn = MAXMEM_PFN; +#ifndef CONFIG_HIGHMEM + /* Maximum memory usable is what is directly addressable */ + printk(KERN_WARNING "Warning only %dMB will be used.\n", + MAXMEM>>20); + printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); +#endif + } + +#ifdef CONFIG_HIGHMEM + /* + * Crude, we really should make a better attempt at detecting + * highstart_pfn + */ + highstart_pfn = highend_pfn = max_pfn; + if (max_pfn > MAXMEM_PFN) { + highstart_pfn = MAXMEM_PFN; + printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", + (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT)); + } +#endif + + /* Initialize the boot-time allocator with low memory only. */ + bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); /* * Register fully available low RAM pages with the bootmem allocator. @@ -694,7 +335,7 @@ * We are rounding up the start address of usable memory: */ curr_pfn = PFN_UP(boot_mem_map.map[i].addr); - if (curr_pfn >= max_pfn) + if (curr_pfn >= max_low_pfn) continue; if (curr_pfn < start_pfn) curr_pfn = start_pfn; @@ -705,8 +346,19 @@ last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); - if (last_pfn > max_pfn) - last_pfn = max_pfn; + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + /* + * Only register lowmem part of lowmem segment with bootmem. + */ + size = last_pfn - curr_pfn; + if (curr_pfn > PFN_DOWN(HIGHMEM_START)) + continue; + if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START)) + size = PFN_DOWN(HIGHMEM_START) - curr_pfn; + if (!size) + continue; /* * ... finally, did all the rounding and playing @@ -715,7 +367,7 @@ if (last_pfn <= curr_pfn) continue; - size = last_pfn - curr_pfn; + /* Register lowmem ranges */ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); } @@ -725,38 +377,49 @@ #ifdef CONFIG_BLK_DEV_INITRD /* Board specific code should have set up initrd_start and initrd_end */ ROOT_DEV = Root_RAM0; - if( __rd_start != __rd_end ) { + if (&__rd_start != &__rd_end) { initrd_start = (unsigned long)&__rd_start; initrd_end = (unsigned long)&__rd_end; } initrd_below_start_ok = 1; if (initrd_start) { - unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); + unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); printk("Initial ramdisk at: 0x%p (%lu bytes)\n", - (void *)initrd_start, + (void *)initrd_start, initrd_size); - if ((void *)initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) { + if (PHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " - "(0x%lx > 0x%p)\ndisabling initrd\n", - initrd_end, - phys_to_virt(PFN_PHYS(max_low_pfn))); + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + PHYSADDR(initrd_end), + PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; - } + } } #endif /* CONFIG_BLK_DEV_INITRD */ +} - paging_init(); +static inline void resource_init(void) +{ + int i; - code_resource.start = virt_to_bus(&_ftext); - code_resource.end = virt_to_bus(&_etext) - 1; - data_resource.start = virt_to_bus(&_fdata); - data_resource.end = virt_to_bus(&_edata) - 1; + code_resource.start = virt_to_phys(&_text); + code_resource.end = virt_to_phys(&_etext) - 1; + data_resource.start = virt_to_phys(&_etext); + data_resource.end = virt_to_phys(&_edata) - 1; /* * Request address space for all standard RAM. */ for (i = 0; i < boot_mem_map.nr_map; i++) { struct resource *res; + unsigned long start, end; + + start = boot_mem_map.map[i].addr; + end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; + if (start >= MAXMEM) + continue; + if (end >= MAXMEM) + end = MAXMEM - 1; res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { @@ -768,8 +431,10 @@ default: res->name = "reserved"; } - res->start = boot_mem_map.map[i].addr; - res->end = res->start + boot_mem_map.map[i].size - 1; + + res->start = start; + res->end = end; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); @@ -783,15 +448,244 @@ } } -void r3081_wait(void) +#undef PFN_UP +#undef PFN_DOWN +#undef PFN_PHYS + +#undef MAXMEM +#undef MAXMEM_PFN + + +void __init setup_arch(char **cmdline_p) { - unsigned long cfg = read_32bit_cp0_register(CP0_CONF); - write_32bit_cp0_register(CP0_CONF, cfg|CONF_HALT); + void atlas_setup(void); + void baget_setup(void); + void cobalt_setup(void); + void lasat_setup(void); + void ddb_setup(void); + void decstation_setup(void); + void deskstation_setup(void); + void jazz_setup(void); + void sni_rm200_pci_setup(void); + void ip22_setup(void); + void ev96100_setup(void); + void malta_setup(void); + void sead_setup(void); + void ikos_setup(void); + void momenco_ocelot_setup(void); + void momenco_ocelot_g_setup(void); + void momenco_ocelot_c_setup(void); + void nec_osprey_setup(void); + void nec_eagle_setup(void); + void zao_capcella_setup(void); + void victor_mpc30x_setup(void); + void ibm_workpad_setup(void); + void casio_e55_setup(void); + void jmr3927_setup(void); + void it8172_setup(void); + void swarm_setup(void); + void hp_setup(void); + void au1x00_setup(void); + void frame_info_init(void); + + frame_info_init(); + +#ifdef CONFIG_BLK_DEV_FD + fd_ops = &no_fd_ops; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &no_ide_ops; +#endif + + rtc_ops = &no_rtc_ops; + + switch(mips_machgroup) + { +#ifdef CONFIG_BAGET_MIPS + case MACH_GROUP_BAGET: + baget_setup(); + break; +#endif +#ifdef CONFIG_MIPS_COBALT + case MACH_GROUP_COBALT: + cobalt_setup(); + break; +#endif +#ifdef CONFIG_DECSTATION + case MACH_GROUP_DEC: + decstation_setup(); + break; +#endif +#ifdef CONFIG_MIPS_ATLAS + case MACH_GROUP_UNKNOWN: + atlas_setup(); + break; +#endif +#ifdef CONFIG_MIPS_JAZZ + case MACH_GROUP_JAZZ: + jazz_setup(); + break; +#endif +#ifdef CONFIG_MIPS_MALTA + case MACH_GROUP_UNKNOWN: + malta_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT + case MACH_GROUP_MOMENCO: + momenco_ocelot_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_G + case MACH_GROUP_MOMENCO: + momenco_ocelot_g_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_C + case MACH_GROUP_MOMENCO: + momenco_ocelot_c_setup(); + break; +#endif +#ifdef CONFIG_MIPS_SEAD + case MACH_GROUP_UNKNOWN: + sead_setup(); + break; +#endif +#ifdef CONFIG_SGI_IP22 + /* As of now this is only IP22. */ + case MACH_GROUP_SGI: + ip22_setup(); + break; +#endif +#ifdef CONFIG_SNI_RM200_PCI + case MACH_GROUP_SNI_RM: + sni_rm200_pci_setup(); + break; +#endif +#ifdef CONFIG_DDB5074 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_DDB5476 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_DDB5477 + case MACH_GROUP_NEC_DDB: + ddb_setup(); + break; +#endif +#ifdef CONFIG_CPU_VR41XX + case MACH_GROUP_NEC_VR41XX: + switch (mips_machtype) { +#ifdef CONFIG_NEC_OSPREY + case MACH_NEC_OSPREY: + nec_osprey_setup(); + break; +#endif +#ifdef CONFIG_NEC_EAGLE + case MACH_NEC_EAGLE: + nec_eagle_setup(); + break; +#endif +#ifdef CONFIG_ZAO_CAPCELLA + case MACH_ZAO_CAPCELLA: + zao_capcella_setup(); + break; +#endif +#ifdef CONFIG_VICTOR_MPC30X + case MACH_VICTOR_MPC30X: + victor_mpc30x_setup(); + break; +#endif +#ifdef CONFIG_IBM_WORKPAD + case MACH_IBM_WORKPAD: + ibm_workpad_setup(); + break; +#endif +#ifdef CONFIG_CASIO_E55 + case MACH_CASIO_E55: + casio_e55_setup(); + break; +#endif +#ifdef CONFIG_TANBAC_TB0229 + case MACH_TANBAC_TB0229: + tanbac_tb0229_setup(); + break; +#endif + } + break; +#endif +#ifdef CONFIG_MIPS_EV96100 + case MACH_GROUP_GALILEO: + ev96100_setup(); + break; +#endif +#ifdef CONFIG_MIPS_EV64120 + case MACH_GROUP_GALILEO: + ev64120_setup(); + break; +#endif +#if defined(CONFIG_MIPS_IVR) || defined(CONFIG_MIPS_ITE8172) + case MACH_GROUP_ITE: + case MACH_GROUP_GLOBESPAN: + it8172_setup(); + break; +#endif +#ifdef CONFIG_LASAT + case MACH_GROUP_LASAT: + lasat_setup(); + break; +#endif +#ifdef CONFIG_SOC_AU1X00 + case MACH_GROUP_ALCHEMY: + au1x00_setup(); + break; +#endif +#ifdef CONFIG_TOSHIBA_JMR3927 + case MACH_GROUP_TOSHIBA: + jmr3927_setup(); + break; +#endif +#ifdef CONFIG_TOSHIBA_RBTX4927 + case MACH_GROUP_TOSHIBA: + tx4927_setup(); + break; +#endif +#ifdef CONFIG_SIBYTE_BOARD + case MACH_GROUP_SIBYTE: + swarm_setup(); + break; +#endif +#ifdef CONFIG_HP_LASERJET + case MACH_GROUP_HP_LJ: + hp_setup(); + break; +#endif + default: + panic("Unsupported architecture"); + } + + strlcpy(command_line, arcs_cmdline, sizeof command_line); + strlcpy(saved_command_line, command_line, sizeof saved_command_line); + *cmdline_p = command_line; + + parse_cmdline_early(); + + bootmem_init(); + + paging_init(); + + resource_init(); } -void r4k_wait(void) +int __init fpu_disable(char *s) { - __asm__(".set\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); + cpu_data[0].options &= ~MIPS_CPU_FPU; + + return 1; } +__setup("nofpu", fpu_disable); diff -Nru a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c --- a/arch/mips/kernel/signal.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/kernel/signal.c Fri Jun 27 14:20:00 2003 @@ -10,19 +10,22 @@ #include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/personality.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/kernel.h> #include <linux/signal.h> #include <linux/errno.h> #include <linux/wait.h> -#include <linux/ptrace.h> #include <linux/unistd.h> #include <asm/asm.h> #include <asm/bitops.h> -#include <asm/pgalloc.h> -#include <asm/stackframe.h> +#include <asm/cacheflush.h> +#include <asm/cpu.h> +#include <asm/fpu.h> +#include <asm/offset.h> +#include <asm/ptrace.h> #include <asm/uaccess.h> #include <asm/ucontext.h> @@ -32,17 +35,13 @@ extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); - -extern asmlinkage void syscall_trace(void); +extern asmlinkage void do_syscall_trace(void); /* * Atomically swap in the new signal mask, and wait for a signal. */ save_static_function(sys_sigsuspend); -static_unused int -_sys_sigsuspend(struct pt_regs regs) +static_unused int _sys_sigsuspend(struct pt_regs regs) { sigset_t *uset, saveset, newset; @@ -51,11 +50,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); regs.regs[2] = EINTR; regs.regs[7] = 1; @@ -67,10 +66,8 @@ } } - save_static_function(sys_rt_sigsuspend); -static_unused int -_sys_rt_sigsuspend(struct pt_regs regs) +static_unused int _sys_rt_sigsuspend(struct pt_regs regs) { sigset_t *unewset, saveset, newset; size_t sigsetsize; @@ -85,11 +82,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); regs.regs[2] = EINTR; regs.regs[7] = 1; @@ -101,8 +98,8 @@ } } -asmlinkage int -sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +asmlinkage int sys_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -116,7 +113,6 @@ err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); if (err) return -EFAULT; @@ -134,7 +130,6 @@ err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); err |= __put_user(0, &oact->sa_mask.sig[3]); - err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); if (err) return -EFAULT; } @@ -142,8 +137,7 @@ return ret; } -asmlinkage int -sys_sigaltstack(struct pt_regs regs) +asmlinkage int sys_sigaltstack(struct pt_regs regs) { const stack_t *uss = (const stack_t *) regs.regs[4]; stack_t *uoss = (stack_t *) regs.regs[5]; @@ -152,10 +146,8 @@ return do_sigaltstack(uss, uoss, usp); } -asmlinkage int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; u64 reg; @@ -183,10 +175,15 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); - if (owned_fp) { + err |= __get_user(current->used_math, &sc->sc_used_math); + + if (current->used_math) { + /* restore fpu context if we have used it before */ + own_fpu(); err |= restore_fp_context(sc); - last_task_used_math = current; + } else { + /* signal handler may have used FPU. Give it up. */ + loose_fpu(); } return err; @@ -206,8 +203,7 @@ struct ucontext rs_uc; }; -asmlinkage void -sys_sigreturn(struct pt_regs regs) +asmlinkage void sys_sigreturn(struct pt_regs regs) { struct sigframe *frame; sigset_t blocked; @@ -219,10 +215,10 @@ goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = blocked; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(®s, &frame->sf_sc)) goto badframe; @@ -230,11 +226,11 @@ /* * Don't let your children do this ... */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); + if (current_thread_info()->flags & TIF_SYSCALL_TRACE) + do_syscall_trace(); __asm__ __volatile__( "move\t$29, %0\n\t" - "j\tret_from_sys_call" + "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ @@ -243,8 +239,7 @@ force_sig(SIGSEGV, current); } -asmlinkage void -sys_rt_sigreturn(struct pt_regs regs) +asmlinkage void sys_rt_sigreturn(struct pt_regs regs) { struct rt_sigframe *frame; sigset_t set; @@ -257,10 +252,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) goto badframe; @@ -276,7 +271,7 @@ */ __asm__ __volatile__( "move\t$29, %0\n\t" - "j\tret_from_sys_call" + "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ @@ -285,21 +280,20 @@ force_sig(SIGSEGV, current); } -static inline int -setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +static inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; u64 reg; - err |= __put_user(regs->cp0_epc, &sc->sc_pc); + reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc); err |= __put_user(regs->cp0_status, &sc->sc_status); #define save_gp_reg(i) { \ reg = regs->regs[i]; \ err |= __put_user(reg, &sc->sc_regs[i]); \ } while(0) - __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); + reg = 0; err |= __put_user(reg, &sc->sc_regs[0]); + save_gp_reg(1); save_gp_reg(2); save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); @@ -310,36 +304,48 @@ save_gp_reg(31); #undef save_gp_reg - err |= __put_user(regs->hi, &sc->sc_mdhi); - err |= __put_user(regs->lo, &sc->sc_mdlo); + reg = regs->hi; err |= __put_user(reg, &sc->sc_mdhi); + reg = regs->lo; err |= __put_user(reg, &sc->sc_mdlo); err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - owned_fp = (current == last_task_used_math); - err |= __put_user(owned_fp, &sc->sc_ownedfp); + err |= __put_user(current->used_math, &sc->sc_used_math); + + if (!current->used_math) + goto out; - if (current->used_math) { /* fp is active. */ - set_cp0_status(ST0_CU1); - err |= save_fp_context(sc); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - current->used_math = 0; + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. + */ + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); } + err |= save_fp_context(sc); +out: return err; } /* * Determine which stack to use.. */ -static inline void * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, + size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->regs[29]; + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + /* This is the X/Open sanctioned signal stack switching. */ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; @@ -347,9 +353,8 @@ return (void *)((sp - frame_size) & ALMASK); } -static void inline -setup_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set) { struct sigframe *frame; int err = 0; @@ -358,23 +363,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); + err |= __put_user(0x0000000c , frame->sf_code + 1); + flush_cache_sigtramp((unsigned long) frame->sf_code); err |= setup_sigcontext(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); @@ -399,8 +396,9 @@ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; #if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n", - current->comm, current->pid, frame, regs->cp0_epc, frame->code); + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, frame->sf_code); #endif return; @@ -410,9 +408,8 @@ force_sig(SIGSEGV, current); } -static void inline -setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set, siginfo_t *info) +static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set, siginfo_t *info) { struct rt_sigframe *frame; int err = 0; @@ -421,23 +418,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); @@ -475,8 +464,9 @@ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; #if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n", - current->comm, current->pid, frame, regs->cp0_epc, frame->code); + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, frame->rs_code); #endif return; @@ -486,31 +476,11 @@ force_sig(SIGSEGV, current); } -static inline void -handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs) +static inline void handle_signal(unsigned long sig, siginfo_t *info, + sigset_t *oldset, struct pt_regs * regs) { - struct k_sigaction *ka = ¤t->sig->action[sig-1]; + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; - if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(ka, regs, sig, oldset, info); - else - setup_frame(ka, regs, sig, oldset); - - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; - if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sigmask_lock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); - } -} - -static inline void -syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) -{ switch(regs->regs[0]) { case ERESTARTNOHAND: regs->regs[2] = EINTR; @@ -527,27 +497,33 @@ } regs->regs[0] = 0; /* Don't deal with this again. */ -} -extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(ka, regs, sig, oldset, info); + else + setup_frame(ka, regs, sig, oldset); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } +} asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) { siginfo_t info; - int sig_nr; - -#ifdef CONFIG_BINFMT_IRIX - if (current->personality != PER_LINUX) - return do_irix_signal(oldset, regs); -#endif + int signr; if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { - if (regs->regs[0]) - syscall_restart(regs, ka); /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); return 1; @@ -567,4 +543,25 @@ } } return 0; +} + +extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); + +/* + * notification of userspace execution resumption + * - triggered by current->work.notify_resume + */ +asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, + __u32 thread_info_flags) +{ + /* deal with pending signal delivery */ + if (thread_info_flags & _TIF_SIGPENDING) { +#ifdef CONFIG_BINFMT_IRIX + if (unlikely(current->personality != PER_LINUX)) { + do_irix_signal(oldset, regs); + return; + } +#endif + do_signal(oldset, regs); + } } diff -Nru a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c --- a/arch/mips/kernel/smp.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/smp.c Fri Jun 27 14:19:54 2003 @@ -1,11 +1,4 @@ /* - * - * arch/mips/kernel/smp.c - * - * Copyright (C) 2000 Sibyte - * - * Written by Justin Carlson (carlson@sibyte.com) - * * 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 @@ -15,229 +8,256 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - */ - - + * Copyright (C) 2000, 2001 Kanoj Sarcar + * Copyright (C) 2000, 2001 Ralf Baechle + * Copyright (C) 2000, 2001 Silicon Graphics, Inc. + * Copyright (C) 2000, 2001 Broadcom Corporation + */ #include <linux/config.h> +#include <linux/cache.h> +#include <linux/delay.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/spinlock.h> #include <linux/threads.h> +#include <linux/module.h> #include <linux/time.h> #include <linux/timex.h> #include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/cache.h> #include <asm/atomic.h> +#include <asm/cpu.h> #include <asm/processor.h> #include <asm/system.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> -#include <asm/delay.h> #include <asm/smp.h> -/* - * This was written with the BRCM12500 MP SOC in mind, but tries to - * be generic. It's modelled on the mips64 smp.c code, which is - * derived from Sparc, I'm guessing, which is derived from... - * - * It's probably horribly designed for very large ccNUMA systems - * as it doesn't take any node clustering into account. -*/ - - -/* Ze Big Kernel Lock! */ -int smp_threads_ready; /* Not used */ -int smp_num_cpus; -int global_irq_holder = NO_PROC_ID; -spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; -struct mips_cpuinfo cpu_data[NR_CPUS]; - -struct smp_fn_call_struct smp_fn_call = -{ SPIN_LOCK_UNLOCKED, ATOMIC_INIT(0), NULL, NULL}; +int smp_threads_ready; /* Not used */ -static atomic_t cpus_booted = ATOMIC_INIT(0); +// static atomic_t cpus_booted = ATOMIC_INIT(0); +atomic_t cpus_booted = ATOMIC_INIT(0); +cpumask_t phys_cpu_present_map; /* Bitmask of physically CPUs */ +cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ +int __cpu_number_map[NR_CPUS]; +int __cpu_logical_map[NR_CPUS]; /* These are defined by the board-specific code. */ -/* Cause the function described by smp_fn_call - to be executed on the passed cpu. When the function - has finished, increment the finished field of - smp_fn_call. */ - -void core_call_function(int cpu); +/* + * Cause the function described by call_data to be executed on the passed + * cpu. When the function has finished, increment the finished field of + * call_data. + */ +void core_send_ipi(int cpu, unsigned int action); /* * Clear all undefined state in the cpu, set up sp and gp to the passed - * values, and kick the cpu into smp_bootstrap(); + * values, and kick the cpu into smp_bootstrap(); */ void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); /* * After we've done initial boot, this function is called to allow the - * board code to clean up state, if needed + * board code to clean up state, if needed */ - void prom_init_secondary(void); +void prom_smp_finish(void); -void cpu_idle(void); - -/* Do whatever setup needs to be done for SMP at the board level. Return - the number of cpus in the system, including this one */ -int prom_setup_smp(void); - -int start_secondary(void *unused) -{ - prom_init_secondary(); - write_32bit_cp0_register(CP0_CONTEXT, smp_processor_id()<<23); - current_pgd[smp_processor_id()] = init_mm.pgd; - printk("Slave cpu booted successfully\n"); - atomic_inc(&cpus_booted); - cpu_idle(); - return 0; -} +cycles_t cacheflush_time; +unsigned long cache_decay_ticks; -void __init smp_boot_cpus(void) +void smp_tune_scheduling (void) { - int i; - - smp_num_cpus = prom_setup_smp(); - init_new_context(current, &init_mm); - current->processor = 0; - atomic_set(&cpus_booted, 1); /* Master CPU is already booted... */ - init_idle(); - for (i = 1; i < smp_num_cpus; i++) { - struct task_struct *p; - struct pt_regs regs; - printk("Starting CPU %d... ", i); - - /* Spawn a new process normally. Grab a pointer to - its task struct so we can mess with it */ - p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0); - - /* Schedule the first task manually */ - p->processor = i; - p->cpus_runnable = 1 << i; /* we schedule the first task manually */ - - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; - init_tasks[i] = p; - - del_from_runqueue(p); - unhash_process(p); - - prom_boot_secondary(i, - (unsigned long)p + KERNEL_STACK_SIZE - 32, - (unsigned long)p); + struct cache_desc *cd = ¤t_cpu_data.scache; + unsigned long cachesize; /* kB */ + unsigned long bandwidth = 350; /* MB/s */ + unsigned long cpu_khz; -#if 0 - - /* This is copied from the ip-27 code in the mips64 tree */ - - struct task_struct *p; + /* + * Crude estimate until we actually meassure ... + */ + cpu_khz = loops_per_jiffy * 2 * HZ / 1000; + /* + * Rough estimation for SMP scheduling, this is the number of + * cycles it takes for a fully memory-limited process to flush + * the SMP-local cache. + * + * (For a P5 this pretty much means we will choose another idle + * CPU almost always at wakeup time (this is due to the small + * L1 cache), on PIIs it's around 50-100 usecs, depending on + * the cache size) + */ + if (!cpu_khz) { /* - * The following code is purely to make sure - * Linux can schedule processes on this slave. + * This basically disables processor-affinity scheduling on SMP + * without a cycle counter. Currently all SMP capable MIPS + * processors have a cycle counter. */ - kernel_thread(0, NULL, CLONE_IDLETASK); - p = prev_task(&init_task); - sprintf(p->comm, "%s%d", "Idle", i); - init_tasks[i] = p; - p->processor = i; - p->cpus_runnable = 1 << i; /* we schedule the first task manually */ - del_from_runqueue(p); - unhash_process(p); - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; - prom_boot_secondary(i, - (unsigned long)p + KERNEL_STACK_SIZE - 32, - (unsigned long)p); -#endif + cacheflush_time = 0; + return; } - /* Wait for everyone to come up */ - while (atomic_read(&cpus_booted) != smp_num_cpus); + cachesize = cd->linesz * cd->sets * cd->ways; + cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth; + cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000; + + printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", + (long)cacheflush_time/(cpu_khz/1000), + ((long)cacheflush_time*100/(cpu_khz/1000)) % 100); + printk("task migration cache decay timeout: %ld msecs.\n", + (cache_decay_ticks + 1) * 1000 / HZ); } -void __init smp_commence(void) +void __init smp_callin(void) { - /* Not sure what to do here yet */ +#if 0 + calibrate_delay(); + smp_store_cpu_info(cpuid); +#endif } -static void reschedule_this_cpu(void *dummy) +#ifndef CONFIG_SGI_IP27 +/* + * Hook for doing final board-specific setup after the generic smp setup + * is done + */ +asmlinkage void start_secondary(void) { - current->work.need_resched = 1; + unsigned int cpu = smp_processor_id(); + + cpu_probe(); + prom_init_secondary(); + per_cpu_trap_init(); + + /* + * XXX parity protection should be folded in here when it's converted + * to an option instead of something based on .cputype + */ + pgd_current[cpu] = init_mm.pgd; + cpu_data[cpu].udelay_val = loops_per_jiffy; + prom_smp_finish(); + printk("Slave cpu booted successfully\n"); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + cpu_idle(); } +#endif /* CONFIG_SGI_IP27 */ -void FASTCALL(smp_send_reschedule(int cpu)) +/* + * this function sends a 'reschedule' IPI to another CPU. + * it goes straight through and wastes no time serializing + * anything. Worst case is that we lose a reschedule ... + */ +void smp_send_reschedule(int cpu) { - smp_call_function(reschedule_this_cpu, NULL, 0, 0); + core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); } +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; + +struct call_data_struct *call_data; /* - * The caller of this wants the passed function to run on every cpu. If wait - * is set, wait until all cpus have finished the function before returning. - * The lock is here to protect the call structure. + * Run a function on all other CPUs. + * <func> The function to run. This must be fast and non-blocking. + * <info> An arbitrary pointer to pass to the function. + * <retry> If true, keep retrying until ready. + * <wait> If true, wait until function has completed on other CPUs. + * [RETURNS] 0 on success, else a negative status code. + * + * Does not return until remote CPUs are nearly ready to execute <func> + * or are or have executed. + * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -int smp_call_function (void (*func) (void *info), void *info, int retry, +int smp_call_function (void (*func) (void *info), void *info, int retry, int wait) { - int cpus = smp_num_cpus - 1; - int i; + struct call_data_struct data; + int i, cpus = num_online_cpus() - 1; + int cpu = smp_processor_id(); - if (smp_num_cpus < 2) { + if (!cpus) return 0; - } - - spin_lock(&smp_fn_call.lock); - atomic_set(&smp_fn_call.finished, 0); - smp_fn_call.fn = func; - smp_fn_call.data = info; - - for (i = 0; i < smp_num_cpus; i++) { - if (i != smp_processor_id()) { - /* Call the board specific routine */ - core_call_function(i); - } - } - - if (wait) { - while(atomic_read(&smp_fn_call.finished) != cpus) {} - } + data.func = func; + data.info = info; + atomic_set(&data.started, 0); + data.wait = wait; + if (wait) + atomic_set(&data.finished, 0); + + spin_lock(&call_lock); + call_data = &data; + + /* Send a message to all other CPUs and wait for them to respond */ + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(cpu) && cpu != smp_processor_id()) + core_send_ipi(i, SMP_CALL_FUNCTION); + + /* Wait for response */ + /* FIXME: lock-up detection, backtrace on lock-up */ + while (atomic_read(&data.started) != cpus) + barrier(); + + if (wait) + while (atomic_read(&data.finished) != cpus) + barrier(); + spin_unlock(&call_lock); - spin_unlock(&smp_fn_call.lock); return 0; } -void synchronize_irq(void) +void smp_call_function_interrupt(void) { - panic("synchronize_irq"); + void (*func) (void *info) = call_data->func; + void *info = call_data->info; + int wait = call_data->wait; + + irq_enter(); + /* + * Notify initiating CPU that I've grabbed the data and am + * about to execute the function. + */ + mb(); + atomic_inc(&call_data->started); + + /* + * At this point the info structure may be out of scope unless wait==1. + */ + irq_enter(); + (*func)(info); + irq_exit(); + + if (wait) { + mb(); + atomic_inc(&call_data->finished); + } } static void stop_this_cpu(void *dummy) { - printk("Cpu stopping\n"); - for (;;); + /* + * Remove this CPU: + */ + clear_bit(smp_processor_id(), &cpu_online_map); + local_irq_enable(); /* May need to service _machine_restart IPI */ + for (;;); /* Wait if available. */ } void smp_send_stop(void) { smp_call_function(stop_this_cpu, NULL, 1, 0); - smp_num_cpus = 1; } /* Not really SMP stuff ... */ @@ -246,157 +266,142 @@ return 0; } +static void flush_tlb_all_ipi(void *info) +{ + local_flush_tlb_all(); +} + +void flush_tlb_all(void) +{ + on_each_cpu(flush_tlb_all_ipi, 0, 1, 1); +} + +static void flush_tlb_mm_ipi(void *mm) +{ + local_flush_tlb_mm((struct mm_struct *)mm); +} /* - * Most of this code is take from the mips64 tree (ip27-irq.c). It's virtually - * identical to the i386 implentation in arh/i386/irq.c, with translations for - * the interrupt enable bit + * The following tlb flush calls are invoked when old translations are + * being torn down, or pte attributes are changing. For single threaded + * address spaces, a new context is obtained on the current cpu, and tlb + * context on other cpus are invalidated to force a new context allocation + * at switch_mm time, should the mm ever be used on other cpus. For + * multithreaded address spaces, intercpu interrupts have to be sent. + * Another case where intercpu interrupts are required is when the target + * mm might be active on another cpu (eg debuggers doing the flushes on + * behalf of debugees, kswapd stealing pages from another process etc). + * Kanoj 07/00. */ -#define MAXCOUNT 100000000 -#define SYNC_OTHER_CORES(x) udelay(x+1) - -static inline void wait_on_irq(int cpu) +void flush_tlb_mm(struct mm_struct *mm) { - int count = MAXCOUNT; - - for (;;) { + preempt_disable(); - /* - * Wait until all interrupts are gone. Wait - * for bottom half handlers unless we're - * already executing in one.. - */ - if (!irqs_running()) - if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) - break; - - /* Duh, we have to loop. Release the lock to avoid deadlocks */ - spin_unlock(&global_irq_lock); - - for (;;) { - if (!--count) { - printk("Count spun out. Huh?\n"); - count = ~0; - } - local_irq_enable(); - SYNC_OTHER_CORES(cpu); - local_irq_disable(); - if (irqs_running()) - continue; - if (spin_is_locked(&global_irq_lock)) - continue; - if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) - continue; - if (spin_trylock(&global_irq_lock)) - break; - } + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { + smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); + } else { + int i; + for (i = 0; i < num_online_cpus(); i++) + if (smp_processor_id() != i) + cpu_context(i, mm) = 0; } + local_flush_tlb_mm(mm); + + preempt_enable(); } +struct flush_tlb_data { + struct vm_area_struct *vma; + unsigned long addr1; + unsigned long addr2; +}; -static inline void get_irqlock(int cpu) +static void flush_tlb_range_ipi(void *info) { - if (!spin_trylock(&global_irq_lock)) { - /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait.. */ - spin_lock(&global_irq_lock); - } - /* - * We also to make sure that nobody else is running - * in an interrupt context. - */ - wait_on_irq(cpu); + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; - /* - * Ok, finally.. - */ - global_irq_holder = cpu; + local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2); } - -/* - * A global "cli()" while in an interrupt context - * turns into just a local cli(). Interrupts - * should use spinlocks for the (very unlikely) - * case that they ever want to protect against - * each other. - * - * If we already have local interrupts disabled, - * this will not turn a local disable into a - * global one (problems with spinlocks: this makes - * save_flags+cli+sti usable inside a spinlock). - */ -void __global_cli(void) +void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - unsigned int flags; + struct mm_struct *mm = vma->vm_mm; - local_save_flags(flags); - if (flags & ST0_IE) { - int cpu = smp_processor_id(); - local_irq_disable(); - if (!local_irq_count(cpu)) - get_irqlock(cpu); + preempt_disable(); + if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { + struct flush_tlb_data fd; + + fd.vma = vma; + fd.addr1 = start; + fd.addr2 = end; + smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1); + } else { + int i; + for (i = 0; i < num_online_cpus(); i++) + if (smp_processor_id() != i) + cpu_context(i, mm) = 0; } + local_flush_tlb_range(vma, start, end); + preempt_enable(); } -void __global_sti(void) +static void flush_tlb_kernel_range_ipi(void *info) { - int cpu = smp_processor_id(); + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; - if (!local_irq_count(cpu)) - release_irqlock(cpu); - local_irq_enable(); + local_flush_tlb_kernel_range(fd->addr1, fd->addr2); } -/* - * SMP flags value to restore to: - * 0 - global cli - * 1 - global sti - * 2 - local cli - * 3 - local sti - */ -unsigned long __global_save_flags(void) +void flush_tlb_kernel_range(unsigned long start, unsigned long end) { - int retval; - int local_enabled; - unsigned long flags; - int cpu = smp_processor_id(); + struct flush_tlb_data fd; - local_save_flags(flags); - local_enabled = (flags & ST0_IE); - /* default to local */ - retval = 2 + local_enabled; - - /* check for global flags if we're not in an interrupt */ - if (!local_irq_count(cpu)) { - if (local_enabled) - retval = 1; - if (global_irq_holder == cpu) - retval = 0; - } + fd.addr1 = start; + fd.addr2 = end; + on_each_cpu(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1); +} + +static void flush_tlb_page_ipi(void *info) +{ + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; - return retval; + local_flush_tlb_page(fd->vma, fd->addr1); } -void __global_restore_flags(unsigned long flags) +void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { - switch (flags) { - case 0: - __global_cli(); - break; - case 1: - __global_sti(); - break; - case 2: - local_irq_disable(); - break; - case 3: - local_irq_enable(); - break; - default: - printk("global_restore_flags: %08lx\n", flags); + preempt_disable(); + if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { + struct flush_tlb_data fd; + + fd.vma = vma; + fd.addr1 = page; + smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1); + } else { + int i; + for (i = 0; i < num_online_cpus(); i++) + if (smp_processor_id() != i) + cpu_context(i, vma->vm_mm) = 0; } + local_flush_tlb_page(vma, page); + preempt_enable(); } + +static void flush_tlb_one_ipi(void *info) +{ + unsigned long vaddr = (unsigned long) info; + + local_flush_tlb_one(vaddr); +} + +void flush_tlb_one(unsigned long vaddr) +{ + smp_call_function(flush_tlb_one_ipi, (void *) vaddr, 1, 1); + local_flush_tlb_one(vaddr); +} + +EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(flush_tlb_one); +EXPORT_SYMBOL(cpu_data); +EXPORT_SYMBOL(synchronize_irq); diff -Nru a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c --- a/arch/mips/kernel/syscall.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/kernel/syscall.c Fri Jun 27 14:20:00 2003 @@ -14,6 +14,7 @@ #undef CONF_DEBUG_IRIX #include <linux/config.h> +#include <linux/compiler.h> #include <linux/linkage.h> #include <linux/mm.h> #include <linux/smp.h> @@ -28,7 +29,7 @@ #include <asm/offset.h> #include <asm/ptrace.h> #include <asm/signal.h> -#include <asm/stackframe.h> +#include <asm/shmparam.h> #include <asm/uaccess.h> extern asmlinkage void syscall_trace(void); @@ -54,6 +55,61 @@ return res; } +unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ + +#define COLOUR_ALIGN(addr,pgoff) \ + ((((addr) + shm_align_mask) & ~shm_align_mask) + \ + (((pgoff) << PAGE_SHIFT) & shm_align_mask)) + +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct vm_area_struct * vmm; + int do_color_align; + + if (flags & MAP_FIXED) { + /* + * We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ + if ((flags & MAP_SHARED) && (addr & shm_align_mask)) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + do_color_align = 0; + if (filp || (flags & MAP_SHARED)) + do_color_align = 1; + if (addr) { + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + vmm = find_vma(current->mm, addr); + if (TASK_SIZE - len >= addr && + (!vmm || addr + len <= vmm->vm_start)) + return addr; + } + addr = TASK_UNMAPPED_BASE; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { + /* At this point: (!vmm || addr < vmm->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; + if (!vmm || addr + len <= vmm->vm_start) + return addr; + addr = vmm->vm_end; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + } +} + /* common code for old and new mmaps */ static inline long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, @@ -82,7 +138,16 @@ asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot, int flags, int fd, off_t offset) { - return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + int result; + + result = -EINVAL; + if (offset & ~PAGE_MASK) + goto out; + + result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); + +out: + return result; } asmlinkage long @@ -95,10 +160,7 @@ save_static_function(sys_fork); static_unused int _sys_fork(struct pt_regs regs) { - struct task_struct *p; - - p = do_fork(SIGCHLD, regs.regs[29], ®s, 0); - return IS_ERR(p) ? PTR_ERR(p) : p->pid; + return do_fork(SIGCHLD, regs.regs[29], ®s, 0, NULL, NULL); } @@ -107,14 +169,16 @@ { unsigned long clone_flags; unsigned long newsp; - struct task_struct *p; + int *parent_tidptr, *child_tidptr; clone_flags = regs.regs[4]; newsp = regs.regs[5]; if (!newsp) newsp = regs.regs[29]; - p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0); - return IS_ERR(p) ? PTR_ERR(p) : p->pid; + parent_tidptr = (int *) regs.regs[6]; + child_tidptr = (int *) regs.regs[7]; + return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, + parent_tidptr, child_tidptr); } /* @@ -158,7 +222,7 @@ return -EFAULT; if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); error -= __put_user(0,name->sysname+__OLD_UTS_LEN); error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); @@ -172,76 +236,6 @@ error = error ? -EFAULT : 0; return error; -} - -/* - * Do the indirect syscall syscall. - * Don't care about kernel locking; the actual syscall will do it. - * - * XXX This is borken. - */ -asmlinkage int sys_syscall(struct pt_regs regs) -{ - syscall_t syscall; - unsigned long syscallnr = regs.regs[4]; - unsigned long a0, a1, a2, a3, a4, a5, a6; - int nargs, errno; - - if (syscallnr > __NR_Linux + __NR_Linux_syscalls) - return -ENOSYS; - - syscall = sys_call_table[syscallnr]; - nargs = sys_narg_table[syscallnr]; - /* - * Prevent stack overflow by recursive - * syscall(__NR_syscall, __NR_syscall,...); - */ - if (syscall == (syscall_t) sys_syscall) { - return -EINVAL; - } - - if (syscall == NULL) { - return -ENOSYS; - } - - if(nargs > 3) { - unsigned long usp = regs.regs[29]; - unsigned long *sp = (unsigned long *) usp; - if(usp & 3) { - printk("unaligned usp -EFAULT\n"); - force_sig(SIGSEGV, current); - return -EFAULT; - } - errno = verify_area(VERIFY_READ, (void *) (usp + 16), - (nargs - 3) * sizeof(unsigned long)); - if(errno) { - return -EFAULT; - } - switch(nargs) { - case 7: - a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = sp[7]; - break; - case 6: - a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = 0; - break; - case 5: - a3 = sp[4]; a4 = sp[5]; a5 = a6 = 0; - break; - case 4: - a3 = sp[4]; a4 = a5 = a6 = 0; - break; - - default: - a3 = a4 = a5 = a6 = 0; - break; - } - } else { - a3 = a4 = a5 = a6 = 0; - } - a0 = regs.regs[5]; a1 = regs.regs[6]; a2 = regs.regs[7]; - if(nargs == 0) - a0 = (unsigned long) ®s; - return syscall((void *)a0, a1, a2, a3, a4, a5, a6); } /* diff -Nru a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h --- a/arch/mips/kernel/syscalls.h Fri Jun 27 14:19:52 2003 +++ b/arch/mips/kernel/syscalls.h Fri Jun 27 14:19:52 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001, 2002 by Ralf Baechle */ /* @@ -20,7 +20,7 @@ SYS(sys_read, 3) SYS(sys_write, 3) SYS(sys_open, 3) /* 4005 */ -SYS(sys_close, 3) +SYS(sys_close, 1) SYS(sys_waitpid, 3) SYS(sys_creat, 2) SYS(sys_link, 2) @@ -32,7 +32,7 @@ SYS(sys_chmod, 2) /* 4015 */ SYS(sys_lchown, 3) SYS(sys_ni_syscall, 0) -SYS(sys_stat, 2) +SYS(sys_ni_syscall, 0) /* was sys_stat */ SYS(sys_lseek, 3) SYS(sys_getpid, 0) /* 4020 */ SYS(sys_mount, 5) @@ -42,7 +42,7 @@ SYS(sys_stime, 1) /* 4025 */ SYS(sys_ptrace, 4) SYS(sys_alarm, 1) -SYS(sys_fstat, 2) +SYS(sys_ni_syscall, 0) /* was sys_fstat */ SYS(sys_pause, 0) SYS(sys_utime, 2) /* 4030 */ SYS(sys_ni_syscall, 0) @@ -96,9 +96,9 @@ SYS(sys_settimeofday, 2) SYS(sys_getgroups, 2) /* 4080 */ SYS(sys_setgroups, 2) -SYS(sys_ni_syscall, 0) /* old_select */ +SYS(sys_ni_syscall, 0) /* old_select */ SYS(sys_symlink, 2) -SYS(sys_lstat, 2) +SYS(sys_ni_syscall, 0) /* was sys_lstat */ SYS(sys_readlink, 3) /* 4085 */ SYS(sys_uselib, 1) SYS(sys_swapon, 2) @@ -115,7 +115,7 @@ SYS(sys_ni_syscall, 0) SYS(sys_statfs, 2) SYS(sys_fstatfs, 2) /* 4100 */ -SYS(sys_ioperm, 3) +SYS(sys_ni_syscall, 0) /* was ioperm(2) */ SYS(sys_socketcall, 2) SYS(sys_syslog, 3) SYS(sys_setitimer, 3) @@ -124,10 +124,10 @@ SYS(sys_newlstat, 2) SYS(sys_newfstat, 2) SYS(sys_uname, 1) -SYS(sys_iopl, 0) /* Well, actually 17 args ... */ /* 4110 */ +SYS(sys_ni_syscall, 0) /* 4110 was iopl(2) */ SYS(sys_vhangup, 0) -SYS(sys_ni_syscall, 0) /* was sys_idle() */ -SYS(sys_vm86, 1) +SYS(sys_ni_syscall, 0) /* was sys_idle() */ +SYS(sys_ni_syscall, 0) /* was sys_vm86 */ SYS(sys_wait4, 4) SYS(sys_swapoff, 1) /* 4115 */ SYS(sys_sysinfo, 1) @@ -141,10 +141,10 @@ SYS(sys_adjtimex, 1) SYS(sys_mprotect, 3) /* 4125 */ SYS(sys_sigprocmask, 3) -SYS(sys_create_module, 2) +SYS(sys_ni_syscall, 0) /* was create_module */ SYS(sys_init_module, 5) SYS(sys_delete_module, 1) -SYS(sys_get_kernel_syms, 1) /* 4130 */ +SYS(sys_ni_syscall, 0) /* 4130, was get_kernel_syms */ SYS(sys_quotactl, 0) SYS(sys_getpgid, 1) SYS(sys_fchdir, 1) @@ -201,7 +201,7 @@ SYS(sys_socketpair, 4) SYS(sys_setresuid, 3) /* 4185 */ SYS(sys_getresuid, 3) -SYS(sys_query_module, 5) +SYS(sys_ni_syscall, 0) /* sys_query_module */ SYS(sys_poll, 3) SYS(sys_nfsservctl, 3) SYS(sys_setresgid, 3) /* 4190 */ @@ -214,19 +214,19 @@ SYS(sys_rt_sigtimedwait, 4) SYS(sys_rt_sigqueueinfo, 3) SYS(sys_rt_sigsuspend, 0) -SYS(sys_pread, 6) /* 4200 */ -SYS(sys_pwrite, 6) +SYS(sys_pread64, 6) /* 4200 */ +SYS(sys_pwrite64, 6) SYS(sys_chown, 3) SYS(sys_getcwd, 2) SYS(sys_capget, 2) SYS(sys_capset, 2) /* 4205 */ SYS(sys_sigaltstack, 0) -SYS(sys_sendfile, 3) +SYS(sys_sendfile, 4) SYS(sys_ni_syscall, 0) SYS(sys_ni_syscall, 0) SYS(sys_mmap2, 6) /* 4210 */ -SYS(sys_truncate64, 2) -SYS(sys_ftruncate64, 2) +SYS(sys_truncate64, 4) +SYS(sys_ftruncate64, 4) SYS(sys_stat64, 2) SYS(sys_lstat64, 2) SYS(sys_fstat64, 2) /* 4215 */ @@ -235,5 +235,39 @@ SYS(sys_madvise, 3) SYS(sys_getdents64, 3) SYS(sys_fcntl64, 3) /* 4220 */ +SYS(sys_ni_syscall, 0) SYS(sys_gettid, 0) +SYS(sys_readahead, 5) +SYS(sys_setxattr, 5) +SYS(sys_lsetxattr, 5) /* 4225 */ +SYS(sys_fsetxattr, 5) +SYS(sys_getxattr, 4) +SYS(sys_lgetxattr, 4) +SYS(sys_fgetxattr, 4) +SYS(sys_listxattr, 3) /* 4230 */ +SYS(sys_llistxattr, 3) +SYS(sys_flistxattr, 3) +SYS(sys_removexattr, 2) +SYS(sys_lremovexattr, 2) +SYS(sys_fremovexattr, 2) /* 4235 */ SYS(sys_tkill, 2) +SYS(sys_sendfile64, 5) +SYS(sys_futex, 2) +SYS(sys_sched_setaffinity, 3) +SYS(sys_sched_getaffinity, 3) /* 4240 */ +SYS(sys_io_setup, 2) +SYS(sys_io_destroy, 1) +SYS(sys_io_getevents, 5) +SYS(sys_io_submit, 3) +SYS(sys_io_cancel, 3) /* 4245 */ +SYS(sys_exit_group, 1) +SYS(sys_lookup_dcookie, 3) +SYS(sys_epoll_create, 1) +SYS(sys_epoll_ctl, 4) +SYS(sys_epoll_wait, 3) /* 4250 */ +SYS(sys_remap_file_pages, 5) +SYS(sys_set_tid_address, 1) +SYS(sys_restart_syscall, 0) /* XXX */ +SYS(sys_fadvise64, 6) +SYS(sys_statfs64, 3) /* 4255 */ +SYS(sys_fstatfs64, 2) diff -Nru a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c --- a/arch/mips/kernel/sysirix.c Fri Jun 27 14:20:04 2003 +++ b/arch/mips/kernel/sysirix.c Fri Jun 27 14:20:04 2003 @@ -7,6 +7,8 @@ */ #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/binfmts.h> +#include <linux/highuid.h> #include <linux/pagemap.h> #include <linux/mm.h> #include <linux/mman.h> @@ -24,6 +26,8 @@ #include <linux/utsname.h> #include <linux/file.h> #include <linux/vfs.h> +#include <linux/namei.h> +#include <linux/socket.h> #include <asm/ptrace.h> #include <asm/page.h> @@ -55,7 +59,7 @@ break; case MP_NPROCS: case MP_NAPROCS: - error = smp_num_cpus; + error = num_online_cpus(); break; default: printk("SYSMP[%s:%d]: Unsupported opcode %d\n", @@ -111,7 +115,7 @@ if (error) error = (task->run_list.next != NULL); read_unlock(&tasklist_lock); - /* Can _your_ OS find this out that fast? */ + /* Can _your_ OS find this out that fast? */ break; } @@ -334,7 +338,7 @@ current->comm, current->pid, name, value, retval); /* if (retval == PROM_ENOENT) retval = -ENOENT; */ - break; + break; } #endif @@ -507,7 +511,7 @@ } break; } - + default: printk("irix_syssgi: Unsupported command %d\n", (int)cmd); retval = -EINVAL; @@ -600,7 +604,7 @@ asmlinkage int irix_getpid(struct pt_regs *regs) { - regs->regs[3] = current->p_opptr->pid; + regs->regs[3] = current->real_parent->pid; return current->pid; } @@ -623,9 +627,11 @@ write_seqlock_irq(&xtime_lock); xtime.tv_sec = value; - xtime.tv_usec = 0; - time_maxerror = MAXPHASE; - time_esterror = MAXPHASE; + xtime.tv_nsec = 0; + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; write_sequnlock_irq(&xtime_lock); return 0; @@ -819,10 +825,10 @@ err = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf); if (err) return err; - err |= __put_user(current->times.tms_utime,&tbuf->tms_utime); - err |= __put_user(current->times.tms_stime,&tbuf->tms_stime); - err |= __put_user(current->times.tms_cutime,&tbuf->tms_cutime); - err |= __put_user(current->times.tms_cstime,&tbuf->tms_cstime); + err |= __put_user(current->utime, &tbuf->tms_utime); + err |= __put_user(current->stime, &tbuf->tms_stime); + err |= __put_user(current->cutime, &tbuf->tms_cutime); + err |= __put_user(current->cstime, &tbuf->tms_cstime); } return err; @@ -1048,7 +1054,23 @@ asmlinkage int irix_gettimeofday(struct timeval *tv) { - return copy_to_user(tv, &xtime, sizeof(*tv)) ? -EFAULT : 0; + time_t sec; + long nsec, seq; + int err; + + if (verify_area(VERIFY_WRITE, tv, sizeof(struct timeval))) + return -EFAULT; + + do { + seq = read_seqbegin(&xtime_lock); + sec = xtime.tv_sec; + nsec = xtime.tv_nsec; + } while (read_seqretry(&xtime_lock, seq)); + + err = __put_user(sec, &tv->tv_sec); + err |= __put_user((nsec / 1000), &tv->tv_usec); + + return err; } #define IRIX_MAP_AUTOGROW 0x40 @@ -1068,7 +1090,7 @@ if (flags & IRIX_MAP_AUTOGROW) { unsigned long old_pos; long max_size = offset + len; - + if (max_size > file->f_dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, "", 1); @@ -1198,14 +1220,14 @@ #if BITS_PER_LONG == 32 if (stat->size > MAX_NON_LFS) return -EOVERFLOW; -#endif +#endif ub.st_size = stat->size; - ub.st_atime0 = stat->atime; - ub.st_atime1 = 0; - ub.st_mtime0 = stat->mtime; - ub.st_mtime1 = 0; - ub.st_ctime0 = stat->ctime; - ub.st_ctime1 = 0; + ub.st_atime0 = stat->atime.tv_sec; + ub.st_atime1 = stat->atime.tv_nsec; + ub.st_mtime0 = stat->mtime.tv_sec; + ub.st_mtime1 = stat->atime.tv_nsec; + ub.st_ctime0 = stat->ctime.tv_sec; + ub.st_ctime1 = stat->atime.tv_nsec; ub.st_blksize = stat->blksize; ub.st_blocks = stat->blocks; strcpy (ub.st_fstype, "efs"); @@ -1243,9 +1265,12 @@ ks.st_pad3 = 0; /* XXX hackety hack... */ - ks.st_atime.tv_sec = (s32) stat->atime; ks.st_atime.tv_nsec = 0; - ks.st_mtime.tv_sec = (s32) stat->atime; ks.st_mtime.tv_nsec = 0; - ks.st_ctime.tv_sec = (s32) stat->atime; ks.st_ctime.tv_nsec = 0; + ks.st_atime.tv_sec = (s32) stat->atime.tv_sec; + ks.st_atime.tv_nsec = stat->atime.tv_nsec; + ks.st_mtime.tv_sec = (s32) stat->mtime.tv_sec; + ks.st_mtime.tv_nsec = stat->mtime.tv_nsec;; + ks.st_ctime.tv_sec = (s32) stat->ctime.tv_sec; + ks.st_ctime.tv_nsec = stat->ctime.tv_nsec;; ks.st_blksize = (s32) stat->blksize; ks.st_blocks = (long long) stat->blocks; @@ -1812,7 +1837,8 @@ return 0; } -asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob) +asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, + unsigned int count, int *eob) { struct file *file; struct irix_dirent32 *lastdirent; @@ -1836,6 +1862,7 @@ error = vfs_readdir(file, irix_filldir32, &buf); if (error < 0) goto out_putf; + error = buf.error; lastdirent = buf.previous; if (lastdirent) { @@ -1844,10 +1871,9 @@ } if (put_user(0, eob) < 0) { - error = EFAULT; + error = -EFAULT; goto out_putf; } - #ifdef DEBUG_GETDENTS printk("eob=%d returning %d\n", *eob, count - buf.count); diff -Nru a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c --- a/arch/mips/kernel/sysmips.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/kernel/sysmips.c Fri Jun 27 14:19:54 2003 @@ -1,13 +1,11 @@ /* - * MIPS specific syscalls - * * 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) 1995, 1996, 1997, 2000 by Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 2000, 2001 by Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. */ -#include <linux/config.h> #include <linux/errno.h> #include <linux/linkage.h> #include <linux/mm.h> @@ -19,7 +17,7 @@ #include <linux/ptrace.h> #include <asm/cachectl.h> -#include <asm/pgalloc.h> +#include <asm/cacheflush.h> #include <asm/sysmips.h> #include <asm/uaccess.h> @@ -49,11 +47,10 @@ } asmlinkage int -sys_sysmips(int cmd, int arg1, int arg2, int arg3) +_sys_sysmips(int cmd, int arg1, int arg2, int arg3) { - int *p; char *name; - int tmp, len, retval, errno; + int tmp, len, retval; switch(cmd) { case SETNAME: { @@ -65,66 +62,22 @@ name = (char *) arg1; len = strncpy_from_user(nodename, name, __NEW_UTS_LEN); - if (len < 0) + if (len < 0) return -EFAULT; - nodename[__NEW_UTS_LEN] = '\0'; down_write(&uts_sem); + strncpy(system_utsname.nodename, nodename, len); + nodename[__NEW_UTS_LEN] = '\0'; strlcpy(system_utsname.nodename, nodename, - sizeof(system_utsname.nodename)); + sizeof(system_utsname.nodename)); up_write(&uts_sem); return 0; } - case MIPS_ATOMIC_SET: { -#ifdef CONFIG_CPU_HAS_LLSC - unsigned int tmp; - - p = (int *) arg1; - errno = verify_area(VERIFY_WRITE, p, sizeof(*p)); - if (errno) - return errno; - errno = 0; - - __asm__(".set\tpush\t\t\t# sysmips(MIPS_ATOMIC, ...)\n\t" - ".set\tmips2\n\t" - ".set\tnoat\n\t" - "1:\tll\t%0, %4\n\t" - "move\t$1, %3\n\t" - "2:\tsc\t$1, %1\n\t" - "beqz\t$1, 1b\n\t" - ".set\tpop\n\t" - ".section\t.fixup,\"ax\"\n" - "3:\tli\t%2, 1\t\t\t# error\n\t" - ".previous\n\t" - ".section\t__ex_table,\"a\"\n\t" - ".word\t1b, 3b\n\t" - ".word\t2b, 3b\n\t" - ".previous\n\t" - : "=&r" (tmp), "=o" (* (u32 *) p), "=r" (errno) - : "r" (arg2), "o" (* (u32 *) p), "2" (errno) - : "$1"); - - if (errno) - return -EFAULT; - - /* We're skipping error handling etc. */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); - - ((struct pt_regs *)&cmd)->regs[2] = tmp; - ((struct pt_regs *)&cmd)->regs[7] = 0; - - __asm__ __volatile__( - "move\t$29, %0\n\t" - "j\to32_ret_from_sys_call" - : /* No outputs */ - : "r" (&cmd)); - /* Unreached */ -#else - printk("sys_sysmips(MIPS_ATOMIC_SET, ...) not ready for !CONFIG_CPU_HAS_LLSC\n"); -#endif - } + case MIPS_ATOMIC_SET: + printk(KERN_CRIT "How did I get here?\n"); + retval = -EINVAL; + goto out; case MIPS_FIXADE: tmp = current->thread.mflags & ~3; @@ -133,7 +86,7 @@ goto out; case FLUSH_CACHE: - flush_cache_all(); + __flush_cache_all(); retval = 0; goto out; diff -Nru a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c --- a/arch/mips/kernel/time.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/kernel/time.c Fri Jun 27 14:19:56 2003 @@ -2,8 +2,8 @@ * Copyright 2001 MontaVista Software Inc. * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net * - * Common time service routines for MIPS machines. See - * Documentation/mips/time.README. + * Common time service routines for MIPS machines. See + * Documents/mips/README.txt. * * 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 @@ -21,6 +21,7 @@ #include <linux/kernel_stat.h> #include <linux/spinlock.h> #include <linux/interrupt.h> +#include <linux/module.h> #include <asm/bootinfo.h> #include <asm/cpu.h> @@ -30,7 +31,9 @@ /* This is for machines which generate the exact clock. */ #define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((1000000ULL << 32) / HZ & 0xffffffff) +#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) + +#define TICK_SIZE (tick_nsec / 1000) u64 jiffies_64 = INITIAL_JIFFIES; @@ -39,6 +42,13 @@ */ extern volatile unsigned long wall_jiffies; +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + +/* + * whether we emulate local_timer_interrupts for SMP machines. + */ +int emulate_local_timer_interrupt; + /* * By default we provide the null RTC ops */ @@ -57,58 +67,64 @@ /* - * timeofday services, for syscalls. + * This version of gettimeofday has microsecond resolution and better than + * microsecond precision on fast machines with cycle counter. */ void do_gettimeofday(struct timeval *tv) { - unsigned long flags; unsigned long seq; + unsigned long usec, sec; do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. - * jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - + seq = read_seqbegin(&xtime_lock); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry(&xtime_lock, seq)); - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + while (usec >= 1000000) { + usec -= 1000000; + sec++; } + + tv->tv_sec = sec; + tv->tv_usec = usec; } -void do_settimeofday(struct timeval *tv) +int do_settimeofday(struct timespec *tv) { - write_seqlock_irq (&xtime_lock); + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! */ - tv->tv_usec -= do_gettimeoffset(); + tv->tv_nsec -= do_gettimeoffset() * NSEC_PER_USEC; + tv->tv_nsec -= (jiffies - wall_jiffies) * TICK_NSEC; - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; + while (tv->tv_nsec < 0) { + tv->tv_nsec += NSEC_PER_SEC; tv->tv_sec--; } - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ + + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = tv->tv_nsec; + time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; + write_sequnlock_irq(&xtime_lock); - write_sequnlock_irq (&xtime_lock); + return 0; } @@ -137,6 +153,9 @@ /* Cycle counter value at the previous timer interrupt.. */ static unsigned int timerhi, timerlo; +/* expirelo is the count value for next CPU timer interrupt */ +static unsigned int expirelo; + /* last time when xtime and rtc are sync'ed up */ static long last_rtc_update; @@ -154,7 +173,7 @@ unsigned long res; /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -210,7 +229,7 @@ } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -260,13 +279,12 @@ :"r" (timerhi), "m" (timerlo), "r" (tmp), - "r" (USECS_PER_JIFFY) - :"$1"); + "r" (USECS_PER_JIFFY)); cached_quotient = quotient; } /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); + count = read_c0_count(); /* .. relative to previous jiffy (32 bits is enough) */ count -= timerlo; @@ -289,35 +307,18 @@ /* - * high-level timer interrupt service routines. This function - * is set as irqaction->handler and is invoked through do_IRQ. + * local_timer_interrupt() does profiling and process accounting + * on a per-CPU basis. + * + * In UP mode, it is invoked from the (global) timer_interrupt. + * + * In SMP mode, it might invoked by per-CPU timer interrupt, or + * a broadcasted inter-processor interrupt which itself is triggered + * by the global timer interrupt. */ -void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - unsigned long seq; - - if (mips_cpu.options & MIPS_CPU_COUNTER) { - unsigned int count; - - /* - * The cycle counter is only 32 bit which is good for about - * a minute at current count rates of upto 150MHz or so. - */ - count = read_32bit_cp0_register(CP0_COUNT); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - - /* - * set up for next timer interrupt - no harm if the machine - * is using another timer interrupt source. - * Note that writing to COMPARE register clears the interrupt - */ - write_32bit_cp0_register (CP0_COMPARE, - count + cycles_per_jiffy); - - } - - if(!user_mode(regs)) { + if (!user_mode(regs)) { if (prof_buffer && current->pid) { extern int _stext; unsigned long pc = regs->cp0_epc; @@ -335,6 +336,38 @@ } } +#ifdef CONFIG_SMP + /* in UP mode, update_process_times() is invoked by do_timer() */ + update_process_times(user_mode(regs)); +#endif +} + +/* + * high-level timer interrupt service routines. This function + * is set as irqaction->handler and is invoked through do_IRQ. + */ +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + if (cpu_has_counter) { + unsigned int count; + + /* ack timer interrupt, and try to set next interrupt */ + expirelo += cycles_per_jiffy; + write_c0_compare(expirelo); + count = read_c0_count(); + + /* check to see if we have missed any timer interrupts */ + if ((count - expirelo) < 0x7fffffff) { + /* missed_timer_count ++; */ + expirelo = count + cycles_per_jiffy; + write_c0_compare(expirelo); + } + + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; + } + /* * call the generic timer interrupt handling */ @@ -345,21 +378,19 @@ * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be * called as close as possible to 500 ms before the new second starts. */ - do { - seq = read_seqbegin(&xtime_lock); - - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && - xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { - if (rtc_set_time(xtime.tv_sec) == 0) { - last_rtc_update = xtime.tv_sec; - } else { - last_rtc_update = xtime.tv_sec - 600; - /* do it again in 60 s */ - } + write_seqlock(&xtime_lock); + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && + (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { + if (rtc_set_time(xtime.tv_sec) == 0) { + last_rtc_update = xtime.tv_sec; + } else { + last_rtc_update = xtime.tv_sec - 600; + /* do it again in 60 s */ } - } while (read_seqretry(&xtime_lock, seq)); + } + write_sequnlock(&xtime_lock); /* * If jiffies has overflowed in this timer_interrupt we must @@ -369,41 +400,83 @@ if (!jiffies) { timerhi = timerlo = 0; } + +#if !defined(CONFIG_SMP) + /* + * In UP mode, we call local_timer_interrupt() to do profiling + * and process accouting. + * + * In SMP mode, local_timer_interrupt() is invoked by appropriate + * low-level local timer interrupt handler. + */ + local_timer_interrupt(0, NULL, regs); + +#else /* CONFIG_SMP */ + + if (emulate_local_timer_interrupt) { + /* + * this is the place where we send out inter-process + * interrupts and let each CPU do its own profiling + * and process accouting. + * + * Obviously we need to call local_timer_interrupt() for + * the current CPU too. + */ + panic("Not implemented yet!!!"); + } +#endif /* CONFIG_SMP */ + + return IRQ_HANDLED; } asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) { int cpu = smp_processor_id(); - irq_enter(cpu, irq); + irq_enter(); kstat_cpu(cpu).irqs[irq]++; /* we keep interrupt disabled all the time */ timer_interrupt(irq, NULL, regs); - - irq_exit(cpu, irq); + + irq_exit(); if (softirq_pending(cpu)) do_softirq(); } +asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + + /* we keep interrupt disabled all the time */ + local_timer_interrupt(irq, NULL, regs); + + irq_exit(); + + if (softirq_pending(cpu)) + do_softirq(); +} /* * time_init() - it does the following things. * - * 1) board_time_init() - - * a) (optional) set up RTC routines, + * 1) board_time_init() - + * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_counter_frequency * (only needed if you intended to use fixed_rate_gettimeoffset * or use cpu counter as timer interrupt source) * 2) setup xtime based on rtc_get_time(). * 3) choose a appropriate gettimeoffset routine. * 4) calculate a couple of cached variables for later usage - * 5) board_timer_setup() - + * 5) board_timer_setup() - * a) (optional) over-write any choices made above by time_init(). * b) machine specific code should setup the timer irqaction. * c) enable the timer interrupt - */ + */ void (*board_time_init)(void) = NULL; void (*board_timer_setup)(struct irqaction *irq) = NULL; @@ -416,7 +489,8 @@ 0, "timer", NULL, - NULL}; + NULL +}; void __init time_init(void) { @@ -424,18 +498,18 @@ board_time_init(); xtime.tv_sec = rtc_get_time(); - xtime.tv_usec = 0; + xtime.tv_nsec = 0; /* choose appropriate gettimeoffset routine */ - if (!(mips_cpu.options & MIPS_CPU_COUNTER)) { + if (!cpu_has_counter) { /* no cpu counter - sorry */ do_gettimeoffset = null_gettimeoffset; } else if (mips_counter_frequency != 0) { /* we have cpu counter and know counter frequency! */ do_gettimeoffset = fixed_rate_gettimeoffset; - } else if ((mips_cpu.isa_level == MIPS_CPU_ISA_M32) || - (mips_cpu.isa_level == MIPS_CPU_ISA_I) || - (mips_cpu.isa_level == MIPS_CPU_ISA_II) ) { + } else if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II) ) { /* we need to calibrate the counter but we don't have * 64-bit division. */ do_gettimeoffset = calibrate_div32_gettimeoffset; @@ -443,7 +517,7 @@ /* we need to calibrate the counter but we *do* have * 64-bit division. */ do_gettimeoffset = calibrate_div64_gettimeoffset; - } + } /* caclulate cache parameters */ if (mips_counter_frequency) { @@ -454,16 +528,24 @@ sll32_usecs_per_cycle = mips_counter_frequency / 100000; sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; sll32_usecs_per_cycle *= 10; + + /* + * For those using cpu counter as timer, this sets up the + * first interrupt + */ + write_c0_compare(cycles_per_jiffy); + write_c0_count(0); + expirelo = cycles_per_jiffy; } - /* + /* * Call board specific timer interrupt setup. * - * this pointer must be setup in machine setup routine. + * this pointer must be setup in machine setup routine. * * Even if the machine choose to use low-level timer interrupt, * it still needs to setup the timer_irqaction. - * In that case, it might be better to set timer_irqaction.handler + * In that case, it might be better to set timer_irqaction.handler * to be NULL function so that we are sure the high-level code * is not invoked accidentally. */ @@ -484,10 +566,10 @@ void to_tm(unsigned long tim, struct rtc_time * tm) { - long hms, day; + long hms, day, gday; int i; - day = tim / SECDAY; + gday = day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ @@ -506,7 +588,7 @@ for (i = 1; day >= days_in_month(i); i++) day -= days_in_month(i); days_in_month(FEBRUARY) = 28; - tm->tm_mon = i; + tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ /* Days are what is left over (+1) from all that. */ tm->tm_mday = day + 1; @@ -514,5 +596,7 @@ /* * Determine the day of week */ - tm->tm_wday = (day + 3) % 7; + tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ } + +EXPORT_SYMBOL(rtc_lock); diff -Nru a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c --- a/arch/mips/kernel/traps.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/kernel/traps.c Fri Jun 27 14:19:55 2003 @@ -4,12 +4,12 @@ * for more details. * * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle - * Modified for R3000 by Paul M. Antoine, 1995, 1996 - * Complete output from die() by Ulf Carlsson, 1998 + * Copyright (C) 1995, 1996 Paul M. Antoine + * Copyright (C) 1998 Ulf Carlsson * Copyright (C) 1999 Silicon Graphics, Inc. - * * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000, 01 MIPS Technologies, Inc. + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include <linux/config.h> #include <linux/init.h> @@ -19,30 +19,23 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/spinlock.h> +#include <linux/kallsyms.h> #include <asm/bootinfo.h> #include <asm/branch.h> #include <asm/cpu.h> -#include <asm/cachectl.h> -#include <asm/inst.h> -#include <asm/jazz.h> +#include <asm/fpu.h> #include <asm/module.h> #include <asm/pgtable.h> -#include <asm/io.h> -#include <asm/siginfo.h> -#include <asm/watch.h> +#include <asm/ptrace.h> +#include <asm/sections.h> #include <asm/system.h> +#include <asm/tlbdebug.h> +#include <asm/traps.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> - -/* - * Machine specific interrupt handlers - */ -extern asmlinkage void acer_pica_61_handle_int(void); -extern asmlinkage void decstation_handle_int(void); -extern asmlinkage void deskstation_rpc44_handle_int(void); -extern asmlinkage void deskstation_tyne_handle_int(void); -extern asmlinkage void mips_magnum_4000_handle_int(void); +#include <asm/watch.h> +#include <asm/types.h> extern asmlinkage void handle_mod(void); extern asmlinkage void handle_tlbl(void); @@ -58,16 +51,16 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); -extern int fpu_emulator_cop1Handler(struct pt_regs *); - -char watch_available = 0; +extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, + struct mips_fpu_soft_struct *ctx); -void (*ibe_board_handler)(struct pt_regs *regs); -void (*dbe_board_handler)(struct pt_regs *regs); +void (*board_be_init)(void); +int (*board_be_handler)(struct pt_regs *regs, int is_fixup); /* * These constant is for searching for possible module text segments. @@ -75,99 +68,74 @@ */ #define MODULE_RANGE (8*1024*1024) -#ifndef CONFIG_CPU_HAS_LLSC -/* - * This stuff is needed for the userland ll-sc emulation for R2300 - */ -void simulate_ll(struct pt_regs *regs, unsigned int opcode); -void simulate_sc(struct pt_regs *regs, unsigned int opcode); - -#define OPCODE 0xfc000000 -#define BASE 0x03e00000 -#define RT 0x001f0000 -#define OFFSET 0x0000ffff -#define LL 0xc0000000 -#define SC 0xe0000000 -#endif - /* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... */ -void show_stack(unsigned int *sp) +void show_stack(struct task_struct *task, unsigned long *sp) { + const int field = 2 * sizeof(unsigned long); + long stackdata; int i; - unsigned int *stack; - - stack = sp; - i = 0; - printk("Stack:"); - while ((unsigned long) stack & (PAGE_SIZE - 1)) { - unsigned long stackdata; + sp = sp ? sp : (unsigned long *) &sp; - if (__get_user(stackdata, stack++)) { - printk(" (Bad stack address)"); + printk("Stack: "); + i = 1; + while ((unsigned long) sp & (PAGE_SIZE - 1)) { + if (i && ((i % (64 / sizeof(unsigned long))) == 0)) + printk("\n "); + if (i > 40) { + printk(" ..."); break; } - printk(" %08lx", stackdata); - - if (++i > 40) { - printk(" ..."); + if (__get_user(stackdata, sp++)) { + printk(" (Bad stack address)"); break; } - if (i % 8 == 0) - printk("\n "); + printk(" %0*lx", field, stackdata); + i++; } + printk("\n"); } -void show_trace(unsigned int *sp) +void show_trace(struct task_struct *task, unsigned long *stack) { - int i; - unsigned int *stack; - unsigned long kernel_start, kernel_end; - unsigned long module_start, module_end; - extern char _stext, _etext; - - stack = sp; - i = 0; - - kernel_start = (unsigned long) &_stext; - kernel_end = (unsigned long) &_etext; - module_start = VMALLOC_START; - module_end = module_start + MODULE_RANGE; + const int field = 2 * sizeof(unsigned long); + unsigned long addr; - printk("\nCall Trace:"); + if (!stack) + stack = (unsigned long*)&stack; - while ((unsigned long) stack & (PAGE_SIZE -1)) { - unsigned long addr; - - if (__get_user(addr, stack++)) { - printk(" (Bad stack address)\n"); - break; + printk("Call Trace:"); +#ifdef CONFIG_KALLSYMS + printk("\n"); +#endif + while (((long) stack & (THREAD_SIZE-1)) != 0) { + addr = *stack++; + if (kernel_text_address(addr)) { + printk(" [<%0*lx>] ", field, addr); + print_symbol("%s\n", addr); } + } + printk("\n"); +} - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ +void show_trace_task(struct task_struct *tsk) +{ + show_trace(tsk, (long *)tsk->thread.reg29); +} - if ((addr >= kernel_start && addr < kernel_end) || - (addr >= module_start && addr < module_end)) { +/* + * The architecture-independent dump_stack generator + */ +void dump_stack(void) +{ + unsigned long stack; - printk(" [<%08lx>]", addr); - if (++i > 40) { - printk(" ..."); - break; - } - } - } + show_trace(current, &stack); } void show_code(unsigned int *pc) @@ -177,43 +145,114 @@ printk("\nCode:"); for(i = -3 ; i < 6 ; i++) { - unsigned long insn; + unsigned int insn; if (__get_user(insn, pc + i)) { printk(" (Bad address in epc)\n"); break; } - printk("%c%08lx%c",(i?' ':'<'),insn,(i?' ':'>')); + printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>')); + } +} + +void show_regs(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + int i; + + printk("Cpu %d\n", smp_processor_id()); + + /* + * Saved main processor registers + */ + for (i = 0; i < 32; i++) { + if ((i % 4) == 0) + printk("$%2d :", i); + if (i == 0) + printk(" %0*lx", field, 0UL); + else if (i == 26 || i == 27) + printk(" %*s", field, ""); + else + printk(" %0*lx", field, regs->regs[i]); + + i++; + if ((i % 4) == 0) + printk("\n"); } + + printk("Hi : %0*lx\n", field, regs->hi); + printk("Lo : %0*lx\n", field, regs->lo); + + /* + * Saved cp0 registers + */ + printk("epc : %0*lx %s\n", field, regs->cp0_epc, print_tainted()); + printk("Status: %0*lx\n", field, regs->cp0_status); + printk("Cause : %0*lx\n", field, regs->cp0_cause); + + if (regs->cp0_status & ST0_KX) + printk("KX "); + if (regs->cp0_status & ST0_SX) + printk("SX "); + if (regs->cp0_status & ST0_UX) + printk("UX "); + switch (regs->cp0_status & ST0_KSU) { + case KSU_USER: + printk("USER "); + break; + case KSU_SUPERVISOR: + printk("SUPERVISOR "); + break; + case KSU_KERNEL: + printk("KERNEL "); + break; + default: + printk("BAD_MODE "); + break; + } + if (regs->cp0_status & ST0_ERL) + printk("ERL "); + if (regs->cp0_status & ST0_EXL) + printk("EXL "); + if (regs->cp0_status & ST0_IE) + printk("IE "); +} + +void show_registers(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + + show_regs(regs); + printk("Process %s (pid: %d, stackpage=%0*lx)\n", + current->comm, current->pid, field, (unsigned long) current); + show_stack(current, (long *) regs->regs[29]); + show_trace(current, (long *) regs->regs[29]); + show_code((unsigned int *) regs->cp0_epc); + printk("\n"); } -spinlock_t die_lock; +static spinlock_t die_lock = SPIN_LOCK_UNLOCKED; -extern void __die(const char * str, struct pt_regs * regs, const char *where, - unsigned long line) +void __die(const char * str, struct pt_regs * regs, const char * file, + const char * func, unsigned long line) { static int die_counter; + console_verbose(); spin_lock_irq(&die_lock); printk("%s", str); - if (where) - printk(" in %s, line %ld", where, line); + if (file && func) + printk(" in %s:%s, line %ld", file, func, line); printk("[#%d]:\n", ++die_counter); - show_regs(regs); - printk("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, (unsigned long) current); - show_stack((unsigned int *) regs->regs[29]); - show_trace((unsigned int *) regs->regs[29]); - show_code((unsigned int *) regs->cp0_epc); - printk("\n"); + show_registers(regs); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); } -void __die_if_kernel(const char * str, struct pt_regs * regs, const char *where, - unsigned long line) +void __die_if_kernel(const char * str, struct pt_regs * regs, + const char * file, const char * func, unsigned long line) { if (!user_mode(regs)) - __die(str, regs, where, line); + __die(str, regs, file, func, line); } extern const struct exception_table_entry __start___dbe_table[]; @@ -227,106 +266,199 @@ ); } -static inline unsigned long -search_one_table(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - const struct exception_table_entry *mid; - long diff; - - while (first < last) { - mid = (last - first) / 2 + first; - diff = mid->insn - value; - if (diff < 0) - first = mid + 1; - else - last = mid; - } - return (first == last && first->insn == value) ? first->nextinsn : 0; -} +asmlinkage void do_be(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + const struct exception_table_entry *fixup = NULL; + int data = regs->cp0_cause & 4; + int action = MIPS_BE_FATAL; -extern spinlock_t modlist_lock; + /* XXX For now. Fixme, this searches the wrong table ... */ + if (data && !user_mode(regs)) + fixup = search_exception_tables(regs->cp0_epc); -static inline unsigned long -search_dbe_table(unsigned long addr) -{ - unsigned long ret = 0; - -#ifndef CONFIG_MODULES - /* There is only the kernel to search. */ - ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr); - return ret; -#else - unsigned long flags; - - /* The kernel is the last "module" -- no need to treat it special. */ - struct module *mp; - struct archdata *ap; - - spin_lock_irqsave(&modlist_lock, flags); - for (mp = module_list; mp != NULL; mp = mp->next) { - if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, - dbe_table_end)) - continue; - ap = (struct archdata *)(mp->archdata_start); - - if (ap->dbe_table_start == NULL || - !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING))) - continue; - ret = search_one_table(ap->dbe_table_start, - ap->dbe_table_end - 1, addr); - if (ret) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - return ret; -#endif -} + if (fixup) + action = MIPS_BE_FIXUP; -static void default_be_board_handler(struct pt_regs *regs) -{ - unsigned long new_epc; - unsigned long fixup; - int data = regs->cp0_cause & 4; + if (board_be_handler) + action = board_be_handler(regs, fixup != 0); - if (data && !user_mode(regs)) { - fixup = search_dbe_table(regs->cp0_epc); + switch (action) { + case MIPS_BE_DISCARD: + return; + case MIPS_BE_FIXUP: if (fixup) { - new_epc = fixup_exception(dpf_reg, fixup, - regs->cp0_epc); - regs->cp0_epc = new_epc; + regs->cp0_epc = fixup->nextinsn; return; } + break; + default: + break; } /* * Assume it would be too dangerous to continue ... */ - printk(KERN_ALERT "%s bus error, epc == %08lx, ra == %08lx\n", + printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", data ? "Data" : "Instruction", - regs->cp0_epc, regs->regs[31]); + field, regs->cp0_epc, field, regs->regs[31]); die_if_kernel("Oops", regs); force_sig(SIGBUS, current); } -asmlinkage void do_ibe(struct pt_regs *regs) +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) +{ + unsigned int *epc; + + epc = (unsigned int *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + +/* + * ll/sc emulation + */ + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xe0000000 + +/* + * The ll_bit is cleared by r*_switch.S + */ + +unsigned long ll_bit; + +static struct task_struct *ll_task = NULL; + +static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode) +{ + unsigned long value, *vaddr; + long offset; + int signal = 0; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (get_user(value, vaddr)) { + signal = SIGSEGV; + goto sig; + } + + if (ll_task == NULL || ll_task == current) { + ll_bit = 1; + } else { + ll_bit = 0; + } + ll_task = current; + + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); +} + +static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode) { - ibe_board_handler(regs); + unsigned long *vaddr, reg; + long offset; + int signal = 0; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (ll_bit == 0 || ll_task != current) { + regs->regs[reg] = 0; + compute_return_epc(regs); + return; + } + + if (put_user(regs->regs[reg], vaddr)) { + signal = SIGSEGV; + goto sig; + } + + regs->regs[reg] = 1; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); } -asmlinkage void do_dbe(struct pt_regs *regs) +/* + * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both + * opcodes are supposed to result in coprocessor unusable exceptions if + * executed on ll/sc-less processors. That's the theory. In practice a + * few processors such as NEC's VR4100 throw reserved instruction exceptions + * instead, so we're doing the emulation thing in both exception handlers. + */ +static inline int simulate_llsc(struct pt_regs *regs) { - dbe_board_handler(regs); + unsigned int opcode; + + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; + + if ((opcode & OPCODE) == LL) { + simulate_ll(regs, opcode); + return 0; + } + if ((opcode & OPCODE) == SC) { + simulate_sc(regs, opcode); + return 0; + } + + return -EFAULT; /* Strange things going on ... */ } asmlinkage void do_ov(struct pt_regs *regs) { - if (compute_return_epc(regs)) - return; + siginfo_t info; - force_sig(SIGFPE, current); + info.si_code = FPE_INTOVF; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_addr = (void *)regs->cp0_epc; + force_sig_info(SIGFPE, &info, current); } /* @@ -335,30 +467,29 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) { if (fcr31 & FPU_CSR_UNI_X) { - extern void save_fp(struct task_struct *); - extern void restore_fp(struct task_struct *); int sig; + /* - * Unimplemented operation exception. If we've got the - * full software emulator on-board, let's use it... + * Unimplemented operation exception. If we've got the full + * software emulator on-board, let's use it... * - * Force FPU to dump state into task/thread context. - * We're moving a lot of data here for what is probably - * a single instruction, but the alternative is to - * pre-decode the FP register operands before invoking - * the emulator, which seems a bit extreme for what - * should be an infrequent event. + * Force FPU to dump state into task/thread context. We're + * moving a lot of data here for what is probably a single + * instruction, but the alternative is to pre-decode the FP + * register operands before invoking the emulator, which seems + * a bit extreme for what should be an infrequent event. */ save_fp(current); - + /* Run the emulator */ - sig = fpu_emulator_cop1Handler(regs); + sig = fpu_emulator_cop1Handler (0, regs, + ¤t->thread.fpu.soft); - /* - * We can't allow the emulated instruction to leave the - * Unimplemented Operation bit set in $fcr31. + /* + * We can't allow the emulated instruction to leave any of + * the cause bit set in $fcr31. */ - current->thread.fpu.soft.sr &= ~FPU_CSR_UNI_X; + current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X; /* Restore the hardware register state */ restore_fp(current); @@ -370,36 +501,18 @@ return; } - if (compute_return_epc(regs)) - return; - force_sig(SIGFPE, current); - printk(KERN_DEBUG "Sent send SIGFPE to %s\n", current->comm); -} - -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned int *epc; - - epc = (unsigned int *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(*opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; } asmlinkage void do_bp(struct pt_regs *regs) { - siginfo_t info; unsigned int opcode, bcode; - unsigned int *epc; + siginfo_t info; - epc = (unsigned int *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (get_user(opcode, epc)) - goto sigsegv; + die_if_kernel("Break instruction in kernel code", regs); + + if (get_insn_opcode(regs, &opcode)) + return; /* * There is the ancient bug in the MIPS assemblers that the break @@ -423,241 +536,107 @@ info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; - info.si_addr = (void *)compute_return_epc(regs); + info.si_addr = (void *)regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; default: force_sig(SIGTRAP, current); } - return; - -sigsegv: - force_sig(SIGSEGV, current); } asmlinkage void do_tr(struct pt_regs *regs) { + unsigned int opcode, tcode = 0; siginfo_t info; - unsigned int opcode, bcode; - unsigned *epc; - epc = (unsigned int *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (get_user(opcode, epc)) - goto sigsegv; + die_if_kernel("Trap instruction in kernel code", regs); + + if (get_insn_opcode(regs, &opcode)) + return; - bcode = ((opcode >> 6) & ((1 << 20) - 1)); + /* Immediate versions don't provide a code. */ + if (!(opcode & OPCODE)) + tcode = ((opcode >> 6) & ((1 << 20) - 1)); /* - * (A short test says that IRIX 5.3 sends SIGTRAP for all break - * insns, even for break codes that indicate arithmetic failures. + * (A short test says that IRIX 5.3 sends SIGTRAP for all trap + * insns, even for trap codes that indicate arithmetic failures. * Weird ...) * But should we continue the brokenness??? --macro */ - switch (bcode) { + switch (tcode) { case 6: case 7: - if (bcode == 7) + if (tcode == 7) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; - info.si_addr = (void *)compute_return_epc(regs); + info.si_addr = (void *)regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; default: force_sig(SIGTRAP, current); } - return; - -sigsegv: - force_sig(SIGSEGV, current); } -#ifndef CONFIG_CPU_HAS_LLSC - -#ifdef CONFIG_SMP -#error "ll/sc emulation is not SMP safe" -#endif - -/* - * userland emulation for R2300 CPUs - * needed for the multithreading part of glibc - * - * this implementation can handle only sychronization between 2 or more - * user contexts and is not SMP safe. - */ asmlinkage void do_ri(struct pt_regs *regs) { - unsigned int opcode; - - if (!user_mode(regs)) - BUG(); + die_if_kernel("Reserved instruction in kernel code", regs); - if (!get_insn_opcode(regs, &opcode)) { - if ((opcode & OPCODE) == LL) { - simulate_ll(regs, opcode); + if (!cpu_has_llsc) + if (!simulate_llsc(regs)) return; - } - if ((opcode & OPCODE) == SC) { - simulate_sc(regs, opcode); - return; - } - } - if (compute_return_epc(regs)) - return; force_sig(SIGILL, current); } -/* - * The ll_bit is cleared by r*_switch.S - */ - -unsigned long ll_bit; -#ifdef CONFIG_PROC_FS -extern unsigned long ll_ops; -extern unsigned long sc_ops; -#endif - -static struct task_struct *ll_task = NULL; - -void simulate_ll(struct pt_regs *regp, unsigned int opcode) +asmlinkage void do_cpu(struct pt_regs *regs) { - unsigned long value, *vaddr; - long offset; - int signal = 0; + unsigned int cpid; - /* - * analyse the ll instruction that just caused a ri exception - * and put the referenced address to addr. - */ + die_if_kernel("do_cpu invoked from kernel context!", regs); - /* sign extend offset */ - offset = opcode & OFFSET; - offset <<= 16; - offset >>= 16; + cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); + switch (cpid) { + case 0: + if (cpu_has_llsc) + break; -#ifdef CONFIG_PROC_FS - ll_ops++; -#endif + if (!simulate_llsc(regs)) + return; + break; - if ((unsigned long)vaddr & 3) - signal = SIGBUS; - else if (get_user(value, vaddr)) - signal = SIGSEGV; - else { - if (ll_task == NULL || ll_task == current) { - ll_bit = 1; - } else { - ll_bit = 0; + case 1: + own_fpu(); + if (current->used_math) { /* Using the FPU again. */ + restore_fp(current); + } else { /* First time FPU user. */ + init_fpu(); + current->used_math = 1; } - ll_task = current; - regp->regs[(opcode & RT) >> 16] = value; - } - if (compute_return_epc(regp)) - return; - if (signal) - send_sig(signal, current, 1); -} - -void simulate_sc(struct pt_regs *regp, unsigned int opcode) -{ - unsigned long *vaddr, reg; - long offset; - int signal = 0; - - /* - * analyse the sc instruction that just caused a ri exception - * and put the referenced address to addr. - */ - - /* sign extend offset */ - offset = opcode & OFFSET; - offset <<= 16; - offset >>= 16; - - vaddr = (unsigned long *)((long)(regp->regs[(opcode & BASE) >> 21]) + offset); - reg = (opcode & RT) >> 16; -#ifdef CONFIG_PROC_FS - sc_ops++; -#endif + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(0, regs, + ¤t->thread.fpu.soft); + if (sig) + force_sig(sig, current); + } - if ((unsigned long)vaddr & 3) - signal = SIGBUS; - else if (ll_bit == 0 || ll_task != current) - regp->regs[reg] = 0; - else if (put_user(regp->regs[reg], vaddr)) - signal = SIGSEGV; - else - regp->regs[reg] = 1; - if (compute_return_epc(regp)) return; - if (signal) - send_sig(signal, current, 1); -} - -#else /* MIPS 2 or higher */ -asmlinkage void do_ri(struct pt_regs *regs) -{ - unsigned int opcode; - - get_insn_opcode(regs, &opcode); - if (compute_return_epc(regs)) - return; + case 2: + case 3: + break; + } force_sig(SIGILL, current); } -#endif - -asmlinkage void do_cpu(struct pt_regs *regs) +asmlinkage void do_mdmx(struct pt_regs *regs) { - unsigned int cpid; - extern void lazy_fpu_switch(void *); - extern void init_fpu(void); - void fpu_emulator_init_fpu(void); - int sig; - - cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid != 1) - goto bad_cid; - - if (!(mips_cpu.options & MIPS_CPU_FPU)) - goto fp_emul; - - regs->cp0_status |= ST0_CU1; - if (last_task_used_math == current) - return; - - if (current->used_math) { /* Using the FPU again. */ - lazy_fpu_switch(last_task_used_math); - } else { /* First time FPU user. */ - init_fpu(); - current->used_math = 1; - } - last_task_used_math = current; - return; - -fp_emul: - if (last_task_used_math != current) { - if (!current->used_math) { - fpu_emulator_init_fpu(); - current->used_math = 1; - } - } - sig = fpu_emulator_cop1Handler(regs); - last_task_used_math = current; - if (sig) - force_sig(sig, current); - return; - -bad_cid: force_sig(SIGILL, current); } @@ -667,6 +646,7 @@ * We use the watch exception where available to detect stack * overflows. */ + dump_tlb_all(); show_regs(regs); panic("Caught WATCH exception - probably caused by stack overflow."); } @@ -674,8 +654,14 @@ asmlinkage void do_mcheck(struct pt_regs *regs) { show_regs(regs); - panic("Caught Machine Check exception - probably caused by multiple " - "matching entries in the TLB."); + dump_tlb_all(); + /* + * Some chips may have other causes of machine check (e.g. SB1 + * graduation timer) + */ + panic("Caught Machine Check exception - %scaused by multiple " + "matching entries in the TLB.", + (regs->cp0_status & ST0_TS) ? "" : "not "); } asmlinkage void do_reserved(struct pt_regs *regs) @@ -686,15 +672,8 @@ * hard/software error. */ show_regs(regs); - panic("Caught reserved exception - should not happen."); -} - -static inline void watch_init(void) -{ - if (mips_cpu.options & MIPS_CPU_WATCH ) { - set_except_vector(23, handle_watch); - watch_available = 1; - } + panic("Caught reserved exception %ld - should not happen.", + (regs->cp0_cause & 0x7f) >> 2); } /* @@ -703,14 +682,12 @@ */ static inline void parity_protection_init(void) { - switch (mips_cpu.cputype) { + switch (current_cpu_data.cputype) { case CPU_5KC: - /* Set the PE bit (bit 31) in the CP0_ECC register. */ + /* Set the PE bit (bit 31) in the c0_ecc register. */ printk(KERN_INFO "Enable the cache parity protection for " "MIPS 5KC CPUs.\n"); - write_32bit_cp0_register(CP0_ECC, - read_32bit_cp0_register(CP0_ECC) - | 0x80000000); + write_c0_ecc(read_c0_ecc() | 0x80000000); break; default: break; @@ -719,16 +696,16 @@ asmlinkage void cache_parity_error(void) { + const int field = 2 * sizeof(unsigned long); unsigned int reg_val; /* For the moment, report the problem and hang. */ - reg_val = read_32bit_cp0_register(CP0_ERROREPC); printk("Cache error exception:\n"); - printk("cp0_errorepc == %08x\n", reg_val); - reg_val = read_32bit_cp0_register(CP0_CACHEERR); - printk("cp0_cacheerr == %08x\n", reg_val); + printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); + reg_val = read_c0_cacheerr(); + printk("c0_cacheerr == %08x\n", reg_val); - printk("Decoded CP0_CACHEERR: %s cache fault in %s reference.\n", + printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", reg_val & (1<<30) ? "secondary" : "primary", reg_val & (1<<31) ? "data" : "insn"); printk("Error bits: %s%s%s%s%s%s%s\n", @@ -741,17 +718,63 @@ reg_val & (1<<22) ? "E0 " : ""); printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); - if (reg_val&(1<<22)) - printk("DErrAddr0: 0x%08x\n", - read_32bit_cp0_set1_register(CP0_S1_DERRADDR0)); - - if (reg_val&(1<<23)) - printk("DErrAddr1: 0x%08x\n", - read_32bit_cp0_set1_register(CP0_S1_DERRADDR1)); +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + if (reg_val & (1<<22)) + printk("DErrAddr0: 0x%08x\n", read_c0_derraddr0()); + + if (reg_val & (1<<23)) + printk("DErrAddr1: 0x%08x\n", read_c0_derraddr1()); +#endif panic("Can't handle the cache error!"); } +/* + * SDBBP EJTAG debug exception handler. + * We skip the instruction and return to the next instruction. + */ +void ejtag_exception_handler(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + unsigned long depc, old_epc; + unsigned int debug; + + printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); + depc = read_c0_depc(); + debug = read_c0_debug(); + printk("c0_depc = %0*lx, DEBUG = %08x\n", field, depc, debug); + if (debug & 0x80000000) { + /* + * In branch delay slot. + * We cheat a little bit here and use EPC to calculate the + * debug return address (DEPC). EPC is restored after the + * calculation. + */ + old_epc = regs->cp0_epc; + regs->cp0_epc = depc; + __compute_return_epc(regs); + depc = regs->cp0_epc; + regs->cp0_epc = old_epc; + } else + depc += 4; + write_c0_depc(depc); + +#if 0 + printk("\n\n----- Enable EJTAG single stepping ----\n\n"); + write_c0_debug(debug | 0x100); +#endif +} + +/* + * NMI exception handler. + */ +void nmi_exception_handler(struct pt_regs *regs) +{ + printk("NMI taken!!!!\n"); + die("NMI", regs); + while(1) ; +} + unsigned long exception_handlers[32]; /* @@ -761,11 +784,11 @@ */ void *set_except_vector(int n, void *addr) { - unsigned handler = (unsigned long) addr; - unsigned old_handler = exception_handlers[n]; - exception_handlers[n] = handler; + unsigned long handler = (unsigned long) addr; + unsigned long old_handler = exception_handlers[n]; - if (n == 0 && mips_cpu.options & MIPS_CPU_DIVEC) { + exception_handlers[n] = handler; + if (n == 0 && cpu_has_divec) { *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | (0x03ffffff & (handler >> 2)); flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); @@ -775,56 +798,70 @@ asmlinkage int (*save_fp_context)(struct sigcontext *sc); asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + extern asmlinkage int _save_fp_context(struct sigcontext *sc); extern asmlinkage int _restore_fp_context(struct sigcontext *sc); extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); +void __init per_cpu_trap_init(void) +{ + unsigned int cpu = smp_processor_id(); + + /* Some firmware leaves the BEV flag set, clear it. */ + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + + /* + * Some MIPS CPUs have a dedicated interrupt vector which reduces the + * interrupt processing overhead. Use it where available. + */ + if (cpu_has_divec) + set_c0_cause(CAUSEF_IV); + + cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; + write_c0_context(cpu << 23); +} + void __init trap_init(void) { - extern char except_vec0_nevada, except_vec0_r4000; - extern char except_vec0_r4600, except_vec0_r2300; - extern char except_vec1_generic, except_vec2_generic; + extern char except_vec1_generic; extern char except_vec3_generic, except_vec3_r4000; - extern char except_vec4; extern char except_vec_ejtag_debug; + extern char except_vec4; unsigned long i; - /* Some firmware leaves the BEV flag set, clear it. */ - clear_cp0_status(ST0_BEV); + per_cpu_trap_init(); /* Copy the generic exception handler code to its final destination. */ memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); - flush_icache_range(KSEG0 + 0x80, KSEG0 + 0x200); + /* * Setup default vectors */ for (i = 0; i <= 31; i++) set_except_vector(i, handle_reserved); - /* - * Copy the EJTAG debug exception vector handler code to its final + /* + * Copy the EJTAG debug exception vector handler code to it's final * destination. */ - memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80); + if (cpu_has_ejtag) + memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80); /* * Only some CPUs have the watch exceptions or a dedicated * interrupt vector. */ - watch_init(); + if (cpu_has_watch) + set_except_vector(23, handle_watch); /* * Some MIPS CPUs have a dedicated interrupt vector which reduces the * interrupt processing overhead. Use it where available. */ - if (mips_cpu.options & MIPS_CPU_DIVEC) { - memcpy((void *)(KSEG0 + 0x200), &except_vec4, 8); - set_cp0_cause(CAUSEF_IV); - } + if (cpu_has_divec) + memcpy((void *)(KSEG0 + 0x200), &except_vec4, 0x8); /* * Some CPUs can enable/disable for cache parity detection, but does @@ -832,21 +869,22 @@ */ parity_protection_init(); + /* + * The Data Bus Errors / Instruction Bus Errors are signaled + * by external hardware. Therefore these two exceptions + * may have board specific handlers. + */ + if (board_be_init) + board_be_init(); + set_except_vector(1, handle_mod); set_except_vector(2, handle_tlbl); set_except_vector(3, handle_tlbs); set_except_vector(4, handle_adel); set_except_vector(5, handle_ades); - /* - * The Data Bus Error/ Instruction Bus Errors are signaled - * by external hardware. Therefore these two expection have - * board specific handlers. - */ set_except_vector(6, handle_ibe); set_except_vector(7, handle_dbe); - ibe_board_handler = default_be_board_handler; - dbe_board_handler = default_be_board_handler; set_except_vector(8, handle_sys); set_except_vector(9, handle_bp); @@ -854,59 +892,23 @@ set_except_vector(11, handle_cpu); set_except_vector(12, handle_ov); set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); - /* - * Handling the following exceptions depends mostly of the cpu type - */ - if ((mips_cpu.options & MIPS_CPU_4KEX) - && (mips_cpu.options & MIPS_CPU_4KTLB)) { - if (mips_cpu.cputype == CPU_NEVADA) { - memcpy((void *)KSEG0, &except_vec0_nevada, 0x80); - } else if (mips_cpu.cputype == CPU_R4600) - memcpy((void *)KSEG0, &except_vec0_r4600, 0x80); - else - memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); - - /* Cache error vector already set above. */ - - if (mips_cpu.options & MIPS_CPU_VCE) { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, - 0x80); - } else { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, - 0x80); - } + if (cpu_has_mcheck) + set_except_vector(24, handle_mcheck); - if (mips_cpu.options & MIPS_CPU_FPU) { - save_fp_context = _save_fp_context; - restore_fp_context = _restore_fp_context; - } else { - save_fp_context = fpu_emulator_save_context; - restore_fp_context = fpu_emulator_restore_context; - } - } else switch (mips_cpu.cputype) { - case CPU_SB1: - /* - * XXX - This should be folded in to the "cleaner" handling, - * above - */ - memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); + if (cpu_has_vce) memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x80); - save_fp_context = _save_fp_context; - restore_fp_context = _restore_fp_context; + else if (cpu_has_4kex) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); + else + memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80); - /* Enable timer interrupt and scd mapped interrupt */ - clear_cp0_status(0xf000); - set_cp0_status(0xc00); - break; - case CPU_R6000: - case CPU_R6000A: - save_fp_context = _save_fp_context; - restore_fp_context = _restore_fp_context; - + if (current_cpu_data.cputype == CPU_R6000 || + current_cpu_data.cputype == CPU_R6000A) { /* * The R6000 is the only R-series CPU that features a machine * check exception (similar to the R4000 cache error) and @@ -917,34 +919,24 @@ */ //set_except_vector(14, handle_mc); //set_except_vector(15, handle_ndc); - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3041: - case CPU_R3051: - case CPU_R3052: - case CPU_R3081: - case CPU_R3081E: - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: + } + + if (cpu_has_fpu) { save_fp_context = _save_fp_context; restore_fp_context = _restore_fp_context; - memcpy((void *)KSEG0, &except_vec0_r2300, 0x80); - memcpy((void *)(KSEG0 + 0x80), &except_vec3_generic, 0x80); - break; - - case CPU_UNKNOWN: - default: - panic("Unknown CPU type"); + } else { + save_fp_context = fpu_emulator_save_context; + restore_fp_context = fpu_emulator_restore_context; } - flush_icache_range(KSEG0, KSEG0 + 0x200); - if (mips_cpu.isa_level == MIPS_CPU_ISA_IV) - set_cp0_status(ST0_XX); + flush_icache_range(KSEG0, KSEG0 + 0x400); + + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); - atomic_inc(&init_mm.mm_count); /* XXX UP? */ + atomic_inc(&init_mm.mm_count); /* XXX UP? */ current->active_mm = &init_mm; - write_32bit_cp0_register(CP0_CONTEXT, smp_processor_id()<<23); - current_pgd[0] = init_mm.pgd; + + /* XXX Must be done for all CPUs */ + TLBMISS_HANDLER_SETUP(); } diff -Nru a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c --- a/arch/mips/kernel/unaligned.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/kernel/unaligned.c Fri Jun 27 14:19:57 2003 @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1998 by Ralf Baechle + * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * * This file contains exception handler for address error exception with the @@ -41,7 +41,7 @@ * * #include <stdio.h> * #include <asm/sysmips.h> - * + * * struct foo { * unsigned char bar[8]; * }; @@ -74,6 +74,7 @@ */ #include <linux/config.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/signal.h> #include <linux/smp.h> #include <linux/smp_lock.h> @@ -88,23 +89,22 @@ #define STR(x) __STR(x) #define __STR(x) #x -/* - * User code may only access USEG; kernel code may access the - * entire address space. - */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ - goto sigbus; +#ifdef CONFIG_PROC_FS +unsigned long unaligned_instructions; +#endif -static inline void -emulate_load_store_insn(struct pt_regs *regs, - unsigned long addr, - unsigned long pc) +static inline int emulate_load_store_insn(struct pt_regs *regs, + void *addr, unsigned long pc, + unsigned long **regptr, unsigned long *newvalue) { union mips_instruction insn; - unsigned long value, fixup; + unsigned long value; + const struct exception_table_entry *fixup; + unsigned int res; regs->regs[0] = 0; + *regptr=NULL; + /* * This load never faults. */ @@ -144,186 +144,295 @@ * The remaining opcodes are the ones that are really of interest. */ case lh_op: - check_axs(pc, addr, 2); - __asm__( - ".set\tnoat\n" + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ (".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlb\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlb\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlb\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlb\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault) - :"$1"); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lw_op: - check_axs(pc, addr, 4); - __asm__( + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lhu_op: - check_axs(pc, addr, 2); - __asm__( + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ ( ".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlbu\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlbu\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlbu\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlbu\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault) - :"$1"); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lwu_op: - check_axs(pc, addr, 4); - __asm__( +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "dsll\t%0, %0, 32\n\t" + "dsrl\t%0, %0, 32\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - value &= 0xffffffff; - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case ld_op: - check_axs(pc, addr, 8); - __asm__( - ".set\tmips3\n" +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 8)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tldl\t%0,(%1)\n" - "2:\tldr\t%0,7(%1)\n\t" + "1:\tldl\t%0, (%2)\n" + "2:\tldr\t%0, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tldl\t%0,7(%1)\n" - "2:\tldr\t%0,(%1)\n\t" + "1:\tldl\t%0, 7(%2)\n" + "2:\tldr\t%0, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case sh_op: - check_axs(pc, addr, 2); + if (verify_area(VERIFY_WRITE, addr, 2)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,1(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,0(%1)\n\t" + "1:\tsb\t%1, 1(%2)\n\t" + "srl\t$1, %1, 0x8\n" + "2:\tsb\t$1, 0(%2)\n\t" ".set\tat\n\t" #endif #ifdef __LITTLE_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,0(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,1(%1)\n\t" + "1:\tsb\t%1, 0(%2)\n\t" + "srl\t$1,%1, 0x8\n" + "2:\tsb\t$1, 1(%2)\n\t" ".set\tat\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault) - :"$1"); - return; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sw_op: - check_axs(pc, addr, 4); + if (verify_area(VERIFY_WRITE, addr, 4)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tswl\t%0,(%1)\n" - "2:\tswr\t%0,3(%1)\n\t" + "1:\tswl\t%1,(%2)\n" + "2:\tswr\t%1, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tswl\t%0,3(%1)\n" - "2:\tswr\t%0,(%1)\n\t" + "1:\tswl\t%1, 3(%2)\n" + "2:\tswr\t%1, (%2)\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sd_op: - check_axs(pc, addr, 8); +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_WRITE, addr, 8)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( - ".set\tmips3\n" + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tsdl\t%0,(%1)\n" - "2:\tsdr\t%0,7(%1)\n\t" + "1:\tsdl\t%1,(%2)\n" + "2:\tsdr\t%1, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tsdl\t%0,7(%1)\n" - "2:\tsdr\t%0,(%1)\n\t" + "1:\tsdl\t%1, 7(%2)\n" + "2:\tsdr\t%1, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case lwc1_op: case ldc1_op: @@ -352,78 +461,97 @@ */ goto sigill; } - return; + +#ifdef CONFIG_PROC_FS + unaligned_instructions++; +#endif + + return 0; fault: /* Did we have an exception handler installed? */ - fixup = search_exception_table(regs->cp0_epc); + fixup = search_exception_tables(exception_epc(regs)); if (fixup) { - long new_epc; - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); + unsigned long new_epc = fixup->nextinsn; printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n", current->comm, regs->cp0_epc, new_epc); regs->cp0_epc = new_epc; - return; + return 1; } die_if_kernel ("Unhandled kernel unaligned access", regs); send_sig(SIGSEGV, current, 1); - return; + + return 0; + sigbus: - die_if_kernel ("Unhandled kernel unaligned access", regs); + die_if_kernel("Unhandled kernel unaligned access", regs); send_sig(SIGBUS, current, 1); - return; + + return 0; + sigill: - die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); + die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); send_sig(SIGILL, current, 1); - return; -} -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; -#endif + return 0; +} asmlinkage void do_ade(struct pt_regs *regs) { - unsigned long pc; + unsigned long *regptr, newval; extern int do_dsemulret(struct pt_regs *); + mm_segment_t seg; + unsigned long pc; - /* - * Address errors may be deliberately induced - * by the FPU emulator to take retake control - * of the CPU after executing the instruction - * in the delay slot of an emulated branch. + /* + * Address errors may be deliberately induced by the FPU emulator to + * retake control of the CPU after executing the instruction in the + * delay slot of an emulated branch. */ - - if ((unsigned long)regs->cp0_epc == current->thread.dsemul_aerpc) { - do_dsemulret(regs); + /* Terminate if exception was recognized as a delay slot return */ + if (do_dsemulret(regs)) return; - } + + /* Otherwise handle as normal */ /* * Did we catch a fault trying to load an instruction? - * This also catches attempts to activate MIPS16 code on - * CPUs which don't support it. + * Or are we running in MIPS16 mode? */ - if (regs->cp0_badvaddr == regs->cp0_epc) + if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) goto sigbus; - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); - if (compute_return_epc(regs)) - return; + pc = exception_epc(regs); if ((current->thread.mflags & MF_FIXADE) == 0) goto sigbus; - emulate_load_store_insn(regs, regs->cp0_badvaddr, pc); -#ifdef CONFIG_PROC_FS - unaligned_instructions++; -#endif + /* + * Do branch emulation only if we didn't forward the exception. + * This is all so but ugly ... + */ + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); + if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc, + ®ptr, &newval)) { + compute_return_epc(regs); + /* + * Now that branch is evaluated, update the dest + * register if necessary + */ + if (regptr) + *regptr = newval; + } + set_fs(seg); return; sigbus: - die_if_kernel ("Kernel unaligned instruction access", regs); + die_if_kernel("Kernel unaligned instruction access", regs); force_sig(SIGBUS, current); - return; + /* + * XXX On return from the signal handler we should advance the epc + */ } diff -Nru a/arch/mips/kernel/vm86.c b/arch/mips/kernel/vm86.c --- a/arch/mips/kernel/vm86.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,13 +0,0 @@ -/* - * arch/mips/vm86.c - * - * Copyright (C) 1994 Waldorf GMBH, - * written by Ralf Baechle - */ -#include <linux/linkage.h> -#include <linux/errno.h> - -asmlinkage int sys_vm86(void *v86) -{ - return -ENOSYS; -} diff -Nru a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,14 @@ +# +# Makefile for the LASAT specific kernel interface routines under Linux. +# + +obj-y += reset.o setup.o prom.o lasat_board.o \ + at93c.o interrupt.o lasatIRQ.o + +obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o +obj-$(CONFIG_DS1603) += ds1603.o +obj-$(CONFIG_PICVUE) += picvue.o +obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o + +clean: + make -C image clean diff -Nru a/arch/mips/lasat/at93c.c b/arch/mips/lasat/at93c.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/at93c.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,148 @@ +/* + * Atmel AT93C46 serial eeprom driver + * + * Brian Murphy <brian.murphy@eicon.com> + * + */ +#include <linux/kernel.h> +#include <linux/delay.h> +#include <asm/lasat/lasat.h> +#include <linux/module.h> +#include <linux/init.h> + +#include "at93c.h" + +#define AT93C_ADDR_SHIFT 7 +#define AT93C_ADDR_MAX ((1 << AT93C_ADDR_SHIFT) - 1) +#define AT93C_RCMD (0x6 << AT93C_ADDR_SHIFT) +#define AT93C_WCMD (0x5 << AT93C_ADDR_SHIFT) +#define AT93C_WENCMD 0x260 +#define AT93C_WDSCMD 0x200 + +struct at93c_defs *at93c; + +static void at93c_reg_write(u32 val) +{ + *at93c->reg = val; +} + +static u32 at93c_reg_read(void) +{ + u32 tmp = *at93c->reg; + return tmp; +} + +static u32 at93c_datareg_read(void) +{ + u32 tmp = *at93c->rdata_reg; + return tmp; +} + +static void at93c_cycle_clk(u32 data) +{ + at93c_reg_write(data | at93c->clk); + ndelay(250); + at93c_reg_write(data & ~at93c->clk); + ndelay(250); +} + +static void at93c_write_databit(u8 bit) +{ + u32 data = at93c_reg_read(); + if (bit) + data |= 1 << at93c->wdata_shift; + else + data &= ~(1 << at93c->wdata_shift); + + at93c_reg_write(data); + ndelay(100); + at93c_cycle_clk(data); +} + +static unsigned int at93c_read_databit(void) +{ + u32 data; + + at93c_cycle_clk(at93c_reg_read()); + data = (at93c_datareg_read() >> at93c->rdata_shift) & 1; + return data; +} + +static u8 at93c_read_byte(void) +{ + int i; + u8 data = 0; + + for (i = 0; i<=7; i++) { + data <<= 1; + data |= at93c_read_databit(); + } + return data; +} + +static void at93c_write_bits(u32 data, int size) +{ + int i; + int shift = size - 1; + u32 mask = (1 << shift); + + for (i = 0; i < size; i++) { + at93c_write_databit((data & mask) >> shift); + data <<= 1; + } +} + +static void at93c_init_op(void) +{ + at93c_reg_write((at93c_reg_read() | at93c->cs) & ~at93c->clk & ~(1 << at93c->rdata_shift)); + ndelay(50); +} + +static void at93c_end_op(void) +{ + at93c_reg_write(at93c_reg_read() & ~at93c->cs); + ndelay(250); +} + +static void at93c_wait(void) +{ + at93c_init_op(); + while (!at93c_read_databit()) + ; + at93c_end_op(); +}; + +static void at93c_disable_wp(void) +{ + at93c_init_op(); + at93c_write_bits(AT93C_WENCMD, 10); + at93c_end_op(); +} + +static void at93c_enable_wp(void) +{ + at93c_init_op(); + at93c_write_bits(AT93C_WDSCMD, 10); + at93c_end_op(); +} + +u8 at93c_read(u8 addr) +{ + u8 byte; + at93c_init_op(); + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_RCMD, 10); + byte = at93c_read_byte(); + at93c_end_op(); + return byte; +} + +void at93c_write(u8 addr, u8 data) +{ + at93c_disable_wp(); + at93c_init_op(); + at93c_write_bits((addr & AT93C_ADDR_MAX)|AT93C_WCMD, 10); + at93c_write_bits(data, 8); + at93c_end_op(); + at93c_wait(); + at93c_enable_wp(); +} diff -Nru a/arch/mips/lasat/at93c.h b/arch/mips/lasat/at93c.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/at93c.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,18 @@ +/* + * Atmel AT93C46 serial eeprom driver + * + * Brian Murphy <brian.murphy@eicon.com> + * + */ + +extern struct at93c_defs { + volatile u32 *reg; + volatile u32 *rdata_reg; + int rdata_shift; + int wdata_shift; + u32 cs; + u32 clk; +} *at93c; + +u8 at93c_read(u8 addr); +void at93c_write(u8 addr, u8 data); diff -Nru a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/ds1603.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,174 @@ +/* + * Dallas Semiconductors 1603 RTC driver + * + * Brian Murphy <brian@murphy.dk> + * + */ +#include <linux/kernel.h> +#include <asm/lasat/lasat.h> +#include <linux/delay.h> +#include <asm/lasat/ds1603.h> + +#include "ds1603.h" + +#define READ_TIME_CMD 0x81 +#define SET_TIME_CMD 0x80 +#define TRIMMER_SET_CMD 0xC0 +#define TRIMMER_VALUE_MASK 0x38 +#define TRIMMER_SHIFT 3 + +struct ds_defs *ds1603 = NULL; + +/* HW specific register functions */ +static void rtc_reg_write(unsigned long val) +{ + *ds1603->reg = val; +} + +static unsigned long rtc_reg_read(void) +{ + unsigned long tmp = *ds1603->reg; + return tmp; +} + +static unsigned long rtc_datareg_read(void) +{ + unsigned long tmp = *ds1603->data_reg; + return tmp; +} + +static void rtc_nrst_high(void) +{ + rtc_reg_write(rtc_reg_read() | ds1603->rst); +} + +static void rtc_nrst_low(void) +{ + rtc_reg_write(rtc_reg_read() & ~ds1603->rst); +} + +static void rtc_cycle_clock(unsigned long data) +{ + data |= ds1603->clk; + rtc_reg_write(data); + ndelay(250); + if (ds1603->data_reversed) + data &= ~ds1603->data; + else + data |= ds1603->data; + data &= ~ds1603->clk; + rtc_reg_write(data); + ndelay(250 + ds1603->huge_delay); +} + +static void rtc_write_databit(unsigned int bit) +{ + unsigned long data = rtc_reg_read(); + if (ds1603->data_reversed) + bit = !bit; + if (bit) + data |= ds1603->data; + else + data &= ~ds1603->data; + + rtc_reg_write(data); + ndelay(50 + ds1603->huge_delay); + rtc_cycle_clock(data); +} + +static unsigned int rtc_read_databit(void) +{ + unsigned int data; + + data = (rtc_datareg_read() & (1 << ds1603->data_read_shift)) + >> ds1603->data_read_shift; + rtc_cycle_clock(rtc_reg_read()); + return data; +} + +static void rtc_write_byte(unsigned int byte) +{ + int i; + + for (i = 0; i<=7; i++) { + rtc_write_databit(byte & 1L); + byte >>= 1; + } +} + +static void rtc_write_word(unsigned long word) +{ + int i; + + for (i = 0; i<=31; i++) { + rtc_write_databit(word & 1L); + word >>= 1; + } +} + +static unsigned long rtc_read_word(void) +{ + int i; + unsigned long word = 0; + unsigned long shift = 0; + + for (i = 0; i<=31; i++) { + word |= rtc_read_databit() << shift; + shift++; + } + return word; +} + +static void rtc_init_op(void) +{ + rtc_nrst_high(); + + rtc_reg_write(rtc_reg_read() & ~ds1603->clk); + + ndelay(50); +} + +static void rtc_end_op(void) +{ + rtc_nrst_low(); + ndelay(1000); +} + +/* interface */ +unsigned long ds1603_read(void) +{ + unsigned long word; + rtc_init_op(); + rtc_write_byte(READ_TIME_CMD); + word = rtc_read_word(); + rtc_end_op(); + return word; +} + +int ds1603_set(unsigned long time) +{ + rtc_init_op(); + rtc_write_byte(SET_TIME_CMD); + rtc_write_word(time); + rtc_end_op(); + + return 0; +} + +void ds1603_set_trimmer(unsigned int trimval) +{ + rtc_init_op(); + rtc_write_byte(((trimval << TRIMMER_SHIFT) & TRIMMER_VALUE_MASK) + | (TRIMMER_SET_CMD)); + rtc_end_op(); +} + +void ds1603_disable(void) +{ + ds1603_set_trimmer(TRIMMER_DISABLE_RTC); +} + +void ds1603_enable(void) +{ + ds1603_set_trimmer(TRIMMER_DEFAULT); +} diff -Nru a/arch/mips/lasat/ds1603.h b/arch/mips/lasat/ds1603.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/ds1603.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,33 @@ +/* + * Dallas Semiconductors 1603 RTC driver + * + * Brian Murphy <brian@murphy.dk> + * + */ +#ifndef __DS1603_H +#define __DS1603_H + +struct ds_defs { + volatile u32 *reg; + volatile u32 *data_reg; + u32 rst; + u32 clk; + u32 data; + u32 data_read_shift; + char data_reversed; + u32 huge_delay; +}; + +extern struct ds_defs *ds1603; + +unsigned long ds1603_read(void); +int ds1603_set(unsigned long); +void ds1603_set_trimmer(unsigned int); +void ds1603_enable(void); +void ds1603_disable(void); +void ds1603_init(struct ds_defs *); + +#define TRIMMER_DEFAULT 3 +#define TRIMMER_DISABLE_RTC 0 + +#endif diff -Nru a/arch/mips/lasat/image/Makefile b/arch/mips/lasat/image/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/image/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,52 @@ +# +# MAKEFILE FOR THE MIPS LINUX BOOTLOADER AND ROM DEBUGGER +# +# i-data Networks +# +# Author: Thomas Horsten <thh@i-data.com> +# + +ifndef Version + Version = "$(USER)-test" +endif + +MKLASATIMG = mklasatimg +MKLASATIMG_ARCH = mq2,mqpro,sp100,sp200 +KERNEL_IMAGE = $(TOPDIR)/vmlinux +KERNEL_START = $(shell $(NM) $(KERNEL_IMAGE) | grep " _text" | cut -f1 -d\ ) +KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IMAGE) | grep kernel_entry | cut -f1 -d\ ) + +LDSCRIPT= -L$(obj) -Tromscript.normal + +AFLAGS_head.o += -D_kernel_start=0x$(KERNEL_START) \ + -D_kernel_entry=0x$(KERNEL_ENTRY) \ + -D VERSION="\"$(Version)\"" \ + -D TIMESTAMP=$(shell date +%s) + +head.o: $(KERNEL_IMAGE) + +obj-y = head.o kImage.o + +rom.sw: $(obj)/rom.sw + +$(obj)/rom.sw: $(obj)/rom.bin + $(MKLASATIMG) -o $@ -k $^ -m $(MKLASATIMG_ARCH) + +$(obj)/rom.bin: $(obj)/rom + $(OBJCOPY) -O binary -S $^ $@ + +# Rule to make the bootloader +$(obj)/rom: $(addprefix $(obj)/,$(obj-y)) + $(LD) $(LDFLAGS) $(LDSCRIPT) -o $@ $^ + +$(obj)/%.o: $(obj)/%.gz + $(LD) -r -o $@ -b binary $< + +$(obj)/%.gz: $(obj)/%.bin + gzip -cf -9 $< > $@ + +$(obj)/kImage.bin: $(KERNEL_IMAGE) + $(OBJCOPY) -O binary -S $^ $@ + +clean: + rm -f rom rom.bin rom.sw kImage.bin kImage.o diff -Nru a/arch/mips/lasat/image/head.S b/arch/mips/lasat/image/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/image/head.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,31 @@ +#include <asm/lasat/head.h> + + .text + .section .text.start, "ax" + .set noreorder + .set mips3 + + /* Magic words identifying a software image */ + .word LASAT_K_MAGIC0_VAL + .word LASAT_K_MAGIC1_VAL + + /* Image header version */ + .word 0x00000002 + + /* image start and size */ + .word _image_start + .word _image_size + + /* start of kernel and entrypoint in uncompressed image */ + .word _kernel_start + .word _kernel_entry + + /* Here we have room for future flags */ + + .org 0x40 +reldate: + .word TIMESTAMP + + .org 0x50 +release: + .string VERSION diff -Nru a/arch/mips/lasat/image/romscript.normal b/arch/mips/lasat/image/romscript.normal --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/image/romscript.normal Fri Jun 27 14:20:06 2003 @@ -0,0 +1,22 @@ +OUTPUT_ARCH(mips) + +SECTIONS +{ + .text : + { + *(.text.start) + } + + /* Data in ROM */ + + .data ALIGN(0x10) : + { + *(.data) + } + _image_start = ADDR(.data); + _image_size = SIZEOF(.data); + + .other : { + *(.*) + } +} diff -Nru a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/interrupt.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,194 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines for generic manipulation of the interrupts found on the + * Lasat boards. + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> + +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/lasat/lasatint.h> +#include <asm/gdb-stub.h> + +static volatile int *lasat_int_status = NULL; +static volatile int *lasat_int_mask = NULL; +static volatile int lasat_int_mask_shift; + +extern asmlinkage void mipsIRQ(void); + +#if 0 +#define DEBUG_INT(x...) printk(x) +#else +#define DEBUG_INT(x...) +#endif + +void disable_lasat_irq(unsigned int irq_nr) +{ + unsigned long flags; + DEBUG_INT("disable_lasat_irq: %d", irq_nr); + + local_irq_save(flags); + *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); +} + +void enable_lasat_irq(unsigned int irq_nr) +{ + unsigned long flags; + DEBUG_INT("enable_lasat_irq: %d", irq_nr); + + local_irq_save(flags); + *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; + local_irq_restore(flags); +} + +static unsigned int startup_lasat_irq(unsigned int irq) +{ + enable_lasat_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_lasat_irq disable_lasat_irq + +#define mask_and_ack_lasat_irq disable_lasat_irq + +static void end_lasat_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_lasat_irq(irq); +} + +static struct hw_interrupt_type lasat_irq_type = { + "Lasat", + startup_lasat_irq, + shutdown_lasat_irq, + enable_lasat_irq, + disable_lasat_irq, + mask_and_ack_lasat_irq, + end_lasat_irq, + NULL +}; + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +static unsigned long (* get_int_status)(void); + +static unsigned long get_int_status_100(void) +{ + return (*lasat_int_status & *lasat_int_mask); +} + +static unsigned long get_int_status_200(void) +{ + unsigned long int_status; + + int_status = *lasat_int_status; + int_status &= (int_status >> LASATINT_MASK_SHIFT_200) & 0xffff; + return int_status; +} + +void lasat_hw0_irqdispatch(struct pt_regs *regs) +{ + struct irqaction *action; + unsigned long int_status; + int irq; + + int_status = get_int_status(); + + /* if int_status == 0, then the interrupt has already been cleared */ + if (int_status == 0) + return; + + irq = ls1bit32(int_status); + action = irq_desc[irq].action; + + DEBUG_INT("lasat_hw0_irqdispatch: irq=%d\n", irq); + + /* if action == NULL, then we don't have a handler for the irq */ + if (action == NULL) { + printk("No handler for hw0 irq: %i\n", irq); + atomic_inc(&irq_err_count); + disable_lasat_irq(irq); + return; + } + + irq_enter(); + kstat_cpu(0).irqs[irq]++; + action->handler(irq, action->dev_id, regs); + irq_exit(); + + return; +} + +void __init init_IRQ(void) +{ + int i; + + init_generic_irq(); + + switch (mips_machtype) { + case MACH_LASAT_100: + lasat_int_status = (void *)LASAT_INT_STATUS_REG_100; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_100; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_100; + get_int_status = get_int_status_100; + *lasat_int_mask = 0; + break; + case MACH_LASAT_200: + printk("**** MACH_LASAT_200 interrupt routines\n"); + lasat_int_status = (void *)LASAT_INT_STATUS_REG_200; + lasat_int_mask = (void *)LASAT_INT_MASK_REG_200; + lasat_int_mask_shift = LASATINT_MASK_SHIFT_200; + get_int_status = get_int_status_200; + *lasat_int_mask &= 0xffff; + break; + default: + panic("init_IRQ: mips_machtype incorrect"); + } + + /* Now safe to set the exception vector. */ + set_except_vector(0, mipsIRQ); + + for (i = 0; i <= LASATINT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &lasat_irq_type; + } +} diff -Nru a/arch/mips/lasat/lasatIRQ.S b/arch/mips/lasat/lasatIRQ.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/lasatIRQ.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,75 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Interrupt exception dispatch code. + * + */ +#include <linux/config.h> + +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + .text + .set noreorder + .set noat + .align 5 + NESTED(mipsIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 s0, CP0_CAUSE # get irq mask + + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP7 + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt + + /* Wheee, a timer interrupt. */ + move a0, sp + jal lasat_timer_interrupt + nop + + j ret_from_irq + nop + +1: + /* Wheee, combined hardware level zero interrupt. */ + jal lasat_hw0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + /* + * Here by mistake? This is possible, what can happen is that by the + * time we take the exception the IRQ pin goes low, so just leave if + * this is the case. + */ + move a1,s0 + mfc0 a1, CP0_EPC + + j ret_from_irq + nop + END(mipsIRQ) diff -Nru a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/lasat_board.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,282 @@ +/* + * lasat_board.c + * + * Thomas Horsten <thh@lasat.com> + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines specific to the LASAT boards + */ +#include <linux/types.h> +#include <linux/crc32.h> +#include <asm/lasat/lasat.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <asm/bootinfo.h> +#include <asm/addrspace.h> +#include "at93c.h" +/* New model description table */ +#include "lasat_models.h" + +#define EEPROM_CRC(data, len) (~0 ^ crc32(~0, data, len)) + +struct lasat_info lasat_board_info; + +void update_bcastaddr(void); + +int EEPROMRead(unsigned int pos, unsigned char *data, int len) +{ + int i; + + for (i=0; i<len; i++) + *data++ = at93c_read(pos++); + + return 0; +} +int EEPROMWrite(unsigned int pos, unsigned char *data, int len) +{ + int i; + + for (i=0; i<len; i++) + at93c_write(pos++, *data++); + + return 0; +} + +static void init_flash_sizes(void) +{ + int i; + unsigned long *lb = lasat_board_info.li_flashpart_base; + unsigned long *ls = lasat_board_info.li_flashpart_size; + + ls[LASAT_MTD_BOOTLOADER] = 0x40000; + ls[LASAT_MTD_SERVICE] = 0xC0000; + ls[LASAT_MTD_NORMAL] = 0x100000; + + if (mips_machtype == MACH_LASAT_100) { + lasat_board_info.li_flash_base = KSEG1ADDR(0x1e000000); + + lb[LASAT_MTD_BOOTLOADER] = KSEG1ADDR(0x1e400000); + + if (lasat_board_info.li_flash_size > 0x200000) { + ls[LASAT_MTD_CONFIG] = 0x100000; + ls[LASAT_MTD_FS] = 0x500000; + } + } else { + lasat_board_info.li_flash_base = KSEG1ADDR(0x10000000); + + if (lasat_board_info.li_flash_size < 0x1000000) { + lb[LASAT_MTD_BOOTLOADER] = KSEG1ADDR(0x10000000); + ls[LASAT_MTD_CONFIG] = 0x100000; + if (lasat_board_info.li_flash_size >= 0x400000) { + ls[LASAT_MTD_FS] = lasat_board_info.li_flash_size - 0x300000; + } + } + } + + for (i = 1; i < LASAT_MTD_LAST; i++) + lb[i] = lb[i-1] + ls[i-1]; +} + +int lasat_init_board_info(void) +{ + int c; + unsigned long crc; + unsigned long cfg0, cfg1; + const product_info_t *ppi; + int i_n_base_models = N_BASE_MODELS; + const char * const * i_txt_base_models = txt_base_models; + int i_n_prids = N_PRIDS; + + memset(&lasat_board_info, 0, sizeof(lasat_board_info)); + + /* First read the EEPROM info */ + EEPROMRead(0, (unsigned char *)&lasat_board_info.li_eeprom_info, + sizeof(struct lasat_eeprom_struct)); + + /* Check the CRC */ + crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), + sizeof(struct lasat_eeprom_struct) - 4); + + if (crc != lasat_board_info.li_eeprom_info.crc32) { + prom_printf("WARNING...\nWARNING...\nEEPROM CRC does not match calculated, attempting to soldier on...\n"); + } + + if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) + { + prom_printf("WARNING...\nWARNING...\nEEPROM version %d, wanted version %d, attempting to soldier on...\n", + (unsigned int)lasat_board_info.li_eeprom_info.version, + LASAT_EEPROM_VERSION); + } + + cfg0 = lasat_board_info.li_eeprom_info.cfg[0]; + cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; + + if ( LASAT_W0_DSCTYPE(cfg0) != 1) { + prom_printf("WARNING...\nWARNING...\nInvalid configuration read from EEPROM, attempting to soldier on..."); + } + /* We have a valid configuration */ + + switch (LASAT_W0_SDRAMBANKSZ(cfg0)) { + case 0: + lasat_board_info.li_memsize = 0x0800000; + break; + case 1: + lasat_board_info.li_memsize = 0x1000000; + break; + case 2: + lasat_board_info.li_memsize = 0x2000000; + break; + case 3: + lasat_board_info.li_memsize = 0x4000000; + break; + case 4: + lasat_board_info.li_memsize = 0x8000000; + break; + default: + lasat_board_info.li_memsize = 0; + } + + switch (LASAT_W0_SDRAMBANKS(cfg0)) { + case 0: + break; + case 1: + lasat_board_info.li_memsize *= 2; + break; + default: + break; + } + + switch (LASAT_W0_BUSSPEED(cfg0)) { + case 0x0: + lasat_board_info.li_bus_hz = 60000000; + break; + case 0x1: + lasat_board_info.li_bus_hz = 66000000; + break; + case 0x2: + lasat_board_info.li_bus_hz = 66666667; + break; + case 0x3: + lasat_board_info.li_bus_hz = 80000000; + break; + case 0x4: + lasat_board_info.li_bus_hz = 83333333; + break; + case 0x5: + lasat_board_info.li_bus_hz = 100000000; + break; + } + + switch (LASAT_W0_CPUCLK(cfg0)) { + case 0x0: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz; + break; + case 0x1: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + (lasat_board_info.li_bus_hz >> 1); + break; + case 0x2: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz; + break; + case 0x3: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz + + (lasat_board_info.li_bus_hz >> 1); + break; + case 0x4: + lasat_board_info.li_cpu_hz = + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz + + lasat_board_info.li_bus_hz; + break; + } + + /* Flash size */ + switch (LASAT_W1_FLASHSIZE(cfg1)) { + case 0: + lasat_board_info.li_flash_size = 0x200000; + break; + case 1: + lasat_board_info.li_flash_size = 0x400000; + break; + case 2: + lasat_board_info.li_flash_size = 0x800000; + break; + case 3: + lasat_board_info.li_flash_size = 0x1000000; + break; + case 4: + lasat_board_info.li_flash_size = 0x2000000; + break; + } + + init_flash_sizes(); + + lasat_board_info.li_bmid = LASAT_W0_BMID(cfg0); + lasat_board_info.li_prid = lasat_board_info.li_eeprom_info.prid; + if (lasat_board_info.li_prid == 0xffff || lasat_board_info.li_prid == 0) + lasat_board_info.li_prid = lasat_board_info.li_bmid; + + /* Base model stuff */ + if (lasat_board_info.li_bmid > i_n_base_models) + lasat_board_info.li_bmid = i_n_base_models; + strcpy(lasat_board_info.li_bmstr, i_txt_base_models[lasat_board_info.li_bmid]); + + /* Product ID dependent values */ + c = lasat_board_info.li_prid; + if (c >= i_n_prids) { + strcpy(lasat_board_info.li_namestr, "Unknown Model"); + strcpy(lasat_board_info.li_typestr, "Unknown Type"); + } else { + ppi = &vendor_info_table[0].vi_product_info[c]; + strcpy(lasat_board_info.li_namestr, ppi->pi_name); + if (ppi->pi_type) + strcpy(lasat_board_info.li_typestr, ppi->pi_type); + else + sprintf(lasat_board_info.li_typestr, "%d",10*c); + } + +#if defined(CONFIG_INET) && defined(CONFIG_SYSCTL) + update_bcastaddr(); +#endif + + return 0; +} + +void lasat_write_eeprom_info(void) +{ + unsigned long crc; + + /* Generate the CRC */ + crc = EEPROM_CRC((unsigned char *)(&lasat_board_info.li_eeprom_info), + sizeof(struct lasat_eeprom_struct) - 4); + lasat_board_info.li_eeprom_info.crc32 = crc; + + /* Write the EEPROM info */ + EEPROMWrite(0, (unsigned char *)&lasat_board_info.li_eeprom_info, + sizeof(struct lasat_eeprom_struct)); +} + diff -Nru a/arch/mips/lasat/lasat_models.h b/arch/mips/lasat/lasat_models.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/lasat_models.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,63 @@ +/* + * Model description tables + */ + +typedef struct product_info_t { + const char *pi_name; + const char *pi_type; +} product_info_t; + +typedef struct vendor_info_t { + const char *vi_name; + const product_info_t *vi_product_info; +} vendor_info_t; + +/* + * Base models + */ +static const char * const txt_base_models[] = { + "MQ 2", "MQ Pro", "SP 25", "SP 50", "SP 100", "SP 5000", "SP 7000", "SP 1000", "Unknown" +}; +#define N_BASE_MODELS (sizeof(txt_base_models)/sizeof(char*)-1) + +/* + * Eicon Networks + */ +static const char txt_en_mq[] = "Masquerade"; +static const char txt_en_sp[] = "Safepipe"; + +static const product_info_t product_info_eicon[] = { + { txt_en_mq, "II" }, /* 0 */ + { txt_en_mq, "Pro" }, /* 1 */ + { txt_en_sp, "25" }, /* 2 */ + { txt_en_sp, "50" }, /* 3 */ + { txt_en_sp, "100" }, /* 4 */ + { txt_en_sp, "5000" }, /* 5 */ + { txt_en_sp, "7000" }, /* 6 */ + { txt_en_sp, "30" }, /* 7 */ + { txt_en_sp, "5100" }, /* 8 */ + { txt_en_sp, "7100" }, /* 9 */ + { txt_en_sp, "1110" }, /* 10 */ + { txt_en_sp, "3020" }, /* 11 */ + { txt_en_sp, "3030" }, /* 12 */ + { txt_en_sp, "5020" }, /* 13 */ + { txt_en_sp, "5030" }, /* 14 */ + { txt_en_sp, "1120" }, /* 15 */ + { txt_en_sp, "1130" }, /* 16 */ + { txt_en_sp, "6010" }, /* 17 */ + { txt_en_sp, "6110" }, /* 18 */ + { txt_en_sp, "6210" }, /* 19 */ + { txt_en_sp, "1020" }, /* 20 */ + { txt_en_sp, "1040" }, /* 21 */ + { txt_en_sp, "1050" }, /* 22 */ + { txt_en_sp, "1060" }, /* 23 */ +}; +#define N_PRIDS (sizeof(product_info_eicon)/sizeof(product_info_t)) + +/* + * The vendor table + */ +static vendor_info_t const vendor_info_table[] = { + { "Eicon Networks", product_info_eicon }, +}; +#define N_VENDORS (sizeof(vendor_info_table)/sizeof(vendor_info_t)) diff -Nru a/arch/mips/lasat/picvue.c b/arch/mips/lasat/picvue.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/picvue.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,240 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy <brian@murphy.dk> + * + */ +#include <linux/kernel.h> +#include <linux/delay.h> +#include <asm/bootinfo.h> +#include <asm/lasat/lasat.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/string.h> + +#include "picvue.h" + +#define PVC_BUSY 0x80 +#define PVC_NLINES 2 +#define PVC_DISPMEM 80 +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES + +struct pvc_defs *picvue = NULL; + +DECLARE_MUTEX(pvc_sem); + +static void pvc_reg_write(u32 val) +{ + *picvue->reg = val; +} + +static u32 pvc_reg_read(void) +{ + u32 tmp = *picvue->reg; + return tmp; +} + +static void pvc_write_byte(u32 data, u8 byte) +{ + data |= picvue->e; + pvc_reg_write(data); + data &= ~picvue->data_mask; + data |= byte << picvue->data_shift; + pvc_reg_write(data); + ndelay(220); + pvc_reg_write(data & ~picvue->e); + ndelay(220); +} + +static u8 pvc_read_byte(u32 data) +{ + u8 byte; + + data |= picvue->e; + pvc_reg_write(data); + ndelay(220); + byte = (pvc_reg_read() & picvue->data_mask) >> picvue->data_shift; + data &= ~picvue->e; + pvc_reg_write(data); + ndelay(220); + return byte; +} + +static u8 pvc_read_data(void) +{ + u32 data = pvc_reg_read(); + u8 byte; + data |= picvue->rw; + data &= ~picvue->rs; + pvc_reg_write(data); + ndelay(40); + byte = pvc_read_byte(data); + data |= picvue->rs; + pvc_reg_write(data); + return byte; +} + +#define TIMEOUT 1000 +static int pvc_wait(void) +{ + int i = TIMEOUT; + int err = 0; + + while ((pvc_read_data() & PVC_BUSY) && i) + i--; + if (i == 0) + err = -ETIME; + + return err; +} + +#define MODE_INST 0 +#define MODE_DATA 1 +static void pvc_write(u8 byte, int mode) +{ + u32 data = pvc_reg_read(); + data &= ~picvue->rw; + if (mode == MODE_DATA) + data |= picvue->rs; + else + data &= ~picvue->rs; + pvc_reg_write(data); + ndelay(40); + pvc_write_byte(data, byte); + if (mode == MODE_DATA) + data &= ~picvue->rs; + else + data |= picvue->rs; + pvc_reg_write(data); + pvc_wait(); +} + +void pvc_write_string(const unsigned char *str, u8 addr, int line) +{ + int i = 0; + + if (line > 0 && (PVC_NLINES > 1)) + addr += 0x40 * line; + pvc_write(0x80 | addr, MODE_INST); + + while (*str != 0 && i < PVC_LINELEN) { + pvc_write(*str++, MODE_DATA); + i++; + } +} + +void pvc_write_string_centered(const unsigned char *str, int line) +{ + int len = strlen(str); + u8 addr; + + if (len > PVC_VISIBLE_CHARS) + addr = 0; + else + addr = (PVC_VISIBLE_CHARS - strlen(str))/2; + + pvc_write_string(str, addr, line); +} + +void pvc_dump_string(const unsigned char *str) +{ + int len = strlen(str); + + pvc_write_string(str, 0, 0); + if (len > PVC_VISIBLE_CHARS) + pvc_write_string(&str[PVC_VISIBLE_CHARS], 0, 1); +} + +#define BM_SIZE 8 +#define MAX_PROGRAMMABLE_CHARS 8 +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]) +{ + int i; + int addr; + + if (charnum > MAX_PROGRAMMABLE_CHARS) + return -ENOENT; + + addr = charnum * 8; + pvc_write(0x40 | addr, MODE_INST); + + for (i=0; i<BM_SIZE; i++) + pvc_write(bitmap[i], MODE_DATA); + return 0; +} + +#define FUNC_SET_CMD 0x20 +#define EIGHT_BYTE (1 << 4) +#define FOUR_BYTE 0 +#define TWO_LINES (1 << 3) +#define ONE_LINE 0 +#define LARGE_FONT (1 << 2) +#define SMALL_FONT 0 +static void pvc_funcset(u8 cmd) +{ + pvc_write(FUNC_SET_CMD | (cmd & (EIGHT_BYTE|TWO_LINES|LARGE_FONT)), MODE_INST); +} + +#define ENTRYMODE_CMD 0x4 +#define AUTO_INC (1 << 1) +#define AUTO_DEC 0 +#define CURSOR_FOLLOWS_DISP (1 << 0) +static void pvc_entrymode(u8 cmd) +{ + pvc_write(ENTRYMODE_CMD | (cmd & (AUTO_INC|CURSOR_FOLLOWS_DISP)), MODE_INST); +} + +#define DISP_CNT_CMD 0x08 +#define DISP_OFF 0 +#define DISP_ON (1 << 2) +#define CUR_ON (1 << 1) +#define CUR_BLINK (1 << 0) +void pvc_dispcnt(u8 cmd) +{ + pvc_write(DISP_CNT_CMD | (cmd & (DISP_ON|CUR_ON|CUR_BLINK)), MODE_INST); +} + +#define MOVE_CMD 0x10 +#define DISPLAY (1 << 3) +#define CURSOR 0 +#define RIGHT (1 << 2) +#define LEFT 0 +void pvc_move(u8 cmd) +{ + pvc_write(MOVE_CMD | (cmd & (DISPLAY|RIGHT)), MODE_INST); +} + +#define CLEAR_CMD 0x1 +void pvc_clear(void) +{ + pvc_write(CLEAR_CMD, MODE_INST); +} + +#define HOME_CMD 0x2 +void pvc_home(void) +{ + pvc_write(HOME_CMD, MODE_INST); +} + +int pvc_init(void) +{ + u8 cmd = EIGHT_BYTE; + + if (PVC_NLINES == 2) + cmd |= (SMALL_FONT|TWO_LINES); + else + cmd |= (LARGE_FONT|ONE_LINE); + pvc_funcset(cmd); + pvc_dispcnt(DISP_ON); + pvc_entrymode(AUTO_INC); + + pvc_clear(); + pvc_write_string_centered("Display", 0); + pvc_write_string_centered("Initialized", 1); + + return 0; +} + +module_init(pvc_init); +MODULE_LICENSE("GPL"); diff -Nru a/arch/mips/lasat/picvue.h b/arch/mips/lasat/picvue.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/picvue.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,48 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy <brian.murphy@eicon.com> + * + */ +#include <asm/semaphore.h> + +struct pvc_defs { + volatile u32 *reg; + u32 data_shift; + u32 data_mask; + u32 e; + u32 rw; + u32 rs; +}; + +extern struct pvc_defs *picvue; + +#define PVC_NLINES 2 +#define PVC_DISPMEM 80 +#define PVC_LINELEN PVC_DISPMEM / PVC_NLINES +#define PVC_VISIBLE_CHARS 16 + +void pvc_write_string(const unsigned char *str, u8 addr, int line); +void pvc_write_string_centered(const unsigned char *str, int line); +void pvc_dump_string(const unsigned char *str); + +#define BM_SIZE 8 +#define MAX_PROGRAMMABLE_CHARS 8 +int pvc_program_cg(int charnum, u8 bitmap[BM_SIZE]); + +void pvc_dispcnt(u8 cmd); +#define DISP_OFF 0 +#define DISP_ON (1 << 2) +#define CUR_ON (1 << 1) +#define CUR_BLINK (1 << 0) + +void pvc_move(u8 cmd); +#define DISPLAY (1 << 3) +#define CURSOR 0 +#define RIGHT (1 << 2) +#define LEFT 0 + +void pvc_clear(void); +void pvc_home(void); + +extern struct semaphore pvc_sem; diff -Nru a/arch/mips/lasat/picvue_proc.c b/arch/mips/lasat/picvue_proc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/picvue_proc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,186 @@ +/* + * Picvue PVC160206 display driver + * + * Brian Murphy <brian.murphy@eicon.com> + * + */ +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/errno.h> + +#include <linux/proc_fs.h> +#include <linux/interrupt.h> + +#include <linux/timer.h> + +#include "picvue.h" + +static char pvc_lines[PVC_NLINES][PVC_LINELEN+1]; +static int pvc_linedata[PVC_NLINES]; +static struct proc_dir_entry *pvc_display_dir; +static char *pvc_linename[PVC_NLINES] = {"line1", "line2"}; +#define DISPLAY_DIR_NAME "display" +static int scroll_dir = 0, scroll_interval = 0; + +static struct timer_list timer; + +static void pvc_display(unsigned long data) { + int i; + + pvc_clear(); + for (i=0; i<PVC_NLINES; i++) + pvc_write_string(pvc_lines[i], 0, i); +} + +static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0); + +static int pvc_proc_read_line(char *page, char **start, + off_t off, int count, + int *eof, void *data) +{ + char *origpage = page; + int lineno = *(int *)data; + + if (lineno < 0 || lineno > PVC_NLINES) { + printk("proc_read_line: invalid lineno %d\n", lineno); + return 0; + } + + down(&pvc_sem); + page += sprintf(page, "%s\n", pvc_lines[lineno]); + up(&pvc_sem); + + return page - origpage; +} + +static int pvc_proc_write_line(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int origcount = count; + int lineno = *(int *)data; + + if (lineno < 0 || lineno > PVC_NLINES) { + printk("proc_write_line: invalid lineno %d\n", lineno); + return origcount; + } + + if (count > PVC_LINELEN) + count = PVC_LINELEN; + + if (buffer[count-1] == '\n') + count--; + + down(&pvc_sem); + strncpy(pvc_lines[lineno], buffer, count); + pvc_lines[lineno][count] = '\0'; + up(&pvc_sem); + + tasklet_schedule(&pvc_display_tasklet); + + return origcount; +} + +static int pvc_proc_write_scroll(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int origcount = count; + int cmd = simple_strtol(buffer, NULL, 10); + + down(&pvc_sem); + if (scroll_interval != 0) + del_timer(&timer); + + if (cmd == 0) { + scroll_dir = 0; + scroll_interval = 0; + } else { + if (cmd < 0) { + scroll_dir = -1; + scroll_interval = -cmd; + } else { + scroll_dir = 1; + scroll_interval = cmd; + } + add_timer(&timer); + } + up(&pvc_sem); + + return origcount; +} + +static int pvc_proc_read_scroll(char *page, char **start, + off_t off, int count, + int *eof, void *data) +{ + char *origpage = page; + + down(&pvc_sem); + page += sprintf(page, "%d\n", scroll_dir * scroll_interval); + up(&pvc_sem); + + return page - origpage; +} + + +void pvc_proc_timerfunc(unsigned long data) +{ + if (scroll_dir < 0) + pvc_move(DISPLAY|RIGHT); + else if (scroll_dir > 0) + pvc_move(DISPLAY|LEFT); + + timer.expires = jiffies + scroll_interval; + add_timer(&timer); +} + +static void pvc_proc_cleanup(void) +{ + int i; + for (i=0; i<PVC_NLINES; i++) + remove_proc_entry(pvc_linename[i], pvc_display_dir); + remove_proc_entry("scroll", pvc_display_dir); + remove_proc_entry(DISPLAY_DIR_NAME, NULL); + + del_timer(&timer); +} + +static int __init pvc_proc_init(void) +{ + struct proc_dir_entry *proc_entry; + int i; + + pvc_display_dir = proc_mkdir(DISPLAY_DIR_NAME, NULL); + if (pvc_display_dir == NULL) + goto error; + + for (i=0; i<PVC_NLINES; i++) { + strcpy(pvc_lines[i], ""); + pvc_linedata[i] = i; + } + for (i=0; i<PVC_NLINES; i++) { + proc_entry = create_proc_entry(pvc_linename[i], 0644, pvc_display_dir); + if (proc_entry == NULL) + goto error; + proc_entry->read_proc = pvc_proc_read_line; + proc_entry->write_proc = pvc_proc_write_line; + proc_entry->data = &pvc_linedata[i]; + } + proc_entry = create_proc_entry("scroll", 0644, pvc_display_dir); + if (proc_entry == NULL) + goto error; + proc_entry->write_proc = pvc_proc_write_scroll; + proc_entry->read_proc = pvc_proc_read_scroll; + + init_timer(&timer); + timer.function = pvc_proc_timerfunc; + + return 0; +error: + pvc_proc_cleanup(); + return -ENOMEM; +} + +module_init(pvc_proc_init); +module_exit(pvc_proc_cleanup); +MODULE_LICENSE("GPL"); diff -Nru a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/prom.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,135 @@ +/* + * PROM interface routines. + */ +#include <linux/types.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/string.h> +#include <linux/ctype.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/ioport.h> +#include <asm/bootinfo.h> +#include <asm/lasat/lasat.h> +#include <asm/cpu.h> + +#include "at93c.h" +#include <asm/lasat/eeprom.h> +#include "prom.h" + +#define RESET_VECTOR 0xbfc00000 +#define PROM_JUMP_TABLE_ENTRY(n) (*((u32 *)(RESET_VECTOR + 0x20) + n)) +#define PROM_DISPLAY_ADDR PROM_JUMP_TABLE_ENTRY(0) +#define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) +#define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) + +static void null_prom_printf(const char * fmt, ...) +{ +} + +static void null_prom_display(const char *string, int pos, int clear) +{ +} + +static void null_prom_monitor(void) +{ +} + +static void null_prom_putc(char c) +{ +} + +/* these are functions provided by the bootloader */ +static void (* prom_putc)(char c) = null_prom_putc; +void (* prom_printf)(const char * fmt, ...) = null_prom_printf; +void (* prom_display)(const char *string, int pos, int clear) = + null_prom_display; +void (* prom_monitor)(void) = null_prom_monitor; + +#define PROM_PRINTFBUF_SIZE 256 +static char prom_printfbuf[PROM_PRINTFBUF_SIZE]; + +static void real_prom_printf(const char * fmt, ...) +{ + va_list ap; + int len; + char *c = prom_printfbuf; + int i; + + va_start(ap, fmt); + len = vsnprintf(prom_printfbuf, PROM_PRINTFBUF_SIZE, fmt, ap); + va_end(ap); + + /* output overflowed the buffer */ + if (len < 0 || len > PROM_PRINTFBUF_SIZE) + len = PROM_PRINTFBUF_SIZE; + + for (i=0; i < len; i++) { + if (*c == '\n') + prom_putc('\r'); + prom_putc(*c++); + } +} + +static void setup_prom_vectors(void) +{ + u32 version = *(u32 *)(RESET_VECTOR + 0x90); + + if (version == 306) { + prom_display = (void *)PROM_DISPLAY_ADDR; + prom_putc = (void *)PROM_PUTC_ADDR; + prom_printf = real_prom_printf; + prom_monitor = (void *)PROM_MONITOR_ADDR; + } + prom_printf("prom vectors set up\n"); +} + +char arcs_cmdline[CL_SIZE]; + +static struct at93c_defs at93c_defs[N_MACHTYPES] = { + {(void *)AT93C_REG_100, (void *)AT93C_RDATA_REG_100, AT93C_RDATA_SHIFT_100, + AT93C_WDATA_SHIFT_100, AT93C_CS_M_100, AT93C_CLK_M_100}, + {(void *)AT93C_REG_200, (void *)AT93C_RDATA_REG_200, AT93C_RDATA_SHIFT_200, + AT93C_WDATA_SHIFT_200, AT93C_CS_M_200, AT93C_CLK_M_200}, +}; + +void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + setup_prom_vectors(); + + if (current_cpu_data.cputype == CPU_R5000) + mips_machtype = MACH_LASAT_200; + else + mips_machtype = MACH_LASAT_100; + + at93c = &at93c_defs[mips_machtype]; + + lasat_init_board_info(); /* Read info from EEPROM */ + + mips_machgroup = MACH_GROUP_LASAT; + + /* Get the command line */ + if (argc>0) { + strncpy(arcs_cmdline, argv[0], CL_SIZE-1); + arcs_cmdline[CL_SIZE-1] = '\0'; + } + + /* Set the I/O base address */ + set_io_port_base(KSEG1); + + /* Set memory regions */ + ioport_resource.start = 0; /* Should be KSEGx ??? */ + ioport_resource.end = 0xffffffff; /* Should be ??? */ + + add_memory_region(0, lasat_board_info.li_memsize, BOOT_MEM_RAM); +} + +void prom_free_prom_memory(void) +{ +} + +const char *get_system_type(void) +{ + return lasat_board_info.li_bmstr; +} diff -Nru a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/prom.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,6 @@ +#ifndef PROM_H +#define PROM_H +extern void (* prom_display)(const char *string, int pos, int clear); +extern void (* prom_monitor)(void); +extern void (* prom_printf)(const char * fmt, ...); +#endif diff -Nru a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,73 @@ +/* + * + * Thomas Horsten <thh@lasat.com> + * Copyright (C) 2000 LASAT Networks A/S. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Reset the LASAT board. + * + */ + +#include <linux/kernel.h> +#include <asm/reboot.h> +#include <asm/system.h> +#include <asm/lasat/lasat.h> +#include "picvue.h" +#include "prom.h" + +static void lasat_machine_restart(char *command); +static void lasat_machine_halt(void); + +/* Used to set machine to boot in service mode via /proc interface */ +int lasat_boot_to_service = 0; + +static void lasat_machine_restart(char *command) +{ + local_irq_disable(); + + if (lasat_boot_to_service) { + printk("machine_restart: Rebooting to service mode\n"); + *(volatile unsigned int *)0xa0000024 = 0xdeadbeef; + *(volatile unsigned int *)0xa00000fc = 0xfedeabba; + } + *lasat_misc->reset_reg = 0xbedead; + for (;;) ; +} + +#define MESSAGE "System halted" +static void lasat_machine_halt(void) +{ + local_irq_disable(); + + /* Disable interrupts and loop forever */ + printk(KERN_NOTICE MESSAGE "\n"); +#ifdef CONFIG_PICVUE + pvc_clear(); + pvc_write_string(MESSAGE, 0, 0); +#endif + prom_monitor(); + for (;;) ; +} + +void lasat_reboot_setup(void) +{ + _machine_restart = lasat_machine_restart; + _machine_halt = lasat_machine_halt; + _machine_power_off = lasat_machine_halt; +} diff -Nru a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,221 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999 MIPS Technologies, Inc. All rights reserved. + * + * Thomas Horsten <thh@lasat.com> + * Copyright (C) 2000 LASAT Networks A/S. + * + * Brian Murphy <brian@murphy.dk> + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Lasat specific setup. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/pci.h> +#include <linux/ide.h> + +#include <linux/interrupt.h> +#include <asm/time.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/lasat/lasat.h> + +#include <linux/serial.h> +#include <asm/serial.h> +#include <asm/lasat/serial.h> + +#ifdef CONFIG_PICVUE +#include <linux/notifier.h> +#endif + +#include "ds1603.h" +#include "at93c.h" +#include <asm/lasat/ds1603.h> +#include <asm/lasat/picvue.h> +#include <asm/lasat/eeprom.h> + +#include "prom.h" + +int lasat_command_line = 0; +void lasatint_init(void); + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops std_ide_ops; +extern struct ide_ops *ide_ops; +#endif + +extern char arcs_cmdline[CL_SIZE]; + +extern void lasat_reboot_setup(void); +extern void pcisetup(void); +extern void edhac_init(void *, void *, void *); +extern void addrflt_init(void); + +struct lasat_misc lasat_misc_info[N_MACHTYPES] = { + {(void *)KSEG1ADDR(0x1c840000), (void *)KSEG1ADDR(0x1c800000), 2}, + {(void *)KSEG1ADDR(0x11080000), (void *)KSEG1ADDR(0x11000000), 6} +}; + +struct lasat_misc *lasat_misc = NULL; + +#ifdef CONFIG_DS1603 +static struct ds_defs ds_defs[N_MACHTYPES] = { + { (void *)DS1603_REG_100, (void *)DS1603_REG_100, + DS1603_RST_100, DS1603_CLK_100, DS1603_DATA_100, + DS1603_DATA_SHIFT_100, 0, 0 }, + { (void *)DS1603_REG_200, (void *)DS1603_DATA_REG_200, + DS1603_RST_200, DS1603_CLK_200, DS1603_DATA_200, + DS1603_DATA_READ_SHIFT_200, 1, 2000 } +}; +#endif + +#ifdef CONFIG_PICVUE +#include "picvue.h" +static struct pvc_defs pvc_defs[N_MACHTYPES] = { + { (void *)PVC_REG_100, PVC_DATA_SHIFT_100, PVC_DATA_M_100, + PVC_E_100, PVC_RW_100, PVC_RS_100 }, + { (void *)PVC_REG_200, PVC_DATA_SHIFT_200, PVC_DATA_M_200, + PVC_E_200, PVC_RW_200, PVC_RS_200 } +}; +#endif + +static int lasat_panic_display(struct notifier_block *this, + unsigned long event, void *ptr) +{ +#ifdef CONFIG_PICVUE + unsigned char *string = ptr; + if (string == NULL) + string = "Kernel Panic"; + pvc_dump_string(string); +#endif + return NOTIFY_DONE; +} + +static int lasat_panic_prom_monitor(struct notifier_block *this, + unsigned long event, void *ptr) +{ + prom_monitor(); + return NOTIFY_DONE; +} + +static struct notifier_block lasat_panic_block[] = +{ + { lasat_panic_display, NULL, INT_MAX }, + { lasat_panic_prom_monitor, NULL, INT_MIN } +}; + +#ifdef CONFIG_BLK_DEV_IDE +static int lasat_ide_default_irq(ide_ioreg_t base) { + return 0; +} + +static ide_ioreg_t lasat_ide_default_io_base(int index) { + return 0; +} +#endif + +static void lasat_time_init(void) +{ + mips_counter_frequency = lasat_board_info.li_cpu_hz / 2; +} + +static void lasat_timer_setup(struct irqaction *irq) +{ + + write_c0_compare( + read_c0_count() + + mips_counter_frequency / HZ); + change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); +} + +#define MIPS_CPU_TIMER_IRQ 7 +asmlinkage void lasat_timer_interrupt(struct pt_regs *regs) +{ + ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); +} + +//#define DYNAMIC_SERIAL_INIT +#ifdef DYNAMIC_SERIAL_INIT +void __init serial_init(void) +{ +#ifdef CONFIG_SERIAL + struct serial_struct s; + + memset(&s, 0, sizeof(s)); + + s.flags = STD_COM_FLAGS; + s.io_type = SERIAL_IO_MEM; + + if (mips_machtype == MACH_LASAT_100) { + s.baud_base = LASAT_BASE_BAUD_100; + s.irq = LASATINT_UART_100; + s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_100; + s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_100); + } else { + s.baud_base = LASAT_BASE_BAUD_200; + s.irq = LASATINT_UART_200; + s.iomem_reg_shift = LASAT_UART_REGS_SHIFT_200; + s.iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE_200); + } + + if (early_serial_setup(&s) != 0) + printk(KERN_ERR "Serial setup failed!\n"); +#endif +} +#endif + +void __init lasat_setup(void) +{ + int i; + lasat_misc = &lasat_misc_info[mips_machtype]; +#ifdef CONFIG_PICVUE + picvue = &pvc_defs[mips_machtype]; +#endif + + /* Set up panic notifier */ + for (i = 0; i < sizeof(lasat_panic_block) / sizeof(struct notifier_block); i++) + notifier_chain_register(&panic_notifier_list, &lasat_panic_block[i]); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; + ide_ops->ide_default_irq = &lasat_ide_default_irq; + ide_ops->ide_default_io_base = &lasat_ide_default_io_base; +#endif + + lasat_reboot_setup(); + + board_time_init = lasat_time_init; + board_timer_setup = lasat_timer_setup; + +#ifdef CONFIG_DS1603 + ds1603 = &ds_defs[mips_machtype]; + rtc_get_time = ds1603_read; + rtc_set_time = ds1603_set; +#endif + +#ifdef DYNAMIC_SERIAL_INIT + serial_init(); +#endif + /* Switch from prom exception handler to normal mode */ + change_c0_status(ST0_BEV,0); + + prom_printf("Lasat specific initialization complete\n"); +} + + diff -Nru a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/sysctl.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,355 @@ +/* + * Thomas Horsten <thh@lasat.com> + * Copyright (C) 2000 LASAT Networks A/S. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Routines specific to the LASAT boards + */ +#include <linux/types.h> +#include <asm/lasat/lasat.h> + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/sysctl.h> +#include <linux/stddef.h> +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/ctype.h> +#include <linux/string.h> +#include <linux/net.h> +#include <linux/inet.h> +#include <asm/uaccess.h> + +#include "sysctl.h" +#include "ds1603.h" + +static DECLARE_MUTEX(lasat_info_sem); + +/* Strategy function to write EEPROM after changing string entry */ +int sysctl_lasatstring(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + r = sysctl_string(table, name, + nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + lasat_write_eeprom_info(); + } + up(&lasat_info_sem); + return 1; +} + + +/* And the same for proc */ +int proc_dolasatstring(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dostring(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +/* proc function to write EEPROM after changing int entry */ +int proc_dolasatint(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +static int rtctmp; + +#ifdef CONFIG_DS1603 +/* proc function to read/write RealTime Clock */ +int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + if (!write) { + rtctmp = ds1603_read(); + /* check for time < 0 and set to 0 */ + if (rtctmp < 0) + rtctmp = 0; + } + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + ds1603_set(rtctmp); + up(&lasat_info_sem); + return 0; +} +#endif + +/* Sysctl for setting the IP addresses */ +int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + lasat_write_eeprom_info(); + } + up(&lasat_info_sem); + return 1; +} + +#ifdef CONFIG_DS1603 +/* Same for RTC */ +int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, void **context) +{ + int r; + down(&lasat_info_sem); + rtctmp = ds1603_read(); + if (rtctmp < 0) + rtctmp = 0; + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + if (newval && newlen) { + ds1603_set(rtctmp); + } + up(&lasat_info_sem); + return 1; +} +#endif + +#ifdef CONFIG_INET +static char lasat_bcastaddr[16]; + +void update_bcastaddr(void) +{ + unsigned int ip; + + ip = (lasat_board_info.li_eeprom_info.ipaddr & + lasat_board_info.li_eeprom_info.netmask) | + ~lasat_board_info.li_eeprom_info.netmask; + + sprintf(lasat_bcastaddr, "%d.%d.%d.%d", + (ip ) & 0xff, + (ip >> 8) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); +} + +static char proc_lasat_ipbuf[32]; +/* Parsing of IP address */ +int proc_lasat_ip(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int len; + unsigned int ip; + char *p, c; + + if (!table->data || !table->maxlen || !*lenp || + (filp->f_pos && !write)) { + *lenp = 0; + return 0; + } + + down(&lasat_info_sem); + if (write) { + len = 0; + p = buffer; + while (len < *lenp) { + if(get_user(c, p++)) { + up(&lasat_info_sem); + return -EFAULT; + } + if (c == 0 || c == '\n') + break; + len++; + } + if (len >= sizeof(proc_lasat_ipbuf)-1) + len = sizeof(proc_lasat_ipbuf) - 1; + if (copy_from_user(proc_lasat_ipbuf, buffer, len)) + { + up(&lasat_info_sem); + return -EFAULT; + } + proc_lasat_ipbuf[len] = 0; + filp->f_pos += *lenp; + /* Now see if we can convert it to a valid IP */ + ip = in_aton(proc_lasat_ipbuf); + *(unsigned int *)(table->data) = ip; + lasat_write_eeprom_info(); + } else { + ip = *(unsigned int *)(table->data); + sprintf(proc_lasat_ipbuf, "%d.%d.%d.%d", + (ip ) & 0xff, + (ip >> 8) & 0xff, + (ip >> 16) & 0xff, + (ip >> 24) & 0xff); + len = strlen(proc_lasat_ipbuf); + if (len > *lenp) + len = *lenp; + if (len) + if(copy_to_user(buffer, proc_lasat_ipbuf, len)) { + up(&lasat_info_sem); + return -EFAULT; + } + if (len < *lenp) { + if(put_user('\n', ((char *) buffer) + len)) { + up(&lasat_info_sem); + return -EFAULT; + } + len++; + } + *lenp = len; + filp->f_pos += len; + } + update_bcastaddr(); + up(&lasat_info_sem); + return 0; +} +#endif /* defined(CONFIG_INET) */ + +static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, + void *oldval, size_t *oldlenp, + void *newval, size_t newlen, + void **context) +{ + int r; + + down(&lasat_info_sem); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + if (r < 0) { + up(&lasat_info_sem); + return r; + } + + if (newval && newlen) + { + if (name && *name == LASAT_PRID) + lasat_board_info.li_eeprom_info.prid = *(int*)newval; + + lasat_write_eeprom_info(); + lasat_init_board_info(); + } + up(&lasat_info_sem); + + return 0; +} + +int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + down(&lasat_info_sem); + r = proc_dointvec(table, write, filp, buffer, lenp); + if ( (!write) || r) { + up(&lasat_info_sem); + return r; + } + if (filp && filp->f_dentry) + { + if (!strcmp(filp->f_dentry->d_name.name, "prid")) + lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; + if (!strcmp(filp->f_dentry->d_name.name, "debugaccess")) + lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; + } + lasat_write_eeprom_info(); + up(&lasat_info_sem); + return 0; +} + +extern int lasat_boot_to_service; + +#ifdef CONFIG_SYSCTL + +static ctl_table lasat_table[] = { + {LASAT_CPU_HZ, "cpu-hz", &lasat_board_info.li_cpu_hz, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_BUS_HZ, "bus-hz", &lasat_board_info.li_bus_hz, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_MODEL, "bmid", &lasat_board_info.li_bmid, sizeof(int), + 0444, NULL, &proc_dointvec, &sysctl_intvec}, + {LASAT_PRID, "prid", &lasat_board_info.li_prid, sizeof(int), + 0644, NULL, &proc_lasat_eeprom_value, &sysctl_lasat_eeprom_value}, +#ifdef CONFIG_INET + {LASAT_IPADDR, "ipaddr", &lasat_board_info.li_eeprom_info.ipaddr, sizeof(int), + 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec}, + {LASAT_NETMASK, "netmask", &lasat_board_info.li_eeprom_info.netmask, sizeof(int), + 0644, NULL, &proc_lasat_ip, &sysctl_lasat_intvec}, + {LASAT_BCAST, "bcastaddr", &lasat_bcastaddr, + sizeof(lasat_bcastaddr), 0600, NULL, + &proc_dostring, &sysctl_string}, +#endif + {LASAT_PASSWORD, "passwd_hash", &lasat_board_info.li_eeprom_info.passwd_hash, sizeof(lasat_board_info.li_eeprom_info.passwd_hash), + 0600, NULL, &proc_dolasatstring, &sysctl_lasatstring}, + {LASAT_SBOOT, "boot-service", &lasat_boot_to_service, sizeof(int), + 0644, NULL, &proc_dointvec, &sysctl_intvec}, +#ifdef CONFIG_DS1603 + {LASAT_RTC, "rtc", &rtctmp, sizeof(int), + 0644, NULL, &proc_dolasatrtc, &sysctl_lasat_rtc}, +#endif + {LASAT_NAMESTR, "namestr", &lasat_board_info.li_namestr, sizeof(lasat_board_info.li_namestr), + 0444, NULL, &proc_dostring, &sysctl_string}, + {LASAT_TYPESTR, "typestr", &lasat_board_info.li_typestr, sizeof(lasat_board_info.li_typestr), + 0444, NULL, &proc_dostring, &sysctl_string}, + {0} +}; + +#define CTL_LASAT 1 // CTL_ANY ??? +static ctl_table lasat_root_table[] = { + { CTL_LASAT, "lasat", NULL, 0, 0555, lasat_table }, + { 0 } +}; + +static int __init lasat_register_sysctl(void) +{ + struct ctl_table_header *lasat_table_header; + + lasat_table_header = + register_sysctl_table(lasat_root_table, 0); + + return 0; +} + +__initcall(lasat_register_sysctl); +#endif /* CONFIG_SYSCTL */ diff -Nru a/arch/mips/lasat/sysctl.h b/arch/mips/lasat/sysctl.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lasat/sysctl.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,24 @@ +/* + * LASAT sysctl values + */ + +#ifndef _LASAT_SYSCTL_H +#define _LASAT_SYSCTL_H + +/* /proc/sys/lasat */ +enum { + LASAT_CPU_HZ=1, + LASAT_BUS_HZ, + LASAT_MODEL, + LASAT_PRID, + LASAT_IPADDR, + LASAT_NETMASK, + LASAT_BCAST, + LASAT_PASSWORD, + LASAT_SBOOT, + LASAT_RTC, + LASAT_NAMESTR, + LASAT_TYPESTR, +}; + +#endif /* _LASAT_SYSCTL_H */ diff -Nru a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile --- a/arch/mips/lib/Makefile Fri Jun 27 14:19:53 2003 +++ b/arch/mips/lib/Makefile Fri Jun 27 14:19:53 2003 @@ -2,19 +2,17 @@ # Makefile for MIPS-specific library files.. # -EXTRA_AFLAGS := $(CFLAGS) - -lib-y += csum_partial.o csum_partial_copy.o \ - rtc-std.o rtc-no.o memcpy.o memset.o \ - watch.o strlen_user.o strncpy_user.o \ - strnlen_user.o +lib-y += csum_partial.o csum_partial_copy.o memcpy.o \ + memset.o promlib.o rtc-std.o rtc-no.o strlen_user.o \ + strncpy_user.o strnlen_user.o watch.o -ifdef CONFIG_CPU_R3000 - lib-y += r3k_dump_tlb.o +ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) + lib-y += r3k_dump_tlb.o else - lib-y += dump_tlb.o + lib-y += dump_tlb.o endif lib-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o -lib-$(CONFIG_IDE) += ide-std.o ide-no.o -lib-$(CONFIG_PC_KEYB) += kbd-std.o kbd-no.o +lib-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S --- a/arch/mips/lib/csum_partial.S Fri Jun 27 14:20:04 2003 +++ b/arch/mips/lib/csum_partial.S Fri Jun 27 14:20:04 2003 @@ -1,5 +1,4 @@ -/* $Id: csum_partial.S,v 1.1 1998/05/04 09:12:52 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff -Nru a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c --- a/arch/mips/lib/csum_partial_copy.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/lib/csum_partial_copy.c Fri Jun 27 14:20:06 2003 @@ -13,8 +13,6 @@ * 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. - * - * $Id: csum_partial_copy.c,v 1.2 1998/09/19 19:16:17 ralf Exp $ */ #include <net/checksum.h> #include <linux/types.h> @@ -25,8 +23,8 @@ /* * copy while checksumming, otherwise like csum_partial */ -unsigned int csum_partial_copy_nocheck(const char *src, char *dst, - int len, unsigned int sum) +unsigned int csum_partial_copy_nocheck(const char *src, char *dst, + int len, unsigned int sum) { /* * It's 2:30 am and I don't feel like doing it real ... @@ -43,8 +41,7 @@ * then zero the rest of the buffer. */ unsigned int csum_partial_copy_from_user (const char *src, char *dst, - int len, unsigned int sum, - int *err_ptr) + int len, unsigned int sum, int *err_ptr) { int missing; @@ -53,6 +50,6 @@ memset(dst + len - missing, 0, missing); *err_ptr = -EFAULT; } - + return csum_partial(dst, len, sum); } diff -Nru a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c --- a/arch/mips/lib/dump_tlb.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/lib/dump_tlb.c Fri Jun 27 14:19:57 2003 @@ -4,31 +4,48 @@ * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle. * Copyright (C) 1999 by Silicon Graphics, Inc. */ +#include <linux/config.h> #include <linux/kernel.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/string.h> #include <asm/bootinfo.h> +#include <asm/cpu.h> #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/page.h> #include <asm/pgtable.h> -#define mips_tlb_entries 48 +static inline const char *msg2str(unsigned int mask) +{ + switch (mask) { + case PM_4K: return "4kb"; + case PM_16K: return "16kb"; + case PM_64K: return "64kb"; + case PM_256K: return "256kb"; +#ifndef CONFIG_CPU_VR41XX + case PM_1M: return "1Mb"; + case PM_4M: return "4Mb"; + case PM_16M: return "16Mb"; + case PM_64M: return "64Mb"; + case PM_256M: return "256Mb"; +#endif + } +} -void -dump_tlb(int first, int last) +void dump_tlb(int first, int last) { int i; unsigned int pagemask, c0, c1, asid; - unsigned long entryhi, entrylo0, entrylo1; + unsigned long long entrylo0, entrylo1; + unsigned long entryhi; - asid = get_entryhi() & 0xff; + asid = read_c0_entryhi() & 0xff; - for(i=first;i<=last;i++) - { - write_32bit_cp0_register(CP0_INDEX, i); + printk("\n"); + for(i=first;i<=last;i++) { + write_c0_index(i); __asm__ __volatile__( ".set\tmips3\n\t" ".set\tnoreorder\n\t" @@ -37,57 +54,53 @@ "nop;nop;nop;nop\n\t" ".set\treorder\n\t" ".set\tmips0\n\t"); - pagemask = read_32bit_cp0_register(CP0_PAGEMASK); - entryhi = read_32bit_cp0_register(CP0_ENTRYHI); - entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0); - entrylo1 = read_32bit_cp0_register(CP0_ENTRYLO1); + pagemask = read_c0_pagemask(); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); - /* Unused entries have a virtual address of KSEG0. */ - if ((entryhi & 0xffffe000) != 0x80000000 + /* Unused entries have a virtual address in KSEG0. */ + if ((entryhi & 0xf0000000) != 0x80000000 && (entryhi & 0xff) == asid) { /* * Only print entries in use */ - printk("Index: %2d pgmask=%08x ", i, pagemask); + printk("Index: %2d pgmask=%s ", i, msg2str(pagemask)); c0 = (entrylo0 >> 3) & 7; c1 = (entrylo1 >> 3) & 7; - printk("va=%08lx asid=%08lx" - " [pa=%06lx c=%d d=%d v=%d g=%ld]" - " [pa=%06lx c=%d d=%d v=%d g=%ld]", - (entryhi & 0xffffe000), - entryhi & 0xff, - entrylo0 & PAGE_MASK, c0, + printk("va=%08lx asid=%02lx\n", + (entryhi & 0xffffe000), (entryhi & 0xff)); + printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n", + (entrylo0 << 6) & PAGE_MASK, c0, (entrylo0 & 4) ? 1 : 0, (entrylo0 & 2) ? 1 : 0, - (entrylo0 & 1), - entrylo1 & PAGE_MASK, c1, + (entrylo0 & 1)); + printk("\t\t\t[pa=%08Lx c=%d d=%d v=%d g=%Ld]\n", + (entrylo1 << 6) & PAGE_MASK, c1, (entrylo1 & 4) ? 1 : 0, (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1)); - + printk("\n"); } } - printk("\n"); - set_entryhi(asid); + write_c0_entryhi(asid); } -void -dump_tlb_all(void) +void dump_tlb_all(void) { - dump_tlb(0, mips_tlb_entries - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } -void -dump_tlb_wired(void) +void dump_tlb_wired(void) { int wired; - wired = read_32bit_cp0_register(CP0_WIRED); + wired = read_c0_wired(); printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, read_c0_wired()); } #define BARRIER \ @@ -103,14 +116,14 @@ int index; local_irq_save(flags); - oldpid = get_entryhi() & 0xff; + oldpid = read_c0_entryhi() & 0xff; BARRIER; - set_entryhi((addr & PAGE_MASK) | oldpid); + write_c0_entryhi((addr & PAGE_MASK) | oldpid); BARRIER; tlb_probe(); BARRIER; - index = get_index(); - set_entryhi(oldpid); + index = read_c0_index(); + write_c0_entryhi(oldpid); local_irq_restore(flags); if (index < 0) { @@ -125,7 +138,7 @@ void dump_tlb_nonwired(void) { - dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1); + dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); } void @@ -140,12 +153,20 @@ addr = (unsigned int) address; printk("Addr == %08x\n", addr); - printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); - - page_dir = pgd_offset(t->mm, 0); + printk("task == %8p\n", t); + printk("task->mm == %8p\n", t->mm); + //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); + + if (addr > KSEG0) + page_dir = pgd_offset_k(0); + else + page_dir = pgd_offset(t->mm, 0); printk("page_dir == %08x\n", (unsigned int) page_dir); - pgd = pgd_offset(t->mm, addr); + if (addr > KSEG0) + pgd = pgd_offset_k(addr); + else + pgd = pgd_offset(t->mm, addr); printk("pgd == %08x, ", (unsigned int) pgd); pmd = pmd_offset(pgd, addr); @@ -155,7 +176,11 @@ printk("pte == %08x, ", (unsigned int) pte); page = *pte; - printk("page == %08x\n", (unsigned int) pte_val(page)); +#ifdef CONFIG_64BIT_PHYS_ADDR + printk("page == %08Lx\n", pte_val(page)); +#else + printk("page == %08lx\n", pte_val(page)); +#endif val = pte_val(page); if (val & _PAGE_PRESENT) printk("present "); @@ -200,9 +225,7 @@ for(i=0;i<8;i++) { - printk("*%08lx == %08lx, ", - (unsigned long)p, (unsigned long)*p++); - printk("*%08lx == %08lx\n", - (unsigned long)p, (unsigned long)*p++); + printk("*%8p = %08lx, ", p, *p); p++; + printk("*%8p = %08lx\n", p, *p); p++; } } diff -Nru a/arch/mips/lib/floppy-no.c b/arch/mips/lib/floppy-no.c --- a/arch/mips/lib/floppy-no.c Fri Jun 27 14:20:03 2003 +++ b/arch/mips/lib/floppy-no.c Fri Jun 27 14:20:03 2003 @@ -1,5 +1,4 @@ -/* $Id: floppy-no.c,v 1.1 1998/05/07 18:38:32 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff -Nru a/arch/mips/lib/floppy-std.c b/arch/mips/lib/floppy-std.c --- a/arch/mips/lib/floppy-std.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/lib/floppy-std.c Fri Jun 27 14:19:59 2003 @@ -1,5 +1,4 @@ -/* $Id: floppy-std.c,v 1.2 1999/01/04 16:03:51 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -20,7 +19,6 @@ #include <asm/cachectl.h> #include <asm/dma.h> #include <asm/floppy.h> -#include <asm/keyboard.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mc146818rtc.h> @@ -112,8 +110,8 @@ } static void std_fd_dma_mem_free(unsigned long addr, unsigned long size) -{ - free_pages(addr, get_order(size)); +{ + free_pages(addr, get_order(size)); } static unsigned long std_fd_drive_type(unsigned long n) diff -Nru a/arch/mips/lib/ide-no.c b/arch/mips/lib/ide-no.c --- a/arch/mips/lib/ide-no.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/lib/ide-no.c Fri Jun 27 14:19:55 2003 @@ -1,5 +1,4 @@ -/* $Id: ide-no.c,v 1.2 1998/06/30 00:21:54 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -13,7 +12,6 @@ #include <linux/kernel.h> #include <linux/ide.h> #include <asm/hdreg.h> -#include <asm/ptrace.h> static int no_ide_default_irq(ide_ioreg_t base) { diff -Nru a/arch/mips/lib/ide-std.c b/arch/mips/lib/ide-std.c --- a/arch/mips/lib/ide-std.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/lib/ide-std.c Fri Jun 27 14:19:57 2003 @@ -11,7 +11,6 @@ #include <linux/ide.h> #include <linux/ioport.h> #include <linux/hdreg.h> -#include <asm/ptrace.h> #include <asm/hdreg.h> static int std_ide_default_irq(ide_ioreg_t base) @@ -30,16 +29,11 @@ static ide_ioreg_t std_ide_default_io_base(int index) { - switch (index) { - case 0: return 0x1f0; - case 1: return 0x170; - case 2: return 0x1e8; - case 3: return 0x168; - case 4: return 0x1e0; - case 5: return 0x160; - default: - return 0; - } + static unsigned long ata_io_base[MAX_HWIFS] = { + 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 + }; + + return ata_io_base[index]; } static void std_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, diff -Nru a/arch/mips/lib/kbd-no.c b/arch/mips/lib/kbd-no.c --- a/arch/mips/lib/kbd-no.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,63 +0,0 @@ -/* $Id: kbd-no.c,v 1.1 1998/10/28 12:38:14 ralf Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Stub keyboard and psaux routines to keep Linux from crashing on machines - * without a keyboard. - * - * Copyright (C) 1998 by Ralf Baechle - */ -#include <linux/sched.h> -#include <asm/keyboard.h> - -static void no_kbd_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static void no_aux_free_irq(void) -{ -} - -static unsigned char no_kbd_read_input(void) -{ - return 0; -} - -static void no_kbd_write_output(unsigned char val) -{ -} - -static void no_kbd_write_command(unsigned char val) -{ -} - -static unsigned char no_kbd_read_status(void) -{ - return 0; -} - -struct kbd_ops no_kbd_ops = { - no_kbd_request_region, - no_kbd_request_irq, - - no_aux_request_irq, - no_aux_free_irq, - - no_kbd_read_input, - no_kbd_write_output, - no_kbd_write_command, - no_kbd_read_status -}; diff -Nru a/arch/mips/lib/kbd-std.c b/arch/mips/lib/kbd-std.c --- a/arch/mips/lib/kbd-std.c Fri Jun 27 14:19:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,85 +0,0 @@ -/* $Id: kbd-std.c,v 1.2 1999/06/11 14:29:45 ralf Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Routines for standard PC style keyboards accessible via I/O ports. - * - * Copyright (C) 1998, 1999 by Ralf Baechle - */ -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/pc_keyb.h> -#include <asm/keyboard.h> -#include <asm/io.h> - -#define KEYBOARD_IRQ 1 -#define AUX_IRQ 12 - -static void std_kbd_request_region(void) -{ -#ifdef CONFIG_MIPS_ITE8172 - request_region(0x14000060, 16, "keyboard"); -#else - request_region(0x60, 16, "keyboard"); -#endif -} - -static int std_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL); -} - -static int std_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return request_irq(AUX_IRQ, handler, 0, "PS/2 Mouse", NULL); -} - -static void std_aux_free_irq(void) -{ - free_irq(AUX_IRQ, NULL); -} - -static unsigned char std_kbd_read_input(void) -{ - return inb(KBD_DATA_REG); -} - -static void std_kbd_write_output(unsigned char val) -{ - int status; - - do { - status = inb(KBD_CNTL_REG); - } while (status & KBD_STAT_IBF); - outb(val, KBD_DATA_REG); -} - -static void std_kbd_write_command(unsigned char val) -{ - int status; - - do { - status = inb(KBD_CNTL_REG); - } while (status & KBD_STAT_IBF); - outb(val, KBD_CNTL_REG); -} - -static unsigned char std_kbd_read_status(void) -{ - return inb(KBD_STATUS_REG); -} - -struct kbd_ops std_kbd_ops = { - std_kbd_request_region, - std_kbd_request_irq, - - std_aux_request_irq, - std_aux_free_irq, - - std_kbd_read_input, - std_kbd_write_output, - std_kbd_write_command, - std_kbd_read_status -}; diff -Nru a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S --- a/arch/mips/lib/memcpy.S Fri Jun 27 14:19:58 2003 +++ b/arch/mips/lib/memcpy.S Fri Jun 27 14:19:58 2003 @@ -4,407 +4,468 @@ * for more details. * * Unified implementation of memcpy, memmove and the __copy_user backend. - * For __rmemcpy and memmove an exception is always a kernel bug, therefore - * they're not protected. In order to keep the exception fixup routine - * simple all memory accesses in __copy_user to src rsp. dst are stricly - * incremental. The fixup routine depends on $at not being changed. + * + * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. + * Copyright (C) 2002 Broadcom, Inc. + * memcpy/copy_user author: Mark Vandevoorde + * + * Mnemonic names for arguments to memcpy/__copy_user */ +#include <linux/config.h> #include <asm/asm.h> #include <asm/offset.h> #include <asm/regdef.h> +#define dst a0 +#define src a1 +#define len a2 + /* - * The fixup routine for copy_to_user depends on copying strictly in - * increasing order. Gas expands the ulw/usw macros in the wrong order for - * little endian machines, so we cannot depend on them. + * Spec + * + * memcpy copies len bytes from src to dst and sets v0 to dst. + * It assumes that + * - src and dst don't overlap + * - src is readable + * - dst is writable + * memcpy uses the standard calling convention + * + * __copy_user copies up to len bytes from src to dst and sets a2 (len) to + * the number of uncopied bytes due to an exception caused by a read or write. + * __copy_user assumes that src and dst don't overlap, and that the call is + * implementing one of the following: + * copy_to_user + * - src is readable (no exceptions when reading src) + * copy_from_user + * - dst is writable (no exceptions when writing dst) + * __copy_user uses a non-standard calling convention; see + * include/asm-mips/uaccess.h + * + * When an exception happens on a load, the handler must + # ensure that all of the destination buffer is overwritten to prevent + * leaking information to user mode programs. */ -#ifdef __MIPSEB__ -#define uswL swl -#define uswU swr -#define ulwL lwl -#define ulwU lwr -#endif -#ifdef __MIPSEL__ -#define uswL swr -#define uswU swl -#define ulwL lwr -#define ulwU lwl -#endif -#define EX(insn,reg,addr,handler) \ -9: insn reg, addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - .previous +/* + * Implementation + */ + +/* + * The exception handler for loads requires that: + * 1- AT contain the address of the byte just past the end of the source + * of the copy, + * 2- src_entry <= src < AT, and + * 3- (dst - src) == (dst_entry - src_entry), + * The _entry suffix denotes values when __copy_user was called. + * + * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user + * (2) is met by incrementing src by the number of bytes copied + * (3) is met by not doing loads between a pair of increments of dst and src + * + * The exception handlers for stores adjust len (if necessary) and return. + * These handlers do not need to overwrite any data. + * + * For __rmemcpy and memmove an exception is always a kernel bug, therefore + * they're not protected. + */ -#define UEX(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 3 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ +#define EXC(inst_reg,addr,handler) \ +9: inst_reg, addr; \ + .section __ex_table,"a"; \ + PTR 9b, handler; \ .previous -/* ascending order, destination aligned */ -#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x04)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x08)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x10)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x14)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x18)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x1c)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x00)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x04)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x08)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x10)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x14)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x18)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x1c)(dst), s_fixup) +/* + * Only on the 64-bit kernel we can made use of 64-bit registers. + */ +#ifdef CONFIG_MIPS64 +#define USE_DOUBLE +#endif + +#ifdef USE_DOUBLE + +#define LOAD ld +#define LOADL ldl +#define LOADR ldr +#define STOREL sdl +#define STORER sdr +#define STORE sd +#define ADD daddu +#define SUB dsubu +#define SRL dsrl +#define SRA dsra +#define SLL dsll +#define SLLV dsllv +#define SRLV dsrlv +#define NBYTES 8 +#define LOG_NBYTES 3 + +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + +#else + +#define LOAD lw +#define LOADL lwl +#define LOADR lwr +#define STOREL swl +#define STORER swr +#define STORE sw +#define ADD addu +#define SUB subu +#define SRL srl +#define SLL sll +#define SRA sra +#define SLLV sllv +#define SRLV srlv +#define NBYTES 4 +#define LOG_NBYTES 2 + +#endif /* USE_DOUBLE */ + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define LDFIRST LOADR +#define LDREST LOADL +#define STFIRST STORER +#define STREST STOREL +#define SHIFT_DISCARD SLLV +#else +#define LDFIRST LOADL +#define LDREST LOADR +#define STFIRST STOREL +#define STREST STORER +#define SHIFT_DISCARD SRLV +#endif + +#define FIRST(unit) ((unit)*NBYTES) +#define REST(unit) (FIRST(unit)+NBYTES-1) +#define UNIT(unit) FIRST(unit) + +#define ADDRMASK (NBYTES-1) .text .set noreorder .set noat +/* + * A combined memcpy/__copy_user + * __copy_user sets len to 0 for success; else to an upper bound of + * the number of uncopied bytes. + * memcpy sets v0 to dst. + */ .align 5 LEAF(memcpy) /* a0=dst a1=src a2=len */ - move v0, a0 /* return value */ + move v0, dst /* return value */ __memcpy: -EXPORT(__copy_user) - xor t0, a0, a1 - andi t0, t0, 0x3 - move t7, a0 - beqz t0, can_align - sltiu t8, a2, 0x8 - - b memcpy_u_src # bad alignment - move t2, a2 - -can_align: - bnez t8, small_memcpy # < 8 bytes to copy - move t2, a2 - - beqz a2, out - andi t8, a1, 0x1 - -hword_align: - beqz t8, word_align - andi t8, a1, 0x2 - - EX(lb, t0, (a1), l_fixup) - subu a2, a2, 0x1 - EX(sb, t0, (a0), s_fixup) - addu a1, a1, 0x1 - addu a0, a0, 0x1 - andi t8, a1, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a2, 56 - - EX(lh, t0, (a1), l_fixup) - subu a2, a2, 0x2 - EX(sh, t0, (a0), s_fixup) - sltiu t8, a2, 56 - addu a0, a0, 0x2 - addu a1, a1, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, qword_align - andi t8, a1, 0x8 - - EX(lw, t0, 0x00(a1), l_fixup) - subu a2, a2, 0x4 - EX(sw, t0, 0x00(a0), s_fixup) - addu a1, a1, 0x4 - addu a0, a0, 0x4 - andi t8, a1, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, a1, 0x10 - - EX(lw, t0, 0x00(a1), l_fixup) - EX(lw, t1, 0x04(a1), l_fixup) - subu a2, a2, 0x8 - EX(sw, t0, 0x00(a0), s_fixup) - EX(sw, t1, 0x04(a0), s_fixup) - addu a1, a1, 0x8 - andi t8, a1, 0x10 - addu a0, a0, 0x8 - -oword_align: - beqz t8, begin_movement - srl t8, a2, 0x7 - - EX(lw, t3, 0x00(a1), l_fixup) - EX(lw, t4, 0x04(a1), l_fixup) - EX(lw, t0, 0x08(a1), l_fixup) - EX(lw, t1, 0x0c(a1), l_fixup) - EX(sw, t3, 0x00(a0), s_fixup) - EX(sw, t4, 0x04(a0), s_fixup) - EX(sw, t0, 0x08(a0), s_fixup) - EX(sw, t1, 0x0c(a0), s_fixup) - subu a2, a2, 0x10 - addu a1, a1, 0x10 - srl t8, a2, 0x7 - addu a0, a0, 0x10 - -begin_movement: - beqz t8, 0f - andi t2, a2, 0x40 - -move_128bytes: - MOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - MOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4) - MOVE_BIGCHUNK(a1, a0, 0x40, t0, t1, t3, t4) - MOVE_BIGCHUNK(a1, a0, 0x60, t0, t1, t3, t4) - subu t8, t8, 0x01 - addu a1, a1, 0x80 - bnez t8, move_128bytes - addu a0, a0, 0x80 - -0: - beqz t2, 1f - andi t2, a2, 0x20 - -move_64bytes: - MOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - MOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4) - addu a1, a1, 0x40 - addu a0, a0, 0x40 - +FEXPORT(__copy_user) + /* + * Note: dst & src may be unaligned, len may be 0 + * Temps + */ +#define rem t8 + + /* + * The "issue break"s below are very approximate. + * Issue delays for dcache fills will perturb the schedule, as will + * load queue full replay traps, etc. + * + * If len < NBYTES use byte operations. + */ + PREF( 0, 0(src) ) + PREF( 1, 0(dst) ) + sltu t2, len, NBYTES + and t1, dst, ADDRMASK + PREF( 0, 1*32(src) ) + PREF( 1, 1*32(dst) ) + bnez t2, copy_bytes_checklen + and t0, src, ADDRMASK + PREF( 0, 2*32(src) ) + PREF( 1, 2*32(dst) ) + bnez t1, dst_unaligned + nop + bnez t0, src_unaligned_dst_aligned + /* + * use delay slot for fall-through + * src and dst are aligned; need to compute rem + */ +both_aligned: + SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter + beqz t0, cleanup_both_aligned # len < 8*NBYTES + and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) + PREF( 0, 3*32(src) ) + PREF( 1, 3*32(dst) ) + .align 4 1: - beqz t2, do_end_words - andi t8, a2, 0x1c - -move_32bytes: - MOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - andi t8, a2, 0x1c - addu a1, a1, 0x20 - addu a0, a0, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - srl t8, t8, 0x2 - -end_words: - EX(lw, t0, (a1), l_fixup) - subu t8, t8, 0x1 - EX(sw, t0, (a0), s_fixup) - addu a1, a1, 0x4 - bnez t8, end_words - addu a0, a0, 0x4 - -maybe_end_cruft: - andi t2, a2, 0x3 - -small_memcpy: - beqz t2, out - move a2, t2 - -end_bytes: - EX(lb, t0, (a1), l_fixup) - subu a2, a2, 0x1 - EX(sb, t0, (a0), s_fixup) - addu a1, a1, 0x1 - bnez a2, end_bytes - addu a0, a0, 0x1 - -out: jr ra - move a2, zero - -/* ------------------------------------------------------------------------- */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 8*NBYTES +EXC( LOAD t4, UNIT(4)(src), l_exc_copy) +EXC( LOAD t7, UNIT(5)(src), l_exc_copy) +EXC( STORE t0, UNIT(0)(dst), s_exc_p8u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p7u) +EXC( LOAD t0, UNIT(6)(src), l_exc_copy) +EXC( LOAD t1, UNIT(7)(src), l_exc_copy) + ADD src, src, 8*NBYTES + ADD dst, dst, 8*NBYTES +EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) +EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) +EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u) +EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u) +EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u) +EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u) + PREF( 0, 8*32(src) ) + PREF( 1, 8*32(dst) ) + bne len, rem, 1b + nop -/* Bad, bad. At least try to align the source */ + /* + * len == rem == the number of bytes left to copy < 8*NBYTES + */ +cleanup_both_aligned: + beqz len, done + sltu t0, len, 4*NBYTES + bnez t0, less_than_4units + and rem, len, (NBYTES-1) # rem = len % NBYTES + /* + * len >= 4*NBYTES + */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 4*NBYTES + ADD src, src, 4*NBYTES +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + beqz len, done + ADD dst, dst, 4*NBYTES +less_than_4units: + /* + * rem = len % NBYTES + */ + beq rem, len, copy_bytes + nop +1: +EXC( LOAD t0, 0(src), l_exc) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne rem, len, 1b + ADD dst, dst, NBYTES + + /* + * src and dst are aligned, need to copy rem bytes (rem < NBYTES) + * A loop would do only a byte at a time with possible branch + * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE + * because can't assume read-access to dst. Instead, use + * STREST dst, which doesn't require read access to dst. + * + * This code should perform better than a simple loop on modern, + * wide-issue mips processors because the code has fewer branches and + * more instruction-level parallelism. + */ +#define bits t2 + beqz len, done + ADD t1, dst, len # t1 is just past last byte of dst + li bits, 8*NBYTES + SLL rem, len, 3 # rem = number of bits to keep +EXC( LOAD t0, 0(src), l_exc) + SUB bits, bits, rem # bits = number of bits to discard + SHIFT_DISCARD t0, t0, bits +EXC( STREST t0, -1(t1), s_exc) + jr ra + move len, zero +dst_unaligned: + /* + * dst is unaligned + * t0 = src & ADDRMASK + * t1 = dst & ADDRMASK; T1 > 0 + * len >= NBYTES + * + * Copy enough bytes to align dst + * Set match = (src and dst have same alignment) + */ +#define match rem +EXC( LDFIRST t3, FIRST(0)(src), l_exc) + ADD t2, zero, NBYTES +EXC( LDREST t3, REST(0)(src), l_exc_copy) + SUB t2, t2, t1 # t2 = number of bytes copied + xor match, t0, t1 +EXC( STFIRST t3, FIRST(0)(dst), s_exc) + beq len, t2, done + SUB len, len, t2 + ADD dst, dst, t2 + beqz match, both_aligned + ADD src, src, t2 + +src_unaligned_dst_aligned: + SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter + PREF( 0, 3*32(src) ) + beqz t0, cleanup_src_unaligned + and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES + PREF( 1, 3*32(dst) ) +1: +/* + * Avoid consecutive LD*'s to the same register since some mips + * implementations can't issue them in the same cycle. + * It's OK to load FIRST(N+1) before REST(N) because the two addresses + * are to the same unit (unless src is aligned, but it's not). + */ +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) + SUB len, len, 4*NBYTES +EXC( LDREST t0, REST(0)(src), l_exc_copy) +EXC( LDREST t1, REST(1)(src), l_exc_copy) +EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) +EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) +EXC( LDREST t2, REST(2)(src), l_exc_copy) +EXC( LDREST t3, REST(3)(src), l_exc_copy) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + ADD src, src, 4*NBYTES +#ifdef CONFIG_CPU_SB1 + nop # improves slotting +#endif +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) + bne len, rem, 1b + ADD dst, dst, 4*NBYTES + +cleanup_src_unaligned: + beqz len, done + and rem, len, NBYTES-1 # rem = len % NBYTES + beq rem, len, copy_bytes + nop +1: +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDREST t0, REST(0)(src), l_exc_copy) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne len, rem, 1b + ADD dst, dst, NBYTES -memcpy_u_src: - bnez t8, small_memcpy # < 8 bytes? - move t2, a2 - - addiu t0, a1, 7 # t0: how much to align - ori t0, 7 - xori t0, 7 - subu t0, a1 - - UEX(ulw, t1, 0(a1), l_fixup) # dword alignment - UEX(ulw, t2, 4(a1), l_fixup) - UEX(usw, t1, 0(a0), s_fixup) - UEX(usw, t2, 4(a0), s_fixup) - - addu a1, t0 # src - addu a0, t0 # dst - subu a2, t0 # len - - sltiu t8, a2, 56 - bnez t8, u_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -u_qword_align: - beqz t8, u_oword_align - andi t8, a1, 0x10 - - EX(lw, t0, 0x00(a1), l_fixup) - EX(lw, t1, 0x04(a1), l_fixup) - subu a2, a2, 0x8 - UEX(usw, t0, 0x00(a0), s_fixup) - UEX(usw, t1, 0x04(a0), s_fixup) - addu a1, a1, 0x8 - andi t8, a1, 0x10 - addu a0, a0, 0x8 - -u_oword_align: - beqz t8, u_begin_movement - srl t8, a2, 0x7 - - EX(lw, t3, 0x08(a1), l_fixup) - EX(lw, t4, 0x0c(a1), l_fixup) - EX(lw, t0, 0x00(a1), l_fixup) - EX(lw, t1, 0x04(a1), l_fixup) - UEX(usw, t3, 0x08(a0), s_fixup) - UEX(usw, t4, 0x0c(a0), s_fixup) - UEX(usw, t0, 0x00(a0), s_fixup) - UEX(usw, t1, 0x04(a0), s_fixup) - subu a2, a2, 0x10 - addu a1, a1, 0x10 - srl t8, a2, 0x7 - addu a0, a0, 0x10 - -u_begin_movement: - beqz t8, 0f - andi t2, a2, 0x40 - -u_move_128bytes: - UMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - UMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4) - UMOVE_BIGCHUNK(a1, a0, 0x40, t0, t1, t3, t4) - UMOVE_BIGCHUNK(a1, a0, 0x60, t0, t1, t3, t4) - subu t8, t8, 0x01 - addu a1, a1, 0x80 - bnez t8, u_move_128bytes - addu a0, a0, 0x80 - -0: - beqz t2, 1f - andi t2, a2, 0x20 - -u_move_64bytes: - UMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - UMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4) - addu a1, a1, 0x40 - addu a0, a0, 0x40 +copy_bytes_checklen: + beqz len, done + nop +copy_bytes: + /* 0 < len < NBYTES */ +#define COPY_BYTE(N) \ +EXC( lb t0, N(src), l_exc); \ + SUB len, len, 1; \ + beqz len, done; \ +EXC( sb t0, N(dst), s_exc_p1) + + COPY_BYTE(0) + COPY_BYTE(1) +#ifdef USE_DOUBLE + COPY_BYTE(2) + COPY_BYTE(3) + COPY_BYTE(4) + COPY_BYTE(5) +#endif +EXC( lb t0, NBYTES-2(src), l_exc) + SUB len, len, 1 + jr ra +EXC( sb t0, NBYTES-2(dst), s_exc_p1) +done: + jr ra + nop + END(memcpy) +l_exc_copy: + /* + * Copy bytes from src until faulting load address (or until a + * lb faults) + * + * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) + * may be more than a byte beyond the last address. + * Hence, the lb below may get an exception. + * + * Assumes src < THREAD_BUADDR($28) + */ + LOAD t0, TI_TASK($28) + LOAD t0, THREAD_BUADDR(t0) 1: - beqz t2, u_do_end_words - andi t8, a2, 0x1c +EXC( lb t1, 0(src), l_exc) + ADD src, src, 1 + sb t1, 0(dst) # can't fault -- we're copy_from_user + bne src, t0, 1b + ADD dst, dst, 1 +l_exc: + LOAD t0, THREAD_BUADDR($28) # t0 is just past last good address + LOAD t0, THREAD_BUADDR(t0) + nop + SUB len, AT, t0 # len number of uncopied bytes + /* + * Here's where we rely on src and dst being incremented in tandem, + * See (3) above. + * dst += (fault addr - src) to put dst at first byte to clear + */ + ADD dst, t0 # compute start address in a1 + SUB dst, src + /* + * Clear len bytes starting at dst. Can't call __bzero because it + * might modify len. An inefficient loop for these rare times... + */ + beqz len, done + SUB src, len, 1 +1: sb zero, 0(dst) + ADD dst, dst, 1 + bnez src, 1b + SUB src, src, 1 + jr ra + nop -u_move_32bytes: - UMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - andi t8, a2, 0x1c - addu a1, a1, 0x20 - addu a0, a0, 0x20 - -u_do_end_words: - beqz t8, u_maybe_end_cruft - srl t8, t8, 0x2 - -u_end_words: - EX(lw, t0, 0x00(a1), l_fixup) - subu t8, t8, 0x1 - UEX(usw, t0, 0x00(a0), s_fixup) - addu a1, a1, 0x4 - bnez t8, u_end_words - addu a0, a0, 0x4 - -u_maybe_end_cruft: - andi t2, a2, 0x3 - -u_cannot_optimize: - beqz t2, out - move a2, t2 - -u_end_bytes: - EX(lb, t0, (a1), l_fixup) - subu a2, a2, 0x1 - EX(sb, t0, (a0), s_fixup) - addu a1, a1, 0x1 - bnez a2, u_end_bytes - addu a0, a0, 0x1 - jr ra - move a2, zero - END(memcpy) +#define SEXC(n) \ +s_exc_p ## n ## u: \ + jr ra; \ + ADD len, len, n*NBYTES + +SEXC(8) +SEXC(7) +SEXC(6) +SEXC(5) +SEXC(4) +SEXC(3) +SEXC(2) +SEXC(1) -/* descending order, destination aligned */ -#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - sw t0, (offset + 0x10)(dst); \ - sw t1, (offset + 0x14)(dst); \ - sw t2, (offset + 0x18)(dst); \ - sw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - sw t0, (offset + 0x00)(dst); \ - sw t1, (offset + 0x04)(dst); \ - sw t2, (offset + 0x08)(dst); \ - sw t3, (offset + 0x0c)(dst) - -/* descending order, destination ununaligned */ -#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - usw t0, (offset + 0x10)(dst); \ - usw t1, (offset + 0x14)(dst); \ - usw t2, (offset + 0x18)(dst); \ - usw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - usw t0, (offset + 0x00)(dst); \ - usw t1, (offset + 0x04)(dst); \ - usw t2, (offset + 0x08)(dst); \ - usw t3, (offset + 0x0c)(dst) +s_exc_p1: + jr ra + ADD len, len, 1 +s_exc: + jr ra + nop .align 5 LEAF(memmove) - addu t0, a0, a2 + ADD t0, a0, a2 + ADD t1, a1, a2 sltu t0, a1, t0 # dst + len <= src -> memcpy - addu t1, a1, a2 sltu t1, a0, t1 # dst >= src + len -> memcpy and t0, t1 beqz t0, __memcpy @@ -412,159 +473,21 @@ beqz a2, r_out END(memmove) + /* fall through to __rmemcpy */ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ - sltu t0, a1, a0 + sltu t0, a1, a0 beqz t0, r_end_bytes_up # src >= dst nop - addu a0, a2 # dst = dst + len - addu a1, a2 # src = src + len - -#if 0 /* Horror fix */ - xor t0, a0, a1 - andi t0, t0, 0x3 - move t7, a0 - beqz t0, r_can_align - sltiu t8, a2, 0x8 - - b r_memcpy_u_src # bad alignment - move t2, a2 - -r_can_align: - bnez t8, r_small_memcpy # < 8 bytes to copy - move t2, a2 - - beqz a2, r_out - andi t8, a1, 0x1 - -r_hword_align: - beqz t8, r_word_align - andi t8, a1, 0x2 - - lb t0, -1(a1) - subu a2, a2, 0x1 - sb t0, -1(a0) - subu a1, a1, 0x1 - subu a0, a0, 0x1 - andi t8, a1, 0x2 - -r_word_align: - beqz t8, r_dword_align - sltiu t8, a2, 56 - - lh t0, -2(a1) - subu a2, a2, 0x2 - sh t0, -2(a0) - sltiu t8, a2, 56 - subu a0, a0, 0x2 - subu a1, a1, 0x2 - -r_dword_align: - bnez t8, r_do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, r_qword_align - andi t8, a1, 0x8 - - lw t0, -4(a1) - subu a2, a2, 0x4 - sw t0, -4(a0) - subu a1, a1, 0x4 - subu a0, a0, 0x4 - andi t8, a1, 0x8 - -r_qword_align: - beqz t8, r_oword_align - andi t8, a1, 0x10 - - subu a1, a1, 0x8 - lw t0, 0x04(a1) - lw t1, 0x00(a1) - subu a0, a0, 0x8 - sw t0, 0x04(a0) - sw t1, 0x00(a0) - subu a2, a2, 0x8 - - andi t8, a1, 0x10 - -r_oword_align: - beqz t8, r_begin_movement - srl t8, a2, 0x7 - - subu a1, a1, 0x10 - lw t3, 0x08(a1) # assumes subblock ordering - lw t4, 0x0c(a1) - lw t0, 0x00(a1) - lw t1, 0x04(a1) - subu a0, a0, 0x10 - sw t3, 0x08(a0) - sw t4, 0x0c(a0) - sw t0, 0x00(a0) - sw t1, 0x04(a0) - subu a2, a2, 0x10 - srl t8, a2, 0x7 - -r_begin_movement: - beqz t8, 0f - andi t2, a2, 0x40 - -r_move_128bytes: - RMOVE_BIGCHUNK(a1, a0, -0x80, t0, t1, t3, t4) - RMOVE_BIGCHUNK(a1, a0, -0x60, t0, t1, t3, t4) - RMOVE_BIGCHUNK(a1, a0, -0x40, t0, t1, t3, t4) - RMOVE_BIGCHUNK(a1, a0, -0x20, t0, t1, t3, t4) - subu t8, t8, 0x01 - subu a1, a1, 0x80 - bnez t8, r_move_128bytes - subu a0, a0, 0x80 - -0: - beqz t2, 1f - andi t2, a2, 0x20 - -r_move_64bytes: - subu a1, a1, 0x40 - subu a0, a0, 0x40 - RMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4) - RMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - -1: - beqz t2, r_do_end_words - andi t8, a2, 0x1c - -r_move_32bytes: - subu a1, a1, 0x20 - subu a0, a0, 0x20 - RMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - andi t8, a2, 0x1c - -r_do_end_words: - beqz t8, r_maybe_end_cruft - srl t8, t8, 0x2 - -r_end_words: - lw t0, -4(a1) - subu t8, t8, 0x1 - sw t0, -4(a0) - subu a1, a1, 0x4 - bnez t8, r_end_words - subu a0, a0, 0x4 - -r_maybe_end_cruft: - andi t2, a2, 0x3 - -r_small_memcpy: - beqz t2, r_out - move a2, t2 -#endif /* Horror fix */ + ADD a0, a2 # dst = dst + len + ADD a1, a2 # src = src + len r_end_bytes: lb t0, -1(a1) - subu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, -1(a0) - subu a1, a1, 0x1 + SUB a1, a1, 0x1 bnez a2, r_end_bytes - subu a0, a0, 0x1 + SUB a0, a0, 0x1 r_out: jr ra @@ -572,148 +495,12 @@ r_end_bytes_up: lb t0, (a1) - subu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, (a0) - addu a1, a1, 0x1 + ADD a1, a1, 0x1 bnez a2, r_end_bytes_up - addu a0, a0, 0x1 + ADD a0, a0, 0x1 jr ra move a2, zero - -#if 0 /* Horror fix */ -/* ------------------------------------------------------------------------- */ - -/* Bad, bad. At least try to align the source */ - -r_memcpy_u_src: - bnez t8, r_small_memcpy # < 8 bytes? - move t2, a2 - - andi t0, a1, 7 # t0: how much to align - - ulw t1, -8(a1) # dword alignment - ulw t2, -4(a1) - usw t1, -8(a0) - usw t2, -4(a0) - - subu a1, t0 # src - subu a0, t0 # dst - subu a2, t0 # len - - sltiu t8, a2, 56 - bnez t8, ru_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -ru_qword_align: - beqz t8, ru_oword_align - andi t8, a1, 0x10 - - subu a1, a1, 0x8 - lw t0, 0x00(a1) - lw t1, 0x04(a1) - subu a0, a0, 0x8 - usw t0, 0x00(a0) - usw t1, 0x04(a0) - subu a2, a2, 0x8 - - andi t8, a1, 0x10 - -ru_oword_align: - beqz t8, ru_begin_movement - srl t8, a2, 0x7 - - subu a1, a1, 0x10 - lw t3, 0x08(a1) # assumes subblock ordering - lw t4, 0x0c(a1) - lw t0, 0x00(a1) - lw t1, 0x04(a1) - subu a0, a0, 0x10 - usw t3, 0x08(a0) - usw t4, 0x0c(a0) - usw t0, 0x00(a0) - usw t1, 0x04(a0) - subu a2, a2, 0x10 - - srl t8, a2, 0x7 - -ru_begin_movement: - beqz t8, 0f - andi t2, a2, 0x40 - -ru_move_128bytes: - RUMOVE_BIGCHUNK(a1, a0, -0x80, t0, t1, t3, t4) - RUMOVE_BIGCHUNK(a1, a0, -0x60, t0, t1, t3, t4) - RUMOVE_BIGCHUNK(a1, a0, -0x40, t0, t1, t3, t4) - RUMOVE_BIGCHUNK(a1, a0, -0x20, t0, t1, t3, t4) - subu t8, t8, 0x01 - subu a1, a1, 0x80 - bnez t8, ru_move_128bytes - subu a0, a0, 0x80 - -0: - beqz t2, 1f - andi t2, a2, 0x20 - -ru_move_64bytes: - subu a1, a1, 0x40 - subu a0, a0, 0x40 - RUMOVE_BIGCHUNK(a1, a0, 0x20, t0, t1, t3, t4) - RUMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - -1: - beqz t2, ru_do_end_words - andi t8, a2, 0x1c - -ru_move_32bytes: - subu a1, a1, 0x20 - subu a0, a0, 0x20 - RUMOVE_BIGCHUNK(a1, a0, 0x00, t0, t1, t3, t4) - andi t8, a2, 0x1c - -ru_do_end_words: - beqz t8, ru_maybe_end_cruft - srl t8, t8, 0x2 - -ru_end_words: - lw t0, -4(a1) - usw t0, -4(a0) - subu t8, t8, 0x1 - subu a1, a1, 0x4 - bnez t8, ru_end_words - subu a0, a0, 0x4 - -ru_maybe_end_cruft: - andi t2, a2, 0x3 - -ru_cannot_optimize: - beqz t2, r_out - move a2, t2 - -ru_end_bytes: - lb t0, -1(a1) - subu a2, a2, 0x1 - sb t0, -1(a0) - subu a1, a1, 0x1 - bnez a2, ru_end_bytes - subu a0, a0, 0x1 - - jr ra - move a2, zero -#endif /* Horror fix */ END(__rmemcpy) - -l_fixup: # clear the rest of the buffer - lw t0, THREAD_BUADDR($28) - nop - subu a2, AT, t0 # a2 bytes to go - addu a0, t0 # compute start address in a1 - subu a0, a1 - j __bzero - move a1, zero - -s_fixup: - jr ra - nop diff -Nru a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S --- a/arch/mips/lib/memset.S Fri Jun 27 14:20:06 2003 +++ b/arch/mips/lib/memset.S Fri Jun 27 14:20:06 2003 @@ -54,7 +54,6 @@ 1: EXPORT(__bzero) - .type __bzero, @function sltiu t0, a2, 4 /* very small region? */ bnez t0, small_memset andi t0, a0, 3 /* aligned? */ @@ -84,13 +83,17 @@ .set noreorder memset_partial: - la t1, 2f /* where to start */ + PTR_LA t1, 2f /* where to start */ subu t1, t0 jr t1 addu a0, t0 /* dest ptr */ + .set push + .set noreorder + .set nomacro F_FILL64(a0, -64, a1, partial_fixup) /* ... but first do wrds ... */ -2: andi a2, 3 /* 0 <= n <= 3 to go */ +2: .set pop + andi a2, 3 /* 0 <= n <= 3 to go */ beqz a2, 1f addu a0, a2 /* What's left */ @@ -120,14 +123,16 @@ nop fwd_fixup: - lw t0, THREAD_BUADDR($28) + lw t0, TI_TASK($28) + lw t0, THREAD_BUADDR(t0) andi a2, 0x3f addu a2, t1 jr ra subu a2, t0 partial_fixup: - lw t0, THREAD_BUADDR($28) + lw t0, TI_TASK($28) + lw t0, THREAD_BUADDR(t0) andi a2, 3 addu a2, t1 jr ra diff -Nru a/arch/mips/lib/promlib.c b/arch/mips/lib/promlib.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/lib/promlib.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,24 @@ +#include <stdarg.h> +#include <linux/kernel.h> + +extern void prom_putchar(char); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff -Nru a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c --- a/arch/mips/lib/r3k_dump_tlb.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/lib/r3k_dump_tlb.c Fri Jun 27 14:19:53 2003 @@ -12,11 +12,12 @@ #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/cpu.h> #include <asm/mipsregs.h> #include <asm/page.h> #include <asm/pgtable.h> -#define mips_tlb_entries 64 +extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */ void dump_tlb(int first, int last) @@ -25,18 +26,18 @@ unsigned int asid; unsigned long entryhi, entrylo0; - asid = get_entryhi() & 0xfc0; + asid = read_c0_entryhi() & 0xfc0; for(i=first;i<=last;i++) { - write_32bit_cp0_register(CP0_INDEX, i<<8); + write_c0_index(i<<8); __asm__ __volatile__( ".set\tnoreorder\n\t" "tlbr\n\t" "nop\n\t" ".set\treorder"); - entryhi = read_32bit_cp0_register(CP0_ENTRYHI); - entrylo0 = read_32bit_cp0_register(CP0_ENTRYLO0); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); /* Unused entries have a virtual address of KSEG0. */ if ((entryhi & 0xffffe000) != 0x80000000 @@ -59,22 +60,22 @@ } printk("\n"); - set_entryhi(asid); + write_c0_entryhi(asid); } void dump_tlb_all(void) { - dump_tlb(0, mips_tlb_entries - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } void dump_tlb_wired(void) { - int wired = 7; + int wired = r3k_have_wired_reg ? read_c0_wired() : 8; printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, wired - 1); } void @@ -84,11 +85,11 @@ int index; local_irq_save(flags); - oldpid = get_entryhi() & 0xff; - set_entryhi((addr & PAGE_MASK) | oldpid); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi((addr & PAGE_MASK) | oldpid); tlb_probe(); - index = get_index(); - set_entryhi(oldpid); + index = read_c0_index(); + write_c0_entryhi(oldpid); local_irq_restore(flags); if (index < 0) { @@ -103,7 +104,8 @@ void dump_tlb_nonwired(void) { - dump_tlb(8, mips_tlb_entries - 1); + int wired = r3k_have_wired_reg ? read_c0_wired() : 8; + dump_tlb(wired, current_cpu_data.tlbsize - 1); } void diff -Nru a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S --- a/arch/mips/lib/strlen_user.S Fri Jun 27 14:20:04 2003 +++ b/arch/mips/lib/strlen_user.S Fri Jun 27 14:20:04 2003 @@ -1,5 +1,4 @@ -/* $Id: strlen_user.S,v 1.3 1999/08/21 22:19:11 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -24,22 +23,18 @@ * Return 0 for error */ LEAF(__strlen_user_asm) - lw v0, THREAD_CURDS($28) # pointer ok? + lw v0, TI_ADDR_LIMIT($28) # pointer ok? and v0, a0 bltz v0, fault -EXPORT(__strlen_user_nocheck_asm) +FEXPORT(__strlen_user_nocheck_asm) move v0, a0 1: EX(lb, t0, (v0), fault) addiu v0, 1 bnez t0, 1b subu v0, a0 jr ra - END(__strlen_user_nocheck_asm) - - .section __ex_table,"a" - PTR 1b, fault - .previous + END(__strlen_user_asm) fault: move v0, zero jr ra diff -Nru a/arch/mips/lib/strncpy_user.S b/arch/mips/lib/strncpy_user.S --- a/arch/mips/lib/strncpy_user.S Fri Jun 27 14:19:59 2003 +++ b/arch/mips/lib/strncpy_user.S Fri Jun 27 14:19:59 2003 @@ -1,5 +1,4 @@ -/* $Id: strncpy_user.S,v 1.3 1999/08/21 22:19:11 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -29,7 +28,7 @@ */ LEAF(__strncpy_from_user_asm) - lw v0, THREAD_CURDS($28) # pointer ok? + lw v0, TI_ADDR_LIMIT($28) # pointer ok? and v0, a1 bltz v0, fault diff -Nru a/arch/mips/lib/strnlen_user.S b/arch/mips/lib/strnlen_user.S --- a/arch/mips/lib/strnlen_user.S Fri Jun 27 14:20:01 2003 +++ b/arch/mips/lib/strnlen_user.S Fri Jun 27 14:20:01 2003 @@ -1,5 +1,4 @@ -/* $Id: strnlen_user.S,v 1.2 1999/11/19 20:35:21 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -28,11 +27,11 @@ * bytes. There's nothing secret there ... */ LEAF(__strnlen_user_asm) - lw v0, THREAD_CURDS($28) # pointer ok? + lw v0, TI_ADDR_LIMIT($28) # pointer ok? and v0, a0 bltz v0, fault -EXPORT(__strnlen_user_nocheck_asm) +FEXPORT(__strnlen_user_nocheck_asm) .type __strnlen_user_nocheck_asm,@function move v0, a0 addu a1, a0 # stop pointer @@ -45,10 +44,6 @@ 1: subu v0, a0 jr ra END(__strnlen_user_asm) - - .section __ex_table,"a" - PTR 1b, fault - .previous fault: move v0, zero jr ra diff -Nru a/arch/mips/lib/tinycon.c b/arch/mips/lib/tinycon.c --- a/arch/mips/lib/tinycon.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/lib/tinycon.c Fri Jun 27 14:19:57 2003 @@ -38,7 +38,7 @@ cursor_y = 0; vram_addr = (unsigned short *)0xb00b8000; - + console_needs_init = 0; } @@ -87,7 +87,7 @@ *(caddr++) = *(caddr + size_x); /* blank last line */ - + caddr = vram_addr + (size_x * (size_y-1)); for(i=0; i<size_x; i++) *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' '; diff -Nru a/arch/mips/lib/watch.S b/arch/mips/lib/watch.S --- a/arch/mips/lib/watch.S Fri Jun 27 14:19:54 2003 +++ b/arch/mips/lib/watch.S Fri Jun 27 14:19:54 2003 @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * 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. diff -Nru a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile --- a/arch/mips/math-emu/Makefile Fri Jun 27 14:19:57 2003 +++ b/arch/mips/math-emu/Makefile Fri Jun 27 14:19:57 2003 @@ -8,4 +8,4 @@ dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \ sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \ sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ - dp_sqrt.o sp_sqrt.o kernel_linkage.o + dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o diff -Nru a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c --- a/arch/mips/math-emu/cp1emu.c Fri Jun 27 14:20:03 2003 +++ b/arch/mips/math-emu/cp1emu.c Fri Jun 27 14:20:03 2003 @@ -1,6 +1,6 @@ /* * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator - * + * * MIPS floating point support * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. * http://www.algor.co.uk @@ -23,37 +23,32 @@ * * A complete emulator for MIPS coprocessor 1 instructions. This is * required for #float(switch) or #float(trap), where it catches all - * COP1 instructions via the "CoProcessor Unusable" exception. + * COP1 instructions via the "CoProcessor Unusable" exception. * * More surprisingly it is also required for #float(ieee), to help out * the hardware fpu at the boundaries of the IEEE-754 representation * (denormalised values, infinities, underflow, etc). It is made * quite nasty because emulation of some non-COP1 instructions is * required, e.g. in branch delay slots. - * - * Note if you know that you won't have an fpu, then you'll get much + * + * Note if you know that you won't have an fpu, then you'll get much * better performance by compiling with -msoft-float! */ -#include <linux/mm.h> -#include <linux/signal.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> +#include <linux/sched.h> -#include <asm/asm.h> -#include <asm/branch.h> +#include <asm/inst.h> #include <asm/bootinfo.h> -#include <asm/byteorder.h> #include <asm/cpu.h> -#include <asm/inst.h> -#include <asm/uaccess.h> #include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/signal.h> #include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/pgtable.h> - #include <asm/fpu_emulator.h> +#include <asm/uaccess.h> +#include <asm/branch.h> #include "ieee754.h" +#include "dsemul.h" /* Strap kernel emulator for full MIPS IV emulation */ @@ -62,20 +57,14 @@ #endif #define __mips 4 -typedef void *vaddr_t; - -/* Function which emulates the instruction in a branch delay slot. */ - -static int mips_dsemul(struct pt_regs *, mips_instruction, vaddr_t); - /* Function which emulates a floating point instruction. */ static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *, - mips_instruction); + mips_instruction); #if __mips >= 4 && __mips != 32 static int fpux_emu(struct pt_regs *, - struct mips_fpu_soft_struct *, mips_instruction); + struct mips_fpu_soft_struct *, mips_instruction); #endif /* Further private data for which no space exists in mips_fpu_soft_struct */ @@ -107,8 +96,7 @@ #endif - -/* +/* * Redundant with logic already in kernel/branch.c, * embedded in compute_return_epc. At some point, * a single subroutine should be used across both @@ -164,67 +152,45 @@ return 0; } -#define REG_TO_VA (vaddr_t) -#define VA_TO_REG (unsigned long) - -static unsigned long mips_get_word(struct pt_regs *xcp, void *va, int *perr) -{ - unsigned long temp; - - if (!user_mode(xcp)) { - *perr = 0; - return (*(unsigned long *) va); - } - - *perr = (int) get_user(temp, (unsigned long *) va); - return temp; -} - -static unsigned long long -mips_get_dword(struct pt_regs *xcp, void *va, int *perr) -{ - unsigned long long temp; - - if (!user_mode(xcp)) { - *perr = 0; - return (*(unsigned long long *) va); - } - - *perr = (int) get_user(temp, (unsigned long long *) va); - return temp; -} - -static int mips_put_word(struct pt_regs *xcp, void *va, unsigned long val) -{ - if (!user_mode(xcp)) { - *(unsigned long *) va = val; - return 0; - } - - return put_user(val, (unsigned long *) va); -} - -static int mips_put_dword(struct pt_regs *xcp, void *va, long long val) -{ - if (!user_mode(xcp)) { - *(unsigned long long *) va = val; - return 0; - } - - return put_user(val, (unsigned long long *) va); -} - - /* * In the Linux kernel, we support selection of FPR format on the * basis of the Status.FR bit. This does imply that, if a full 32 * FPRs are desired, there needs to be a flip-flop that can be written - * to one at that bit position. In any case, normal MIPS ABI uses + * to one at that bit position. In any case, O32 MIPS ABI uses * only the even FPRs (Status.FR = 0). */ #define CP0_STATUS_FR_SUPPORT +#ifdef CP0_STATUS_FR_SUPPORT +#define FR_BIT ST0_FR +#else +#define FR_BIT 0 +#endif + +#define SIFROMREG(si,x) ((si) = \ + (xcp->cp0_status & FR_BIT) || !(x & 1) ? \ + (int)ctx->regs[x] : \ + (int)(ctx->regs[x & ~1] >> 32 )) +#define SITOREG(si,x) (ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \ + (xcp->cp0_status & FR_BIT) || !(x & 1) ? \ + ctx->regs[x & ~1] >> 32 << 32 | (u32)(si) : \ + ctx->regs[x & ~1] << 32 >> 32 | (u64)(si) << 32) + +#define DIFROMREG(di,x) ((di) = \ + ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)]) +#define DITOREG(di,x) (ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] \ + = (di)) +#define DIFROMREG(di,x) ((di) = \ + ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)]) +#define DITOREG(di,x) (ctx->regs[x & ~((xcp->cp0_status & FR_BIT) == 0)] \ + = (di)) + +#define SPFROMREG(sp,x) SIFROMREG((sp).bits,x) +#define SPTOREG(sp,x) SITOREG((sp).bits,x) +#define DPFROMREG(dp,x) DIFROMREG((dp).bits,x) +#define DPTOREG(dp,x) DITOREG((dp).bits,x) + /* * Emulate the single floating point instruction pointed at by EPC. * Two instructions if the instruction is in a branch delay slot. @@ -233,13 +199,10 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx) { mips_instruction ir; - vaddr_t emulpc; - vaddr_t contpc; + vaddr_t emulpc, contpc; unsigned int cond; - int err = 0; - ir = mips_get_word(xcp, REG_TO_VA xcp->cp0_epc, &err); - if (err) { + if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -252,7 +215,7 @@ /* * The instruction to be emulated is in a branch delay slot * which means that we have to emulate the branch instruction - * BEFORE we do the cop1 instruction. + * BEFORE we do the cop1 instruction. * * This branch could be a COP1 branch, but in that case we * would have had a trap for that instruction, and would not @@ -266,363 +229,201 @@ if (__compute_return_epc(xcp)) { #ifdef CP1DBG printk("failed to emulate branch at %p\n", - REG_TO_VA(xcp->cp0_epc)); + REG_TO_VA(xcp->cp0_epc)); #endif - return SIGILL;; + return SIGILL; } - ir = mips_get_word(xcp, emulpc, &err); - if (err) { + if (get_user(ir, (mips_instruction *) emulpc)) { fpuemuprivate.stats.errors++; return SIGBUS; } + /* __computer_return_epc() will have updated cp0_epc */ contpc = REG_TO_VA xcp->cp0_epc; - } else { + /* In order not to confuse ptrace() et al, tweak context */ + xcp->cp0_epc = VA_TO_REG emulpc - 4; + } + else { emulpc = REG_TO_VA xcp->cp0_epc; - contpc = REG_TO_VA xcp->cp0_epc + 4; + contpc = REG_TO_VA(xcp->cp0_epc + 4); } -emul: + emul: fpuemuprivate.stats.emulated++; switch (MIPSInst_OPCODE(ir)) { -#ifdef CP0_STATUS_FR_SUPPORT - /* R4000+ 64-bit fpu registers */ #ifndef SINGLE_ONLY_FPU - case ldc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - int ft = MIPSInst_RT(ir); - if (!(xcp->cp0_status & ST0_FR)) - ft &= ~1; - ctx->regs[ft] = mips_get_dword(xcp, va, &err); - fpuemuprivate.stats.loads++; - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } + case ldc1_op:{ + u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] + + MIPSInst_SIMM(ir)); + u64 val; + + fpuemuprivate.stats.loads++; + if (get_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; } + DITOREG(val, MIPSInst_RT(ir)); break; + } - case sdc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - int ft = MIPSInst_RT(ir); - if (!(xcp->cp0_status & ST0_FR)) - ft &= ~1; - fpuemuprivate.stats.stores++; - if (mips_put_dword(xcp, va, ctx->regs[ft])) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } + case sdc1_op:{ + u64 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] + + MIPSInst_SIMM(ir)); + u64 val; + + fpuemuprivate.stats.stores++; + DIFROMREG(val, MIPSInst_RT(ir)); + if (put_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; } break; + } #endif - case lwc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - fpureg_t val; - int ft = MIPSInst_RT(ir); - fpuemuprivate.stats.loads++; - val = mips_get_word(xcp, va, &err); - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - if (xcp->cp0_status & ST0_FR) { - /* load whole register */ - ctx->regs[ft] = val; - } else if (ft & 1) { - /* load to m.s. 32 bits */ -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - ctx->regs[(ft & ~1)] &= 0xffffffff; - ctx->regs[(ft & ~1)] |= val << 32; -#endif - } else { - /* load to l.s. 32 bits */ - ctx->regs[ft] &= ~0xffffffffLL; - ctx->regs[ft] |= val; - } - } - break; + case lwc1_op:{ + u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] + + MIPSInst_SIMM(ir)); + u32 val; - case swc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - unsigned int val; - int ft = MIPSInst_RT(ir); - fpuemuprivate.stats.stores++; - if (xcp->cp0_status & ST0_FR) { - /* store whole register */ - val = ctx->regs[ft]; - } else if (ft & 1) { -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - /* store from m.s. 32 bits */ - val = ctx->regs[(ft & ~1)] >> 32; -#endif - } else { - /* store from l.s. 32 bits */ - val = ctx->regs[ft]; - } - if (mips_put_word(xcp, va, val)) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - } - break; -#else /* old 32-bit fpu registers */ - case lwc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - ctx->regs[MIPSInst_RT(ir)] = - mips_get_word(xcp, va, &err); - fpuemuprivate.stats.loads++; - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } + fpuemuprivate.stats.loads++; + if (get_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; } - break; - - case swc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - fpuemuprivate.stats.stores++; - if (mips_put_word - (xcp, va, ctx->regs[MIPSInst_RT(ir)])) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } +#ifdef SINGLE_ONLY_FPU + if (MIPSInst_RT(ir) & 1) { + /* illegal register in single-float mode */ + return SIGILL; } - break; - case ldc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - unsigned int rt = MIPSInst_RT(ir) & ~1; - int errs = 0; - fpuemuprivate.stats.loads++; -#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__) - ctx->regs[rt + 1] = - mips_get_word(xcp, va + 0, &err); - errs += err; - ctx->regs[rt + 0] = - mips_get_word(xcp, va + 4, &err); - errs += err; -#else - ctx->regs[rt + 0] = - mips_get_word(xcp, va + 0, &err); - errs += err; - ctx->regs[rt + 1] = - mips_get_word(xcp, va + 4, &err); - errs += err; #endif - if (err) - return SIGBUS; - } + SITOREG(val, MIPSInst_RT(ir)); break; + } - case sdc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - unsigned int rt = MIPSInst_RT(ir) & ~1; - fpuemuprivate.stats.stores++; -#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__) - if (mips_put_word(xcp, va + 0, ctx->regs[rt + 1])) - return SIGBUS; - if (mips_put_word(xcp, va + 4, ctx->regs[rt + 0])) - return SIGBUS; -#else - if (mips_put_word(xcp, va + 0, ctx->regs[rt + 0])) - return SIGBUS; - if (mips_put_word(xcp, va + 4, ctx->regs[rt + 1])) - return SIGBUS; + case swc1_op:{ + u32 *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)] + + MIPSInst_SIMM(ir)); + u32 val; + + fpuemuprivate.stats.stores++; +#ifdef SINGLE_ONLY_FPU + if (MIPSInst_RT(ir) & 1) { + /* illegal register in single-float mode */ + return SIGILL; + } #endif + SIFROMREG(val, MIPSInst_RT(ir)); + if (put_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; } break; -#endif + } case cop1_op: switch (MIPSInst_RS(ir)) { -#ifdef CP0_STATUS_FR_SUPPORT #if __mips64 && !defined(SINGLE_ONLY_FPU) case dmfc_op: /* copregister fs -> gpr[rt] */ if (MIPSInst_RT(ir) != 0) { - int fs = MIPSInst_RD(ir); - if (!(xcp->cp0_status & ST0_FR)) - fs &= ~1; - xcp->regs[MIPSInst_RT(ir)] = ctx->regs[fs]; + DIFROMREG(xcp->regs[MIPSInst_RT(ir)], + MIPSInst_RD(ir)); } break; - case dmtc_op: { + case dmtc_op: /* copregister fs <- rt */ - fpureg_t value; - int fs = MIPSInst_RD(ir); - if (!(xcp->cp0_status & ST0_FR)) - fs &= ~1; - value = - (MIPSInst_RT(ir) == - 0) ? 0 : xcp->regs[MIPSInst_RT(ir)]; - ctx->regs[fs] = value; + DITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); break; - } #endif case mfc_op: /* copregister rd -> gpr[rt] */ - if (MIPSInst_RT(ir) != 0) { - /* default value from l.s. 32 bits */ - int value = ctx->regs[MIPSInst_RD(ir)]; - if (MIPSInst_RD(ir) & 1) { #ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - if (!(xcp->cp0_status & ST0_FR)) { - /* move from m.s. 32 bits */ - value = - ctx-> - regs[MIPSInst_RD(ir) & - ~1] >> 32; - } -#endif - } - xcp->regs[MIPSInst_RT(ir)] = value; + if (MIPSInst_RD(ir) & 1) { + /* illegal register in single-float mode */ + return SIGILL; } - break; - - case mtc_op: - /* copregister rd <- rt */ - { - fpureg_t value; - if (MIPSInst_RT(ir) == 0) - value = 0; - else - value = - (unsigned int) xcp-> - regs[MIPSInst_RT(ir)]; - if (MIPSInst_RD(ir) & 1) { -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - if (!(xcp->cp0_status & ST0_FR)) { - /* move to m.s. 32 bits */ - ctx-> - regs[ - (MIPSInst_RD(ir) & - ~1)] &= - 0xffffffff; - ctx-> - regs[ - (MIPSInst_RD(ir) & - ~1)] |= - value << 32; - break; - } #endif - } - /* move to l.s. 32 bits */ - ctx->regs[MIPSInst_RD(ir)] &= - ~0xffffffffLL; - ctx->regs[MIPSInst_RD(ir)] |= value; - } - break; -#else - - case mfc_op: - /* copregister rd -> gpr[rt] */ if (MIPSInst_RT(ir) != 0) { - unsigned value = - ctx->regs[MIPSInst_RD(ir)]; - xcp->regs[MIPSInst_RT(ir)] = value; + SIFROMREG(xcp->regs[MIPSInst_RT(ir)], + MIPSInst_RD(ir)); } break; case mtc_op: /* copregister rd <- rt */ - { - unsigned value; - value = - (MIPSInst_RT(ir) == - 0) ? 0 : xcp->regs[MIPSInst_RT(ir)]; - ctx->regs[MIPSInst_RD(ir)] = value; +#ifdef SINGLE_ONLY_FPU + if (MIPSInst_RD(ir) & 1) { + /* illegal register in single-float mode */ + return SIGILL; } - break; #endif + SITOREG(xcp->regs[MIPSInst_RT(ir)], MIPSInst_RD(ir)); + break; - case cfc_op: + case cfc_op:{ /* cop control register rd -> gpr[rt] */ - { - unsigned value; + u32 value; - if (MIPSInst_RD(ir) == FPCREG_CSR) { - value = ctx->sr; + if (ir == CP1UNDEF) { + return do_dsemulret(xcp); + } + if (MIPSInst_RD(ir) == FPCREG_CSR) { + value = ctx->sr; #ifdef CSRTRACE - printk - ("%p gpr[%d]<-csr=%08x\n", - REG_TO_VA(xcp->cp0_epc), - MIPSInst_RT(ir), value); + printk("%p gpr[%d]<-csr=%08x\n", + REG_TO_VA(xcp->cp0_epc), + MIPSInst_RT(ir), value); #endif - } else if (MIPSInst_RD(ir) == FPCREG_RID) - value = 0; - else - value = 0; - if (MIPSInst_RT(ir)) - xcp->regs[MIPSInst_RT(ir)] = value; } + else if (MIPSInst_RD(ir) == FPCREG_RID) + value = 0; + else + value = 0; + if (MIPSInst_RT(ir)) + xcp->regs[MIPSInst_RT(ir)] = value; break; + } - case ctc_op: + case ctc_op:{ /* copregister rd <- rt */ - { - unsigned value; - - if (MIPSInst_RT(ir) == 0) - value = 0; - else - value = xcp->regs[MIPSInst_RT(ir)]; + u32 value; - /* we only have one writable control reg - */ - if (MIPSInst_RD(ir) == FPCREG_CSR) { + if (MIPSInst_RT(ir) == 0) + value = 0; + else + value = xcp->regs[MIPSInst_RT(ir)]; + + /* we only have one writable control reg + */ + if (MIPSInst_RD(ir) == FPCREG_CSR) { #ifdef CSRTRACE - printk - ("%p gpr[%d]->csr=%08x\n", - REG_TO_VA(xcp->cp0_epc), - MIPSInst_RT(ir), value); -#endif - ctx->sr = value; - /* copy new rounding mode to ieee library state! */ - ieee754_csr.rm = - ieee_rm[value & 0x3]; - } + printk("%p gpr[%d]->csr=%08x\n", + REG_TO_VA(xcp->cp0_epc), + MIPSInst_RT(ir), value); +#endif + ctx->sr = value; + /* copy new rounding mode and + flush bit to ieee library state! */ + ieee754_csr.nod = (ctx->sr & 0x1000000) != 0; + ieee754_csr.rm = ieee_rm[value & 0x3]; + } + if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) { + return SIGFPE; } break; + } - case bc_op: { + case bc_op:{ int likely = 0; if (xcp->cp0_cause & CAUSEF_BD) return SIGILL; #if __mips >= 4 - cond = ctx-> sr & fpucondbit[MIPSInst_RT(ir) >> 2]; + cond = ctx->sr & fpucondbit[MIPSInst_RT(ir) >> 2]; #else cond = ctx->sr & FPU_CSR_COND; #endif @@ -643,14 +444,16 @@ xcp->cp0_cause |= CAUSEF_BD; if (cond) { - /* branch taken: emulate dslot instruction */ + /* branch taken: emulate dslot + * instruction + */ xcp->cp0_epc += 4; - contpc = REG_TO_VA xcp->cp0_epc + - (MIPSInst_SIMM(ir) << 2); + contpc = REG_TO_VA + (xcp->cp0_epc + + (MIPSInst_SIMM(ir) << 2)); - ir = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), - &err); - if (err) { + if (get_user(ir, (mips_instruction *) + REG_TO_VA xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } @@ -677,30 +480,36 @@ } /* - * Single step the non-cp1 instruction in the - * dslot + * Single step the non-cp1 + * instruction in the dslot */ - return mips_dsemul(xcp, ir, contpc); - } else { + return mips_dsemul(xcp, ir, VA_TO_REG contpc); + } + else { /* branch not taken */ - if (likely) + if (likely) { /* - * branch likely nullifies dslot if not - * taken + * branch likely nullifies + * dslot if not taken */ xcp->cp0_epc += 4; - /* else continue & execute dslot as normal insn */ + contpc += 4; + /* + * else continue & execute + * dslot as normal insn + */ + } } break; } - default: { - int sig; - + default: if (!(MIPSInst_RS(ir) & 0x10)) return SIGILL; + { + int sig; - /* a real fpu computation instruction */ + /* a real fpu computation instruction */ if ((sig = fpu_emu(xcp, ctx, ir))) return sig; } @@ -708,13 +517,13 @@ break; #if __mips >= 4 && __mips != 32 - case cop1x_op: - { - int sig; - if ((sig = fpux_emu(xcp, ctx, ir))) - return sig; - } + case cop1x_op:{ + int sig; + + if ((sig = fpux_emu(xcp, ctx, ir))) + return sig; break; + } #endif #if __mips >= 4 @@ -722,8 +531,8 @@ if (MIPSInst_FUNC(ir) != movc_op) return SIGILL; cond = fpucondbit[MIPSInst_RT(ir) >> 2]; - if (((ctx->sr & cond) != 0) != - ((MIPSInst_RT(ir) & 1) != 0)) return 0; + if (((ctx->sr & cond) != 0) != ((MIPSInst_RT(ir) & 1) != 0)) + return 0; xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)]; break; #endif @@ -739,141 +548,20 @@ } /* - * Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when - * we have to emulate the instruction in a COP1 branch delay slot. Do - * not change cp0_epc due to the instruction - * - * According to the spec: - * 1) it shouldnt be a branch :-) - * 2) it can be a COP instruction :-( - * 3) if we are tring to run a protected memory space we must take - * special care on memory access instructions :-( - */ - -/* - * "Trampoline" return routine to catch exception following - * execution of delay-slot instruction execution. - */ - -int do_dsemulret(struct pt_regs *xcp) -{ -#ifdef DSEMUL_TRACE - printk("desemulret\n"); -#endif - /* Set EPC to return to post-branch instruction */ - xcp->cp0_epc = current->thread.dsemul_epc; - /* - * Clear the state that got us here. - */ - current->thread.dsemul_aerpc = (unsigned long) 0; - - return 0; -} - - -#define AdELOAD 0x8c000001 /* lw $0,1($0) */ - -static int -mips_dsemul(struct pt_regs *xcp, mips_instruction ir, vaddr_t cpc) -{ - mips_instruction *dsemul_insns; - mips_instruction forcetrap; - extern asmlinkage void handle_dsemulret(void); - - if (ir == 0) { /* a nop is easy */ - xcp->cp0_epc = VA_TO_REG(cpc); - return 0; - } -#ifdef DSEMUL_TRACE - printk("desemul %p %p\n", REG_TO_VA(xcp->cp0_epc), cpc); -#endif - - /* - * The strategy is to push the instruction onto the user stack - * and put a trap after it which we can catch and jump to - * the required address any alternative apart from full - * instruction emulation!!. - */ - dsemul_insns = (mips_instruction *) (xcp->regs[29] & ~3); - dsemul_insns -= 3; /* Two instructions, plus one for luck ;-) */ - - /* Verify that the stack pointer is not competely insane */ - if (verify_area(VERIFY_WRITE, dsemul_insns, - sizeof(mips_instruction) * 2)) - return SIGBUS; - - if (mips_put_word(xcp, &dsemul_insns[0], ir)) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - - /* - * Algorithmics used a system call instruction, and - * borrowed that vector. MIPS/Linux version is a bit - * more heavyweight in the interests of portability and - * multiprocessor support. We flag the thread for special - * handling in the unaligned access handler and force an - * address error excpetion. - */ - - /* If one is *really* paranoid, one tests for a bad stack pointer */ - if ((xcp->regs[29] & 0x3) == 0x3) - forcetrap = AdELOAD - 1; - else - forcetrap = AdELOAD; - - if (mips_put_word(xcp, &dsemul_insns[1], forcetrap)) { - fpuemuprivate.stats.errors++; - return (SIGBUS); - } - - /* Set thread state to catch and handle the exception */ - current->thread.dsemul_epc = (unsigned long) cpc; - current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1]; - xcp->cp0_epc = VA_TO_REG & dsemul_insns[0]; - flush_cache_sigtramp((unsigned long) dsemul_insns); - - return SIGILL; /* force out of emulation loop */ -} - -/* * Conversion table from MIPS compare ops 48-63 - * cond = ieee754dp_cmp(x,y,IEEE754_UN); + * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig); */ static const unsigned char cmptab[8] = { - 0, /* cmp_0 (sig) cmp_sf */ - IEEE754_CUN, /* cmp_un (sig) cmp_ngle */ - IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */ - IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */ - IEEE754_CLT, /* cmp_olt (sig) cmp_lt */ - IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */ - IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */ - IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */ + 0, /* cmp_0 (sig) cmp_sf */ + IEEE754_CUN, /* cmp_un (sig) cmp_ngle */ + IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */ + IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */ + IEEE754_CLT, /* cmp_olt (sig) cmp_lt */ + IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */ + IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */ + IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */ }; -#define SIFROMREG(si,x) ((si) = ctx->regs[x]) -#define SITOREG(si,x) (ctx->regs[x] = (int)(si)) - -#if __mips64 && !defined(SINGLE_ONLY_FPU) -#define DIFROMREG(di,x) ((di) = ctx->regs[x]) -#define DITOREG(di,x) (ctx->regs[x] = (di)) -#endif - -#define SPFROMREG(sp,x) ((sp).bits = ctx->regs[x]) -#define SPTOREG(sp,x) (ctx->regs[x] = (sp).bits) - -#ifdef CP0_STATUS_FR_SUPPORT -#define DPFROMREG(dp,x) ((dp).bits = \ - ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]) -#define DPTOREG(dp,x) (ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]\ - = (dp).bits) -#else -/* Beware: MIPS COP1 doubles are always little_word endian in registers */ -#define DPFROMREG(dp,x) \ - ((dp).bits = ((unsigned long long)ctx->regs[(x)+1] << 32) | ctx->regs[x]) -#define DPTOREG(dp,x) \ - (ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32) -#endif #if __mips >= 4 && __mips != 32 @@ -881,6 +569,22 @@ * Additional MIPS4 instructions */ +#define DEF3OP(name, p, f1, f2, f3) \ +static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \ + ieee754##p t) \ +{ \ + struct ieee754_csr ieee754_csr_save; \ + s = f1 (s, t); \ + ieee754_csr_save = ieee754_csr; \ + s = f2 (s, r); \ + ieee754_csr_save.cx |= ieee754_csr.cx; \ + ieee754_csr_save.sx |= ieee754_csr.sx; \ + s = f3 (s); \ + ieee754_csr.cx |= ieee754_csr_save.cx; \ + ieee754_csr.sx |= ieee754_csr_save.sx; \ + return s; \ +} + static ieee754dp fpemu_dp_recip(ieee754dp d) { return ieee754dp_div(ieee754dp_one(0), d); @@ -901,287 +605,184 @@ return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s)); } +DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add,); +DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub,); +DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg); +DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg); +DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add,); +DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub,); +DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); +DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); -static ieee754dp fpemu_dp_madd(ieee754dp r, ieee754dp s, ieee754dp t) +static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx, + mips_instruction ir) { - return ieee754dp_add(ieee754dp_mul(s, t), r); -} + unsigned rcsr = 0; /* resulting csr */ -static ieee754dp fpemu_dp_msub(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_sub(ieee754dp_mul(s, t), r); -} + fpuemuprivate.stats.cp1xops++; -static ieee754dp fpemu_dp_nmadd(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_neg(ieee754dp_add(ieee754dp_mul(s, t), r)); -} + switch (MIPSInst_FMA_FFMT(ir)) { + case s_fmt:{ /* 0 */ -static ieee754dp fpemu_dp_nmsub(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_neg(ieee754dp_sub(ieee754dp_mul(s, t), r)); -} + ieee754sp(*handler) (ieee754sp, ieee754sp, ieee754sp); + ieee754sp fd, fr, fs, ft; + u32 *va; + u32 val; + switch (MIPSInst_FUNC(ir)) { + case lwxc1_op: + va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] + + xcp->regs[MIPSInst_FT(ir)]); -static ieee754sp fpemu_sp_madd(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_add(ieee754sp_mul(s, t), r); -} + fpuemuprivate.stats.loads++; + if (get_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; + } +#ifdef SINGLE_ONLY_FPU + if (MIPSInst_FD(ir) & 1) { + /* illegal register in single-float + * mode + */ + return SIGILL; + } +#endif + SITOREG(val, MIPSInst_FD(ir)); + break; -static ieee754sp fpemu_sp_msub(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_sub(ieee754sp_mul(s, t), r); -} + case swxc1_op: + va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] + + xcp->regs[MIPSInst_FT(ir)]); -static ieee754sp fpemu_sp_nmadd(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_neg(ieee754sp_add(ieee754sp_mul(s, t), r)); -} + fpuemuprivate.stats.stores++; +#ifdef SINGLE_ONLY_FPU + if (MIPSInst_FS(ir) & 1) { + /* illegal register in single-float + * mode + */ + return SIGILL; + } +#endif -static ieee754sp fpemu_sp_nmsub(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_neg(ieee754sp_sub(ieee754sp_mul(s, t), r)); -} + SIFROMREG(val, MIPSInst_FS(ir)); + if (put_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; + } + break; -static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx, - mips_instruction ir) -{ - unsigned rcsr = 0; /* resulting csr */ + case madd_s_op: + handler = fpemu_sp_madd; + goto scoptop; + case msub_s_op: + handler = fpemu_sp_msub; + goto scoptop; + case nmadd_s_op: + handler = fpemu_sp_nmadd; + goto scoptop; + case nmsub_s_op: + handler = fpemu_sp_nmsub; + goto scoptop; - fpuemuprivate.stats.cp1xops++; + scoptop: + SPFROMREG(fr, MIPSInst_FR(ir)); + SPFROMREG(fs, MIPSInst_FS(ir)); + SPFROMREG(ft, MIPSInst_FT(ir)); + fd = (*handler) (fr, fs, ft); + SPTOREG(fd, MIPSInst_FD(ir)); - switch (MIPSInst_FMA_FFMT(ir)) { - case s_fmt: /* 0 */ - { - ieee754sp(*handler) (ieee754sp, ieee754sp, - ieee754sp); - ieee754sp fd, fr, fs, ft; - - switch (MIPSInst_FUNC(ir)) { - case lwxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - fpureg_t val; - int err = 0; - val = mips_get_word(xcp, va, &err); - if (err) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - if (xcp->cp0_status & ST0_FR) { - /* load whole register */ - ctx-> - regs[MIPSInst_FD(ir)] = - val; - } else if (MIPSInst_FD(ir) & 1) { - /* load to m.s. 32 bits */ -#if defined(SINGLE_ONLY_FPU) - /* illegal register in single-float mode */ - return SIGILL; -#else - ctx-> - regs[ - (MIPSInst_FD(ir) & - ~1)] &= - 0xffffffff; - ctx-> - regs[ - (MIPSInst_FD(ir) & - ~1)] |= - val << 32; -#endif - } else { - /* load to l.s. 32 bits */ - ctx-> - regs[MIPSInst_FD(ir)] - &= ~0xffffffffLL; - ctx-> - regs[MIPSInst_FD(ir)] - |= val; - } - } - break; + copcsr: + if (ieee754_cxtest(IEEE754_INEXACT)) + rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S; + if (ieee754_cxtest(IEEE754_UNDERFLOW)) + rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S; + if (ieee754_cxtest(IEEE754_OVERFLOW)) + rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S; + if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) + rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S; - case swxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - unsigned int val; - if (xcp->cp0_status & ST0_FR) { - /* store whole register */ - val = - ctx-> - regs[MIPSInst_FS(ir)]; - } else if (MIPSInst_FS(ir) & 1) { -#if defined(SINGLE_ONLY_FPU) - /* illegal register in single-float mode */ - return SIGILL; -#else - /* store from m.s. 32 bits */ - val = - ctx-> - regs[ - (MIPSInst_FS(ir) & - ~1)] >> 32; -#endif - } else { - /* store from l.s. 32 bits */ - val = - ctx-> - regs[MIPSInst_FS(ir)]; - } - if (mips_put_word(xcp, va, val)) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - } - break; + ctx->sr = (ctx->sr & ~FPU_CSR_ALL_X) | rcsr; + if (ieee754_csr.nod) + ctx->sr |= 0x1000000; + if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) { + /*printk ("SIGFPE: fpu csr = %08x\n", + ctx->sr); */ + return SIGFPE; + } - case madd_s_op: - handler = fpemu_sp_madd; - goto scoptop; - case msub_s_op: - handler = fpemu_sp_msub; - goto scoptop; - case nmadd_s_op: - handler = fpemu_sp_nmadd; - goto scoptop; - case nmsub_s_op: - handler = fpemu_sp_nmsub; - goto scoptop; + break; - scoptop: - SPFROMREG(fr, MIPSInst_FR(ir)); - SPFROMREG(fs, MIPSInst_FS(ir)); - SPFROMREG(ft, MIPSInst_FT(ir)); - fd = (*handler) (fr, fs, ft); - SPTOREG(fd, MIPSInst_FD(ir)); + default: + return SIGILL; + } + break; + } - copcsr: - if (ieee754_cxtest(IEEE754_INEXACT)) - rcsr |= - FPU_CSR_INE_X | FPU_CSR_INE_S; - if (ieee754_cxtest(IEEE754_UNDERFLOW)) - rcsr |= - FPU_CSR_UDF_X | FPU_CSR_UDF_S; - if (ieee754_cxtest(IEEE754_OVERFLOW)) - rcsr |= - FPU_CSR_OVF_X | FPU_CSR_OVF_S; - if (ieee754_cxtest - (IEEE754_INVALID_OPERATION)) rcsr |= - FPU_CSR_INV_X | FPU_CSR_INV_S; - - ctx->sr = - (ctx->sr & ~FPU_CSR_ALL_X) | rcsr; - if ((ctx->sr >> 5) & ctx-> - sr & FPU_CSR_ALL_E) { - /*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */ - return SIGFPE; - } +#ifndef SINGLE_ONLY_FPU + case d_fmt:{ /* 1 */ + ieee754dp(*handler) (ieee754dp, ieee754dp, ieee754dp); + ieee754dp fd, fr, fs, ft; + u64 *va; + u64 val; - break; + switch (MIPSInst_FUNC(ir)) { + case ldxc1_op: + va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] + + xcp->regs[MIPSInst_FT(ir)]); - default: - return SIGILL; + fpuemuprivate.stats.loads++; + if (get_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; } - } - break; + DITOREG(val, MIPSInst_FD(ir)); + break; -#if !defined(SINGLE_ONLY_FPU) - case d_fmt: /* 1 */ - { - ieee754dp(*handler) (ieee754dp, ieee754dp, - ieee754dp); - ieee754dp fd, fr, fs, ft; - - switch (MIPSInst_FUNC(ir)) { - case ldxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - int err = 0; - ctx->regs[MIPSInst_FD(ir)] = - mips_get_dword(xcp, va, &err); - if (err) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - } - break; + case sdxc1_op: + va = REG_TO_VA(xcp->regs[MIPSInst_FR(ir)] + + xcp->regs[MIPSInst_FT(ir)]); - case sdxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - if (mips_put_dword - (xcp, va, - ctx->regs[MIPSInst_FS(ir)])) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - } - break; + fpuemuprivate.stats.stores++; + DIFROMREG(val, MIPSInst_FS(ir)); + if (put_user(val, va)) { + fpuemuprivate.stats.errors++; + return SIGBUS; + } + break; - case madd_d_op: - handler = fpemu_dp_madd; - goto dcoptop; - case msub_d_op: - handler = fpemu_dp_msub; - goto dcoptop; - case nmadd_d_op: - handler = fpemu_dp_nmadd; - goto dcoptop; - case nmsub_d_op: - handler = fpemu_dp_nmsub; - goto dcoptop; + case madd_d_op: + handler = fpemu_dp_madd; + goto dcoptop; + case msub_d_op: + handler = fpemu_dp_msub; + goto dcoptop; + case nmadd_d_op: + handler = fpemu_dp_nmadd; + goto dcoptop; + case nmsub_d_op: + handler = fpemu_dp_nmsub; + goto dcoptop; - dcoptop: - DPFROMREG(fr, MIPSInst_FR(ir)); - DPFROMREG(fs, MIPSInst_FS(ir)); - DPFROMREG(ft, MIPSInst_FT(ir)); - fd = (*handler) (fr, fs, ft); - DPTOREG(fd, MIPSInst_FD(ir)); - goto copcsr; + dcoptop: + DPFROMREG(fr, MIPSInst_FR(ir)); + DPFROMREG(fs, MIPSInst_FS(ir)); + DPFROMREG(ft, MIPSInst_FT(ir)); + fd = (*handler) (fr, fs, ft); + DPTOREG(fd, MIPSInst_FD(ir)); + goto copcsr; - default: - return SIGILL; - } + default: + return SIGILL; } break; + } #endif case 0x7: /* 7 */ - { - if (MIPSInst_FUNC(ir) != pfetch_op) { - return SIGILL; - } - /* ignore prefx operation */ + if (MIPSInst_FUNC(ir) != pfetch_op) { + return SIGILL; } + /* ignore prefx operation */ break; default: @@ -1198,7 +799,7 @@ * Emulate a single COP1 arithmetic instruction. */ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx, - mips_instruction ir) + mips_instruction ir) { int rfmt; /* resulting format */ unsigned rcsr = 0; /* resulting csr */ @@ -1208,49 +809,52 @@ ieee754sp s; int w; #if __mips64 - long long l; + s64 l; #endif } rv; /* resulting value */ fpuemuprivate.stats.cp1ops++; switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) { - case s_fmt: { /* 0 */ - ieee754sp(*handler) (); + case s_fmt:{ /* 0 */ + union { + ieee754sp(*b) (ieee754sp, ieee754sp); + ieee754sp(*u) (ieee754sp); + } handler; switch (MIPSInst_FUNC(ir)) { /* binary ops */ case fadd_op: - handler = ieee754sp_add; + handler.b = ieee754sp_add; goto scopbop; case fsub_op: - handler = ieee754sp_sub; + handler.b = ieee754sp_sub; goto scopbop; case fmul_op: - handler = ieee754sp_mul; + handler.b = ieee754sp_mul; goto scopbop; case fdiv_op: - handler = ieee754sp_div; + handler.b = ieee754sp_div; goto scopbop; /* unary ops */ #if __mips >= 2 || __mips64 case fsqrt_op: - handler = ieee754sp_sqrt; + handler.u = ieee754sp_sqrt; goto scopuop; #endif #if __mips >= 4 && __mips != 32 case frsqrt_op: - handler = fpemu_sp_rsqrt; + handler.u = fpemu_sp_rsqrt; goto scopuop; case frecip_op: - handler = fpemu_sp_recip; + handler.u = fpemu_sp_recip; goto scopuop; #endif #if __mips >= 4 case fmovc_op: cond = fpucondbit[MIPSInst_FT(ir) >> 2]; if (((ctx->sr & cond) != 0) != - ((MIPSInst_FT(ir) & 1) != 0)) + ((MIPSInst_FT(ir) & 1) != 0)) return 0; SPFROMREG(rv.s, MIPSInst_FS(ir)); break; @@ -1266,35 +870,36 @@ break; #endif case fabs_op: - handler = ieee754sp_abs; + handler.u = ieee754sp_abs; goto scopuop; case fneg_op: - handler = ieee754sp_neg; + handler.u = ieee754sp_neg; goto scopuop; case fmov_op: /* an easy one */ SPFROMREG(rv.s, MIPSInst_FS(ir)); - break; + goto copcsr; + /* binary op on handler */ -scopbop: + scopbop: { ieee754sp fs, ft; SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(ft, MIPSInst_FT(ir)); - rv.s = (*handler) (fs, ft); + rv.s = (*handler.b) (fs, ft); goto copcsr; } -scopuop: + scopuop: { ieee754sp fs; SPFROMREG(fs, MIPSInst_FS(ir)); - rv.s = (*handler) (fs); + rv.s = (*handler.u) (fs); goto copcsr; } -copcsr: + copcsr: if (ieee754_cxtest(IEEE754_INEXACT)) rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S; if (ieee754_cxtest(IEEE754_UNDERFLOW)) @@ -1303,15 +908,14 @@ rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S; if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S; - if (ieee754_cxtest - (IEEE754_INVALID_OPERATION)) rcsr |= - FPU_CSR_INV_X | FPU_CSR_INV_S; - break; + if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) + rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S; + break; - /* unary conv ops */ + /* unary conv ops */ case fcvts_op: return SIGILL; /* not defined */ - case fcvtd_op: { + case fcvtd_op:{ #ifdef SINGLE_ONLY_FPU return SIGILL; /* not defined */ #else @@ -1323,7 +927,7 @@ goto copcsr; } #endif - case fcvtw_op: { + case fcvtw_op:{ ieee754sp fs; SPFROMREG(fs, MIPSInst_FS(ir)); @@ -1336,7 +940,7 @@ case fround_op: case ftrunc_op: case fceil_op: - case ffloor_op: { + case ffloor_op:{ unsigned int oldrm = ieee754_csr.rm; ieee754sp fs; @@ -1350,7 +954,7 @@ #endif /* __mips >= 2 */ #if __mips64 && !defined(SINGLE_ONLY_FPU) - case fcvtl_op: { + case fcvtl_op:{ ieee754sp fs; SPFROMREG(fs, MIPSInst_FS(ir)); @@ -1362,7 +966,7 @@ case froundl_op: case ftruncl_op: case fceill_op: - case ffloorl_op: { + case ffloorl_op:{ unsigned int oldrm = ieee754_csr.rm; ieee754sp fs; @@ -1382,55 +986,65 @@ SPFROMREG(fs, MIPSInst_FS(ir)); SPFROMREG(ft, MIPSInst_FT(ir)); - rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]); + rv.w = ieee754sp_cmp(fs, ft, + cmptab[cmpop & 0x7], cmpop & 0x8); rfmt = -1; - if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION)) + if ((cmpop & 0x8) && ieee754_cxtest + (IEEE754_INVALID_OPERATION)) rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; - } else { - return SIGILL; - } - break; + else + goto copcsr; + + } + else { + return SIGILL; } break; } + break; + } -#if !defined(SINGLE_ONLY_FPU) - case d_fmt: { - ieee754dp(*handler) (); +#ifndef SINGLE_ONLY_FPU + case d_fmt:{ + union { + ieee754dp(*b) (ieee754dp, ieee754dp); + ieee754dp(*u) (ieee754dp); + } handler; switch (MIPSInst_FUNC(ir)) { /* binary ops */ case fadd_op: - handler = ieee754dp_add; + handler.b = ieee754dp_add; goto dcopbop; case fsub_op: - handler = ieee754dp_sub; + handler.b = ieee754dp_sub; goto dcopbop; case fmul_op: - handler = ieee754dp_mul; + handler.b = ieee754dp_mul; goto dcopbop; case fdiv_op: - handler = ieee754dp_div; + handler.b = ieee754dp_div; goto dcopbop; /* unary ops */ #if __mips >= 2 || __mips64 case fsqrt_op: - handler = ieee754dp_sqrt; + handler.u = ieee754dp_sqrt; goto dcopuop; #endif #if __mips >= 4 && __mips != 32 case frsqrt_op: - handler = fpemu_dp_rsqrt; + handler.u = fpemu_dp_rsqrt; goto dcopuop; case frecip_op: - handler = fpemu_dp_recip; + handler.u = fpemu_dp_recip; goto dcopuop; #endif #if __mips >= 4 case fmovc_op: cond = fpucondbit[MIPSInst_FT(ir) >> 2]; - if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0)) + if (((ctx->sr & cond) != 0) != + ((MIPSInst_FT(ir) & 1) != 0)) return 0; DPFROMREG(rv.d, MIPSInst_FS(ir)); break; @@ -1446,40 +1060,38 @@ break; #endif case fabs_op: - handler = ieee754dp_abs; + handler.u = ieee754dp_abs; goto dcopuop; case fneg_op: - handler = ieee754dp_neg; + handler.u = ieee754dp_neg; goto dcopuop; case fmov_op: /* an easy one */ DPFROMREG(rv.d, MIPSInst_FS(ir)); - break; + goto copcsr; /* binary op on handler */ -dcopbop: - { + dcopbop:{ ieee754dp fs, ft; DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(ft, MIPSInst_FT(ir)); - rv.d = (*handler) (fs, ft); + rv.d = (*handler.b) (fs, ft); goto copcsr; } -dcopuop: - { + dcopuop:{ ieee754dp fs; DPFROMREG(fs, MIPSInst_FS(ir)); - rv.d = (*handler) (fs); + rv.d = (*handler.u) (fs); goto copcsr; } - /* unary conv ops */ - case fcvts_op: { + /* unary conv ops */ + case fcvts_op:{ ieee754dp fs; DPFROMREG(fs, MIPSInst_FS(ir)); @@ -1490,7 +1102,7 @@ case fcvtd_op: return SIGILL; /* not defined */ - case fcvtw_op: { + case fcvtw_op:{ ieee754dp fs; DPFROMREG(fs, MIPSInst_FS(ir)); @@ -1503,7 +1115,7 @@ case fround_op: case ftrunc_op: case fceil_op: - case ffloor_op: { + case ffloor_op:{ unsigned int oldrm = ieee754_csr.rm; ieee754dp fs; @@ -1517,7 +1129,7 @@ #endif #if __mips64 && !defined(SINGLE_ONLY_FPU) - case fcvtl_op: { + case fcvtl_op:{ ieee754dp fs; DPFROMREG(fs, MIPSInst_FS(ir)); @@ -1529,7 +1141,7 @@ case froundl_op: case ftruncl_op: case fceill_op: - case ffloorl_op: { + case ffloorl_op:{ unsigned int oldrm = ieee754_csr.rm; ieee754dp fs; @@ -1549,30 +1161,42 @@ DPFROMREG(fs, MIPSInst_FS(ir)); DPFROMREG(ft, MIPSInst_FT(ir)); - rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]); + rv.w = ieee754dp_cmp(fs, ft, + cmptab[cmpop & 0x7], cmpop & 0x8); rfmt = -1; - if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION)) + if ((cmpop & 0x8) + && + ieee754_cxtest + (IEEE754_INVALID_OPERATION)) rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; - } else { + else + goto copcsr; + + } + else { return SIGILL; } break; } break; } -#endif /* !defined(SINGLE_ONLY_FPU) */ +#endif /* ifndef SINGLE_ONLY_FPU */ + + case w_fmt:{ + ieee754sp fs; - case w_fmt: { switch (MIPSInst_FUNC(ir)) { case fcvts_op: /* convert word to single precision real */ - rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]); + SPFROMREG(fs, MIPSInst_FS(ir)); + rv.s = ieee754sp_fint(fs.bits); rfmt = s_fmt; goto copcsr; -#if !defined(SINGLE_ONLY_FPU) +#ifndef SINGLE_ONLY_FPU case fcvtd_op: /* convert word to double precision real */ - rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]); + SPFROMREG(fs, MIPSInst_FS(ir)); + rv.d = ieee754dp_fint(fs.bits); rfmt = d_fmt; goto copcsr; #endif @@ -1583,16 +1207,16 @@ } #if __mips64 && !defined(SINGLE_ONLY_FPU) - case l_fmt: { + case l_fmt:{ switch (MIPSInst_FUNC(ir)) { case fcvts_op: /* convert long to single precision real */ - rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]); + rv.s = ieee754sp_flong(ctx->regs[MIPSInst_FS(ir)]); rfmt = s_fmt; goto copcsr; case fcvtd_op: /* convert long to double precision real */ - rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]); + rv.d = ieee754dp_flong(ctx->regs[MIPSInst_FS(ir)]); rfmt = d_fmt; goto copcsr; default: @@ -1619,11 +1243,11 @@ return SIGFPE; } - /* + /* * Now we can safely write the result back to the register file. */ switch (rfmt) { - case -1: { + case -1:{ #if __mips >= 4 cond = fpucondbit[MIPSInst_FD(ir) >> 2]; #else @@ -1635,7 +1259,7 @@ ctx->sr &= ~cond; break; } -#if !defined(SINGLE_ONLY_FPU) +#ifndef SINGLE_ONLY_FPU case d_fmt: DPTOREG(rv.d, MIPSInst_FD(ir)); break; @@ -1658,38 +1282,39 @@ return 0; } - -/* - * Emulate the floating point instruction at EPC, and continue to run until we - * hit a non-fp instruction, or a backward branch. This cuts down dramatically - * on the per instruction exception overhead. - */ -int fpu_emulator_cop1Handler(struct pt_regs *xcp) +int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, + struct mips_fpu_soft_struct *ctx) { - struct mips_fpu_soft_struct *ctx = ¤t->thread.fpu.soft; - unsigned long oldepc, prevepc; - unsigned int insn; + gpreg_t oldepc, prevepc; + mips_instruction insn; int sig = 0; - int err = 0; oldepc = xcp->cp0_epc; do { - cond_resched(); - prevepc = xcp->cp0_epc; - insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err); - if (err) { + + if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } - if (insn != 0) - sig = cop1Emulate(xcp, ctx); - else + if (insn == 0) xcp->cp0_epc += 4; /* skip nops */ + else { + /* Update ieee754_csr. Only relevant if we have a + h/w FPU */ + ieee754_csr.nod = (ctx->sr & 0x1000000) != 0; + ieee754_csr.rm = ieee_rm[ctx->sr & 0x3]; + ieee754_csr.cx = (ctx->sr >> 12) & 0x1f; + sig = cop1Emulate(xcp, ctx); + } - if (mips_cpu.options & MIPS_CPU_FPU) + if (cpu_has_fpu) + break; + if (sig) break; - } while (xcp->cp0_epc > prevepc && sig == 0); + + cond_resched(); + } while (xcp->cp0_epc > prevepc); /* SIGILL indicates a non-fpu instruction */ if (sig == SIGILL && xcp->cp0_epc != oldepc) @@ -1698,80 +1323,3 @@ return sig; } - - -#ifdef NOTDEF -/* - * Patch up the hardware fpu state when an f.p. exception occurs. - */ -static int cop1Patcher(int xcptno, struct pt_regs *xcp) -{ - struct mips_fpu_soft_struct *ctx = ¤t->thread.fpu.soft; - unsigned sr; - int sig; - - /* reenable Cp1, else fpe_save() will get nested exception */ - sr = mips_bissr(ST0_CU1); - - /* get fpu registers and status, then clear pending exceptions */ - fpe_save(ctx); - fpe_setsr(ctx->sr &= ~FPU_CSR_ALL_X); - - /* get current rounding mode for IEEE library, and emulate insn */ - ieee754_csr.rm = ieee_rm[ctx->sr & 0x3]; - sig = cop1Emulate(xcp, ctx); - - /* don't return with f.p. exceptions pending */ - ctx->sr &= ~FPU_CSR_ALL_X; - fpe_restore(ctx); - - mips_setsr(sr); - return sig; -} - -void _cop1_init(int emulate) -{ - extern int _nofpu; - - if (emulate) { - /* - * Install cop1 emulator to handle "coprocessor unusable" exception - */ - xcption(XCPTCPU, cop1Handler); - fpuemuactive = 1; /* tell dbg.c that we are in charge */ - _nofpu = 0; /* tell setjmp() it "has" an fpu */ - } else { - /* - * Install cop1 emulator for floating point exceptions only, - * i.e. denormalised results, underflow, overflow etc, which - * must be emulated in s/w. - */ -#ifdef 1 - /* r4000 or above use dedicate exception */ - xcption(XCPTFPE, cop1Patcher); -#else - /* r3000 et al use interrupt */ - extern int _sbd_getfpuintr(void); - int intno = _sbd_getfpuintr(); - intrupt(intno, cop1Patcher, 0); - mips_bissr(SR_IM0 << intno); -#endif - -#if (#cpu(r4640) || #cpu(r4650)) && !defined(SINGLE_ONLY_FPU) - /* For R4640/R4650 compiled *without* the -msingle-float flag, - then we share responsibility: the h/w handles the single - precision operations, and the trap emulator handles the - double precision. We set fpuemuactive so that dbg.c first - fetches the s/w state before saving the h/w state. */ - fpuemuactive = 1; - { - int i; - /* initialise the unused d.p high order words to be NaN */ - for (i = 0; i < 32; i++) - current->thread.fpu.soft.regs[i] = - 0x7ff80bad00000000LL; - } -#endif /* (r4640 || r4650) && !fpu(single) */ - } -} -#endif diff -Nru a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c --- a/arch/mips/math-emu/dp_add.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/math-emu/dp_add.c Fri Jun 27 14:19:54 2003 @@ -38,27 +38,23 @@ CLEARCX; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "add", x, - y); + FLUSHXDP; + FLUSHYDP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "add", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "add", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -66,6 +62,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -73,7 +70,7 @@ return x; - /* Inifity handling + /* Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): diff -Nru a/arch/mips/math-emu/dp_cmp.c b/arch/mips/math-emu/dp_cmp.c --- a/arch/mips/math-emu/dp_cmp.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/math-emu/dp_cmp.c Fri Jun 27 14:20:01 2003 @@ -27,21 +27,30 @@ #include "ieee754dp.h" -int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp) +int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig) { - CLEARCX; + COMPXDP; + COMPYDP; + + EXPLODEXDP; + EXPLODEYDP; + FLUSHXDP; + FLUSHYDP; + CLEARCX; /* Even clear inexact flag here */ if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) { + if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN) + SETCX(IEEE754_INVALID_OPERATION); if (cmp & IEEE754_CUN) return 1; if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (SETCX(IEEE754_INVALID_OPERATION)) + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) return ieee754si_xcpt(0, "fcmpf", x); } return 0; } else { - long long int vx = x.bits; - long long int vy = y.bits; + s64 vx = x.bits; + s64 vy = y.bits; if (vx < 0) vx = -vx ^ DP_SIGN_BIT; diff -Nru a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c --- a/arch/mips/math-emu/dp_div.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/math-emu/dp_div.c Fri Jun 27 14:19:53 2003 @@ -32,32 +32,28 @@ COMPXDP; COMPYDP; - CLEARCX; - EXPLODEXDP; EXPLODEYDP; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "div", x, - y); + CLEARCX; + + FLUSHXDP; + FLUSHYDP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "div", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "div", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -129,9 +126,9 @@ { /* now the dirty work */ - unsigned long long rm = 0; + u64 rm = 0; int re = xe - ye; - unsigned long long bm; + u64 bm; for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) { if (xm >= ym) { diff -Nru a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c --- a/arch/mips/math-emu/dp_flong.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/math-emu/dp_flong.c Fri Jun 27 14:19:59 2003 @@ -27,7 +27,7 @@ #include "ieee754dp.h" -ieee754dp ieee754dp_flong(long long x) +ieee754dp ieee754dp_flong(s64 x) { COMPXDP; @@ -67,9 +67,9 @@ DPNORMRET1(xs, xe, xm, "dp_flong", x); } -ieee754dp ieee754dp_fulong(unsigned long long u) +ieee754dp ieee754dp_fulong(u64 u) { - if ((long long) u < 0) + if ((s64) u < 0) return ieee754dp_add(ieee754dp_1e63(), ieee754dp_flong(u & ~(1ULL << 63))); return ieee754dp_flong(u); diff -Nru a/arch/mips/math-emu/dp_frexp.c b/arch/mips/math-emu/dp_frexp.c --- a/arch/mips/math-emu/dp_frexp.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/math-emu/dp_frexp.c Fri Jun 27 14:19:54 2003 @@ -27,7 +27,7 @@ #include "ieee754dp.h" -/* close to ieeep754dp_logb +/* close to ieeep754dp_logb */ ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr) { diff -Nru a/arch/mips/math-emu/dp_fsp.c b/arch/mips/math-emu/dp_fsp.c --- a/arch/mips/math-emu/dp_fsp.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/math-emu/dp_fsp.c Fri Jun 27 14:19:53 2003 @@ -31,16 +31,20 @@ { COMPXSP; + EXPLODEXSP; + CLEARCX; - EXPLODEXSP; + FLUSHXSP; switch (xc) { - case IEEE754_CLASS_QNAN: case IEEE754_CLASS_SNAN: + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp"); + case IEEE754_CLASS_QNAN: return ieee754dp_nanxcpt(builddp(xs, DP_EMAX + 1 + DP_EBIAS, - ((unsigned long long) xm + ((u64) xm << (DP_MBITS - SP_MBITS))), "fsp", x); @@ -66,5 +70,5 @@ xm &= ~SP_HIDDEN_BIT; return builddp(xs, xe + DP_EBIAS, - (unsigned long long) xm << (DP_MBITS - SP_MBITS)); + (u64) xm << (DP_MBITS - SP_MBITS)); } diff -Nru a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c --- a/arch/mips/math-emu/dp_modf.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips/math-emu/dp_modf.c Fri Jun 27 14:19:58 2003 @@ -59,7 +59,7 @@ *ip = x; return ieee754dp_zero(xs); } - /* generate ipart mantissa by clearing bottom bits + /* generate ipart mantissa by clearing bottom bits */ *ip = builddp(xs, xe + DP_EBIAS, ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) & diff -Nru a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c --- a/arch/mips/math-emu/dp_mul.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/math-emu/dp_mul.c Fri Jun 27 14:19:56 2003 @@ -32,32 +32,28 @@ COMPXDP; COMPYDP; - CLEARCX; - EXPLODEXDP; EXPLODEYDP; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "mul", x, - y); + CLEARCX; + + FLUSHXDP; + FLUSHYDP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -114,7 +111,7 @@ { int re = xe + ye; int rs = xs ^ ys; - unsigned long long rm; + u64 rm; /* shunt to top of word */ xm <<= 64 - (DP_MBITS + 1); @@ -124,23 +121,23 @@ */ /* 32 * 32 => 64 */ -#define DPXMULT(x,y) ((unsigned long long)(x) * (unsigned long long)y) +#define DPXMULT(x,y) ((u64)(x) * (u64)y) { unsigned lxm = xm; unsigned hxm = xm >> 32; unsigned lym = ym; unsigned hym = ym >> 32; - unsigned long long lrm; - unsigned long long hrm; + u64 lrm; + u64 hrm; lrm = DPXMULT(lxm, lym); hrm = DPXMULT(hxm, hym); { - unsigned long long t = DPXMULT(lxm, hym); + u64 t = DPXMULT(lxm, hym); { - unsigned long long at = + u64 at = lrm + (t << 32); hrm += at < lrm; lrm = at; @@ -149,9 +146,9 @@ } { - unsigned long long t = DPXMULT(hxm, lym); + u64 t = DPXMULT(hxm, lym); { - unsigned long long at = + u64 at = lrm + (t << 32); hrm += at < lrm; lrm = at; @@ -164,7 +161,7 @@ /* * sticky shift down to normal rounding precision */ - if ((signed long long) rm < 0) { + if ((s64) rm < 0) { rm = (rm >> (64 - (DP_MBITS + 1 + 3))) | ((rm << (DP_MBITS + 1 + 3)) != 0); diff -Nru a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c --- a/arch/mips/math-emu/dp_simple.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/math-emu/dp_simple.c Fri Jun 27 14:20:00 2003 @@ -42,7 +42,16 @@ ieee754dp ieee754dp_neg(ieee754dp x) { + COMPXDP; + + EXPLODEXDP; CLEARCX; + FLUSHXDP; + + if (xc == IEEE754_CLASS_SNAN) { + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); + } if (ieee754dp_isnan(x)) /* but not infinity */ return ieee754dp_nanxcpt(x, "neg", x); @@ -55,7 +64,16 @@ ieee754dp ieee754dp_abs(ieee754dp x) { + COMPXDP; + + EXPLODEXDP; CLEARCX; + FLUSHXDP; + + if (xc == IEEE754_CLASS_SNAN) { + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); + } if (ieee754dp_isnan(x)) /* but not infinity */ return ieee754dp_nanxcpt(x, "abs", x); diff -Nru a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c --- a/arch/mips/math-emu/dp_sqrt.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/math-emu/dp_sqrt.c Fri Jun 27 14:20:01 2003 @@ -27,16 +27,6 @@ #include "ieee754dp.h" -static const struct ieee754dp_konst knan = { -#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__) - 0, 0, DP_EBIAS + DP_EMAX + 1, 0 -#else - 0, DP_EBIAS + DP_EMAX + 1, 0, 0 -#endif -}; - -#define nan ((ieee754dp)knan) - static const unsigned table[] = { 0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, 29598, 36145, 43202, 50740, 58733, 67158, 75992, @@ -53,29 +43,37 @@ COMPXDP; EXPLODEXDP; + CLEARCX; + FLUSHXDP; /* x == INF or NAN? */ switch (xc) { case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: /* sqrt(Nan) = Nan */ return ieee754dp_nanxcpt(x, "sqrt"); + case IEEE754_CLASS_SNAN: + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); case IEEE754_CLASS_ZERO: /* sqrt(0) = 0 */ return x; case IEEE754_CLASS_INF: - if (xs) + if (xs) { /* sqrt(-Inf) = Nan */ - return ieee754dp_nanxcpt(nan, "sqrt"); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); + } /* sqrt(+Inf) = Inf */ return x; case IEEE754_CLASS_DNORM: DPDNORMX; /* fall through */ case IEEE754_CLASS_NORM: - if (xs) + if (xs) { /* sqrt(-x) = Nan */ - return ieee754dp_nanxcpt(nan, "sqrt"); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); + } break; } @@ -101,7 +99,7 @@ yh = y.bits >> 32; yh = (yh >> 1) + 0x1ff80000; yh = yh - table[(yh >> 15) & 31]; - y.bits = ((unsigned long long) yh << 32) | (y.bits & 0xffffffff); + y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff); /* Heron's rule once with correction to improve to ~18 sig. bits */ /* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */ diff -Nru a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c --- a/arch/mips/math-emu/dp_sub.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/math-emu/dp_sub.c Fri Jun 27 14:19:59 2003 @@ -32,32 +32,28 @@ COMPXDP; COMPYDP; - CLEARCX; - EXPLODEXDP; EXPLODEYDP; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "sub", x, - y); + CLEARCX; + + FLUSHXDP; + FLUSHYDP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -72,7 +69,7 @@ return x; - /* Inifity handling + /* Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): @@ -183,7 +180,7 @@ return ieee754dp_zero(0); /* other round modes => sign = 1 */ } - /* normalize to rounding precision + /* normalize to rounding precision */ while ((xm >> (DP_MBITS + 3)) == 0) { xm <<= 1; diff -Nru a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c --- a/arch/mips/math-emu/dp_tint.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/math-emu/dp_tint.c Fri Jun 27 14:19:53 2003 @@ -35,38 +35,74 @@ CLEARCX; EXPLODEXDP; + FLUSHXDP; switch (xc) { case IEEE754_CLASS_SNAN: case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754si_xcpt(ieee754si_indef(), "fixdp", x); case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fixdp", x); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); case IEEE754_CLASS_ZERO: return 0; - case IEEE754_CLASS_DNORM: /* much to small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fixdp", x); + case IEEE754_CLASS_DNORM: case IEEE754_CLASS_NORM: break; } - if (xe >= 31) { - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fix", x); - } - if (xe < 0) { - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fix", x); + if (xe > 31) { + /* Set invalid. We will only use overflow for floating + point overflow */ + SETCX(IEEE754_INVALID_OPERATION); + return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); } /* oh gawd */ if (xe > DP_MBITS) { xm <<= xe - DP_MBITS; } else if (xe < DP_MBITS) { - /* XXX no rounding - */ - xm >>= DP_MBITS - xe; + u64 residue; + int round; + int sticky; + int odd; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } + else { + residue = xm << (64 - DP_MBITS + xe); + round = (residue >> 63) != 0; + sticky = (residue << 1) != 0; + xm >>= DP_MBITS - xe; + } + /* Note: At this point upper 32 bits of xm are guaranteed + to be zero */ + odd = (xm & 0x1) != 0x0; + switch (ieee754_csr.rm) { + case IEEE754_RN: + if (round && (sticky || odd)) + xm++; + break; + case IEEE754_RZ: + break; + case IEEE754_RU: /* toward +Infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case IEEE754_RD: /* toward -Infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + /* look for valid corner case 0x80000000 */ + if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) { + /* This can happen after rounding */ + SETCX(IEEE754_INVALID_OPERATION); + return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); + } + if (round || sticky) + SETCX(IEEE754_INEXACT); } if (xs) return -xm; diff -Nru a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c --- a/arch/mips/math-emu/dp_tlong.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/math-emu/dp_tlong.c Fri Jun 27 14:19:55 2003 @@ -27,99 +27,85 @@ #include "ieee754dp.h" -long long ieee754dp_tlong(ieee754dp x) +s64 ieee754dp_tlong(ieee754dp x) { COMPXDP; CLEARCX; EXPLODEXDP; + FLUSHXDP; switch (xc) { case IEEE754_CLASS_SNAN: case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); + SETCX(IEEE754_INVALID_OPERATION); return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); case IEEE754_CLASS_ZERO: return 0; - case IEEE754_CLASS_DNORM: /* much too small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "dp_tlong", x); + case IEEE754_CLASS_DNORM: case IEEE754_CLASS_NORM: break; } if (xe >= 63) { - SETCX(IEEE754_OVERFLOW); + /* look for valid corner case */ + if (xe == 63 && xs && xm == DP_HIDDEN_BIT) + return -0x8000000000000000LL; + /* Set invalid. We will only use overflow for floating + point overflow */ + SETCX(IEEE754_INVALID_OPERATION); return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); } - if (xe < 0) { - if (ieee754_csr.rm == IEEE754_RU) { - if (xs) { /* Negative */ - return 0x0000000000000000LL; - } else { /* Positive */ - return 0x0000000000000001LL; - } - } else if (ieee754_csr.rm == IEEE754_RD) { - if (xs) { /* Negative , return -1 */ - return 0xffffffffffffffffLL; - } else { /* Positive */ - return 0x0000000000000000LL; - } - } else { - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "dp_tlong", x); - } - } /* oh gawd */ if (xe > DP_MBITS) { xm <<= xe - DP_MBITS; } else if (xe < DP_MBITS) { - unsigned long long residue; - unsigned long long mask = 0; - int i; + u64 residue; int round; int sticky; int odd; - /* compute mask */ - for (i = 0; i < DP_MBITS - xe; i++) { - mask = mask << 1; - mask = mask | 0x1; + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; } - residue = (xm & mask) << (64 - (DP_MBITS - xe)); - round = - ((0x8000000000000000LL & residue) != - 0x0000000000000000LL); - sticky = - ((0x7fffffffffffffffLL & residue) != - 0x0000000000000000LL); - - xm >>= DP_MBITS - xe; - - odd = ((xm & 0x1) != 0x0000000000000000LL); - - /* Do the rounding */ - if (!round && sticky) { - if ((ieee754_csr.rm == IEEE754_RU && !xs) - || (ieee754_csr.rm == IEEE754_RD && xs)) { + else { + /* Shifting a u64 64 times does not work, + * so we do it in two steps. Be aware that xe + * may be -1 */ + residue = xm << (xe + 1); + residue <<= 63 - DP_MBITS; + round = (residue >> 63) != 0; + sticky = (residue << 1) != 0; + xm >>= DP_MBITS - xe; + } + odd = (xm & 0x1) != 0x0; + switch (ieee754_csr.rm) { + case IEEE754_RN: + if (round && (sticky || odd)) xm++; - } - } else if (round && !sticky) { - if ((ieee754_csr.rm == IEEE754_RU && !xs) - || (ieee754_csr.rm == IEEE754_RD && xs) - || (ieee754_csr.rm == IEEE754_RN && odd)) { + break; + case IEEE754_RZ: + break; + case IEEE754_RU: /* toward +Infinity */ + if ((round || sticky) && !xs) xm++; - } - } else if (round && sticky) { - if ((ieee754_csr.rm == IEEE754_RU && !xs) - || (ieee754_csr.rm == IEEE754_RD && xs) - || (ieee754_csr.rm == IEEE754_RN)) { + break; + case IEEE754_RD: /* toward -Infinity */ + if ((round || sticky) && xs) xm++; - } + break; + } + if ((xm >> 63) != 0) { + /* This can happen after rounding */ + SETCX(IEEE754_INVALID_OPERATION); + return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); } + if (round || sticky) + SETCX(IEEE754_INEXACT); } if (xs) return -xm; @@ -128,14 +114,14 @@ } -unsigned long long ieee754dp_tulong(ieee754dp x) +u64 ieee754dp_tulong(ieee754dp x) { ieee754dp hb = ieee754dp_1e63(); /* what if x < 0 ?? */ if (ieee754dp_lt(x, hb)) - return (unsigned long long) ieee754dp_tlong(x); + return (u64) ieee754dp_tlong(x); - return (unsigned long long) ieee754dp_tlong(ieee754dp_sub(x, hb)) | + return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) | (1ULL << 63); } diff -Nru a/arch/mips/math-emu/dsemul.c b/arch/mips/math-emu/dsemul.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/math-emu/dsemul.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,173 @@ +#include <linux/compiler.h> +#include <linux/mm.h> +#include <linux/signal.h> +#include <linux/smp.h> +#include <linux/smp_lock.h> + +#include <asm/asm.h> +#include <asm/bootinfo.h> +#include <asm/byteorder.h> +#include <asm/cpu.h> +#include <asm/inst.h> +#include <asm/processor.h> +#include <asm/uaccess.h> +#include <asm/branch.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/cacheflush.h> + +#include <asm/fpu_emulator.h> + +#include "ieee754.h" +#include "dsemul.h" + +/* Strap kernel emulator for full MIPS IV emulation */ + +#ifdef __mips +#undef __mips +#endif +#define __mips 4 + +extern struct mips_fpu_emulator_private fpuemuprivate; + + +/* + * Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when + * we have to emulate the instruction in a COP1 branch delay slot. Do + * not change cp0_epc due to the instruction + * + * According to the spec: + * 1) it shouldnt be a branch :-) + * 2) it can be a COP instruction :-( + * 3) if we are tring to run a protected memory space we must take + * special care on memory access instructions :-( + */ + +/* + * "Trampoline" return routine to catch exception following + * execution of delay-slot instruction execution. + */ + +struct emuframe { + mips_instruction emul; + mips_instruction badinst; + mips_instruction cookie; + gpreg_t epc; +}; + +int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc) +{ + extern asmlinkage void handle_dsemulret(void); + mips_instruction *dsemul_insns; + struct emuframe *fr; + int err; + + if (ir == 0) { /* a nop is easy */ + regs->cp0_epc = cpc; + regs->cp0_cause &= ~CAUSEF_BD; + return 0; + } +#ifdef DSEMUL_TRACE + printk("dsemul %lx %lx\n", regs->cp0_epc, cpc); + +#endif + + /* + * The strategy is to push the instruction onto the user stack + * and put a trap after it which we can catch and jump to + * the required address any alternative apart from full + * instruction emulation!!. + * + * Algorithmics used a system call instruction, and + * borrowed that vector. MIPS/Linux version is a bit + * more heavyweight in the interests of portability and + * multiprocessor support. For Linux we generate a + * an unaligned access and force an address error exception. + * + * For embedded systems (stand-alone) we prefer to use a + * non-existing CP1 instruction. This prevents us from emulating + * branches, but gives us a cleaner interface to the exception + * handler (single entry point). + */ + + /* Ensure that the two instructions are in the same cache line */ + dsemul_insns = (mips_instruction *) REG_TO_VA ((regs->regs[29] - sizeof(struct emuframe)) & ~0x7); + fr = (struct emuframe *) dsemul_insns; + + /* Verify that the stack pointer is not competely insane */ + if (unlikely(verify_area(VERIFY_WRITE, fr, sizeof(struct emuframe)))) + return SIGBUS; + + err = __put_user(ir, &fr->emul); + err |= __put_user((mips_instruction)BADINST, &fr->badinst); + err |= __put_user((mips_instruction)BD_COOKIE, &fr->cookie); + err |= __put_user(cpc, &fr->epc); + + if (unlikely(err)) { + fpuemuprivate.stats.errors++; + return SIGBUS; + } + + regs->cp0_epc = VA_TO_REG & fr->emul; + + flush_cache_sigtramp((unsigned long)&fr->badinst); + + return SIGILL; /* force out of emulation loop */ +} + +int do_dsemulret(struct pt_regs *xcp) +{ + struct emuframe *fr; + gpreg_t epc; + u32 insn, cookie; + int err = 0; + + fr = (struct emuframe *) (xcp->cp0_epc - sizeof(mips_instruction)); + + /* + * If we can't even access the area, something is very wrong, but we'll + * leave that to the default handling + */ + if (verify_area(VERIFY_READ, fr, sizeof(struct emuframe))) + return 0; + + /* + * Do some sanity checking on the stackframe: + * + * - Is the instruction pointed to by the EPC an BADINST? + * - Is the following memory word the BD_COOKIE? + */ + err = __get_user(insn, &fr->badinst); + err |= __get_user(cookie, &fr->cookie); + + if (unlikely(err || (insn != BADINST) || (cookie != BD_COOKIE))) { + fpuemuprivate.stats.errors++; + + return 0; + } + + /* + * At this point, we are satisfied that it's a BD emulation trap. Yes, + * a user might have deliberately put two malformed and useless + * instructions in a row in his program, in which case he's in for a + * nasty surprise - the next instruction will be treated as a + * continuation address! Alas, this seems to be the only way that we + * can handle signals, recursion, and longjmps() in the context of + * emulating the branch delay instruction. + */ + +#ifdef DSEMUL_TRACE + printk("dsemulret\n"); +#endif + if (__get_user(epc, &fr->epc)) { /* Saved EPC */ + /* This is not a good situation to be in */ + force_sig(SIGBUS, current); + + return 0; + } + + /* Set EPC to return to post-branch instruction */ + xcp->cp0_epc = epc; + + return 1; +} diff -Nru a/arch/mips/math-emu/dsemul.h b/arch/mips/math-emu/dsemul.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/math-emu/dsemul.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,23 @@ +typedef long gpreg_t; +typedef void *vaddr_t; + +#define REG_TO_VA (vaddr_t) +#define VA_TO_REG (gpreg_t) + +int mips_dsemul(struct pt_regs *regs, mips_instruction ir, gpreg_t cpc); +int do_dsemulret(struct pt_regs *xcp); + +/* Instruction which will always cause an address error */ +#define AdELOAD 0x8c000001 /* lw $0,1($0) */ +/* Instruction which will plainly cause a CP1 exception when FPU is disabled */ +#define CP1UNDEF 0x44400001 /* cfc1 $0,$0 undef */ + +/* Instruction inserted following the badinst to further tag the sequence */ +#define BD_COOKIE 0x0000bd36 /* tne $0,$0 with baggage */ + +/* Setup which instruction to use for trampoline */ +#ifdef STANDALONE_EMULATOR +#define BADINST CP1UNDEF +#else +#define BADINST AdELOAD +#endif diff -Nru a/arch/mips/math-emu/ieee754.c b/arch/mips/math-emu/ieee754.c --- a/arch/mips/math-emu/ieee754.c Fri Jun 27 14:19:52 2003 +++ b/arch/mips/math-emu/ieee754.c Fri Jun 27 14:19:52 2003 @@ -50,7 +50,7 @@ "SNaN", }; -/* the control status register +/* the control status register */ struct ieee754_csr ieee754_csr; @@ -77,7 +77,7 @@ DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */ DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */ DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */ - DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x40000, 0), /* + indef quiet Nan */ + DPSTR(0,DP_EMAX+1+DP_EBIAS,0x7FFFF,0xFFFFFFFF), /* + indef quiet Nan */ DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */ DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */ DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */ @@ -97,7 +97,7 @@ SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */ SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */ SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */ - SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x200000), /* + indef quiet Nan */ + SPSTR(0,SP_EMAX+1+SP_EBIAS,0x3FFFFF), /* + indef quiet Nan */ SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */ SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */ SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */ @@ -123,7 +123,7 @@ return ax.rv.si; } -long long ieee754di_xcpt(long long r, const char *op, ...) +s64 ieee754di_xcpt(s64 r, const char *op, ...) { struct ieee754xctx ax; diff -Nru a/arch/mips/math-emu/ieee754.h b/arch/mips/math-emu/ieee754.h --- a/arch/mips/math-emu/ieee754.h Fri Jun 27 14:19:53 2003 +++ b/arch/mips/math-emu/ieee754.h Fri Jun 27 14:19:53 2003 @@ -26,7 +26,7 @@ /************************************************************************** * Nov 7, 2000 - * Modification to allow integration with Linux kernel + * Modification to allow integration with Linux kernel * * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. @@ -36,8 +36,8 @@ /* Going from Algorithmics to Linux native environment, add this */ #include <linux/types.h> -/* - * Not very pretty, but the Linux kernel's normal va_list definition +/* + * Not very pretty, but the Linux kernel's normal va_list definition * does not allow it to be used as a structure element, as it is here. */ #ifndef _STDARG_H @@ -71,18 +71,18 @@ typedef union _ieee754dp { struct ieee754dp_konst oparts; struct { - unsigned long long mant:52; + u64 mant:52; unsigned int bexp:11; unsigned int sign:1; } parts; - unsigned long long bits; + u64 bits; double d; } ieee754dp; typedef union _ieee754sp { struct ieee754sp_konst parts; float f; - unsigned long bits; + u32 bits; } ieee754sp; #endif @@ -98,10 +98,10 @@ struct { unsigned int sign:1; unsigned int bexp:11; - unsigned long long mant:52; + u64 mant:52; } parts; double d; - unsigned long long bits; + u64 bits; } ieee754dp; struct ieee754sp_konst { @@ -113,7 +113,7 @@ typedef union _ieee754sp { struct ieee754sp_konst parts; float f; - unsigned long bits; + u32 bits; } ieee754sp; #endif @@ -138,16 +138,16 @@ ieee754sp ieee754sp_fint(int x); ieee754sp ieee754sp_funs(unsigned x); -ieee754sp ieee754sp_flong(long long x); -ieee754sp ieee754sp_fulong(unsigned long long x); +ieee754sp ieee754sp_flong(s64 x); +ieee754sp ieee754sp_fulong(u64 x); ieee754sp ieee754sp_fdp(ieee754dp x); int ieee754sp_tint(ieee754sp x); unsigned int ieee754sp_tuns(ieee754sp x); -long long ieee754sp_tlong(ieee754sp x); -unsigned long long ieee754sp_tulong(ieee754sp x); +s64 ieee754sp_tlong(ieee754sp x); +u64 ieee754sp_tulong(ieee754sp x); -int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop); +int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig); /* * basic sp math */ @@ -179,14 +179,14 @@ ieee754dp ieee754dp_neg(ieee754dp x); ieee754dp ieee754dp_scalb(ieee754dp x, int); -/* return exponent as integer in floating point format +/* return exponent as integer in floating point format */ ieee754dp ieee754dp_logb(ieee754dp x); ieee754dp ieee754dp_fint(int x); ieee754dp ieee754dp_funs(unsigned x); -ieee754dp ieee754dp_flong(long long x); -ieee754dp ieee754dp_fulong(unsigned long long x); +ieee754dp ieee754dp_flong(s64 x); +ieee754dp ieee754dp_fulong(u64 x); ieee754dp ieee754dp_fsp(ieee754sp x); ieee754dp ieee754dp_ceil(ieee754dp x); @@ -195,10 +195,10 @@ int ieee754dp_tint(ieee754dp x); unsigned int ieee754dp_tuns(ieee754dp x); -long long ieee754dp_tlong(ieee754dp x); -unsigned long long ieee754dp_tulong(ieee754dp x); +s64 ieee754dp_tlong(ieee754dp x); +u64 ieee754dp_tulong(ieee754dp x); -int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop); +int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig); /* * basic sp math */ @@ -214,7 +214,7 @@ -/* 5 types of floating point number +/* 5 types of floating point number */ #define IEEE754_CLASS_NORM 0x00 #define IEEE754_CLASS_ZERO 0x01 @@ -238,7 +238,7 @@ #define IEEE754_CGT 0x04 #define IEEE754_CUN 0x08 -/* rounding mode +/* rounding mode */ #define IEEE754_RN 0 /* round to nearest */ #define IEEE754_RZ 1 /* round toward zero */ @@ -253,65 +253,65 @@ */ static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y) { - return ieee754sp_cmp(x, y, IEEE754_CEQ); + return ieee754sp_cmp(x, y, IEEE754_CEQ, 0); } static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y) { return ieee754sp_cmp(x, y, - IEEE754_CLT | IEEE754_CGT | IEEE754_CUN); + IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0); } static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y) { - return ieee754sp_cmp(x, y, IEEE754_CLT); + return ieee754sp_cmp(x, y, IEEE754_CLT, 0); } static __inline int ieee754sp_le(ieee754sp x, ieee754sp y) { - return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ); + return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0); } static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y) { - return ieee754sp_cmp(x, y, IEEE754_CGT); + return ieee754sp_cmp(x, y, IEEE754_CGT, 0); } static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y) { - return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ); + return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0); } static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y) { - return ieee754dp_cmp(x, y, IEEE754_CEQ); + return ieee754dp_cmp(x, y, IEEE754_CEQ, 0); } static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y) { return ieee754dp_cmp(x, y, - IEEE754_CLT | IEEE754_CGT | IEEE754_CUN); + IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0); } static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y) { - return ieee754dp_cmp(x, y, IEEE754_CLT); + return ieee754dp_cmp(x, y, IEEE754_CLT, 0); } static __inline int ieee754dp_le(ieee754dp x, ieee754dp y) { - return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ); + return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0); } static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y) { - return ieee754dp_cmp(x, y, IEEE754_CGT); + return ieee754dp_cmp(x, y, IEEE754_CGT, 0); } static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y) { - return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ); + return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0); } @@ -321,11 +321,10 @@ char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af); -/* the control status register +/* the control status register */ struct ieee754_csr { unsigned pad:13; - unsigned noq:1; /* set 1 for no quiet NaN's */ unsigned nod:1; /* set 1 for no denormalised numbers */ unsigned cx:5; /* exceptions this operation */ unsigned mx:5; /* exception enable mask */ @@ -351,7 +350,7 @@ return (ieee754_csr.cx); } -/* test for current exception condition +/* test for current exception condition */ static __inline int ieee754_cxtest(unsigned n) { @@ -373,7 +372,7 @@ return (ieee754_csr.sx = 0); } -/* test for sticky exception condition +/* test for sticky exception condition */ static __inline int ieee754_sxtest(unsigned n) { @@ -451,13 +450,13 @@ #define ieee754sp_1e63() \ (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63]) -/* indefinite integer value +/* indefinite integer value */ -#define ieee754si_indef() INT_MIN -#ifdef LONG_LONG_MIN -#define ieee754di_indef() LONG_LONG_MIN +#define ieee754si_indef() INT_MAX +#ifdef LONG_LONG_MAX +#define ieee754di_indef() LONG_LONG_MAX #else -#define ieee754di_indef() (-9223372036854775807LL-1) +#define ieee754di_indef() ((s64)(~0ULL>>1)) #endif /* IEEE exception context, passed to handler */ @@ -471,7 +470,7 @@ ieee754xp xp; /* extended precision */ #endif int si; /* standard signed integer (32bits) */ - long long di; /* extended signed integer (64bits) */ + s64 di; /* extended signed integer (64bits) */ } rv; /* default result format implied by op */ va_list ap; }; diff -Nru a/arch/mips/math-emu/ieee754d.c b/arch/mips/math-emu/ieee754d.c --- a/arch/mips/math-emu/ieee754d.c Fri Jun 27 14:20:03 2003 +++ b/arch/mips/math-emu/ieee754d.c Fri Jun 27 14:20:03 2003 @@ -1,12 +1,11 @@ -/* some debug functions -*/ /* + * Some debug functions + * * MIPS floating point support + * * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. * http://www.algor.co.uk * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -20,17 +19,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - */ - -/************************************************************************** * Nov 7, 2000 - * Modified to build and operate in Linux kernel environment. + * Modified to build and operate in Linux kernel environment. * * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - *************************************************************************/ + */ +#include <linux/kernel.h> #include "ieee754.h" #define DP_EBIAS 1023 @@ -43,12 +39,12 @@ #define SP_EMAX 127 #define SP_FBITS 23 -#define DP_MBIT(x) ((unsigned long long)1 << (x)) +#define DP_MBIT(x) ((u64)1 << (x)) #define DP_HIDDEN_BIT DP_MBIT(DP_FBITS) #define DP_SIGN_BIT DP_MBIT(63) -#define SP_MBIT(x) ((unsigned long)1 << (x)) +#define SP_MBIT(x) ((u32)1 << (x)) #define SP_HIDDEN_BIT SP_MBIT(SP_FBITS) #define SP_SIGN_BIT SP_MBIT(31) diff -Nru a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c --- a/arch/mips/math-emu/ieee754dp.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/math-emu/ieee754dp.c Fri Jun 27 14:19:59 2003 @@ -42,9 +42,7 @@ int ieee754dp_issnan(ieee754dp x) { assert(ieee754dp_isnan(x)); - if (ieee754_csr.noq) - return 1; - return !(DPMANT(x) & DP_MBIT(DP_MBITS - 1)); + return ((DPMANT(x) & DP_MBIT(DP_MBITS-1)) == DP_MBIT(DP_MBITS-1)); } @@ -71,12 +69,13 @@ if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ return r; - if (!SETCX(IEEE754_INVALID_OPERATION)) { + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { /* not enabled convert to a quiet NaN */ - if (ieee754_csr.noq) + DPMANT(r) &= (~DP_MBIT(DP_MBITS-1)); + if (ieee754dp_isnan(r)) return r; - DPMANT(r) |= DP_MBIT(DP_MBITS - 1); - return r; + else + return ieee754dp_indef(); } ax.op = op; @@ -99,12 +98,38 @@ } +static u64 get_rounding(int sn, u64 xm) +{ + /* inexact must round of 3 bits + */ + if (xm & (DP_MBIT(3) - 1)) { + switch (ieee754_csr.rm) { + case IEEE754_RZ: + break; + case IEEE754_RN: + xm += 0x3 + ((xm >> 3) & 1); + /* xm += (xm&0x8)?0x4:0x3 */ + break; + case IEEE754_RU: /* toward +Infinity */ + if (!sn) /* ?? */ + xm += 0x8; + break; + case IEEE754_RD: /* toward -Infinity */ + if (sn) /* ?? */ + xm += 0x8; + break; + } + } + return xm; +} + + /* generate a normal/denormal number with over,under handling * sn is sign * xe is an unbiased exponent * xm is 3bit extended precision value. */ -ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm) +ieee754dp ieee754dp_format(int sn, int xe, u64 xm) { assert(xm); /* we don't gen exact zeros (probably should) */ @@ -117,40 +142,59 @@ if (ieee754_csr.nod) { SETCX(IEEE754_UNDERFLOW); - return ieee754dp_zero(sn); - } + SETCX(IEEE754_INEXACT); - /* sticky right shift es bits - */ - xm = XDPSRS(xm, es); - xe += es; + switch(ieee754_csr.rm) { + case IEEE754_RN: + return ieee754dp_zero(sn); + case IEEE754_RZ: + return ieee754dp_zero(sn); + case IEEE754_RU: /* toward +Infinity */ + if(sn == 0) + return ieee754dp_min(0); + else + return ieee754dp_zero(1); + case IEEE754_RD: /* toward -Infinity */ + if(sn == 0) + return ieee754dp_zero(0); + else + return ieee754dp_min(1); + } + } - assert((xm & (DP_HIDDEN_BIT << 3)) == 0); - assert(xe == DP_EMIN); + if (xe == DP_EMIN - 1 + && get_rounding(sn, xm) >> (DP_MBITS + 1 + 3)) + { + /* Not tiny after rounding */ + SETCX(IEEE754_INEXACT); + xm = get_rounding(sn, xm); + xm >>= 1; + /* Clear grs bits */ + xm &= ~(DP_MBIT(3) - 1); + xe++; + } + else { + /* sticky right shift es bits + */ + xm = XDPSRS(xm, es); + xe += es; + assert((xm & (DP_HIDDEN_BIT << 3)) == 0); + assert(xe == DP_EMIN); + } } if (xm & (DP_MBIT(3) - 1)) { SETCX(IEEE754_INEXACT); - /* inexact must round of 3 bits - */ - switch (ieee754_csr.rm) { - case IEEE754_RZ: - break; - case IEEE754_RN: - xm += 0x3 + ((xm >> 3) & 1); - /* xm += (xm&0x8)?0x4:0x3 */ - break; - case IEEE754_RU: /* toward +Infinity */ - if (!sn) /* ?? */ - xm += 0x8; - break; - case IEEE754_RD: /* toward -Infinity */ - if (sn) /* ?? */ - xm += 0x8; - break; + if ((xm & (DP_HIDDEN_BIT << 3)) == 0) { + SETCX(IEEE754_UNDERFLOW); } - /* adjust exponent for rounding add overflowing + + /* inexact must round of 3 bits */ - if (xm >> (DP_MBITS + 3 + 1)) { /* add causes mantissa overflow */ + xm = get_rounding(sn, xm); + /* adjust exponent for rounding add overflowing + */ + if (xm >> (DP_MBITS + 3 + 1)) { + /* add causes mantissa overflow */ xm >>= 1; xe++; } @@ -163,6 +207,7 @@ if (xe > DP_EMAX) { SETCX(IEEE754_OVERFLOW); + SETCX(IEEE754_INEXACT); /* -O can be table indexed by (rm,sn) */ switch (ieee754_csr.rm) { case IEEE754_RN: @@ -186,7 +231,8 @@ if ((xm & DP_HIDDEN_BIT) == 0) { /* we underflow (tiny/zero) */ assert(xe == DP_EMIN); - SETCX(IEEE754_UNDERFLOW); + if (ieee754_csr.mx & IEEE754_UNDERFLOW) + SETCX(IEEE754_UNDERFLOW); return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm); } else { assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ diff -Nru a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h --- a/arch/mips/math-emu/ieee754dp.h Fri Jun 27 14:19:58 2003 +++ b/arch/mips/math-emu/ieee754dp.h Fri Jun 27 14:19:58 2003 @@ -1,4 +1,4 @@ -/* +/* * IEEE754 floating point * double precision internal header file */ @@ -46,7 +46,7 @@ #define DPDNORMX DPDNORMx(xm,xe) #define DPDNORMY DPDNORMx(ym,ye) -static __inline ieee754dp builddp(int s, int bx, unsigned long long m) +static __inline ieee754dp builddp(int s, int bx, u64 m) { ieee754dp r; @@ -64,11 +64,11 @@ extern int ieee754dp_isnan(ieee754dp); extern int ieee754dp_issnan(ieee754dp); extern int ieee754si_xcpt(int, const char *, ...); -extern long long ieee754di_xcpt(long long, const char *, ...); +extern s64 ieee754di_xcpt(s64, const char *, ...); extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...); extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...); extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp); -extern ieee754dp ieee754dp_format(int, int, unsigned long long); +extern ieee754dp ieee754dp_format(int, int, u64); #define DPNORMRET2(s,e,m,name,a0,a1) \ diff -Nru a/arch/mips/math-emu/ieee754int.h b/arch/mips/math-emu/ieee754int.h --- a/arch/mips/math-emu/ieee754int.h Fri Jun 27 14:19:58 2003 +++ b/arch/mips/math-emu/ieee754int.h Fri Jun 27 14:19:58 2003 @@ -1,4 +1,4 @@ -/* +/* * IEEE754 floating point * common internal header file */ @@ -38,11 +38,11 @@ #define SP_EMAX 127 #define SP_MBITS 23 -#define DP_MBIT(x) ((unsigned long long)1 << (x)) +#define DP_MBIT(x) ((u64)1 << (x)) #define DP_HIDDEN_BIT DP_MBIT(DP_MBITS) #define DP_SIGN_BIT DP_MBIT(63) -#define SP_MBIT(x) ((unsigned long)1 << (x)) +#define SP_MBIT(x) ((u32)1 << (x)) #define SP_HIDDEN_BIT SP_MBIT(SP_MBITS) #define SP_SIGN_BIT SP_MBIT(31) @@ -61,7 +61,10 @@ (ieee754_csr.cx = 0) #define SETCX(x) \ - (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x),ieee754_csr.mx & (x)) + (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x)) + +#define SETANDTESTCX(x) \ + (SETCX(x),ieee754_csr.mx & (x)) #define TSTX() \ (ieee754_csr.cx & ieee754_csr.mx) @@ -82,9 +85,9 @@ if(vm == 0)\ vc = IEEE754_CLASS_INF;\ else if(vm & SP_MBIT(SP_MBITS-1)) \ - vc = IEEE754_CLASS_QNAN;\ - else \ vc = IEEE754_CLASS_SNAN;\ + else \ + vc = IEEE754_CLASS_QNAN;\ } else if(ve == SP_EMIN-1+SP_EBIAS) {\ if(vm) {\ ve = SP_EMIN;\ @@ -102,10 +105,10 @@ #define COMPXDP \ -unsigned long long xm; int xe; int xs; int xc +u64 xm; int xe; int xs; int xc #define COMPYDP \ -unsigned long long ym; int ye; int ys; int yc +u64 ym; int ye; int ys; int yc #define EXPLODEDP(v,vc,vs,ve,vm) \ {\ @@ -116,9 +119,9 @@ if(vm == 0)\ vc = IEEE754_CLASS_INF;\ else if(vm & DP_MBIT(DP_MBITS-1)) \ - vc = IEEE754_CLASS_QNAN;\ - else \ vc = IEEE754_CLASS_SNAN;\ + else \ + vc = IEEE754_CLASS_QNAN;\ } else if(ve == DP_EMIN-1+DP_EBIAS) {\ if(vm) {\ ve = DP_EMIN;\ @@ -133,3 +136,30 @@ } #define EXPLODEXDP EXPLODEDP(x,xc,xs,xe,xm) #define EXPLODEYDP EXPLODEDP(y,yc,ys,ye,ym) + +#define FLUSHDP(v,vc,vs,ve,vm) \ + if(vc==IEEE754_CLASS_DNORM) {\ + if(ieee754_csr.nod) {\ + SETCX(IEEE754_INEXACT);\ + vc = IEEE754_CLASS_ZERO;\ + ve = DP_EMIN-1+DP_EBIAS;\ + vm = 0;\ + v = ieee754dp_zero(vs);\ + }\ + } + +#define FLUSHSP(v,vc,vs,ve,vm) \ + if(vc==IEEE754_CLASS_DNORM) {\ + if(ieee754_csr.nod) {\ + SETCX(IEEE754_INEXACT);\ + vc = IEEE754_CLASS_ZERO;\ + ve = SP_EMIN-1+SP_EBIAS;\ + vm = 0;\ + v = ieee754sp_zero(vs);\ + }\ + } + +#define FLUSHXDP FLUSHDP(x,xc,xs,xe,xm) +#define FLUSHYDP FLUSHDP(y,yc,ys,ye,ym) +#define FLUSHXSP FLUSHSP(x,xc,xs,xe,xm) +#define FLUSHYSP FLUSHSP(y,yc,ys,ye,ym) diff -Nru a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c --- a/arch/mips/math-emu/ieee754sp.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/math-emu/ieee754sp.c Fri Jun 27 14:19:55 2003 @@ -42,9 +42,7 @@ int ieee754sp_issnan(ieee754sp x) { assert(ieee754sp_isnan(x)); - if (ieee754_csr.noq) - return 1; - return !(SPMANT(x) & SP_MBIT(SP_MBITS - 1)); + return (SPMANT(x) & SP_MBIT(SP_MBITS-1)); } @@ -72,12 +70,13 @@ if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ return r; - if (!SETCX(IEEE754_INVALID_OPERATION)) { + if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { /* not enabled convert to a quiet NaN */ - if (ieee754_csr.noq) + SPMANT(r) &= (~SP_MBIT(SP_MBITS-1)); + if (ieee754sp_isnan(r)) return r; - SPMANT(r) |= SP_MBIT(SP_MBITS - 1); - return r; + else + return ieee754sp_indef(); } ax.op = op; @@ -100,6 +99,32 @@ } +static unsigned get_rounding(int sn, unsigned xm) +{ + /* inexact must round of 3 bits + */ + if (xm & (SP_MBIT(3) - 1)) { + switch (ieee754_csr.rm) { + case IEEE754_RZ: + break; + case IEEE754_RN: + xm += 0x3 + ((xm >> 3) & 1); + /* xm += (xm&0x8)?0x4:0x3 */ + break; + case IEEE754_RU: /* toward +Infinity */ + if (!sn) /* ?? */ + xm += 0x8; + break; + case IEEE754_RD: /* toward -Infinity */ + if (sn) /* ?? */ + xm += 0x8; + break; + } + } + return xm; +} + + /* generate a normal/denormal number with over,under handling * sn is sign * xe is an unbiased exponent @@ -118,39 +143,58 @@ if (ieee754_csr.nod) { SETCX(IEEE754_UNDERFLOW); - return ieee754sp_zero(sn); - } + SETCX(IEEE754_INEXACT); - /* sticky right shift es bits - */ - SPXSRSXn(es); + switch(ieee754_csr.rm) { + case IEEE754_RN: + return ieee754sp_zero(sn); + case IEEE754_RZ: + return ieee754sp_zero(sn); + case IEEE754_RU: /* toward +Infinity */ + if(sn == 0) + return ieee754sp_min(0); + else + return ieee754sp_zero(1); + case IEEE754_RD: /* toward -Infinity */ + if(sn == 0) + return ieee754sp_zero(0); + else + return ieee754sp_min(1); + } + } - assert((xm & (SP_HIDDEN_BIT << 3)) == 0); - assert(xe == SP_EMIN); + if (xe == SP_EMIN - 1 + && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3)) + { + /* Not tiny after rounding */ + SETCX(IEEE754_INEXACT); + xm = get_rounding(sn, xm); + xm >>= 1; + /* Clear grs bits */ + xm &= ~(SP_MBIT(3) - 1); + xe++; + } + else { + /* sticky right shift es bits + */ + SPXSRSXn(es); + assert((xm & (SP_HIDDEN_BIT << 3)) == 0); + assert(xe == SP_EMIN); + } } if (xm & (SP_MBIT(3) - 1)) { SETCX(IEEE754_INEXACT); - /* inexact must round of 3 bits - */ - switch (ieee754_csr.rm) { - case IEEE754_RZ: - break; - case IEEE754_RN: - xm += 0x3 + ((xm >> 3) & 1); - /* xm += (xm&0x8)?0x4:0x3 */ - break; - case IEEE754_RU: /* toward +Infinity */ - if (!sn) /* ?? */ - xm += 0x8; - break; - case IEEE754_RD: /* toward -Infinity */ - if (sn) /* ?? */ - xm += 0x8; - break; + if ((xm & (SP_HIDDEN_BIT << 3)) == 0) { + SETCX(IEEE754_UNDERFLOW); } - /* adjust exponent for rounding add overflowing + + /* inexact must round of 3 bits */ - if (xm >> (SP_MBITS + 1 + 3)) { /* add causes mantissa overflow */ + xm = get_rounding(sn, xm); + /* adjust exponent for rounding add overflowing + */ + if (xm >> (SP_MBITS + 1 + 3)) { + /* add causes mantissa overflow */ xm >>= 1; xe++; } @@ -163,6 +207,7 @@ if (xe > SP_EMAX) { SETCX(IEEE754_OVERFLOW); + SETCX(IEEE754_INEXACT); /* -O can be table indexed by (rm,sn) */ switch (ieee754_csr.rm) { case IEEE754_RN: @@ -186,7 +231,8 @@ if ((xm & SP_HIDDEN_BIT) == 0) { /* we underflow (tiny/zero) */ assert(xe == SP_EMIN); - SETCX(IEEE754_UNDERFLOW); + if (ieee754_csr.mx & IEEE754_UNDERFLOW) + SETCX(IEEE754_UNDERFLOW); return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm); } else { assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ diff -Nru a/arch/mips/math-emu/ieee754sp.h b/arch/mips/math-emu/ieee754sp.h --- a/arch/mips/math-emu/ieee754sp.h Fri Jun 27 14:19:52 2003 +++ b/arch/mips/math-emu/ieee754sp.h Fri Jun 27 14:19:52 2003 @@ -1,4 +1,4 @@ -/* +/* * IEEE754 floating point * double precision internal header file */ @@ -70,7 +70,7 @@ extern int ieee754sp_isnan(ieee754sp); extern int ieee754sp_issnan(ieee754sp); extern int ieee754si_xcpt(int, const char *, ...); -extern long long ieee754di_xcpt(long long, const char *, ...); +extern s64 ieee754di_xcpt(s64, const char *, ...); extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...); extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...); extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp); diff -Nru a/arch/mips/math-emu/ieee754xcpt.c b/arch/mips/math-emu/ieee754xcpt.c --- a/arch/mips/math-emu/ieee754xcpt.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/math-emu/ieee754xcpt.c Fri Jun 27 14:19:53 2003 @@ -23,12 +23,13 @@ /************************************************************************** * Nov 7, 2000 - * Added preprocessor hacks to map to Linux kernel diagnostics. + * Added preprocessor hacks to map to Linux kernel diagnostics. * * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. *************************************************************************/ +#include <linux/kernel.h> #include "ieee754.h" /* @@ -42,7 +43,7 @@ void ieee754_xcpt(struct ieee754xctx *xcp) { - printk("floating point exception in \"%s\", type=%s\n", + printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n", xcp->op, rtnames[xcp->rt]); } diff -Nru a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c --- a/arch/mips/math-emu/kernel_linkage.c Fri Jun 27 14:19:52 2003 +++ b/arch/mips/math-emu/kernel_linkage.c Fri Jun 27 14:19:52 2003 @@ -20,13 +20,10 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - *************************************************************************/ -/* * Routines corresponding to Linux kernel FP context * manipulation primitives for the Algorithmics MIPS * FPU Emulator */ - #include <linux/sched.h> #include <asm/processor.h> #include <asm/signal.h> @@ -42,10 +39,10 @@ { static int first = 1; int i; - + if (first) { first = 0; - printk("Algorithmics/MIPS FPU Emulator v1.4\n"); + printk("Algorithmics/MIPS FPU Emulator v1.5\n"); } current->thread.fpu.soft.sr = 0; diff -Nru a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c --- a/arch/mips/math-emu/sp_add.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/math-emu/sp_add.c Fri Jun 27 14:20:00 2003 @@ -37,27 +37,23 @@ CLEARCX; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "add", x, - y); + FLUSHXSP; + FLUSHYSP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "add", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "add", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -72,7 +69,7 @@ return x; - /* Inifity handling + /* Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): diff -Nru a/arch/mips/math-emu/sp_cmp.c b/arch/mips/math-emu/sp_cmp.c --- a/arch/mips/math-emu/sp_cmp.c Fri Jun 27 14:19:30 2003 +++ b/arch/mips/math-emu/sp_cmp.c Fri Jun 27 14:19:30 2003 @@ -27,15 +27,24 @@ #include "ieee754sp.h" -int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp) +int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig) { - CLEARCX; + COMPXSP; + COMPYSP; + + EXPLODEXSP; + EXPLODEYSP; + FLUSHXSP; + FLUSHYSP; + CLEARCX; /* Even clear inexact flag here */ if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) { + if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN) + SETCX(IEEE754_INVALID_OPERATION); if (cmp & IEEE754_CUN) return 1; if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (SETCX(IEEE754_INVALID_OPERATION)) + if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) return ieee754si_xcpt(0, "fcmpf", x); } return 0; diff -Nru a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c --- a/arch/mips/math-emu/sp_div.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/math-emu/sp_div.c Fri Jun 27 14:20:00 2003 @@ -32,32 +32,28 @@ COMPXSP; COMPYSP; - CLEARCX; - EXPLODEXSP; EXPLODEYSP; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "div", x, - y); + CLEARCX; + + FLUSHXSP; + FLUSHYSP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "div", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "div", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): diff -Nru a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c --- a/arch/mips/math-emu/sp_fdp.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/math-emu/sp_fdp.c Fri Jun 27 14:19:56 2003 @@ -30,20 +30,24 @@ ieee754sp ieee754sp_fdp(ieee754dp x) { COMPXDP; + ieee754sp nan; + + EXPLODEXDP; CLEARCX; - EXPLODEXDP; + FLUSHXDP; switch (xc) { - case IEEE754_CLASS_QNAN: case IEEE754_CLASS_SNAN: - return ieee754sp_nanxcpt(buildsp(xs, - SP_EMAX + 1 + SP_EBIAS, - (unsigned long) - (xm >> - (DP_MBITS - SP_MBITS))), - "fdp", x); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp"); + case IEEE754_CLASS_QNAN: + nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32) + (xm >> (DP_MBITS - SP_MBITS))); + if (!ieee754sp_isnan(nan)) + nan = ieee754sp_indef(); + return ieee754sp_nanxcpt(nan, "fdp", x); case IEEE754_CLASS_INF: return ieee754sp_inf(xs); case IEEE754_CLASS_ZERO: @@ -51,15 +55,19 @@ case IEEE754_CLASS_DNORM: /* can't possibly be sp representable */ SETCX(IEEE754_UNDERFLOW); + SETCX(IEEE754_INEXACT); + if ((ieee754_csr.rm == IEEE754_RU && !xs) || + (ieee754_csr.rm == IEEE754_RD && xs)) + return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x); return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x); case IEEE754_CLASS_NORM: break; } { - unsigned long rm; + u32 rm; - /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift + /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift */ rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) | ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0); diff -Nru a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c --- a/arch/mips/math-emu/sp_fint.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/math-emu/sp_fint.c Fri Jun 27 14:19:55 2003 @@ -52,13 +52,13 @@ xe = SP_MBITS + 3; if (xm >> (SP_MBITS + 1 + 3)) { - /* shunt out overflow bits + /* shunt out overflow bits */ while (xm >> (SP_MBITS + 1 + 3)) { SPXSRSX1(); } } else { - /* normalize in grs extended single precision + /* normalize in grs extended single precision */ while ((xm >> (SP_MBITS + 3)) == 0) { xm <<= 1; diff -Nru a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c --- a/arch/mips/math-emu/sp_flong.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/math-emu/sp_flong.c Fri Jun 27 14:20:01 2003 @@ -27,7 +27,7 @@ #include "ieee754sp.h" -ieee754sp ieee754sp_flong(long long x) +ieee754sp ieee754sp_flong(s64 x) { COMPXDP; /* <--- need 64-bit mantissa temp */ @@ -52,7 +52,7 @@ xe = SP_MBITS + 3; if (xm >> (SP_MBITS + 1 + 3)) { - /* shunt out overflow bits + /* shunt out overflow bits */ while (xm >> (SP_MBITS + 1 + 3)) { SPXSRSX1(); @@ -68,9 +68,9 @@ } -ieee754sp ieee754sp_fulong(unsigned long long u) +ieee754sp ieee754sp_fulong(u64 u) { - if ((long long) u < 0) + if ((s64) u < 0) return ieee754sp_add(ieee754sp_1e63(), ieee754sp_flong(u & ~(1ULL << 63))); return ieee754sp_flong(u); diff -Nru a/arch/mips/math-emu/sp_frexp.c b/arch/mips/math-emu/sp_frexp.c --- a/arch/mips/math-emu/sp_frexp.c Fri Jun 27 14:19:30 2003 +++ b/arch/mips/math-emu/sp_frexp.c Fri Jun 27 14:19:30 2003 @@ -27,7 +27,7 @@ #include "ieee754sp.h" -/* close to ieeep754sp_logb +/* close to ieeep754sp_logb */ ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr) { diff -Nru a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c --- a/arch/mips/math-emu/sp_modf.c Fri Jun 27 14:20:04 2003 +++ b/arch/mips/math-emu/sp_modf.c Fri Jun 27 14:20:04 2003 @@ -59,7 +59,7 @@ *ip = x; return ieee754sp_zero(xs); } - /* generate ipart mantissa by clearing bottom bits + /* generate ipart mantissa by clearing bottom bits */ *ip = buildsp(xs, xe + SP_EBIAS, ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) & diff -Nru a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c --- a/arch/mips/math-emu/sp_mul.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips/math-emu/sp_mul.c Fri Jun 27 14:19:58 2003 @@ -32,32 +32,28 @@ COMPXSP; COMPYSP; - CLEARCX; - EXPLODEXSP; EXPLODEYSP; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "mul", x, - y); + CLEARCX; + + FLUSHXSP; + FLUSHYSP; + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): diff -Nru a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c --- a/arch/mips/math-emu/sp_simple.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/math-emu/sp_simple.c Fri Jun 27 14:19:57 2003 @@ -42,7 +42,16 @@ ieee754sp ieee754sp_neg(ieee754sp x) { + COMPXSP; + + EXPLODEXSP; CLEARCX; + FLUSHXSP; + + if (xc == IEEE754_CLASS_SNAN) { + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "neg"); + } if (ieee754sp_isnan(x)) /* but not infinity */ return ieee754sp_nanxcpt(x, "neg", x); @@ -55,7 +64,16 @@ ieee754sp ieee754sp_abs(ieee754sp x) { + COMPXSP; + + EXPLODEXSP; CLEARCX; + FLUSHXSP; + + if (xc == IEEE754_CLASS_SNAN) { + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "abs"); + } if (ieee754sp_isnan(x)) /* but not infinity */ return ieee754sp_nanxcpt(x, "abs", x); diff -Nru a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c --- a/arch/mips/math-emu/sp_sqrt.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/math-emu/sp_sqrt.c Fri Jun 27 14:19:53 2003 @@ -27,43 +27,44 @@ #include "ieee754sp.h" -static const struct ieee754sp_konst knan = { - 0, SP_EBIAS + SP_EMAX + 1, 0 -}; - -#define nan ((ieee754sp)knan) - ieee754sp ieee754sp_sqrt(ieee754sp x) { - int sign = (int) 0x80000000; int ix, s, q, m, t, i; unsigned int r; - COMPXDP; + COMPXSP; /* take care of Inf and NaN */ - EXPLODEXDP; + EXPLODEXSP; + CLEARCX; + FLUSHXSP; /* x == INF or NAN? */ switch (xc) { case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: /* sqrt(Nan) = Nan */ return ieee754sp_nanxcpt(x, "sqrt"); + case IEEE754_CLASS_SNAN: + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); case IEEE754_CLASS_ZERO: /* sqrt(0) = 0 */ return x; case IEEE754_CLASS_INF: - if (xs) + if (xs) { /* sqrt(-Inf) = Nan */ - return ieee754sp_nanxcpt(nan, "sqrt"); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); + } /* sqrt(+Inf) = Inf */ return x; case IEEE754_CLASS_DNORM: case IEEE754_CLASS_NORM: - if (xs) + if (xs) { /* sqrt(-x) = Nan */ - return ieee754sp_nanxcpt(nan, "sqrt"); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); + } break; } @@ -99,6 +100,7 @@ } if (ix != 0) { + SETCX(IEEE754_INEXACT); switch (ieee754_csr.rm) { case IEEE754_RP: q += 2; diff -Nru a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c --- a/arch/mips/math-emu/sp_sub.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/math-emu/sp_sub.c Fri Jun 27 14:19:55 2003 @@ -32,32 +32,28 @@ COMPXSP; COMPYSP; - CLEARCX; - EXPLODEXSP; EXPLODEYSP; - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "sub", x, - y); + CLEARCX; + FLUSHXSP; + FLUSHYSP; + + switch (CLPAIR(xc, yc)) { + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): @@ -65,6 +61,7 @@ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): return y; + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): @@ -72,7 +69,7 @@ return x; - /* Inifity handling + /* Infinity handling */ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): @@ -170,13 +167,13 @@ xe = xe; xs = ys; } - if (xm == 0) + if (xm == 0) { if (ieee754_csr.rm == IEEE754_RD) return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ else return ieee754sp_zero(0); /* other round modes => sign = 1 */ - - /* normalize to rounding precision + } + /* normalize to rounding precision */ while ((xm >> (SP_MBITS + 3)) == 0) { xm <<= 1; diff -Nru a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c --- a/arch/mips/math-emu/sp_tint.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/math-emu/sp_tint.c Fri Jun 27 14:20:06 2003 @@ -35,38 +35,78 @@ CLEARCX; EXPLODEXSP; + FLUSHXSP; switch (xc) { case IEEE754_CLASS_SNAN: case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754si_xcpt(ieee754si_indef(), "fixsp", x); case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fixsp", x); + SETCX(IEEE754_INVALID_OPERATION); + return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); case IEEE754_CLASS_ZERO: return 0; - case IEEE754_CLASS_DNORM: /* much to small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fixsp", x); + case IEEE754_CLASS_DNORM: case IEEE754_CLASS_NORM: break; } if (xe >= 31) { - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fix", x); - } - if (xe < 0) { - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fix", x); + /* look for valid corner case */ + if (xe == 31 && xs && xm == SP_HIDDEN_BIT) + return -0x80000000; + /* Set invalid. We will only use overflow for floating + point overflow */ + SETCX(IEEE754_INVALID_OPERATION); + return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); } /* oh gawd */ if (xe > SP_MBITS) { xm <<= xe - SP_MBITS; - } else if (xe < SP_MBITS) { - /* XXX no rounding - */ - xm >>= SP_MBITS - xe; + } else { + u32 residue; + int round; + int sticky; + int odd; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } + else { + /* Shifting a u32 32 times does not work, + * so we do it in two steps. Be aware that xe + * may be -1 */ + residue = xm << (xe + 1); + residue <<= 31 - SP_MBITS; + round = (residue >> 31) != 0; + sticky = (residue << 1) != 0; + xm >>= SP_MBITS - xe; + } + odd = (xm & 0x1) != 0x0; + switch (ieee754_csr.rm) { + case IEEE754_RN: + if (round && (sticky || odd)) + xm++; + break; + case IEEE754_RZ: + break; + case IEEE754_RU: /* toward +Infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case IEEE754_RD: /* toward -Infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + if ((xm >> 31) != 0) { + /* This can happen after rounding */ + SETCX(IEEE754_INVALID_OPERATION); + return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); + } + if (round || sticky) + SETCX(IEEE754_INEXACT); } if (xs) return -xm; diff -Nru a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c --- a/arch/mips/math-emu/sp_tlong.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/math-emu/sp_tlong.c Fri Jun 27 14:20:06 2003 @@ -27,45 +27,81 @@ #include "ieee754sp.h" -long long ieee754sp_tlong(ieee754sp x) +s64 ieee754sp_tlong(ieee754sp x) { COMPXDP; /* <-- need 64-bit mantissa tmp */ CLEARCX; EXPLODEXSP; + FLUSHXSP; switch (xc) { case IEEE754_CLASS_SNAN: case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); + SETCX(IEEE754_INVALID_OPERATION); return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); case IEEE754_CLASS_ZERO: return 0; - case IEEE754_CLASS_DNORM: /* much to small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "sp_tlong", x); + case IEEE754_CLASS_DNORM: case IEEE754_CLASS_NORM: break; } if (xe >= 63) { - SETCX(IEEE754_OVERFLOW); + /* look for valid corner case */ + if (xe == 63 && xs && xm == SP_HIDDEN_BIT) + return -0x8000000000000000LL; + /* Set invalid. We will only use overflow for floating + point overflow */ + SETCX(IEEE754_INVALID_OPERATION); return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); } - if (xe < 0) { - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "sp_tlong", x); - } /* oh gawd */ if (xe > SP_MBITS) { xm <<= xe - SP_MBITS; } else if (xe < SP_MBITS) { - /* XXX no rounding - */ - xm >>= SP_MBITS - xe; + u32 residue; + int round; + int sticky; + int odd; + + if (xe < -1) { + residue = xm; + round = 0; + sticky = residue != 0; + xm = 0; + } + else { + residue = xm << (32 - SP_MBITS + xe); + round = (residue >> 31) != 0; + sticky = (residue << 1) != 0; + xm >>= SP_MBITS - xe; + } + odd = (xm & 0x1) != 0x0; + switch (ieee754_csr.rm) { + case IEEE754_RN: + if (round && (sticky || odd)) + xm++; + break; + case IEEE754_RZ: + break; + case IEEE754_RU: /* toward +Infinity */ + if ((round || sticky) && !xs) + xm++; + break; + case IEEE754_RD: /* toward -Infinity */ + if ((round || sticky) && xs) + xm++; + break; + } + if ((xm >> 63) != 0) { + /* This can happen after rounding */ + SETCX(IEEE754_INVALID_OPERATION); + return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); + } + if (round || sticky) + SETCX(IEEE754_INEXACT); } if (xs) return -xm; @@ -74,14 +110,14 @@ } -unsigned long long ieee754sp_tulong(ieee754sp x) +u64 ieee754sp_tulong(ieee754sp x) { ieee754sp hb = ieee754sp_1e63(); /* what if x < 0 ?? */ if (ieee754sp_lt(x, hb)) - return (unsigned long long) ieee754sp_tlong(x); + return (u64) ieee754sp_tlong(x); - return (unsigned long long) ieee754sp_tlong(ieee754sp_sub(x, hb)) | + return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) | (1ULL << 63); } diff -Nru a/arch/mips/mips-boards/atlas/Makefile b/arch/mips/mips-boards/atlas/Makefile --- a/arch/mips/mips-boards/atlas/Makefile Fri Jun 27 14:20:04 2003 +++ b/arch/mips/mips-boards/atlas/Makefile Fri Jun 27 14:20:04 2003 @@ -7,12 +7,12 @@ # This program is free software; you can distribute it and/or modify it # under the terms of the GNU General Public License (Version 2) as # published by the Free Software Foundation. -# +# # This program is distributed in the hope it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. -# +# # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. diff -Nru a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c --- a/arch/mips/mips-boards/atlas/atlas_int.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/mips-boards/atlas/atlas_int.c Fri Jun 27 14:19:59 2003 @@ -19,17 +19,17 @@ * * ######################################################################## * - * Routines for generic manipulation of the interrupts found on the MIPS + * Routines for generic manipulation of the interrupts found on the MIPS * Atlas board. * */ #include <linux/config.h> +#include <linux/compiler.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> -#include <linux/seq_file.h> #include <asm/irq.h> #include <asm/mips-boards/atlas.h> @@ -41,10 +41,6 @@ = (struct atlas_ictrl_regs *)ATLAS_ICTRL_REGS_BASE; extern asmlinkage void mipsIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); - -unsigned long spurious_count = 0; -irq_desc_t irq_desc[NR_IRQS]; #if 0 #define DEBUG_INT(x...) printk(x) @@ -52,11 +48,6 @@ #define DEBUG_INT(x...) #endif -void inline disable_irq_nosync(unsigned int irq_nr) -{ - disable_atlas_irq(irq_nr); -} - void disable_atlas_irq(unsigned int irq_nr) { atlas_hw0_icregs->intrsten = (1 << irq_nr); @@ -94,80 +85,6 @@ NULL }; -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - int num = 0; - struct irqaction *action; - unsigned long flags; - - for (i = 0; i < ATLASINT_END; i++, num++) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto skip; - seq_printf(p, "%2d: %8d %c %s", - num, kstat_cpu(0).irqs[num], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_printf(p, " [hw0]\n"); -skip: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } - return 0; -} - -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, - const char * devname, - void *dev_id) -{ - struct irqaction *action; - - DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname); - - if (irq >= ATLASINT_END) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if(!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->dev_id = dev_id; - action->next = 0; - irq_desc[irq].action = action; - enable_atlas_irq(irq); - - return 0; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *action; - - if (irq >= ATLASINT_END) { - printk("Trying to free IRQ%d\n",irq); - return; - } - - action = irq_desc[irq].action; - irq_desc[irq].action = NULL; - disable_atlas_irq(irq); - kfree(action); -} - static inline int ls1bit32(unsigned int x) { int b = 31, s; @@ -183,48 +100,23 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs) { - struct irqaction *action; unsigned long int_status; - int irq, cpu = smp_processor_id(); + int irq; - int_status = atlas_hw0_icregs->intstatus; + int_status = atlas_hw0_icregs->intstatus; /* if int_status == 0, then the interrupt has already been cleared */ - if (int_status == 0) + if (unlikely(int_status == 0)) return; irq = ls1bit32(int_status); - action = irq_desc[irq].action; DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); - /* if action == NULL, then we don't have a handler for the irq */ - if ( action == NULL ) { - printk("No handler for hw0 irq: %i\n", irq); - spurious_count++; - return; - } - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - action->handler(irq, action->dev_id, regs); - irq_exit(cpu, irq); - - return; -} - -unsigned long probe_irq_on (void) -{ - return 0; -} - - -int probe_irq_off (unsigned long irqs) -{ - return 0; + do_IRQ(irq, regs); } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void breakpoint(void); extern int remote_debug; #endif @@ -233,11 +125,11 @@ { int i; - /* - * Mask out all interrupt by writing "1" to all bit position in - * the interrupt reset reg. + /* + * Mask out all interrupt by writing "1" to all bit position in + * the interrupt reset reg. */ - atlas_hw0_icregs->intrsten = 0xffffffff; + atlas_hw0_icregs->intrsten = 0xffffffff; /* Now safe to set the exception vector. */ set_except_vector(0, mipsIRQ); @@ -250,7 +142,7 @@ spin_lock_init(&irq_desc[i].lock); } -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); diff -Nru a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c --- a/arch/mips/mips-boards/atlas/atlas_setup.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/mips-boards/atlas/atlas_setup.c Fri Jun 27 14:19:57 2003 @@ -19,6 +19,7 @@ */ #include <linux/config.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/sched.h> #include <linux/mc146818rtc.h> #include <linux/ioport.h> @@ -28,15 +29,17 @@ #include <asm/irq.h> #include <asm/mips-boards/generic.h> #include <asm/mips-boards/prom.h> -#include <asm/gt64120.h> #include <asm/mips-boards/atlasint.h> +#include <asm/gt64120.h> +#include <asm/time.h> +#include <asm/traps.h> #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) extern void console_setup(char *, int *); char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); extern void saa9730_kgdb_hook(void); extern void breakpoint(void); @@ -47,9 +50,18 @@ extern void mips_reboot_setup(void); +const char *get_system_type(void) +{ + return "MIPS Atlas"; +} + +extern void mips_time_init(void); +extern void mips_timer_setup(struct irqaction *irq); +extern unsigned long mips_rtc_get_time(void); + void __init atlas_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int rs_putDebugChar(char); char rs_getDebugChar(void); int saa9730_putDebugChar(char); @@ -73,9 +85,9 @@ prom_printf("Config serial console: %s\n", serial_console); console_setup(serial_console, NULL); } -#endif +#endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -107,9 +119,12 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; + cpu_data[0].options &= ~MIPS_CPU_FPU; rtc_ops = &atlas_rtc_ops; + board_time_init = mips_time_init; + board_timer_setup = mips_timer_setup; + rtc_get_time = mips_rtc_get_time; mips_reboot_setup(); } diff -Nru a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile --- a/arch/mips/mips-boards/generic/Makefile Fri Jun 27 14:20:00 2003 +++ b/arch/mips/mips-boards/generic/Makefile Fri Jun 27 14:20:00 2003 @@ -2,28 +2,26 @@ # Carsten Langgaard, carstenl@mips.com # Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. # -# ######################################################################## -# # This program is free software; you can distribute it and/or modify it # under the terms of the GNU General Public License (Version 2) as # published by the Free Software Foundation. -# +# # This program is distributed in the hope it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. -# +# # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # -# ####################################################################### -# # Makefile for the MIPS boards generic routines under Linux. # -EXTRA_AFLAGS := $(CFLAGS) +obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ + printf.o cmdline.o +obj-$(CONFIG_MIPS_ATLAS) += time.o +obj-$(CONFIG_MIPS_MALTA) += time.o +obj-$(CONFIG_KGDB) += gdb_hook.o -obj-y := mipsIRQ.o pci.o reset.o display.o init.o \ - memory.o printf.o cmdline.o time.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/mips-boards/generic/cmdline.c b/arch/mips/mips-boards/generic/cmdline.c --- a/arch/mips/mips-boards/generic/cmdline.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/mips-boards/generic/cmdline.c Fri Jun 27 14:20:00 2003 @@ -17,16 +17,21 @@ * * Kernel command line creation using the prom monitor (YAMON) argc/argv. */ -#include <linux/config.h> #include <linux/init.h> #include <linux/string.h> #include <asm/bootinfo.h> extern int prom_argc; -extern char **prom_argv; +extern int *_prom_argv; -char arcs_cmdline[COMMAND_LINE_SIZE]; +/* + * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. + * This macro take care of sign extension. + */ +#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)])) + +char arcs_cmdline[CL_SIZE]; char * __init prom_getcmdline(void) { @@ -43,8 +48,8 @@ cp = &(arcs_cmdline[0]); while(actr < prom_argc) { - strcpy(cp, prom_argv[actr]); - cp += strlen(prom_argv[actr]); + strcpy(cp, prom_argv(actr)); + cp += strlen(prom_argv(actr)); *cp++ = ' '; actr++; } diff -Nru a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c --- a/arch/mips/mips-boards/generic/display.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/mips-boards/generic/display.c Fri Jun 27 14:19:59 2003 @@ -18,7 +18,7 @@ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * ######################################################################## - * + * * Display routines for display messages in MIPS boards ascii display. * */ @@ -39,9 +39,11 @@ } } +#ifndef CONFIG_MIPS_SEAD void mips_display_word(unsigned int num) { volatile unsigned int *display = (void *)ASCII_DISPLAY_WORD_BASE; - + *display = num; } +#endif diff -Nru a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c --- a/arch/mips/mips-boards/generic/gdb_hook.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips/mips-boards/generic/gdb_hook.c Fri Jun 27 14:19:55 2003 @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,12 +15,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * This is the interface to the remote debugger stub. - * */ - +#include <linux/config.h> #include <linux/serialP.h> #include <linux/serial_reg.h> @@ -67,28 +62,28 @@ serial_in(&kdb_port_info, UART_MSR); /* - * Now, initialize the UART + * Now, initialize the UART */ serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ if (kdb_port_info.flags & ASYNC_FOURPORT) { kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS; t = UART_MCR_DTR | UART_MCR_OUT1; } else { - kdb_port_info.MCR + kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; t = UART_MCR_DTR | UART_MCR_RTS; } kdb_port_info.MCR = t; /* no interrupts, please */ serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR); - + /* * and set the speed of the serial port * (currently hardwired to 9600 8N1 */ /* baud rate is fixed to 9600 (is this sufficient?)*/ - t = kdb_port_info.state->baud_base / 9600; + t = kdb_port_info.state->baud_base / 9600; /* set DLAB */ serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB); serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */ @@ -102,7 +97,7 @@ return generic_putDebugChar(c); } -char getDebugChar(void) +char getDebugChar(void) { return generic_getDebugChar(); } @@ -156,7 +151,7 @@ static int saa9730_kgdb_active = 0; -void saa9730_kgdb_hook(void) +void saa9730_kgdb_hook(void) { volatile unsigned char t; diff -Nru a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c --- a/arch/mips/mips-boards/generic/init.c Fri Jun 27 14:19:52 2003 +++ b/arch/mips/mips-boards/generic/init.c Fri Jun 27 14:19:52 2003 @@ -27,6 +27,8 @@ #include <asm/mips-boards/generic.h> #include <asm/gt64120.h> #include <asm/mips-boards/malta.h> +#include <asm/mips-boards/msc01_pci.h> +#include <asm/mips-boards/bonito64.h> /* Environment variable */ typedef struct @@ -36,27 +38,37 @@ } t_env_var; int prom_argc; -char **prom_argv, **prom_envp; +int *_prom_argv, *_prom_envp; + +/* + * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. + * This macro take care of sign extension, if running in 64-bit mode. + */ +#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)])) int init_debug = 0; +unsigned int mips_revision_corid; + char *prom_getenv(char *envname) { - /* + /* * Return a pointer to the given environment variable. + * In 64-bit mode: we're using 64-bit pointers, but all pointers + * in the PROM structures are only 32-bit, so we need some + * workarounds, if we are running in 64-bit mode. */ - - t_env_var *env = (t_env_var *)prom_envp; - int i; + int i, index=0; i = strlen(envname); - while(env->name) { - if(strncmp(envname, env->name, i) == 0) { - return(env->val); + while(prom_envp(index)) { + if(strncmp(envname, prom_envp(index), i) == 0) { + return(prom_envp(index+1)); } - env++; + index += 2; } + return(NULL); } @@ -83,7 +95,7 @@ ea[i] = num; } } - + int get_ethernet_addr(char *ethernet_addr) { char *ethaddr_str; @@ -109,28 +121,84 @@ int __init prom_init(int argc, char **argv, char **envp) { prom_argc = argc; - prom_argv = argv; - prom_envp = envp; + _prom_argv = (int *)argv; + _prom_envp = (int *)envp; mips_display_message("LINUX"); - /* - * Setup the North bridge to do Master byte-lane swapping when - * running in bigendian. - */ +#ifdef CONFIG_MIPS_SEAD + set_io_port_base(KSEG1); +#else + mips_revision_corid = MIPS_REVISION_CORID; + switch(mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + /* + * Setup the North bridge to do Master byte-lane swapping + * when running in bigendian. + */ +#if defined(__MIPSEL__) + GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | + GT_PCI0_CMD_SBYTESWAP_BIT); +#else + GT_WRITE(GT_PCI0_CMD_OFS, 0); +#endif + +#if defined(CONFIG_MIPS_MALTA) + set_io_port_base(MALTA_GT_PORT_BASE); +#else + set_io_port_base(KSEG1); +#endif + + break; + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + /* + * Disable Bonito IOBC. + */ + BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG & + ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | + BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); + + /* + * Setup the North bridge to do Master byte-lane swapping + * when running in bigendian. + */ #if defined(__MIPSEL__) - GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | - GT_PCI0_CMD_SBYTESWAP_BIT); + BONITO_BONGENCFG = BONITO_BONGENCFG & + ~(BONITO_BONGENCFG_MSTRBYTESWAP | + BONITO_BONGENCFG_BYTESWAP); #else - GT_WRITE(GT_PCI0_CMD_OFS, 0); + BONITO_BONGENCFG = BONITO_BONGENCFG | + BONITO_BONGENCFG_MSTRBYTESWAP | + BONITO_BONGENCFG_BYTESWAP; #endif #if defined(CONFIG_MIPS_MALTA) - mips_io_port_base = MALTA_PORT_BASE; + set_io_port_base(MALTA_BONITO_PORT_BASE); #else - mips_io_port_base = KSEG1; + set_io_port_base(KSEG1); +#endif + break; + + case MIPS_REVISION_CORID_CORE_MSC: + set_io_port_base(MALTA_MSC_PORT_BASE); +#if defined(__MIPSEL__) + MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP); +#else + MSC_WRITE(MSC01_PCI_SWAP, + MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF | + MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | + MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); +#endif + break; + default: + /* Unknown Core card */ + mips_display_message("CC Error"); + while(1); /* We die here... */ + } #endif - setup_prom_printf(0); prom_printf("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); diff -Nru a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c --- a/arch/mips/mips-boards/generic/memory.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips/mips-boards/generic/memory.c Fri Jun 27 14:19:53 2003 @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,11 +15,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * - * PROM library functions for acquiring/using memory descriptors given to + * PROM library functions for acquiring/using memory descriptors given to * us from the YAMON. - * */ #include <linux/config.h> #include <linux/init.h> @@ -83,11 +78,11 @@ mdesc[1].size = 0x000ef000; #if (CONFIG_MIPS_MALTA) - /* + /* * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the - * south bridge and PCI access always forwarded to the ISA Bus and + * south bridge and PCI access always forwarded to the ISA Bus and * BIOSCS# is always generated. - * This mean that this area can't be used as DMA memory for PCI + * This mean that this area can't be used as DMA memory for PCI * devices. */ mdesc[2].type = yamon_dontuse; @@ -148,7 +143,7 @@ size = p->size; add_memory_region(base, size, type); - p++; + p++; } } @@ -168,7 +163,7 @@ + boot_mem_map.map[i].size) { ClearPageReserved(virt_to_page(__va(addr))); set_page_count(virt_to_page(__va(addr)), 1); - free_page(__va(addr)); + free_page((unsigned long)__va(addr)); addr += PAGE_SIZE; freed += PAGE_SIZE; } diff -Nru a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S --- a/arch/mips/mips-boards/generic/mipsIRQ.S Fri Jun 27 14:19:54 2003 +++ b/arch/mips/mips-boards/generic/mipsIRQ.S Fri Jun 27 14:19:54 2003 @@ -56,6 +56,10 @@ * 6 Hardware (ignored) * 7 R4k timer (what we use) * + * Note: On the SEAD board thing are a little bit different. + * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired + * wired to UART1. + * * We handle the IRQ according to _our_ priority which is: * * Highest ---- R4k Timer @@ -74,7 +78,9 @@ CLI .set at - mfc0 s0, CP0_CAUSE # get irq mask + mfc0 s0, CP0_CAUSE # get irq bits + mfc0 s1, CP0_STATUS # get irq mask + and s0, s1 /* First we check for r4k counter/timer IRQ. */ andi a0, s0, CAUSEF_IP7 @@ -90,16 +96,23 @@ nop 1: +#if defined(CONFIG_MIPS_SEAD) beq a0, zero, 1f - nop + andi a0, s0, CAUSEF_IP3 # delay slot, check hw1 interrupt +#else + beq a0, zero, 1f # delay slot, check hw3 interrupt + andi a0, s0, CAUSEF_IP5 +#endif /* Wheee, combined hardware level zero interrupt. */ #if defined(CONFIG_MIPS_ATLAS) jal atlas_hw0_irqdispatch #elif defined(CONFIG_MIPS_MALTA) jal malta_hw0_irqdispatch +#elif defined(CONFIG_MIPS_SEAD) + jal sead_hw0_irqdispatch #else -#error "MIPS board not supported\n" +#error "MIPS board not supported\n" #endif move a0, sp # delay slot @@ -107,6 +120,24 @@ nop # delay slot 1: +#if defined(CONFIG_MIPS_SEAD) + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP5 # delay slot, check hw3 interrupt + jal sead_hw1_irqdispatch + move a0, sp # delay slot + j ret_from_irq + nop # delay slot +1: +#endif +#if defined(CONFIG_MIPS_MALTA) + beq a0, zero, 1f # check hw3 (coreHI) interrupt + nop + jal corehi_irqdispatch + move a0, sp + j ret_from_irq + nop +1: +#endif /* * Here by mistake? This is possible, what can happen is that by the * time we take the exception the IRQ pin goes low, so just leave if diff -Nru a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c --- a/arch/mips/mips-boards/generic/pci.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,267 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS boards specific PCI support. - * - */ -#include <linux/config.h> - -#ifdef CONFIG_PCI - -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> - -#include <asm/mips-boards/generic.h> -#include <asm/gt64120.h> -#ifdef CONFIG_MIPS_MALTA -#include <asm/mips-boards/malta.h> -#endif - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -static int -mips_pcibios_config_access(unsigned char access_type, struct pci_bus *bus_dev, unsigned int dev_fn, unsigned char where, u32 *data) -{ - unsigned char bus = bus_dev->number; - u32 intr; - - if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) - return -1; /* Because of a bug in the galileo (for slot 31). */ - - /* Clear cause register bits */ - GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - - if (access_type == PCI_ACCESS_WRITE) { - if (bus == 0 && dev_fn == 0) { - /* - * Galileo is acting differently than other devices. - */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } - } else { - if (bus == 0 && dev_fn == 0) { - /* - * Galileo is acting differently than other devices. - */ - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data); - } - } - - /* Check for master or target abort */ - GT_READ(GT_INTRCAUSE_OFS, intr); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) - { - /* Error occurred */ - - /* Clear bits */ - GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT) ); - - return -1; - } - - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int -mips_pcibios_read (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) -{ - u32 data = 0; - - if((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if ((size == 4) && (where & 3)) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) - return -1; - if(size == 1) - *val = (u8)(data >> ((where & 3) << 3)) & 0xff; - else if (size == 2) - *val = (u16)(data >> ((where & 3) << 3)) & 0xffff; - else if (size == 4) - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_write (struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) -{ - u32 data = 0; - - if((size == 2) && (where & 1)) - return PCIBIOS_BAD_REGISTER_NUMBER; - else if (size == 4) { - if(where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if(mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &val)) - return -1; - return PCIBIOS_SUCCESSFUL; - } - if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) - return -1; - if(size == 1) { - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - } else if (size == 2) { - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - } - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops mips_pci_ops = { - .read = mips_pcibios_read, - .write = mips_pcibios_write, -}; - -void __init pcibios_init(void) -{ -#ifdef CONFIG_MIPS_MALTA - struct pci_dev *pdev = NULL; - unsigned char reg_val; -#endif - - printk("PCI: Probing PCI hardware on host bus 0.\n"); - pci_scan_bus(0, &mips_pci_ops, NULL); - - /* - * Due to a bug in the Galileo system controller, we need to setup - * the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be fixed in - * a later revision of YAMON (the MIPS boards boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 device */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0 */ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4 */ - GT_PCI0_CFGADDR_CONFIGEN_BIT ); - - /* Perform the write */ - GT_WRITE( GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); - -#ifdef CONFIG_MIPS_MALTA - while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { - if ((pdev->vendor == PCI_VENDOR_ID_INTEL) - && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB) - && (PCI_SLOT(pdev->devfn) == 0x0a)) { - /* - * IDE Decode enable. - */ - pci_read_config_byte(pdev, 0x41, ®_val); - pci_write_config_byte(pdev, 0x41, reg_val | 0x80); - pci_read_config_byte(pdev, 0x43, ®_val); - pci_write_config_byte(pdev, 0x43, reg_val | 0x80); - } - - if ((pdev->vendor == PCI_VENDOR_ID_INTEL) - && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB_0) - && (PCI_SLOT(pdev->devfn) == 0x0a)) { - /* - * Set top of main memory accessible by ISA or DMA - * devices to 16 Mb. - */ - pci_read_config_byte(pdev, 0x69, ®_val); - pci_write_config_byte(pdev, 0x69, reg_val | 0xf0); - } - } - - /* - * Activate Floppy Controller in the SMSC FDC37M817 Super I/O - * Controller. - * This should be done in the bios/bootprom and will be fixed in - * a later revision of YAMON (the MIPS boards boot prom). - */ - /* Entering config state. */ - SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); - - /* Activate floppy controller. */ - SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); - SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); - SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); - SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); - - /* Exit config state. */ - SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); -#endif -} - -int __init -pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void __init -pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - -struct pci_fixup pcibios_fixups[] = { - { 0 } -}; - -#warning pcibios_update_resource() is now a generic implementation - please check - -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void __init pcibios_fixup_bus(struct pci_bus *b) -{ - pci_read_bridge_bases(b); -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -#endif /* CONFIG_PCI */ diff -Nru a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/printf.c --- a/arch/mips/mips-boards/generic/printf.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips/mips-boards/generic/printf.c Fri Jun 27 14:20:00 2003 @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,101 +15,84 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Putting things on the screen/serial line using YAMONs facilities. - * */ #include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/serialP.h> #include <linux/serial_reg.h> -#include <asm/system.h> +#include <linux/spinlock.h> #include <asm/io.h> -#include <asm/serial.h> +#ifdef CONFIG_MIPS_ATLAS -#ifdef CONFIG_MIPS_ATLAS -/* - * Atlas registers are memory mapped on 64-bit aligned boundaries and +#include <asm/mips-boards/atlas.h> + +/* + * Atlas registers are memory mapped on 64-bit aligned boundaries and * only word access are allowed. * When reading the UART 8 bit registers only the LSB are valid. */ -unsigned int atlas_serial_in(struct async_struct *info, int offset) +static inline unsigned int serial_in(int offset) { - return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff); + return (*(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) & 0xff); } -void atlas_serial_out(struct async_struct *info, int offset, int value) +static inline void serial_out(int offset, int value) { - *(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value; + *(volatile unsigned int *)(mips_io_port_base + ATLAS_UART_REGS_BASE + offset*8) = value; } -#define serial_in atlas_serial_in -#define serial_out atlas_serial_out +#elif defined(CONFIG_MIPS_SEAD) -#else +#include <asm/mips-boards/sead.h> -static unsigned int serial_in(struct async_struct *info, int offset) +/* + * SEAD registers are just like Atlas registers. + */ +static inline unsigned int serial_in(int offset) { - return inb(info->port + offset); + return (*(volatile unsigned int *)(mips_io_port_base + SEAD_UART0_REGS_BASE + offset*8) & 0xff); } -static void serial_out(struct async_struct *info, int offset, - int value) +static inline void serial_out(int offset, int value) { - outb(value, info->port + offset); + *(volatile unsigned int *)(mips_io_port_base + SEAD_UART0_REGS_BASE + offset*8) = value; } -#endif -static struct serial_state rs_table[] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -/* - * Hooks to fake "prom" console I/O before devices - * are fully initialized. - */ -static struct async_struct prom_port_info = {0}; - -void __init setup_prom_printf(int tty_no) { - struct serial_state *ser = &rs_table[tty_no]; +#else - prom_port_info.state = ser; - prom_port_info.magic = SERIAL_MAGIC; - prom_port_info.port = ser->port; - prom_port_info.flags = ser->flags; +static inline unsigned int serial_in(int offset) +{ + return inb(0x3f8 + offset); +} - /* No setup of UART - assume YAMON left in sane state */ +static inline void serial_out(int offset, int value) +{ + outb(value, 0x3f8 + offset); } +#endif int putPromChar(char c) { - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0) + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; - serial_out(&prom_port_info, UART_TX, c); + serial_out(UART_TX, c); return 1; } char getPromChar(void) { - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while (!(serial_in(&prom_port_info, UART_LSR) & 1)) + while (!(serial_in(UART_LSR) & 1)) ; - return(serial_in(&prom_port_info, UART_RX)); + return serial_in(UART_RX); } +static spinlock_t con_lock = SPIN_LOCK_UNLOCKED; + static char buf[1024]; void __init prom_printf(char *fmt, ...) @@ -123,8 +104,7 @@ int putPromChar(char); - /* Low level, brute force, not SMP safe... */ - save_and_cli(flags); + spin_lock_irqsave(con_lock, flags); va_start(args, fmt); l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ va_end(args); @@ -133,8 +113,9 @@ for (p = buf; p < buf_end; p++) { /* Crude cr/nl handling is better than none */ - if(*p == '\n')putPromChar('\r'); + if (*p == '\n') + putPromChar('\r'); putPromChar(*p); } - restore_flags(flags); + spin_unlock_irqrestore(con_lock, flags); } diff -Nru a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c --- a/arch/mips/mips-boards/generic/time.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips/mips-boards/generic/time.c Fri Jun 27 14:19:58 2003 @@ -23,29 +23,29 @@ * */ +#include <linux/types.h> #include <linux/config.h> #include <linux/init.h> #include <linux/kernel_stat.h> #include <linux/sched.h> #include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/time.h> +#include <linux/timex.h> +#include <linux/mc146818rtc.h> #include <asm/mipsregs.h> #include <asm/ptrace.h> +#include <asm/hardirq.h> #include <asm/div64.h> - -#include <linux/mc146818rtc.h> -#include <linux/time.h> -#include <linux/timex.h> +#include <asm/cpu.h> +#include <asm/time.h> #include <asm/mips-boards/generic.h> #include <asm/mips-boards/prom.h> -extern volatile unsigned long wall_jiffies; -static long last_rtc_update = 0; -unsigned long missed_heart_beats = 0; - -static unsigned long r4k_offset; /* Amount to increment compare reg each time */ -static unsigned long r4k_cur; /* What counter should be at next timer irq */ +static unsigned int r4k_offset; /* Amount to increment compare reg each time */ +static unsigned int r4k_cur; /* What counter should be at next timer irq */ #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) @@ -56,142 +56,37 @@ static char display_string[] = " LINUX ON MALTA "; #endif static unsigned int display_count = 0; -#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) - -static unsigned int timer_tick_count=0; +#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) +#define MIPS_CPU_TIMER_IRQ 7 -static inline void ack_r4ktimer(unsigned long newval) -{ - write_32bit_cp0_register(CP0_COMPARE, newval); -} +static unsigned int timer_tick_count=0; -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you won't notice until after reboot! - */ -static int set_rtc_mmss(unsigned long nowtime) +static inline void ack_r4ktimer(unsigned int newval) { - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; + write_c0_compare(newval); } -/* - * There are a lot of conceptually broken versions of the MIPS timer interrupt - * handler floating around. This one is rather different, but the algorithm - * is provably more robust. - */ void mips_timer_interrupt(struct pt_regs *regs) { - unsigned long flags; - int irq = 7; - unsigned long seq; - - if (r4k_offset == 0) - goto null; - - do { - kstat_cpu(0).irqs[irq]++; - do_timer(regs); - - /* Historical comment/code: - * RTC time of day s updated approx. every 11 - * minutes. Because of how the numbers work out - * we need to make absolutely sure we do this update - * within 500ms before the * next second starts, - * thus the following code. - */ - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - (tick >> 1) - && xtime.tv_usec <= 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - if ((timer_tick_count++ % HZ) == 0) { - mips_display_message(&display_string[display_count++]); - if (display_count == MAX_DISPLAY_COUNT) + if ((timer_tick_count++ % HZ) == 0) { + mips_display_message(&display_string[display_count++]); + if (display_count == MAX_DISPLAY_COUNT) display_count = 0; - } - r4k_cur += r4k_offset; - ack_r4ktimer(r4k_cur); - - } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT) - - r4k_cur) < 0x7fffffff); - - return; + } -null: - ack_r4ktimer(0); + ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs); } -/* +/* * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. + * register for each time tick. * Use the RTC to calculate offset. */ -static unsigned long __init cal_r4koff(void) +static unsigned int __init cal_r4koff(void) { - unsigned long count; unsigned int flags; local_irq_save(flags); @@ -201,21 +96,21 @@ while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); + write_c0_count(0); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - count = read_32bit_cp0_register(CP0_COUNT); + mips_counter_frequency = read_c0_count(); /* restore interrupts */ local_irq_restore(flags); - return (count / HZ); + return (mips_counter_frequency / HZ); } -static unsigned long __init get_mips_time(void) +unsigned long __init mips_rtc_get_time(void) { unsigned int year, mon, day, hour, min, sec; unsigned char save_control; @@ -235,7 +130,7 @@ if ((hour & 0xf) == 0xc) hour &= 0x80; if (hour & 0x80) - hour = (hour & 0xf) + 12; + hour = (hour & 0xf) + 12; } day = CMOS_READ(RTC_DAY_OF_MONTH); mon = CMOS_READ(RTC_MONTH); @@ -250,170 +145,41 @@ return mktime(year, mon, day, hour, min, sec); } -void __init time_init(void) +void __init mips_time_init(void) { unsigned int est_freq, flags; - /* Set Data mode - binary. */ + local_irq_save(flags); + + /* Set Data mode - binary. */ CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); printk("calculating r4koff... "); r4k_offset = cal_r4koff(); - printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + printk("%08x(%d)\n", r4k_offset, r4k_offset); + + if ((read_c0_prid() & 0xffff00) == + (PRID_COMP_MIPS | PRID_IMP_20KC)) + est_freq = r4k_offset*HZ; + else + est_freq = 2*r4k_offset*HZ; - est_freq = 2*r4k_offset*HZ; est_freq += 5000; /* round */ est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, (est_freq%1000000)*100/1000000); - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - change_cp0_status(ST0_IM, ALLINTS); - - /* Read time from the RTC chipset. */ - write_seqlock_irqsave (&xtime_lock, flags); - xtime.tv_sec = get_mips_time(); - xtime.tv_usec = 0; - write_sequnlock_irqrestore(&xtime_lock, flags); -} - -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC ((1000000 << 32) / HZ & 0xffffffff) - -/* Cycle counter value at the previous timer interrupt.. */ - -static unsigned int timerhi = 0, timerlo = 0; - -/* - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ -static unsigned long do_fast_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies=0; - unsigned long quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient=0; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; -#ifdef CONFIG_CPU_MIPS32 - if (last_jiffies != 0) { - unsigned long r0; - do_div64_32(r0, timerhi, timerlo, tmp); - do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); - cached_quotient = quotient; - } -#else - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY) - :"$1"); - cached_quotient = quotient; -#endif - } - - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. - * jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } + local_irq_restore(flags); } -void do_settimeofday(struct timeval *tv) +void __init mips_timer_setup(struct irqaction *irq) { - write_seqlock_irq (&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. - * Discover what correction gettimeofday would have done, and then - * undo it! - */ - tv->tv_usec -= do_fast_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; - - write_sequnlock_irq (&xtime_lock); + /* we are using the cpu counter for timer interrupts */ + irq->handler = no_action; /* we use our own handler */ + setup_irq(MIPS_CPU_TIMER_IRQ, irq); + + /* to generate the first timer interrupt */ + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); } diff -Nru a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile --- a/arch/mips/mips-boards/malta/Makefile Fri Jun 27 14:19:30 2003 +++ b/arch/mips/mips-boards/malta/Makefile Fri Jun 27 14:19:30 2003 @@ -7,12 +7,12 @@ # This program is free software; you can distribute it and/or modify it # under the terms of the GNU General Public License (Version 2) as # published by the Free Software Foundation. -# +# # This program is distributed in the hope it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. -# +# # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. diff -Nru a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c --- a/arch/mips/mips-boards/malta/malta_int.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/mips-boards/malta/malta_int.c Fri Jun 27 14:19:54 2003 @@ -16,65 +16,137 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * Routines for generic manipulation of the interrupts found on the MIPS + * Routines for generic manipulation of the interrupts found on the MIPS * Malta board. - * The interrupt controller is located in the South Bridge a PIIX4 device + * The interrupt controller is located in the South Bridge a PIIX4 device * with two internal 82C95 interrupt controllers. */ #include <linux/config.h> #include <linux/init.h> +#include <linux/irq.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> #include <linux/random.h> -#include <asm/irq.h> +#include <asm/i8259.h> #include <asm/io.h> +#include <asm/mips-boards/generic.h> #include <asm/mips-boards/malta.h> #include <asm/mips-boards/maltaint.h> #include <asm/mips-boards/piix4.h> +#include <asm/mips-boards/msc01_pci.h> #include <asm/gt64120.h> -#include <asm/mips-boards/generic.h> extern asmlinkage void mipsIRQ(void); +extern int mips_pcibios_iack(void); -void malta_hw0_irqdispatch(struct pt_regs *regs) +#ifdef CONFIG_KGDB +extern void breakpoint(void); +extern void set_debug_traps(void); +extern int remote_debug; +#endif + +static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED; + +static inline int get_int(int *irq) { - int irq; + unsigned long flags; - /* - * Determine highest priority pending interrupt by performing a PCI - * Interrupt Acknowledge cycle. - */ - GT_READ(GT_PCI0_IACK_OFS, irq); - irq &= 0xFF; + spin_lock_irqsave(&mips_irq_lock, flags); + + *irq = mips_pcibios_iack(); - /* - * IRQ7 is used to detect spurious interrupts. The interrupt - * acknowledge cycle returns IRQ7, if no interrupts is requested. We - * can differentiate between this situation and a "normal" IRQ7 by - * reading the ISR. + /* + * IRQ7 is used to detect spurious interrupts. + * The interrupt acknowledge cycle returns IRQ7, if no + * interrupts is requested. + * We can differentiate between this situation and a + * "Normal" IRQ7 by reading the ISR. */ - if (irq == 7) { - outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, PIIX4_ICTLR1_OCW3); - if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) - return; /* Spurious interrupt. */ + if (*irq == 7) + { + outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, + PIIX4_ICTLR1_OCW3); + if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) { + spin_unlock_irqrestore(&mips_irq_lock, flags); + printk("We got a spurious interrupt from PIIX4.\n"); + atomic_inc(&irq_err_count); + return -1; /* Spurious interrupt. */ + } } + spin_unlock_irqrestore(&mips_irq_lock, flags); + + return 0; +} + +void malta_hw0_irqdispatch(struct pt_regs *regs) +{ + int irq; + + if (get_int(&irq)) + return; /* interrupt has already been cleared */ + do_IRQ(irq, regs); } +void corehi_irqdispatch(struct pt_regs *regs) +{ + unsigned int data,datahi; + + /* Mask out corehi interrupt. */ + clear_c0_status(IE_IRQ3); + + printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); + printk("epc : %08lx\nStatus: %08lx\nCause : %08lx\nbadVaddr : %08lx\n" +, regs->cp0_epc, regs->cp0_status, regs->cp0_cause, regs->cp0_badvaddr); + switch(mips_revision_corid) { + case MIPS_REVISION_CORID_CORE_MSC: + break; + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + GT_READ(GT_INTRCAUSE_OFS, data); + printk("GT_INTRCAUSE = %08x\n", data); + GT_READ(0x70, data); + GT_READ(0x78, datahi); + printk("GT_CPU_ERR_ADDR = %0x2%08x\n", datahi,data); + break; + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + data = BONITO_INTISR; + printk("BONITO_INTISR = %08x\n", data); + data = BONITO_INTEN; + printk("BONITO_INTEN = %08x\n", data); + data = BONITO_INTPOL; + printk("BONITO_INTPOL = %08x\n", data); + data = BONITO_INTEDGE; + printk("BONITO_INTEDGE = %08x\n", data); + data = BONITO_INTSTEER; + printk("BONITO_INTSTEER = %08x\n", data); + data = BONITO_PCICMD; + printk("BONITO_PCICMD = %08x\n", data); + break; + } + + /* We die here*/ + die("CoreHi interrupt", regs); +} + void __init init_IRQ(void) { set_except_vector(0, mipsIRQ); init_generic_irq(); init_i8259_irqs(); -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB if (remote_debug) { set_debug_traps(); breakpoint(); } #endif } + + diff -Nru a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c --- a/arch/mips/mips-boards/malta/malta_setup.c Fri Jun 27 14:20:06 2003 +++ b/arch/mips/mips-boards/malta/malta_setup.c Fri Jun 27 14:20:06 2003 @@ -36,17 +36,20 @@ #include <asm/floppy.h> #endif #include <asm/dma.h> +#include <asm/time.h> +#include <asm/traps.h> +#ifdef CONFIG_VT +#include <linux/console.h> +#endif #if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) extern void console_setup(char *, int *); char serial_console[20]; #endif -#ifdef CONFIG_REMOTE_DEBUG -extern void set_debug_traps(void); +#ifdef CONFIG_KGDB extern void rs_kgdb_hook(int); -extern void breakpoint(void); -static int remote_debug = 0; +int remote_debug = 0; #endif extern struct ide_ops std_ide_ops; @@ -56,6 +59,10 @@ extern void mips_reboot_setup(void); +extern void mips_time_init(void); +extern void mips_timer_setup(struct irqaction *irq); +extern unsigned long mips_rtc_get_time(void); + struct resource standard_io_resources[] = { { "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, { "timer", 0x40, 0x5f, IORESOURCE_BUSY }, @@ -65,9 +72,14 @@ #define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) +const char *get_system_type(void) +{ + return "MIPS Malta"; +} + void __init malta_setup(void) { -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB int rs_putDebugChar(char); char rs_getDebugChar(void); extern int (*generic_putDebugChar)(char); @@ -80,7 +92,7 @@ for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, standard_io_resources+i); - /* + /* * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. */ enable_dma(4); @@ -93,7 +105,7 @@ } #endif -#ifdef CONFIG_REMOTE_DEBUG +#ifdef CONFIG_KGDB argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { int line; @@ -119,17 +131,38 @@ argptr = prom_getcmdline(); if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; - + cpu_data[0].options &= ~MIPS_CPU_FPU; + rtc_ops = &malta_rtc_ops; + #ifdef CONFIG_BLK_DEV_IDE ide_ops = &std_ide_ops; #endif #ifdef CONFIG_BLK_DEV_FD fd_ops = &std_fd_ops; #endif -#ifdef CONFIG_PC_KEYB - kbd_ops = &std_kbd_ops; +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0,0,0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + 1, /* orig-video-isVGA */ + 16 /* orig-video-points */ + }; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif #endif mips_reboot_setup(); + + board_time_init = mips_time_init; + board_timer_setup = mips_timer_setup; + rtc_get_time = mips_rtc_get_time; } diff -Nru a/arch/mips/mips-boards/sead/Makefile b/arch/mips/mips-boards/sead/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mips-boards/sead/Makefile Fri Jun 27 14:20:07 2003 @@ -0,0 +1,26 @@ +# +# Carsten Langgaard, carstenl@mips.com +# Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. +# +# ######################################################################## +# +# This program is free software; you can distribute it and/or modify it +# under the terms of the GNU General Public License (Version 2) as +# published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +# ####################################################################### +# +# Makefile for the MIPS SEAD specific kernel interface routines +# under Linux. +# + +obj-y := sead_int.o sead_setup.o sead_time.o diff -Nru a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mips-boards/sead/sead_int.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,115 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Routines for generic manipulation of the interrupts found on the MIPS + * Sead board. + * + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> + +#include <asm/mips-boards/sead.h> +#include <asm/mips-boards/seadint.h> + +extern asmlinkage void mipsIRQ(void); + +void disable_sead_irq(unsigned int irq_nr) +{ + if (irq_nr == SEADINT_UART0) + clear_c0_status(0x00000400); + else + if (irq_nr == SEADINT_UART1) + clear_c0_status(0x00000800); +} + +void enable_sead_irq(unsigned int irq_nr) +{ + if (irq_nr == SEADINT_UART0) + set_c0_status(0x00000400); + else + if (irq_nr == SEADINT_UART1) + set_c0_status(0x00000800); +} + +static unsigned int startup_sead_irq(unsigned int irq) +{ + enable_sead_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_sead_irq disable_sead_irq + +#define mask_and_ack_sead_irq disable_sead_irq + +static void end_sead_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_sead_irq(irq); +} + +static struct hw_interrupt_type sead_irq_type = { + "SEAD", + startup_sead_irq, + shutdown_sead_irq, + enable_sead_irq, + disable_sead_irq, + mask_and_ack_sead_irq, + end_sead_irq, + NULL +}; + +void sead_hw0_irqdispatch(struct pt_regs *regs) +{ + do_IRQ(0, regs); +} + +void sead_hw1_irqdispatch(struct pt_regs *regs) +{ + do_IRQ(1, regs); +} + +void __init init_IRQ(void) +{ + int i; + + /* + * Mask out all interrupt + */ + clear_c0_status(0x0000ff00); + + /* Now safe to set the exception vector. */ + set_except_vector(0, mipsIRQ); + + init_generic_irq(); + + for (i = 0; i <= SEADINT_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].lock = SPIN_LOCK_UNLOCKED; + irq_desc[i].handler = &sead_irq_type; + } +} diff -Nru a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mips-boards/sead/sead_setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,77 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * SEAD specific setup. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mc146818rtc.h> +#include <linux/ioport.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/mips-boards/generic.h> +#include <asm/mips-boards/prom.h> +#include <asm/mips-boards/seadint.h> +#include <asm/time.h> + +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) +extern void console_setup(char *, int *); +char serial_console[20]; +#endif + +extern void mips_reboot_setup(void); +extern void mips_time_init(void); +extern void mips_timer_setup(struct irqaction *irq); + +const char *get_system_type(void) +{ + return "MIPS SEAD"; +} + +void __init sead_setup(void) +{ + char *argptr; + + ioport_resource.end = 0x7fffffff; + +#ifdef CONFIG_SERIAL_CONSOLE + argptr = prom_getcmdline(); + if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { + int i = 0; + char *s = prom_getenv("modetty0"); + while(s[i] >= '0' && s[i] <= '9') + i++; + strcpy(serial_console, "ttyS0,"); + strncpy(serial_console + 6, s, i); + prom_printf("Config serial console: %s\n", serial_console); + console_setup(serial_console, NULL); + } +#endif + + argptr = prom_getcmdline(); + + if ((argptr = strstr(argptr, "nofpu")) != NULL) + cpu_data[0].options &= ~MIPS_CPU_FPU; + + board_time_init = mips_time_init; + board_timer_setup = mips_timer_setup; + + mips_reboot_setup(); +} diff -Nru a/arch/mips/mips-boards/sead/sead_time.c b/arch/mips/mips-boards/sead/sead_time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mips-boards/sead/sead_time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,142 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Setting up the clock on the MIPS boards. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/sched.h> +#include <linux/spinlock.h> + +#include <asm/mipsregs.h> +#include <asm/ptrace.h> +#include <asm/hardirq.h> +#include <asm/cpu.h> + +#include <linux/interrupt.h> +#include <linux/timex.h> + +#include <asm/mips-boards/generic.h> +#include <asm/mips-boards/prom.h> + +extern volatile unsigned long wall_jiffies; + +static unsigned long r4k_offset; /* Amount to increment compare reg each time */ +static unsigned long r4k_cur; /* What counter should be at next timer irq */ + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ5) + +static char display_string[] = " LINUX ON SEAD "; + +static unsigned int display_count = 0; +#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) + +#define MIPS_CPU_TIMER_IRQ 7 + +static unsigned int timer_tick_count=0; + +static inline void ack_r4ktimer(unsigned long newval) +{ + write_c0_compare(newval); +} + +/* + * There are a lot of conceptually broken versions of the MIPS timer interrupt + * handler floating around. This one is rather different, but the algorithm + * is provably more robust. + */ +void mips_timer_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int irq = MIPS_CPU_TIMER_IRQ; + + irq_enter(); + + do { + kstat_cpu(cpu).irqs[irq]++; + do_timer(regs); + + if ((timer_tick_count++ % HZ) == 0) { + mips_display_message(&display_string[display_count++]); + if (display_count == MAX_DISPLAY_COUNT) + display_count = 0; + } + + r4k_cur += r4k_offset; + ack_r4ktimer(r4k_cur); + + } while (((unsigned long)read_c0_count() + - r4k_cur) < 0x7fffffff); + + irq_exit(); + if (softirq_pending(cpu)) + do_softirq(); +} + +/* + * Figure out the r4k offset, the amount to increment the compare + * register for each time tick. + */ +static unsigned long __init cal_r4koff(void) +{ + /* + * The SEAD board doesn't have a real time clock, so we can't + * really calculate the timer offset. + * For now we hardwire the SEAD board frequency to 12MHz. + */ + return(6000000/HZ); +} + +void __init mips_time_init(void) +{ + unsigned int est_freq, flags; + + local_irq_save(flags); + + /* Start r4k counter. */ + write_c0_count(0); + + printk("calculating r4koff... "); + r4k_offset = cal_r4koff(); + printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); + + if ((read_c0_prid() & 0xffff00) == + (PRID_COMP_MIPS | PRID_IMP_20KC)) + est_freq = r4k_offset*HZ; + else + est_freq = 2*r4k_offset*HZ; + + est_freq += 5000; /* round */ + est_freq -= est_freq%10000; + printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, + (est_freq%1000000)*100/1000000); + + local_irq_restore(flags); +} + +void __init mips_timer_setup(struct irqaction *irq) +{ + /* we are using the cpu counter for timer interrupts */ + irq->handler = no_action; /* we use our own handler */ + setup_irq(MIPS_CPU_TIMER_IRQ, irq); + + /* to generate the first timer interrupt */ + r4k_cur = (read_c0_count() + r4k_offset); + write_c0_compare(r4k_cur); + set_c0_status(ALLINTS); +} diff -Nru a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile --- a/arch/mips/mm/Makefile Fri Jun 27 14:19:58 2003 +++ b/arch/mips/mm/Makefile Fri Jun 27 14:19:58 2003 @@ -2,17 +2,29 @@ # Makefile for the Linux/MIPS-specific parts of the memory manager. # -obj-y += extable.o init.o ioremap.o fault.o loadmmu.o +obj-y += cache.o extable.o init.o ioremap.o fault.o \ + pgtable.o loadmmu.o -obj-$(CONFIG_CPU_R3000) += r2300.o -obj-$(CONFIG_CPU_R4300) += r4xx0.o -obj-$(CONFIG_CPU_R4X00) += r4xx0.o -obj-$(CONFIG_CPU_VR41XX) += r4xx0.o -obj-$(CONFIG_CPU_R5000) += r4xx0.o -obj-$(CONFIG_CPU_NEVADA) += r4xx0.o -obj-$(CONFIG_CPU_R5432) += r5432.o -obj-$(CONFIG_CPU_RM7000) += rm7k.o -obj-$(CONFIG_CPU_MIPS32) += mips32.o -obj-$(CONFIG_CPU_MIPS64) += mips32.o -obj-$(CONFIG_SGI_IP22) += umap.o -obj-$(CONFIG_BAGET_MIPS) += umap.o +obj-$(CONFIG_HIGHMEM) += highmem.o + +obj-$(CONFIG_CPU_R3000) += pg-r3k.o c-r3k.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX39XX) += pg-r3k.o c-tx39.o tlb-r3k.o tlbex-r3k.o +obj-$(CONFIG_CPU_TX49XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R4300) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R4X00) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_VR41XX) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_NEVADA) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R5432) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_RM7000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_R10000) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_MIPS32) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_MIPS64) += pg-r4k.o c-r4k.o tlb-r4k.o tlbex-r4k.o +obj-$(CONFIG_CPU_SB1) += c-sb1.o cex-sb1.o cerr-sb1.o pg-sb1.o \ + tlb-sb1.o tlbex-r4k.o + +obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/mm/andes.c b/arch/mips/mm/andes.c --- a/arch/mips/mm/andes.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,196 +0,0 @@ -/* - * andes.c: MMU and cache operations for the R10000 (ANDES). - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/sgialib.h> -#include <asm/mmu_context.h> - -/* page functions */ -void andes_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%2\n" - "1:\tsw\t$0,(%0)\n\t" - "sw\t$0,4(%0)\n\t" - "sw\t$0,8(%0)\n\t" - "sw\t$0,12(%0)\n\t" - "addiu\t%0,32\n\t" - "sw\t$0,-16(%0)\n\t" - "sw\t$0,-12(%0)\n\t" - "sw\t$0,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t$0,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE) - :"$1","memory"); -} - -static void andes_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%8\n" - "1:\tlw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE)); -} - -/* Cache operations. XXX Write these dave... */ -static inline void andes_flush_cache_all(void) -{ - /* XXX */ -} - -static void andes_flush_cache_mm(struct mm_struct *mm) -{ - /* XXX */ -} - -static void andes_flush_cache_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - /* XXX */ -} - -static void andes_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) -{ - /* XXX */ -} - -static void andes_flush_page_to_ram(struct page * page) -{ - /* XXX */ -} - -static void __andes_flush_icache_range(unsigned long start, unsigned long end) -{ - /* XXX */ -} - -static void andes_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - /* XXX */ -} - -static void andes_flush_cache_sigtramp(unsigned long page) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* TLB operations. XXX Write these dave... */ -void flush_tlb_all(void) -{ - /* XXX */ -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - /* XXX */ -} - -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - /* XXX */ -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - /* XXX */ -} - -void pgd_init(unsigned long page) -{ -} - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - /* XXX */ -} - -void __init ld_mmu_andes(void) -{ - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - - _flush_cache_all = andes_flush_cache_all; - ___flush_cache_all = andes_flush_cache_all; - _flush_cache_mm = andes_flush_cache_mm; - _flush_cache_range = andes_flush_cache_range; - _flush_cache_page = andes_flush_cache_page; - _flush_cache_sigtramp = andes_flush_cache_sigtramp; - _flush_page_to_ram = andes_flush_page_to_ram; - _flush_icache_page = andes_flush_icache_page; - _flush_icache_range = andes_flush_icache_range; - - write_32bit_cp0_register(CP0_FRAMEMASK, 0); - - flush_cache_all(); - flush_tlb_all(); - - /* - * The R10k might even work for Linux/MIPS - but we're paranoid - * and refuse to run until this is tested on real silicon - */ - panic("CPU too expensive - making holiday in the ANDES!"); -} diff -Nru a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/c-r3k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,344 @@ +/* + * r2300.c: R2000 and R3000 specific mmu/cache code. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * with a lot of changes to make this thing work for R3000s + * Tx39XX R4k style caches added. HK + * Copyright (C) 1998, 1999, 2000 Harald Koerfgen + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 2001 Maciej W. Rozycki + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/mmu_context.h> +#include <asm/system.h> +#include <asm/isadep.h> +#include <asm/io.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> + +void r3k_clear_page(void * page); +void r3k_copy_page(void * to, void * from); + +static unsigned long icache_size, dcache_size; /* Size in bytes */ +static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ + +#undef DEBUG_CACHE + +unsigned long __init r3k_cache_size(unsigned long ca_flags) +{ + unsigned long flags, status, dummy, size; + volatile unsigned long *p; + + p = (volatile unsigned long *) KSEG0; + + flags = read_c0_status(); + + /* isolate cache space */ + write_c0_status((ca_flags|flags)&~ST0_IEC); + + *p = 0xa5a55a5a; + dummy = *p; + status = read_c0_status(); + + if (dummy != 0xa5a55a5a || (status & ST0_CM)) { + size = 0; + } else { + for (size = 128; size <= 0x40000; size <<= 1) + *(p + size) = 0; + *p = -1; + for (size = 128; + (size <= 0x40000) && (*(p + size) == 0); + size <<= 1) + ; + if (size > 0x40000) + size = 0; + } + + write_c0_status(flags); + + return size * sizeof(*p); +} + +unsigned long __init r3k_cache_lsize(unsigned long ca_flags) +{ + unsigned long flags, status, lsize, i; + volatile unsigned long *p; + + p = (volatile unsigned long *) KSEG0; + + flags = read_c0_status(); + + /* isolate cache space */ + write_c0_status((ca_flags|flags)&~ST0_IEC); + + for (i = 0; i < 128; i++) + *(p + i) = 0; + *(volatile unsigned char *)p = 0; + for (lsize = 1; lsize < 128; lsize <<= 1) { + *(p + lsize); + status = read_c0_status(); + if (!(status & ST0_CM)) + break; + } + for (i = 0; i < 128; i += lsize) + *(volatile unsigned char *)(p + i) = 0; + + write_c0_status(flags); + + return lsize * sizeof(*p); +} + +static void __init r3k_probe_cache(void) +{ + dcache_size = r3k_cache_size(ST0_ISC); + if (dcache_size) + dcache_lsize = r3k_cache_lsize(ST0_ISC); + + icache_size = r3k_cache_size(ST0_ISC|ST0_SWC); + if (icache_size) + icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC); +} + +static void r3k_flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long size, i, flags; + volatile unsigned char *p; + + size = end - start; + if (size > icache_size || KSEGX(start) != KSEG0) { + start = KSEG0; + size = icache_size; + } + p = (char *)start; + + flags = read_c0_status(); + + /* isolate cache space */ + write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); + + for (i = 0; i < size; i += 0x080) { + asm ( "sb\t$0, 0x000(%0)\n\t" + "sb\t$0, 0x004(%0)\n\t" + "sb\t$0, 0x008(%0)\n\t" + "sb\t$0, 0x00c(%0)\n\t" + "sb\t$0, 0x010(%0)\n\t" + "sb\t$0, 0x014(%0)\n\t" + "sb\t$0, 0x018(%0)\n\t" + "sb\t$0, 0x01c(%0)\n\t" + "sb\t$0, 0x020(%0)\n\t" + "sb\t$0, 0x024(%0)\n\t" + "sb\t$0, 0x028(%0)\n\t" + "sb\t$0, 0x02c(%0)\n\t" + "sb\t$0, 0x030(%0)\n\t" + "sb\t$0, 0x034(%0)\n\t" + "sb\t$0, 0x038(%0)\n\t" + "sb\t$0, 0x03c(%0)\n\t" + "sb\t$0, 0x040(%0)\n\t" + "sb\t$0, 0x044(%0)\n\t" + "sb\t$0, 0x048(%0)\n\t" + "sb\t$0, 0x04c(%0)\n\t" + "sb\t$0, 0x050(%0)\n\t" + "sb\t$0, 0x054(%0)\n\t" + "sb\t$0, 0x058(%0)\n\t" + "sb\t$0, 0x05c(%0)\n\t" + "sb\t$0, 0x060(%0)\n\t" + "sb\t$0, 0x064(%0)\n\t" + "sb\t$0, 0x068(%0)\n\t" + "sb\t$0, 0x06c(%0)\n\t" + "sb\t$0, 0x070(%0)\n\t" + "sb\t$0, 0x074(%0)\n\t" + "sb\t$0, 0x078(%0)\n\t" + "sb\t$0, 0x07c(%0)\n\t" + : : "r" (p) ); + p += 0x080; + } + + write_c0_status(flags); +} + +static void r3k_flush_dcache_range(unsigned long start, unsigned long end) +{ + unsigned long size, i, flags; + volatile unsigned char *p; + + size = end - start; + if (size > dcache_size || KSEGX(start) != KSEG0) { + start = KSEG0; + size = dcache_size; + } + p = (char *)start; + + flags = read_c0_status(); + + /* isolate cache space */ + write_c0_status((ST0_ISC|flags)&~ST0_IEC); + + for (i = 0; i < size; i += 0x080) { + asm ( "sb\t$0, 0x000(%0)\n\t" + "sb\t$0, 0x004(%0)\n\t" + "sb\t$0, 0x008(%0)\n\t" + "sb\t$0, 0x00c(%0)\n\t" + "sb\t$0, 0x010(%0)\n\t" + "sb\t$0, 0x014(%0)\n\t" + "sb\t$0, 0x018(%0)\n\t" + "sb\t$0, 0x01c(%0)\n\t" + "sb\t$0, 0x020(%0)\n\t" + "sb\t$0, 0x024(%0)\n\t" + "sb\t$0, 0x028(%0)\n\t" + "sb\t$0, 0x02c(%0)\n\t" + "sb\t$0, 0x030(%0)\n\t" + "sb\t$0, 0x034(%0)\n\t" + "sb\t$0, 0x038(%0)\n\t" + "sb\t$0, 0x03c(%0)\n\t" + "sb\t$0, 0x040(%0)\n\t" + "sb\t$0, 0x044(%0)\n\t" + "sb\t$0, 0x048(%0)\n\t" + "sb\t$0, 0x04c(%0)\n\t" + "sb\t$0, 0x050(%0)\n\t" + "sb\t$0, 0x054(%0)\n\t" + "sb\t$0, 0x058(%0)\n\t" + "sb\t$0, 0x05c(%0)\n\t" + "sb\t$0, 0x060(%0)\n\t" + "sb\t$0, 0x064(%0)\n\t" + "sb\t$0, 0x068(%0)\n\t" + "sb\t$0, 0x06c(%0)\n\t" + "sb\t$0, 0x070(%0)\n\t" + "sb\t$0, 0x074(%0)\n\t" + "sb\t$0, 0x078(%0)\n\t" + "sb\t$0, 0x07c(%0)\n\t" + : : "r" (p) ); + p += 0x080; + } + + write_c0_status(flags); +} + +static inline unsigned long get_phys_page (unsigned long addr, + struct mm_struct *mm) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + unsigned long physpage; + + pgd = pgd_offset(mm, addr); + pmd = pmd_offset(pgd, addr); + pte = pte_offset(pmd, addr); + + if ((physpage = pte_val(*pte)) & _PAGE_VALID) + return KSEG0ADDR(physpage & PAGE_MASK); + + return 0; +} + +static inline void r3k_flush_cache_all(void) +{ +} + +static inline void r3k___flush_cache_all(void) +{ + r3k_flush_icache_range(KSEG0, KSEG0 + icache_size); +} + +static void r3k_flush_cache_mm(struct mm_struct *mm) +{ +} + +static void r3k_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ +} + +static void r3k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) +{ +} + +static void r3k_flush_data_cache_page(unsigned long addr) +{ +} + +static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long physpage; + + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + if (!(vma->vm_flags & VM_EXEC)) + return; + +#ifdef DEBUG_CACHE + printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page); +#endif + + physpage = (unsigned long) page_address(page); + if (physpage) + r3k_flush_icache_range(physpage, physpage + PAGE_SIZE); +} + +static void r3k_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long flags; + +#ifdef DEBUG_CACHE + printk("csigtramp[%08lx]", addr); +#endif + + flags = read_c0_status(); + + write_c0_status(flags&~ST0_IEC); + + /* Fill the TLB to avoid an exception with caches isolated. */ + asm ( "lw\t$0, 0x000(%0)\n\t" + "lw\t$0, 0x004(%0)\n\t" + : : "r" (addr) ); + + write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); + + asm ( "sb\t$0, 0x000(%0)\n\t" + "sb\t$0, 0x004(%0)\n\t" + : : "r" (addr) ); + + write_c0_status(flags); +} + +static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) +{ + iob(); + r3k_flush_dcache_range(start, start + size); +} + +void __init ld_mmu_r23000(void) +{ + _clear_page = r3k_clear_page; + _copy_page = r3k_copy_page; + + r3k_probe_cache(); + + flush_cache_all = r3k_flush_cache_all; + __flush_cache_all = r3k___flush_cache_all; + flush_cache_mm = r3k_flush_cache_mm; + flush_cache_range = r3k_flush_cache_range; + flush_cache_page = r3k_flush_cache_page; + flush_icache_page = r3k_flush_icache_page; + flush_icache_range = r3k_flush_icache_range; + + flush_cache_sigtramp = r3k_flush_cache_sigtramp; + flush_data_cache_page = r3k_flush_data_cache_page; + + _dma_cache_wback_inv = r3k_dma_cache_wback_inv; + + printk("Primary instruction cache %ldkB, linesize %ld bytes.\n", + icache_size >> 10, icache_lsize); + printk("Primary data cache %ldkB, linesize %ld bytes.\n", + dcache_size >> 10, dcache_lsize); +} diff -Nru a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/c-r4k.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,1161 @@ +/* + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/bitops.h> + +#include <asm/bcache.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/mmu_context.h> +#include <asm/war.h> + +/* Primary cache parameters. */ +static unsigned long icache_size, dcache_size, scache_size; +unsigned long icache_way_size, dcache_way_size, scache_way_size; +static unsigned long scache_size; + +#include <asm/cacheops.h> +#include <asm/r4kcache.h> + +extern void andes_clear_page(void * page); +extern void r4k_clear_page32_d16(void * page); +extern void r4k_clear_page32_d32(void * page); +extern void r4k_clear_page_d16(void * page); +extern void r4k_clear_page_d32(void * page); +extern void r4k_clear_page_r4600_v1(void * page); +extern void r4k_clear_page_r4600_v2(void * page); +extern void r4k_clear_page_s16(void * page); +extern void r4k_clear_page_s32(void * page); +extern void r4k_clear_page_s64(void * page); +extern void r4k_clear_page_s128(void * page); +extern void andes_copy_page(void * to, void * from); +extern void r4k_copy_page_d16(void * to, void * from); +extern void r4k_copy_page_d32(void * to, void * from); +extern void r4k_copy_page_r4600_v1(void * to, void * from); +extern void r4k_copy_page_r4600_v2(void * to, void * from); +extern void r4k_copy_page_s16(void * to, void * from); +extern void r4k_copy_page_s32(void * to, void * from); +extern void r4k_copy_page_s64(void * to, void * from); +extern void r4k_copy_page_s128(void * to, void * from); + +/* + * Dummy cache handling routines for machines without boardcaches + */ +static void no_sc_noop(void) {} + +static struct bcache_ops no_sc_ops = { + .bc_enable = (void *)no_sc_noop, + .bc_disable = (void *)no_sc_noop, + .bc_wback_inv = (void *)no_sc_noop, + .bc_inv = (void *)no_sc_noop +}; + +struct bcache_ops *bcops = &no_sc_ops; + +#define R4600_HIT_CACHEOP_WAR_IMPL \ +do { \ + if (R4600_V2_HIT_CACHEOP_WAR && \ + (read_c0_prid() & 0xfff0) == 0x2020) { /* R4600 V2.0 */\ + *(volatile unsigned long *)KSEG1; \ + } \ + if (R4600_V1_HIT_CACHEOP_WAR) \ + __asm__ __volatile__("nop;nop;nop;nop"); \ +} while (0) + +static void r4k_blast_dcache_page(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page(addr); + return; + +dc_32: + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache_page_indexed(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page_indexed(addr); + return; + +dc_32: + blast_dcache32_page_indexed(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache(void) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16(); + return; + +dc_32: + blast_dcache32(); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_icache_page(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page(addr); + return; + +ic_32: + blast_icache32_page(addr); + return; + +ic_64: + blast_icache64_page(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache_page_indexed(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page_indexed(addr); + return; + +ic_32: + blast_icache32_page_indexed(addr); + return; + +ic_64: + blast_icache64_page_indexed(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache(void) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16(); + return; + +ic_32: + blast_icache32(); + return; + +ic_64: + blast_icache64(); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_scache_page(unsigned long addr) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16_page(addr); + return; + +sc_32: + blast_scache32_page(addr); + return; + +sc_64: + blast_scache64_page(addr); + return; + +sc_128: + blast_scache128_page(addr); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_blast_scache(void) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16(); + return; + +sc_32: + blast_scache32(); + return; + +sc_64: + blast_scache64(); + return; + +sc_128: + blast_scache128(); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); +} + +static void r4k___flush_cache_all(void) +{ + r4k_blast_dcache(); + r4k_blast_icache(); + + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R10000: + case CPU_R12000: + r4k_blast_scache(); + } +} + +static void r4k_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) { + r4k_blast_dcache(); + if (vma->vm_flags & VM_EXEC) + r4k_blast_icache(); + } +} + +static void r4k_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) + return; + + if (!cpu_context(smp_processor_id(), mm)) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); + + /* + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... + */ + if (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || + current_cpu_data.cputype == CPU_R4400MC) + r4k_blast_scache(); +} + +static void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) +{ + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + page &= PAGE_MASK; + pgdp = pgd_offset(mm, page); + pmdp = pmd_offset(pgdp, page); + ptep = pte_offset(pmdp, page); + + /* + * If the page isn't marked valid, the page cannot possibly be + * in the cache. + */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + /* + * Doing flushes for another ASID than the current one is + * too difficult since stupid R4k caches do a TLB translation + * for every cache flush operation. So we do indexed flushes + * in that case, which doesn't overly flush the cache too much. + */ + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page(page); + if (exec) + r4k_blast_icache_page(page); + + return; + } + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page_indexed(page); + if (exec) { + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache_page_indexed(page); + } +} + +static void r4k_flush_data_cache_page(unsigned long addr) +{ + r4k_blast_dcache_page(addr); +} + +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + } + + if (end - start > icache_size) + r4k_blast_icache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } +} + +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); +} + +#ifdef CONFIG_NONCOHERENT_IO + +static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_wback_inv(addr, size); +} + +static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_inv(addr, size); +} +#endif /* CONFIG_NONCOHERENT_IO */ + +/* + * While we're protected against bad userland addresses we don't care + * very much about what happens in that case. Usually a segmentation + * fault will dump the process later on anyway ... + */ +static void r4k_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); +} + +static void r4k_flush_icache_all(void) +{ + if (cpu_has_vtag_icache) + r4k_blast_icache(); +} + +static inline void rm7k_erratum31(void) +{ + const unsigned long ic_lsize = 32; + unsigned long addr; + + /* RM7000 erratum #31. The icache is screwed at startup. */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + "cache\t%2, 0(%0)\n\t" + "cache\t%2, 0x1000(%0)\n\t" + "cache\t%2, 0x2000(%0)\n\t" + "cache\t%2, 0x3000(%0)\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + ".set\tmips0\n\t" + ".set\treorder\n\t" + : + : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); + } +} + +static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way" +}; + +static void __init probe_pcache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + unsigned int prid = read_c0_prid(); + unsigned long config1; + unsigned int lsize; + + switch (current_cpu_data.cputype) { + case CPU_R4600: /* QED style two way caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit= ffs(dcache_size/2) - 1; + break; + + case CPU_R5432: + case CPU_R5500: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_TX49XX: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + break; + + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_R10000: + case CPU_R12000: + icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26)); + c->dcache.linesz = 32; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_VR4131: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = ffs(dcache_size/2) - 1; + break; + + case CPU_VR41XX: + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_RM7000: + rm7k_erratum31(); + + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + break; + + default: + if (!(config & MIPS_CONF_M)) + panic("Don't know how to probe P-caches on this cpu."); + + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + break; + } + + /* + * Processor configuration sanity check for the R4000SC erratum + * #5. With page sizes larger than 32kB there is no possibility + * to get a VCE exception anymore so we don't care about this + * misconfiguration. The case is rather theoretical anyway; + * presumably no vendor is shipping his hardware in the "bad" + * configuration. + */ + if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && + !(config & CONF_SC) && c->icache.linesz != 16 && + PAGE_SIZE <= 0x8000) + panic("Improper R4000SC processor configuration detected"); + + /* compute a couple of other cache variables */ + icache_way_size = icache_size / c->icache.ways; + dcache_way_size = dcache_size / c->dcache.ways; + + c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); + c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + if (current_cpu_data.cputype != CPU_R10000 && + current_cpu_data.cputype != CPU_R12000) + if (dcache_way_size > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + switch (c->cputype) { + case CPU_20KC: + /* + * Some older 20Kc chips doesn't have the 'VI' bit in + * the config register. + */ + c->icache.flags |= MIPS_CACHE_VTAG; + break; + + case CPU_AU1500: + c->icache.flags |= MIPS_CACHE_IC_F_DC; + break; + } + + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", + icache_size >> 10, + cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + way_string[c->icache.ways], c->icache.linesz); + + printk("Primary data cache %ldkB %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); +} + +/* + * If you even _breathe_ on this function, look at the gcc output and make sure + * it does not pop things on and off the stack for the cache sizing loop that + * executes in KSEG1 space or else you will crash and burn badly. You have + * been warned. + */ +static int __init probe_scache(void) +{ + extern unsigned long stext; + unsigned long flags, addr, begin, end, pow2; + unsigned int config = read_c0_config(); + struct cpuinfo_mips *c = ¤t_cpu_data; + int tmp; + + if (config & CONF_SC) + return 0; + + begin = (unsigned long) &stext; + begin &= ~((4 * 1024 * 1024) - 1); + end = begin + (4 * 1024 * 1024); + + /* + * This is such a bitch, you'd think they would make it easy to do + * this. Away you daemons of stupidity! + */ + local_irq_save(flags); + + /* Fill each size-multiple cache line with a valid tag. */ + pow2 = (64 * 1024); + for (addr = begin; addr < end; addr = (begin + pow2)) { + unsigned long *p = (unsigned long *) addr; + __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ + pow2 <<= 1; + } + + /* Load first line with zero (therefore invalid) tag. */ + write_c0_taglo(0); + write_c0_taghi(0); + __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ + cache_op(Index_Store_Tag_I, begin); + cache_op(Index_Store_Tag_D, begin); + cache_op(Index_Store_Tag_SD, begin); + + /* Now search for the wrap around point. */ + pow2 = (128 * 1024); + tmp = 0; + for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { + cache_op(Index_Load_Tag_SD, addr); + __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ + if (!read_c0_taglo()) + break; + pow2 <<= 1; + } + local_irq_restore(flags); + addr -= begin; + + c = ¤t_cpu_data; + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + + return 1; +} + +static void __init setup_noscache_funcs(void) +{ + unsigned int prid; + + switch (current_cpu_data.dcache.linesz) { + case 16: + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d16; + else + _clear_page = r4k_clear_page32_d16; + _copy_page = r4k_copy_page_d16; + + break; + case 32: + prid = read_c0_prid() & 0xfff0; + if (prid == 0x2010) { /* R4600 V1.7 */ + _clear_page = r4k_clear_page_r4600_v1; + _copy_page = r4k_copy_page_r4600_v1; + } else if (prid == 0x2020) { /* R4600 V2.0 */ + _clear_page = r4k_clear_page_r4600_v2; + _copy_page = r4k_copy_page_r4600_v2; + } else { + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d32; + else + _clear_page = r4k_clear_page32_d32; + _copy_page = r4k_copy_page_d32; + } + break; + } +} + +static void __init setup_scache_funcs(void) +{ + if (current_cpu_data.dcache.linesz > current_cpu_data.scache.linesz) + panic("Invalid primary cache configuration detected"); + + if (current_cpu_data.cputype == CPU_R10000 || + current_cpu_data.cputype == CPU_R12000) { + _clear_page = andes_clear_page; + _copy_page = andes_copy_page; + return; + } + + switch (current_cpu_data.scache.linesz) { + case 16: + _clear_page = r4k_clear_page_s16; + _copy_page = r4k_copy_page_s16; + break; + case 32: + _clear_page = r4k_clear_page_s32; + _copy_page = r4k_copy_page_s32; + break; + case 64: + _clear_page = r4k_clear_page_s64; + _copy_page = r4k_copy_page_s64; + break; + case 128: + _clear_page = r4k_clear_page_s128; + _copy_page = r4k_copy_page_s128; + break; + } +} + +typedef int (*probe_func_t)(unsigned long); +extern int r5k_sc_init(void); +extern int rm7k_sc_init(void); + +static void __init setup_scache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + probe_func_t probe_scache_kseg1; + int sc_present = 0; + + /* + * Do the probing thing on R4000SC and R4400SC processors. Other + * processors don't have a S-cache that would be relevant to the + * Linux memory managment. + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); + sc_present = probe_scache_kseg1(config); + break; + + case CPU_R10000: + case CPU_R12000: + scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16); + c->scache.linesz = 64 << ((config >> 13) & 1); + c->scache.ways = 2; + c->scache.waybit= 0; + sc_present = 1; + break; + + case CPU_R5000: + case CPU_NEVADA: + setup_noscache_funcs(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); +#endif + return; + + case CPU_RM7000: + setup_noscache_funcs(); +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + + default: + sc_present = 0; + } + + if (!sc_present) { + setup_noscache_funcs(); + return; + } + + if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32 || + current_cpu_data.isa_level == MIPS_CPU_ISA_M64) && + !(current_cpu_data.scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); + + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + current_cpu_data.options |= MIPS_CPU_SUBSET_CACHES; + setup_scache_funcs(); +} + +static inline void coherency_setup(void) +{ + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + + /* + * c0_status.cu=0 specifies that updates by the sc instruction use + * the coherency mode specified by the TLB; 1 means cachable + * coherent update on write will be used. Not all processors have + * this bit and; some wire it to zero, others like Toshiba had the + * silly idea of putting something else there ... + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + clear_c0_config(CONF_CU); + break; + } + +} + +void __init ld_mmu_r4xx0(void) +{ + extern char except_vec2_generic; + + /* Default cache error handler for R4000 and R5000 family */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + + probe_pcache(); + setup_scache(); + coherency_setup(); + + if (current_cpu_data.dcache.sets * + current_cpu_data.dcache.ways > PAGE_SIZE) + current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES; + + /* + * Some MIPS32 and MIPS64 processors have physically indexed caches. + * This code supports virtually indexed processors and will be + * unnecessarily unefficient on physically indexed processors. + */ + shm_align_mask = max_t(unsigned long, + current_cpu_data.dcache.sets * current_cpu_data.dcache.linesz - 1, + PAGE_SIZE - 1); + + flush_cache_all = r4k_flush_cache_all; + __flush_cache_all = r4k___flush_cache_all; + flush_cache_mm = r4k_flush_cache_mm; + flush_cache_page = r4k_flush_cache_page; + flush_icache_page = r4k_flush_icache_page; + flush_cache_range = r4k_flush_cache_range; + + flush_cache_sigtramp = r4k_flush_cache_sigtramp; + flush_icache_all = r4k_flush_icache_all; + flush_data_cache_page = r4k_flush_data_cache_page; + flush_icache_range = r4k_flush_icache_range; + +#ifdef CONFIG_NONCOHERENT_IO + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; +#endif + + __flush_cache_all(); +} diff -Nru a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/c-sb1.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,611 @@ +/* + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <asm/mmu_context.h> +#include <asm/bootinfo.h> +#include <asm/cacheops.h> +#include <asm/cpu.h> +#include <asm/uaccess.h> + +extern void sb1_clear_page(void * page); +extern void sb1_copy_page(void * to, void * from); + +/* These are probed at ld_mmu time */ +static unsigned long icache_size; +static unsigned long dcache_size; + +static unsigned long icache_line_size; +static unsigned long dcache_line_size; + +static unsigned int icache_index_mask; +static unsigned int dcache_index_mask; + +static unsigned long icache_assoc; +static unsigned long dcache_assoc; + +static unsigned int icache_sets; +static unsigned int dcache_sets; + +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; + +void pgd_init(unsigned long page) +{ + unsigned long *p = (unsigned long *) page; + int i; + + for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { + p[i + 0] = (unsigned long) invalid_pte_table; + p[i + 1] = (unsigned long) invalid_pte_table; + p[i + 2] = (unsigned long) invalid_pte_table; + p[i + 3] = (unsigned long) invalid_pte_table; + p[i + 4] = (unsigned long) invalid_pte_table; + p[i + 5] = (unsigned long) invalid_pte_table; + p[i + 6] = (unsigned long) invalid_pte_table; + p[i + 7] = (unsigned long) invalid_pte_table; + } +} + +/* + * The dcache is fully coherent to the system, with one + * big caveat: the instruction stream. In other words, + * if we miss in the icache, and have dirty data in the + * L1 dcache, then we'll go out to memory (or the L2) and + * get the not-as-recent data. + * + * So the only time we have to flush the dcache is when + * we're flushing the icache. Since the L2 is fully + * coherent to everything, including I/O, we never have + * to flush it + */ + +/* + * Writeback and invalidate the entire dcache + */ +static inline void __sb1_writeback_inv_dcache_all(void) +{ + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " addiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " addu $1, $1, %0 \n" /* Next address */ + ".set pop \n" + : + : "r" (dcache_line_size), "r" (dcache_sets), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. The addresses are + * virtual, and since we're using index ops and bit 12 is part of both + * the virtual frame and physical index, we have to clear both sets + * (bit 12 set and cleared). + */ +static inline void __sb1_writeback_inv_dcache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " xori $1, $1, 1<<12 \n" /* flip bit 12 (va/pa alias) */ + " cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. With physical + * addresseses, we don't have to worry about possible bit 12 aliasing. + * XXXKW is it worth turning on KX and using hit ops with xkphys? + */ +static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + + +/* + * Invalidate the entire icache + */ +static inline void __sb1_flush_icache_all(void) +{ + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " addiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " addu $1, $1, %0 \n" /* Next address */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (icache_line_size), "r" (icache_sets), + "i" (Index_Invalidate_I)); +} + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr) +{ + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + + /* + * Bumping the ASID is probably cheaper than the flush ... + */ + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); +} + +#ifdef CONFIG_SMP +struct flush_cache_page_args { + struct vm_area_struct *vma; + unsigned long addr; +}; + +static void sb1_flush_cache_page_ipi(void *info) +{ + struct flush_cache_page_args *args = info; + + local_sb1_flush_cache_page(args->vma, args->addr); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + struct flush_cache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.addr = addr; + on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); +} +#else +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +asm("sb1_flush_cache_page = local_sb1_flush_cache_page"); +#endif + +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-inval this address */ + " addu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (start & ~(icache_line_size - 1)), + "r" ((end + icache_line_size - 1) & ~(icache_line_size - 1)), + "r" (icache_line_size), + "r" (icache_index_mask), + "i" (Index_Invalidate_I)); +} + + +/* + * Invalidate all caches on this CPU + */ +static void local_sb1___flush_cache_all(void) +{ + __sb1_writeback_inv_dcache_all(); + __sb1_flush_icache_all(); +} + +#ifdef CONFIG_SMP +extern void sb1___flush_cache_all_ipi(void *ignored); +asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all"); + +static void sb1___flush_cache_all(void) +{ + on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); +} +#else +extern void sb1___flush_cache_all(void); +asm("sb1___flush_cache_all = local_sb1___flush_cache_all"); +#endif + +/* + * When flushing a range in the icache, we have to first writeback + * the dcache for the same range, so new ifetches will see any + * data that was dirty in the dcache. + * + * The start/end arguments are Kseg addresses (possibly mapped Kseg). + */ + +static void local_sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + /* Just wb-inv the whole dcache if the range is big enough */ + if ((end - start) > dcache_range_cutoff) + __sb1_writeback_inv_dcache_all(); + else + __sb1_writeback_inv_dcache_range(start, end); + + /* Just flush the whole icache if the range is big enough */ + if ((end - start) > icache_range_cutoff) + __sb1_flush_icache_all(); + else + __sb1_flush_icache_range(start, end); +} + +#ifdef CONFIG_SMP +struct flush_icache_range_args { + unsigned long start; + unsigned long end; +}; + +static void sb1_flush_icache_range_ipi(void *info) +{ + struct flush_icache_range_args *args = info; + + local_sb1_flush_icache_range(args->start, args->end); +} + +void sb1_flush_icache_range(unsigned long start, unsigned long end) +{ + struct flush_icache_range_args args; + + args.start = start; + args.end = end; + on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); +} +#else +void sb1_flush_icache_range(unsigned long start, unsigned long end); +asm("sb1_flush_icache_range = local_sb1_flush_icache_range"); +#endif + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); + /* + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) + */ + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } +} + +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) +{ + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); +} +#else +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page); +asm("sb1_flush_icache_page = local_sb1_flush_icache_page"); +#endif + +/* + * A signal trampoline must fit into a single cacheline. + */ +static void local_sb1_flush_cache_sigtramp(unsigned long addr) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " cache %2, (0<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (1<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (2<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (3<<13)(%0) \n" /* Index-inval this address */ + " xori $1, %0, 1<<12 \n" /* Flip index bit 12 */ + " cache %2, (0<<13)($1) \n" /* Index-inval this address */ + " cache %2, (1<<13)($1) \n" /* Index-inval this address */ + " cache %2, (2<<13)($1) \n" /* Index-inval this address */ + " cache %2, (3<<13)($1) \n" /* Index-inval this address */ + " cache %3, (0<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (1<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (2<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (3<<13)(%1) \n" /* Index-inval this address */ + " bnezl $0, 1f \n" /* Force mispredict */ + " nop \n" + "1: \n" + " .set pop \n" + : + : "r" (addr & dcache_index_mask), "r" (addr & icache_index_mask), + "i" (Index_Writeback_Inv_D), "i" (Index_Invalidate_I)); +} + +#ifdef CONFIG_SMP +static void sb1_flush_cache_sigtramp_ipi(void *info) +{ + unsigned long iaddr = (unsigned long) info; + local_sb1_flush_cache_sigtramp(iaddr); +} + +static void sb1_flush_cache_sigtramp(unsigned long addr) +{ + on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); +} +#else +void sb1_flush_cache_sigtramp(unsigned long addr); +asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp"); +#endif + + +/* + * Anything that just flushes dcache state can be ignored, as we're always + * coherent in dcache space. This is just a dummy function that all the + * nop'ed routines point to + */ +static void sb1_nop(void) +{ +} + +/* + * Cache set values (from the mips64 spec) + * 0 - 64 + * 1 - 128 + * 2 - 256 + * 3 - 512 + * 4 - 1024 + * 5 - 2048 + * 6 - 4096 + * 7 - Reserved + */ + +static unsigned int decode_cache_sets(unsigned int config_field) +{ + if (config_field == 7) { + /* JDCXXX - Find a graceful way to abort. */ + return 0; + } + return (1<<(config_field + 6)); +} + +/* + * Cache line size values (from the mips64 spec) + * 0 - No cache present. + * 1 - 4 bytes + * 2 - 8 bytes + * 3 - 16 bytes + * 4 - 32 bytes + * 5 - 64 bytes + * 6 - 128 bytes + * 7 - Reserved + */ + +static unsigned int decode_cache_line_size(unsigned int config_field) +{ + if (config_field == 0) { + return 0; + } else if (config_field == 7) { + /* JDCXXX - Find a graceful way to abort. */ + return 0; + } + return (1<<(config_field + 1)); +} + +/* + * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs) + * + * 24:22 Icache sets per way + * 21:19 Icache line size + * 18:16 Icache Associativity + * 15:13 Dcache sets per way + * 12:10 Dcache line size + * 9:7 Dcache Associativity + */ + +static __init void probe_cache_sizes(void) +{ + u32 config1; + + config1 = read_c0_config1(); + icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); + dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); + icache_sets = decode_cache_sets((config1 >> 22) & 0x7); + dcache_sets = decode_cache_sets((config1 >> 13) & 0x7); + icache_assoc = ((config1 >> 16) & 0x7) + 1; + dcache_assoc = ((config1 >> 7) & 0x7) + 1; + icache_size = icache_line_size * icache_sets * icache_assoc; + dcache_size = dcache_line_size * dcache_sets * dcache_assoc; + /* Need to remove non-index bits for index ops */ + icache_index_mask = (icache_sets - 1) * icache_line_size; + dcache_index_mask = (dcache_sets - 1) * dcache_line_size; + /* + * These are for choosing range (index ops) versus all. + * icache flushes all ways for each set, so drop icache_assoc. + * dcache flushes all ways and each setting of bit 12 for each + * index, so drop dcache_assoc and halve the dcache_sets. + */ + icache_range_cutoff = icache_sets * icache_line_size; + dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; +} + +/* + * This is called from loadmmu.c. We have to set up all the + * memory management function pointers, as well as initialize + * the caches and tlbs + */ +void ld_mmu_sb1(void) +{ + extern char except_vec2_sb1; + unsigned long temp; + + /* Special cache error handler for SB1 */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + + probe_cache_sizes(); + + _clear_page = sb1_clear_page; + _copy_page = sb1_copy_page; + + /* + * None of these are needed for the SB1 - the Dcache is + * physically indexed and tagged, so no virtual aliasing can + * occur + */ + flush_cache_range = (void *) sb1_nop; + flush_cache_page = sb1_flush_cache_page; + flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + flush_cache_all = sb1_nop; + + /* These routines are for Icache coherence with the Dcache */ + flush_icache_range = sb1_flush_icache_range; + flush_icache_page = sb1_flush_icache_page; + flush_icache_all = __sb1_flush_icache_all; /* local only */ + + flush_cache_sigtramp = sb1_flush_cache_sigtramp; + flush_data_cache_page = (void *) sb1_nop; + + /* Full flush */ + __flush_cache_all = sb1___flush_cache_all; + + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* + * This is the only way to force the update of K0 to complete + * before subsequent instruction fetch. + */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips4 \n" + " la %0, 1f \n" + " mtc0 %0, $14 \n" + " eret \n" + "1: .set pop \n" + : "=r" (temp)); + flush_cache_all(); +} diff -Nru a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/c-tx39.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,495 @@ +/* + * r2300.c: R2000 and R3000 specific mmu/cache code. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * with a lot of changes to make this thing work for R3000s + * Tx39XX R4k style caches added. HK + * Copyright (C) 1998, 1999, 2000 Harald Koerfgen + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/cacheops.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/mmu_context.h> +#include <asm/system.h> +#include <asm/isadep.h> +#include <asm/io.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> + +/* For R3000 cores with R4000 style caches */ +static unsigned long icache_size, dcache_size; /* Size in bytes */ +static unsigned long icache_way_size, dcache_way_size; /* Size divided by ways */ +#define scache_size 0 +#define scache_way_size 0 + +#include <asm/r4kcache.h> + +extern void r3k_clear_page(void * page); +extern void r3k_copy_page(void * to, void * from); + +extern int r3k_have_wired_reg; /* in r3k-tlb.c */ + +/* This sequence is required to ensure icache is disabled immediately */ +#define TX39_STOP_STREAMING() \ +__asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "b 1f\n\t" \ + "nop\n\t" \ + "1:\n\t" \ + ".set pop" \ + ) + +/* TX39H-style cache flush routines. */ +static void tx39h_flush_icache_all(void) +{ + unsigned long start = KSEG0; + unsigned long end = (start + icache_size); + unsigned long flags, config; + + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + + /* invalidate icache */ + while (start < end) { + cache16_unroll32(start, Index_Invalidate_I); + start += 0x200; + } + + write_c0_conf(config); + local_irq_restore(flags); +} + +static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + iob(); + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + invalidate_dcache_line(a); /* Hit_Invalidate_D */ + if (a == end) break; + a += dc_lsize; + } +} + + +/* TX39H2,TX39H3 */ +static inline void tx39_blast_dcache_page(unsigned long addr) +{ + if (current_cpu_data.cputype != CPU_TX3912) + blast_dcache16_page(addr); +} + +static inline void tx39_blast_dcache_page_indexed(unsigned long addr) +{ + blast_dcache16_page_indexed(addr); +} + +static inline void tx39_blast_dcache(void) +{ + blast_dcache16(); +} + +static inline void tx39_blast_icache_page(unsigned long addr) +{ + unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16_page(addr); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_blast_icache_page_indexed(unsigned long addr) +{ + unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16_page_indexed(addr); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_blast_icache(void) +{ + unsigned long flags, config; + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + blast_icache16(); + write_c0_conf(config); + local_irq_restore(flags); +} + +static inline void tx39_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + tx39_blast_dcache(); + tx39_blast_icache(); +} + +static inline void tx39___flush_cache_all(void) +{ + tx39_blast_dcache(); + tx39_blast_icache(); +} + +static void tx39_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) + return; + + if (cpu_context(smp_processor_id(), mm) != 0) { + tx39_flush_cache_all(); + } +} + +static void tx39_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + if (!cpu_has_dc_aliases) + return; + + if (cpu_context(smp_processor_id(), mm) != 0) { + tx39_blast_dcache(); + tx39_blast_icache(); + } +} + +static void tx39_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) +{ + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + page &= PAGE_MASK; + pgdp = pgd_offset(mm, page); + pmdp = pmd_offset(pgdp, page); + ptep = pte_offset(pmdp, page); + + /* + * If the page isn't marked valid, the page cannot possibly be + * in the cache. + */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + /* + * Doing flushes for another ASID than the current one is + * too difficult since stupid R4k caches do a TLB translation + * for every cache flush operation. So we do indexed flushes + * in that case, which doesn't overly flush the cache too much. + */ + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || exec) + tx39_blast_dcache_page(page); + if (exec) + tx39_blast_icache_page(page); + + return; + } + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || exec) + tx39_blast_dcache_page_indexed(page); + if (exec) + tx39_blast_icache_page_indexed(page); +} + +static void tx39_flush_data_cache_page(unsigned long addr) +{ + tx39_blast_dcache_page(addr); +} + +static void tx39_flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (end - start > dcache_size) + tx39_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + + if (end - start > icache_size) + tx39_blast_icache(); + else { + unsigned long flags, config; + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + write_c0_conf(config); + local_irq_restore(flags); + } +} + +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + unsigned long addr; + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + addr = (unsigned long) page_address(page); + tx39_blast_dcache_page(addr); + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + tx39_blast_icache(); +} + +static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (((size | addr) & (PAGE_SIZE - 1)) == 0) { + end = addr + size; + do { + tx39_blast_dcache_page(addr); + addr += PAGE_SIZE; + } while(addr != end); + } else if (size > dcache_size) { + tx39_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) break; + a += dc_lsize; + } + } +} + +static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (((size | addr) & (PAGE_SIZE - 1)) == 0) { + end = addr + size; + do { + tx39_blast_dcache_page(addr); + addr += PAGE_SIZE; + } while(addr != end); + } else if (size > dcache_size) { + tx39_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + invalidate_dcache_line(a); /* Hit_Invalidate_D */ + if (a == end) break; + a += dc_lsize; + } + } +} + +static void tx39_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long config; + unsigned long flags; + + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + + /* disable icache (set ICE#) */ + local_irq_save(flags); + config = read_c0_conf(); + write_c0_conf(config & ~TX39_CONF_ICE); + TX39_STOP_STREAMING(); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); + write_c0_conf(config); + local_irq_restore(flags); +} + +static __init void tx39_probe_cache(void) +{ + unsigned long config; + + config = read_c0_conf(); + + icache_size = 1 << (10 + ((config & TX39_CONF_ICS_MASK) >> + TX39_CONF_ICS_SHIFT)); + dcache_size = 1 << (10 + ((config & TX39_CONF_DCS_MASK) >> + TX39_CONF_DCS_SHIFT)); + + current_cpu_data.icache.linesz = 16; + switch (current_cpu_data.cputype) { + case CPU_TX3912: + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = 4; + break; + + case CPU_TX3927: + current_cpu_data.icache.ways = 2; + current_cpu_data.dcache.ways = 2; + current_cpu_data.dcache.linesz = 16; + break; + + case CPU_TX3922: + default: + current_cpu_data.icache.ways = 1; + current_cpu_data.dcache.ways = 1; + current_cpu_data.dcache.linesz = 16; + break; + } +} + +void __init ld_mmu_tx39(void) +{ + unsigned long config; + + _clear_page = r3k_clear_page; + _copy_page = r3k_copy_page; + + config = read_c0_conf(); + config &= ~TX39_CONF_WBON; + write_c0_conf(config); + + tx39_probe_cache(); + + switch (current_cpu_data.cputype) { + case CPU_TX3912: + /* TX39/H core (writethru direct-map cache) */ + flush_cache_all = tx39h_flush_icache_all; + __flush_cache_all = tx39h_flush_icache_all; + flush_cache_mm = (void *) tx39h_flush_icache_all; + flush_cache_range = (void *) tx39h_flush_icache_all; + flush_cache_page = (void *) tx39h_flush_icache_all; + flush_icache_page = (void *) tx39h_flush_icache_all; + flush_icache_range = (void *) tx39h_flush_icache_all; + + flush_cache_sigtramp = (void *) tx39h_flush_icache_all; + flush_data_cache_page = (void *) tx39h_flush_icache_all; + + _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; + + shm_align_mask = PAGE_SIZE - 1; + + break; + + case CPU_TX3922: + case CPU_TX3927: + default: + /* TX39/H2,H3 core (writeback 2way-set-associative cache) */ + r3k_have_wired_reg = 1; + write_c0_wired(0); /* set 8 on reset... */ + /* board-dependent init code may set WBON */ + + flush_cache_all = tx39_flush_cache_all; + __flush_cache_all = tx39___flush_cache_all; + flush_cache_mm = tx39_flush_cache_mm; + flush_cache_range = tx39_flush_cache_range; + flush_cache_page = tx39_flush_cache_page; + flush_icache_page = tx39_flush_icache_page; + flush_icache_range = tx39_flush_icache_range; + + flush_cache_sigtramp = tx39_flush_cache_sigtramp; + flush_data_cache_page = tx39_flush_data_cache_page; + + _dma_cache_wback_inv = tx39_dma_cache_wback_inv; + _dma_cache_wback = tx39_dma_cache_wback_inv; + _dma_cache_inv = tx39_dma_cache_inv; + + shm_align_mask = max_t(unsigned long, + (dcache_size / current_cpu_data.dcache.ways) - 1, + PAGE_SIZE - 1); + + break; + } + + icache_way_size = icache_size / current_cpu_data.icache.ways; + dcache_way_size = dcache_size / current_cpu_data.dcache.ways; + + current_cpu_data.icache.sets = + icache_way_size / current_cpu_data.icache.linesz; + current_cpu_data.dcache.sets = + dcache_way_size / current_cpu_data.dcache.linesz; + + if (dcache_way_size > PAGE_SIZE) + current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES; + + current_cpu_data.icache.waybit = 0; + current_cpu_data.dcache.waybit = 0; + + printk("Primary instruction cache %ldkb, linesize %d bytes\n", + icache_size >> 10, current_cpu_data.icache.linesz); + printk("Primary data cache %ldkb, linesize %d bytes\n", + dcache_size >> 10, current_cpu_data.dcache.linesz); +} diff -Nru a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/cache.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,60 @@ +/* + * 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 - 2003 by Ralf Baechle + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/cacheflush.h> + +asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +{ + /* This should flush more selectivly ... */ + __flush_cache_all(); + + return 0; +} + +void flush_dcache_page(struct page *page) +{ + unsigned long addr; + + if (page->mapping && + list_empty(&page->mapping->i_mmap) && + list_empty(&page->mapping->i_mmap_shared)) { + SetPageDcacheDirty(page); + + return; + } + + /* + * We could delay the flush for the !page->mapping case too. But that + * case is for exec env/arg pages and those are %99 certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + struct page *page; + unsigned long pfn, addr; + + pfn = pte_pfn(pte); + if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page->mapping) && + Page_dcache_dirty(page)) { + if (pages_do_alias((unsigned long)page_address(page), + address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); + } + + ClearPageDcacheDirty(page); + } +} diff -Nru a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/cerr-sb1.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/sched.h> +#include <asm/mipsregs.h> +#include <asm/sibyte/sb1250.h> + +#ifndef CONFIG_SIBYTE_BUS_WATCHER +#include <asm/io.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/64bit.h> +#endif + +/* SB1 definitions */ + +/* XXX should come from config1 XXX */ +#define SB1_CACHE_INDEX_MASK 0x1fe0 + +#define CP0_ERRCTL_RECOVERABLE (1 << 31) +#define CP0_ERRCTL_DCACHE (1 << 30) +#define CP0_ERRCTL_ICACHE (1 << 29) +#define CP0_ERRCTL_MULTIBUS (1 << 23) +#define CP0_ERRCTL_MC_TLB (1 << 15) +#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) + +#define CP0_CERRI_TAG_PARITY (1 << 29) +#define CP0_CERRI_DATA_PARITY (1 << 28) +#define CP0_CERRI_EXTERNAL (1 << 26) + +#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) +#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) + +#define CP0_CERRD_MULTIPLE (1 << 31) +#define CP0_CERRD_TAG_STATE (1 << 30) +#define CP0_CERRD_TAG_ADDRESS (1 << 29) +#define CP0_CERRD_DATA_SBE (1 << 28) +#define CP0_CERRD_DATA_DBE (1 << 27) +#define CP0_CERRD_EXTERNAL (1 << 26) +#define CP0_CERRD_LOAD (1 << 25) +#define CP0_CERRD_STORE (1 << 24) +#define CP0_CERRD_FILLWB (1 << 23) +#define CP0_CERRD_COHERENCY (1 << 22) +#define CP0_CERRD_DUPTAG (1 << 21) + +#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) +#define CP0_CERRD_IDX_VALID(c) \ + (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) +#define CP0_CERRD_CAUSES \ + (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) +#define CP0_CERRD_TYPES \ + (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) +#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) + +static uint32_t extract_ic(unsigned short addr, int data); +static uint32_t extract_dc(unsigned short addr, int data); + +static inline void breakout_errctl(unsigned int val) +{ + if (val & CP0_ERRCTL_RECOVERABLE) + prom_printf(" recoverable"); + if (val & CP0_ERRCTL_DCACHE) + prom_printf(" dcache"); + if (val & CP0_ERRCTL_ICACHE) + prom_printf(" icache"); + if (val & CP0_ERRCTL_MULTIBUS) + prom_printf(" multiple-buserr"); + prom_printf("\n"); +} + +static inline void breakout_cerri(unsigned int val) +{ + if (val & CP0_CERRI_TAG_PARITY) + prom_printf(" tag-parity"); + if (val & CP0_CERRI_DATA_PARITY) + prom_printf(" data-parity"); + if (val & CP0_CERRI_EXTERNAL) + prom_printf(" external"); + prom_printf("\n"); +} + +static inline void breakout_cerrd(unsigned int val) +{ + switch (val & CP0_CERRD_CAUSES) { + case CP0_CERRD_LOAD: + prom_printf(" load,"); + break; + case CP0_CERRD_STORE: + prom_printf(" store,"); + break; + case CP0_CERRD_FILLWB: + prom_printf(" fill/wb,"); + break; + case CP0_CERRD_COHERENCY: + prom_printf(" coherency,"); + break; + case CP0_CERRD_DUPTAG: + prom_printf(" duptags,"); + break; + default: + prom_printf(" NO CAUSE,"); + break; + } + if (!(val & CP0_CERRD_TYPES)) + prom_printf(" NO TYPE"); + else { + if (val & CP0_CERRD_MULTIPLE) + prom_printf(" multi-err"); + if (val & CP0_CERRD_TAG_STATE) + prom_printf(" tag-state"); + if (val & CP0_CERRD_TAG_ADDRESS) + prom_printf(" tag-address"); + if (val & CP0_CERRD_DATA_SBE) + prom_printf(" data-SBE"); + if (val & CP0_CERRD_DATA_DBE) + prom_printf(" data-DBE"); + if (val & CP0_CERRD_EXTERNAL) + prom_printf(" external"); + } + prom_printf("\n"); +} + +#ifndef CONFIG_SIBYTE_BUS_WATCHER + +static void check_bus_watcher(void) +{ + uint32_t status, l2_err, memio_err; + + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + /* Bit 31 is always on, but there's no #define for that */ + if (status & ~(1UL << 31)) { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + prom_printf("\nLast recorded signature:\n"); + prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); + } else { + prom_printf("Bus watcher indicates no error\n"); + } +} +#else +extern void check_bus_watcher(void); +#endif + +asmlinkage void sb1_cache_error(void) +{ + uint64_t cerr_dpa; + uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + + prom_printf("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); + + __asm__ __volatile__ ( + " .set push\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " mfc0 %0, $26\n\t" + " mfc0 %1, $27\n\t" + " mfc0 %2, $27, 1\n\t" + " dmfc0 $1, $27, 3\n\t" + " dsrl32 %3, $1, 0 \n\t" + " sll %4, $1, 0 \n\t" + " mfc0 %5, $30\n\t" + " .set pop" + : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), + "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); + + cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; + prom_printf(" cp0_errorepc == %08x\n", eepc); + prom_printf(" cp0_errctl == %08x", errctl); + breakout_errctl(errctl); + if (errctl & CP0_ERRCTL_ICACHE) { + prom_printf(" cp0_cerr_i == %08x", cerr_i); + breakout_cerri(cerr_i); + if (CP0_CERRI_IDX_VALID(cerr_i)) { + if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_i idx doesn't match eepc\n"); + else { + res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, + (cerr_i & CP0_CERRI_DATA) != 0); + if (!(res & cerr_i)) + prom_printf("...didn't see indicated icache problem\n"); + } + } + } + if (errctl & CP0_ERRCTL_DCACHE) { + prom_printf(" cp0_cerr_d == %08x", cerr_d); + breakout_cerrd(cerr_d); + if (CP0_CERRD_DPA_VALID(cerr_d)) { + prom_printf(" cp0_cerr_dpa == %010llx\n", cerr_dpa); + if (!CP0_CERRD_IDX_VALID(cerr_d)) { + res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated dcache problem\n"); + } else { + if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + else { + res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated problem\n"); + } + } + } + } + + check_bus_watcher(); + + while (1); + /* + * This tends to make things get really ugly; let's just stall instead. + * panic("Can't handle the cache error!"); + */ +} + + +/* Parity lookup table. */ +static const uint8_t parity[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ +static const uint64_t mask_72_64[8] = { + 0x0738C808099264FFL, + 0x38C808099264FF07L, + 0xC808099264FF0738L, + 0x08099264FF0738C8L, + 0x099264FF0738C808L, + 0x9264FF0738C80809L, + 0x64FF0738C8080992L, + 0xFF0738C808099264L +}; + +/* Calculate the parity on a range of bits */ +static char range_parity(uint64_t dword, int max, int min) +{ + char parity = 0; + int i; + dword >>= min; + for (i=max-min; i>=0; i--) { + if (dword & 0x1) + parity = !parity; + dword >>= 1; + } + return parity; +} + +/* Calculate the 4-bit even byte-parity for an instruction */ +static unsigned char inst_parity(uint32_t word) +{ + int i, j; + char parity = 0; + for (j=0; j<4; j++) { + char byte_parity = 0; + for (i=0; i<8; i++) { + if (word & 0x80000000) + byte_parity = !byte_parity; + word <<= 1; + } + parity <<= 1; + parity |= byte_parity; + } + return parity; +} + +static uint32_t extract_ic(unsigned short addr, int data) +{ + unsigned short way; + int valid; + uint64_t taglo, va, tlo_tmp; + uint32_t taghi, taglolo, taglohi; + uint8_t lru; + int res = 0; + + prom_printf("Icache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + /* Index-load-tag-I */ + __asm__ __volatile__ ( + " .set push \n\t" + " .set noreorder \n\t" + " .set mips64 \n\t" + " .set noat \n\t" + " cache 4, 0(%3) \n\t" + " mfc0 %0, $29 \n\t" + " dmfc0 $1, $28 \n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 5) & 0x3), /* bank */ + ((addr >> 7) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + va = (taglo & 0xC0000FFFFFFFE000) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) + va |= 0x3FFFF00000000000; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; + if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { + prom_printf(" ** bad parity in VTag0/G/ASID\n"); + res |= CP0_CERRI_TAG_PARITY; + } + if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { + prom_printf(" ** bad parity in R/VTag1\n"); + res |= CP0_CERRI_TAG_PARITY; + } + } + if (valid ^ ((taghi >> 27) & 1)) { + prom_printf(" ** bad parity for valid bit\n"); + res |= CP0_CERRI_TAG_PARITY; + } + prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + way, va, valid, taghi, taglo); + + if (data) { + uint32_t datahi, insta, instb; + uint8_t predecode; + int offset; + + /* (hit all banks and ways) */ + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-I */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 6, 0(%3) \n\t" + " mfc0 %0, $29, 1\n\t" + " dmfc0 $1, $28, 1\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop \n" + : "=r" (datahi), "=r" (insta), "=r" (instb) + : "r" ((way << 13) | addr | (offset << 3))); + predecode = (datahi >> 8) & 0xff; + if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { + prom_printf(" ** bad parity in predecode\n"); + res |= CP0_CERRI_DATA_PARITY; + } + /* XXXKW should/could check predecode bits themselves */ + if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { + prom_printf(" ** bad parity in instruction a\n"); + res |= CP0_CERRI_DATA_PARITY; + } + if ((datahi & 0xf) ^ inst_parity(instb)) { + prom_printf(" ** bad parity in instruction b\n"); + res |= CP0_CERRI_DATA_PARITY; + } + prom_printf(" %05X-%08X%08X", datahi, insta, instb); + } + prom_printf("\n"); + } + } + return res; +} + +/* Compute the ECC for a data doubleword */ +static uint8_t dc_ecc(uint64_t dword) +{ + uint64_t t; + uint32_t w; + uint8_t p; + int i; + + p = 0; + for (i = 7; i >= 0; i--) + { + p <<= 1; + t = dword & mask_72_64[i]; + w = (uint32_t)(t >> 32); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + w = (uint32_t)(t & 0xFFFFFFFF); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + } + return p; +} + +struct dc_state { + unsigned char val; + char *name; +}; + +static struct dc_state dc_states[] = { + { 0x00, "INVALID" }, + { 0x0f, "COH-SHD" }, + { 0x13, "NCO-E-C" }, + { 0x19, "NCO-E-D" }, + { 0x16, "COH-E-C" }, + { 0x1c, "COH-E-D" }, + { 0xff, "*ERROR*" } +}; + +#define DC_TAG_VALID(state) \ + (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) + +static char *dc_state_str(unsigned char state) +{ + struct dc_state *dsc = dc_states; + while (dsc->val != 0xff) { + if (dsc->val == state) + break; + dsc++; + } + return dsc->name; +} + +static uint32_t extract_dc(unsigned short addr, int data) +{ + int valid, way; + unsigned char state; + uint64_t taglo, pa; + uint32_t taghi, taglolo, taglohi; + uint8_t ecc, lru; + int res = 0; + + prom_printf("Dcache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 5, 0(%3)\n\t" /* Index-load-tag-D */ + " mfc0 %0, $29, 2\n\t" + " dmfc0 $1, $28, 2\n\t" + " dsrl32 %1, $1, 0\n\t" + " sll %2, $1, 0\n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + pa = (taglo & 0xFFFFFFE000) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ + ((addr >> 6) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + state = (taghi >> 25) & 0x1f; + valid = DC_TAG_VALID(state); + prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + way, pa, dc_state_str(state), state, taghi, taglo); + if (valid) { + if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { + prom_printf(" ** bad parity in PTag1\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { + prom_printf(" ** bad parity in PTag0\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + } else { + res |= CP0_CERRD_TAG_STATE; + } + + if (data) { + uint64_t datalo; + uint32_t datalohi, datalolo, datahi; + int offset; + + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-D */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 7, 0(%3)\n\t" /* Index-load-data-D */ + " mfc0 %0, $29, 3\n\t" + " dmfc0 $1, $28, 3\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (datahi), "=r" (datalohi), "=r" (datalolo) + : "r" ((way << 13) | addr | (offset << 3))); + datalo = ((unsigned long long)datalohi << 32) | datalolo; + ecc = dc_ecc(datalo); + if (ecc != datahi) { + int bits = 0; + prom_printf(" ** bad ECC (%02x %02x) ->", + datahi, ecc); + ecc ^= datahi; + while (ecc) { + if (ecc & 1) bits++; + ecc >>= 1; + } + res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; + } + prom_printf(" %02X-%016llX", datahi, datalo); + } + prom_printf("\n"); + } + } + return res; +} diff -Nru a/arch/mips/mm/cex-sb1.S b/arch/mips/mm/cex-sb1.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/cex-sb1.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> +#include <asm/sibyte/board.h> + + .text + .set noat + .set mips4 + + __INIT + + /* Cache Error handler for SB1 */ + LEAF(except_vec2_sb1) + mfc0 k1, $26 + # check if error was recoverable + bltz k1, leave_cerr +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + # look for signature of spurious CErr + lui k0, 0x4000 + bne k0, k1, 1f + .word 0x401Bd801 # mfc0 k1, $27, 1 + lui k0, 0xffe0 + and k1, k0, k1 + lui k0, 0x0200 + beq k0, k1, leave_cerr +1: +#endif + j handle_vec2_sb1 + +leave_cerr: + # clear/unlock the registers + mtc0 zero, $26 + mtc0 zero, $27 + .word 0x4080d801 # mtc0 zero, $27, 1 + .word 0x4080d803 # mtc0 zero, $27, 3 + eret + END(except_vec2_sb1) + + __FINIT + + LEAF(handle_vec2_sb1) + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + + SSNOP + SSNOP + SSNOP + SSNOP + bnezl $0, 1f +1: + mfc0 k0, CP0_STATUS + sll k0, k0, 3 # check CU0 (kernel?) + bltz k0, 2f + GET_SAVED_SP + move sp, k0 # want Kseg SP (so uncached) +2: + j sb1_cache_error + + END(handle_vec2_sb1) diff -Nru a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c --- a/arch/mips/mm/extable.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips/mm/extable.c Fri Jun 27 14:19:57 2003 @@ -1,62 +1,30 @@ /* - * linux/arch/mips/mm/extable.c + * linux/arch/i386/mm/extable.c */ + #include <linux/config.h> #include <linux/module.h> #include <linux/spinlock.h> #include <asm/uaccess.h> -extern const struct exception_table_entry __start___ex_table[]; -extern const struct exception_table_entry __stop___ex_table[]; - -static inline unsigned long -search_one_table(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) +/* Simple binary search */ +const struct exception_table_entry * +search_extable(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) { - while (first <= last) { + while (first <= last) { const struct exception_table_entry *mid; long diff; mid = (last - first) / 2 + first; diff = mid->insn - value; - if (diff == 0) - return mid->nextinsn; - else if (diff < 0) - first = mid+1; - else - last = mid-1; - } - return 0; -} - -extern spinlock_t modlist_lock; - -unsigned long -search_exception_table(unsigned long addr) -{ - unsigned long ret = 0; - -#ifndef CONFIG_MODULES - /* There is only the kernel to search. */ - ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); - return ret; -#else - unsigned long flags; - - /* The kernel is the last "module" -- no need to treat it special. */ - struct module *mp; - - spin_lock_irqsave(&modlist_lock, flags); - for (mp = module_list; mp != NULL; mp = mp->next) { - if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING))) - continue; - ret = search_one_table(mp->ex_table_start, - mp->ex_table_end - 1, addr); - if (ret) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - return ret; -#endif + if (diff == 0) + return mid; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return NULL; } diff -Nru a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c --- a/arch/mips/mm/fault.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips/mm/fault.c Fri Jun 27 14:19:54 2003 @@ -5,6 +5,7 @@ * * Copyright (C) 1995 - 2000 by Ralf Baechle */ +#include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> @@ -18,23 +19,50 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/version.h> +#include <linux/vt_kern.h> /* For unblank_screen() */ +#include <linux/module.h> +#include <asm/branch.h> #include <asm/hardirq.h> #include <asm/pgalloc.h> #include <asm/mmu_context.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/ptrace.h> #define development_version (LINUX_VERSION_CODE & 0x100) -unsigned long asid_cache = ASID_FIRST_VERSION; - /* * Macro for exception fixup code to access integer registers. */ #define dpf_reg(r) (regs->regs[r]) /* + * Unlock any spinlocks which will prevent us from getting the out + */ +void bust_spinlocks(int yes) +{ + int loglevel_save = console_loglevel; + + if (yes) { + oops_in_progress = 1; + return; + } +#ifdef CONFIG_VT + unblank_screen(); +#endif + oops_in_progress = 0; + /* + * OK, the message is on the console. Now we call printk() + * without oops_in_progress set so that printk will give klogd + * a poke. Hold onto your hats... + */ + console_loglevel = 15; /* NMI oopser may have shut the console up */ + printk(" "); + console_loglevel = loglevel_save; +} + +/* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. @@ -45,9 +73,14 @@ struct vm_area_struct * vma; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; - unsigned long fixup; + const struct exception_table_entry *fixup; siginfo_t info; +#if 0 + printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), + current->comm, current->pid, address, write, regs->cp0_epc); +#endif + /* * We fault-in kernel-space virtual memory on-demand. The * 'reference' page table is init_mm.pgd. @@ -57,7 +90,7 @@ * only copy the information from the master page table, * nothing more. */ - if (address >= TASK_SIZE) + if (address >= VMALLOC_START) goto vmalloc_fault; info.si_code = SEGV_MAPERR; @@ -65,12 +98,9 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; -#if 0 - printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid, - address, write, regs->cp0_epc); -#endif + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -96,22 +126,25 @@ goto bad_area; } +survive: /* * If for any reason at all we couldn't handle the fault, * make sure we exit gracefully rather than endlessly redo * the fault. */ switch (handle_mm_fault(mm, vma, address, write)) { - case 1: + case VM_FAULT_MINOR: tsk->min_flt++; break; - case 2: + case VM_FAULT_MAJOR: tsk->maj_flt++; break; - case 0: + case VM_FAULT_SIGBUS: goto do_sigbus; - default: + case VM_FAULT_OOM: goto out_of_memory; + default: + BUG(); } up_read(&mm->mmap_sem); @@ -124,7 +157,6 @@ bad_area: up_read(&mm->mmap_sem); -bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { tsk->thread.cp0_badvaddr = address; @@ -148,12 +180,11 @@ no_context: /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_table(regs->cp0_epc); + fixup = search_exception_tables(exception_epc(regs)); if (fixup) { - long new_epc; + unsigned long new_epc = fixup->nextinsn; tsk->thread.cp0_baduaddr = address; - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); if (development_version) printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", tsk->comm, regs->cp0_epc, new_epc); @@ -165,11 +196,13 @@ * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. */ + + bust_spinlocks(1); + printk(KERN_ALERT "Unable to handle kernel paging request at virtual " "address %08lx, epc == %08lx, ra == %08lx\n", address, regs->cp0_epc, regs->regs[31]); die("Oops", regs); - do_exit(SIGKILL); /* * We ran out of memory, or some other thing happened to us that made @@ -177,6 +210,11 @@ */ out_of_memory: up_read(&mm->mmap_sem); + if (tsk->pid == 1) { + yield(); + down_read(&mm->mmap_sem); + goto survive; + } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) do_exit(SIGKILL); @@ -207,26 +245,31 @@ /* * Synchronize this task's top level page-table * with the 'reference' page table. + * + * Do _not_ use "tsk" here. We might be inside + * an interrupt in the middle of a task switch.. */ - int offset = pgd_index(address); + int offset = __pgd_offset(address); pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; + pte_t *pte_k; - pgd = tsk->active_mm->pgd + offset; + pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset; pgd_k = init_mm.pgd + offset; - if (!pgd_present(*pgd)) { - if (!pgd_present(*pgd_k)) - goto bad_area_nosemaphore; - set_pgd(pgd, *pgd_k); - return; - } + if (!pgd_present(*pgd_k)) + goto no_context; + set_pgd(pgd, *pgd_k); pmd = pmd_offset(pgd, address); pmd_k = pmd_offset(pgd_k, address); - - if (pmd_present(*pmd) || !pmd_present(*pmd_k)) - goto bad_area_nosemaphore; + if (!pmd_present(*pmd_k)) + goto no_context; set_pmd(pmd, *pmd_k); + + pte_k = pte_offset_kernel(pmd_k, address); + if (!pte_present(*pte_k)) + goto no_context; + return; } } diff -Nru a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/highmem.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,101 @@ +#include <linux/module.h> +#include <linux/highmem.h> +#include <asm/tlbflush.h> + +void *kmap(struct page *page) +{ + void *addr; + + if (in_interrupt()) + BUG(); + + if (page < highmem_start_page) + return page_address(page); + addr = kmap_high(page); + flush_tlb_one((unsigned long)addr); + + return addr; +} + +void kunmap(struct page *page) +{ + if (in_interrupt()) + BUG(); + if (page < highmem_start_page) + return; + kunmap_high(page); +} + +/* + * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because + * no global lock is needed and because the kmap code must perform a global TLB + * invalidation when the kmap pool wraps. + * + * However when holding an atomic kmap is is not legal to sleep, so atomic + * kmaps are appropriate for short, tight code paths only. + */ + +void *kmap_atomic(struct page *page, enum km_type type) +{ + enum fixed_addresses idx; + unsigned long vaddr; + + inc_preempt_count(); + if (page < highmem_start_page) + return page_address(page); + + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM + if (!pte_none(*(kmap_pte-idx))) + BUG(); +#endif + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + local_flush_tlb_one((unsigned long)vaddr); + + return (void*) vaddr; +} + +void kunmap_atomic(void *kvaddr, enum km_type type) +{ +#ifdef CONFIG_DEBUG_HIGHMEM + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); + + if (vaddr < FIXADDR_START) { // FIXME + dec_preempt_count(); + return; + } + + if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) + BUG(); + + /* + * force other mappings to Oops if they'll try to access + * this pte without first remap it + */ + pte_clear(kmap_pte-idx); + local_flush_tlb_one(vaddr); +#endif + + dec_preempt_count(); +} + +struct page *kmap_atomic_to_page(void *ptr) +{ + unsigned long idx, vaddr = (unsigned long)ptr; + pte_t *pte; + + if (vaddr < FIXADDR_START) + return virt_to_page(ptr); + + idx = virt_to_fix(vaddr); + pte = kmap_pte - (idx - FIX_KMAP_BEGIN); + return pte_page(*pte); +} + +EXPORT_SYMBOL(kmap); +EXPORT_SYMBOL(kunmap); +EXPORT_SYMBOL(kmap_atomic); +EXPORT_SYMBOL(kunmap_atomic); +EXPORT_SYMBOL(kmap_atomic_to_page); diff -Nru a/arch/mips/mm/init.c b/arch/mips/mm/init.c --- a/arch/mips/mm/init.c Fri Jun 27 14:20:01 2003 +++ b/arch/mips/mm/init.c Fri Jun 27 14:20:01 2003 @@ -24,36 +24,23 @@ #include <linux/bootmem.h> #include <linux/highmem.h> #include <linux/swap.h> -#ifdef CONFIG_BLK_DEV_INITRD #include <linux/blk.h> -#endif #include <asm/bootinfo.h> +#include <asm/cacheflush.h> #include <asm/cachectl.h> #include <asm/cpu.h> #include <asm/dma.h> -#include <asm/jazzdma.h> -#include <asm/system.h> -#include <asm/pgtable.h> #include <asm/pgalloc.h> -#ifdef CONFIG_SGI_IP22 -#include <asm/sgialib.h> -#endif #include <asm/mmu_context.h> +#include <asm/sections.h> #include <asm/tlb.h> DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -extern void prom_free_prom_memory(void); - - -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) -{ - /* This should flush more selectivly ... */ - __flush_cache_all(); - - return 0; -} +unsigned long highstart_pfn, highend_pfn; +static unsigned long totalram_pages; +static unsigned long totalhigh_pages; /* * We have upto 8 empty zeroed pages so we can map one of the right colour @@ -68,9 +55,10 @@ { unsigned long order, size; struct page *page; - if(mips_cpu.options & MIPS_CPU_VCE) + + if (cpu_has_vce) order = 3; - else + else order = 0; empty_zero_page = __get_free_pages(GFP_KERNEL, order); @@ -91,69 +79,109 @@ return 1UL << order; } -int do_check_pgt_cache(int low, int high) +#ifdef CONFIG_HIGHMEM +pte_t *kmap_pte; +pgprot_t kmap_prot; + +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) + +static void __init kmap_init(void) { - int freed = 0; + unsigned long kmap_vstart; + + /* cache the first kmap pte */ + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); + kmap_pte = kmap_get_fixmap_pte(kmap_vstart); - if(pgtable_cache_size > high) { - do { - if(pgd_quicklist) - free_pgd_slow(get_pgd_fast()), freed++; - if(pmd_quicklist) - free_pmd_slow(get_pmd_fast()), freed++; - if(pte_quicklist) - free_pte_slow(get_pte_fast()), freed++; - } while(pgtable_cache_size > low); - } - return freed; -} - -void show_mem(void) -{ - int i, free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map + i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk("%d pages of RAM\n", total); - printk("%d reserved pages\n", reserved); - printk("%d pages shared\n", shared); - printk("%d pages swap cached\n",cached); - printk("%ld pages in page table cache\n",pgtable_cache_size); - printk("%d free pages\n", free); + kmap_prot = PAGE_KERNEL; } -/* References to section boundaries */ +#endif /* CONFIG_HIGHMEM */ -extern char _ftext, _etext, _fdata, _edata; -extern char __init_begin, __init_end; +#ifdef CONFIG_HIGHMEM +static void __init fixrange_init (unsigned long start, unsigned long end, + pgd_t *pgd_base) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int i, j; + unsigned long vaddr; + + vaddr = start; + i = __pgd_offset(vaddr); + j = __pmd_offset(vaddr); + pgd = pgd_base + i; + + for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { + pmd = (pmd_t *)pgd; + for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { + if (pmd_none(*pmd)) { + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + set_pmd(pmd, __pmd(pte)); + if (pte != pte_offset_kernel(pmd, 0)) + BUG(); + } + vaddr += PMD_SIZE; + } + j = 0; + } +} +#endif -void __init paging_init(void) +void __init pagetable_init(void) { - unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; - unsigned long max_dma, low; +#ifdef CONFIG_HIGHMEM + unsigned long vaddr; + pgd_t *pgd, *pgd_base; + pmd_t *pmd; + pte_t *pte; +#endif /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); - pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2); + pgd_init((unsigned long)swapper_pg_dir + + sizeof(pgd_t ) * USER_PTRS_PER_PGD); + +#ifdef CONFIG_HIGHMEM + pgd_base = swapper_pg_dir; + + /* + * Fixed mappings: + */ + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + fixrange_init(vaddr, 0, pgd_base); + + /* + * Permanent kmaps: + */ + vaddr = PKMAP_BASE; + fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base); + + pgd = swapper_pg_dir + __pgd_offset(vaddr); + pmd = pmd_offset(pgd, vaddr); + pte = pte_offset_kernel(pmd, vaddr); + pkmap_page_table = pte; +#endif +} + +void __init paging_init(void) +{ + unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; + unsigned long max_dma, high, low; + + pagetable_init(); + +#ifdef CONFIG_HIGHMEM + kmap_init(); +#endif max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; + high = highend_pfn; -#if defined(CONFIG_PCI) || defined(CONFIG_ISA) +#ifdef CONFIG_ISA if (low < max_dma) zones_size[ZONE_DMA] = low; else { @@ -163,6 +191,9 @@ #else zones_size[ZONE_DMA] = low; #endif +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = high - low; +#endif free_area_init(zones_size); } @@ -197,8 +228,17 @@ unsigned long codesize, reservedpages, datasize, initsize; unsigned long tmp, ram; +#ifdef CONFIG_HIGHMEM + highstart_pfn = (KSEG1 - KSEG0) >> PAGE_SHIFT; + highmem_start_page = mem_map + highstart_pfn; +#ifdef CONFIG_DISCONTIGMEM +#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet" +#endif + max_mapnr = num_physpages = highend_pfn; +#else max_mapnr = num_physpages = max_low_pfn; - high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); +#endif + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); totalram_pages += free_all_bootmem(); totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ @@ -211,25 +251,43 @@ reservedpages++; } - codesize = (unsigned long) &_etext - (unsigned long) &_ftext; - datasize = (unsigned long) &_edata - (unsigned long) &_fdata; +#ifdef CONFIG_HIGHMEM + for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { + struct page *page = mem_map + tmp; + + if (!page_is_ram(tmp)) { + SetPageReserved(page); + continue; + } + ClearPageReserved(page); + set_bit(PG_highmem, &page->flags); + atomic_set(&page->count, 1); + __free_page(page); + totalhigh_pages++; + } + totalram_pages += totalhigh_pages; +#endif + + codesize = (unsigned long) &_etext - (unsigned long) &_text; + datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " - "%ldk data, %ldk init)\n", + printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " + "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), ram << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, - initsize >> 10); + initsize >> 10, + (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))); } #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { if (start < end) - printk("Freeing initrd memory: %ldk freed\n", + printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); for (; start < end; start += PAGE_SIZE) { @@ -242,14 +300,14 @@ #endif extern char __init_begin, __init_end; -extern void prom_free_prom_memory(void); +extern void prom_free_prom_memory(void) __init; void free_initmem(void) { unsigned long addr; prom_free_prom_memory (); - + addr = (unsigned long) &__init_begin; while (addr < (unsigned long) &__init_end) { ClearPageReserved(virt_to_page(addr)); @@ -258,6 +316,6 @@ totalram_pages++; addr += PAGE_SIZE; } - printk("Freeing unused kernel memory: %dk freed\n", + printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } diff -Nru a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c --- a/arch/mips/mm/ioremap.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips/mm/ioremap.c Fri Jun 27 14:19:56 2003 @@ -4,20 +4,22 @@ * for more details. * * (C) Copyright 1995 1996 Linus Torvalds - * (C) Copyright 2001 Ralf Baechle + * (C) Copyright 2001, 2002 Ralf Baechle */ #include <linux/module.h> #include <asm/addrspace.h> #include <asm/byteorder.h> #include <linux/vmalloc.h> +#include <asm/cacheflush.h> #include <asm/io.h> #include <asm/pgalloc.h> +#include <asm/tlbflush.h> -static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) +static inline void remap_area_pte(pte_t * pte, unsigned long address, + phys_t size, phys_t phys_addr, unsigned long flags) { - unsigned long end; + phys_t end; unsigned long pfn; pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE | __WRITEABLE | flags); @@ -41,10 +43,10 @@ } while (address && (address < end)); } -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, + phys_t size, phys_t phys_addr, unsigned long flags) { - unsigned long end; + phys_t end; address &= ~PGDIR_MASK; end = address + size; @@ -54,7 +56,7 @@ if (address >= end) BUG(); do { - pte_t * pte = pte_alloc(&init_mm, pmd, address); + pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); if (!pte) return -ENOMEM; remap_area_pte(pte, address, end - address, address + phys_addr, flags); @@ -64,8 +66,8 @@ return 0; } -static int remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) +static int remap_area_pages(unsigned long address, phys_t phys_addr, + phys_t size, unsigned long flags) { int error; pgd_t * dir; @@ -109,13 +111,14 @@ * caller shouldn't need to know that small detail. */ -#define IS_LOW512(addr) (!((unsigned long)(addr) & ~0x1fffffffUL)) +#define IS_LOW512(addr) (!((phys_t)(addr) & ~0x1fffffffUL)) -void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) +void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) { - void * addr; struct vm_struct * area; - unsigned long offset, last_addr; + unsigned long offset; + phys_t last_addr; + void * addr; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -123,10 +126,11 @@ return NULL; /* - * Map objects in the low 512mb of address space using KSEG1, otherwise - * map using page tables. + * Map uncached objects in the low 512mb of address space using KSEG1, + * otherwise map using page tables. */ - if (IS_LOW512(phys_addr) && IS_LOW512(phys_addr + size - 1)) + if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) && + flags == _CACHE_UNCACHED) return (void *) KSEG1ADDR(phys_addr); /* @@ -138,7 +142,7 @@ t_addr = __va(phys_addr); t_end = t_addr + (size - 1); - + for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) if(!PageReserved(page)) return NULL; @@ -159,7 +163,7 @@ return NULL; addr = area->addr; if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) { - vfree(addr); + vunmap(addr); return NULL; } @@ -170,8 +174,19 @@ void iounmap(void *addr) { - if (!IS_KSEG1(addr)) - return vfree((void *) (PAGE_MASK & (unsigned long) addr)); + struct vm_struct *p; + + if (IS_KSEG1(addr)) + return; + + vfree((void *) (PAGE_MASK & (unsigned long) addr)); + p = remove_vm_area((void *) (PAGE_MASK & (unsigned long) addr)); + if (!p) { + printk(KERN_ERR "iounmap: bad address %p\n", addr); + return; + } + + kfree(p); } EXPORT_SYMBOL(__ioremap); diff -Nru a/arch/mips/mm/loadmmu.c b/arch/mips/mm/loadmmu.c --- a/arch/mips/mm/loadmmu.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips/mm/loadmmu.c Fri Jun 27 14:19:59 2003 @@ -1,7 +1,11 @@ /* - * loadmmu.c: Setup cpu/cache specific function ptrs at boot time. + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ @@ -10,6 +14,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/module.h> #include <asm/bootinfo.h> #include <asm/cpu.h> @@ -22,80 +27,93 @@ void (*_copy_page)(void * to, void * from); /* Cache operations. */ -void (*_flush_cache_all)(void); -void (*___flush_cache_all)(void); -void (*_flush_cache_mm)(struct mm_struct *mm); -void (*_flush_cache_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -void (*_flush_cache_sigtramp)(unsigned long addr); -void (*_flush_page_to_ram)(struct page * page); -void (*_flush_icache_range)(unsigned long start, unsigned long end); -void (*_flush_icache_page)(struct vm_area_struct *vma, struct page *page); +void (*flush_cache_all)(void); +void (*__flush_cache_all)(void); +void (*flush_cache_mm)(struct mm_struct *mm); +void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, + unsigned long end); +void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page); +void (*flush_icache_range)(unsigned long start, unsigned long end); +void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); + +/* MIPS specific cache operations */ +void (*flush_cache_sigtramp)(unsigned long addr); +void (*flush_data_cache_page)(unsigned long addr); +void (*flush_icache_all)(void); + +#ifdef CONFIG_NONCOHERENT_IO /* DMA cache operations. */ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); void (*_dma_cache_wback)(unsigned long start, unsigned long size); void (*_dma_cache_inv)(unsigned long start, unsigned long size); +EXPORT_SYMBOL(_dma_cache_wback_inv); +EXPORT_SYMBOL(_dma_cache_wback); +EXPORT_SYMBOL(_dma_cache_inv); + +#endif /* CONFIG_NONCOHERENT_IO */ + extern void ld_mmu_r23000(void); extern void ld_mmu_r4xx0(void); -extern void ld_mmu_r5432(void); +extern void ld_mmu_tx39(void); extern void ld_mmu_r6000(void); -extern void ld_mmu_rm7k(void); extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); extern void ld_mmu_sb1(void); -extern void ld_mmu_mips32(void); +extern void sb1_tlb_init(void); +extern void r3k_tlb_init(void); +extern void r4k_tlb_init(void); +extern void sb1_tlb_init(void); -void __init loadmmu(void) +void __init load_mmu(void) { - - if (mips_cpu.options & MIPS_CPU_4KTLB) { -#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ - defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ - defined(CONFIG_CPU_NEVADA) - printk("Loading R4000 MMU routines.\n"); + if (cpu_has_4ktlb) { +#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ + defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ + defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ + defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ + defined(CONFIG_CPU_RM7000) ld_mmu_r4xx0(); + r4k_tlb_init(); #endif -#if defined(CONFIG_CPU_RM7000) - printk("Loading RM7000 MMU routines.\n"); - ld_mmu_rm7k(); -#endif -#if defined(CONFIG_CPU_R5432) - printk("Loading R5432 MMU routines.\n"); - ld_mmu_r5432(); -#endif - -#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) - printk("Loading MIPS32 MMU routines.\n"); - ld_mmu_mips32(); -#endif - } else switch(mips_cpu.cputype) { + } else switch (current_cpu_data.cputype) { #ifdef CONFIG_CPU_R3000 case CPU_R2000: case CPU_R3000: case CPU_R3000A: + case CPU_R3081E: + ld_mmu_r23000(); + r3k_tlb_init(); + break; +#endif +#ifdef CONFIG_CPU_TX39XX case CPU_TX3912: case CPU_TX3922: case CPU_TX3927: - case CPU_R3081E: - printk("Loading R[23]000 MMU routines.\n"); - ld_mmu_r23000(); + ld_mmu_tx39(); + r3k_tlb_init(); break; #endif #ifdef CONFIG_CPU_R10000 case CPU_R10000: - printk("Loading R10000 MMU routines.\n"); - ld_mmu_andes(); + case CPU_R12000: + ld_mmu_r4xx0(); + andes_tlb_init(); break; #endif #ifdef CONFIG_CPU_SB1 case CPU_SB1: - printk("Loading SB1 MMU routines.\n"); ld_mmu_sb1(); + sb1_tlb_init(); break; #endif + + case CPU_R8000: + panic("R8000 is unsupported"); + break; + default: panic("Yeee, unsupported mmu/cache architecture."); } diff -Nru a/arch/mips/mm/mips32.c b/arch/mips/mm/mips32.c --- a/arch/mips/mm/mips32.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1065 +0,0 @@ -/* - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * MIPS32 CPU variant specific MMU/Cache routines. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/bootinfo.h> -#include <asm/cpu.h> -#include <asm/bcache.h> -#include <asm/io.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/mmu_context.h> - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include <asm/cacheops.h> -#include <asm/mips32_cache.h> - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - - -/* - * Zero an entire page. - */ - -static void mips32_clear_page_dc(unsigned long page) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) { - for (i=page; i<page+PAGE_SIZE; i+=dc_lsize) { - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "cache\t%2,(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (i) - :"0" (i), - "I" (Create_Dirty_Excl_D)); - } - } - for (i=page; i<page+PAGE_SIZE; i+=4) - *(unsigned long *)(i) = 0; -} - -static void mips32_clear_page_sc(unsigned long page) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) { - for (i=page; i<page+PAGE_SIZE; i+=sc_lsize) { - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "cache\t%2,(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (i) - :"0" (i), - "I" (Create_Dirty_Excl_SD)); - } - } - for (i=page; i<page+PAGE_SIZE; i+=4) - *(unsigned long *)(i) = 0; -} - -static void mips32_copy_page_dc(unsigned long to, unsigned long from) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) { - for (i=to; i<to+PAGE_SIZE; i+=dc_lsize) { - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "cache\t%2,(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (i) - :"0" (i), - "I" (Create_Dirty_Excl_D)); - } - } - for (i=0; i<PAGE_SIZE; i+=4) - *(unsigned long *)(to+i) = *(unsigned long *)(from+i); -} - -static void mips32_copy_page_sc(unsigned long to, unsigned long from) -{ - unsigned long i; - - if (mips_cpu.options & MIPS_CPU_CACHE_CDEX) { - for (i=to; i<to+PAGE_SIZE; i+=sc_lsize) { - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "cache\t%2,(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (i) - :"0" (i), - "I" (Create_Dirty_Excl_SD)); - } - } - for (i=0; i<PAGE_SIZE; i+=4) - *(unsigned long *)(to+i) = *(unsigned long *)(from+i); -} - -static inline void mips32_flush_cache_all_sc(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache(); blast_icache(); blast_scache(); - local_irq_restore(flags); -} - -static inline void mips32_flush_cache_all_pc(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache(); blast_icache(); - local_irq_restore(flags); -} - -static void -mips32_flush_cache_range_sc(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if(mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if(mm->context != current->mm->context) { - mips32_flush_cache_all_sc(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void mips32_flush_cache_range_pc(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if(mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - local_irq_save(flags); - blast_dcache(); blast_icache(); - local_irq_restore(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void mips32_flush_cache_mm_sc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips32_flush_cache_all_sc(); - } -} - -static void mips32_flush_cache_mm_pc(struct mm_struct *mm) -{ - if(mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - mips32_flush_cache_all_pc(); - } -} - - - - - -static void mips32_flush_cache_page_sc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache_page_indexed(page); - blast_scache_page_indexed(page); - } else - blast_scache_page(page); -out: - local_irq_restore(flags); -} - -static void mips32_flush_cache_page_pc(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since Mips32 caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache_page_indexed(page); - } -out: - local_irq_restore(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void mips32_flush_page_to_ram_sc(struct page *page) -{ - blast_scache_page((unsigned long)page_address(page)); -} - -static void mips32_flush_page_to_ram_pc(struct page *page) -{ - blast_dcache_page((unsigned long)page_address(page)); -} - -static void -mips32_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -static void -mips32_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -static void -mips32_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - int address; - - if (!(vma->vm_flags & VM_EXEC)) - return; - - address = KSEG0 + ((unsigned long)page_address(page) & PAGE_MASK & (dcache_size - 1)); - blast_icache_page_indexed(address); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -mips32_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - local_irq_save(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - local_irq_restore(flags); - } - bc_wback_inv(addr, size); -} - -static void -mips32_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips32_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - local_irq_save(flags); - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - local_irq_restore(flags); - } - - bc_inv(addr, size); -} - -static void -mips32_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -mips32_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("mips32_dma_cache called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void mips32_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -#undef DEBUG_TLB -#undef DEBUG_TLBUPDATE - -void flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < mips_cpu.tlbsize) { - /* Make sure all entries differ. */ - set_entryhi(KSEG0+entry*0x2000); - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - local_irq_restore(flags); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - local_irq_save(flags); - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - local_irq_restore(flags); - } -} - -void flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - if(idx < 0) - continue; - /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); - BARRIER; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - } - local_irq_restore(flags); - } -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - if(idx < 0) - goto finish; - /* Make sure all entries differ. */ - set_entryhi(KSEG0+idx*0x2000); - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - local_irq_restore(flags); - } -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for(i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} - -/* - * Updates the TLB with the new pte(s). - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); - } -#endif - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - local_irq_restore(flags); -} - -void show_regs(struct pt_regs * regs) -{ - /* Saved main processor registers. */ - printk("$0 : %08lx %08lx %08lx %08lx\n", - 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); - printk("$4 : %08lx %08lx %08lx %08lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - printk("$8 : %08lx %08lx %08lx %08lx\n", - regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); - printk("$12: %08lx %08lx %08lx %08lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); - printk("$16: %08lx %08lx %08lx %08lx\n", - regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); - printk("$20: %08lx %08lx %08lx %08lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); - printk("$24: %08lx %08lx\n", - regs->regs[24], regs->regs[25]); - printk("$28: %08lx %08lx %08lx %08lx\n", - regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); - - /* Saved cp0 registers. */ - printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); -} - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - flush_tlb_all(); - local_irq_restore(flags); -} - -/* Detect and size the various caches. */ -static void __init probe_icache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - mips_cpu.icache.linesz = ic_lsize; - - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.icache.ways) mips_cpu.icache.ways = 1; - mips_cpu.icache.sets = - (icache_size / ic_lsize) / mips_cpu.icache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 19) & 7))) - mips_cpu.icache.linesz = 2 << lsize; - else - mips_cpu.icache.linesz = lsize; - mips_cpu.icache.sets = 64 << ((config1 >> 22) & 7); - mips_cpu.icache.ways = 1 + ((config1 >> 16) & 7); - - ic_lsize = mips_cpu.icache.linesz; - icache_size = mips_cpu.icache.sets * mips_cpu.icache.ways * - ic_lsize; - } - printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n", - icache_size >> 10, ic_lsize, mips_cpu.icache.ways); -} - -static void __init probe_dcache(unsigned long config) -{ - unsigned long config1; - unsigned int lsize; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - mips_cpu.dcache.linesz = dc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.dcache.ways) mips_cpu.dcache.ways = 1; - mips_cpu.dcache.sets = - (dcache_size / dc_lsize) / mips_cpu.dcache.ways; - } else { - config1 = read_mips32_cp0_config1(); - - if ((lsize = ((config1 >> 10) & 7))) - mips_cpu.dcache.linesz = 2 << lsize; - else - mips_cpu.dcache.linesz= lsize; - mips_cpu.dcache.sets = 64 << ((config1 >> 13) & 7); - mips_cpu.dcache.ways = 1 + ((config1 >> 7) & 7); - - dc_lsize = mips_cpu.dcache.linesz; - dcache_size = - mips_cpu.dcache.sets * mips_cpu.dcache.ways - * dc_lsize; - } - printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n", - dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - if (mips_cpu.scache.flags == MIPS_CACHE_NOT_PRESENT) - return 0; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - local_irq_save(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 8, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 9, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 11, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 7, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - local_irq_restore(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - _clear_page = (void *)mips32_clear_page_dc; - _copy_page = (void *)mips32_copy_page_dc; - _flush_cache_all = mips32_flush_cache_all_pc; - ___flush_cache_all = mips32_flush_cache_all_pc; - _flush_cache_mm = mips32_flush_cache_mm_pc; - _flush_cache_range = mips32_flush_cache_range_pc; - _flush_cache_page = mips32_flush_cache_page_pc; - _flush_page_to_ram = mips32_flush_page_to_ram_pc; - - _flush_icache_page = mips32_flush_icache_page; - - _dma_cache_wback_inv = mips32_dma_cache_wback_inv_pc; - _dma_cache_wback = mips32_dma_cache_wback; - _dma_cache_inv = mips32_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - _flush_cache_all = mips32_flush_cache_all_sc; - ___flush_cache_all = mips32_flush_cache_all_sc; - _flush_cache_mm = mips32_flush_cache_mm_sc; - _flush_cache_range = mips32_flush_cache_range_sc; - _flush_cache_page = mips32_flush_cache_page_sc; - _flush_page_to_ram = mips32_flush_page_to_ram_sc; - _clear_page = (void *)mips32_clear_page_sc; - _copy_page = (void *)mips32_copy_page_sc; - - _flush_icache_page = mips32_flush_icache_page_s; - - _dma_cache_wback_inv = mips32_dma_cache_wback_inv_sc; - _dma_cache_wback = mips32_dma_cache_wback; - _dma_cache_inv = mips32_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - mips_cpu.scache.linesz = sc_lsize; - /* - * We cannot infer associativity - assume direct map - * unless probe template indicates otherwise - */ - if(!mips_cpu.scache.ways) mips_cpu.scache.ways = 1; - mips_cpu.scache.sets = - (scache_size / sc_lsize) / mips_cpu.scache.ways; - - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -static void __init probe_tlb(unsigned long config) -{ - unsigned long config1; - - if (!(config & (1 << 31))) { - /* - * Not a MIPS32 complainant CPU. - * Config 1 register not supported, we assume R4k style. - */ - mips_cpu.tlbsize = 48; - } else { - config1 = read_mips32_cp0_config1(); - if (!((config >> 7) & 3)) - panic("No MMU present"); - else - mips_cpu.tlbsize = ((config1 >> 25) & 0x3f) + 1; - } - - printk("Number of TLB entries %d.\n", mips_cpu.tlbsize); -} - -void __init ld_mmu_mips32(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - -#ifdef CONFIG_MIPS_UNCACHED - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); -#else - change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); -#endif - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - probe_tlb(config); - - _flush_cache_sigtramp = mips32_flush_cache_sigtramp; - _flush_icache_range = mips32_flush_icache_range; /* Ouch */ - - __flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - - /* - * You should never change this register: - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - flush_tlb_all(); -} diff -Nru a/arch/mips/mm/pg-r3k.c b/arch/mips/mm/pg-r3k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/pg-r3k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) + */ +#include <linux/sched.h> +#include <linux/mm.h> + +/* page functions */ +void r3k_clear_page(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "addiu\t$1,%0,%2\n" + "1:\tsw\t$0,(%0)\n\t" + "sw\t$0,4(%0)\n\t" + "sw\t$0,8(%0)\n\t" + "sw\t$0,12(%0)\n\t" + "addiu\t%0,32\n\t" + "sw\t$0,-16(%0)\n\t" + "sw\t$0,-12(%0)\n\t" + "sw\t$0,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t$0,-4(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE) + : "memory"); +} + +void r3k_copy_page(void * to, void * from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "addiu\t$1,%0,%8\n" + "1:\tlw\t%2,(%1)\n\t" + "lw\t%3,4(%1)\n\t" + "lw\t%4,8(%1)\n\t" + "lw\t%5,12(%1)\n\t" + "sw\t%2,(%0)\n\t" + "sw\t%3,4(%0)\n\t" + "sw\t%4,8(%0)\n\t" + "sw\t%5,12(%0)\n\t" + "lw\t%2,16(%1)\n\t" + "lw\t%3,20(%1)\n\t" + "lw\t%4,24(%1)\n\t" + "lw\t%5,28(%1)\n\t" + "sw\t%2,16(%0)\n\t" + "sw\t%3,20(%0)\n\t" + "sw\t%4,24(%0)\n\t" + "sw\t%5,28(%0)\n\t" + "addiu\t%0,64\n\t" + "addiu\t%1,64\n\t" + "lw\t%2,-32(%1)\n\t" + "lw\t%3,-28(%1)\n\t" + "lw\t%4,-24(%1)\n\t" + "lw\t%5,-20(%1)\n\t" + "sw\t%2,-32(%0)\n\t" + "sw\t%3,-28(%0)\n\t" + "sw\t%4,-24(%0)\n\t" + "sw\t%5,-20(%0)\n\t" + "lw\t%2,-16(%1)\n\t" + "lw\t%3,-12(%1)\n\t" + "lw\t%4,-8(%1)\n\t" + "lw\t%5,-4(%1)\n\t" + "sw\t%2,-16(%0)\n\t" + "sw\t%3,-12(%0)\n\t" + "sw\t%4,-8(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sw\t%5,-4(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + : "0" (to), "1" (from), + "I" (PAGE_SIZE)); +} + +/* + * Initialize new page directory with pointers to invalid ptes + */ +void pgd_init(unsigned long page) +{ + unsigned long dummy1, dummy2; + + /* + * The plain and boring version for the R3000. No cache flushing + * stuff is implemented since the R3000 has physical caches. + */ + __asm__ __volatile__( + ".set\tnoreorder\n" + "1:\tsw\t%2, (%0)\n\t" + "sw\t%2, 4(%0)\n\t" + "sw\t%2, 8(%0)\n\t" + "sw\t%2, 12(%0)\n\t" + "sw\t%2, 16(%0)\n\t" + "sw\t%2, 20(%0)\n\t" + "sw\t%2, 24(%0)\n\t" + "sw\t%2, 28(%0)\n\t" + "subu\t%1, 1\n\t" + "bnez\t%1, 1b\n\t" + "addiu\t%0, 32\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2) + :"r" ((unsigned long) invalid_pte_table), "0" (page), + "1" (USER_PTRS_PER_PGD / 8)); +} diff -Nru a/arch/mips/mm/pg-r4k.S b/arch/mips/mm/pg-r4k.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/pg-r4k.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,803 @@ +/* + * 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. + * + * r4xx0.c: R4000 processor variant specific MMU/Cache routines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org + */ +#include <linux/config.h> +#include <asm/addrspace.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/cacheops.h> +#include <asm/mipsregs.h> +#include <asm/offset.h> + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PGD_SIZE 0x2000 +#else +#define PGD_SIZE 0x1000 +#endif + + .text + .set noat + +/* + * Zero an entire page. Basically a simple unrolled loop should do the + * job but we want more performance by saving memory bus bandwidth. We + * have five flavours of the routine available for: + * + * - 16byte cachelines and no second level cache + * - 32byte cachelines second level cache + * - a version which handles the buggy R4600 v1.x + * - a version which handles the buggy R4600 v2.0 + * - Finally a last version without fancy cache games for the SC and MC + * versions of R4000 and R4400. + */ + +LEAF(r4k_clear_page32_d16) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + sw zero, (a0) + sw zero, 4(a0) + sw zero, 8(a0) + sw zero, 12(a0) + addiu a0, 32 + cache Create_Dirty_Excl_D, -16(a0) + sw zero, -16(a0) + sw zero, -12(a0) + sw zero, -8(a0) + sw zero, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page32_d16) + +LEAF(r4k_clear_page32_d32) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + sw zero, (a0) + sw zero, 4(a0) + sw zero, 8(a0) + sw zero, 12(a0) + addiu a0, 32 + sw zero, -16(a0) + sw zero, -12(a0) + sw zero, -8(a0) + sw zero, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page32_d32) + +LEAF(r4k_clear_page_d16) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + sd zero, (a0) + sd zero, 8(a0) + cache Create_Dirty_Excl_D, 16(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + cache Create_Dirty_Excl_D, -32(a0) + sd zero, -32(a0) + sd zero, -24(a0) + cache Create_Dirty_Excl_D, -16(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_d16) + +LEAF(r4k_clear_page_d32) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + sd zero, (a0) + sd zero, 8(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + cache Create_Dirty_Excl_D, -32(a0) + sd zero, -32(a0) + sd zero, -24(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_d32) + +/* + * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the + * IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + */ + +LEAF(r4k_clear_page_r4600_v1) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: nop + nop + nop + nop + cache Create_Dirty_Excl_D, (a0) + sd zero, (a0) + sd zero, 8(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + nop + nop + nop + cache Create_Dirty_Excl_D, -32(a0) + sd zero, -32(a0) + sd zero, -24(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_r4600_v1) + +LEAF(r4k_clear_page_r4600_v2) + .set mips3 + mfc0 a1, CP0_STATUS + ori AT, a1, 1 + xori AT, 1 + mtc0 AT, CP0_STATUS + nop + nop + nop + + .set volatile + la AT, KSEG1 + lw zero, (AT) + .set novolatile + + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + sd zero, (a0) + sd zero, 8(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + cache Create_Dirty_Excl_D, -32(a0) + sd zero, -32(a0) + sd zero, -24(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + + mfc0 AT, CP0_STATUS # local_irq_restore + andi a1, 1 + ori AT, 1 + xori AT, 1 + or a1, AT + mtc0 a1, CP0_STATUS + nop + nop + nop + + jr ra + END(r4k_clear_page_r4600_v2) + +/* + * The next 4 versions are optimized for all possible scache configurations + * of the SC / MC versions of R4000 and R4400 ... + * + * Todo: For even better performance we should have a routine optimized for + * every legal combination of dcache / scache linesize. When I (Ralf) tried + * this the kernel crashed shortly after mounting the root filesystem. CPU + * bug? Weirdo cache instruction semantics? + */ + +LEAF(r4k_clear_page_s16) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + sd zero, (a0) + sd zero, 8(a0) + cache Create_Dirty_Excl_SD, 16(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + cache Create_Dirty_Excl_SD, -32(a0) + sd zero, -32(a0) + sd zero, -24(a0) + cache Create_Dirty_Excl_SD, -16(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_s16) + +LEAF(r4k_clear_page_s32) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + sd zero, (a0) + sd zero, 8(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + cache Create_Dirty_Excl_SD, -32(a0) + sd zero, -32(a0) + sd zero, -24(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_s32) + +LEAF(r4k_clear_page_s64) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + sd zero, (a0) + sd zero, 8(a0) + sd zero, 16(a0) + sd zero, 24(a0) + addiu a0, 64 + sd zero, -32(a0) + sd zero, -24(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_s64) + +LEAF(r4k_clear_page_s128) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + sd zero, (a0) + sd zero, 8(a0) + sd zero, 16(a0) + sd zero, 24(a0) + sd zero, 32(a0) + sd zero, 40(a0) + sd zero, 48(a0) + sd zero, 56(a0) + addiu a0, 128 + sd zero, -64(a0) + sd zero, -56(a0) + sd zero, -48(a0) + sd zero, -40(a0) + sd zero, -32(a0) + sd zero, -24(a0) + sd zero, -16(a0) + sd zero, -8(a0) + bne AT, a0, 1b + jr ra + END(r4k_clear_page_s128) + +/* + * This is suboptimal for 32-bit kernels; we assume that R10000 is only used + * with 64-bit kernels. The prefetch offsets have been experimentally tuned + * an Origin 200. + */ +LEAF(andes_clear_page) + .set mips4 + LONG_ADDIU AT, a0, _PAGE_SIZE +1: pref 7, 512(a0) + sd zero, 0*SZREG(a0) + sd zero, 1*SZREG(a0) + sd zero, 2*SZREG(a0) + sd zero, 3*SZREG(a0) + LONG_ADDIU a0, a0, 8*SZREG + sd zero, -4*SZREG(a0) + sd zero, -3*SZREG(a0) + sd zero, -2*SZREG(a0) + sd zero, -1*SZREG(a0) + bne AT, a0, 1b + j ra + END(andes_clear_page) + .set mips0 + +/* + * This is still inefficient. We only can do better if we know the + * virtual address where the copy will be accessed. + */ + +LEAF(r4k_copy_page_d16) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + cache Create_Dirty_Excl_D, 16(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + cache Create_Dirty_Excl_D, 32(a0) + addiu a0, 64 + addiu a1, 64 + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + cache Create_Dirty_Excl_D, -16(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_d16) + +LEAF(r4k_copy_page_d32) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_D, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + cache Create_Dirty_Excl_D, 32(a0) + addiu a0, 64 + addiu a1, 64 + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_d32) + +/* + * Again a special version for the R4600 V1.x + */ + +LEAF(r4k_copy_page_r4600_v1) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: nop + nop + nop + nop + cache Create_Dirty_Excl_D, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + nop + nop + nop + nop + cache Create_Dirty_Excl_D, 32(a0) + addiu a0, 64 + addiu a1, 64 + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_r4600_v1) + +LEAF(r4k_copy_page_r4600_v2) + .set mips3 + mfc0 v1, CP0_STATUS + ori AT, v1, 1 + xori AT, 1 + + mtc0 AT, CP0_STATUS + nop + nop + nop + + addiu AT, a0, _PAGE_SIZE +1: nop + nop + nop + nop + cache Create_Dirty_Excl_D, (a0) + lw t1, (a1) + lw t0, 4(a1) + lw a3, 8(a1) + lw a2, 12(a1) + sw t1, (a0) + sw t0, 4(a0) + sw a3, 8(a0) + sw a2, 12(a0) + lw t1, 16(a1) + lw t0, 20(a1) + lw a3, 24(a1) + lw a2, 28(a1) + sw t1, 16(a0) + sw t0, 20(a0) + sw a3, 24(a0) + sw a2, 28(a0) + nop + nop + nop + nop + cache Create_Dirty_Excl_D, 32(a0) + addiu a0, 64 + addiu a1, 64 + lw t1, -32(a1) + lw t0, -28(a1) + lw a3, -24(a1) + lw a2, -20(a1) + sw t1, -32(a0) + sw t0, -28(a0) + sw a3, -24(a0) + sw a2, -20(a0) + lw t1, -16(a1) + lw t0, -12(a1) + lw a3, -8(a1) + lw a2, -4(a1) + sw t1, -16(a0) + sw t0, -12(a0) + sw a3, -8(a0) + sw a2, -4(a0) + bne AT, a0, 1b + + mfc0 AT, CP0_STATUS # local_irq_restore + andi v1, 1 + ori AT, 1 + xori AT, 1 + or v1, AT + mtc0 v1, CP0_STATUS + nop + nop + nop + jr ra + END(r4k_copy_page_r4600_v2) + +/* + * These are for R4000SC / R4400MC + */ + +LEAF(r4k_copy_page_s16) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + cache Create_Dirty_Excl_SD, 16(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + cache Create_Dirty_Excl_SD, 32(a0) + addiu a0, 64 + addiu a1, 64 + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + cache Create_Dirty_Excl_SD, -16(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_s16) + +LEAF(r4k_copy_page_s32) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + cache Create_Dirty_Excl_SD, 32(a0) + addiu a0, 64 + addiu a1, 64 + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_s32) + +LEAF(r4k_copy_page_s64) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + addiu a0, 64 + addiu a1, 64 + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_s64) + +LEAF(r4k_copy_page_s128) + .set mips3 + addiu AT, a0, _PAGE_SIZE +1: cache Create_Dirty_Excl_SD, (a0) + lw a3, (a1) + lw a2, 4(a1) + lw v1, 8(a1) + lw v0, 12(a1) + sw a3, (a0) + sw a2, 4(a0) + sw v1, 8(a0) + sw v0, 12(a0) + lw a3, 16(a1) + lw a2, 20(a1) + lw v1, 24(a1) + lw v0, 28(a1) + sw a3, 16(a0) + sw a2, 20(a0) + sw v1, 24(a0) + sw v0, 28(a0) + lw a3, 32(a1) + lw a2, 36(a1) + lw v1, 40(a1) + lw v0, 44(a1) + sw a3, 32(a0) + sw a2, 36(a0) + sw v1, 40(a0) + sw v0, 44(a0) + lw a3, 48(a1) + lw a2, 52(a1) + lw v1, 56(a1) + lw v0, 60(a1) + sw a3, 48(a0) + sw a2, 52(a0) + sw v1, 56(a0) + sw v0, 60(a0) + addiu a0, 128 + addiu a1, 128 + lw a3, -64(a1) + lw a2, -60(a1) + lw v1, -56(a1) + lw v0, -52(a1) + sw a3, -64(a0) + sw a2, -60(a0) + sw v1, -56(a0) + sw v0, -52(a0) + lw a3, -48(a1) + lw a2, -44(a1) + lw v1, -40(a1) + lw v0, -36(a1) + sw a3, -48(a0) + sw a2, -44(a0) + sw v1, -40(a0) + sw v0, -36(a0) + lw a3, -32(a1) + lw a2, -28(a1) + lw v1, -24(a1) + lw v0, -20(a1) + sw a3, -32(a0) + sw a2, -28(a0) + sw v1, -24(a0) + sw v0, -20(a0) + lw a3, -16(a1) + lw a2, -12(a1) + lw v1, -8(a1) + lw v0, -4(a1) + sw a3, -16(a0) + sw a2, -12(a0) + sw v1, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(r4k_copy_page_s128) + + + .text + .set mips4 + .set noat + + +/* + * This is suboptimal for 32-bit kernels; we assume that R10000 is only used + * with 64-bit kernels. The prefetch offsets have been experimentally tuned + * an Origin 200. + */ +LEAF(andes_copy_page) + .set mips4 + LONG_ADDIU AT, a0, _PAGE_SIZE +1: pref 0, 2*128(a1) + pref 1, 2*128(a0) + LONG_L a3, 0*SZREG(a1) + LONG_L a2, 1*SZREG(a1) + LONG_L v1, 2*SZREG(a1) + LONG_L v0, 3*SZREG(a1) + LONG_S a3, 0*SZREG(a0) + LONG_S a2, 1*SZREG(a0) + LONG_S v1, 2*SZREG(a0) + LONG_S v0, 3*SZREG(a0) + LONG_ADDIU a0, a0, 8*SZREG + LONG_ADDIU a1, a1, 8*SZREG + LONG_L a3, -4*SZREG(a1) + LONG_L a2, -3*SZREG(a1) + LONG_L v1, -2*SZREG(a1) + LONG_L v0, -1*SZREG(a1) + LONG_S a3, -4*SZREG(a0) + LONG_S a2, -3*SZREG(a0) + LONG_S v1, -2*SZREG(a0) + LONG_S v0, -1*SZREG(a0) + bne AT, a0,1b + j ra + END(andes_copy_page) + .set mips0 + +/* This one still needs to receive cache optimizations */ +LEAF(pgd_init) + .set mips0 + addiu AT, a0, PGD_SIZE / 2 + la v0, invalid_pte_table +1: sw v0, (a0) + sw v0, 4(a0) + sw v0, 8(a0) + sw v0, 12(a0) + addiu a0, 32 + sw v0, -16(a0) + sw v0, -12(a0) + sw v0, -8(a0) + sw v0, -4(a0) + bne AT, a0, 1b + jr ra + END(pgd_init) diff -Nru a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/pg-sb1.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2000 Sibyte + * + * Written by Justin Carlson (carlson@sibyte.com) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <asm/page.h> + +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS +#define SB1_PREF_LOAD_STREAMED_HINT "0" +#define SB1_PREF_STORE_STREAMED_HINT "1" +#else +#define SB1_PREF_LOAD_STREAMED_HINT "4" +#define SB1_PREF_STORE_STREAMED_HINT "5" +#endif + +/* These are the functions hooked by the memory management function pointers */ +void sb1_clear_page(void *page) +{ + /* + * JDCXXX - This should be bottlenecked by the write buffer, but these + * things tend to be mildly unpredictable...should check this on the + * performance model + * + * We prefetch 4 lines ahead. We're also "cheating" slightly here... + * since we know we're on an SB1, we force the assembler to take + * 64-bit operands to speed things up + */ + __asm__ __volatile__( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " addiu $1, %0, %2 \n" /* Calculate the end of the page to clear */ +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 4 lines */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%0) \n" +#endif + "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ + " sd $0, 8(%0) \n" + " sd $0, 16(%0) \n" + " sd $0, 24(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_STORE_STREAMED_HINT ",128(%0) \n" /* Prefetch 4 lines ahead */ +#endif + " bne $1, %0, 1b \n" + " addiu %0, %0, 32 \n" /* Next cacheline (This instruction better be short piped!) */ + ".set pop \n" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE-32) + : "memory"); + +} + +void sb1_copy_page(void *to, void *from) +{ + + /* + * This should be optimized in assembly...can't use ld/sd, though, + * because the top 32 bits could be nuked if we took an interrupt + * during the routine. And this is not a good place to be cli()'ing + * + * The pref's used here are using "streaming" hints, which cause the + * copied data to be kicked out of the cache sooner. A page copy often + * ends up copying a lot more data than is commonly used, so this seems + * to make sense in terms of reducing cache pollution, but I've no real + * performance data to back this up + */ + + __asm__ __volatile__( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " addiu $1, %0, %4 \n" /* Calculate the end of the page to copy */ +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 3 lines */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%1) \n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 32(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%1) \n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 64(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%1) \n" +#endif + "1: lw $2, 0(%0) \n" /* Block copy a cacheline */ + " lw $3, 4(%0) \n" + " lw $4, 8(%0) \n" + " lw $5, 12(%0) \n" + " lw $6, 16(%0) \n" + " lw $7, 20(%0) \n" + " lw $8, 24(%0) \n" + " lw $9, 28(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 96(%0) \n" /* Prefetch ahead */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%1) \n" +#endif + " sw $2, 0(%1) \n" + " sw $3, 4(%1) \n" + " sw $4, 8(%1) \n" + " sw $5, 12(%1) \n" + " sw $6, 16(%1) \n" + " sw $7, 20(%1) \n" + " sw $8, 24(%1) \n" + " sw $9, 28(%1) \n" + " addiu %1, %1, 32 \n" /* Next cacheline */ + " nop \n" /* Force next add to short pipe */ + " nop \n" /* Force next add to short pipe */ + " bne $1, %0, 1b \n" + " addiu %0, %0, 32 \n" /* Next cacheline */ + ".set pop \n" + : "=r" (to), "=r" (from) + : "0" (from), "1" (to), "I" (PAGE_SIZE-32) + : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); +} diff -Nru a/arch/mips/mm/pgtable.c b/arch/mips/mm/pgtable.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/pgtable.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,33 @@ +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/swap.h> + +void show_mem(void) +{ + int pfn, total = 0, reserved = 0; + int shared = 0, cached = 0; + int highmem = 0; + struct page *page; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + pfn = max_mapnr; + while (pfn-- > 0) { + page = pfn_to_page(pfn); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + printk("%d pages of RAM\n", total); + printk("%d pages of HIGHMEM\n",highmem); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} diff -Nru a/arch/mips/mm/r2300.c b/arch/mips/mm/r2300.c --- a/arch/mips/mm/r2300.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,804 +0,0 @@ -/* - * r2300.c: R2000 and R3000 specific mmu/cache code. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * with a lot of changes to make this thing work for R3000s - * Tx39XX R4k style caches added. HK - * Copyright (C) 1998, 1999, 2000 Harald Koerfgen - * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/mmu_context.h> -#include <asm/system.h> -#include <asm/isadep.h> -#include <asm/io.h> -#include <asm/wbflush.h> -#include <asm/bootinfo.h> -#include <asm/cpu.h> - -/* - * According to the paper written by D. Miller about Linux cache & TLB - * flush implementation, DMA/Driver coherence should be done at the - * driver layer. Thus, normally, we don't need flush dcache for R3000. - * Define this if driver does not handle cache consistency during DMA ops. - */ - -/* For R3000 cores with R4000 style caches */ -static unsigned long icache_size, dcache_size; /* Size in bytes */ -static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */ -static unsigned long scache_size; - -#include <asm/cacheops.h> -#include <asm/r4kcache.h> - -#undef DEBUG_TLB -#undef DEBUG_CACHE - -/* page functions */ -void r3k_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%2\n" - "1:\tsw\t$0,(%0)\n\t" - "sw\t$0,4(%0)\n\t" - "sw\t$0,8(%0)\n\t" - "sw\t$0,12(%0)\n\t" - "addiu\t%0,32\n\t" - "sw\t$0,-16(%0)\n\t" - "sw\t$0,-12(%0)\n\t" - "sw\t$0,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t$0,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE) - :"$1","memory"); -} - -static void r3k_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "addiu\t$1,%0,%8\n" - "1:\tlw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "addiu\t%0,64\n\t" - "addiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE)); -} - -unsigned long __init r3k_cache_size(unsigned long ca_flags) -{ - unsigned long flags, status, dummy, size; - volatile unsigned long *p; - - p = (volatile unsigned long *) KSEG0; - - flags = read_32bit_cp0_register(CP0_STATUS); - - /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC); - - *p = 0xa5a55a5a; - dummy = *p; - status = read_32bit_cp0_register(CP0_STATUS); - - if (dummy != 0xa5a55a5a || (status & ST0_CM)) { - size = 0; - } else { - for (size = 128; size <= 0x40000; size <<= 1) - *(p + size) = 0; - *p = -1; - for (size = 128; - (size <= 0x40000) && (*(p + size) == 0); - size <<= 1) - ; - if (size > 0x40000) - size = 0; - } - - write_32bit_cp0_register(CP0_STATUS, flags); - - return size * sizeof(*p); -} - -unsigned long __init r3k_cache_lsize(unsigned long ca_flags) -{ - unsigned long flags, status, lsize, i, j; - volatile unsigned long *p; - - p = (volatile unsigned long *) KSEG0; - - flags = read_32bit_cp0_register(CP0_STATUS); - - /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC); - - for (i = 0; i < 128; i++) - *(p + i) = 0; - *(volatile unsigned char *)p = 0; - for (lsize = 1; lsize < 128; lsize <<= 1) { - *(p + lsize); - status = read_32bit_cp0_register(CP0_STATUS); - if (!(status & ST0_CM)) - break; - } - for (i = 0; i < 128; i += lsize) - *(volatile unsigned char *)(p + i) = 0; - - write_32bit_cp0_register(CP0_STATUS, flags); - - return lsize * sizeof(*p); -} - -static void __init r3k_probe_cache(void) -{ - dcache_size = r3k_cache_size(ST0_ISC); - if (dcache_size) - dcache_lsize = r3k_cache_lsize(ST0_ISC); - - - icache_size = r3k_cache_size(ST0_ISC|ST0_SWC); - if (icache_size) - icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC); -} - -static void r3k_flush_icache_range(unsigned long start, unsigned long end) -{ - unsigned long size, i, flags; - volatile unsigned char *p = (char *)start; - - size = end - start; - if (size > icache_size) - size = icache_size; - - flags = read_32bit_cp0_register(CP0_STATUS); - - /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC); - - for (i = 0; i < size; i += 0x080) { - asm ( "sb\t$0,0x000(%0)\n\t" - "sb\t$0,0x004(%0)\n\t" - "sb\t$0,0x008(%0)\n\t" - "sb\t$0,0x00c(%0)\n\t" - "sb\t$0,0x010(%0)\n\t" - "sb\t$0,0x014(%0)\n\t" - "sb\t$0,0x018(%0)\n\t" - "sb\t$0,0x01c(%0)\n\t" - "sb\t$0,0x020(%0)\n\t" - "sb\t$0,0x024(%0)\n\t" - "sb\t$0,0x028(%0)\n\t" - "sb\t$0,0x02c(%0)\n\t" - "sb\t$0,0x030(%0)\n\t" - "sb\t$0,0x034(%0)\n\t" - "sb\t$0,0x038(%0)\n\t" - "sb\t$0,0x03c(%0)\n\t" - "sb\t$0,0x040(%0)\n\t" - "sb\t$0,0x044(%0)\n\t" - "sb\t$0,0x048(%0)\n\t" - "sb\t$0,0x04c(%0)\n\t" - "sb\t$0,0x050(%0)\n\t" - "sb\t$0,0x054(%0)\n\t" - "sb\t$0,0x058(%0)\n\t" - "sb\t$0,0x05c(%0)\n\t" - "sb\t$0,0x060(%0)\n\t" - "sb\t$0,0x064(%0)\n\t" - "sb\t$0,0x068(%0)\n\t" - "sb\t$0,0x06c(%0)\n\t" - "sb\t$0,0x070(%0)\n\t" - "sb\t$0,0x074(%0)\n\t" - "sb\t$0,0x078(%0)\n\t" - "sb\t$0,0x07c(%0)\n\t" - : : "r" (p) ); - p += 0x080; - } - - write_32bit_cp0_register(CP0_STATUS,flags); -} - -static void r3k_flush_dcache_range(unsigned long start, unsigned long end) -{ - unsigned long size, i, flags; - volatile unsigned char *p = (char *)start; - - size = end - start; - if (size > dcache_size) - size = dcache_size; - - flags = read_32bit_cp0_register(CP0_STATUS); - - /* isolate cache space */ - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|flags)&~ST0_IEC); - - for (i = 0; i < size; i += 0x080) { - asm ( "sb\t$0,0x000(%0)\n\t" - "sb\t$0,0x004(%0)\n\t" - "sb\t$0,0x008(%0)\n\t" - "sb\t$0,0x00c(%0)\n\t" - "sb\t$0,0x010(%0)\n\t" - "sb\t$0,0x014(%0)\n\t" - "sb\t$0,0x018(%0)\n\t" - "sb\t$0,0x01c(%0)\n\t" - "sb\t$0,0x020(%0)\n\t" - "sb\t$0,0x024(%0)\n\t" - "sb\t$0,0x028(%0)\n\t" - "sb\t$0,0x02c(%0)\n\t" - "sb\t$0,0x030(%0)\n\t" - "sb\t$0,0x034(%0)\n\t" - "sb\t$0,0x038(%0)\n\t" - "sb\t$0,0x03c(%0)\n\t" - "sb\t$0,0x040(%0)\n\t" - "sb\t$0,0x044(%0)\n\t" - "sb\t$0,0x048(%0)\n\t" - "sb\t$0,0x04c(%0)\n\t" - "sb\t$0,0x050(%0)\n\t" - "sb\t$0,0x054(%0)\n\t" - "sb\t$0,0x058(%0)\n\t" - "sb\t$0,0x05c(%0)\n\t" - "sb\t$0,0x060(%0)\n\t" - "sb\t$0,0x064(%0)\n\t" - "sb\t$0,0x068(%0)\n\t" - "sb\t$0,0x06c(%0)\n\t" - "sb\t$0,0x070(%0)\n\t" - "sb\t$0,0x074(%0)\n\t" - "sb\t$0,0x078(%0)\n\t" - "sb\t$0,0x07c(%0)\n\t" - : : "r" (p) ); - p += 0x080; - } - - write_32bit_cp0_register(CP0_STATUS,flags); -} - -static inline unsigned long get_phys_page (unsigned long addr, - struct mm_struct *mm) -{ - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - unsigned long physpage; - - pgd = pgd_offset(mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - - if ((physpage = pte_val(*pte)) & _PAGE_VALID) - return KSEG0ADDR(physpage & PAGE_MASK); - - return 0; -} - -static inline void r3k_flush_cache_all(void) -{ - r3k_flush_icache_range(KSEG0, KSEG0 + icache_size); -} - -static void r3k_flush_cache_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r3k_flush_cache_all(); - } -} - -static void r3k_flush_cache_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (mm->context != current->active_mm->context) { - flush_cache_all(); - } else { - unsigned long flags, physpage; - - save_and_cli(flags); - while (start < end) { - if ((physpage = get_phys_page(start, mm))) - r3k_flush_icache_range(physpage, - physpage + PAGE_SIZE); - start += PAGE_SIZE; - } - restore_flags(flags); - } -} - -static void r3k_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - if (vma->vm_flags & VM_EXEC) { - unsigned long physpage; - - if ((physpage = get_phys_page(page, vma->vm_mm))) - r3k_flush_icache_range(physpage, physpage + PAGE_SIZE); - } -} - -static void r3k_flush_page_to_ram(struct page * page) -{ - /* - * Nothing to be done - */ -} - -static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long physpage; - - if (mm->context == 0) - return; - - if (!(vma->vm_flags & VM_EXEC)) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - - physpage = (unsigned long) page_address(page); - if (physpage) - r3k_flush_icache_range(physpage, physpage + PAGE_SIZE); -} - -static void r3k_flush_cache_sigtramp(unsigned long addr) -{ - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("csigtramp[%08lx]", addr); -#endif - - flags = read_32bit_cp0_register(CP0_STATUS); - - write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC); - - /* Fill the TLB to avoid an exception with caches isolated. */ - asm ( "lw\t$0,0x000(%0)\n\t" - "lw\t$0,0x004(%0)\n\t" - : : "r" (addr) ); - - write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC); - - asm ( "sb\t$0,0x000(%0)\n\t" - "sb\t$0,0x004(%0)\n\t" - : : "r" (addr) ); - - write_32bit_cp0_register(CP0_STATUS, flags); -} - -static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) -{ - wbflush(); - r3k_flush_dcache_range(start, start + size); -} - -/* TLB operations. */ -void flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - save_and_cli(flags); - old_ctx = (get_entryhi() & 0xfc0); - write_32bit_cp0_register(CP0_ENTRYLO0, 0); - for (entry = 8; entry < mips_cpu.tlbsize; entry++) { - write_32bit_cp0_register(CP0_INDEX, entry << 8); - write_32bit_cp0_register(CP0_ENTRYHI, ((entry | 0x80000) << 12)); - __asm__ __volatile__("tlbwi"); - } - set_entryhi(old_ctx); - restore_flags(flags); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%lu>]", (unsigned long) mm->context); -#endif - save_and_cli(flags); - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); - restore_flags(flags); - } -} - -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", - (mm->context & 0xfc0), start, end); -#endif - save_and_cli(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if(size <= mips_cpu.tlbsize) { - int oldpid = (get_entryhi() & 0xfc0); - int newpid = (mm->context & 0xfc0); - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += PAGE_SIZE; - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if(idx < 0) - continue; - tlb_write_indexed(); - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xfc0); - } - restore_flags(flags); - } -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if(vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%lu,0x%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xfc0); - page &= PAGE_MASK; - save_and_cli(flags); - oldpid = (get_entryhi() & 0xfc0); - set_entryhi(page | newpid); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - tlb_write_indexed(); - -finish: - set_entryhi(oldpid); - restore_flags(flags); - } -} - -/* - * Initialize new page directory with pointers to invalid ptes - */ -void pgd_init(unsigned long page) -{ - unsigned long dummy1, dummy2; - - /* - * The plain and boring version for the R3000. No cache flushing - * stuff is implemented since the R3000 has physical caches. - */ - __asm__ __volatile__( - ".set\tnoreorder\n" - "1:\tsw\t%2,(%0)\n\t" - "sw\t%2,4(%0)\n\t" - "sw\t%2,8(%0)\n\t" - "sw\t%2,12(%0)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%2,20(%0)\n\t" - "sw\t%2,24(%0)\n\t" - "sw\t%2,28(%0)\n\t" - "subu\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,32\n\t" - ".set\treorder" - :"=r" (dummy1), - "=r" (dummy2) - :"r" ((unsigned long) invalid_pte_table), - "0" (page), - "1" (PAGE_SIZE/(sizeof(pmd_t)*8))); -} - -void update_mmu_cache(struct vm_area_struct * vma, unsigned long address, - pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xfc0; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xfc0)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", - (vma->vm_mm->context & 0xfc0), pid); - } -#endif - - save_and_cli(flags); - address &= PAGE_MASK; - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep)); - set_entryhi(address | (pid)); - if(idx < 0) { - tlb_write_random(); -#if 0 - printk("[MISS]"); -#endif - } else { - tlb_write_indexed(); -#if 0 - printk("[HIT]"); -#endif - } - set_entryhi(pid); - restore_flags(flags); -} - -void show_regs(struct pt_regs * regs) -{ - /* - * Saved main processor registers - */ - printk("$0 : %08x %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - 0, (unsigned long) regs->regs[1], (unsigned long) regs->regs[2], - (unsigned long) regs->regs[3], (unsigned long) regs->regs[4], - (unsigned long) regs->regs[5], (unsigned long) regs->regs[6], - (unsigned long) regs->regs[7]); - printk("$8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (unsigned long) regs->regs[8], (unsigned long) regs->regs[9], - (unsigned long) regs->regs[10], (unsigned long) regs->regs[11], - (unsigned long) regs->regs[12], (unsigned long) regs->regs[13], - (unsigned long) regs->regs[14], (unsigned long) regs->regs[15]); - printk("$16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - (unsigned long) regs->regs[16], (unsigned long) regs->regs[17], - (unsigned long) regs->regs[18], (unsigned long) regs->regs[19], - (unsigned long) regs->regs[20], (unsigned long) regs->regs[21], - (unsigned long) regs->regs[22], (unsigned long) regs->regs[23]); - printk("$24: %08lx %08lx %08lx %08lx %08lx %08lx\n", - (unsigned long) regs->regs[24], (unsigned long) regs->regs[25], - (unsigned long) regs->regs[28], (unsigned long) regs->regs[29], - (unsigned long) regs->regs[30], (unsigned long) regs->regs[31]); - - /* - * Saved cp0 registers - */ - printk("epc : %08lx %s\nStatus: %08x\nCause : %08x\n", - (unsigned long) regs->cp0_epc, - print_tainted(), - (unsigned int) regs->cp0_status, - (unsigned int) regs->cp0_cause); -} - -/* Todo: handle r4k-style TX39 TLB */ -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long old_ctx; - static unsigned long wired = 0; - - if (wired < 8) { - save_and_cli(flags); - old_ctx = get_entryhi() & 0xfc0; - set_entrylo0(entrylo0); - set_entryhi(entryhi); - set_index(wired); - wired++; - tlb_write_indexed(); - set_entryhi(old_ctx); - flush_tlb_all(); - restore_flags(flags); - } -} - -static void tx39_flush_icache_all(void ) -{ - - unsigned long start = KSEG0; - unsigned long end = (start + icache_size); - unsigned long dummy = 0; - - /* disable icache and stop streaming */ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "mfc0\t%0,$3\n\t" - "xori\t%0,32\n\t" - "mtc0\t%0,$3\n\t" - "j\t1f\n\t" - "nop\n\t" - "1:\t.set\treorder\n\t" - : : "r"(dummy)); - - /* invalidate icache */ - while (start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } - - /* enable icache */ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "mfc0\t%0,$3\n\t" - "xori\t%0,32\n\t" - "mtc0\t%0,$3\n\t" - ".set\treorder\n\t" - : : "r"(dummy)); -} - -static __init void tx39_probe_cache(void) -{ - unsigned long config; - - config = read_32bit_cp0_register(CP0_CONF); - - icache_size = 1 << (10 + ((config >> 19) & 3)); - icache_lsize = 16; - - dcache_size = 1 << (10 + ((config >> 16) & 3)); - dcache_lsize = 4; -} - -void __init ld_mmu_r23000(void) -{ - unsigned long config; - - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - - _clear_page = r3k_clear_page; - _copy_page = r3k_copy_page; - - switch (mips_cpu.cputype) { - case CPU_R2000: - case CPU_R3000: - case CPU_R3000A: - case CPU_R3081: - case CPU_R3081E: - - r3k_probe_cache(); - - _flush_cache_all = r3k_flush_cache_all; - ___flush_cache_all = r3k_flush_cache_all; - _flush_cache_mm = r3k_flush_cache_mm; - _flush_cache_range = r3k_flush_cache_range; - _flush_cache_page = r3k_flush_cache_page; - _flush_cache_sigtramp = r3k_flush_cache_sigtramp; - _flush_page_to_ram = r3k_flush_page_to_ram; - _flush_icache_page = r3k_flush_icache_page; - _flush_icache_range = r3k_flush_icache_range; - - _dma_cache_wback_inv = r3k_dma_cache_wback_inv; - break; - - case CPU_TX3912: - case CPU_TX3922: - case CPU_TX3927: - - config=read_32bit_cp0_register(CP0_CONF); - config &= ~TX39_CONF_WBON; - write_32bit_cp0_register(CP0_CONF, config); - - tx39_probe_cache(); - - _flush_cache_all = tx39_flush_icache_all; - ___flush_cache_all = tx39_flush_icache_all; - _flush_cache_mm = tx39_flush_icache_all; - _flush_cache_range = tx39_flush_icache_all; - _flush_cache_page = tx39_flush_icache_all; - _flush_cache_sigtramp = tx39_flush_icache_all; - _flush_page_to_ram = r3k_flush_page_to_ram; - _flush_icache_page = tx39_flush_icache_all; - _flush_icache_range = tx39_flush_icache_all; - - _dma_cache_wback_inv = r3k_dma_cache_wback_inv; - - break; - } - - printk("Primary instruction cache %dkb, linesize %d bytes\n", - (int) (icache_size >> 10), (int) icache_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - (int) (dcache_size >> 10), (int) dcache_lsize); - - flush_tlb_all(); -} diff -Nru a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c --- a/arch/mips/mm/r4xx0.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2712 +0,0 @@ -/* - * 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. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/bootinfo.h> -#include <asm/cpu.h> -#include <asm/bcache.h> -#include <asm/io.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/mmu_context.h> - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include <asm/cacheops.h> -#include <asm/r4kcache.h> - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - -/* - * On processors with QED R4600 style two set assosicative cache - * this is the bit which selects the way in the cache for the - * indexed cachops. - */ -#define icache_waybit (icache_size >> 1) -#define dcache_waybit (dcache_size >> 1) - -/* - * Zero an entire page. Basically a simple unrolled loop should do the - * job but we want more performance by saving memory bus bandwidth. We - * have five flavours of the routine available for: - * - * - 16byte cachelines and no second level cache - * - 32byte cachelines second level cache - * - a version which handles the buggy R4600 v1.x - * - a version which handles the buggy R4600 v2.0 - * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. - */ - -static void r4k_clear_page_d16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1","memory"); -} - -static void r4k_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1","memory"); -} - - -/* - * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the - * IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. - * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ -static void r4k_clear_page_r4600_v1(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1","memory"); -} - -/* - * And this one is for the R4600 V2.0 - */ -static void r4k_clear_page_r4600_v2(void * page) -{ - unsigned int flags; - - local_irq_save(flags); - *(volatile unsigned int *)KSEG1; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1","memory"); - local_irq_restore(flags); -} - -/* - * The next 4 versions are optimized for all possible scache configurations - * of the SC / MC versions of R4000 and R4400 ... - * - * Todo: For even better performance we should have a routine optimized for - * every legal combination of dcache / scache linesize. When I (Ralf) tried - * this the kernel crashed shortly after mounting the root filesystem. CPU - * bug? Weirdo cache instruction semantics? - */ -static void r4k_clear_page_s16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - -static void r4k_clear_page_s32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - -static void r4k_clear_page_s64(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - -static void r4k_clear_page_s128(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "sd\t$0,32(%0)\n\t" - "sd\t$0,40(%0)\n\t" - "sd\t$0,48(%0)\n\t" - "sd\t$0,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "sd\t$0,-64(%0)\n\t" - "sd\t$0,-56(%0)\n\t" - "sd\t$0,-48(%0)\n\t" - "sd\t$0,-40(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -static void r4k_copy_page_d16(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "cache\t%9,16(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "cache\t%9,-16(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -/* - * Again a special version for the R4600 V1.x - */ -static void r4k_copy_page_r4600_v1(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_r4600_v2(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - unsigned int flags; - - local_irq_save(flags); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); - local_irq_restore(flags); -} - -/* - * These are for R4000SC / R4400MC - */ -static void r4k_copy_page_s16(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "cache\t%9,16(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "cache\t%9,-16(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s32(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s64(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s128(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "lw\t%2,32(%1)\n\t" - "lw\t%3,36(%1)\n\t" - "lw\t%4,40(%1)\n\t" - "lw\t%5,44(%1)\n\t" - "sw\t%2,32(%0)\n\t" - "sw\t%3,36(%0)\n\t" - "sw\t%4,40(%0)\n\t" - "sw\t%5,44(%0)\n\t" - "lw\t%2,48(%1)\n\t" - "lw\t%3,52(%1)\n\t" - "lw\t%4,56(%1)\n\t" - "lw\t%5,60(%1)\n\t" - "sw\t%2,48(%0)\n\t" - "sw\t%3,52(%0)\n\t" - "sw\t%4,56(%0)\n\t" - "sw\t%5,60(%0)\n\t" - "daddiu\t%0,128\n\t" - "daddiu\t%1,128\n\t" - "lw\t%2,-64(%1)\n\t" - "lw\t%3,-60(%1)\n\t" - "lw\t%4,-56(%1)\n\t" - "lw\t%5,-52(%1)\n\t" - "sw\t%2,-64(%0)\n\t" - "sw\t%3,-60(%0)\n\t" - "sw\t%4,-56(%0)\n\t" - "sw\t%5,-52(%0)\n\t" - "lw\t%2,-48(%1)\n\t" - "lw\t%3,-44(%1)\n\t" - "lw\t%4,-40(%1)\n\t" - "lw\t%5,-36(%1)\n\t" - "sw\t%2,-48(%0)\n\t" - "sw\t%3,-44(%0)\n\t" - "sw\t%4,-40(%0)\n\t" - "sw\t%5,-36(%0)\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r4k_flush_cache_all_s16d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache16(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s32d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache32(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache64(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache128(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s32d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); blast_scache32(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s64d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); blast_scache64(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s128d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); blast_scache128(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); - local_irq_restore(flags); -} - -static void -r4k_flush_cache_range_s16d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s16d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache16_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void -r4k_flush_cache_range_s32d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s32d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s64d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if(vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s64d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s128d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s128d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s32d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s32d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s64d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s64d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s128d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (mm->context == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (mm->context != current->active_mm->context) { - r4k_flush_cache_all_s128d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_d16i16(struct mm_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - local_irq_save(flags); - blast_dcache16(); blast_icache16(); - local_irq_restore(flags); - } -} - -static void r4k_flush_cache_range_d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - local_irq_save(flags); - blast_dcache32(); blast_icache32(); - local_irq_restore(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } -} - -static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d16i16(); - } -} - -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d32i32(); - } -} - -static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d32i32(); - } -} - -static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d32i32(); - } -} - -static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} - -static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d32i32(); - } -} - -static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm->context != current->active_mm->context) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (mm == current->active_mm) { - blast_dcache16_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed(page); - } -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - blast_dcache32_page_indexed(page ^ dcache_waybit); - } -out: - local_irq_restore(flags); -} - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r4k_flush_page_to_ram_s16(struct page *page) -{ - blast_scache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s32(struct page *page) -{ - blast_scache32_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s64(struct page *page) -{ - blast_scache64_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s128(struct page *page) -{ - blast_scache128_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - blast_dcache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d32_r4600(struct page *page) -{ - unsigned long flags; - - local_irq_save(flags); /* For R4600 v1.7 bug. */ - blast_dcache32_page((unsigned long)page_address(page)); - local_irq_restore(flags); -} - -static void -r4k_flush_icache_page_s(struct vm_area_struct *vma, struct page *page) -{ - /* - * We did an scache flush therefore PI is already clean. - */ -} - -static void -r4k_flush_icache_range(unsigned long start, unsigned long end) -{ - flush_cache_all(); -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r4k_flush_icache_page_p(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - flush_cache_all(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -static void -r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - /* Workaround for R4600 bug. See comment above. */ - local_irq_save(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - local_irq_restore(flags); - } - bc_wback_inv(addr, size); -} - -static void -r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - /* Workaround for R4600 bug. See comment above. */ - local_irq_save(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - local_irq_restore(flags); - } - - bc_inv(addr, size); -} - -static void -r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= scache_size) { - flush_cache_all(); - return; - } - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void -r4k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r4k_dma_cache called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - __asm__ __volatile__("nop;nop;nop;nop"); /* R4600 V1.7 */ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void r4600v20k_flush_cache_sigtramp(unsigned long addr) -{ - unsigned int flags; - - local_irq_save(flags); - - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); - - local_irq_restore(flags); -} - -#undef DEBUG_TLB -#undef DEBUG_TLBUPDATE - -void flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < mips_cpu.tlbsize) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - local_irq_restore(flags); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - local_irq_save(flags); - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - local_irq_restore(flags); - } -} - -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= mips_cpu.tlbsize/2) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - } - local_irq_restore(flags); - } -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - local_irq_restore(flags); - } -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for(i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} - -/* We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); - } -#endif - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - local_irq_restore(flags); -} - -#if 0 -static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx; - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - BARRIER; - if(idx < 0) - tlb_write_random(); - else - tlb_write_indexed(); - BARRIER; - local_irq_restore(flags); -} -#endif - -void show_regs(struct pt_regs * regs) -{ - /* Saved main processor registers. */ - printk("$0 : %08lx %08lx %08lx %08lx\n", - 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); - printk("$4 : %08lx %08lx %08lx %08lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - printk("$8 : %08lx %08lx %08lx %08lx\n", - regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); - printk("$12: %08lx %08lx %08lx %08lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); - printk("$16: %08lx %08lx %08lx %08lx\n", - regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); - printk("$20: %08lx %08lx %08lx %08lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); - printk("$24: %08lx %08lx\n", - regs->regs[24], regs->regs[25]); - printk("$28: %08lx %08lx %08lx %08lx\n", - regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); - - /* Saved cp0 registers. */ - printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); -} - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - flush_tlb_all(); - local_irq_restore(flags); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - switch (mips_cpu.cputype) { - case CPU_VR41XX: - icache_size = 1 << (10 + ((config >> 9) & 7)); - break; - default: - icache_size = 1 << (12 + ((config >> 9) & 7)); - break; - } - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - switch (mips_cpu.cputype) { - case CPU_VR41XX: - dcache_size = 1 << (10 + ((config >> 6) & 7)); - break; - default: - dcache_size = 1 << (12 + ((config >> 6) & 7)); - break; - } - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - local_irq_save(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 8, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 9, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 11, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - ".set mips3\n\t" - "cache 7, (%0)\n\t" - ".set mips0\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - local_irq_restore(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d bytes.\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - unsigned int prid; - - switch(dc_lsize) { - case 16: - _clear_page = r4k_clear_page_d16; - _copy_page = r4k_copy_page_d16; - _flush_cache_all = r4k_flush_cache_all_d16i16; - _flush_cache_mm = r4k_flush_cache_mm_d16i16; - _flush_cache_range = r4k_flush_cache_range_d16i16; - _flush_cache_page = r4k_flush_cache_page_d16i16; - _flush_page_to_ram = r4k_flush_page_to_ram_d16; - break; - case 32: - prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; - if (prid == 0x2010) { /* R4600 V1.7 */ - _clear_page = r4k_clear_page_r4600_v1; - _copy_page = r4k_copy_page_r4600_v1; - _flush_page_to_ram = r4k_flush_page_to_ram_d32_r4600; - } else if (prid == 0x2020) { /* R4600 V2.0 */ - _clear_page = r4k_clear_page_r4600_v2; - _copy_page = r4k_copy_page_r4600_v2; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - } else { - _clear_page = r4k_clear_page_d32; - _copy_page = r4k_copy_page_d32; - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - } - _flush_cache_all = r4k_flush_cache_all_d32i32; - _flush_cache_mm = r4k_flush_cache_mm_d32i32; - _flush_cache_range = r4k_flush_cache_range_d32i32; - _flush_cache_page = r4k_flush_cache_page_d32i32; - break; - } - ___flush_cache_all = _flush_cache_all; - - _flush_icache_page = r4k_flush_icache_page_p; - - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc; - _dma_cache_wback = r4k_dma_cache_wback; - _dma_cache_inv = r4k_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - switch(sc_lsize) { - case 16: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s16d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s16d16i16; - _flush_cache_range = r4k_flush_cache_range_s16d16i16; - _flush_cache_page = r4k_flush_cache_page_s16d16i16; - break; - case 32: - panic("Invalid cache configuration detected"); - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s16; - _clear_page = r4k_clear_page_s16; - _copy_page = r4k_copy_page_s16; - break; - case 32: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s32d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s32d16i16; - _flush_cache_range = r4k_flush_cache_range_s32d16i16; - _flush_cache_page = r4k_flush_cache_page_s32d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s32d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s32d32i32; - _flush_cache_range = r4k_flush_cache_range_s32d32i32; - _flush_cache_page = r4k_flush_cache_page_s32d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s32; - _clear_page = r4k_clear_page_s32; - _copy_page = r4k_copy_page_s32; - break; - case 64: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s64d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s64d16i16; - _flush_cache_range = r4k_flush_cache_range_s64d16i16; - _flush_cache_page = r4k_flush_cache_page_s64d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s64d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s64d32i32; - _flush_cache_range = r4k_flush_cache_range_s64d32i32; - _flush_cache_page = r4k_flush_cache_page_s64d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s64; - _clear_page = r4k_clear_page_s64; - _copy_page = r4k_copy_page_s64; - break; - case 128: - switch(dc_lsize) { - case 16: - _flush_cache_all = r4k_flush_cache_all_s128d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s128d16i16; - _flush_cache_range = r4k_flush_cache_range_s128d16i16; - _flush_cache_page = r4k_flush_cache_page_s128d16i16; - break; - case 32: - _flush_cache_all = r4k_flush_cache_all_s128d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s128d32i32; - _flush_cache_range = r4k_flush_cache_range_s128d32i32; - _flush_cache_page = r4k_flush_cache_page_s128d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s128; - _clear_page = r4k_clear_page_s128; - _copy_page = r4k_copy_page_s128; - break; - } - ___flush_cache_all = _flush_cache_all; - _flush_icache_page = r4k_flush_icache_page_s; - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; - _dma_cache_wback = r4k_dma_cache_wback; - _dma_cache_inv = r4k_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -void __init ld_mmu_r4xx0(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - -#ifdef CONFIG_MIPS_UNCACHED - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); -#else - change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); -#endif - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - switch(mips_cpu.cputype) { - case CPU_R4600: /* QED style two way caches? */ - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - _flush_cache_page = r4k_flush_cache_page_d32i32_r4600; - } - - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - _flush_icache_range = r4k_flush_icache_range; /* Ouch */ - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { - _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; - } - - __flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - set_pagemask(PM_4K); - flush_tlb_all(); -} diff -Nru a/arch/mips/mm/r5432.c b/arch/mips/mm/r5432.c --- a/arch/mips/mm/r5432.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,864 +0,0 @@ -/* - * 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. - * - * r5432.c: NEC Vr5432 processor. We cannot use r4xx0.c because of - * its unique way-selection method for indexed operations. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Jun Sun (jsun@mvista.com) - * - */ - -/* - * [jsun] - * In a sense, this is really silly. We cannot re-use r4xx0.c because - * the lowest-level indexed cache operation does not take way-selection - * into account. So all what I am doing here is to copy all the funcs - * and macros (in r4kcache.h) relavent to R5432 to this file, and then - * modify a few indexed cache operations. *sigh* - */ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/bcache.h> -#include <asm/io.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/bootinfo.h> -#include <asm/mmu_context.h> - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -#include <asm/asm.h> -#include <asm/cacheops.h> - -#undef DEBUG_CACHE - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - - -/* -------------------------------------------------------------------- */ -/* #include <asm/r4kcache.h> */ - -extern inline void flush_icache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - "cache %1, 1(%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); -} - -extern inline void flush_dcache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - "cache %1, 1(%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); -} - -extern inline void flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -extern inline void flush_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); -} - -extern inline void invalidate_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); -} - - -/* - * The next two are for badland addresses like signal trampolines. - */ -extern inline void protected_flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -extern inline void protected_writeback_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Writeback_D)); -} - - -#define cache32_unroll32(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, 0x000(%0); cache %1, 0x020(%0); \ - cache %1, 0x040(%0); cache %1, 0x060(%0); \ - cache %1, 0x080(%0); cache %1, 0x0a0(%0); \ - cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \ - cache %1, 0x100(%0); cache %1, 0x120(%0); \ - cache %1, 0x140(%0); cache %1, 0x160(%0); \ - cache %1, 0x180(%0); cache %1, 0x1a0(%0); \ - cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \ - cache %1, 0x200(%0); cache %1, 0x220(%0); \ - cache %1, 0x240(%0); cache %1, 0x260(%0); \ - cache %1, 0x280(%0); cache %1, 0x2a0(%0); \ - cache %1, 0x2c0(%0); cache %1, 0x2e0(%0); \ - cache %1, 0x300(%0); cache %1, 0x320(%0); \ - cache %1, 0x340(%0); cache %1, 0x360(%0); \ - cache %1, 0x380(%0); cache %1, 0x3a0(%0); \ - cache %1, 0x3c0(%0); cache %1, 0x3e0(%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -extern inline void blast_dcache32(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + dcache_size/2); - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - cache32_unroll32(start+1,Index_Writeback_Inv_D); - start += 0x400; - } -} - -extern inline void blast_dcache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Hit_Writeback_Inv_D); - start += 0x400; - } -} - -extern inline void blast_dcache32_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - cache32_unroll32(start+1,Index_Writeback_Inv_D); - start += 0x400; - } -} - -extern inline void blast_icache32(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + icache_size/2); - - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - cache32_unroll32(start+1,Index_Invalidate_I); - start += 0x400; - } -} - -extern inline void blast_icache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Hit_Invalidate_I); - start += 0x400; - } -} - -extern inline void blast_icache32_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - cache32_unroll32(start+1,Index_Invalidate_I); - start += 0x400; - } -} - -/* -------------------------------------------------------------------- */ - -static void r5432_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1","memory"); -} - - - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -static void r5432_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r5432_flush_cache_all_d32i32(void) -{ - blast_dcache32(); blast_icache32(); -} - -static void r5432_flush_cache_range_d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - blast_dcache32(); blast_icache32(); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r5432_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (mm->context != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r5432_flush_cache_all_d32i32(); - } -} - -static void r5432_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (mm->context == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if (!(pte_val(*ptep) & _PAGE_PRESENT)) - return; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -} - - -/* If the addresses passed to these routines are valid, they are - * either: - * - * 1) In KSEG0, so we can do a direct flush of the page. - * 2) In KSEG2, and since every process can translate those - * addresses all the time in kernel mode we can do a direct - * flush. - * 3) In KSEG1, no flush necessary. - */ -static void r5432_flush_page_to_ram_d32(struct page *page) -{ - blast_dcache32_page((unsigned long)page_address(page)); -} - -static void -r5432_flush_icache_range(unsigned long start, unsigned long end) -{ - r5432_flush_cache_all_d32i32(); -} - -/* - * Ok, this seriously sucks. We use them to flush a user page but don't - * know the virtual address, so we have to blast away the whole icache - * which is significantly more expensive than the real thing. - */ -static void -r5432_flush_icache_page_i32(struct vm_area_struct *vma, struct page *page) -{ - if (!(vma->vm_flags & VM_EXEC)) - return; - - r5432_flush_cache_all_d32i32(); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - */ -static void -r5432_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - } - bc_wback_inv(addr, size); -} - -static void -r5432_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= dcache_size) { - flush_cache_all(); - } else { - a = addr & ~(dc_lsize - 1); - end = (addr + size) & ~(dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - } - - bc_inv(addr, size); -} - -static void -r5432_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r5432_dma_cache called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r5432_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -#undef DEBUG_TLB -#undef DEBUG_TLBUPDATE - -#define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */ - -#define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */ - -void flush_tlb_all(void) -{ - unsigned long old_ctx; - int entry; - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < NTLB_ENTRIES) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - local_irq_restore(flags); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - if (mm->context != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - local_irq_save(flags); - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - local_irq_restore(flags); - } -} - -void flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_entryhi(mm->context & 0xff); - } - local_irq_restore(flags); - } -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - local_irq_restore(flags); - } -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for(i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} - -/* We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - -#ifdef DEBUG_TLB - if((pid != (vma->vm_mm->context & 0xff)) || (vma->vm_mm->context == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", - (int) (vma->vm_mm->context & 0xff), pid); - } -#endif - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - local_irq_restore(flags); -} - -void show_regs(struct pt_regs * regs) -{ - /* Saved main processor registers. */ - printk("$0 : %08lx %08lx %08lx %08lx\n", - 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); - printk("$4 : %08lx %08lx %08lx %08lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - printk("$8 : %08lx %08lx %08lx %08lx\n", - regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); - printk("$12: %08lx %08lx %08lx %08lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); - printk("$16: %08lx %08lx %08lx %08lx\n", - regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); - printk("$20: %08lx %08lx %08lx %08lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); - printk("$24: %08lx %08lx\n", - regs->regs[24], regs->regs[25]); - printk("$28: %08lx %08lx %08lx %08lx\n", - regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); - - /* Saved cp0 registers. */ - printk("epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); -} - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - flush_tlb_all(); - local_irq_restore(flags); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes.\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes.\n", - dcache_size >> 10, dc_lsize); -} - - -void __init ld_mmu_r5432(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); - - probe_icache(config); - probe_dcache(config); - - _clear_page = r5432_clear_page_d32; - _copy_page = r5432_copy_page_d32; - _flush_cache_all = r5432_flush_cache_all_d32i32; - ___flush_cache_all = r5432_flush_cache_all_d32i32; - _flush_page_to_ram = r5432_flush_page_to_ram_d32; - _flush_cache_mm = r5432_flush_cache_mm_d32i32; - _flush_cache_range = r5432_flush_cache_range_d32i32; - _flush_cache_page = r5432_flush_cache_page_d32i32; - _flush_icache_page = r5432_flush_icache_page_i32; - _dma_cache_wback_inv = r5432_dma_cache_wback_inv_pc; - _dma_cache_wback = r5432_dma_cache_wback; - _dma_cache_inv = r5432_dma_cache_inv_pc; - - _flush_cache_sigtramp = r5432_flush_cache_sigtramp; - _flush_icache_range = r5432_flush_icache_range; /* Ouch */ - - __flush_cache_all(); - write_32bit_cp0_register(CP0_WIRED, 0); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - flush_tlb_all(); -} diff -Nru a/arch/mips/mm/rm7k.c b/arch/mips/mm/rm7k.c --- a/arch/mips/mm/rm7k.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,751 +0,0 @@ -/* - * 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. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle ralf@gnu.org - * - * To do: - * - * - this code is a overbloated pig - * - many of the bug workarounds are not efficient at all, but at - * least they are functional ... - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/io.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/bootinfo.h> -#include <asm/mmu_context.h> - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ - -#define ic_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define dc_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define sc_lsize 32 /* Fixed to 32 byte on RM7000 */ -#define tc_pagesize (32*128) - -/* Secondary cache parameters. */ -#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ - -#include <asm/cacheops.h> -#include <asm/r4kcache.h> - -int rm7k_tcache_enabled = 0; - -/* - * Not added to asm/r4kcache.h because it seems to be RM7000-specific. - */ -#define Page_Invalidate_T 0x16 - -static inline void invalidate_tcache_page(unsigned long addr) -{ - __asm__ __volatile__( - ".set\tnoreorder\t\t\t# invalidate_tcache_page\n\t" - ".set\tmips3\n\t" - "cache\t%1, (%0)\n\t" - ".set\tmips0\n\t" - ".set\treorder" - : - : "r" (addr), - "i" (Page_Invalidate_T)); -} - -/* - * Zero an entire page. Note that while the RM7000 has a second level cache - * it doesn't have a Create_Dirty_Excl_SD operation. - */ -static void rm7k_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1","memory"); -} - - -/* - * Copy an entire page. Note that while the RM7000 has a second level cache - * it doesn't have a Create_Dirty_Excl_SD operation. - */ -static void rm7k_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "lw\t%2,(%1)\n\t" - "lw\t%3,4(%1)\n\t" - "lw\t%4,8(%1)\n\t" - "lw\t%5,12(%1)\n\t" - "sw\t%2,(%0)\n\t" - "sw\t%3,4(%0)\n\t" - "sw\t%4,8(%0)\n\t" - "sw\t%5,12(%0)\n\t" - "lw\t%2,16(%1)\n\t" - "lw\t%3,20(%1)\n\t" - "lw\t%4,24(%1)\n\t" - "lw\t%5,28(%1)\n\t" - "sw\t%2,16(%0)\n\t" - "sw\t%3,20(%0)\n\t" - "sw\t%4,24(%0)\n\t" - "sw\t%5,28(%0)\n\t" - "cache\t%9,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "lw\t%2,-32(%1)\n\t" - "lw\t%3,-28(%1)\n\t" - "lw\t%4,-24(%1)\n\t" - "lw\t%5,-20(%1)\n\t" - "sw\t%2,-32(%0)\n\t" - "sw\t%3,-28(%0)\n\t" - "sw\t%4,-24(%0)\n\t" - "sw\t%5,-20(%0)\n\t" - "lw\t%2,-16(%1)\n\t" - "lw\t%3,-12(%1)\n\t" - "lw\t%4,-8(%1)\n\t" - "lw\t%5,-4(%1)\n\t" - "sw\t%2,-16(%0)\n\t" - "sw\t%3,-12(%0)\n\t" - "sw\t%4,-8(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sw\t%5,-4(%0)\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void __flush_cache_all_d32i32(void) -{ - blast_dcache32(); - blast_icache32(); -} - -static inline void rm7k_flush_cache_all_d32i32(void) -{ - /* Yes! Caches that don't suck ... */ -} - -static void rm7k_flush_cache_range_d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - /* RM7000 caches are sane ... */ -} - -static void rm7k_flush_page_to_ram_d32i32(struct page * page) -{ - /* Yes! Caches that don't suck! */ -} - -static void rm7k_flush_icache_range(unsigned long start, unsigned long end) -{ - /* - * FIXME: This is overdoing things and harms performance. - */ - __flush_cache_all_d32i32(); -} - -static void rm7k_flush_icache_page(struct vm_area_struct *vma, - struct page *page) -{ - /* - * FIXME: We should not flush the entire cache but establish some - * temporary mapping and use hit_invalidate operation to flush out - * the line from the cache. - */ - __flush_cache_all_d32i32(); -} - - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * (XXX These need to be fixed ...) - */ -static void -rm7k_dma_cache_wback_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - flush_icache_line(a); /* Hit_Invalidate_I */ - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } - - if (!rm7k_tcache_enabled) - return; - - a = addr & ~(tc_pagesize - 1); - end = (addr + size) & ~(tc_pagesize - 1); - while(1) { - invalidate_tcache_page(a); /* Page_Invalidate_T */ - if (a == end) break; - a += tc_pagesize; - } -} - -static void -rm7k_dma_cache_inv(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - a = addr & ~(sc_lsize - 1); - end = (addr + size) & ~(sc_lsize - 1); - while (1) { - invalidate_dcache_line(a); /* Hit_Invalidate_D */ - flush_icache_line(a); /* Hit_Invalidate_I */ - invalidate_scache_line(a); /* Hit_Invalidate_SD */ - if (a == end) break; - a += sc_lsize; - } - - if (!rm7k_tcache_enabled) - return; - - a = addr & ~(tc_pagesize - 1); - end = (addr + size) & ~(tc_pagesize - 1); - while(1) { - invalidate_tcache_page(a); /* Page_Invalidate_T */ - if (a == end) break; - a += tc_pagesize; - } -} - -static void -rm7k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("rm7k_dma_cache_wback called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void rm7k_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -/* - * Undocumented RM7000: Bit 29 in the info register of the RM7000 v2.0 - * indicates if the TLB has 48 or 64 entries. - * - * 29 1 => 64 entry JTLB - * 0 => 48 entry JTLB - */ -static inline int __attribute__((const)) ntlb_entries(void) -{ - if (get_info() & (1 << 29)) - return 64; - - return 48; -} - -void flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while (entry < ntlb_entries()) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - local_irq_restore(flags); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - if(mm->context != 0) { - unsigned long flags; - - local_irq_save(flags); - get_new_mmu_context(mm, asid_cache); - if (mm == current->mm) - set_entryhi(mm->context & 0xff); - local_irq_restore(flags); - } -} - -void flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if(mm->context != 0) { - unsigned long flags; - int size; - - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if (size <= (ntlb_entries() / 2)) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (mm->context & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_mmu_context(mm, asid_cache); - if(mm == current->mm) - set_entryhi(mm->context & 0xff); - } - local_irq_restore(flags); - } -} - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if(vma->vm_mm->context != 0) { - unsigned long flags; - int oldpid, newpid, idx; - - newpid = (vma->vm_mm->context & 0xff); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - local_irq_restore(flags); - } -} - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} - -/* - * We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - pid = get_entryhi() & 0xff; - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if (idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - local_irq_restore(flags); -} - -void show_regs(struct pt_regs * regs) -{ - /* Saved main processor registers. */ - printk(KERN_INFO "$0 : %08lx %08lx %08lx %08lx\n", - 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); - printk(KERN_INFO "$4 : %08lx %08lx %08lx %08lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - printk(KERN_INFO "$8 : %08lx %08lx %08lx %08lx\n", - regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); - printk(KERN_INFO "$12: %08lx %08lx %08lx %08lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); - printk(KERN_INFO "$16: %08lx %08lx %08lx %08lx\n", - regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); - printk(KERN_INFO "$20: %08lx %08lx %08lx %08lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); - printk(KERN_INFO "$24: %08lx %08lx\n", - regs->regs[24], regs->regs[25]); - printk(KERN_INFO "$28: %08lx %08lx %08lx %08lx\n", - regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); - - /* Saved cp0 registers. */ - printk(KERN_INFO "epc : %08lx %s\nStatus: %08lx\nCause : %08lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_status, regs->cp0_cause); -} - -void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - set_wired (wired + 1); - set_index (wired); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - flush_tlb_all(); - local_irq_restore(flags); -} - -/* Used for loading TLB entries before trap_init() has started, when we - don't actually want to add a wired entry which remains throughout the - lifetime of the system */ - -static int temp_tlb_entry __initdata; - -__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, - unsigned long entryhi, unsigned long pagemask) -{ - int ret = 0; - unsigned long flags; - unsigned long wired; - unsigned long old_pagemask; - unsigned long old_ctx; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - old_pagemask = get_pagemask(); - wired = get_wired(); - if (--temp_tlb_entry < wired) { - printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); - ret = -ENOSPC; - goto out; - } - - set_index (temp_tlb_entry); - BARRIER; - set_pagemask (pagemask); - set_entryhi(entryhi); - set_entrylo0(entrylo0); - set_entrylo1(entrylo1); - BARRIER; - tlb_write_indexed(); - BARRIER; - - set_entryhi(old_ctx); - BARRIER; - set_pagemask (old_pagemask); - out: - local_irq_restore(flags); - return ret; -} - - - -/* Detect and size the caches. */ -static inline void probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - - printk(KERN_INFO "Primary instruction cache %dKiB.\n", icache_size >> 10); -} - -static inline void probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - - printk(KERN_INFO "Primary data cache %dKiB.\n", dcache_size >> 10); -} - - -/* - * This function is executed in the uncached segment KSEG1. - * It must not touch the stack, because the stack pointer still points - * into KSEG0. - * - * Three options: - * - Write it in assembly and guarantee that we don't use the stack. - * - Disable caching for KSEG0 before calling it. - * - Pray that GCC doesn't randomly start using the stack. - * - * This being Linux, we obviously take the least sane of those options - - * following DaveM's lead in r4xx0.c - * - * It seems we get our kicks from relying on unguaranteed behaviour in GCC - */ -static __init void setup_scache(void) -{ - int register i; - - set_cp0_config(1<<3 /* CONF_SE */); - - set_taglo(0); - set_taghi(0); - - for (i=0; i<scache_size; i+=sc_lsize) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (KSEG0ADDR(i)), - "i" (Index_Store_Tag_SD)); - } - -} - -static inline void probe_scache(unsigned long config) -{ - void (*func)(void) = KSEG1ADDR(&setup_scache); - - if ((config >> 31) & 1) - return; - - printk(KERN_INFO "Secondary cache %dKiB, linesize %d bytes.\n", - (scache_size >> 10), sc_lsize); - - if ((config >> 3) & 1) - return; - - printk(KERN_INFO "Enabling secondary cache..."); - func(); - printk("Done\n"); -} - -static inline void probe_tcache(unsigned long config) -{ - if ((config >> 17) & 1) - return; - - /* We can't enable the L3 cache yet. There may be board-specific - * magic necessary to turn it on, and blindly asking the CPU to - * start using it would may give cache errors. - * - * Also, board-specific knowledge may allow us to use the - * CACHE Flash_Invalidate_T instruction if the tag RAM supports - * it, and may specify the size of the L3 cache so we don't have - * to probe it. - */ - printk(KERN_INFO "Tertiary cache present, %s enabled\n", - config&(1<<12) ? "already" : "not (yet)"); - - if ((config >> 12) & 1) - rm7k_tcache_enabled = 1; -} - -void __init ld_mmu_rm7k(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - unsigned long addr; - - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - - change_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); - - /* RM7000 erratum #31. The icache is screwed at startup. */ - set_taglo(0); - set_taghi(0); - for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { - __asm__ __volatile__ ( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache\t%1, 0(%0)\n\t" - "cache\t%1, 0x1000(%0)\n\t" - "cache\t%1, 0x2000(%0)\n\t" - "cache\t%1, 0x3000(%0)\n\t" - "cache\t%2, 0(%0)\n\t" - "cache\t%2, 0x1000(%0)\n\t" - "cache\t%2, 0x2000(%0)\n\t" - "cache\t%2, 0x3000(%0)\n\t" - "cache\t%1, 0(%0)\n\t" - "cache\t%1, 0x1000(%0)\n\t" - "cache\t%1, 0x2000(%0)\n\t" - "cache\t%1, 0x3000(%0)\n\t" - ".set\tmips0\n\t" - ".set\treorder\n\t" - : - : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); - } - -#ifndef CONFIG_MIPS_UNCACHED - change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); -#endif - - probe_icache(config); - probe_dcache(config); - probe_scache(config); - probe_tcache(config); - - printk("TLB has %d entries.\n", ntlb_entries()); - - _clear_page = rm7k_clear_page; - _copy_page = rm7k_copy_page; - - _flush_cache_all = rm7k_flush_cache_all_d32i32; - ___flush_cache_all = __flush_cache_all_d32i32; - _flush_cache_mm = rm7k_flush_cache_mm_d32i32; - _flush_cache_range = rm7k_flush_cache_range_d32i32; - _flush_cache_page = rm7k_flush_cache_page_d32i32; - _flush_page_to_ram = rm7k_flush_page_to_ram_d32i32; - _flush_cache_sigtramp = rm7k_flush_cache_sigtramp; - _flush_icache_range = rm7k_flush_icache_range; - _flush_icache_page = rm7k_flush_icache_page; - - _dma_cache_wback_inv = rm7k_dma_cache_wback_inv; - _dma_cache_wback = rm7k_dma_cache_wback; - _dma_cache_inv = rm7k_dma_cache_inv; - - __flush_cache_all_d32i32(); - write_32bit_cp0_register(CP0_WIRED, 0); - temp_tlb_entry = ntlb_entries() - 1; - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - flush_tlb_all(); -} diff -Nru a/arch/mips/mm/sb1.c b/arch/mips/mm/sb1.c --- a/arch/mips/mm/sb1.c Fri Jun 27 14:19:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,436 +0,0 @@ -/* - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 2000 Sibyte - * - * Written by Justin Carlson (carlson@sibyte.com) - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -/* - * In this entire file, I'm not sure what the role of the L2 on the sb1250 - * is. Since it is coherent to the system, we should never need to flush - * it...right?...right??? -JDC - */ - -#include <asm/mmu_context.h> - -/* These are probed at ld_mmu time */ -static unsigned int icache_size; -static unsigned int dcache_size; - -static unsigned int icache_line_size; -static unsigned int dcache_line_size; - -static unsigned int icache_assoc; -static unsigned int dcache_assoc; - -static unsigned int icache_sets; -static unsigned int dcache_sets; -static unsigned int tlb_entries; - -void pgd_init(unsigned long page) -{ - unsigned long *p = (unsigned long *) page; - int i; - - for (i = 0; i < USER_PTRS_PER_PGD; i+=8) { - p[i + 0] = (unsigned long) invalid_pte_table; - p[i + 1] = (unsigned long) invalid_pte_table; - p[i + 2] = (unsigned long) invalid_pte_table; - p[i + 3] = (unsigned long) invalid_pte_table; - p[i + 4] = (unsigned long) invalid_pte_table; - p[i + 5] = (unsigned long) invalid_pte_table; - p[i + 6] = (unsigned long) invalid_pte_table; - p[i + 7] = (unsigned long) invalid_pte_table; - } -} - -void flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entrylo0(0); - set_entrylo1(0); - for (entry = 0; entry < tlb_entries; entry++) { - set_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); - set_index(entry); - tlb_write_indexed(); - } - set_entryhi(old_ctx); - local_irq_restore(flags); -} - - - -/* These are the functions hooked by the memory management function pointers */ -static void sb1_clear_page(void *page) -{ - /* JDCXXX - This should be bottlenecked by the write buffer, but these - things tend to be mildly unpredictable...should check this on the - performance model */ - - /* We prefetch 4 lines ahead. We're also "cheating" slightly here... - since we know we're on an SB1, we force the assembler to take - 64-bit operands to speed things up */ - __asm__ __volatile__( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " addiu $1, %0, %2 \n" /* Calculate the end of the page to clear */ - " pref 5, 0(%0) \n" /* Prefetch the first 4 lines */ - " pref 5, 32(%0) \n" - " pref 5, 64(%0) \n" - " pref 5, 96(%0) \n" - "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ - " sd $0, 8(%0) \n" - " sd $0, 16(%0) \n" - " sd $0, 24(%0) \n" - " pref 5,128(%0) \n" /* Prefetch 4 lines ahead */ - " bne $1, %0, 1b \n" - " addiu %0, %0, 32 \n" /* Next cacheline (This instruction better be short piped!) */ - ".set pop \n" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE-32) - :"$1","memory"); - -} - -static void sb1_copy_page(void *to, void *from) -{ - - /* This should be optimized in assembly...can't use ld/sd, though, - * because the top 32 bits could be nuked if we took an interrupt - * during the routine. And this is not a good place to be cli()'ing - */ - - /* The pref's used here are using "streaming" hints, which cause the - * copied data to be kicked out of the cache sooner. A page copy often - * ends up copying a lot more data than is commonly used, so this seems - * to make sense in terms of reducing cache pollution, but I've no real - * performance data to back this up - */ - - __asm__ __volatile__( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " addiu $1, %0, %4 \n" /* Calculate the end of the page to copy */ - " pref 4, 0(%0) \n" /* Prefetch the first 3 lines to be read and copied */ - " pref 5, 0(%1) \n" - " pref 4, 32(%0) \n" - " pref 5, 32(%1) \n" - " pref 4, 64(%0) \n" - " pref 5, 64(%1) \n" - "1: lw $2, 0(%0) \n" /* Block copy a cacheline */ - " lw $3, 4(%0) \n" - " lw $4, 8(%0) \n" - " lw $5, 12(%0) \n" - " lw $6, 16(%0) \n" - " lw $7, 20(%0) \n" - " lw $8, 24(%0) \n" - " lw $9, 28(%0) \n" - " pref 4, 96(%0) \n" /* Prefetch ahead */ - " pref 5, 96(%1) \n" - " sw $2, 0(%1) \n" - " sw $3, 4(%1) \n" - " sw $4, 8(%1) \n" - " sw $5, 12(%1) \n" - " sw $6, 16(%1) \n" - " sw $7, 20(%1) \n" - " sw $8, 24(%1) \n" - " sw $9, 28(%1) \n" - " addiu %1, %1, 32 \n" /* Next cacheline */ - " nop \n" /* Force next add to short pipe */ - " nop \n" /* Force next add to short pipe */ - " bne $1, %0, 1b \n" - " addiu %0, %0, 32 \n" /* Next cacheline */ - ".set pop \n" - :"=r" (to), - "=r" (from) - : - "0" (from), - "1" (to), - "I" (PAGE_SIZE-32) - :"$1","$2","$3","$4","$5","$6","$7","$8","$9","memory"); -/* - unsigned long *src = from; - unsigned long *dest = to; - unsigned long *target = (unsigned long *) (((unsigned long)src) + PAGE_SIZE); - while (src != target) { - *dest++ = *src++; - } -*/ -} - -/* - * The dcache is fully coherent to the system, with one - * big caveat: the instruction stream. In other words, - * if we miss in the icache, and have dirty data in the - * L1 dcache, then we'll go out to memory (or the L2) and - * get the not-as-recent data. - * - * So the only time we have to flush the dcache is when - * we're flushing the icache. Since the L2 is fully - * coherent to everything, including I/O, we never have - * to flush it - */ - -static void sb1_flush_cache_all(void) -{ - - /* - * Haven't worried too much about speed here; given that we're flushing - * the icache, the time to invalidate is dwarfed by the time it's going - * to take to refill it. Register usage: - * - * $1 - moving cache index - * $2 - set count - */ - if (icache_sets) { - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache 0, 0($1) \n" /* Invalidate this index */ - " addiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address JDCXXX - Should be short piped */ - ".set pop \n" - ::"r" (icache_line_size), - "r" (icache_sets * icache_assoc), - "r" (KSEG0) - :"$1"); - } - if (dcache_sets) { - __asm__ __volatile__ ( - ".set push \n" - ".set noreorder \n" - ".set noat \n" - ".set mips4 \n" - " move $1, %2 \n" /* Start at index 0 */ - "1: cache 0x1, 0($1) \n" /* WB/Invalidate this index */ - " addiu %1, %1, -1 \n" /* Decrement loop count */ - " bnez %1, 1b \n" /* loop test */ - " addu $1, $1, %0 \n" /* Next address JDCXXX - Should be short piped */ - ".set pop \n" - ::"r" (dcache_line_size), - "r" (dcache_sets * dcache_assoc), - "r" (KSEG0) - :"$1"); - } -} - -/* - * When flushing a range in the icache, we have to first writeback - * the dcache for the same range, so new ifetches will see any - * data that was dirty in the dcache - */ - -static void sb1_flush_icache_range(unsigned long start, unsigned long end) -{ - - /* JDCXXX - Implement me! */ - sb1_flush_cache_all(); -} - -static void sb1_flush_cache_mm(struct mm_struct *mm) -{ - /* Don't need to do this, as the dcache is physically tagged */ -} - -static void sb1_flush_cache_range(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - /* Don't need to do this, as the dcache is physically tagged */ -} - - -static void sb1_flush_cache_sigtramp(unsigned long page) -{ - /* JDCXXX - Implement me! */ - sb1_flush_cache_all(); -} - - -/* - * This only needs to make sure stores done up to this - * point are visible to other agents outside the CPU. Given - * the coherent nature of the ZBus, all that's required here is - * a sync to make sure the data gets out to the caches and is - * visible to an arbitrary A Phase from an external agent - * - * Actually, I'm not even sure that's necessary; the semantics - * of this function aren't clear. If it's supposed to serve as - * a memory barrier, this is needed. If it's only meant to - * prevent data from being invisible to non-cpu memory accessors - * for some indefinite period of time (e.g. in a non-coherent - * dcache) then this function would be a complete nop. - */ -static void sb1_flush_page_to_ram(struct page *page) -{ - __asm__ __volatile__( - " sync \n" /* Short pipe */ - :::"memory"); -} - - -/* Cribbed from the r2300 code */ -static void sb1_flush_cache_page(struct vm_area_struct *vma, - unsigned long page) -{ - sb1_flush_cache_all(); -#if 0 - struct mm_struct *mm = vma->vm_mm; - unsigned long physpage; - - /* No icache flush needed without context; */ - if (mm->context == 0) - return; - - /* No icache flush needed if the page isn't executable */ - if (!(vma->vm_flags & VM_EXEC)) - return; - - physpage = (unsigned long) page_address(page); - if (physpage) - sb1_flush_icache_range(physpage, physpage + PAGE_SIZE); -#endif -} - - -/* - * Cache set values (from the mips64 spec) - * 0 - 64 - * 1 - 128 - * 2 - 256 - * 3 - 512 - * 4 - 1024 - * 5 - 2048 - * 6 - 4096 - * 7 - Reserved - */ -static unsigned int decode_cache_sets(unsigned int config_field) -{ - if (config_field == 7) { - /* JDCXXX - Find a graceful way to abort. */ - return 0; - } - - return (1<<(config_field + 6)); -} - -/* - * Cache line size values (from the mips64 spec) - * 0 - No cache present. - * 1 - 4 bytes - * 2 - 8 bytes - * 3 - 16 bytes - * 4 - 32 bytes - * 5 - 64 bytes - * 6 - 128 bytes - * 7 - Reserved - */ -static unsigned int decode_cache_line_size(unsigned int config_field) -{ - if (config_field == 0) { - return 0; - } else if (config_field == 7) { - /* JDCXXX - Find a graceful way to abort. */ - return 0; - } - return (1<<(config_field + 1)); -} - -/* - * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs) - * - * 24:22 Icache sets per way - * 21:19 Icache line size - * 18:16 Icache Associativity - * 15:13 Dcache sets per way - * 12:10 Dcache line size - * 9:7 Dcache Associativity - */ - - -static void probe_cache_sizes(void) -{ - u32 config1; - - __asm__ __volatile__( - ".set push \n" - ".set mips64 \n" - " mfc0 %0, $16, 1 \n" /* Get config1 register */ - ".set pop \n" - :"=r" (config1)); - icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); - dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); - icache_sets = decode_cache_sets((config1 >> 22) & 0x7); - dcache_sets = decode_cache_sets((config1 >> 13) & 0x7); - icache_assoc = ((config1 >> 16) & 0x7) + 1; - dcache_assoc = ((config1 >> 7) & 0x7) + 1; - icache_size = icache_line_size * icache_sets * icache_assoc; - dcache_size = dcache_line_size * dcache_sets * dcache_assoc; - tlb_entries = ((config1 >> 25) & 0x3f) + 1; -} - - -/* This is called from loadmmu.c. We have to set up all the - memory management function pointers, as well as initialize - the caches and tlbs */ -void ld_mmu_sb1(void) -{ - probe_cache_sizes(); - - _clear_page = sb1_clear_page; - _copy_page = sb1_copy_page; - - _flush_cache_all = sb1_flush_cache_all; - _flush_cache_mm = sb1_flush_cache_mm; - _flush_cache_range = sb1_flush_cache_range; - _flush_cache_page = sb1_flush_cache_page; - _flush_cache_sigtramp = sb1_flush_cache_sigtramp; - - _flush_page_to_ram = sb1_flush_page_to_ram; - _flush_icache_page = sb1_flush_cache_page; - _flush_icache_range = sb1_flush_icache_range; - - - /* - * JDCXXX I'm not sure whether these are necessary: is this the right - * place to initialize the tlb? If it is, why is it done - * at this level instead of as common code in loadmmu()? - */ - flush_cache_all(); - flush_tlb_all(); - - /* Turn on caching in kseg0 */ - set_cp0_config(CONF_CM_CMASK, 0); -} diff -Nru a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/sc-ip22.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,177 @@ +/* + * sc-ip22.c: Indy cache management functions. + * + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/bcache.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/bootinfo.h> +#include <asm/sgi/ip22.h> +#include <asm/sgi/mc.h> + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__( + ".set\tpush\t\t\t# indy_sc_wipe\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n\t" + "mfc0\t%2, $12\n\t" + "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" + "mtc0\t$1, $12\n\t" + + "dli\t$1, 0x9000000080000000\n\t" + "or\t%0, $1\t\t\t# first line to flush\n\t" + "or\t%1, $1\t\t\t# last line to flush\n\t" + ".set\tat\n\t" + + "1:\tsw\t$0, 0(%0)\n\t" + "bne\t%0, %1, 1b\n\t" + " daddu\t%0, 32\n\t" + + "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last)); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned int flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + + if (!size) + return; + + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(addr + size - 1); + + local_irq_save(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + indy_sc_wipe(first_line, SC_SIZE - SC_LINE); + indy_sc_wipe(0, last_line); +out: + local_irq_restore(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "sb\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop;\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop\n\t" + "sh\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int __init indy_sc_probe(void) +{ + unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17); + if (size == 0) + return 0; + + size <<= PAGE_SHIFT; + printk(KERN_INFO "R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", + size >> 10); + scache_size = size; + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + .bc_enable = indy_sc_enable, + .bc_disable = indy_sc_disable, + .bc_wback_inv = indy_sc_wback_invalidate, + .bc_inv = indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff -Nru a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/sc-r5k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/mipsregs.h> +#include <asm/bcache.h> +#include <asm/cacheops.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/mmu_context.h> + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#define SC_LINE 32 +#define SC_PAGE (128*SC_LINE) + +#define cache_op(base,op) \ +__asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +static inline void blast_r5000_scache(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + cache_op(start, R5K_Page_Invalidate_S); + start += SC_PAGE; + } +} + +static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (size >= scache_size) { + blast_r5000_scache(); + return; + } + + /* On the R5000 secondary cache we cannot + * invalidate less than a page at a time. + * The secondary cache is physically indexed, write-through. + */ + a = addr & ~(SC_PAGE - 1); + end = (addr + size - 1) & ~(SC_PAGE - 1); + while (a <= end) { + cache_op(a, R5K_Page_Invalidate_S); + a += SC_PAGE; + } +} + +static void r5k_sc_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_config(R5K_CONF_SE, R5K_CONF_SE); + blast_r5000_scache(); + local_irq_restore(flags); +} + +static void r5k_sc_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + blast_r5000_scache(); + change_c0_config(R5K_CONF_SE, 0); + local_irq_restore(flags); +} + +static inline int __init r5k_sc_probe(void) +{ + unsigned long config = read_c0_config(); + + if (config & CONF_SC) + return(0); + + scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); + + printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +static struct bcache_ops r5k_sc_ops = { + .bc_enable = r5k_sc_enable, + .bc_disable = r5k_sc_disable, + .bc_wback_inv = r5k_dma_cache_inv_sc, + .bc_inv = r5k_dma_cache_inv_sc +}; + +void __init r5k_sc_init(void) +{ + if (r5k_sc_probe()) { + r5k_sc_enable(); + bcops = &r5k_sc_ops; + } +} diff -Nru a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/sc-rm7k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,191 @@ +/* + * sc-rm7k.c: RM7000 cache management functions. + * + * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org), + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mm.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/cacheops.h> +#include <asm/mipsregs.h> +#include <asm/processor.h> + +/* Primary cache parameters. */ +#define sc_lsize 32 +#define tc_pagesize (32*128) + +/* Secondary cache parameters. */ +#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ + +extern unsigned long icache_way_size, dcache_way_size; + +#include <asm/r4kcache.h> + +int rm7k_tcache_enabled; + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * (XXX These need to be fixed ...) + */ +static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +static void rm7k_sc_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +/* + * This function is executed in the uncached segment KSEG1. + * It must not touch the stack, because the stack pointer still points + * into KSEG0. + * + * Three options: + * - Write it in assembly and guarantee that we don't use the stack. + * - Disable caching for KSEG0 before calling it. + * - Pray that GCC doesn't randomly start using the stack. + * + * This being Linux, we obviously take the least sane of those options - + * following DaveM's lead in c-r4k.c + * + * It seems we get our kicks from relying on unguaranteed behaviour in GCC + */ +static __init void rm7k_sc_enable(void) +{ + int i; + + set_c0_config(1<<3); /* CONF_SE */ + + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i<scache_size; i+=sc_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (KSEG0ADDR(i)), + "i" (Index_Store_Tag_SD)); + } +} + +static void rm7k_sc_disable(void) +{ + set_c0_config(1<<3); /* CONF_SE */ +} + +static inline int __init rm7k_sc_probe(void) +{ + void (*func)(void) = KSEG1ADDR(&rm7k_sc_enable); + unsigned int config = read_c0_config(); + + if ((config >> 31) & 1) + return 0; + + printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + (scache_size >> 10), sc_lsize); + + if ((config >> 3) & 1) + return; + + printk(KERN_INFO "Enabling secondary cache..."); + func(); + printk(" done\n"); + + /* + * While we're at it let's deal with the tertiary cache. + */ + if ((config >> 17) & 1) + return 1; + + /* + * We can't enable the L3 cache yet. There may be board-specific + * magic necessary to turn it on, and blindly asking the CPU to + * start using it would may give cache errors. + * + * Also, board-specific knowledge may allow us to use the + * CACHE Flash_Invalidate_T instruction if the tag RAM supports + * it, and may specify the size of the L3 cache so we don't have + * to probe it. + */ + printk(KERN_INFO "Tertiary cache present, %s enabled\n", + config&(1<<12) ? "already" : "not (yet)"); + + if ((config >> 12) & 1) + rm7k_tcache_enabled = 1; + + return 1; +} + +struct bcache_ops rm7k_sc_ops = { + .bc_enable = rm7k_sc_enable, + .bc_disable = rm7k_sc_disable, + .bc_wback_inv = rm7k_sc_wback_inv, + .bc_inv = rm7k_sc_inv +}; + +void __init rm7k_sc_init(void) +{ + if (rm7k_sc_probe()) { + rm7k_sc_enable(); + bcops = &rm7k_sc_ops; + } +} diff -Nru a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/tlb-r3k.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,290 @@ +/* + * r2300.c: R2000 and R3000 specific mmu/cache code. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * with a lot of changes to make this thing work for R3000s + * Tx39XX R4k style caches added. HK + * Copyright (C) 1998, 1999, 2000 Harald Koerfgen + * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (C) 2002 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/mmu_context.h> +#include <asm/system.h> +#include <asm/isadep.h> +#include <asm/io.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> + +#undef DEBUG_TLB + +extern char except_vec0_r2300; + +/* CP0 hazard avoidance. */ +#define BARRIER \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "nop\n\t" \ + ".set pop\n\t") + +int r3k_have_wired_reg; /* should be in cpu_data? */ + +/* TLB operations. */ +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + +#ifdef DEBUG_TLB + printk("[tlball]"); +#endif + + local_irq_save(flags); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + entry = r3k_have_wired_reg ? read_c0_wired() : 8; + for (; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry << 8); + write_c0_entryhi((entry | 0x80000) << 12); + BARRIER; + tlb_write_indexed(); + } + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { +#ifdef DEBUG_TLB + printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm)); +#endif + drop_mmu_context(mm, cpu); + } +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", + cpu_context(cpu, mm) & ASID_MASK, start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size <= current_cpu_data.tlbsize) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_context(cpu, mm) & ASID_MASK; + + start &= PAGE_MASK; + end += PAGE_SIZE - 1; + end &= PAGE_MASK; + while (start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += PAGE_SIZE; /* BARRIER */ + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ + continue; + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + local_irq_restore(flags); + } +} + +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbrange<%lu,0x%08lx,0x%08lx>]", start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size <= current_cpu_data.tlbsize) { + int pid = read_c0_entryhi(); + + start &= PAGE_MASK; + end += PAGE_SIZE - 1; + end &= PAGE_MASK; + + while (start < end) { + int idx; + + write_c0_entryhi(start); + start += PAGE_SIZE; /* BARRIER */ + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ + continue; + tlb_write_indexed(); + } + write_c0_entryhi(pid); + } else { + local_flush_tlb_all(); + } + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + int cpu = smp_processor_id(); + + if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { + unsigned long flags; + int oldpid, newpid, idx; + +#ifdef DEBUG_TLB + printk("[tlbpage<%lu,0x%08lx>]", cpu_context(cpu, vma->vm_mm), page); +#endif + newpid = cpu_context(cpu, vma->vm_mm) & ASID_MASK; + page &= PAGE_MASK; + local_irq_save(flags); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); + BARRIER; + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entryhi(KSEG0); + if (idx < 0) /* BARRIER */ + goto finish; + tlb_write_indexed(); + +finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +} + +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + +#ifdef DEBUG_TLB + if ((pid != (cpu_context(cpu, vma->vm_mm) & ASID_MASK)) || (cpu_context(cpu, vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%lu tlbpid=%d\n", + (cpu_context(cpu, vma->vm_mm)), pid); + } +#endif + + local_irq_save(flags); + address &= PAGE_MASK; + write_c0_entryhi(address | pid); + BARRIER; + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(pte_val(pte)); + write_c0_entryhi(address | pid); + if (idx < 0) { /* BARRIER */ + tlb_write_random(); + } else { + tlb_write_indexed(); + } + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long old_ctx; + static unsigned long wired = 0; + + if (r3k_have_wired_reg) { /* TX39XX */ + unsigned long old_pagemask; + unsigned long w; + +#ifdef DEBUG_TLB + printk("[tlbwired<entry lo0 %8x, hi %8x\n, pagemask %8x>]\n", + entrylo0, entryhi, pagemask); +#endif + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + w = read_c0_wired(); + write_c0_wired(w + 1); + if (read_c0_wired() != w + 1) { + printk("[tlbwired] No WIRED reg?\n"); + return; + } + write_c0_index(w << 8); + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + BARRIER; + tlb_write_indexed(); + + write_c0_entryhi(old_ctx); + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); + + } else if (wired < 8) { +#ifdef DEBUG_TLB + printk("[tlbwired<entry lo0 %8x, hi %8x\n>]\n", + entrylo0, entryhi); +#endif + + local_irq_save(flags); + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(entrylo0); + write_c0_entryhi(entryhi); + write_c0_index(wired); + wired++; /* BARRIER */ + tlb_write_indexed(); + write_c0_entryhi(old_ctx); + local_flush_tlb_all(); + local_irq_restore(flags); + } +} + +void __init r3k_tlb_init(void) +{ + local_flush_tlb_all(); + memcpy((void *)KSEG0, &except_vec0_r2300, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); +} diff -Nru a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/tlb-r4k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,459 @@ +/* + * 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. + * + * r4xx0.c: R4000 processor variant specific MMU/Cache routines. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org + * + * To do: + * + * - this code is a overbloated pig + * - many of the bug workarounds are not efficient at all, but at + * least they are functional ... + */ +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/mmu_context.h> +#include <asm/pgtable.h> +#include <asm/system.h> + +#undef DEBUG_TLB +#undef DEBUG_TLBUPDATE + +extern char except_vec0_nevada, except_vec0_r4000, except_vec0_r4600; + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + +#ifdef DEBUG_TLB + printk("[tlball]"); +#endif + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = (read_c0_entryhi() & ASID_MASK); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + BARRIER; + + entry = read_c0_wired(); + + /* Blast 'em all away. */ + while (entry < current_cpu_data.tlbsize) { + /* + * Make sure all entries differ. If they're not different + * MIPS32 will take revenge ... + */ + write_c0_entryhi(KSEG0 + entry*0x2000); + write_c0_index(entry); + BARRIER; + tlb_write_indexed(); + BARRIER; + entry++; + } + BARRIER; + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { +#ifdef DEBUG_TLB + printk("[tlbmm<%d>]", cpu_context(cpu, mm)); +#endif + drop_mmu_context(mm,cpu); + } +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbrange<%02x,%08lx,%08lx>]", cpu_context(cpu, mm) & ASID_MASK, + start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= current_cpu_data.tlbsize/2) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_context(cpu, mm) & ASID_MASK; + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while (start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx < 0) + continue; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0 + idx*0x2000); + BARRIER; + tlb_write_indexed(); + BARRIER; + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + local_irq_restore(flags); + } +} + +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbkernelrange<%02x,%08lx,%08lx>]", start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= current_cpu_data.tlbsize / 2) { + int pid = read_c0_entryhi(); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + + while (start < end) { + int idx; + + write_c0_entryhi(start); + start += (PAGE_SIZE << 1); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx < 0) + continue; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0 + idx*0x2000); + BARRIER; + tlb_write_indexed(); + BARRIER; + } + write_c0_entryhi(pid); + } else { + local_flush_tlb_all(); + } + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + int cpu = smp_processor_id(); + + if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { + unsigned long flags; + int oldpid, newpid, idx; + +#ifdef DEBUG_TLB + printk("[tlbpage<%d,%08lx>]", cpu_context(cpu, vma->vm_mm), + page); +#endif + newpid = (cpu_context(cpu, vma->vm_mm) & ASID_MASK); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(page | newpid); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if(idx < 0) + goto finish; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+idx*0x2000); + BARRIER; + tlb_write_indexed(); + + finish: + BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +} + +/* + * This one is only used for pages with the global bit set so we don't care + * much about the ASID. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + local_irq_save(flags); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi(page); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + BARRIER; + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(oldpid); + + local_irq_restore(flags); +} + +/* We will need multiple versions of update_mmu_cache(), one that just + * updates the TLB with the new pte(s), and another which also checks + * for the R4k "end of page" hardware bug and does the needy. + */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + +#ifdef DEBUG_TLB + if ((pid != cpu_context(cpu, vma->vm_mm) & ASID_MASK) || + (cpu_context(vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d " + "tlbpid=%d\n", + (int) (cpu_context(cpu, vma->vm_mm) & ASID_MASK), pid); + } +#endif + + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | pid); + pgdp = pgd_offset(vma->vm_mm, address); + BARRIER; + tlb_probe(); + BARRIER; + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset_map(pmdp, address); + BARRIER; + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | pid); + BARRIER; + if (idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(pid); + BARRIER; + local_irq_restore(flags); +} + +#if 0 +static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx; + + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (read_c0_entryhi() & ASID_MASK)); + pgdp = pgd_offset(vma->vm_mm, address); + tlb_probe(); + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset_map(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + BARRIER; + if (idx < 0) + tlb_write_random(); + else + tlb_write_indexed(); + BARRIER; + local_irq_restore(flags); +} +#endif + +void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); +} + +/* + * Used for loading TLB entries before trap_init() has started, when we + * don't actually want to add a wired entry which remains throughout the + * lifetime of the system + */ + +static int temp_tlb_entry __initdata; + +__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + int ret = 0; + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + if (--temp_tlb_entry < wired) { + printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); + ret = -ENOSPC; + goto out; + } + + write_c0_index(temp_tlb_entry); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); +out: + local_irq_restore(flags); + return ret; +} + +static void __init probe_tlb(unsigned long config) +{ + unsigned int prid, config1; + + prid = read_c0_prid() & ASID_MASK; + if (prid == PRID_IMP_RM7000 || !(config & (1 << 31))) + /* + * Not a MIPS32 complianant CPU. Config 1 register not + * supported, we assume R4k style. Cpu probing already figured + * out the number of tlb entries. + */ + return; + +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + config1 = read_c0_config1(); + if (!((config >> 7) & 3)) + panic("No MMU present"); + else + current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; +#endif +} + +void __init r4k_tlb_init(void) +{ + u32 config = read_c0_config(); + + /* + * You should never change this register: + * - On R4600 1.7 the tlbp never hits for pages smaller than + * the value in the c0_pagemask register. + * - The entire mm handling assumes the c0_pagemask register to + * be set for 4kb pages. + */ + probe_tlb(config); + write_c0_pagemask(PM_4K); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; + local_flush_tlb_all(); + + if (cpu_has_4kex && cpu_has_4ktlb) { + if (current_cpu_data.cputype == CPU_NEVADA) + memcpy((void *)KSEG0, &except_vec0_nevada, 0x80); + else if (current_cpu_data.cputype == CPU_R4600) + memcpy((void *)KSEG0, &except_vec0_r4600, 0x80); + else + memcpy((void *)KSEG0, &except_vec0_r4000, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); + } +} diff -Nru a/arch/mips/mm/tlb-sb1.c b/arch/mips/mm/tlb-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/tlb-sb1.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,339 @@ +/* + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <asm/mmu_context.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> + +extern char except_vec0_sb1[]; + +/* Dump the current entry* and pagemask registers */ +static inline void dump_cur_tlb_regs(void) +{ + unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi; + unsigned int entrylo1lo, pagemask; + + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set mips64 \n" + ".set noat \n" + " dmfc0 $1, $10 \n" + " dsrl32 %0, $1, 0 \n" + " sll %1, $1, 0 \n" + " dmfc0 $1, $2 \n" + " dsrl32 %2, $1, 0 \n" + " sll %3, $1, 0 \n" + " dmfc0 $1, $3 \n" + " dsrl32 %4, $1, 0 \n" + " sll %5, $1, 0 \n" + " mfc0 %6, $5 \n" + ".set pop \n" + : "=r" (entryhihi), "=r" (entryhilo), + "=r" (entrylo0hi), "=r" (entrylo0lo), + "=r" (entrylo1hi), "=r" (entrylo1lo), + "=r" (pagemask)); + + printk("%08X%08X %08X%08X %08X%08X %08X", + entryhihi, entryhilo, + entrylo0hi, entrylo0lo, + entrylo1hi, entrylo1lo, + pagemask); +} + +void sb1_dump_tlb(void) +{ + unsigned long old_ctx; + unsigned long flags; + int entry; + local_irq_save(flags); + old_ctx = read_c0_entryhi(); + printk("Current TLB registers state:\n" + " EntryHi EntryLo0 EntryLo1 PageMask Index\n" + "--------------------------------------------------------------------\n"); + dump_cur_tlb_regs(); + printk(" %08X\n", read_c0_index()); + printk("\n\nFull TLB Dump:\n" + "Idx EntryHi EntryLo0 EntryLo1 PageMask\n" + "--------------------------------------------------------------\n"); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry); + printk("\n%02i ", entry); + tlb_read(); + dump_cur_tlb_regs(); + } + printk("\n"); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + write_c0_index(entry); + tlb_write_indexed(); + } + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + + +/* + * Use a bogus region of memory (starting at 0) to sanitize the TLB's. + * Use increments of the maximum page size (16MB), and check for duplicate + * entries before doing a given write. Then, when we're safe from collisions + * with the firmware, go back and give all the entries invalid addresses with + * the normal flush routine. + */ +void sb1_sanitize_tlb(void) +{ + int entry; + long addr = 0; + + long inc = 1<<24; /* 16MB */ + /* Save old context and create impossible VPN2 value */ + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + do { + addr += inc; + write_c0_entryhi(addr); + tlb_probe(); + } while ((int)(read_c0_index()) >= 0); + write_c0_index(entry); + tlb_write_indexed(); + } + /* Now that we know we're safe from collisions, we can safely flush + the TLB with the "normal" routine. */ + local_flush_tlb_all(); +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long flags; + int cpu; + + local_irq_save(flags); + cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + int size; + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= (current_cpu_data.tlbsize/2)) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while (start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + } + local_irq_restore(flags); +} + +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + local_irq_save(flags); + if (size <= (current_cpu_data.tlbsize/2)) { + int pid = read_c0_entryhi(); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + + while (start < end) { + int idx; + + write_c0_entryhi(start); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(pid); + } else { + local_flush_tlb_all(); + } + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + unsigned long flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + if (cpu_context(cpu, vma->vm_mm) != 0) { + int oldpid, newpid, idx; + newpid = cpu_asid(cpu, vma->vm_mm); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if(idx < 0) + goto finish; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + tlb_write_indexed(); + finish: + write_c0_entryhi(oldpid); + } + local_irq_restore(flags); +} + +/* + * This one is only used for pages with the global bit set so we don't care + * much about the ASID. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + local_irq_save(flags); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + + local_irq_restore(flags); +} + +/* All entries common to a mm share an asid. To effectively flush + these entries, we just bump the asid. */ +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm, cpu); + } +} + +/* Stolen from mips32 routines */ + +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + local_irq_save(flags); + + pid = read_c0_entryhi() & ASID_MASK; + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (pid)); + pgdp = pgd_offset(vma->vm_mm, address); + tlb_probe(); + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset_map(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + if (idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + local_irq_restore(flags); +} + +/* + * This is called from loadmmu.c. We have to set up all the + * memory management function pointers, as well as initialize + * the caches and tlbs + */ +void sb1_tlb_init(void) +{ + u32 config1; + + write_c0_pagemask(PM_4K); + config1 = read_c0_config1(); + current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; + + /* + * We don't know what state the firmware left the TLB's in, so this is + * the ultra-conservative way to flush the TLB's and avoid machine + * check exceptions due to duplicate TLB entries + */ + sb1_sanitize_tlb(); + + memcpy((void *)KSEG0, except_vec0_sb1, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); +} diff -Nru a/arch/mips/mm/tlbex-r3k.S b/arch/mips/mm/tlbex-r3k.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/tlbex-r3k.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,225 @@ +/* + * TLB exception handling code for R2000/R3000. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-CPU abstraction reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Further modifications to make this work: + * Copyright (c) 1998 Harald Koerfgen + * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov + * Copyright (c) 2001 Ralf Baechle + * Copyright (c) 2001 MIPS Technologies, Inc. + */ +#include <linux/init.h> +#include <asm/asm.h> +#include <asm/cachectl.h> +#include <asm/fpregdef.h> +#include <asm/mipsregs.h> +#include <asm/page.h> +#include <asm/pgtable-bits.h> +#include <asm/processor.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + + .text + .set mips1 + .set noreorder + + __INIT + + /* TLB refill, R[23]00 version */ + LEAF(except_vec0_r2300) + .set noat + .set mips1 + mfc0 k0, CP0_BADVADDR + lw k1, pgd_current # get pgd pointer + srl k0, k0, 22 + sll k0, k0, 2 + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + and k0, k0, 0xffc + addu k1, k1, k0 + lw k0, (k1) + nop + mtc0 k0, CP0_ENTRYLO0 + mfc0 k1, CP0_EPC + tlbwr + jr k1 + rfe + END(except_vec0_r2300) + + __FINIT + + /* ABUSE of CPP macros 101. */ + + /* After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ +#define LOAD_PTE(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, pgd_current; \ + srl pte, pte, 22; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_CONTEXT; \ + lw ptr, (ptr); \ + andi pte, pte, 0xffc; \ + addu ptr, ptr, pte; \ + lw pte, (ptr); \ + nop; + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr) \ + lw ptr, (ptr) ; \ + nop ; \ + mtc0 ptr, CP0_ENTRYLO0; \ + nop; + +#define DO_FAULT(write) \ + .set noat; \ + .set macro; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; \ + .set nomacro; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + sw pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + .set push; \ + .set reorder; \ + lw pte, (ptr); \ + .set pop; + + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + sw pte, (ptr); + +/* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ +#define TLB_WRITE(reg) \ + mfc0 reg, CP0_INDEX; \ + nop; \ + bltz reg, 1f; \ + nop; \ + tlbwi; \ + j 2f; \ + nop; \ +1: tlbwr; \ +2: + +#define RET(reg) \ + mfc0 reg, CP0_EPC; \ + nop; \ + jr reg; \ + rfe + + .set noreorder + + .align 5 +NESTED(handle_tlbl, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbl: +#endif + + DO_FAULT(0) +END(handle_tlbl) + +NESTED(handle_tlbs, PT_SIZE, sp) + .set noat + +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1) + TLB_WRITE(k0) + RET(k0) +nopage_tlbs: +#endif + + DO_FAULT(1) +END(handle_tlbs) + + .align 5 +NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + LOAD_PTE(k0, k1) + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + .set push + .set reorder + lw k0, (k1) + .set pop + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1) + tlbwi + RET(k0) +#endif + +nowrite_mod: + DO_FAULT(1) +END(handle_mod) diff -Nru a/arch/mips/mm/tlbex-r4k.S b/arch/mips/mm/tlbex-r4k.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/mm/tlbex-r4k.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,532 @@ +/* + * TLB exception handling code for r4k. + * + * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse + * + * Multi-cpu abstraction and reworking: + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ +#include <linux/init.h> +#include <linux/config.h> + +#include <asm/asm.h> +#include <asm/offset.h> +#include <asm/cachectl.h> +#include <asm/fpregdef.h> +#include <asm/mipsregs.h> +#include <asm/page.h> +#include <asm/pgtable-bits.h> +#include <asm/processor.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/war.h> + +#define TLB_OPTIMIZE /* If you are paranoid, disable this. */ + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PTE_L ld +#define PTE_S sd +#define PTE_SRL dsrl +#define P_MTC0 dmtc0 +#define PTE_SIZE 8 +#define PTEP_INDX_MSK 0xff0 +#define PTE_INDX_MSK 0xff8 +#define PTE_INDX_SHIFT 9 +#else +#define PTE_L lw +#define PTE_S sw +#define PTE_SRL srl +#define P_MTC0 mtc0 +#define PTE_SIZE 4 +#define PTEP_INDX_MSK 0xff8 +#define PTE_INDX_MSK 0xffc +#define PTE_INDX_SHIFT 10 +#endif + +/* + * ABUSE of CPP macros 101. + * + * After this macro runs, the pte faulted on is + * in register PTE, a ptr into the table in which + * the pte belongs is in PTR. + */ + +#ifdef CONFIG_SMP +#define GET_PGD(scratch, ptr) \ + mfc0 ptr, CP0_CONTEXT; \ + la scratch, pgd_current;\ + srl ptr, 23; \ + sll ptr, 2; \ + addu ptr, scratch, ptr; \ + lw ptr, (ptr); +#else +#define GET_PGD(scratch, ptr) \ + lw ptr, pgd_current; +#endif + +#define LOAD_PTE(pte, ptr) \ + GET_PGD(pte, ptr) \ + mfc0 pte, CP0_BADVADDR; \ + srl pte, pte, _PGDIR_SHIFT; \ + sll pte, pte, 2; \ + addu ptr, ptr, pte; \ + mfc0 pte, CP0_BADVADDR; \ + lw ptr, (ptr); \ + srl pte, pte, PTE_INDX_SHIFT; \ + and pte, pte, PTE_INDX_MSK; \ + addu ptr, ptr, pte; \ + PTE_L pte, (ptr); + + /* This places the even/odd pte pair in the page + * table at PTR into ENTRYLO0 and ENTRYLO1 using + * TMP as a scratch register. + */ +#define PTE_RELOAD(ptr, tmp) \ + ori ptr, ptr, PTE_SIZE; \ + xori ptr, ptr, PTE_SIZE; \ + PTE_L tmp, PTE_SIZE(ptr); \ + PTE_L ptr, 0(ptr); \ + PTE_SRL tmp, tmp, 6; \ + P_MTC0 tmp, CP0_ENTRYLO1; \ + PTE_SRL ptr, ptr, 6; \ + P_MTC0 ptr, CP0_ENTRYLO0; + +#define DO_FAULT(write) \ + .set noat; \ + SAVE_ALL; \ + mfc0 a2, CP0_BADVADDR; \ + KMODE; \ + .set at; \ + move a0, sp; \ + jal do_page_fault; \ + li a1, write; \ + j ret_from_exception; \ + nop; \ + .set noat; + + /* Check is PTE is present, if not then jump to LABEL. + * PTR points to the page table where this PTE is located, + * when the macro is done executing PTE will be restored + * with it's original value. + */ +#define PTE_PRESENT(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_READ); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE valid, store result in PTR. */ +#define PTE_MAKEVALID(pte, ptr) \ + ori pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \ + PTE_S pte, (ptr); + + /* Check if PTE can be written to, if not branch to LABEL. + * Regardless restore PTE with value from PTR when done. + */ +#define PTE_WRITABLE(pte, ptr, label) \ + andi pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + xori pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \ + bnez pte, label; \ + PTE_L pte, (ptr); + + /* Make PTE writable, update software status bits as well, + * then store at PTR. + */ +#define PTE_MAKEWRITE(pte, ptr) \ + ori pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \ + _PAGE_VALID | _PAGE_DIRTY); \ + PTE_S pte, (ptr); + + __INIT + +#ifdef CONFIG_64BIT_PHYS_ADDR +#define GET_PTE_OFF(reg) +#elif CONFIG_CPU_VR41XX +#define GET_PTE_OFF(reg) srl reg, reg, 3 +#else +#define GET_PTE_OFF(reg) srl reg, reg, 1 +#endif + +/* + * These handlers much be written in a relocatable manner + * because based upon the cpu type an arbitrary one of the + * following pieces of code will be copied to the KSEG0 + * vector location. + */ + /* TLB refill, EXL == 0, R4xx0, non-R4600 version */ + .set noreorder + .set noat + LEAF(except_vec0_r4000) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + b 1f + tlbwr # write random tlb entry +1: + nop + eret # return from trap + END(except_vec0_r4000) + + /* TLB refill, EXL == 0, R4600 version */ + LEAF(except_vec0_r4600) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 k1, CP0_ENTRYLO1 + nop + tlbwr + nop + eret + END(except_vec0_r4600) + + /* TLB refill, EXL == 0, R52x0 "Nevada" version */ + /* + * This version has a bug workaround for the Nevada. It seems + * as if under certain circumstances the move from cp0_context + * might produce a bogus result when the mfc0 instruction and + * it's consumer are in a different cacheline or a load instruction, + * probably any memory reference, is between them. This is + * potencially slower than the R4000 version, so we use this + * special version. + */ + .set noreorder + .set noat + LEAF(except_vec0_nevada) + .set mips3 + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + lw k1, pgd_current # get pgd pointer + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 # add in pgd offset + lw k1, (k1) + mfc0 k0, CP0_CONTEXT # get context reg + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + nop # QED specified nops + nop + tlbwr # write random tlb entry + nop # traditional nop + eret # return from trap + END(except_vec0_nevada) + + /* TLB refill, EXL == 0, SB1 with M3 errata handling version */ + LEAF(except_vec0_sb1) +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR # Get faulting address + srl k0, k0, _PGDIR_SHIFT # get pgd only bits + sll k0, k0, 2 + addu k1, k1, k0 # add in pgd offset + mfc0 k0, CP0_CONTEXT # get context reg + lw k1, (k1) + GET_PTE_OFF(k0) # get pte offset + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 # add in offset + PTE_L k0, 0(k1) # get even pte + PTE_L k1, PTE_SIZE(k1) # get odd pte + PTE_SRL k0, k0, 6 # convert to entrylo0 + P_MTC0 k0, CP0_ENTRYLO0 # load it + PTE_SRL k1, k1, 6 # convert to entrylo1 + P_MTC0 k1, CP0_ENTRYLO1 # load it + tlbwr # write random tlb entry +1: eret # return from trap + END(except_vec0_sb1) + + /* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */ + LEAF(except_vec0_r45k_bvahwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r45k_bvahwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */ + LEAF(except_vec0_r4k_mphwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + mfc0 k0, CP0_INDEX + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_mphwbug) +#endif + + /* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */ + LEAF(except_vec0_r4k_250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + b 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_250MHZhwbug) + +#ifdef CONFIG_SMP + /* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */ + LEAF(except_vec0_r4k_MP250MHZhwbug) + .set mips3 + GET_PGD(k0, k1) # get pgd pointer + mfc0 k0, CP0_BADVADDR + srl k0, k0, _PGDIR_SHIFT + sll k0, k0, 2 # log2(sizeof(pgd_t) + addu k1, k1, k0 + mfc0 k0, CP0_CONTEXT + lw k1, (k1) +#ifndef CONFIG_64BIT_PHYS_ADDR + srl k0, k0, 1 +#endif + and k0, k0, PTEP_INDX_MSK + addu k1, k1, k0 + PTE_L k0, 0(k1) + PTE_L k1, PTE_SIZE(k1) + nop /* XXX */ + tlbp + PTE_SRL k0, k0, 6 + P_MTC0 zero, CP0_ENTRYLO0 + P_MTC0 k0, CP0_ENTRYLO0 + mfc0 k0, CP0_INDEX + PTE_SRL k1, k1, 6 + P_MTC0 zero, CP0_ENTRYLO1 + P_MTC0 k1, CP0_ENTRYLO1 + bltzl k0, 1f + tlbwr +1: + nop + eret + END(except_vec0_r4k_MP250MHZhwbug) +#endif + + __FINIT + + .set noreorder + +/* + * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: + * 2. A timing hazard exists for the TLBP instruction. + * + * stalling_instruction + * TLBP + * + * The JTLB is being read for the TLBP throughout the stall generated by the + * previous instruction. This is not really correct as the stalling instruction + * can modify the address used to access the JTLB. The failure symptom is that + * the TLBP instruction will use an address created for the stalling instruction + * and not the address held in C0_ENHI and thus report the wrong results. + * + * The software work-around is to not allow the instruction preceding the TLBP + * to stall - make it an NOP or some other instruction guaranteed not to stall. + * + * Errata 2 will not be fixed. This errata is also on the R5000. + * + * As if we MIPS hackers wouldn't know how to nop pipelines happy ... + */ +#define R5K_HAZARD nop + + /* + * Note for many R4k variants tlb probes cannot be executed out + * of the instruction cache else you get bogus results. + */ + .align 5 + NESTED(handle_tlbl, PT_SIZE, sp) + .set noat +#if BCM1250_M3_WAR + mfc0 k0, CP0_BADVADDR + mfc0 k1, CP0_ENTRYHI + xor k0, k1 + srl k0, k0, PAGE_SHIFT+1 + beqz k0, 1f + nop + .set mips3 + eret + .set mips0 +1: +#endif +invalid_tlbl: +#ifdef TLB_OPTIMIZE + /* Test present bit in entry. */ + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp + PTE_PRESENT(k0, k1, nopage_tlbl) + PTE_MAKEVALID(k0, k1) + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbl: + DO_FAULT(0) + END(handle_tlbl) + + .align 5 + NESTED(handle_tlbs, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + li k0,0 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + PTE_WRITABLE(k0, k1, nopage_tlbs) + PTE_MAKEWRITE(k0, k1) + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nopage_tlbs: + DO_FAULT(1) + END(handle_tlbs) + + .align 5 + NESTED(handle_mod, PT_SIZE, sp) + .set noat +#ifdef TLB_OPTIMIZE + .set mips3 + LOAD_PTE(k0, k1) + R5K_HAZARD + tlbp # find faulting entry + andi k0, k0, _PAGE_WRITE + beqz k0, nowrite_mod + PTE_L k0, (k1) + + /* Present and writable bits set, set accessed and dirty bits. */ + PTE_MAKEWRITE(k0, k1) + + /* Now reload the entry into the tlb. */ + PTE_RELOAD(k1, k0) + nop + b 1f + tlbwi +1: + nop + .set mips3 + eret + .set mips0 +#endif + +nowrite_mod: + DO_FAULT(1) + END(handle_mod) + diff -Nru a/arch/mips/mm/umap.c b/arch/mips/mm/umap.c --- a/arch/mips/mm/umap.c Fri Jun 27 14:20:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,222 +0,0 @@ -/* - * (C) Copyright 1994 Linus Torvalds - * - * Changes: - * - * Modified from Linus source to removing active mappings from any - * task. This is required for implementing the virtual graphics - * interface for direct rendering on the SGI - miguel. - * - * Added a routine to map a vmalloc()ed area into user space, this one - * is required by the /dev/shmiq driver - miguel. - */ -#include <linux/stat.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/shm.h> -#include <linux/errno.h> -#include <linux/mman.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/vmalloc.h> -#include <linux/swap.h> - -#include <asm/system.h> -#include <asm/pgalloc.h> -#include <asm/page.h> - -static inline void -remove_mapping_pte_range (pmd_t *pmd, unsigned long address, unsigned long size) -{ - pte_t *pte; - unsigned long end; - - if (pmd_none (*pmd)) - return; - if (pmd_bad (*pmd)){ - printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", pmd_val (*pmd)); - pmd_clear (pmd); - return; - } - pte = pte_offset (pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t entry = *pte; - if (pte_present (entry)) - set_pte (pte, pte_modify (entry, PAGE_NONE)); - address += PAGE_SIZE; - pte++; - } while (address < end); - -} - -static inline void -remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, unsigned long size) -{ - pmd_t *pmd; - unsigned long end; - - if (pgd_none (*pgd)) - return; - - if (pgd_bad (*pgd)){ - printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", pgd_val (*pgd)); - pgd_clear (pgd); - return; - } - pmd = pmd_offset (pgd, address); - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - do { - remove_mapping_pte_range (pmd, address, end - address); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - -} - -/* - * This routine is called from the page fault handler to remove a - * range of active mappings at this point - */ -void -remove_mapping (struct vm_area_struct *vma, struct task_struct *task, unsigned long start, unsigned long end) -{ - unsigned long beg = start; - pgd_t *dir; - - down_write (&task->mm->mmap_sem); - dir = pgd_offset (task->mm, start); - flush_cache_range (vma, beg, end); - while (start < end){ - remove_mapping_pmd_range (dir, start, end - start); - start = (start + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range (vma, beg, end); - up_write (&task->mm->mmap_sem); -} - -EXPORT_SYMBOL(remove_mapping); - -void *vmalloc_uncached (unsigned long size) -{ - return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_UNCACHED); -} - -static inline void free_pte(pte_t page) -{ - if (pte_present(page)) { - unsigned long pfn = pte_pfn(page); - struct page *ptpage; - if (!pfn_valid(pfn)) - return; - ptpage = pfn_to_page(pfn); - if (PageReserved(ptpage)) - return; - __free_page(ptpage); - if (current->mm->rss <= 0) - return; - current->mm->rss--; - return; - } - swap_free(pte_to_swp_entry(page)); -} - -static inline void forget_pte(pte_t page) -{ - if (!pte_none(page)) { - printk("forget_pte: old mapping existed!\n"); - free_pte(page); - } -} - -/* - * maps a range of vmalloc()ed memory into the requested pages. the old - * mappings are removed. - */ -static inline void -vmap_pte_range (pte_t *pte, unsigned long address, unsigned long size, unsigned long vaddr) -{ - unsigned long end; - pgd_t *vdir; - pmd_t *vpmd; - pte_t *vpte; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t oldpage = *pte; - struct page * page; - pte_clear(pte); - - vdir = pgd_offset_k (vaddr); - vpmd = pmd_offset (vdir, vaddr); - vpte = pte_offset (vpmd, vaddr); - page = pte_page (*vpte); - - set_pte(pte, mk_pte(page, PAGE_USERIO)); - forget_pte(oldpage); - address += PAGE_SIZE; - vaddr += PAGE_SIZE; - pte++; - } while (address < end); -} - -static inline int -vmap_pmd_range (pmd_t *pmd, unsigned long address, unsigned long size, unsigned long vaddr) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - vaddr -= address; - do { - pte_t * pte = pte_alloc(current->mm, pmd, address); - if (!pte) - return -ENOMEM; - vmap_pte_range(pte, address, end - address, address + vaddr); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - return 0; -} - -int -vmap_page_range (struct vm_area_struct *vma, unsigned long from, unsigned long size, unsigned long vaddr) -{ - int error = 0; - pgd_t * dir; - unsigned long beg = from; - unsigned long end = from + size; - - vaddr -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(vma, beg, end); - while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); - error = -ENOMEM; - if (!pmd) - break; - error = vmap_pmd_range(pmd, from, end - from, vaddr + from); - if (error) - break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range(vma, beg, end); - return error; -} diff -Nru a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/Makefile Fri Jun 27 14:20:07 2003 @@ -0,0 +1,8 @@ +# +# Makefile for Momentum Computer's Ocelot-C and -CS boards. +# + +obj-y += mv-irq.o cpci-irq.o uart-irq.o int-handler.o irq.o \ + pci-irq.o prom.o reset.o setup.o + +obj-$(CONFIG_KGDB) += dbg_io.o diff -Nru a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/cpci-irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,154 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/cpci-irq.c + * Interrupt routines for cpci. Interrupt numbers are assigned from + * CPCI_IRQ_BASE to CPCI_IRQ_BASE+8 (8 interrupt sources). + * + * Note that the high-level software will need to be careful about using + * these interrupts. If this board is asserting a cPCI interrupt, it will + * also see the asserted interrupt. Care must be taken to avoid an + * interrupt flood. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <asm/ptrace.h> +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <asm/io.h> +#include "ocelot_c_fpga.h" + +#define CPCI_IRQ_BASE 8 + +static inline int ls1bit8(unsigned int x) +{ + int b = 7, s; + + s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; + s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; + s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 0 is enable, 1 is disable */ +static inline void mask_cpci_irq(unsigned int irq) +{ + uint32_t value; + + value = OCELOT_FPGA_READ(INTMASK); + value |= 1 << (irq - CPCI_IRQ_BASE); + OCELOT_FPGA_WRITE(value, INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(INTMASK); +} + +/* unmask an interrupt -- 0 is enable, 1 is disable */ +static inline void unmask_cpci_irq(unsigned int irq) +{ + uint32_t value; + + value = OCELOT_FPGA_READ(INTMASK); + value &= ~(1 << (irq - CPCI_IRQ_BASE)); + OCELOT_FPGA_WRITE(value, INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(INTMASK); +} + +/* + * Enables the IRQ in the FPGA + */ +static void enable_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_cpci_irq(unsigned int irq) +{ + unmask_cpci_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_cpci_irq(unsigned int irq) +{ + mask_cpci_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_cpci_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_cpci_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the FPGA chip. + * It could be built in ethernet ports etc... + */ +void ll_cpci_irq(struct pt_regs *regs) +{ + unsigned int irq_src, irq_mask; + + /* read the interrupt status registers */ + irq_src = OCELOT_FPGA_READ(INTSTAT); + irq_mask = OCELOT_FPGA_READ(INTMASK); + + /* mask for just the interrupts we want */ + irq_src &= ~irq_mask; + + do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE, regs); +} + +#define shutdown_cpci_irq disable_cpci_irq + +struct hw_interrupt_type cpci_irq_type = { + "CPCI/FPGA", + startup_cpci_irq, + shutdown_cpci_irq, + enable_cpci_irq, + disable_cpci_irq, + mask_and_ack_cpci_irq, + end_cpci_irq, + NULL +}; + +void cpci_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &cpci_irq_type; + } +} diff -Nru a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/dbg_io.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,126 @@ +#include <linux/config.h> + +#if defined(CONFIG_KGDB) + +#include <asm/serial.h> /* For the serial port location and base baud */ + +/* --- CONFIG --- */ + +typedef unsigned char uint8; +typedef unsigned int uint32; + +/* --- END OF CONFIG --- */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ + +/* [jsun] we use the second serial port for kdb */ +#define BASE OCELOT_SERIAL1_BASE +#define MAX_BAUD OCELOT_BASE_BAUD + +/* === END OF CONFIG === */ + +#define REG_OFFSET 4 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) + +void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +uint8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); +} + + +int putDebugChar(uint8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +#endif diff -Nru a/arch/mips/momentum/ocelot_c/int-handler.S b/arch/mips/momentum/ocelot_c/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/int-handler.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,104 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * First-level interrupt dispatcher for Ocelot-CS board. + * + * 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 __ASSEMBLY__ +#include <linux/config.h> +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include "ocelot_c_fpga.h" + +/* + * First level interrupt dispatcher for Ocelot-CS board + */ + .align 5 + NESTED(ocelot_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ + bnez t1, ll_sw0_irq + andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ + bnez t1, ll_sw1_irq + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ + bnez t1, ll_scsi_irq + andi t1, t0, STATUSF_IP3 /* int1 hardware line */ + bnez t1, ll_uart_decode_irq + andi t1, t0, STATUSF_IP4 /* int2 hardware line */ + bnez t1, ll_pmc_irq + andi t1, t0, STATUSF_IP5 /* int3 hardware line */ + bnez t1, ll_cpci_decode_irq + andi t1, t0, STATUSF_IP6 /* int4 hardware line */ + bnez t1, ll_mv64340_decode_irq + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(ocelot_handle_int) + + .align 5 +ll_sw0_irq: + li a0, 0 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_sw1_irq: + li a0, 1 + move a1, sp + jal do_IRQ + j ret_from_irq +ll_scsi_irq: + li a0, 2 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_uart_decode_irq: + move a0, sp + jal ll_uart_irq + j ret_from_irq + +ll_pmc_irq: + li a0, 4 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpci_decode_irq: + move a0, sp + jal ll_cpci_irq + j ret_from_irq + +ll_mv64340_decode_irq: + move a0, sp + jal ll_mv64340_irq + j ret_from_irq + +ll_cputimer_irq: + li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + diff -Nru a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * 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 <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + + +static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) +{ + unsigned long status; + unsigned clr_mask; + unsigned set_mask; + + /* do the low 8 bits first */ + clr_mask = 0xff & clr_mask_in; + set_mask = 0xff & set_mask_in; + status = read_c0_status(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_c0_status(status); +} + +static inline void mask_irq(unsigned int irq) +{ + modify_cp0_intmask(irq, 0); +} + +static inline void unmask_irq(unsigned int irq) +{ + modify_cp0_intmask(0, irq); +} + +static void enable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + unmask_irq(1 << irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +static unsigned int startup_cp7000_irq(unsigned int irq) +{ + enable_cp7000_irq(irq); + + return 0; /* never anything pending */ +} + +static void disable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&irq_lock, flags); + mask_irq(1 << irq); + spin_unlock_irqrestore(&irq_lock, flags); +} + +#define shutdown_cp7000_irq disable_cp7000_irq + +static void mask_and_ack_cp7000_irq(unsigned int irq) +{ + mask_irq(1 << irq); +} + +static void end_cp7000_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_irq(1 << irq); +} + +static struct hw_interrupt_type cp7000_hpcdma_irq_type = { +#ifdef CONFIG_CPU_SR71000 + "SR71000", +#else + "RM7000", +#endif + startup_cp7000_irq, + shutdown_cp7000_irq, + enable_cp7000_irq, + disable_cp7000_irq, + mask_and_ack_cp7000_irq, + end_cp7000_irq, + NULL +}; + +extern asmlinkage void ocelot_handle_int(void); +extern void mv64340_irq_init(void); +extern void uart_irq_init(void); +extern void cpci_irq_init(void); + +static struct irqaction cascade_fpga = + { no_action, SA_INTERRUPT, 0, "cascade via FPGA", NULL, NULL }; +static struct irqaction cascade_mv64340 = + { no_action, SA_INTERRUPT, 0, "cascade via MV64340", NULL, NULL }; + +void __init init_IRQ(void) +{ + int i; + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + __cli(); + + /* Sets the first-level interrupt dispatcher. */ + set_except_vector(0, ocelot_handle_int); + init_generic_irq(); + + /* set up handler for first 8 IRQs as the CPU */ + for (i = 0; i < 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &cp7000_hpcdma_irq_type; + } + + /* set up the cascading interrupts */ + setup_irq(3, &cascade_fpga); + setup_irq(5, &cascade_fpga); + setup_irq(6, &cascade_mv64340); + + mv64340_irq_init(); + uart_irq_init(); + cpci_irq_init(); + +#ifdef CONFIG_KGDB + printk("start kgdb ...\n"); + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif +} diff -Nru a/arch/mips/momentum/ocelot_c/mv-irq.c b/arch/mips/momentum/ocelot_c/mv-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/mv-irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,164 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/mv-irq.c + * Interrupt routines for mv64340. Interrupt numbers are assigned from + * MV64340_IRQ_BASE to MV64340_IRQ_BASE+64. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <asm/ptrace.h> +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <asm/io.h> +#include <asm/mv64340.h> + +#define MV64340_IRQ_BASE 16 + +static inline int ls1bit32(unsigned int x) +{ + int b = 31, s; + + s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; + s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; + s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; + s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; + s = 1; if (x << 1 == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 1 is enable, 0 is disable */ +static inline void mask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value &= ~(1 << (irq - MV64340_IRQ_BASE)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value &= ~(1 << (irq - (MV64340_IRQ_BASE - 32))); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* unmask an interrupt -- 1 is enable, 0 is disable */ +static inline void unmask_mv64340_irq(unsigned int irq) +{ + uint32_t value; + + if (irq < (MV64340_IRQ_BASE + 32)) { + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &value); + value |= 1 << (irq - MV64340_IRQ_BASE); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_LOW, value); + } else { + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &value); + value |= 1 << (irq - (MV64340_IRQ_BASE - 32)); + MV_WRITE(MV64340_INTERRUPT0_MASK_0_HIGH, value); + } +} + +/* + * Enables the IRQ on Marvell Chip + */ +static void enable_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); +} + +/* + * Initialize the IRQ on Marvell Chip + */ +static unsigned int startup_mv64340_irq(unsigned int irq) +{ + unmask_mv64340_irq(irq); + return 0; +} + +/* + * Disables the IRQ on Marvell Chip + */ +static void disable_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_mv64340_irq(unsigned int irq) +{ + mask_mv64340_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_mv64340_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_mv64340_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the Marvell chip. + * It could be built in ethernet ports etc... + */ +void ll_mv64340_irq(struct pt_regs *regs) +{ + unsigned int irq_src_low, irq_src_high; + unsigned int irq_mask_low, irq_mask_high; + + /* read the interrupt status registers */ + MV_READ(MV64340_INTERRUPT0_MASK_0_LOW, &irq_mask_low); + MV_READ(MV64340_INTERRUPT0_MASK_0_HIGH, &irq_mask_high); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_LOW, &irq_src_low); + MV_READ(MV64340_MAIN_INTERRUPT_CAUSE_HIGH, &irq_src_high); + + /* mask for just the interrupts we want */ + irq_src_low &= irq_mask_low; + irq_src_high &= irq_mask_high; + + if (irq_src_low) + do_IRQ(ls1bit32(irq_src_low) + MV64340_IRQ_BASE, regs); + else + do_IRQ(ls1bit32(irq_src_high) + MV64340_IRQ_BASE + 32, regs); +} + +#define shutdown_mv64340_irq disable_mv64340_irq + +struct hw_interrupt_type mv64340_irq_type = { + "MV-64340", + startup_mv64340_irq, + shutdown_mv64340_irq, + enable_mv64340_irq, + disable_mv64340_irq, + mask_and_ack_mv64340_irq, + end_mv64340_irq, + NULL +}; + +void mv64340_irq_init(void) +{ + int i; + + /* Reset irq handlers pointers to NULL */ + for (i = MV64340_IRQ_BASE; i < (MV64340_IRQ_BASE + 64); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &mv64340_irq_type; + } +} diff -Nru a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,50 @@ +/* + * Ocelot-C Board Register Definitions + * + * (C) 2002 Momentum Computer 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. + */ +#ifndef __OCELOT_C_FPGA_H__ +#define __OCELOT_C_FPGA_H__ + +#define OCELOT_C_CS0_ADDR (0xfc000000) + +#define OCELOT_C_REG_BOARDREV 0x0 +#define OCELOT_C_REG_FPGA_REV 0x1 +#define OCELOT_C_REG_FPGA_TYPE 0x2 +#define OCELOT_C_REG_RESET_STATUS 0x3 +#define OCELOT_C_REG_BOARD_STATUS 0x4 +#define OCELOT_C_REG_CPCI_ID 0x5 +#define OCELOT_C_REG_SET 0x6 +#define OCELOT_C_REG_CLR 0x7 +#define OCELOT_C_REG_EEPROM_MODE 0x9 +#define OCELOT_C_REG_INTMASK 0xa +#define OCELOT_C_REG_INTSTAT 0xb +#define OCELOT_C_REG_UART_INTMASK 0xc +#define OCELOT_C_REG_UART_INTSTAT 0xd +#define OCELOT_C_REG_INTSET 0xe +#define OCELOT_C_REG_INTCLR 0xf + +#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y) +#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x) + +#endif diff -Nru a/arch/mips/momentum/ocelot_c/pci-irq.c b/arch/mips/momentum/ocelot_c/pci-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/pci-irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,73 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for mv64340 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/version.h> +#include <linux/init.h> +#include <asm/pci.h> + + +void __init mv64340_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + /* loop over all known devices on this bus */ + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1) && + (PCI_FUNC(devices->devfn) == 0)) { + /* LSI 53C10101R SCSI (A) */ + devices->irq = 2; + } else if ((current_bus->number == 0) && + (PCI_SLOT(devices->devfn) == 1) && + (PCI_FUNC(devices->devfn) == 1)) { + /* LSI 53C10101R SCSI (B) */ + devices->irq = 2; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 1)) { + /* Intel 21555 bridge */ + devices->irq = 12; + } else if ((current_bus->number == 1) && + (PCI_SLOT(devices->devfn) == 2)) { + /* PMC Slot */ + devices->irq = 4; + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, devices->irq); + + /* enable master for everything but the MV-64340 */ + if (((current_bus->number != 0) && (current_bus->number != 1)) + || (PCI_SLOT(devices->devfn) != 0)) { + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } + } +} diff -Nru a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/prom.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,151 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/mv64340.h> + +#include "ocelot_c_fpga.h" + +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; + +struct callvectors* debug_vectors; +char arcs_cmdline[CL_SIZE]; + +extern unsigned long mv64340_base; +extern unsigned long cpu_clock; + +#ifdef CONFIG_MV64340_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + +const char *get_system_type(void) +{ +#ifdef CONFIG_CPU_SR71000 + return "Momentum Ocelot-CS"; +#else + return "Momentum Ocelot-C"; +#endif +} + +#ifdef CONFIG_MV64340_ETH +static void burn_clocks(void) +{ + int i; + + /* this loop should burn at least 1us -- this should be plenty */ + for (i = 0; i < 0x10000; i++) + ; +} + +static u8 exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + burn_clocks(); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + burn_clocks(); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); +} + +void get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} +#endif + +/* [jsun@junsun.net] PMON passes arguments in C main() style */ +void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) +{ + int i; + + /* save the PROM vectors for debugging use */ + debug_vectors = cv; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, arg[i]); + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_MOMENCO; + mips_machtype = MACH_MOMENCO_OCELOT_C; + + while (*env) { + if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { + mv64340_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + } + if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) { + cpu_clock = simple_strtol(*env + strlen("cpuclock="), + NULL, 10); + } + env++; + } + +#ifdef CONFIG_MV64340_ETH + /* get the base MAC address for on-board ethernet ports */ + get_mac(prom_mac_addr_base); +#endif + + debug_vectors->printf("Booting Linux kernel...\n"); +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} diff -Nru a/arch/mips/momentum/ocelot_c/reset.c b/arch/mips/momentum/ocelot_c/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,50 @@ +/* + * 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. + * + * Copyright (C) 1997, 2001 Ralf Baechle + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/system.h> +#include <linux/delay.h> + +void momenco_ocelot_restart(char *command) +{ + /* base address of timekeeper portion of part */ + void *nvram = (void*) 0xfc807000; + + /* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */ + writeb(0x84, nvram + 0xff7); + + /* wait for the watchdog to go off */ + mdelay(100+(1000/16)); + + /* if the watchdog fails for some reason, let people know */ + printk(KERN_NOTICE "Watchdog reset failed\n"); +} + +void momenco_ocelot_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void momenco_ocelot_power_off(void) +{ + momenco_ocelot_halt(); +} diff -Nru a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,326 @@ +/* + * BRIEF MODULE DESCRIPTION + * Momentum Computer Ocelot-C and -CS board dependent boot routines + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2002 Momentum Computer + * + * Author: Matthew Dharm, Momentum Computer + * mdharm@momenco.com + * + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * 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 <linux/bcd.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mc146818rtc.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <linux/vmalloc.h> +#include <asm/time.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/mc146818rtc.h> +#include <linux/version.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include <asm/mv64340.h> +#include "ocelot_c_fpga.h" + +unsigned long mv64340_base; +unsigned long cpu_clock; + +/* These functions are used for rebooting or halting the machine*/ +extern void momenco_ocelot_restart(char *command); +extern void momenco_ocelot_halt(void); +extern void momenco_ocelot_power_off(void); + +void momenco_time_init(void); + +static char reset_reason; + +#define ENTRYLO(x) ((pte_val(mk_pte_phys((x), PAGE_KERNEL_UNCACHED)) >> 6)|1) + +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup(void) +{ + /* Some wired TLB entries for the MV64340 and perhiperals. The + MV64340 is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) + + Device Physical Virtual + MV64340 Internal Regs 0xf4000000 0xf4000000 + Ocelot-C[S] PLD (CS0) 0xfc000000 0xfc000000 + NVRAM (CS1) 0xfc800000 0xfc800000 + UARTs (CS2) 0xfd000000 0xfd000000 + Internal SRAM 0xfe000000 0xfe000000 + M-Systems DOC (CS3) 0xff000000 0xff000000 + */ + + /* marvell and extra space */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); + /* fpga, rtc, and uart */ + add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), 0xfc000000, PM_16M); + /* m-sys and internal SRAM */ + add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); + + mv64340_base = 0xf4000000; +} + +unsigned long m48t37y_get_time(void) +{ + unsigned char* rtc_base = (unsigned char*)0xfc800000; + unsigned int year, month, day, hour, min, sec; + + /* stop the update */ + rtc_base[0x7ff8] = 0x40; + + year = BCD2BIN(rtc_base[0x7fff]); + year += BCD2BIN(rtc_base[0x7ff1]) * 100; + + month = BCD2BIN(rtc_base[0x7ffe]); + + day = BCD2BIN(rtc_base[0x7ffd]); + + hour = BCD2BIN(rtc_base[0x7ffb]); + min = BCD2BIN(rtc_base[0x7ffa]); + sec = BCD2BIN(rtc_base[0x7ff9]); + + /* start the update */ + rtc_base[0x7ff8] = 0x00; + + return mktime(year, month, day, hour, min, sec); +} + +int m48t37y_set_time(unsigned long sec) +{ + unsigned char* rtc_base = (unsigned char*)0xfc800000; + struct rtc_time tm; + + /* convert to a more useful format -- note months count from 0 */ + to_tm(sec, &tm); + tm.tm_mon += 1; + + /* enable writing */ + rtc_base[0x7ff8] = 0x80; + + /* year */ + rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100); + rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100); + + /* month */ + rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon); + + /* day */ + rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday); + + /* hour/min/sec */ + rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour); + rtc_base[0x7ffa] = BIN2BCD(tm.tm_min); + rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec); + + /* day of week -- not really used, but let's keep it up-to-date */ + rtc_base[0x7ffc] = CONV_BIN2BCD(tm.tm_wday + 1); + + /* disable writing */ + rtc_base[0x7ff8] = 0x00; + + return 0; +} + +void momenco_timer_setup(struct irqaction *irq) +{ + setup_irq(7, irq); +} + +void momenco_time_init(void) +{ +#ifdef CONFIG_CPU_SR71000 + mips_counter_frequency = cpu_clock; +#elif defined(CONFIG_CPU_RM7000) + mips_counter_frequency = cpu_clock / 2; +#else +#error Unknown CPU for this board +#endif + board_timer_setup = momenco_timer_setup; + + rtc_get_time = m48t37y_get_time; + rtc_set_time = m48t37y_set_time; +} + +void __init momenco_ocelot_c_setup(void) +{ + unsigned int tmpword; + + board_time_init = momenco_time_init; + + _machine_restart = momenco_ocelot_restart; + _machine_halt = momenco_ocelot_halt; + _machine_power_off = momenco_ocelot_power_off; + + /* + * initrd_start = (ulong)ocelot_initrd_start; + * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; + * initrd_below_start_ok = 1; + */ + + /* do handoff reconfiguration */ + PMON_v2_setup(); + + /* shut down ethernet ports, just to be sure our memory doesn't get + * corrupted by random ethernet traffic. + */ + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); + MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); + do {} + while (MV_READ_DATA(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); + MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), MV_READ_DATA(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); + + /* Turn off the Bit-Error LED */ + OCELOT_FPGA_WRITE(0x80, CLR); + + tmpword = OCELOT_FPGA_READ(BOARDREV); +#ifdef CONFIG_CPU_SR71000 + if (tmpword < 26) + printk("Momenco Ocelot-CS: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momenco Ocelot-CS: Board Assembly Revision #0x%x\n", + tmpword); +#else + if (tmpword < 26) + printk("Momenco Ocelot-C: Board Assembly Rev. %c\n", + 'A'+tmpword); + else + printk("Momenco Ocelot-C: Board Assembly Revision #0x%x\n", + tmpword); +#endif + + tmpword = OCELOT_FPGA_READ(FPGA_REV); + printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15); + tmpword = OCELOT_FPGA_READ(RESET_STATUS); + printk("Reset reason: 0x%x\n", tmpword); + switch (tmpword) { + case 0x1: + printk(" - Power-up reset\n"); + break; + case 0x2: + printk(" - Push-button reset\n"); + break; + case 0x4: + printk(" - cPCI bus reset\n"); + break; + case 0x8: + printk(" - Watchdog reset\n"); + break; + case 0x10: + printk(" - Software reset\n"); + break; + default: + printk(" - Unknown reset cause\n"); + } + reset_reason = tmpword; + OCELOT_FPGA_WRITE(0xff, RESET_STATUS); + + tmpword = OCELOT_FPGA_READ(CPCI_ID); + printk("cPCI ID register: 0x%02x\n", tmpword); + printk(" - Slot number: %d\n", tmpword & 0x1f); + printk(" - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no"); + printk(" - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no"); + + tmpword = OCELOT_FPGA_READ(BOARD_STATUS); + printk("Board Status register: 0x%02x\n", tmpword); + printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); + printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); + printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1); + printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3))); + + switch(tmpword &3) { + case 3: + /* 512MiB */ + add_memory_region(0x0, 0x200<<20, BOOT_MEM_RAM); + break; + case 2: + /* 256MiB */ + add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM); + break; + case 1: + /* 128MiB */ + add_memory_region(0x0, 0x80<<20, BOOT_MEM_RAM); + break; + case 0: + /* 1GiB -- needs CONFIG_HIGHMEM */ + add_memory_region(0x0, 0x400<<20, BOOT_MEM_RAM); + break; + } +} + +/* This needs to be one of the first initcalls, because no I/O port access + can work before this */ +static int io_base_ioremap(void) +{ + /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ + void *io_remap_range = ioremap(0xc0000000, 0x30000000); + + if (!io_remap_range) { + panic("Could not ioremap I/O port range"); + } + printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); + + return 0; +} + +module_init(io_base_ioremap); diff -Nru a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_c/uart-irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,148 @@ +/* + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_c/uart-irq.c + * Interrupt routines for UARTs. Interrupt numbers are assigned from + * 80 to 81 (2 interrupt sources). + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <asm/ptrace.h> +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <asm/io.h> +#include <asm/irq.h> +#include "ocelot_c_fpga.h" + +static inline int ls1bit8(unsigned int x) +{ + int b = 7, s; + + s = 4; if (((unsigned char)(x << 4)) == 0) s = 0; b -= s; x <<= s; + s = 2; if (((unsigned char)(x << 2)) == 0) s = 0; b -= s; x <<= s; + s = 1; if (((unsigned char)(x << 1)) == 0) s = 0; b -= s; + + return b; +} + +/* mask off an interrupt -- 0 is enable, 1 is disable */ +static inline void mask_uart_irq(unsigned int irq) +{ + uint8_t value; + + value = OCELOT_FPGA_READ(UART_INTMASK); + value |= 1 << (irq - 74); + OCELOT_FPGA_WRITE(value, UART_INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(UART_INTMASK); +} + +/* unmask an interrupt -- 0 is enable, 1 is disable */ +static inline void unmask_uart_irq(unsigned int irq) +{ + uint8_t value; + + value = OCELOT_FPGA_READ(UART_INTMASK); + value &= ~(1 << (irq - 74)); + OCELOT_FPGA_WRITE(value, UART_INTMASK); + + /* read the value back to assure that it's really been written */ + value = OCELOT_FPGA_READ(UART_INTMASK); +} + +/* + * Enables the IRQ in the FPGA + */ +static void enable_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); +} + +/* + * Initialize the IRQ in the FPGA + */ +static unsigned int startup_uart_irq(unsigned int irq) +{ + unmask_uart_irq(irq); + return 0; +} + +/* + * Disables the IRQ in the FPGA + */ +static void disable_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * Masks and ACKs an IRQ + */ +static void mask_and_ack_uart_irq(unsigned int irq) +{ + mask_uart_irq(irq); +} + +/* + * End IRQ processing + */ +static void end_uart_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_uart_irq(irq); +} + +/* + * Interrupt handler for interrupts coming from the FPGA chip. + */ +void ll_uart_irq(struct pt_regs *regs) +{ + unsigned int irq_src, irq_mask; + + /* read the interrupt status registers */ + irq_src = OCELOT_FPGA_READ(UART_INTSTAT); + irq_mask = OCELOT_FPGA_READ(UART_INTMASK); + + /* mask for just the interrupts we want */ + irq_src &= ~irq_mask; + + do_IRQ(ls1bit8(irq_src) + 74, regs); +} + +#define shutdown_uart_irq disable_uart_irq + +struct hw_interrupt_type uart_irq_type = { + "UART/FPGA", + startup_uart_irq, + shutdown_uart_irq, + enable_uart_irq, + disable_uart_irq, + mask_and_ack_uart_irq, + end_uart_irq, + NULL +}; + +void uart_irq_init(void) +{ + /* Reset irq handlers pointers to NULL */ + irq_desc[80].status = IRQ_DISABLED; + irq_desc[80].action = 0; + irq_desc[80].depth = 2; + irq_desc[80].handler = &uart_irq_type; + + irq_desc[81].status = IRQ_DISABLED; + irq_desc[81].action = 0; + irq_desc[81].depth = 2; + irq_desc[81].handler = &uart_irq_type; +} diff -Nru a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,9 @@ +# +# Makefile for Momentum Computer's Ocelot-G board. +# + +obj-y += gt-irq.o pci-irq.o int-handler.o irq.o prom.o \ + reset.o setup.o +obj-$(CONFIG_KGDB) += dbg_io.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/momentum/ocelot_g/dbg_io.c b/arch/mips/momentum/ocelot_g/dbg_io.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/dbg_io.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,126 @@ +#include <linux/config.h> + +#if defined(CONFIG_KGDB) + +#include <asm/serial.h> /* For the serial port location and base baud */ + +/* --- CONFIG --- */ + +typedef unsigned char uint8; +typedef unsigned int uint32; + +/* --- END OF CONFIG --- */ + +#define UART16550_BAUD_2400 2400 +#define UART16550_BAUD_4800 4800 +#define UART16550_BAUD_9600 9600 +#define UART16550_BAUD_19200 19200 +#define UART16550_BAUD_38400 38400 +#define UART16550_BAUD_57600 57600 +#define UART16550_BAUD_115200 115200 + +#define UART16550_PARITY_NONE 0 +#define UART16550_PARITY_ODD 0x08 +#define UART16550_PARITY_EVEN 0x18 +#define UART16550_PARITY_MARK 0x28 +#define UART16550_PARITY_SPACE 0x38 + +#define UART16550_DATA_5BIT 0x0 +#define UART16550_DATA_6BIT 0x1 +#define UART16550_DATA_7BIT 0x2 +#define UART16550_DATA_8BIT 0x3 + +#define UART16550_STOP_1BIT 0x0 +#define UART16550_STOP_2BIT 0x4 + +/* ----------------------------------------------------- */ + +/* === CONFIG === */ + +/* [jsun] we use the second serial port for kdb */ +#define BASE OCELOT_SERIAL1_BASE +#define MAX_BAUD OCELOT_BASE_BAUD + +/* === END OF CONFIG === */ + +#define REG_OFFSET 4 + +/* register offset */ +#define OFS_RCV_BUFFER 0 +#define OFS_TRANS_HOLD 0 +#define OFS_SEND_BUFFER 0 +#define OFS_INTR_ENABLE (1*REG_OFFSET) +#define OFS_INTR_ID (2*REG_OFFSET) +#define OFS_DATA_FORMAT (3*REG_OFFSET) +#define OFS_LINE_CONTROL (3*REG_OFFSET) +#define OFS_MODEM_CONTROL (4*REG_OFFSET) +#define OFS_RS232_OUTPUT (4*REG_OFFSET) +#define OFS_LINE_STATUS (5*REG_OFFSET) +#define OFS_MODEM_STATUS (6*REG_OFFSET) +#define OFS_RS232_INPUT (6*REG_OFFSET) +#define OFS_SCRATCH_PAD (7*REG_OFFSET) + +#define OFS_DIVISOR_LSB (0*REG_OFFSET) +#define OFS_DIVISOR_MSB (1*REG_OFFSET) + + +/* memory-mapped read/write of the port */ +#define UART16550_READ(y) (*((volatile uint8*)(BASE + y))) +#define UART16550_WRITE(y, z) ((*((volatile uint8*)(BASE + y))) = z) + +void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) +{ + /* disable interrupts */ + UART16550_WRITE(OFS_INTR_ENABLE, 0); + + /* set up buad rate */ + { + uint32 divisor; + + /* set DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x80); + + /* set divisor */ + divisor = MAX_BAUD / baud; + UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff); + UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8); + + /* clear DIAB bit */ + UART16550_WRITE(OFS_LINE_CONTROL, 0x0); + } + + /* set data format */ + UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop); +} + +static int remoteDebugInitialized = 0; + +uint8 getDebugChar(void) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0); + return UART16550_READ(OFS_RCV_BUFFER); +} + + +int putDebugChar(uint8 byte) +{ + if (!remoteDebugInitialized) { + remoteDebugInitialized = 1; + debugInit(UART16550_BAUD_38400, + UART16550_DATA_8BIT, + UART16550_PARITY_NONE, UART16550_STOP_1BIT); + } + + while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0); + UART16550_WRITE(OFS_SEND_BUFFER, byte); + return 1; +} + +#endif diff -Nru a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/gt-irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,294 @@ +/* + * + * Copyright 2002 Momentum Computer + * Author: mdharm@momenco.com + * + * arch/mips/momentum/ocelot_g/gt_irq.c + * Interrupt routines for gt64240. Currently it only handles timer irq. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <asm/ptrace.h> +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/kernel_stat.h> +#include <asm/io.h> +#include "gt64240.h" + +unsigned long bus_clock; + +/* + * These are interrupt handlers for the GT on-chip interrupts. They + * all come in to the MIPS on a single interrupt line, and have to + * be handled and ack'ed differently than other MIPS interrupts. + */ + +#if CURRENTLY_UNUSED + +struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; +void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); + +/* + * Hooks IRQ handler to the system. When the system is interrupted + * the interrupt service routine is called. + * + * Inputs : + * int_cause - The interrupt cause number. In EVB64120 two parameters + * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. + * bit_num - Indicates which bit number in the cause register + * isr_ptr - Pointer to the interrupt service routine + */ +void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr) +{ + irq_handlers[int_cause][bit_num].routine = isr_ptr; +} + + +/* + * Enables the IRQ on Galileo Chip + * + * Inputs : + * int_cause - The interrupt cause number. In EVB64120 two parameters + * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. + * bit_num - Indicates which bit number in the cause register + * + * Outputs : + * 1 if succesful, 0 if failure + */ +int enable_galileo_irq(int int_cause, int bit_num) +{ + if (int_cause == INT_CAUSE_MAIN) + SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num)); + else if (int_cause == INT_CAUSE_HIGH) + SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, + (1 << bit_num)); + else + return 0; + + return 1; +} + +/* + * Disables the IRQ on Galileo Chip + * + * Inputs : + * int_cause - The interrupt cause number. In EVB64120 two parameters + * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH. + * bit_num - Indicates which bit number in the cause register + * + * Outputs : + * 1 if succesful, 0 if failure + */ +int disable_galileo_irq(int int_cause, int bit_num) +{ + if (int_cause == INT_CAUSE_MAIN) + RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, + (1 << bit_num)); + else if (int_cause == INT_CAUSE_HIGH) + RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER, + (1 << bit_num)); + else + return 0; + return 1; +} +#endif /* UNUSED */ + +/* + * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#. + * + * We route the timer interrupt to P0_INT# (IRQ 6), and that's all this + * routine can handle, for now. + * + * In the future, we'll route more interrupts to this pin, and that's why + * we keep this particular structure in the function. + */ + +static void gt64240_p0int_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + uint32_t irq_src, irq_src_mask; + int handled; + + /* get the low interrupt cause register */ + GT_READ(LOW_INTERRUPT_CAUSE_REGISTER, &irq_src); + + /* get the mask register for this pin */ + GT_READ(PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, &irq_src_mask); + + /* mask off only the interrupts we're interested in */ + irq_src = irq_src & irq_src_mask; + + handled = 0; + + /* Check for timer interrupt */ + if (irq_src & 0x00000100) { + handled = 1; + irq_src &= ~0x00000100; + + /* Clear any pending cause bits */ + GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0); + + /* handle the timer call */ + do_timer(regs); + } + + if (irq_src) { + printk(KERN_INFO + "UNKNOWN P0_INT# interrupt received, irq_src=0x%x\n", + irq_src); + } +} + +/* + * Interrupt handler for interrupts coming from the Galileo chip. + * It could be built in ethernet ports etc... + */ +static void gt64240_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int irq_src, int_high_src, irq_src_mask, + int_high_src_mask; + int handled; + +#if 0 + GT_READ(GT_INTRCAUSE_OFS, &irq_src); + GT_READ(GT_INTRMASK_OFS, &irq_src_mask); + GT_READ(GT_HINTRCAUSE_OFS, &int_high_src); + GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask); +#endif + irq_src = irq_src & irq_src_mask; + int_high_src = int_high_src & int_high_src_mask; + + handled = 0; + + /* Execute all interrupt handlers */ + /* Check for timer interrupt */ + if (irq_src & 0x00000800) { + handled = 1; + irq_src &= ~0x00000800; + // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8); + do_timer(regs); + } + + if (irq_src) { + printk(KERN_INFO + "Other Galileo interrupt received irq_src %x\n", + irq_src); +#if CURRENTLY_UNUSED + for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) { + if (irq_src & (1 << count)) { + if (irq_handlers[INT_CAUSE_MAIN][count]. + routine) { + queue_task(&irq_handlers + [INT_CAUSE_MAIN][count], + &tq_immediate); + mark_bh(IMMEDIATE_BH); + handled = 1; + } + } + } +#endif /* UNUSED */ + } +#if 0 + GT_WRITE(GT_INTRCAUSE_OFS, 0); + GT_WRITE(GT_HINTRCAUSE_OFS, 0); +#endif + +#undef GALILEO_I2O +#ifdef GALILEO_I2O + /* + * Future I2O support. We currently attach I2O interrupt handlers to + * the Galileo interrupt (int 4) and handle them in do_IRQ. + */ + if (isInBoundDoorBellInterruptSet()) { + printk(KERN_INFO "I2O doorbell interrupt received.\n"); + handled = 1; + } + + if (isInBoundPostQueueInterruptSet()) { + printk(KERN_INFO "I2O Queue interrupt received.\n"); + handled = 1; + } + + /* + * This normally would be outside of the ifdef, but since we're + * handling I2O outside of this handler, this printk shows up every + * time we get a valid I2O interrupt. So turn this off for now. + */ + if (handled == 0) { + if (counter < 50) { + printk("Spurious Galileo interrupt...\n"); + counter++; + } + } +#endif +} + +/* + * Initializes timer using galileo's built in timer. + */ + +/* + * This will ignore the standard MIPS timer interrupt handler + * that is passed in as *irq (=irq0 in ../kernel/time.c). + * We will do our own timer interrupt handling. + */ +void gt64240_time_init(void) +{ + extern irq_desc_t irq_desc[NR_IRQS]; + static struct irqaction timer; + + /* Stop the timer -- we'll use timer #0 */ + GT_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x0); + + /* Load timer value for 100 Hz */ + GT_WRITE(TIMER_COUNTER0, bus_clock / 100); + + /* + * Create the IRQ structure entry for the timer. Since we're too early + * in the boot process to use the "request_irq()" call, we'll hard-code + * the values to the correct interrupt line. + */ + timer.handler = >64240_p0int_irq; + timer.flags = SA_SHIRQ | SA_INTERRUPT; + timer.name = "timer"; + timer.dev_id = NULL; + timer.next = NULL; + timer.mask = 0; + irq_desc[6].action = &timer; + + enable_irq(6); + + /* Clear any pending cause bits */ + GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0); + + /* Enable the interrupt for timer 0 */ + GT_WRITE(TIMER_COUNTER_0_3_INTERRUPT_MASK, 0x1); + + /* Enable the timer interrupt for GT-64240 pin P0_INT# */ + GT_WRITE (PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW, 0x100); + + /* Configure and start the timer */ + GT_WRITE(TIMER_COUNTER_0_3_CONTROL, 0x3); +} + +void gt64240_irq_init(void) +{ +#if CURRENTLY_UNUSED + int i, j; + + /* Reset irq handlers pointers to NULL */ + for (i = 0; i < MAX_CAUSE_REGS; i++) { + for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) { + irq_handlers[i][j].next = NULL; + irq_handlers[i][j].sync = 0; + irq_handlers[i][j].routine = NULL; + irq_handlers[i][j].data = NULL; + } + } +#endif +} diff -Nru a/arch/mips/momentum/ocelot_g/gt64240.h b/arch/mips/momentum/ocelot_g/gt64240.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/gt64240.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1238 @@ +/* gt64240r.h - GT-64240 Internal registers definition file */ + +/* Copyright - Galileo technology. */ + +#ifndef __INCgt64240rh +#define __INCgt64240rh + +#define GTREG(v) (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \ + (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00) + +#if 0 +#define GTREG_SHORT(X) (((X) << 8) | ((X) >> 8)) + +#define LONG_GTREG(X) ((l64) \ + (((X)&0x00000000000000ffULL) << 56) | \ + (((X)&0x000000000000ff00ULL) << 40) | \ + (((X)&0x0000000000ff0000ULL) << 24) | \ + (((X)&0x00000000ff000000ULL) << 8) | \ + (((X)&0x000000ff00000000ULL) >> 8) | \ + (((X)&0x0000ff0000000000ULL) >> 24) | \ + (((X)&0x00ff000000000000ULL) >> 40) | \ + (((X)&0xff00000000000000ULL) >> 56)) +#endif + +#include "gt64240_dep.h" + +/****************************************/ +/* CPU Control Registers */ +/****************************************/ + +#define CPU_CONFIGURATION 0x000 +#define CPU_MODE 0x120 +#define CPU_READ_RESPONSE_CROSSBAR_LOW 0x170 +#define CPU_READ_RESPONSE_CROSSBAR_HIGH 0x178 + +/****************************************/ +/* Processor Address Space */ +/****************************************/ + +/* Sdram's BAR'S */ +#define SCS_0_LOW_DECODE_ADDRESS 0x008 +#define SCS_0_HIGH_DECODE_ADDRESS 0x010 +#define SCS_1_LOW_DECODE_ADDRESS 0x208 +#define SCS_1_HIGH_DECODE_ADDRESS 0x210 +#define SCS_2_LOW_DECODE_ADDRESS 0x018 +#define SCS_2_HIGH_DECODE_ADDRESS 0x020 +#define SCS_3_LOW_DECODE_ADDRESS 0x218 +#define SCS_3_HIGH_DECODE_ADDRESS 0x220 +/* Devices BAR'S */ +#define CS_0_LOW_DECODE_ADDRESS 0x028 +#define CS_0_HIGH_DECODE_ADDRESS 0x030 +#define CS_1_LOW_DECODE_ADDRESS 0x228 +#define CS_1_HIGH_DECODE_ADDRESS 0x230 +#define CS_2_LOW_DECODE_ADDRESS 0x248 +#define CS_2_HIGH_DECODE_ADDRESS 0x250 +#define CS_3_LOW_DECODE_ADDRESS 0x038 +#define CS_3_HIGH_DECODE_ADDRESS 0x040 +#define BOOTCS_LOW_DECODE_ADDRESS 0x238 +#define BOOTCS_HIGH_DECODE_ADDRESS 0x240 + +#define PCI_0I_O_LOW_DECODE_ADDRESS 0x048 +#define PCI_0I_O_HIGH_DECODE_ADDRESS 0x050 +#define PCI_0MEMORY0_LOW_DECODE_ADDRESS 0x058 +#define PCI_0MEMORY0_HIGH_DECODE_ADDRESS 0x060 +#define PCI_0MEMORY1_LOW_DECODE_ADDRESS 0x080 +#define PCI_0MEMORY1_HIGH_DECODE_ADDRESS 0x088 +#define PCI_0MEMORY2_LOW_DECODE_ADDRESS 0x258 +#define PCI_0MEMORY2_HIGH_DECODE_ADDRESS 0x260 +#define PCI_0MEMORY3_LOW_DECODE_ADDRESS 0x280 +#define PCI_0MEMORY3_HIGH_DECODE_ADDRESS 0x288 + +#define PCI_1I_O_LOW_DECODE_ADDRESS 0x090 +#define PCI_1I_O_HIGH_DECODE_ADDRESS 0x098 +#define PCI_1MEMORY0_LOW_DECODE_ADDRESS 0x0a0 +#define PCI_1MEMORY0_HIGH_DECODE_ADDRESS 0x0a8 +#define PCI_1MEMORY1_LOW_DECODE_ADDRESS 0x0b0 +#define PCI_1MEMORY1_HIGH_DECODE_ADDRESS 0x0b8 +#define PCI_1MEMORY2_LOW_DECODE_ADDRESS 0x2a0 +#define PCI_1MEMORY2_HIGH_DECODE_ADDRESS 0x2a8 +#define PCI_1MEMORY3_LOW_DECODE_ADDRESS 0x2b0 +#define PCI_1MEMORY3_HIGH_DECODE_ADDRESS 0x2b8 + +#define INTERNAL_SPACE_DECODE 0x068 + +#define CPU_0_LOW_DECODE_ADDRESS 0x290 +#define CPU_0_HIGH_DECODE_ADDRESS 0x298 +#define CPU_1_LOW_DECODE_ADDRESS 0x2c0 +#define CPU_1_HIGH_DECODE_ADDRESS 0x2c8 + +#define PCI_0I_O_ADDRESS_REMAP 0x0f0 +#define PCI_0MEMORY0_ADDRESS_REMAP 0x0f8 +#define PCI_0MEMORY0_HIGH_ADDRESS_REMAP 0x320 +#define PCI_0MEMORY1_ADDRESS_REMAP 0x100 +#define PCI_0MEMORY1_HIGH_ADDRESS_REMAP 0x328 +#define PCI_0MEMORY2_ADDRESS_REMAP 0x2f8 +#define PCI_0MEMORY2_HIGH_ADDRESS_REMAP 0x330 +#define PCI_0MEMORY3_ADDRESS_REMAP 0x300 +#define PCI_0MEMORY3_HIGH_ADDRESS_REMAP 0x338 + +#define PCI_1I_O_ADDRESS_REMAP 0x108 +#define PCI_1MEMORY0_ADDRESS_REMAP 0x110 +#define PCI_1MEMORY0_HIGH_ADDRESS_REMAP 0x340 +#define PCI_1MEMORY1_ADDRESS_REMAP 0x118 +#define PCI_1MEMORY1_HIGH_ADDRESS_REMAP 0x348 +#define PCI_1MEMORY2_ADDRESS_REMAP 0x310 +#define PCI_1MEMORY2_HIGH_ADDRESS_REMAP 0x350 +#define PCI_1MEMORY3_ADDRESS_REMAP 0x318 +#define PCI_1MEMORY3_HIGH_ADDRESS_REMAP 0x358 + +/****************************************/ +/* CPU Sync Barrier */ +/****************************************/ + +#define PCI_0SYNC_BARIER_VIRTUAL_REGISTER 0x0c0 +#define PCI_1SYNC_BARIER_VIRTUAL_REGISTER 0x0c8 + + +/****************************************/ +/* CPU Access Protect */ +/****************************************/ + +#define CPU_LOW_PROTECT_ADDRESS_0 0X180 +#define CPU_HIGH_PROTECT_ADDRESS_0 0X188 +#define CPU_LOW_PROTECT_ADDRESS_1 0X190 +#define CPU_HIGH_PROTECT_ADDRESS_1 0X198 +#define CPU_LOW_PROTECT_ADDRESS_2 0X1a0 +#define CPU_HIGH_PROTECT_ADDRESS_2 0X1a8 +#define CPU_LOW_PROTECT_ADDRESS_3 0X1b0 +#define CPU_HIGH_PROTECT_ADDRESS_3 0X1b8 +#define CPU_LOW_PROTECT_ADDRESS_4 0X1c0 +#define CPU_HIGH_PROTECT_ADDRESS_4 0X1c8 +#define CPU_LOW_PROTECT_ADDRESS_5 0X1d0 +#define CPU_HIGH_PROTECT_ADDRESS_5 0X1d8 +#define CPU_LOW_PROTECT_ADDRESS_6 0X1e0 +#define CPU_HIGH_PROTECT_ADDRESS_6 0X1e8 +#define CPU_LOW_PROTECT_ADDRESS_7 0X1f0 +#define CPU_HIGH_PROTECT_ADDRESS_7 0X1f8 + + +/****************************************/ +/* Snoop Control */ +/****************************************/ + +#define SNOOP_BASE_ADDRESS_0 0x380 +#define SNOOP_TOP_ADDRESS_0 0x388 +#define SNOOP_BASE_ADDRESS_1 0x390 +#define SNOOP_TOP_ADDRESS_1 0x398 +#define SNOOP_BASE_ADDRESS_2 0x3a0 +#define SNOOP_TOP_ADDRESS_2 0x3a8 +#define SNOOP_BASE_ADDRESS_3 0x3b0 +#define SNOOP_TOP_ADDRESS_3 0x3b8 + +/****************************************/ +/* CPU Error Report */ +/****************************************/ + +#define CPU_ERROR_ADDRESS_LOW 0x070 +#define CPU_ERROR_ADDRESS_HIGH 0x078 +#define CPU_ERROR_DATA_LOW 0x128 +#define CPU_ERROR_DATA_HIGH 0x130 +#define CPU_ERROR_PARITY 0x138 +#define CPU_ERROR_CAUSE 0x140 +#define CPU_ERROR_MASK 0x148 + +/****************************************/ +/* Pslave Debug */ +/****************************************/ + +#define X_0_ADDRESS 0x360 +#define X_0_COMMAND_ID 0x368 +#define X_1_ADDRESS 0x370 +#define X_1_COMMAND_ID 0x378 +#define WRITE_DATA_LOW 0x3c0 +#define WRITE_DATA_HIGH 0x3c8 +#define WRITE_BYTE_ENABLE 0X3e0 +#define READ_DATA_LOW 0x3d0 +#define READ_DATA_HIGH 0x3d8 +#define READ_ID 0x3e8 + + +/****************************************/ +/* SDRAM and Device Address Space */ +/****************************************/ + + +/****************************************/ +/* SDRAM Configuration */ +/****************************************/ + +#define SDRAM_CONFIGURATION 0x448 +#define SDRAM_OPERATION_MODE 0x474 +#define SDRAM_ADDRESS_DECODE 0x47C +#define SDRAM_TIMING_PARAMETERS 0x4b4 +#define SDRAM_UMA_CONTROL 0x4a4 +#define SDRAM_CROSS_BAR_CONTROL_LOW 0x4a8 +#define SDRAM_CROSS_BAR_CONTROL_HIGH 0x4ac +#define SDRAM_CROSS_BAR_TIMEOUT 0x4b0 + + +/****************************************/ +/* SDRAM Parameters */ +/****************************************/ + +#define SDRAM_BANK0PARAMETERS 0x44C +#define SDRAM_BANK1PARAMETERS 0x450 +#define SDRAM_BANK2PARAMETERS 0x454 +#define SDRAM_BANK3PARAMETERS 0x458 + + +/****************************************/ +/* SDRAM Error Report */ +/****************************************/ + +#define SDRAM_ERROR_DATA_LOW 0x484 +#define SDRAM_ERROR_DATA_HIGH 0x480 +#define SDRAM_AND_DEVICE_ERROR_ADDRESS 0x490 +#define SDRAM_RECEIVED_ECC 0x488 +#define SDRAM_CALCULATED_ECC 0x48c +#define SDRAM_ECC_CONTROL 0x494 +#define SDRAM_ECC_ERROR_COUNTER 0x498 + + +/****************************************/ +/* SDunit Debug (for internal use) */ +/****************************************/ + +#define X0_ADDRESS 0x500 +#define X0_COMMAND_AND_ID 0x504 +#define X0_WRITE_DATA_LOW 0x508 +#define X0_WRITE_DATA_HIGH 0x50c +#define X0_WRITE_BYTE_ENABLE 0x518 +#define X0_READ_DATA_LOW 0x510 +#define X0_READ_DATA_HIGH 0x514 +#define X0_READ_ID 0x51c +#define X1_ADDRESS 0x520 +#define X1_COMMAND_AND_ID 0x524 +#define X1_WRITE_DATA_LOW 0x528 +#define X1_WRITE_DATA_HIGH 0x52c +#define X1_WRITE_BYTE_ENABLE 0x538 +#define X1_READ_DATA_LOW 0x530 +#define X1_READ_DATA_HIGH 0x534 +#define X1_READ_ID 0x53c +#define X0_SNOOP_ADDRESS 0x540 +#define X0_SNOOP_COMMAND 0x544 +#define X1_SNOOP_ADDRESS 0x548 +#define X1_SNOOP_COMMAND 0x54c + + +/****************************************/ +/* Device Parameters */ +/****************************************/ + +#define DEVICE_BANK0PARAMETERS 0x45c +#define DEVICE_BANK1PARAMETERS 0x460 +#define DEVICE_BANK2PARAMETERS 0x464 +#define DEVICE_BANK3PARAMETERS 0x468 +#define DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define DEVICE_CONTROL 0x4c0 +#define DEVICE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define DEVICE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define DEVICE_CROSS_BAR_TIMEOUT 0x4c4 + + +/****************************************/ +/* Device Interrupt */ +/****************************************/ + +#define DEVICE_INTERRUPT_CAUSE 0x4d0 +#define DEVICE_INTERRUPT_MASK 0x4d4 +#define DEVICE_ERROR_ADDRESS 0x4d8 + +/****************************************/ +/* DMA Record */ +/****************************************/ + +#define CHANNEL0_DMA_BYTE_COUNT 0x800 +#define CHANNEL1_DMA_BYTE_COUNT 0x804 +#define CHANNEL2_DMA_BYTE_COUNT 0x808 +#define CHANNEL3_DMA_BYTE_COUNT 0x80C +#define CHANNEL4_DMA_BYTE_COUNT 0x900 +#define CHANNEL5_DMA_BYTE_COUNT 0x904 +#define CHANNEL6_DMA_BYTE_COUNT 0x908 +#define CHANNEL7_DMA_BYTE_COUNT 0x90C +#define CHANNEL0_DMA_SOURCE_ADDRESS 0x810 +#define CHANNEL1_DMA_SOURCE_ADDRESS 0x814 +#define CHANNEL2_DMA_SOURCE_ADDRESS 0x818 +#define CHANNEL3_DMA_SOURCE_ADDRESS 0x81C +#define CHANNEL4_DMA_SOURCE_ADDRESS 0x910 +#define CHANNEL5_DMA_SOURCE_ADDRESS 0x914 +#define CHANNEL6_DMA_SOURCE_ADDRESS 0x918 +#define CHANNEL7_DMA_SOURCE_ADDRESS 0x91C +#define CHANNEL0_DMA_DESTINATION_ADDRESS 0x820 +#define CHANNEL1_DMA_DESTINATION_ADDRESS 0x824 +#define CHANNEL2_DMA_DESTINATION_ADDRESS 0x828 +#define CHANNEL3_DMA_DESTINATION_ADDRESS 0x82C +#define CHANNEL4_DMA_DESTINATION_ADDRESS 0x920 +#define CHANNEL5_DMA_DESTINATION_ADDRESS 0x924 +#define CHANNEL6_DMA_DESTINATION_ADDRESS 0x928 +#define CHANNEL7_DMA_DESTINATION_ADDRESS 0x92C +#define CHANNEL0NEXT_RECORD_POINTER 0x830 +#define CHANNEL1NEXT_RECORD_POINTER 0x834 +#define CHANNEL2NEXT_RECORD_POINTER 0x838 +#define CHANNEL3NEXT_RECORD_POINTER 0x83C +#define CHANNEL4NEXT_RECORD_POINTER 0x930 +#define CHANNEL5NEXT_RECORD_POINTER 0x934 +#define CHANNEL6NEXT_RECORD_POINTER 0x938 +#define CHANNEL7NEXT_RECORD_POINTER 0x93C +#define CHANNEL0CURRENT_DESCRIPTOR_POINTER 0x870 +#define CHANNEL1CURRENT_DESCRIPTOR_POINTER 0x874 +#define CHANNEL2CURRENT_DESCRIPTOR_POINTER 0x878 +#define CHANNEL3CURRENT_DESCRIPTOR_POINTER 0x87C +#define CHANNEL4CURRENT_DESCRIPTOR_POINTER 0x970 +#define CHANNEL5CURRENT_DESCRIPTOR_POINTER 0x974 +#define CHANNEL6CURRENT_DESCRIPTOR_POINTER 0x978 +#define CHANNEL7CURRENT_DESCRIPTOR_POINTER 0x97C +#define CHANNEL0_DMA_SOURCE_HIGH_PCI_ADDRESS 0x890 +#define CHANNEL1_DMA_SOURCE_HIGH_PCI_ADDRESS 0x894 +#define CHANNEL2_DMA_SOURCE_HIGH_PCI_ADDRESS 0x898 +#define CHANNEL3_DMA_SOURCE_HIGH_PCI_ADDRESS 0x89c +#define CHANNEL4_DMA_SOURCE_HIGH_PCI_ADDRESS 0x990 +#define CHANNEL5_DMA_SOURCE_HIGH_PCI_ADDRESS 0x994 +#define CHANNEL6_DMA_SOURCE_HIGH_PCI_ADDRESS 0x998 +#define CHANNEL7_DMA_SOURCE_HIGH_PCI_ADDRESS 0x99c +#define CHANNEL0_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a0 +#define CHANNEL1_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a4 +#define CHANNEL2_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8a8 +#define CHANNEL3_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x8ac +#define CHANNEL4_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a0 +#define CHANNEL5_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a4 +#define CHANNEL6_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9a8 +#define CHANNEL7_DMA_DESTINATION_HIGH_PCI_ADDRESS 0x9ac +#define CHANNEL0_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b0 +#define CHANNEL1_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b4 +#define CHANNEL2_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8b8 +#define CHANNEL3_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x8bc +#define CHANNEL4_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b0 +#define CHANNEL5_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b4 +#define CHANNEL6_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9b8 +#define CHANNEL7_DMA_NEXT_RECORD_POINTER_HIGH_PCI_ADDRESS 0x9bc + +/****************************************/ +/* DMA Channel Control */ +/****************************************/ + +#define CHANNEL0CONTROL 0x840 +#define CHANNEL0CONTROL_HIGH 0x880 + +#define CHANNEL1CONTROL 0x844 +#define CHANNEL1CONTROL_HIGH 0x884 + +#define CHANNEL2CONTROL 0x848 +#define CHANNEL2CONTROL_HIGH 0x888 + +#define CHANNEL3CONTROL 0x84C +#define CHANNEL3CONTROL_HIGH 0x88C + +#define CHANNEL4CONTROL 0x940 +#define CHANNEL4CONTROL_HIGH 0x980 + +#define CHANNEL5CONTROL 0x944 +#define CHANNEL5CONTROL_HIGH 0x984 + +#define CHANNEL6CONTROL 0x948 +#define CHANNEL6CONTROL_HIGH 0x988 + +#define CHANNEL7CONTROL 0x94C +#define CHANNEL7CONTROL_HIGH 0x98C + + +/****************************************/ +/* DMA Arbiter */ +/****************************************/ + +#define ARBITER_CONTROL_0_3 0x860 +#define ARBITER_CONTROL_4_7 0x960 + + +/****************************************/ +/* DMA Interrupt */ +/****************************************/ + +#define CHANELS0_3_INTERRUPT_CAUSE 0x8c0 +#define CHANELS0_3_INTERRUPT_MASK 0x8c4 +#define CHANELS0_3_ERROR_ADDRESS 0x8c8 +#define CHANELS0_3_ERROR_SELECT 0x8cc +#define CHANELS4_7_INTERRUPT_CAUSE 0x9c0 +#define CHANELS4_7_INTERRUPT_MASK 0x9c4 +#define CHANELS4_7_ERROR_ADDRESS 0x9c8 +#define CHANELS4_7_ERROR_SELECT 0x9cc + + +/****************************************/ +/* DMA Debug (for internal use) */ +/****************************************/ + +#define DMA_X0_ADDRESS 0x8e0 +#define DMA_X0_COMMAND_AND_ID 0x8e4 +#define DMA_X0_WRITE_DATA_LOW 0x8e8 +#define DMA_X0_WRITE_DATA_HIGH 0x8ec +#define DMA_X0_WRITE_BYTE_ENABLE 0x8f8 +#define DMA_X0_READ_DATA_LOW 0x8f0 +#define DMA_X0_READ_DATA_HIGH 0x8f4 +#define DMA_X0_READ_ID 0x8fc +#define DMA_X1_ADDRESS 0x9e0 +#define DMA_X1_COMMAND_AND_ID 0x9e4 +#define DMA_X1_WRITE_DATA_LOW 0x9e8 +#define DMA_X1_WRITE_DATA_HIGH 0x9ec +#define DMA_X1_WRITE_BYTE_ENABLE 0x9f8 +#define DMA_X1_READ_DATA_LOW 0x9f0 +#define DMA_X1_READ_DATA_HIGH 0x9f4 +#define DMA_X1_READ_ID 0x9fc + +/****************************************/ +/* Timer_Counter */ +/****************************************/ + +#define TIMER_COUNTER0 0x850 +#define TIMER_COUNTER1 0x854 +#define TIMER_COUNTER2 0x858 +#define TIMER_COUNTER3 0x85C +#define TIMER_COUNTER_0_3_CONTROL 0x864 +#define TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c +#define TIMER_COUNTER4 0x950 +#define TIMER_COUNTER5 0x954 +#define TIMER_COUNTER6 0x958 +#define TIMER_COUNTER7 0x95C +#define TIMER_COUNTER_4_7_CONTROL 0x964 +#define TIMER_COUNTER_4_7_INTERRUPT_CAUSE 0x968 +#define TIMER_COUNTER_4_7_INTERRUPT_MASK 0x96c + +/****************************************/ +/* PCI Slave Address Decoding */ +/****************************************/ + +#define PCI_0SCS_0_BANK_SIZE 0xc08 +#define PCI_1SCS_0_BANK_SIZE 0xc88 +#define PCI_0SCS_1_BANK_SIZE 0xd08 +#define PCI_1SCS_1_BANK_SIZE 0xd88 +#define PCI_0SCS_2_BANK_SIZE 0xc0c +#define PCI_1SCS_2_BANK_SIZE 0xc8c +#define PCI_0SCS_3_BANK_SIZE 0xd0c +#define PCI_1SCS_3_BANK_SIZE 0xd8c +#define PCI_0CS_0_BANK_SIZE 0xc10 +#define PCI_1CS_0_BANK_SIZE 0xc90 +#define PCI_0CS_1_BANK_SIZE 0xd10 +#define PCI_1CS_1_BANK_SIZE 0xd90 +#define PCI_0CS_2_BANK_SIZE 0xd18 +#define PCI_1CS_2_BANK_SIZE 0xd98 +#define PCI_0CS_3_BANK_SIZE 0xc14 +#define PCI_1CS_3_BANK_SIZE 0xc94 +#define PCI_0CS_BOOT_BANK_SIZE 0xd14 +#define PCI_1CS_BOOT_BANK_SIZE 0xd94 +#define PCI_0P2P_MEM0_BAR_SIZE 0xd1c +#define PCI_1P2P_MEM0_BAR_SIZE 0xd9c +#define PCI_0P2P_MEM1_BAR_SIZE 0xd20 +#define PCI_1P2P_MEM1_BAR_SIZE 0xda0 +#define PCI_0P2P_I_O_BAR_SIZE 0xd24 +#define PCI_1P2P_I_O_BAR_SIZE 0xda4 +#define PCI_0CPU_BAR_SIZE 0xd28 +#define PCI_1CPU_BAR_SIZE 0xda8 +#define PCI_0DAC_SCS_0_BANK_SIZE 0xe00 +#define PCI_1DAC_SCS_0_BANK_SIZE 0xe80 +#define PCI_0DAC_SCS_1_BANK_SIZE 0xe04 +#define PCI_1DAC_SCS_1_BANK_SIZE 0xe84 +#define PCI_0DAC_SCS_2_BANK_SIZE 0xe08 +#define PCI_1DAC_SCS_2_BANK_SIZE 0xe88 +#define PCI_0DAC_SCS_3_BANK_SIZE 0xe0c +#define PCI_1DAC_SCS_3_BANK_SIZE 0xe8c +#define PCI_0DAC_CS_0_BANK_SIZE 0xe10 +#define PCI_1DAC_CS_0_BANK_SIZE 0xe90 +#define PCI_0DAC_CS_1_BANK_SIZE 0xe14 +#define PCI_1DAC_CS_1_BANK_SIZE 0xe94 +#define PCI_0DAC_CS_2_BANK_SIZE 0xe18 +#define PCI_1DAC_CS_2_BANK_SIZE 0xe98 +#define PCI_0DAC_CS_3_BANK_SIZE 0xe1c +#define PCI_1DAC_CS_3_BANK_SIZE 0xe9c +#define PCI_0DAC_BOOTCS_BANK_SIZE 0xe20 +#define PCI_1DAC_BOOTCS_BANK_SIZE 0xea0 +#define PCI_0DAC_P2P_MEM0_BAR_SIZE 0xe24 +#define PCI_1DAC_P2P_MEM0_BAR_SIZE 0xea4 +#define PCI_0DAC_P2P_MEM1_BAR_SIZE 0xe28 +#define PCI_1DAC_P2P_MEM1_BAR_SIZE 0xea8 +#define PCI_0DAC_CPU_BAR_SIZE 0xe2c +#define PCI_1DAC_CPU_BAR_SIZE 0xeac +#define PCI_0EXPANSION_ROM_BAR_SIZE 0xd2c +#define PCI_1EXPANSION_ROM_BAR_SIZE 0xdac +#define PCI_0BASE_ADDRESS_REGISTERS_ENABLE 0xc3c +#define PCI_1BASE_ADDRESS_REGISTERS_ENABLE 0xcbc +#define PCI_0SCS_0_BASE_ADDRESS_REMAP 0xc48 +#define PCI_1SCS_0_BASE_ADDRESS_REMAP 0xcc8 +#define PCI_0SCS_1_BASE_ADDRESS_REMAP 0xd48 +#define PCI_1SCS_1_BASE_ADDRESS_REMAP 0xdc8 +#define PCI_0SCS_2_BASE_ADDRESS_REMAP 0xc4c +#define PCI_1SCS_2_BASE_ADDRESS_REMAP 0xccc +#define PCI_0SCS_3_BASE_ADDRESS_REMAP 0xd4c +#define PCI_1SCS_3_BASE_ADDRESS_REMAP 0xdcc +#define PCI_0CS_0_BASE_ADDRESS_REMAP 0xc50 +#define PCI_1CS_0_BASE_ADDRESS_REMAP 0xcd0 +#define PCI_0CS_1_BASE_ADDRESS_REMAP 0xd50 +#define PCI_1CS_1_BASE_ADDRESS_REMAP 0xdd0 +#define PCI_0CS_2_BASE_ADDRESS_REMAP 0xd58 +#define PCI_1CS_2_BASE_ADDRESS_REMAP 0xdd8 +#define PCI_0CS_3_BASE_ADDRESS_REMAP 0xc54 +#define PCI_1CS_3_BASE_ADDRESS_REMAP 0xcd4 +#define PCI_0CS_BOOTCS_BASE_ADDRESS_REMAP 0xd54 +#define PCI_1CS_BOOTCS_BASE_ADDRESS_REMAP 0xdd4 +#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xd5c +#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xddc +#define PCI_0P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xd60 +#define PCI_1P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xde0 +#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xd64 +#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xde4 +#define PCI_0P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xd68 +#define PCI_1P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xde8 +#define PCI_0P2P_I_O_BASE_ADDRESS_REMAP 0xd6c +#define PCI_1P2P_I_O_BASE_ADDRESS_REMAP 0xdec +#define PCI_0CPU_BASE_ADDRESS_REMAP 0xd70 +#define PCI_1CPU_BASE_ADDRESS_REMAP 0xdf0 +#define PCI_0DAC_SCS_0_BASE_ADDRESS_REMAP 0xf00 +#define PCI_1DAC_SCS_0_BASE_ADDRESS_REMAP 0xff0 +#define PCI_0DAC_SCS_1_BASE_ADDRESS_REMAP 0xf04 +#define PCI_1DAC_SCS_1_BASE_ADDRESS_REMAP 0xf84 +#define PCI_0DAC_SCS_2_BASE_ADDRESS_REMAP 0xf08 +#define PCI_1DAC_SCS_2_BASE_ADDRESS_REMAP 0xf88 +#define PCI_0DAC_SCS_3_BASE_ADDRESS_REMAP 0xf0c +#define PCI_1DAC_SCS_3_BASE_ADDRESS_REMAP 0xf8c +#define PCI_0DAC_CS_0_BASE_ADDRESS_REMAP 0xf10 +#define PCI_1DAC_CS_0_BASE_ADDRESS_REMAP 0xf90 +#define PCI_0DAC_CS_1_BASE_ADDRESS_REMAP 0xf14 +#define PCI_1DAC_CS_1_BASE_ADDRESS_REMAP 0xf94 +#define PCI_0DAC_CS_2_BASE_ADDRESS_REMAP 0xf18 +#define PCI_1DAC_CS_2_BASE_ADDRESS_REMAP 0xf98 +#define PCI_0DAC_CS_3_BASE_ADDRESS_REMAP 0xf1c +#define PCI_1DAC_CS_3_BASE_ADDRESS_REMAP 0xf9c +#define PCI_0DAC_BOOTCS_BASE_ADDRESS_REMAP 0xf20 +#define PCI_1DAC_BOOTCS_BASE_ADDRESS_REMAP 0xfa0 +#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xf24 +#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_LOW 0xfa4 +#define PCI_0DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xf28 +#define PCI_1DAC_P2P_MEM0_BASE_ADDRESS_REMAP_HIGH 0xfa8 +#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xf2c +#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_LOW 0xfac +#define PCI_0DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xf30 +#define PCI_1DAC_P2P_MEM1_BASE_ADDRESS_REMAP_HIGH 0xfb0 +#define PCI_0DAC_CPU_BASE_ADDRESS_REMAP 0xf34 +#define PCI_1DAC_CPU_BASE_ADDRESS_REMAP 0xfb4 +#define PCI_0EXPANSION_ROM_BASE_ADDRESS_REMAP 0xf38 +#define PCI_1EXPANSION_ROM_BASE_ADDRESS_REMAP 0xfb8 +#define PCI_0ADDRESS_DECODE_CONTROL 0xd3c +#define PCI_1ADDRESS_DECODE_CONTROL 0xdbc + +/****************************************/ +/* PCI Control */ +/****************************************/ + +#define PCI_0COMMAND 0xc00 +#define PCI_1COMMAND 0xc80 +#define PCI_0MODE 0xd00 +#define PCI_1MODE 0xd80 +#define PCI_0TIMEOUT_RETRY 0xc04 +#define PCI_1TIMEOUT_RETRY 0xc84 +#define PCI_0READ_BUFFER_DISCARD_TIMER 0xd04 +#define PCI_1READ_BUFFER_DISCARD_TIMER 0xd84 +#define MSI_0TRIGGER_TIMER 0xc38 +#define MSI_1TRIGGER_TIMER 0xcb8 +#define PCI_0ARBITER_CONTROL 0x1d00 +#define PCI_1ARBITER_CONTROL 0x1d80 +/* changing untill here */ +#define PCI_0CROSS_BAR_CONTROL_LOW 0x1d08 +#define PCI_0CROSS_BAR_CONTROL_HIGH 0x1d0c +#define PCI_0CROSS_BAR_TIMEOUT 0x1d04 +#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d18 +#define PCI_0READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d1c +#define PCI_0SYNC_BARRIER_VIRTUAL_REGISTER 0x1d10 +#define PCI_0P2P_CONFIGURATION 0x1d14 +#define PCI_0ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define PCI_0ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define PCI_0ACCESS_CONTROL_TOP_0 0x1e08 +#define PCI_0ACCESS_CONTROL_BASE_1_LOW 0c1e10 +#define PCI_0ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define PCI_0ACCESS_CONTROL_TOP_1 0x1e18 +#define PCI_0ACCESS_CONTROL_BASE_2_LOW 0c1e20 +#define PCI_0ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define PCI_0ACCESS_CONTROL_TOP_2 0x1e28 +#define PCI_0ACCESS_CONTROL_BASE_3_LOW 0c1e30 +#define PCI_0ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define PCI_0ACCESS_CONTROL_TOP_3 0x1e38 +#define PCI_0ACCESS_CONTROL_BASE_4_LOW 0c1e40 +#define PCI_0ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define PCI_0ACCESS_CONTROL_TOP_4 0x1e48 +#define PCI_0ACCESS_CONTROL_BASE_5_LOW 0c1e50 +#define PCI_0ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define PCI_0ACCESS_CONTROL_TOP_5 0x1e58 +#define PCI_0ACCESS_CONTROL_BASE_6_LOW 0c1e60 +#define PCI_0ACCESS_CONTROL_BASE_6_HIGH 0x1e64 +#define PCI_0ACCESS_CONTROL_TOP_6 0x1e68 +#define PCI_0ACCESS_CONTROL_BASE_7_LOW 0c1e70 +#define PCI_0ACCESS_CONTROL_BASE_7_HIGH 0x1e74 +#define PCI_0ACCESS_CONTROL_TOP_7 0x1e78 +#define PCI_1CROSS_BAR_CONTROL_LOW 0x1d88 +#define PCI_1CROSS_BAR_CONTROL_HIGH 0x1d8c +#define PCI_1CROSS_BAR_TIMEOUT 0x1d84 +#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_LOW 0x1d98 +#define PCI_1READ_RESPONSE_CROSS_BAR_CONTROL_HIGH 0x1d9c +#define PCI_1SYNC_BARRIER_VIRTUAL_REGISTER 0x1d90 +#define PCI_1P2P_CONFIGURATION 0x1d94 +#define PCI_1ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define PCI_1ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define PCI_1ACCESS_CONTROL_TOP_0 0x1e88 +#define PCI_1ACCESS_CONTROL_BASE_1_LOW 0c1e90 +#define PCI_1ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define PCI_1ACCESS_CONTROL_TOP_1 0x1e98 +#define PCI_1ACCESS_CONTROL_BASE_2_LOW 0c1ea0 +#define PCI_1ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define PCI_1ACCESS_CONTROL_TOP_2 0x1ea8 +#define PCI_1ACCESS_CONTROL_BASE_3_LOW 0c1eb0 +#define PCI_1ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define PCI_1ACCESS_CONTROL_TOP_3 0x1eb8 +#define PCI_1ACCESS_CONTROL_BASE_4_LOW 0c1ec0 +#define PCI_1ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define PCI_1ACCESS_CONTROL_TOP_4 0x1ec8 +#define PCI_1ACCESS_CONTROL_BASE_5_LOW 0c1ed0 +#define PCI_1ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define PCI_1ACCESS_CONTROL_TOP_5 0x1ed8 +#define PCI_1ACCESS_CONTROL_BASE_6_LOW 0c1ee0 +#define PCI_1ACCESS_CONTROL_BASE_6_HIGH 0x1ee4 +#define PCI_1ACCESS_CONTROL_TOP_6 0x1ee8 +#define PCI_1ACCESS_CONTROL_BASE_7_LOW 0c1ef0 +#define PCI_1ACCESS_CONTROL_BASE_7_HIGH 0x1ef4 +#define PCI_1ACCESS_CONTROL_TOP_7 0x1ef8 + +/****************************************/ +/* PCI Snoop Control */ +/****************************************/ + +#define PCI_0SNOOP_CONTROL_BASE_0_LOW 0x1f00 +#define PCI_0SNOOP_CONTROL_BASE_0_HIGH 0x1f04 +#define PCI_0SNOOP_CONTROL_TOP_0 0x1f08 +#define PCI_0SNOOP_CONTROL_BASE_1_0_LOW 0x1f10 +#define PCI_0SNOOP_CONTROL_BASE_1_0_HIGH 0x1f14 +#define PCI_0SNOOP_CONTROL_TOP_1 0x1f18 +#define PCI_0SNOOP_CONTROL_BASE_2_0_LOW 0x1f20 +#define PCI_0SNOOP_CONTROL_BASE_2_0_HIGH 0x1f24 +#define PCI_0SNOOP_CONTROL_TOP_2 0x1f28 +#define PCI_0SNOOP_CONTROL_BASE_3_0_LOW 0x1f30 +#define PCI_0SNOOP_CONTROL_BASE_3_0_HIGH 0x1f34 +#define PCI_0SNOOP_CONTROL_TOP_3 0x1f38 +#define PCI_1SNOOP_CONTROL_BASE_0_LOW 0x1f80 +#define PCI_1SNOOP_CONTROL_BASE_0_HIGH 0x1f84 +#define PCI_1SNOOP_CONTROL_TOP_0 0x1f88 +#define PCI_1SNOOP_CONTROL_BASE_1_0_LOW 0x1f90 +#define PCI_1SNOOP_CONTROL_BASE_1_0_HIGH 0x1f94 +#define PCI_1SNOOP_CONTROL_TOP_1 0x1f98 +#define PCI_1SNOOP_CONTROL_BASE_2_0_LOW 0x1fa0 +#define PCI_1SNOOP_CONTROL_BASE_2_0_HIGH 0x1fa4 +#define PCI_1SNOOP_CONTROL_TOP_2 0x1fa8 +#define PCI_1SNOOP_CONTROL_BASE_3_0_LOW 0x1fb0 +#define PCI_1SNOOP_CONTROL_BASE_3_0_HIGH 0x1fb4 +#define PCI_1SNOOP_CONTROL_TOP_3 0x1fb8 + +/****************************************/ +/* PCI Configuration Address */ +/****************************************/ + +#define PCI_0CONFIGURATION_ADDRESS 0xcf8 +#define PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER 0xcfc +#define PCI_1CONFIGURATION_ADDRESS 0xc78 +#define PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER 0xc7c +#define PCI_0INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xc34 +#define PCI_1INTERRUPT_ACKNOWLEDGE_VIRTUAL_REGISTER 0xcb4 + +/****************************************/ +/* PCI Error Report */ +/****************************************/ + +#define PCI_0SERR_MASK 0xc28 +#define PCI_0ERROR_ADDRESS_LOW 0x1d40 +#define PCI_0ERROR_ADDRESS_HIGH 0x1d44 +#define PCI_0ERROR_DATA_LOW 0x1d48 +#define PCI_0ERROR_DATA_HIGH 0x1d4c +#define PCI_0ERROR_COMMAND 0x1d50 +#define PCI_0ERROR_CAUSE 0x1d58 +#define PCI_0ERROR_MASK 0x1d5c + +#define PCI_1SERR_MASK 0xca8 +#define PCI_1ERROR_ADDRESS_LOW 0x1dc0 +#define PCI_1ERROR_ADDRESS_HIGH 0x1dc4 +#define PCI_1ERROR_DATA_LOW 0x1dc8 +#define PCI_1ERROR_DATA_HIGH 0x1dcc +#define PCI_1ERROR_COMMAND 0x1dd0 +#define PCI_1ERROR_CAUSE 0x1dd8 +#define PCI_1ERROR_MASK 0x1ddc + + +/****************************************/ +/* Lslave Debug (for internal use) */ +/****************************************/ + +#define L_SLAVE_X0_ADDRESS 0x1d20 +#define L_SLAVE_X0_COMMAND_AND_ID 0x1d24 +#define L_SLAVE_X1_ADDRESS 0x1d28 +#define L_SLAVE_X1_COMMAND_AND_ID 0x1d2c +#define L_SLAVE_WRITE_DATA_LOW 0x1d30 +#define L_SLAVE_WRITE_DATA_HIGH 0x1d34 +#define L_SLAVE_WRITE_BYTE_ENABLE 0x1d60 +#define L_SLAVE_READ_DATA_LOW 0x1d38 +#define L_SLAVE_READ_DATA_HIGH 0x1d3c +#define L_SLAVE_READ_ID 0x1d64 + +/****************************************/ +/* PCI Configuration Function 0 */ +/****************************************/ + +#define PCI_DEVICE_AND_VENDOR_ID 0x000 +#define PCI_STATUS_AND_COMMAND 0x004 +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C +#define PCI_SCS_0_BASE_ADDRESS 0x010 +#define PCI_SCS_1_BASE_ADDRESS 0x014 +#define PCI_SCS_2_BASE_ADDRESS 0x018 +#define PCI_SCS_3_BASE_ADDRESS 0x01C +#define PCI_INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS 0x020 +#define PCI_INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS 0x024 +#define PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02C +#define PCI_EXPANSION_ROM_BASE_ADDRESS_REGISTER 0x030 +#define PCI_CAPABILTY_LIST_POINTER 0x034 +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C +#define PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define PCI_VPD_ADDRESS 0x048 +#define PCI_VPD_DATA 0X04c +#define PCI_MSI_MESSAGE_CONTROL 0x050 +#define PCI_MSI_MESSAGE_ADDRESS 0x054 +#define PCI_MSI_MESSAGE_UPPER_ADDRESS 0x058 +#define PCI_MSI_MESSAGE_DATA 0x05c +#define PCI_COMPACT_PCI_HOT_SWAP_CAPABILITY 0x058 + +/****************************************/ +/* PCI Configuration Function 1 */ +/****************************************/ + +#define PCI_CS_0_BASE_ADDRESS 0x110 +#define PCI_CS_1_BASE_ADDRESS 0x114 +#define PCI_CS_2_BASE_ADDRESS 0x118 +#define PCI_CS_3_BASE_ADDRESS 0x11c +#define PCI_BOOTCS_BASE_ADDRESS 0x120 + +/****************************************/ +/* PCI Configuration Function 2 */ +/****************************************/ + +#define PCI_P2P_MEM0_BASE_ADDRESS 0x210 +#define PCI_P2P_MEM1_BASE_ADDRESS 0x214 +#define PCI_P2P_I_O_BASE_ADDRESS 0x218 +#define PCI_CPU_BASE_ADDRESS 0x21c + +/****************************************/ +/* PCI Configuration Function 4 */ +/****************************************/ + +#define PCI_DAC_SCS_0_BASE_ADDRESS_LOW 0x410 +#define PCI_DAC_SCS_0_BASE_ADDRESS_HIGH 0x414 +#define PCI_DAC_SCS_1_BASE_ADDRESS_LOW 0x418 +#define PCI_DAC_SCS_1_BASE_ADDRESS_HIGH 0x41c +#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_LOW 0x420 +#define PCI_DAC_P2P_MEM0_BASE_ADDRESS_HIGH 0x424 + + +/****************************************/ +/* PCI Configuration Function 5 */ +/****************************************/ + +#define PCI_DAC_SCS_2_BASE_ADDRESS_LOW 0x510 +#define PCI_DAC_SCS_2_BASE_ADDRESS_HIGH 0x514 +#define PCI_DAC_SCS_3_BASE_ADDRESS_LOW 0x518 +#define PCI_DAC_SCS_3_BASE_ADDRESS_HIGH 0x51c +#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_LOW 0x520 +#define PCI_DAC_P2P_MEM1_BASE_ADDRESS_HIGH 0x524 + + +/****************************************/ +/* PCI Configuration Function 6 */ +/****************************************/ + +#define PCI_DAC_CS_0_BASE_ADDRESS_LOW 0x610 +#define PCI_DAC_CS_0_BASE_ADDRESS_HIGH 0x614 +#define PCI_DAC_CS_1_BASE_ADDRESS_LOW 0x618 +#define PCI_DAC_CS_1_BASE_ADDRESS_HIGH 0x61c +#define PCI_DAC_CS_2_BASE_ADDRESS_LOW 0x620 +#define PCI_DAC_CS_2_BASE_ADDRESS_HIGH 0x624 + +/****************************************/ +/* PCI Configuration Function 7 */ +/****************************************/ + +#define PCI_DAC_CS_3_BASE_ADDRESS_LOW 0x710 +#define PCI_DAC_CS_3_BASE_ADDRESS_HIGH 0x714 +#define PCI_DAC_BOOTCS_BASE_ADDRESS_LOW 0x718 +#define PCI_DAC_BOOTCS_BASE_ADDRESS_HIGH 0x71c +#define PCI_DAC_CPU_BASE_ADDRESS_LOW 0x720 +#define PCI_DAC_CPU_BASE_ADDRESS_HIGH 0x724 + +/****************************************/ +/* Interrupts */ +/****************************************/ + +#define LOW_INTERRUPT_CAUSE_REGISTER 0xc18 +#define HIGH_INTERRUPT_CAUSE_REGISTER 0xc68 +#define CPU_INTERRUPT_MASK_REGISTER_LOW 0xc1c +#define CPU_INTERRUPT_MASK_REGISTER_HIGH 0xc6c +#define CPU_SELECT_CAUSE_REGISTER 0xc70 +#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xc24 +#define PCI_0INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xc64 +#define PCI_0SELECT_CAUSE 0xc74 +#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_LOW 0xca4 +#define PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH 0xce4 +#define PCI_1SELECT_CAUSE 0xcf4 +#define CPU_INT_0_MASK 0xe60 +#define CPU_INT_1_MASK 0xe64 +#define CPU_INT_2_MASK 0xe68 +#define CPU_INT_3_MASK 0xe6c + +/****************************************/ +/* I20 Support registers */ +/****************************************/ + +#define INBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x010 +#define INBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x014 +#define OUTBOUND_MESSAGE_REGISTER0_PCI0_SIDE 0x018 +#define OUTBOUND_MESSAGE_REGISTER1_PCI0_SIDE 0x01C +#define INBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x020 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x024 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x028 +#define OUTBOUND_DOORBELL_REGISTER_PCI0_SIDE 0x02C +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI0_SIDE 0x030 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI0_SIDE 0x034 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x040 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI0_SIDE 0x044 +#define QUEUE_CONTROL_REGISTER_PCI0_SIDE 0x050 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI0_SIDE 0x054 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x060 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x064 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x068 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x06C +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI0_SIDE 0x070 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI0_SIDE 0x074 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI0_SIDE 0x0F8 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI0_SIDE 0x0FC + +#define INBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x090 +#define INBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x094 +#define OUTBOUND_MESSAGE_REGISTER0_PCI1_SIDE 0x098 +#define OUTBOUND_MESSAGE_REGISTER1_PCI1_SIDE 0x09C +#define INBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0A0 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0A4 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0A8 +#define OUTBOUND_DOORBELL_REGISTER_PCI1_SIDE 0x0AC +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI1_SIDE 0x0B0 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI1_SIDE 0x0B4 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C0 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI1_SIDE 0x0C4 +#define QUEUE_CONTROL_REGISTER_PCI1_SIDE 0x0D0 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI1_SIDE 0x0D4 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E0 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0E4 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0E8 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0EC +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI1_SIDE 0x0F0 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI1_SIDE 0x0F4 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI1_SIDE 0x078 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI1_SIDE 0x07C + +#define INBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C10 +#define INBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C14 +#define OUTBOUND_MESSAGE_REGISTER0_CPU0_SIDE 0X1C18 +#define OUTBOUND_MESSAGE_REGISTER1_CPU0_SIDE 0X1C1C +#define INBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C20 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C24 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C28 +#define OUTBOUND_DOORBELL_REGISTER_CPU0_SIDE 0X1C2C +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU0_SIDE 0X1C30 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU0_SIDE 0X1C34 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C40 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU0_SIDE 0X1C44 +#define QUEUE_CONTROL_REGISTER_CPU0_SIDE 0X1C50 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU0_SIDE 0X1C54 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C60 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C64 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C68 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C6C +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1C70 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1C74 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU0_SIDE 0X1CF8 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU0_SIDE 0X1CFC + +#define INBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C90 +#define INBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C94 +#define OUTBOUND_MESSAGE_REGISTER0_CPU1_SIDE 0X1C98 +#define OUTBOUND_MESSAGE_REGISTER1_CPU1_SIDE 0X1C9C +#define INBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CA0 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CA4 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CA8 +#define OUTBOUND_DOORBELL_REGISTER_CPU1_SIDE 0X1CAC +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU1_SIDE 0X1CB0 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU1_SIDE 0X1CB4 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC0 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU1_SIDE 0X1CC4 +#define QUEUE_CONTROL_REGISTER_CPU1_SIDE 0X1CD0 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU1_SIDE 0X1CD4 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE0 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CE4 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CE8 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CEC +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1CF0 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1CF4 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU1_SIDE 0X1C78 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU1_SIDE 0X1C7C + +/****************************************/ +/* Communication Unit Registers */ +/****************************************/ + +#define ETHERNET_0_ADDRESS_CONTROL_LOW +#define ETHERNET_0_ADDRESS_CONTROL_HIGH 0xf204 +#define ETHERNET_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf208 +#define ETHERNET_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf20c +#define ETHERNET_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf210 +#define ETHERNET_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf214 +#define ETHERNET_0_HASH_TABLE_PCI_HIGH_ADDRESS 0xf218 +#define ETHERNET_1_ADDRESS_CONTROL_LOW 0xf220 +#define ETHERNET_1_ADDRESS_CONTROL_HIGH 0xf224 +#define ETHERNET_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf228 +#define ETHERNET_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf22c +#define ETHERNET_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf230 +#define ETHERNET_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf234 +#define ETHERNET_1_HASH_TABLE_PCI_HIGH_ADDRESS 0xf238 +#define ETHERNET_2_ADDRESS_CONTROL_LOW 0xf240 +#define ETHERNET_2_ADDRESS_CONTROL_HIGH 0xf244 +#define ETHERNET_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf248 +#define ETHERNET_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf24c +#define ETHERNET_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf250 +#define ETHERNET_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf254 +#define ETHERNET_2_HASH_TABLE_PCI_HIGH_ADDRESS 0xf258 +#define MPSC_0_ADDRESS_CONTROL_LOW 0xf280 +#define MPSC_0_ADDRESS_CONTROL_HIGH 0xf284 +#define MPSC_0_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf288 +#define MPSC_0_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf28c +#define MPSC_0_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf290 +#define MPSC_0_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf294 +#define MPSC_1_ADDRESS_CONTROL_LOW 0xf2a0 +#define MPSC_1_ADDRESS_CONTROL_HIGH 0xf2a4 +#define MPSC_1_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2a8 +#define MPSC_1_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2ac +#define MPSC_1_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b0 +#define MPSC_1_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2b4 +#define MPSC_2_ADDRESS_CONTROL_LOW 0xf2c0 +#define MPSC_2_ADDRESS_CONTROL_HIGH 0xf2c4 +#define MPSC_2_RECEIVE_BUFFER_PCI_HIGH_ADDRESS 0xf2c8 +#define MPSC_2_TRANSMIT_BUFFER_PCI_HIGH_ADDRESS 0xf2cc +#define MPSC_2_RECEIVE_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d0 +#define MPSC_2_TRANSMIT_DESCRIPTOR_PCI_HIGH_ADDRESS 0xf2d4 +#define SERIAL_INIT_PCI_HIGH_ADDRESS 0xf320 +#define SERIAL_INIT_LAST_DATA 0xf324 +#define SERIAL_INIT_STATUS_AND_CONTROL 0xf328 +#define COMM_UNIT_ARBITER_CONTROL 0xf300 +#define COMM_UNIT_CROSS_BAR_TIMEOUT 0xf304 +#define COMM_UNIT_INTERRUPT_CAUSE 0xf310 +#define COMM_UNIT_INTERRUPT_MASK 0xf314 +#define COMM_UNIT_ERROR_ADDRESS 0xf314 + +/****************************************/ +/* Cunit Debug (for internal use) */ +/****************************************/ + +#define CUNIT_ADDRESS 0xf340 +#define CUNIT_COMMAND_AND_ID 0xf344 +#define CUNIT_WRITE_DATA_LOW 0xf348 +#define CUNIT_WRITE_DATA_HIGH 0xf34c +#define CUNIT_WRITE_BYTE_ENABLE 0xf358 +#define CUNIT_READ_DATA_LOW 0xf350 +#define CUNIT_READ_DATA_HIGH 0xf354 +#define CUNIT_READ_ID 0xf35c + +/****************************************/ +/* Fast Ethernet Unit Registers */ +/****************************************/ + +/* Ethernet */ + +#define ETHERNET_PHY_ADDRESS_REGISTER 0x2000 +#define ETHERNET_SMI_REGISTER 0x2010 + +/* Ethernet 0 */ + +#define ETHERNET0_PORT_CONFIGURATION_REGISTER 0x2400 +#define ETHERNET0_PORT_CONFIGURATION_EXTEND_REGISTER 0x2408 +#define ETHERNET0_PORT_COMMAND_REGISTER 0x2410 +#define ETHERNET0_PORT_STATUS_REGISTER 0x2418 +#define ETHERNET0_SERIAL_PARAMETRS_REGISTER 0x2420 +#define ETHERNET0_HASH_TABLE_POINTER_REGISTER 0x2428 +#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2430 +#define ETHERNET0_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2438 +#define ETHERNET0_SDMA_CONFIGURATION_REGISTER 0x2440 +#define ETHERNET0_SDMA_COMMAND_REGISTER 0x2448 +#define ETHERNET0_INTERRUPT_CAUSE_REGISTER 0x2450 +#define ETHERNET0_INTERRUPT_MASK_REGISTER 0x2458 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER0 0x2480 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER1 0x2484 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER2 0x2488 +#define ETHERNET0_FIRST_RX_DESCRIPTOR_POINTER3 0x248c +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER0 0x24a0 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER1 0x24a4 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER2 0x24a8 +#define ETHERNET0_CURRENT_RX_DESCRIPTOR_POINTER3 0x24ac +#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER0 0x24e0 +#define ETHERNET0_CURRENT_TX_DESCRIPTOR_POINTER1 0x24e4 +#define ETHERNET0_MIB_COUNTER_BASE 0x2500 + +/* Ethernet 1 */ + +#define ETHERNET1_PORT_CONFIGURATION_REGISTER 0x2800 +#define ETHERNET1_PORT_CONFIGURATION_EXTEND_REGISTER 0x2808 +#define ETHERNET1_PORT_COMMAND_REGISTER 0x2810 +#define ETHERNET1_PORT_STATUS_REGISTER 0x2818 +#define ETHERNET1_SERIAL_PARAMETRS_REGISTER 0x2820 +#define ETHERNET1_HASH_TABLE_POINTER_REGISTER 0x2828 +#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2830 +#define ETHERNET1_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2838 +#define ETHERNET1_SDMA_CONFIGURATION_REGISTER 0x2840 +#define ETHERNET1_SDMA_COMMAND_REGISTER 0x2848 +#define ETHERNET1_INTERRUPT_CAUSE_REGISTER 0x2850 +#define ETHERNET1_INTERRUPT_MASK_REGISTER 0x2858 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER0 0x2880 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER1 0x2884 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER2 0x2888 +#define ETHERNET1_FIRST_RX_DESCRIPTOR_POINTER3 0x288c +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER0 0x28a0 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER1 0x28a4 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER2 0x28a8 +#define ETHERNET1_CURRENT_RX_DESCRIPTOR_POINTER3 0x28ac +#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER0 0x28e0 +#define ETHERNET1_CURRENT_TX_DESCRIPTOR_POINTER1 0x28e4 +#define ETHERNET1_MIB_COUNTER_BASE 0x2900 + +/* Ethernet 2 */ + +#define ETHERNET2_PORT_CONFIGURATION_REGISTER 0x2c00 +#define ETHERNET2_PORT_CONFIGURATION_EXTEND_REGISTER 0x2c08 +#define ETHERNET2_PORT_COMMAND_REGISTER 0x2c10 +#define ETHERNET2_PORT_STATUS_REGISTER 0x2c18 +#define ETHERNET2_SERIAL_PARAMETRS_REGISTER 0x2c20 +#define ETHERNET2_HASH_TABLE_POINTER_REGISTER 0x2c28 +#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_LOW 0x2c30 +#define ETHERNET2_FLOW_CONTROL_SOURCE_ADDRESS_HIGH 0x2c38 +#define ETHERNET2_SDMA_CONFIGURATION_REGISTER 0x2c40 +#define ETHERNET2_SDMA_COMMAND_REGISTER 0x2c48 +#define ETHERNET2_INTERRUPT_CAUSE_REGISTER 0x2c50 +#define ETHERNET2_INTERRUPT_MASK_REGISTER 0x2c58 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER0 0x2c80 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER1 0x2c84 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER2 0x2c88 +#define ETHERNET2_FIRST_RX_DESCRIPTOR_POINTER3 0x2c8c +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER0 0x2ca0 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER1 0x2ca4 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER2 0x2ca8 +#define ETHERNET2_CURRENT_RX_DESCRIPTOR_POINTER3 0x2cac +#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER0 0x2ce0 +#define ETHERNET2_CURRENT_TX_DESCRIPTOR_POINTER1 0x2ce4 +#define ETHERNET2_MIB_COUNTER_BASE 0x2d00 + +/****************************************/ +/* SDMA Registers */ +/****************************************/ + +#define SDMA_GROUP_CONFIGURATION_REGISTER 0xb1f0 +#define CHANNEL0_CONFIGURATION_REGISTER 0x4000 +#define CHANNEL0_COMMAND_REGISTER 0x4008 +#define CHANNEL0_RX_CMD_STATUS 0x4800 +#define CHANNEL0_RX_PACKET_AND_BUFFER_SIZES 0x4804 +#define CHANNEL0_RX_BUFFER_POINTER 0x4808 +#define CHANNEL0_RX_NEXT_POINTER 0x480c +#define CHANNEL0_CURRENT_RX_DESCRIPTOR_POINTER 0x4810 +#define CHANNEL0_TX_CMD_STATUS 0x4C00 +#define CHANNEL0_TX_PACKET_SIZE 0x4C04 +#define CHANNEL0_TX_BUFFER_POINTER 0x4C08 +#define CHANNEL0_TX_NEXT_POINTER 0x4C0c +#define CHANNEL0_CURRENT_TX_DESCRIPTOR_POINTER 0x4c10 +#define CHANNEL0_FIRST_TX_DESCRIPTOR_POINTER 0x4c14 +#define CHANNEL1_CONFIGURATION_REGISTER 0x6000 +#define CHANNEL1_COMMAND_REGISTER 0x6008 +#define CHANNEL1_RX_CMD_STATUS 0x6800 +#define CHANNEL1_RX_PACKET_AND_BUFFER_SIZES 0x6804 +#define CHANNEL1_RX_BUFFER_POINTER 0x6808 +#define CHANNEL1_RX_NEXT_POINTER 0x680c +#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 +#define CHANNEL1_TX_CMD_STATUS 0x6C00 +#define CHANNEL1_TX_PACKET_SIZE 0x6C04 +#define CHANNEL1_TX_BUFFER_POINTER 0x6C08 +#define CHANNEL1_TX_NEXT_POINTER 0x6C0c +#define CHANNEL1_CURRENT_RX_DESCRIPTOR_POINTER 0x6810 +#define CHANNEL1_CURRENT_TX_DESCRIPTOR_POINTER 0x6c10 +#define CHANNEL1_FIRST_TX_DESCRIPTOR_POINTER 0x6c14 + +/* SDMA Interrupt */ + +#define SDMA_CAUSE 0xb820 +#define SDMA_MASK 0xb8a0 + + +/****************************************/ +/* Baude Rate Generators Registers */ +/****************************************/ + +/* BRG 0 */ + +#define BRG0_CONFIGURATION_REGISTER 0xb200 +#define BRG0_BAUDE_TUNING_REGISTER 0xb204 + +/* BRG 1 */ + +#define BRG1_CONFIGURATION_REGISTER 0xb208 +#define BRG1_BAUDE_TUNING_REGISTER 0xb20c + +/* BRG 2 */ + +#define BRG2_CONFIGURATION_REGISTER 0xb210 +#define BRG2_BAUDE_TUNING_REGISTER 0xb214 + +/* BRG Interrupts */ + +#define BRG_CAUSE_REGISTER 0xb834 +#define BRG_MASK_REGISTER 0xb8b4 + +/* MISC */ + +#define MAIN_ROUTING_REGISTER 0xb400 +#define RECEIVE_CLOCK_ROUTING_REGISTER 0xb404 +#define TRANSMIT_CLOCK_ROUTING_REGISTER 0xb408 +#define COMM_UNIT_ARBITER_CONFIGURATION_REGISTER 0xb40c +#define WATCHDOG_CONFIGURATION_REGISTER 0xb410 +#define WATCHDOG_VALUE_REGISTER 0xb414 + + +/****************************************/ +/* Flex TDM Registers */ +/****************************************/ + +/* FTDM Port */ + +#define FLEXTDM_TRANSMIT_READ_POINTER 0xa800 +#define FLEXTDM_RECEIVE_READ_POINTER 0xa804 +#define FLEXTDM_CONFIGURATION_REGISTER 0xa808 +#define FLEXTDM_AUX_CHANNELA_TX_REGISTER 0xa80c +#define FLEXTDM_AUX_CHANNELA_RX_REGISTER 0xa810 +#define FLEXTDM_AUX_CHANNELB_TX_REGISTER 0xa814 +#define FLEXTDM_AUX_CHANNELB_RX_REGISTER 0xa818 + +/* FTDM Interrupts */ + +#define FTDM_CAUSE_REGISTER 0xb830 +#define FTDM_MASK_REGISTER 0xb8b0 + + +/****************************************/ +/* GPP Interface Registers */ +/****************************************/ + +#define GPP_IO_CONTROL 0xf100 +#define GPP_LEVEL_CONTROL 0xf110 +#define GPP_VALUE 0xf104 +#define GPP_INTERRUPT_CAUSE 0xf108 +#define GPP_INTERRUPT_MASK 0xf10c + +#define MPP_CONTROL0 0xf000 +#define MPP_CONTROL1 0xf004 +#define MPP_CONTROL2 0xf008 +#define MPP_CONTROL3 0xf00c +#define DEBUG_PORT_MULTIPLEX 0xf014 +#define SERIAL_PORT_MULTIPLEX 0xf010 + +/****************************************/ +/* I2C Registers */ +/****************************************/ + +#define I2C_SLAVE_ADDRESS 0xc000 +#define I2C_EXTENDED_SLAVE_ADDRESS 0xc040 +#define I2C_DATA 0xc004 +#define I2C_CONTROL 0xc008 +#define I2C_STATUS_BAUDE_RATE 0xc00C +#define I2C_SOFT_RESET 0xc01c + +/****************************************/ +/* MPSC Registers */ +/****************************************/ + +/* MPSC0 */ + +#define MPSC0_MAIN_CONFIGURATION_LOW 0x8000 +#define MPSC0_MAIN_CONFIGURATION_HIGH 0x8004 +#define MPSC0_PROTOCOL_CONFIGURATION 0x8008 +#define CHANNEL0_REGISTER1 0x800c +#define CHANNEL0_REGISTER2 0x8010 +#define CHANNEL0_REGISTER3 0x8014 +#define CHANNEL0_REGISTER4 0x8018 +#define CHANNEL0_REGISTER5 0x801c +#define CHANNEL0_REGISTER6 0x8020 +#define CHANNEL0_REGISTER7 0x8024 +#define CHANNEL0_REGISTER8 0x8028 +#define CHANNEL0_REGISTER9 0x802c +#define CHANNEL0_REGISTER10 0x8030 +#define CHANNEL0_REGISTER11 0x8034 + +/* MPSC1 */ + +#define MPSC1_MAIN_CONFIGURATION_LOW 0x9000 +#define MPSC1_MAIN_CONFIGURATION_HIGH 0x9004 +#define MPSC1_PROTOCOL_CONFIGURATION 0x9008 +#define CHANNEL1_REGISTER1 0x900c +#define CHANNEL1_REGISTER2 0x9010 +#define CHANNEL1_REGISTER3 0x9014 +#define CHANNEL1_REGISTER4 0x9018 +#define CHANNEL1_REGISTER5 0x901c +#define CHANNEL1_REGISTER6 0x9020 +#define CHANNEL1_REGISTER7 0x9024 +#define CHANNEL1_REGISTER8 0x9028 +#define CHANNEL1_REGISTER9 0x902c +#define CHANNEL1_REGISTER10 0x9030 +#define CHANNEL1_REGISTER11 0x9034 + +/* MPSCs Interupts */ + +#define MPSC0_CAUSE 0xb804 +#define MPSC0_MASK 0xb884 +#define MPSC1_CAUSE 0xb80c +#define MPSC1_MASK 0xb88c + +#endif /* __INCgt64240rh */ diff -Nru a/arch/mips/momentum/ocelot_g/gt64240_dep.h b/arch/mips/momentum/ocelot_g/gt64240_dep.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/gt64240_dep.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,57 @@ +/*********************************************************************** + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/gt64240/gt64240-dep.h + * Board-dependent definitions for GT-64120 chip. + * + * 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 _ASM_GT64240_DEP_H +#define _ASM_GT64240_DEP_H + +#include <asm/addrspace.h> /* for KSEG1ADDR() */ +#include <asm/byteorder.h> /* for cpu_to_le32() */ + +/* + * PCI address allocation + */ +#if 0 +#define GT_PCI_MEM_BASE (0x22000000) +#define GT_PCI_MEM_SIZE GT_DEF_PCI0_MEM0_SIZE +#define GT_PCI_IO_BASE (0x20000000) +#define GT_PCI_IO_SIZE GT_DEF_PCI0_IO_SIZE +#endif + +extern unsigned long gt64240_base; + +#define GT64240_BASE (gt64240_base) + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ + +#define GT_WRITE(ofs, data) \ + *(volatile u32 *)(GT64240_BASE+(ofs)) = cpu_to_le32(data) +#define GT_READ(ofs, data) \ + *(data) = le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) +#define GT_READ_DATA(ofs) \ + le32_to_cpu(*(volatile u32 *)(GT64240_BASE+(ofs))) + +#define GT_WRITE_16(ofs, data) \ + *(volatile u16 *)(GT64240_BASE+(ofs)) = cpu_to_le16(data) +#define GT_READ_16(ofs, data) \ + *(data) = le16_to_cpu(*(volatile u16 *)(GT64240_BASE+(ofs))) + +#define GT_WRITE_8(ofs, data) \ + *(volatile u8 *)(GT64240_BASE+(ofs)) = data +#define GT_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(GT64240_BASE+(ofs)) + +#endif /* _ASM_GT64120_MOMENCO_OCELOT_GT64120_DEP_H */ diff -Nru a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/int-handler.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,133 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * First-level interrupt dispatcher for ocelot board. + * + * 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 __ASSEMBLY__ +#include <linux/config.h> +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* + * first level interrupt dispatcher for ocelot board - + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + NESTED(ocelot_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP2 /* int0 hardware line */ + bnez t1, ll_pri_enet_irq + andi t1, t0, STATUSF_IP3 /* int1 hardware line */ + bnez t1, ll_sec_enet_irq + andi t1, t0, STATUSF_IP4 /* int2 hardware line */ + bnez t1, ll_uart_irq + andi t1, t0, STATUSF_IP5 /* int3 hardware line */ + bnez t1, ll_cpci_irq + andi t1, t0, STATUSF_IP6 /* int4 hardware line */ + bnez t1, ll_galileo_p0_irq + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + + /* now look at the extended interrupts */ + mfc0 t0, CP0_CAUSE + cfc0 t1, CP0_S1_INTCONTROL + + /* shift the mask 8 bits left to line up the bits */ + sll t2, t1, 8 + + and t0, t2 + srl t0, t0, 16 + + andi t1, t0, STATUSF_IP8 /* int6 hardware line */ + bnez t1, ll_galileo_p1_irq + andi t1, t0, STATUSF_IP9 /* int7 hardware line */ + bnez t1, ll_pmc_irq + andi t1, t0, STATUSF_IP10 /* int8 hardware line */ + bnez t1, ll_cpci_abcd_irq + andi t1, t0, STATUSF_IP11 /* int9 hardware line */ + bnez t1, ll_testpoint_irq + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(ocelot_handle_int) + + .align 5 +ll_pri_enet_irq: + li a0, 2 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_sec_enet_irq: + li a0, 3 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_uart_irq: + li a0, 4 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpci_irq: + li a0, 5 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_galileo_p0_irq: + li a0, 6 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cputimer_irq: + li a0, 7 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_galileo_p1_irq: + li a0, 8 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_pmc_irq: + li a0, 9 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_cpci_abcd_irq: + li a0, 10 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_testpoint_irq: + li a0, 11 + move a1, sp + jal do_IRQ + j ret_from_irq diff -Nru a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * 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 <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + + +static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED; + +/* Function for careful CP0 interrupt mask access */ +static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in) +{ + unsigned long status; + unsigned clr_mask; + unsigned set_mask; + + /* do the low 8 bits first */ + clr_mask = 0xff & clr_mask_in; + set_mask = 0xff & set_mask_in; + status = read_c0_status(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_c0_status(status); + + /* do the high 8 bits */ + clr_mask = 0xff & (clr_mask_in >> 8); + set_mask = 0xff & (set_mask_in >> 8); + status = read_c0_intcontrol(); + status &= ~((clr_mask & 0xFF) << 8); + status |= (set_mask & 0xFF) << 8; + write_c0_intrcontrol(status); +} + +static inline void mask_irq(unsigned int irq) +{ + modify_cp0_intmask(irq, 0); +} + +static inline void unmask_irq(unsigned int irq) +{ + modify_cp0_intmask(0, irq); +} + +static void enable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&rm7000_irq_lock, flags); + unmask_irq(1 << irq); + spin_unlock_irqrestore(&rm7000_irq_lock, flags); +} + +static unsigned int startup_cp7000_irq(unsigned int irq) +{ + enable_cp7000_irq(irq); + + return 0; /* never anything pending */ +} + +static void disable_cp7000_irq(unsigned int irq) +{ + unsigned long flags; + + spin_lock_irqsave(&rm7000_irq_lock, flags); + mask_irq(1 << irq); + spin_unlock_irqrestore(&rm7000_irq_lock, flags); +} + +#define shutdown_cp7000_irq disable_cp7000_irq + +static void mask_and_ack_cp7000_irq(unsigned int irq) +{ + mask_irq(1 << irq); +} + +static void end_cp7000_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + unmask_irq(1 << irq); +} + +static struct hw_interrupt_type cp7000_hpcdma_irq_type = { + "CP7000", + startup_cp7000_irq, + shutdown_cp7000_irq, + enable_cp7000_irq, + disable_cp7000_irq, + mask_and_ack_cp7000_irq, + end_cp7000_irq, + NULL +}; + + +extern asmlinkage void ocelot_handle_int(void); +extern void gt64240_irq_init(void); + +void __init init_IRQ(void) +{ + int i; + + /* + * Clear all of the interrupts while we change the able around a bit. + * int-handler is not on bootstrap + */ + clear_c0_status(ST0_IM | ST0_BEV); + local_irq_disable(); + + /* Sets the first-level interrupt dispatcher. */ + set_except_vector(0, ocelot_handle_int); + init_generic_irq(); + + for (i = 0; i <= 15; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &cp7000_hpcdma_irq_type; + } + + gt64240_irq_init(); + +#ifdef CONFIG_KGDB + printk("start kgdb ...\n"); + set_debug_traps(); + breakpoint(); /* you may move this line to whereever you want :-) */ +#endif +#ifdef CONFIG_GDB_CONSOLE + register_gdb_console(); +#endif +} diff -Nru a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,30 @@ +/* + * Ocelot Board Register Definitions + * + * (C) 2001 Red Hat, Inc. + * + * GPL'd + */ +#ifndef __MOMENCO_OCELOT_PLD_H__ +#define __MOMENCO_OCELOT_PLD_H__ + +#define OCELOT_CS0_ADDR (0xfc000000) + +#define OCELOT_REG_BOARDREV (0) +#define OCELOT_REG_PLD1_ID (1) +#define OCELOT_REG_PLD2_ID (2) +#define OCELOT_REG_RESET_STATUS (3) +#define OCELOT_REG_BOARD_STATUS (4) +#define OCELOT_REG_CPCI_ID (5) +#define OCELOT_REG_I2C_CTRL (8) +#define OCELOT_REG_EEPROM_MODE (9) +#define OCELOT_REG_INTMASK (10) +#define OCELOT_REG_INTSTATUS (11) +#define OCELOT_REG_INTSET (12) +#define OCELOT_REG_INTCLR (13) + +#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y) +#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x) + + +#endif /* __MOMENCO_OCELOT_PLD_H__ */ diff -Nru a/arch/mips/momentum/ocelot_g/pci-irq.c b/arch/mips/momentum/ocelot_g/pci-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/pci-irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,74 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * Based on work for the Linux port to the Ocelot board, which is + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/momentum/ocelot_g/pci.c + * Board-specific PCI routines for gt64240 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/version.h> +#include <linux/init.h> +#include <asm/pci.h> + + +void __devinit gt64240_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + /* loop over all known devices on this bus */ + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if ((current_bus->number == 0) && + PCI_SLOT(devices->devfn) == 1) { + /* Intel 82543 Gigabit MAC */ + devices->irq = 2; /* irq_nr is 2 for INT0 */ + } else if ((current_bus->number == 0) && + PCI_SLOT(devices->devfn) == 2) { + /* Intel 82543 Gigabit MAC */ + devices->irq = 3; /* irq_nr is 3 for INT1 */ + } else if ((current_bus->number == 1) && + PCI_SLOT(devices->devfn) == 3) { + /* Intel 21555 bridge */ + devices->irq = 5; /* irq_nr is 8 for INT6 */ + } else if ((current_bus->number == 1) && + PCI_SLOT(devices->devfn) == 4) { + /* PMC Slot */ + devices->irq = 9; /* irq_nr is 9 for INT7 */ + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write(current_bus, devices, + PCI_INTERRUPT_LINE, 1, devices->irq); + + /* enable master for everything but the GT-64240 */ + if (((current_bus->number != 0) && (current_bus->number != 1)) + || (PCI_SLOT(devices->devfn) != 0)) { + bus->ops->read(current_bus, devices, + PCI_COMMAND, 2, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write(current_bus, devices, + PCI_COMMAND, 2, cmd); + } + } +} diff -Nru a/arch/mips/momentum/ocelot_g/prom.c b/arch/mips/momentum/ocelot_g/prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/prom.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,100 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * Based on Ocelot Linux port, which is + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include "gt64240.h" +#include "ocelot_pld.h" + +struct callvectors { + int (*open) (char*, int, int); + int (*close) (int); + int (*read) (int, void*, int); + int (*write) (int, void*, int); + off_t (*lseek) (int, off_t, int); + int (*printf) (const char*, ...); + void (*cacheflush) (void); + char* (*gets) (char*); +}; + +struct callvectors* debug_vectors; +char arcs_cmdline[CL_SIZE]; + +extern unsigned long gt64240_base; +extern unsigned long bus_clock; + +#ifdef CONFIG_GALILLEO_GT64240_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + +const char *get_system_type(void) +{ + return "Momentum Ocelot"; +} + +/* [jsun@junsun.net] PMON passes arguments in C main() style */ +void __init prom_init(int argc, char **arg, char** env, struct callvectors *cv) +{ + int i; + uint32_t tmp; + + /* save the PROM vectors for debugging use */ + debug_vectors = cv; + + /* arg[0] is "g", the rest is boot parameters */ + arcs_cmdline[0] = '\0'; + for (i = 1; i < argc; i++) { + if (strlen(arcs_cmdline) + strlen(arg[i] + 1) + >= sizeof(arcs_cmdline)) + break; + strcat(arcs_cmdline, arg[i]); + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_MOMENCO; + mips_machtype = MACH_MOMENCO_OCELOT_G; + +#ifdef CONFIG_GALILLEO_GT64240_ETH + /* get the base MAC address for on-board ethernet ports */ + memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); +#endif + + while (*env) { + if (strncmp("gtbase", *env, strlen("gtbase")) == 0) { + gt64240_base = simple_strtol(*env + strlen("gtbase="), + NULL, 16); + } + if (strncmp("busclock", *env, strlen("busclock")) == 0) { + bus_clock = simple_strtol(*env + strlen("busclock="), + NULL, 10); + } + *env++; + } + + debug_vectors->printf("Booting Linux kernel...\n"); +} + +void __init prom_free_prom_memory(void) +{ +} + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} diff -Nru a/arch/mips/momentum/ocelot_g/reset.c b/arch/mips/momentum/ocelot_g/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,47 @@ +/* + * 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. + * + * Copyright (C) 1997, 2001 Ralf Baechle + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/io.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/system.h> +#include <linux/delay.h> + +void momenco_ocelot_restart(char *command) +{ + void *nvram = ioremap_nocache(0x2c807000, 0x1000); + + if (!nvram) { + printk(KERN_NOTICE "ioremap of reset register failed\n"); + return; + } + writeb(0x84, nvram + 0xff7); /* Ask the NVRAM/RTC/watchdog chip to + assert reset in 1/16 second */ + mdelay(10+(1000/16)); + iounmap(nvram); + printk(KERN_NOTICE "Watchdog reset failed\n"); +} + +void momenco_ocelot_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void momenco_ocelot_power_off(void) +{ + momenco_ocelot_halt(); +} diff -Nru a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/momentum/ocelot_g/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,265 @@ +/* + * setup.c + * + * BRIEF MODULE DESCRIPTION + * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Copyright (C) 2001 Red Hat, Inc. + * Copyright (C) 2002 Momentum Computer + * + * Author: Matthew Dharm, Momentum Computer + * mdharm@momenco.com + * + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * 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 <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mc146818rtc.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <linux/vmalloc.h> +#include <asm/time.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/mc146818rtc.h> +#include <linux/version.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include "gt64240.h" +#include "ocelot_pld.h" + +extern struct rtc_ops no_rtc_ops; + +#ifdef CONFIG_GALILLEO_GT64240_ETH +extern unsigned char prom_mac_addr_base[6]; +#endif + +unsigned long gt64240_base; + +/* These functions are used for rebooting or halting the machine*/ +extern void momenco_ocelot_restart(char *command); +extern void momenco_ocelot_halt(void); +extern void momenco_ocelot_power_off(void); + +extern void gt64240_time_init(void); +extern void momenco_ocelot_irq_setup(void); + +static char reset_reason; + +#define ENTRYLO(x) ((pte_val(pfn_pte((x) >> PAGE_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6)|1) + +static void __init setup_l3cache(unsigned long size); + +/* setup code for a handoff from a version 2 PMON 2000 PROM */ +void PMON_v2_setup(void) +{ + /* A wired TLB entry for the GT64240 and the serial port. The + GT64240 is going to be hit on every IRQ anyway - there's + absolutely no point in letting it be a random TLB entry, as + it'll just cause needless churning of the TLB. And we use + the other half for the serial port, which is just a PITA + otherwise :) + + Device Physical Virtual + GT64240 Internal Regs 0xf4000000 0xe0000000 + UARTs (CS2) 0xfd000000 0xe0001000 + */ + add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); + add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000), 0xfd000000, PM_4K); + + /* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM + in the CS[012] region. We can't use ioremap() yet. The NVRAM + is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions. + + Ocelot PLD (CS0) 0xfc000000 0xe0020000 + NVRAM (CS1) 0xfc800000 0xe0030000 + */ + add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000), 0xfc000000, PM_64K); + add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000), 0xfc800000, PM_64K); + + gt64240_base = 0xf4000000; +} + +void __init momenco_ocelot_g_setup(void) +{ + void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); + unsigned int tmpword; + + board_time_init = gt64240_time_init; + + _machine_restart = momenco_ocelot_restart; + _machine_halt = momenco_ocelot_halt; + _machine_power_off = momenco_ocelot_power_off; + + /* + * initrd_start = (ulong)ocelot_initrd_start; + * initrd_end = (ulong)ocelot_initrd_start + (ulong)ocelot_initrd_size; + * initrd_below_start_ok = 1; + */ + rtc_ops = &no_rtc_ops; + + /* do handoff reconfiguration */ + PMON_v2_setup(); + +#ifdef CONFIG_GALILLEO_GT64240_ETH + /* get the mac addr */ + memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6); +#endif + + /* Turn off the Bit-Error LED */ + OCELOT_PLD_WRITE(0x80, INTCLR); + + tmpword = OCELOT_PLD_READ(BOARDREV); + if (tmpword < 26) + printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword); + else + printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword); + + tmpword = OCELOT_PLD_READ(PLD1_ID); + printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15); + tmpword = OCELOT_PLD_READ(PLD2_ID); + printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15); + tmpword = OCELOT_PLD_READ(RESET_STATUS); + printk("Reset reason: 0x%x\n", tmpword); + reset_reason = tmpword; + OCELOT_PLD_WRITE(0xff, RESET_STATUS); + + tmpword = OCELOT_PLD_READ(BOARD_STATUS); + printk("Board Status register: 0x%02x\n", tmpword); + printk(" - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent"); + printk(" - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent"); + printk(" - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not"); + printk(" - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1); + printk(" - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3))); + + if (tmpword&12) + l3func((1<<(((tmpword&12) >> 2)+20))); + + switch(tmpword &3) { + case 3: + /* 512MiB -- two banks of 256MiB */ + add_memory_region( 0x0<<20, 0x100<<20, BOOT_MEM_RAM); +/* + add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM); +*/ + break; + case 2: + /* 256MiB -- two banks of 128MiB */ + add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM); + add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM); + break; + case 1: + /* 128MiB -- 64MiB per bank */ + add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM); + add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM); + break; + case 0: + /* 64MiB */ + add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM); + break; + } + + /* FIXME: Fix up the DiskOnChip mapping */ + GT_WRITE(0x468, 0xfef73); +} + +extern int rm7k_tcache_enabled; +/* + * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache() + */ +#define Page_Invalidate_T 0x16 +static void __init setup_l3cache(unsigned long size) +{ + int register i; + unsigned long tmp; + + printk("Enabling L3 cache..."); + + /* Enable the L3 cache in the GT64120A's CPU Configuration register */ + GT_READ(0, &tmp); + GT_WRITE(0, tmp | (1<<14)); + + /* Enable the L3 cache in the CPU */ + set_c0_config(1<<12 /* CONF_TE */); + + /* Clear the cache */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i < size; i+= 4096) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (KSEG0ADDR(i)), + "i" (Page_Invalidate_T)); + } + + /* Let the RM7000 MM code know that the tertiary cache is enabled */ + rm7k_tcache_enabled = 1; + + printk("Done\n"); +} + + +/* This needs to be one of the first initcalls, because no I/O port access + can work before this */ + +static int io_base_ioremap(void) +{ + /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ + void *io_remap_range = ioremap(0xc0000000, 0x30000000); + + if (!io_remap_range) { + panic("Could not ioremap I/O port range"); + } + printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); + set_io_port_base(io_remap_range - 0xc0000000); + + return 0; +} + +module_init(io_base_ioremap); diff -Nru a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,36 @@ +# +# Makefile for the PCI specific kernel interface routines under Linux. +# +# This is all organized on a per system base which is horribly wrong and +# really wants a cleanup. You have been warned. +# + +obj-$(CONFIG_NEW_PCI) += pci.o +obj-$(CONFIG_PCI_AUTO) += pci-auto.o +obj-$(CONFIG_DDB5074) += pci-ddb5074.o ops-ddb5074.o +obj-$(CONFIG_DDB5476) += pci-ddb5476.o ops-ddb5476.o +obj-$(CONFIG_DDB5477) += pci-ddb5477.o ops-ddb5477.o +obj-$(CONFIG_HP_LASERJET) += pci-hplj.o +obj-$(CONFIG_ITE_BOARD_GEN) += ops-it8172.o +obj-$(CONFIG_LASAT) += pci-lasat.o +obj-$(CONFIG_MIPS_BOARDS_GEN) += pci-mips.o +obj-$(CONFIG_MIPS_COBALT) += pci-cobalt.o +obj-$(CONFIG_MIPS_EV64120) += ops-ev64120.o +obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o ops-ev96100.o +obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o +obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o +obj-$(CONFIG_MIPS_PB1500) += fixups-au1000.o ops-au1000.o +obj-$(CONFIG_MOMENCO_OCELOT) += fixups-ocelot.o ops-ocelot.o +obj-$(CONFIG_NEC_EAGLE) += fixup-eagle.o ops-vrc4173.o +obj-$(CONFIG_SGI_IP27) += pci-ip27.o +obj-$(CONFIG_SGI_IP32) += pci-ip32.o +obj-$(CONFIG_SIBYTE_SB1250) += pci-sb1250.o +obj-$(CONFIG_SNI_RM200_PCI) += pci-sni.o +obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o +obj-$(CONFIG_TANBAC_TB0229) += fixup-tb0229.o +obj-$(CONFIG_TOSHIBA_JMR3927) += fixup-jmr3927.o ops-jmr3927.o +#obj-$(CONFIG_MOMENCO_OCELOT_C) += pci-ocelot-c.o +obj-$(CONFIG_MOMENCO_OCELOT_G) += pci-ocelot-g.o +obj-$(CONFIG_VICTOR_MPC30X) += fixup-capcella.o +obj-$(CONFIG_VR41XX_COMMON) += pci-vr41xx.o +obj-$(CONFIG_ZAO_CAPCELLA) += fixup-victor-mpc30x.o diff -Nru a/arch/mips/pci/common.c b/arch/mips/pci/common.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/common.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,69 @@ +void __init pcibios_fixup_bus(struct pci_bus *b) +{ + Dprintk("pcibios_fixup_bus()\n"); +} + +static int pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1 << idx))) + continue; + + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of resource collisions\n", + dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + dev->slot_name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + int err; + + if ((err = pcibios_enable_resources(dev, mask)) < 0) + return err; + + return 0; +} + +void __init pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + panic("Uhhoh called pcibios_align_resource"); +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +char *pcibios_setup(char *str) +{ + return str; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff -Nru a/arch/mips/pci/fixup-au1000.c b/arch/mips/pci/fixup-au1000.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-au1000.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,124 @@ +/* + * BRIEF MODULE DESCRIPTION + * Board specific pci fixups. + * + * Copyright 2001-2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/config.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/au1000.h> +//#include <asm/pb1500.h> +#ifdef CONFIG_MIPS_PB1000 +#include <asm/pb1000.h> +#endif + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static void fixup_resource(int r_num, struct pci_dev *dev); +#ifdef CONFIG_SOC_AU1500 +static unsigned long virt_io_addr; +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ +#ifdef CONFIG_SOC_AU1500 + int i; + struct pci_dev *dev; + + virt_io_addr = (unsigned long) ioremap(Au1500_PCI_IO_START, + Au1500_PCI_IO_END - + Au1500_PCI_IO_START + 1); + + if (!virt_io_addr) { + printk(KERN_ERR "Unable to ioremap pci space\n"); + return; + } + + set_io_port_base(virt_io_addr); +#endif + +#ifdef CONFIG_MIPS_PB1000 /* This is truly board specific */ + unsigned long pci_mem_start = (unsigned long) PCI_MEM_START; + + au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0 + au_writel(0, SDRAM_MBAR); // set mbar to 0 + au_writel(0x2, SDRAM_CMD); // enable memory accesses + au_sync_delay(1); + + // set extend byte to mbar of ext slot + au_writel(((pci_mem_start >> 24) & 0xff) | + (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), + PCI_BRIDGE_CONFIG); + DBG("Set bridge config to %x\n", au_readl(PCI_BRIDGE_CONFIG)); +#endif +} + +void __init pcibios_fixup_irqs(void) +{ +#ifdef CONFIG_SOC_AU1500 + unsigned int slot, func; + unsigned char pin; + struct pci_dev *dev = NULL; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + if (dev->bus->number != 0) + return; + + dev->irq = 0xff; + slot = PCI_SLOT(dev->devfn); + switch (slot) { + case 12: + case 13: + dev->irq = AU1000_PCI_INTA; + break; + + } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + DBG("slot %d irq %d\n", slot, dev->irq); + } +#endif +} +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} + +static void fixup_resource(int r_num, struct pci_dev *dev) +{ +} diff -Nru a/arch/mips/pci/fixup-capcella.c b/arch/mips/pci/fixup-capcella.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-capcella.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,72 @@ +/* + * FILE NAME + * arch/mips/vr41xx/zao-capcella/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The ZAO Networks Capcella specific PCI fixups. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/vr41xx/capcella.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + u8 slot, func, pin; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 11: + dev->irq = RTL8139_1_IRQ; + break; + case 12: + dev->irq = RTL8139_2_IRQ; + break; + case 14: + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + switch (pin) { + case 1: + dev->irq = PC104PLUS_INTA_IRQ; + break; + case 2: + dev->irq = PC104PLUS_INTB_IRQ; + break; + case 3: + dev->irq = PC104PLUS_INTC_IRQ; + break; + case 4: + dev->irq = PC104PLUS_INTD_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/fixup-eagle.c b/arch/mips/pci/fixup-eagle.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-eagle.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,166 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The NEC Eagle/Hawk Board specific PCI fixups. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Moved mips_pci_channels[] to arch/mips/vr41xx/vr4122/eagle/setup.c. + * - Added support for NEC Hawk. + * + * Paul Mundt <lethal@chaoticdreams.org> + * - Fix empty break statements. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC Eagle is supported. + */ +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/vr41xx/eagle.h> +#include <asm/vr41xx/vrc4173.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + u8 slot, func, pin; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + dev->irq = 0; + + switch (slot) { + case 8: + switch (pin) { + case 1: + dev->irq = CP_INTA_IRQ; + break; + case 2: + dev->irq = CP_INTB_IRQ; + break; + case 3: + dev->irq = CP_INTC_IRQ; + break; + case 4: + dev->irq = CP_INTD_IRQ; + break; + } + break; + case 9: + switch (pin) { + case 1: + dev->irq = CP_INTD_IRQ; + break; + case 2: + dev->irq = CP_INTA_IRQ; + break; + case 3: + dev->irq = CP_INTB_IRQ; + break; + case 4: + dev->irq = CP_INTC_IRQ; + break; + } + break; + case 10: + switch (pin) { + case 1: + dev->irq = CP_INTC_IRQ; + break; + case 2: + dev->irq = CP_INTD_IRQ; + break; + case 3: + dev->irq = CP_INTA_IRQ; + break; + case 4: + dev->irq = CP_INTB_IRQ; + break; + } + break; + case 12: + dev->irq = VRC4173_PCMCIA1_IRQ; + break; + case 13: + dev->irq = VRC4173_PCMCIA2_IRQ; + break; + case 28: + dev->irq = LANINTA_IRQ; + break; + case 29: + switch (pin) { + case 1: + dev->irq = PCISLOT_IRQ; + break; + case 2: + dev->irq = CP_INTB_IRQ; + break; + case 3: + dev->irq = CP_INTC_IRQ; + break; + case 4: + dev->irq = CP_INTD_IRQ; + break; + } + break; + case 30: + switch (func) { + case 0: + dev->irq = VRC4173_CASCADE_IRQ; + break; + case 1: + dev->irq = VRC4173_AC97_IRQ; + break; + case 2: + dev->irq = VRC4173_USB_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/fixup-ite8172g.c b/arch/mips/pci/fixup-ite8172g.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-ite8172g.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,189 @@ +/* + * BRIEF MODULE DESCRIPTION + * Board specific pci fixups. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/it8172/it8172.h> +#include <asm/it8172/it8172_pci.h> +#include <asm/it8172/it8172_int.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + unsigned int slot, func; + unsigned char pin; + struct pci_dev *dev = NULL; + + const int internal_func_irqs[7] = { + IT8172_AC97_IRQ, + IT8172_DMA_IRQ, + IT8172_CDMA_IRQ, + IT8172_USB_IRQ, + IT8172_BRIDGE_MASTER_IRQ, + IT8172_IDE_IRQ, + IT8172_MC68K_IRQ + }; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + if (dev->bus->number != 0) + return; + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + + switch (slot) { + case 0x01: + /* + * Internal device 1 is actually 7 different + * internal devices on the IT8172G (a multi- + * function device). + */ + if (func < 7) + dev->irq = internal_func_irqs[func]; + break; + case 0x10: + switch (pin) { + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + case 0x11: + switch (pin) { + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + case 0x12: + switch (pin) { + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + case 0x13: + switch (pin) { + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + case 0x14: + switch (pin) { + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + default: + continue; /* do nothing */ + } +#ifdef DEBUG + printk("irq fixup: slot %d, int line %d, int number %d\n", + slot, pin, dev->irq); +#endif + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} diff -Nru a/arch/mips/pci/fixup-ivr.c b/arch/mips/pci/fixup-ivr.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-ivr.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,153 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Globespan IVR board-specific pci fixups. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/it8172/it8172.h> +#include <asm/it8172/it8172_pci.h> +#include <asm/it8172/it8172_int.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + unsigned int slot, func; + unsigned char pin; + struct pci_dev *dev = NULL; + + const int internal_func_irqs[7] = { + IT8172_AC97_IRQ, + IT8172_DMA_IRQ, + IT8172_CDMA_IRQ, + IT8172_USB_IRQ, + IT8172_BRIDGE_MASTER_IRQ, + IT8172_IDE_IRQ, + IT8172_MC68K_IRQ + }; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + if (dev->bus->number != 0) + return; + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + + switch (slot) { + case 0x01: + /* + * Internal device 1 is actually 7 different + * internal devices on the IT8172G (multi-function + * device). + */ + if (func < 7) + dev->irq = internal_func_irqs[func]; + break; + case 0x11: // Realtek RTL-8139 + switch (pin) { + case 0: /* pin A, hardware bug */ + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + case 0x12: // ivr slot + switch (pin) { + case 0: /* pin A, hardware bug */ + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + case 0x13: // expansion slot + switch (pin) { + case 0: /* pin A, hardware bug */ + case 1: /* pin A */ + dev->irq = IT8172_PCI_INTA_IRQ; + break; + case 2: /* pin B */ + dev->irq = IT8172_PCI_INTB_IRQ; + break; + case 3: /* pin C */ + dev->irq = IT8172_PCI_INTC_IRQ; + break; + case 4: /* pin D */ + dev->irq = IT8172_PCI_INTD_IRQ; + break; + default: + dev->irq = 0xff; + break; + + } + break; + default: + break; + } +#ifdef DEBUG + printk("irq fixup: slot %d, int line %d, int number %d\n", + slot, pin, dev->irq); +#endif + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} diff -Nru a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-jmr3927.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,138 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Board specific pci fixups. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/jmr3927/jmr3927.h> + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ + /* nothing to do here */ +} + +int pci_get_irq(struct pci_dev *dev, int pin) +{ + unsigned char irq = pin; + + /* IRQ rotation (PICMG) */ + irq--; /* 0-3 */ + if (dev->bus->parent == NULL && + PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(23)) { + /* PCI CardSlot (IDSEL=A23, DevNu=12) */ + /* PCIA => PCIC (IDSEL=A23) */ + /* NOTE: JMR3927 JP1 must be set to OPEN */ + irq = (irq + 2) % 4; + } else if (dev->bus->parent == NULL && + PCI_SLOT(dev->devfn) == + TX3927_PCIC_IDSEL_AD_TO_SLOT(22)) { + /* PCI CardSlot (IDSEL=A22, DevNu=11) */ + /* PCIA => PCIA (IDSEL=A22) */ + /* NOTE: JMR3927 JP1 must be set to OPEN */ + irq = (irq + 0) % 4; + } else { + /* PCI Backplane */ + irq = (irq + 3 + PCI_SLOT(dev->devfn)) % 4; +#if 0 /* ??? */ + for (bus = dev->bus; bus->parent != NULL; + bus = bus->parent) { + irq = (irq + 3 + PCI_SLOT(bus->self->devfn)) % 4; + } +#endif + } + irq++; /* 1-4 */ + + switch (irq) { + case 1: + irq = JMR3927_IRQ_IOC_PCIA; + break; + case 2: + // wrong for backplane irq = JMR3927_IRQ_IOC_PCIB; + irq = JMR3927_IRQ_IOC_PCID; + break; + case 3: + irq = JMR3927_IRQ_IOC_PCIC; + break; + case 4: + // wrong for backplane irq = JMR3927_IRQ_IOC_PCID; + irq = JMR3927_IRQ_IOC_PCIB; + break; + } + + /* Check OnBoard Ethernet (IDSEL=A24, DevNu=13) */ + if (dev->bus->parent == NULL && + PCI_SLOT(dev->devfn) == TX3927_PCIC_IDSEL_AD_TO_SLOT(24)) { + extern int jmr3927_ether1_irq; + /* check this irq line was reserved for ether1 */ + if (jmr3927_ether1_irq != JMR3927_IRQ_ETHER0) + irq = JMR3927_IRQ_ETHER0; + else + irq = 0; /* disable */ + } + return irq; +} + +void __init pcibios_fixup_irqs(void) +{ + unsigned char irq; + struct pci_dev *dev = NULL; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); + if (irq == 0) + return; + + /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ + if (!(dev->vendor == PCI_VENDOR_ID_EFAR && + dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1)) { + irq = pci_get_irq(dev, irq); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + irq); + } + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + printk(KERN_INFO "PCI: %02x:%02x IRQ %02x\n", + dev->bus->number, dev->devfn, irq); + dev->irq = irq; + } +} diff -Nru a/arch/mips/pci/fixup-ocelot.c b/arch/mips/pci/fixup-ocelot.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-ocelot.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,77 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/gt64120/momenco_ocelot/pci.c + * Board-specific PCI routines for gt64120 controller. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/version.h> +#include <linux/init.h> +#include <asm/pci.h> + + +void __devinit gt64120_board_pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + u16 cmd; + + list_for_each(devices_link, &(current_bus->devices)) { + + devices = pci_dev_b(devices_link); + if (devices == NULL) + continue; + + if (PCI_SLOT(devices->devfn) == 1) { + /* + * Slot 1 is primary ether port, i82559 + * we double-check against that assumption + */ + if ((devices->vendor != 0x8086) || + (devices->device != 0x1209)) { + panic + ("gt64120_board_pcibios_fixup_bus: found " + "unexpected PCI device in slot 1."); + } + devices->irq = 2; /* irq_nr is 2 for INT0 */ + } else if (PCI_SLOT(devices->devfn) == 2) { + /* + * Slot 2 is secondary ether port, i21143 + * we double-check against that assumption + */ + if ((devices->vendor != 0x1011) || + (devices->device != 0x19)) { + panic("galileo_pcibios_fixup_bus: " + "found unexpected PCI device in slot 2."); + } + devices->irq = 3; /* irq_nr is 3 for INT1 */ + } else if (PCI_SLOT(devices->devfn) == 4) { + /* PMC Slot 1 */ + devices->irq = 8; /* irq_nr is 8 for INT6 */ + } else if (PCI_SLOT(devices->devfn) == 5) { + /* PMC Slot 1 */ + devices->irq = 9; /* irq_nr is 9 for INT7 */ + } else { + /* We don't have assign interrupts for other devices. */ + devices->irq = 0xff; + } + + /* Assign an interrupt number for the device */ + bus->ops->write_byte(devices, PCI_INTERRUPT_LINE, + devices->irq); + + /* enable master */ + bus->ops->read_word(devices, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + bus->ops->write_word(devices, PCI_COMMAND, cmd); + } +} diff -Nru a/arch/mips/pci/fixup-tb0226.c b/arch/mips/pci/fixup-tb0226.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-tb0226.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The TANBAC TB0226 specific PCI fixups. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/vr41xx/tb0226.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + u8 slot, pin; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot = PCI_SLOT(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(GD82559_1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_1_PIN, LEVEL_LOW); + dev->irq = GD82559_1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(GD82559_2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(GD82559_2_PIN, LEVEL_LOW); + dev->irq = GD82559_2_IRQ; + break; + case 14: + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + switch (pin) { + case 1: + vr41xx_set_irq_trigger(UPD720100_INTA_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTA_PIN, + LEVEL_LOW); + dev->irq = UPD720100_INTA_IRQ; + break; + case 2: + vr41xx_set_irq_trigger(UPD720100_INTB_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTB_PIN, + LEVEL_LOW); + dev->irq = UPD720100_INTB_IRQ; + break; + case 3: + vr41xx_set_irq_trigger(UPD720100_INTC_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(UPD720100_INTC_PIN, + LEVEL_LOW); + dev->irq = UPD720100_INTC_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/fixup-tb0229.c b/arch/mips/pci/fixup-tb0229.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-tb0229.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,77 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The TANBAC TB0229(VR4131DIMM) specific PCI fixups. + * + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/vr41xx/tb0229.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ +#ifdef CONFIG_TANBAC_TB0219 + struct pci_dev *dev = NULL; + u8 slot; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot = PCI_SLOT(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT1_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT1_PIN, + LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT1_IRQ; + break; + case 13: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT2_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT2_PIN, + LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT2_IRQ; + break; + case 14: + vr41xx_set_irq_trigger(TB0219_PCI_SLOT3_PIN, + TRIGGER_LEVEL, + SIGNAL_THROUGH); + vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, + LEVEL_LOW); + dev->irq = TB0219_PCI_SLOT3_IRQ; + break; + default: + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +#endif +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/fixup-victor-mpc30x.c b/arch/mips/pci/fixup-victor-mpc30x.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixup-victor-mpc30x.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,72 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/pci_fixup.c + * + * BRIEF MODULE DESCRIPTION + * The Victor MP-C303/304 specific PCI fixups. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/init.h> +#include <linux/pci.h> + +#include <asm/vr41xx/vrc4173.h> +#include <asm/vr41xx/mpc30x.h> + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + u8 slot, func; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot = PCI_SLOT(dev->devfn); + func = PCI_FUNC(dev->devfn); + dev->irq = 0; + + switch (slot) { + case 12: /* NEC VRC4173 CARDU1 */ + dev->irq = VRC4173_PCMCIA1_IRQ; + break; + case 13: /* NEC VRC4173 CARDU2 */ + dev->irq = VRC4173_PCMCIA2_IRQ; + break; + case 29: /* mediaQ MQ-200 */ + dev->irq = MQ200_IRQ; + break; + case 30: + switch (func) { + case 0: /* NEC VRC4173 */ + dev->irq = VRC4173_CASCADE_IRQ; + break; + case 1: /* NEC VRC4173 AC97U */ + dev->irq = VRC4173_AC97_IRQ; + break; + case 2: /* NEC VRC4173 USBU */ + dev->irq = VRC4173_USB_IRQ; + break; + } + break; + } + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/fixups-ev96100.c b/arch/mips/pci/fixups-ev96100.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/fixups-ev96100.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * EV96100 Board specific pci fixups. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci_ids.h> + +#include <asm/gt64120.h> +#include <asm/galileo-boards/ev96100.h> + +extern unsigned short get_gt_devid(void); + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + unsigned int slot; + u32 vendor; + unsigned short gt_devid = get_gt_devid(); + + /* + ** EV96100/A interrupt routing for pci bus 0 + ** + ** Note: EV96100A board with irq jumper set on 'VxWorks' + ** for EV96100 compatibility. + */ + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + if (dev->bus->number != 0) + return; + + slot = PCI_SLOT(dev->devfn); + pci_read_config_dword(dev, PCI_SUBSYSTEM_VENDOR_ID, + &vendor); + +#ifdef DEBUG + printk("devfn %x, slot %d devid %x\n", + dev->devfn, slot, gt_devid); +#endif + + /* fixup irq line based on slot # */ + if (slot == 8) { + dev->irq = 5; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + dev->irq); + } else if (slot == 9) { + dev->irq = 2; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + dev->irq); + } + } +} +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-au1000.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,330 @@ +/* + * BRIEF MODULE DESCRIPTION + * Alchemy/AMD Au1x00 pci support. + * + * Copyright 2001,2002,2003 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Support for all devices (greater than 16) added by David Gathright. + * + * 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 <linux/config.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/au1000.h> +#ifdef CONFIG_MIPS_PB1000 +#include <asm/pb1000.h> +#endif +#include <asm/pci_channel.h> + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* TBD */ +static struct resource pci_io_resource = { + "pci IO space", + (u32) PCI_IO_START, + (u32) PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + "pci memory space", + (u32) PCI_MEM_START, + (u32) PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops au1x_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&au1x_pci_ops, &pci_io_resource, &pci_mem_resource, + PCI_FIRST_DEVFN, PCI_LAST_DEVFN}, + {(struct pci_ops *) NULL, (struct resource *) NULL, + (struct resource *) NULL, (int) NULL, (int) NULL} +}; + + +#ifdef CONFIG_MIPS_PB1000 +/* + * "Bus 2" is really the first and only external slot on the pb1000. + * We'll call that bus 0, and limit the accesses to that single + * external slot only. The SDRAM is already initialized in setup.c. + */ +static int config_access(unsigned char access_type, struct pci_dev *dev, + unsigned char where, u32 * data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + unsigned long config; + + if (((dev_fn >> 3) != 0) || (bus != 0)) { + *data = 0xffffffff; + return -1; + } + + config = PCI_CONFIG_BASE | (where & ~0x3); + + if (access_type == PCI_ACCESS_WRITE) { + au_writel(*data, config); + } else { + *data = au_readl(config); + } + au_sync_udelay(1); + + DBG("config_access: %d bus %d dev_fn %x at %x *data %x, conf %x\n", + access_type, bus, dev_fn, where, *data, config); + + DBG("bridge config reg: %x (%x)\n", au_readl(PCI_BRIDGE_CONFIG), + *data); + + if (au_readl(PCI_BRIDGE_CONFIG) & (1 << 16)) { + *data = 0xffffffff; + return -1; + } else { + return PCIBIOS_SUCCESSFUL; + } +} + +#else + +static int config_access(unsigned char access_type, struct pci_bus *bus, + unsigned int devfn, unsigned char where, + u32 * data) +{ +#ifdef CONFIG_SOC_AU1500 + unsigned int device = PCI_SLOT(devfn); + unsigned int function = PCI_FUNC(devfn); + unsigned long config, status; + unsigned long cfg_addr; + + if (device > 19) { + *data = 0xffffffff; + return -1; + } + + au_writel(((0x2000 << 16) | + (au_readl(Au1500_PCI_STATCMD) & 0xffff)), + Au1500_PCI_STATCMD); + //au_writel(au_readl(Au1500_PCI_CFG) & ~PCI_ERROR, Au1500_PCI_CFG); + au_sync_udelay(1); + + /* setup the config window */ + if (bus->number == 0) { + cfg_addr = (unsigned long) ioremap(Au1500_EXT_CFG | + ((1 << device) << 11), + 0x00100000); + } else { + cfg_addr = (unsigned long) ioremap(Au1500_EXT_CFG_TYPE1 | + (bus-> + number << 16) | (device + << + 11), + 0x00100000); + } + + if (!cfg_addr) + panic(KERN_ERR "PCI unable to ioremap cfg space\n"); + + /* setup the lower bits of the 36 bit address */ + config = cfg_addr | (function << 8) | (where & ~0x3); + +#if 0 + if (access_type == PCI_ACCESS_WRITE) { + printk("cfg write: "); + } else { + printk("cfg read: "); + } + printk("devfn %x, device %x func %x \n", devfn, device, function); + if (access_type == PCI_ACCESS_WRITE) { + printk("data %x\n", *data); + } +#endif + + if (access_type == PCI_ACCESS_WRITE) { + au_writel(*data, config); + } else { + *data = au_readl(config); + } + au_sync_udelay(2); + + + DBG("config_access: %d bus %d device %d at %x *data %x, conf %x\n", + access_type, bus->number, device, where, *data, config); + + /* unmap io space */ + iounmap((void *) cfg_addr); + + /* check master abort */ + status = au_readl(Au1500_PCI_STATCMD); +#if 0 + if (access_type == PCI_ACCESS_READ) { + printk("read data: %x\n", *data); + } +#endif + if (status & (1 << 29)) { + *data = 0xffffffff; + return -1; + } else if ((status >> 28) & 0xf) { + printk("PCI ERR detected: status %x\n", status); + *data = 0xffffffff; + return -1; + } else { + return PCIBIOS_SUCCESSFUL; + } +#endif +} +#endif + +static int read_config_byte(struct pci_bus *bus, unsigned int devfn, + int where, u8 * val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); + if (where & 1) + data >>= 8; + if (where & 2) + data >>= 16; + *val = data & 0xff; + return ret; +} + + +static int read_config_word(struct pci_bus *bus, unsigned int devfn, + int where, u16 * val) +{ + u32 data; + int ret; + + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data); + if (where & 2) + data >>= 16; + *val = data & 0xffff; + return ret; +} + +static int read_config_dword(struct pci_bus *bus, unsigned int devfn, + int where, u32 * val) +{ + int ret; + + ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val); + return ret; +} + +static int +write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, + u8 val) +{ + u32 data = 0; + + if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int +write_config_word(struct pci_bus *bus, unsigned int devfn, int where, + u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int +write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, + u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + switch (size) { + case 1: + return read_config_byte(bus, devfn, where, (u8 *) val); + case 2: + return read_config_word(bus, devfn, where, (u16 *) val); + default: + return read_config_dword(bus, devfn, where, val); + } +} + +static int config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + switch (size) { + case 1: + return write_config_byte(bus, devfn, where, (u8) val); + case 2: + return write_config_word(bus, devfn, where, (u16) val); + default: + return write_config_dword(bus, devfn, where, val); + } +} + + +struct pci_ops au1x_pci_ops = { + config_read, + config_write +}; diff -Nru a/arch/mips/pci/ops-ddb5074.c b/arch/mips/pci/ops-ddb5074.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-ddb5074.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,335 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/ddb5xxx/ddb5476/pci_ops.c + * Define the pci_ops for DB5477. + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven <geert@sonycom.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include <linux/config.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/debug.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +/* + * config_swap structure records what set of pdar/pmr are used + * to access pci config space. It also provides a place hold the + * original values for future restoring. + */ +struct pci_config_swap { + u32 pdar; + u32 pmr; + u32 config_base; + u32 config_size; + u32 pdar_backup; + u32 pmr_backup; +}; + +/* + * On DDB5476, we have one set of swap registers + */ +struct pci_config_swap ext_pci_swap = { + DDB_PCIW0, + DDB_PCIINIT0, + DDB_PCI_CONFIG_BASE, + DDB_PCI_CONFIG_SIZE +}; + +static int pci_config_workaround = 1; + +/* + * access config space + */ +static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */ + u32 slot_num) +{ + u32 pci_addr = 0; + u32 pciinit_offset = 0; + u32 virt_addr = swap->config_base; + u32 option; + + if (pci_config_workaround) { + if (slot_num == 5) + slot_num = 14; + } else { + if (slot_num == 5) + return DDB_BASE + DDB_PCI_BASE; + } + + /* minimum pdar (window) size is 2MB */ + db_assert(swap->config_size >= (2 << 20)); + + db_assert(slot_num < (1 << 5)); + db_assert(bus < (1 << 8)); + + /* backup registers */ + swap->pdar_backup = ddb_in32(swap->pdar); + swap->pmr_backup = ddb_in32(swap->pmr); + + /* set the pdar (pci window) register */ + ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */ + 0, /* not on local memory bus */ + 0); /* not visible from PCI bus (N/A) */ + + /* + * calcuate the absolute pci config addr; + * according to the spec, we start scanning from adr:11 (0x800) + */ + if (bus == 0) { + /* type 0 config */ + pci_addr = 0x00040000 << slot_num; + } else { + /* type 1 config */ + pci_addr = 0x00040000 << slot_num; + panic + ("ddb_access_config_base: we don't support type 1 config Yet"); + } + + /* + * if pci_addr is less than pci config window size, we set + * pciinit_offset to 0 and adjust the virt_address. + * Otherwise we will try to adjust pciinit_offset. + */ + if (pci_addr < swap->config_size) { + virt_addr = KSEG1ADDR(swap->config_base + pci_addr); + pciinit_offset = 0; + } else { + db_assert((pci_addr & (swap->config_size - 1)) == 0); + virt_addr = KSEG1ADDR(swap->config_base); + pciinit_offset = pci_addr; + } + + /* set the pmr register */ + option = DDB_PCI_ACCESS_32; + if (bus != 0) + option |= DDB_PCI_CFGTYPE1; + ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option); + + return virt_addr; +} + +static inline void ddb_close_config_base(struct pci_config_swap *swap) +{ + ddb_out32(swap->pdar, swap->pdar_backup); + ddb_out32(swap->pmr, swap->pmr_backup); +} + +static int read_config_dword(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u32 * val) +{ + u32 bus, slot_num, func_num; + u32 base; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + base = ddb_access_config_base(swap, bus, slot_num); + *val = *(volatile u32 *) (base + (func_num << 8) + where); + ddb_close_config_base(swap); + return PCIBIOS_SUCCESSFUL; +} + +static int read_config_word(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u16 * val) +{ + int status; + u32 result; + + db_assert((where & 1) == 0); + + status = read_config_dword(swap, dev, where & ~3, &result); + if (where & 2) + result >>= 16; + *val = result & 0xffff; + return status; +} + +static int read_config_byte(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u8 * val) +{ + int status; + u32 result; + + status = read_config_dword(swap, dev, where & ~3, &result); + if (where & 1) + result >>= 8; + if (where & 2) + result >>= 16; + *val = result & 0xff; + return status; +} + +static int write_config_dword(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u32 val) +{ + u32 bus, slot_num, func_num; + u32 base; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + base = ddb_access_config_base(swap, bus, slot_num); + *(volatile u32 *) (base + (func_num << 8) + where) = val; + ddb_close_config_base(swap); + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_word(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u16 val) +{ + int status, shift = 0; + u32 result; + + db_assert((where & 1) == 0); + + status = read_config_dword(swap, dev, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + + if (where & 2) + shift += 16; + result &= ~(0xffff << shift); + result |= val << shift; + return write_config_dword(swap, dev, where & ~3, result); +} + +static int write_config_byte(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u8 val) +{ + int status, shift = 0; + u32 result; + + status = read_config_dword(swap, dev, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + + if (where & 2) + shift += 16; + if (where & 1) + shift += 8; + result &= ~(0xff << shift); + result |= val << shift; + return write_config_dword(swap, dev, where & ~3, result); +} + +#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \ +static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \ +{ \ + return rw##_config_##unitname(pciswap, \ + dev, \ + where, \ + val); \ +} + +MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap) + MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap) + MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap) + + MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap) + MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap) + MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap) + +struct pci_ops ddb5476_ext_pci_ops = { + extpci_read_config_byte, + extpci_read_config_word, + extpci_read_config_dword, + extpci_write_config_byte, + extpci_write_config_word, + extpci_write_config_dword +}; + + +#if defined(CONFIG_RUNTIME_DEBUG) +void jsun_scan_pci_bus(void) +{ + struct pci_bus bus; + struct pci_dev dev; + unsigned int devfn; + int j; + + pci_config_workaround = 0; + + bus.parent = NULL; /* we scan the top level only */ + dev.bus = &bus; + dev.sysdata = NULL; + + /* scan ext pci bus and io pci bus */ + for (j = 0; j < 1; j++) { + printk(KERN_INFO "scan ddb5476 external PCI bus:\n"); + bus.ops = &ddb5476_ext_pci_ops; + + for (devfn = 0; devfn < 0x100; devfn += 8) { + u32 temp; + u16 temp16; + u8 temp8; + int i; + + dev.devfn = devfn; + db_verify(pci_read_config_dword(&dev, 0, &temp), + == PCIBIOS_SUCCESSFUL); + if (temp == 0xffffffff) + continue; + + printk(KERN_INFO "slot %d: (addr %d) \n", + devfn / 8, 11 + devfn / 8); + + /* verify read word and byte */ + db_verify(pci_read_config_word(&dev, 2, &temp16), + == PCIBIOS_SUCCESSFUL); + db_assert(temp16 == (temp >> 16)); + db_verify(pci_read_config_byte(&dev, 3, &temp8), + == PCIBIOS_SUCCESSFUL); + db_assert(temp8 == (temp >> 24)); + db_verify(pci_read_config_byte(&dev, 1, &temp8), + == PCIBIOS_SUCCESSFUL); + db_assert(temp8 == ((temp >> 8) & 0xff)); + + for (i = 0; i < 16; i++) { + if ((i % 4) == 0) + printk(KERN_INFO); + db_verify(pci_read_config_dword + (&dev, i * 4, &temp), + == PCIBIOS_SUCCESSFUL); + printk("\t%08X", temp); + if ((i % 4) == 3) + printk("\n"); + } + } + } + + pci_config_workaround = 1; +} +#endif diff -Nru a/arch/mips/pci/ops-ddb5476.c b/arch/mips/pci/ops-ddb5476.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-ddb5476.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,350 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/ddb5xxx/ddb5476/pci_ops.c + * Define the pci_ops for DB5477. + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven <geert@sonycom.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include <linux/config.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/debug.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +/* + * config_swap structure records what set of pdar/pmr are used + * to access pci config space. It also provides a place hold the + * original values for future restoring. + */ +struct pci_config_swap { + u32 pdar; + u32 pmr; + u32 config_base; + u32 config_size; + u32 pdar_backup; + u32 pmr_backup; +}; + +/* + * On DDB5476, we have one set of swap registers + */ +struct pci_config_swap ext_pci_swap = { + DDB_PCIW0, + DDB_PCIINIT0, + DDB_PCI_CONFIG_BASE, + DDB_PCI_CONFIG_SIZE +}; + +static int pci_config_workaround = 1; + +/* + * access config space + */ +static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */ + u32 slot_num) +{ + u32 pci_addr = 0; + u32 pciinit_offset = 0; + u32 virt_addr = swap->config_base; + u32 option; + + if (pci_config_workaround) { + /* [jsun] work around Vrc5476 controller itself, returnning + * slot 0 essentially makes vrc5476 invisible + */ + if (slot_num == 12) + slot_num = 0; + +#if 0 + /* BUG : skip P2P bridge for now */ + if (slot_num == 5) + slot_num = 0; +#endif + + } else { + /* now we have to be hornest, returning the true + * PCI config headers for vrc5476 + */ + if (slot_num == 12) { + swap->pdar_backup = ddb_in32(swap->pdar); + swap->pmr_backup = ddb_in32(swap->pmr); + return DDB_BASE + DDB_PCI_BASE; + } + } + + /* minimum pdar (window) size is 2MB */ + db_assert(swap->config_size >= (2 << 20)); + + db_assert(slot_num < (1 << 5)); + db_assert(bus < (1 << 8)); + + /* backup registers */ + swap->pdar_backup = ddb_in32(swap->pdar); + swap->pmr_backup = ddb_in32(swap->pmr); + + /* set the pdar (pci window) register */ + ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */ + 0, /* not on local memory bus */ + 0); /* not visible from PCI bus (N/A) */ + + /* + * calcuate the absolute pci config addr; + * according to the spec, we start scanning from adr:11 (0x800) + */ + if (bus == 0) { + /* type 0 config */ + pci_addr = 0x800 << slot_num; + } else { + /* type 1 config */ + pci_addr = (bus << 16) | (slot_num << 11); + /* panic("ddb_access_config_base: we don't support type 1 config Yet"); */ + } + + /* + * if pci_addr is less than pci config window size, we set + * pciinit_offset to 0 and adjust the virt_address. + * Otherwise we will try to adjust pciinit_offset. + */ + if (pci_addr < swap->config_size) { + virt_addr = KSEG1ADDR(swap->config_base + pci_addr); + pciinit_offset = 0; + } else { + db_assert((pci_addr & (swap->config_size - 1)) == 0); + virt_addr = KSEG1ADDR(swap->config_base); + pciinit_offset = pci_addr; + } + + /* set the pmr register */ + option = DDB_PCI_ACCESS_32; + if (bus != 0) + option |= DDB_PCI_CFGTYPE1; + ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option); + + return virt_addr; +} + +static inline void ddb_close_config_base(struct pci_config_swap *swap) +{ + ddb_out32(swap->pdar, swap->pdar_backup); + ddb_out32(swap->pmr, swap->pmr_backup); +} + +static int read_config_dword(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u32 * val) +{ + u32 bus, slot_num, func_num; + u32 base; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + base = ddb_access_config_base(swap, bus, slot_num); + *val = *(volatile u32 *) (base + (func_num << 8) + where); + ddb_close_config_base(swap); + return PCIBIOS_SUCCESSFUL; +} + +static int read_config_word(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u16 * val) +{ + int status; + u32 result; + + db_assert((where & 1) == 0); + + status = read_config_dword(swap, dev, where & ~3, &result); + if (where & 2) + result >>= 16; + *val = result & 0xffff; + return status; +} + +static int read_config_byte(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u8 * val) +{ + int status; + u32 result; + + status = read_config_dword(swap, dev, where & ~3, &result); + if (where & 1) + result >>= 8; + if (where & 2) + result >>= 16; + *val = result & 0xff; + return status; +} + +static int write_config_dword(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u32 val) +{ + u32 bus, slot_num, func_num; + u32 base; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + base = ddb_access_config_base(swap, bus, slot_num); + *(volatile u32 *) (base + (func_num << 8) + where) = val; + ddb_close_config_base(swap); + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_word(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u16 val) +{ + int status, shift = 0; + u32 result; + + db_assert((where & 1) == 0); + + status = read_config_dword(swap, dev, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + + if (where & 2) + shift += 16; + result &= ~(0xffff << shift); + result |= val << shift; + return write_config_dword(swap, dev, where & ~3, result); +} + +static int write_config_byte(struct pci_config_swap *swap, + struct pci_dev *dev, u32 where, u8 val) +{ + int status, shift = 0; + u32 result; + + status = read_config_dword(swap, dev, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + + if (where & 2) + shift += 16; + if (where & 1) + shift += 8; + result &= ~(0xff << shift); + result |= val << shift; + return write_config_dword(swap, dev, where & ~3, result); +} + +#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \ +static int prefix##_##rw##_config_##unitname(struct pci_dev *dev, int where, unittype val) \ +{ \ + return rw##_config_##unitname(pciswap, \ + dev, \ + where, \ + val); \ +} + +MAKE_PCI_OPS(extpci, read, byte, u8 *, &ext_pci_swap) + MAKE_PCI_OPS(extpci, read, word, u16 *, &ext_pci_swap) + MAKE_PCI_OPS(extpci, read, dword, u32 *, &ext_pci_swap) + + MAKE_PCI_OPS(extpci, write, byte, u8, &ext_pci_swap) + MAKE_PCI_OPS(extpci, write, word, u16, &ext_pci_swap) + MAKE_PCI_OPS(extpci, write, dword, u32, &ext_pci_swap) + +struct pci_ops ddb5476_ext_pci_ops = { + extpci_read_config_byte, + extpci_read_config_word, + extpci_read_config_dword, + extpci_write_config_byte, + extpci_write_config_word, + extpci_write_config_dword +}; + + +#if defined(CONFIG_RUNTIME_DEBUG) +void jsun_scan_pci_bus(void) +{ + struct pci_bus bus; + struct pci_dev dev; + unsigned int devfn; + int j; + + pci_config_workaround = 0; + + bus.parent = NULL; /* we scan the top level only */ + dev.bus = &bus; + dev.sysdata = NULL; + + /* scan ext pci bus and io pci bus */ + for (j = 0; j < 1; j++) { + printk(KERN_INFO "scan ddb5476 external PCI bus:\n"); + bus.ops = &ddb5476_ext_pci_ops; + + for (devfn = 0; devfn < 0x100; devfn += 8) { + u32 temp; + u16 temp16; + u8 temp8; + int i; + + dev.devfn = devfn; + db_verify(pci_read_config_dword(&dev, 0, &temp), + == PCIBIOS_SUCCESSFUL); + if (temp == 0xffffffff) + continue; + + printk(KERN_INFO "slot %d: (addr %d) \n", + devfn / 8, 11 + devfn / 8); + + /* verify read word and byte */ + db_verify(pci_read_config_word(&dev, 2, &temp16), + == PCIBIOS_SUCCESSFUL); + db_assert(temp16 == (temp >> 16)); + db_verify(pci_read_config_byte(&dev, 3, &temp8), + == PCIBIOS_SUCCESSFUL); + db_assert(temp8 == (temp >> 24)); + db_verify(pci_read_config_byte(&dev, 1, &temp8), + == PCIBIOS_SUCCESSFUL); + db_assert(temp8 == ((temp >> 8) & 0xff)); + + for (i = 0; i < 16; i++) { + if ((i % 4) == 0) + printk(KERN_INFO); + db_verify(pci_read_config_dword + (&dev, i * 4, &temp), + == PCIBIOS_SUCCESSFUL); + printk("\t%08X", temp); + if ((i % 4) == 3) + printk("\n"); + } + } + } + + pci_config_workaround = 1; +} +#endif diff -Nru a/arch/mips/pci/ops-ddb5477.c b/arch/mips/pci/ops-ddb5477.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-ddb5477.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,281 @@ +/*********************************************************************** + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * arch/mips/ddb5xxx/ddb5477/pci_ops.c + * Define the pci_ops for DB5477. + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven <geert@sonycom.com> + * + * 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. + *********************************************************************** + */ + +/* + * DDB5477 has two PCI channels, external PCI and IOPIC (internal) + * Therefore we provide two sets of pci_ops. + */ +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/debug.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +/* + * config_swap structure records what set of pdar/pmr are used + * to access pci config space. It also provides a place hold the + * original values for future restoring. + */ +struct pci_config_swap { + u32 pdar; + u32 pmr; + u32 config_base; + u32 config_size; + u32 pdar_backup; + u32 pmr_backup; +}; + +/* + * On DDB5477, we have two sets of swap registers, for ext PCI and IOPCI. + */ +struct pci_config_swap ext_pci_swap = { + DDB_PCIW0, + DDB_PCIINIT00, + DDB_PCI0_CONFIG_BASE, + DDB_PCI0_CONFIG_SIZE +}; +struct pci_config_swap io_pci_swap = { + DDB_IOPCIW0, + DDB_PCIINIT01, + DDB_PCI1_CONFIG_BASE, + DDB_PCI1_CONFIG_SIZE +}; + + +/* + * access config space + */ +static inline u32 ddb_access_config_base(struct pci_config_swap *swap, u32 bus, /* 0 means top level bus */ + u32 slot_num) +{ + u32 pci_addr = 0; + u32 pciinit_offset = 0; + u32 virt_addr = swap->config_base; + u32 option; + + /* minimum pdar (window) size is 2MB */ + db_assert(swap->config_size >= (2 << 20)); + + db_assert(slot_num < (1 << 5)); + db_assert(bus < (1 << 8)); + + /* backup registers */ + swap->pdar_backup = ddb_in32(swap->pdar); + swap->pmr_backup = ddb_in32(swap->pmr); + + /* set the pdar (pci window) register */ + ddb_set_pdar(swap->pdar, swap->config_base, swap->config_size, 32, /* 32 bit wide */ + 0, /* not on local memory bus */ + 0); /* not visible from PCI bus (N/A) */ + + /* + * calcuate the absolute pci config addr; + * according to the spec, we start scanning from adr:11 (0x800) + */ + if (bus == 0) { + /* type 0 config */ + pci_addr = 0x800 << slot_num; + } else { + /* type 1 config */ + pci_addr = (bus << 16) | (slot_num << 11); + } + + /* + * if pci_addr is less than pci config window size, we set + * pciinit_offset to 0 and adjust the virt_address. + * Otherwise we will try to adjust pciinit_offset. + */ + if (pci_addr < swap->config_size) { + virt_addr = KSEG1ADDR(swap->config_base + pci_addr); + pciinit_offset = 0; + } else { + db_assert((pci_addr & (swap->config_size - 1)) == 0); + virt_addr = KSEG1ADDR(swap->config_base); + pciinit_offset = pci_addr; + } + + /* set the pmr register */ + option = DDB_PCI_ACCESS_32; + if (bus != 0) + option |= DDB_PCI_CFGTYPE1; + ddb_set_pmr(swap->pmr, DDB_PCICMD_CFG, pciinit_offset, option); + + return virt_addr; +} + +static inline void ddb_close_config_base(struct pci_config_swap *swap) +{ + ddb_out32(swap->pdar, swap->pdar_backup); + ddb_out32(swap->pmr, swap->pmr_backup); +} + +static int read_config_dword(struct pci_config_swap *swap, + struct pci_bus *bus, u32 where, u32 * val) +{ + u32 bus, slot_num, func_num; + u32 base; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(dev->devfn); + func_num = PCI_FUNC(dev->devfn); + base = ddb_access_config_base(swap, bus, slot_num); + *val = *(volatile u32 *) (base + (func_num << 8) + where); + ddb_close_config_base(swap); + return PCIBIOS_SUCCESSFUL; +} + +static int read_config_word(struct pci_config_swap *swap, + struct pci_bus *bus, u32 where, u16 * val) +{ + int status; + u32 result; + + db_assert((where & 1) == 0); + + status = read_config_dword(swap, bus, where & ~3, &result); + if (where & 2) + result >>= 16; + *val = result & 0xffff; + return status; +} + +static int read_config_byte(struct pci_config_swap *swap, + struct pci_bus *bus, unsigned int devfn, + u8 * val) +{ + int status; + u32 result; + + status = read_config_dword(swap, bus, where & ~3, &result); + if (where & 1) + result >>= 8; + if (where & 2) + result >>= 16; + *val = result & 0xff; + + return status; +} + +static int write_config_dword(struct pci_config_swap *swap, + struct pci_bus *bus, unsigned int devfn, + u32 val) +{ + u32 busno, slot_num, func_num; + u32 base; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (bus->parent != NULL) { + busno = bus->number; + db_assert(busno != 0); + } else { + busno = 0; + } + + slot_num = PCI_SLOT(devfn); + func_num = PCI_FUNC(devfn); + base = ddb_access_config_base(swap, busno, slot_num); + *(volatile u32 *) (base + (func_num << 8) + where) = val; + ddb_close_config_base(swap); + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_word(struct pci_config_swap *swap, + struct pci_bus *bus, unsigned int devfn, + int where, u16 val) +{ + int status, shift = 0; + u32 result; + + db_assert((where & 1) == 0); + + status = read_config_dword(swap, dev, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + + if (where & 2) + shift += 16; + result &= ~(0xffff << shift); + result |= val << shift; + return write_config_dword(swap, dev, where & ~3, result); +} + +static int write_config_byte(struct pci_config_swap *swap, + struct pci_bus *bus, unsigned int devfn, + int where, u8 val) +{ + int status, shift = 0; + u32 result; + + status = read_config_dword(swap, dev, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) + return status; + + if (where & 2) + shift += 16; + if (where & 1) + shift += 8; + result &= ~(0xff << shift); + result |= val << shift; + return write_config_dword(swap, dev, where & ~3, result); +} + +/* + * Dump solution for now so I don't break hw I can't test on ... + */ +#define MAKE_PCI_OPS(prefix, rw, unitname, unittype, pciswap) \ +static int prefix##_##rw##_config(struct pci_bus *bus, int where, int size, unittype val) \ +{ \ + if (size == 1) \ + return rw##_config_byte(pciswap, bus, where, val); \ + else if (size == 2) \ + return rw##_config_word(pciswap, bus, where, val); \ + /* Size must be 4 */ \ + return rw##_config_dword(pciswap, bus, where, val); \ +} + +MAKE_PCI_OPS(extpci, read, &ext_pci_swap) + MAKE_PCI_OPS(extpci, write, &ext_pci_swap) + + MAKE_PCI_OPS(iopci, read, &io_pci_swap) + MAKE_PCI_OPS(iopci, write, &io_pci_swap) + +struct pci_ops ddb5477_ext_pci_ops = { + .read = extpci_read_config, + .write = extpci_write_config +}; + + +struct pci_ops ddb5477_io_pci_ops = { + .read = iopci_read_config, + .write = iopci_write_config +}; diff -Nru a/arch/mips/pci/ops-ev64120.c b/arch/mips/pci/ops-ev64120.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-ev64120.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1201 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo Evaluation Boards PCI support. + * + * The general-purpose functions to read/write and configure the GT64120A's + * PCI registers (function names start with pci0 or pci1) are either direct + * copies of functions written by Galileo Technology, or are modifications + * of their functions to work with Linux 2.4 vs Linux 2.2. These functions + * are Copyright - Galileo Technology. + * + * Other functions are derived from other MIPS PCI implementations, or were + * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/version.h> +#include <asm/pci.h> +#include <asm/io.h> +#include <asm/galileo-boards/ev64120.h> +#include <asm/gt64120.h> + +#include <linux/init.h> + +#undef PCI_DEBUG + +#ifdef PCI_DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define SELF 0 + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +struct pci_device { + u32 slot; + u32 BARtype[6]; + u32 BARsize[6]; +}; + +static void __init scan_and_initialize_pci(void); +static u32 __init scan_pci_bus(struct pci_device *pci_devices); +static void __init allocate_pci_space(struct pci_device *pci_devices); + +static void __devinit galileo_pcibios_fixup_bus(struct pci_bus *bus); + +/* + * The functions that actually read and write to the controller. + * Copied from or modified from Galileo Technology code. + */ +static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device); +static void pci0WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data); +static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device); +static void pci1WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data); + +static void pci0MapIOspace(unsigned int pci0IoBase, + unsigned int pci0IoLength); +static void pci1MapIOspace(unsigned int pci1IoBase, + unsigned int pci1IoLength); +static void pci0MapMemory0space(unsigned int pci0Mem0Base, + unsigned int pci0Mem0Length); +static void pci1MapMemory0space(unsigned int pci1Mem0Base, + unsigned int pci1Mem0Length); +static void pci0MapMemory1space(unsigned int pci0Mem1Base, + unsigned int pci0Mem1Length); +static void pci1MapMemory1space(unsigned int pci1Mem1Base, + unsigned int pci1Mem1Length); +static unsigned int pci0GetIOspaceBase(void); +static unsigned int pci0GetIOspaceSize(void); +static unsigned int pci0GetMemory0Base(void); +static unsigned int pci0GetMemory0Size(void); +static unsigned int pci0GetMemory1Base(void); +static unsigned int pci0GetMemory1Size(void); +static unsigned int pci1GetIOspaceBase(void); +static unsigned int pci1GetIOspaceSize(void); +static unsigned int pci1GetMemory0Base(void); +static unsigned int pci1GetMemory0Size(void); +static unsigned int pci1GetMemory1Base(void); +static unsigned int pci1GetMemory1Size(void); + + +/* Functions to implement "pci ops" */ +static int galileo_pcibios_read_config_word(struct pci_dev *dev, + int offset, u16 * val); +static int galileo_pcibios_read_config_byte(struct pci_dev *dev, + int offset, u8 * val); +static int galileo_pcibios_read_config_dword(struct pci_dev *dev, + int offset, u32 * val); +static int galileo_pcibios_write_config_byte(struct pci_dev *dev, + int offset, u8 val); +static int galileo_pcibios_write_config_word(struct pci_dev *dev, + int offset, u16 val); +static int galileo_pcibios_write_config_dword(struct pci_dev *dev, + int offset, u32 val); +static void galileo_pcibios_set_master(struct pci_dev *dev); + +/* + * General-purpose PCI functions. + */ + +/* + * pci0MapIOspace - Maps PCI0 IO space for the master. + * Inputs: base and length of pci0Io + */ +static void pci0MapIOspace(unsigned int pci0IoBase, + unsigned int pci0IoLength) +{ + unsigned int pci0IoTop = + (unsigned int) (pci0IoBase + pci0IoLength); + + if (pci0IoLength == 0) + pci0IoTop++; + + pci0IoBase = (unsigned int) (pci0IoBase >> 21); + pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); + GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase); + GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop); +} + +/* + * pci1MapIOspace - Maps PCI1 IO space for the master. + * Inputs: base and length of pci1Io + */ + +static void pci1MapIOspace(unsigned int pci1IoBase, + unsigned int pci1IoLength) +{ + unsigned int pci1IoTop = + (unsigned int) (pci1IoBase + pci1IoLength); + + if (pci1IoLength == 0) + pci1IoTop++; + + pci1IoBase = (unsigned int) (pci1IoBase >> 21); + pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); + GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase); + GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop); +} + +/* + * pci0MapMemory0space - Maps PCI0 memory0 space for the master. + * Inputs: base and length of pci0Mem0 + */ + +static void pci0MapMemory0space(unsigned int pci0Mem0Base, + unsigned int pci0Mem0Length) +{ + unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; + + if (pci0Mem0Length == 0) + pci0Mem0Top++; + + pci0Mem0Base = pci0Mem0Base >> 21; + pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base); + GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top); +} + +/* + * pci1MapMemory0space - Maps PCI1 memory0 space for the master. + * Inputs: base and length of pci1Mem0 + */ + +static void pci1MapMemory0space(unsigned int pci1Mem0Base, + unsigned int pci1Mem0Length) +{ + unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; + + if (pci1Mem0Length == 0) + pci1Mem0Top++; + + pci1Mem0Base = pci1Mem0Base >> 21; + pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base); + GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top); +} + +/* + * pci0MapMemory1space - Maps PCI0 memory1 space for the master. + * Inputs: base and length of pci0Mem1 + */ + +static void pci0MapMemory1space(unsigned int pci0Mem1Base, + unsigned int pci0Mem1Length) +{ + unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; + + if (pci0Mem1Length == 0) + pci0Mem1Top++; + + pci0Mem1Base = pci0Mem1Base >> 21; + pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base); + GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top); + +} + +/* + * pci1MapMemory1space - Maps PCI1 memory1 space for the master. + * Inputs: base and length of pci1Mem1 + */ + +static void pci1MapMemory1space(unsigned int pci1Mem1Base, + unsigned int pci1Mem1Length) +{ + unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; + + if (pci1Mem1Length == 0) + pci1Mem1Top++; + + pci1Mem1Base = pci1Mem1Base >> 21; + pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base); + GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top); +} + +/* + * pci0GetIOspaceBase - Return PCI0 IO Base Address. + * Inputs: N/A + * Returns: PCI0 IO Base Address. + */ + +static unsigned int pci0GetIOspaceBase(void) +{ + unsigned int base; + GT_READ(GT_PCI0IOLD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci0GetIOspaceSize - Return PCI0 IO Bar Size. + * Inputs: N/A + * Returns: PCI0 IO Bar Size. + */ +static unsigned int pci0GetIOspaceSize(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI0IOLD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI0IOHD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. + * Inputs: N/A + * Returns: PCI0 Memory 0 Base Address. + */ +static unsigned int pci0GetMemory0Base(void) +{ + unsigned int base; + GT_READ(GT_PCI0M0LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. + * Inputs: N/A + * Returns: PCI0 Memory 0 Bar Size. + */ +static unsigned int pci0GetMemory0Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI0M0LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI0M0HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. + * Inputs: N/A + * Returns: PCI0 Memory 1 Base Address. + */ +static unsigned int pci0GetMemory1Base(void) +{ + unsigned int base; + GT_READ(GT_PCI0M1LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. + * Inputs: N/A + * Returns: PCI0 Memory 1 Bar Size. + */ + +static unsigned int pci0GetMemory1Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI0M1LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI0M1HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci1GetIOspaceBase - Return PCI1 IO Base Address. + * Inputs: N/A + * Returns: PCI1 IO Base Address. + */ + +static unsigned int pci1GetIOspaceBase(void) +{ + unsigned int base; + GT_READ(GT_PCI1IOLD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci1GetIOspaceSize - Return PCI1 IO Bar Size. + * Inputs: N/A + * Returns: PCI1 IO Bar Size. + */ + +static unsigned int pci1GetIOspaceSize(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI1IOLD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI1IOHD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. + * Inputs: N/A + * Returns: PCI1 Memory 0 Base Address. + */ + +static unsigned int pci1GetMemory0Base(void) +{ + unsigned int base; + GT_READ(GT_PCI1M0LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. + * Inputs: N/A + * Returns: PCI1 Memory 0 Bar Size. + */ + +static unsigned int pci1GetMemory0Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI1M1LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI1M1HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. + * Inputs: N/A + * Returns: PCI1 Memory 1 Base Address. + */ + +static unsigned int pci1GetMemory1Base(void) +{ + unsigned int base; + GT_READ(GT_PCI1M1LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. + * Inputs: N/A + * Returns: PCI1 Memory 1 Bar Size. + */ + +static unsigned int pci1GetMemory1Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI1M1LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI1M1HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + //DBG(KERN_INFO "p_r_c %d %d\n",bus,dev); + if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) + return 0; // Bus/Device Number OK + return -1; // Bus/Device Number not OK +} + +/* + * pciXReadConfigReg - Read from a PCI configuration register + * - Make sure the GT is configured as a master before + * reading from another device on the PCI. + * - The function takes care of Big/Little endian conversion. + * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI + * spec) + * pciDevNum: The device number needs to be addressed. + * RETURNS: data , if the data == 0xffffffff check the master abort bit in the + * cause register to make sure the data is valid + * + * Configuration Address 0xCF8: + * + * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number + * |congif|Reserved| Bus |Device|Function|Register|00| + * |Enable| |Number|Number| Number | Number | | <=field Name + * + */ +static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device) +{ + unsigned int DataForRegCf8; + unsigned int data; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + + /* The casual observer might wonder why the READ is duplicated here, + rather than immediately following the WRITE, and just have the + swap in the "if". That's because there is a latency problem + with trying to read immediately after setting up the address + register. The "if" check gives enough time for the address + to stabilize, so the READ can work. + */ + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_READ(GT_PCI0_CFGDATA_OFS, &data); + return data; + } else { /* The PCI is working in LE Mode so swap the Data. */ + GT_READ(GT_PCI0_CFGDATA_OFS, &data); + return cpu_to_le32(data); + } +} + +static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device) +{ + unsigned int DataForRegCf8; + unsigned int data; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + /* The casual observer might wonder why the READ is duplicated here, + rather than immediately following the WRITE, and just have the + swap in the "if". That's because there is a latency problem + with trying to read immediately after setting up the address + register. The "if" check gives enough time for the address + to stabilize, so the READ can work. + */ + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + /* when configurating our own PCI 1 L-unit the access is through + the PCI 0 interface with reg number = reg number + 0x80 */ + DataForRegCf8 |= 0x80; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + } else { /* The PCI is working in LE Mode so swap the Data. */ + GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); + } + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_READ(GT_PCI0_CFGDATA_OFS, &data); + return data; + } else { + GT_READ(GT_PCI1_CFGDATA_OFS, &data); + return cpu_to_le32(data); + } +} + + + +/* + * pciXWriteConfigReg - Write to a PCI configuration register + * - Make sure the GT is configured as a master before + * writingto another device on the PCI. + * - The function takes care of Big/Little endian conversion. + * Inputs: unsigned int regOffset: The register offset as it apears in the + * GT spec + * (or any other PCI device spec) + * pciDevNum: The device number needs to be addressed. + * + * Configuration Address 0xCF8: + * + * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number + * |congif|Reserved| Bus |Device|Function|Register|00| + * |Enable| |Number|Number| Number | Number | | <=field Name + * + */ +static void pci0WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data) +{ + unsigned int DataForRegCf8; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, data); + } else { /* configuration Transaction over the pci. */ + /* The PCI is working in LE Mode so swap the Data. */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data)); + } +} + +static void pci1WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data) +{ + unsigned int DataForRegCf8; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + /* There is a latency problem + with trying to read immediately after setting up the address + register. The "if" check gives enough time for the address + to stabilize, so the WRITE can work. + */ + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + /* when configurating our own PCI 1 L-unit the access is through + the PCI 0 interface with reg number = reg number + 0x80 */ + DataForRegCf8 |= 0x80; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + } else { /* configuration Transaction over the pci. */ + /* The PCI is working in LE Mode so swap the Data. */ + GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); + } + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, data); + } else { /* configuration Transaction over the pci. */ + GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data)); + } +} + + +/* + * galileo_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int galileo_pcibios_read_config_dword(struct pci_dev *device, + int offset, u32 * val) +{ + int dev, bus; + //DBG(KERN_INFO "rcd entry \n",offset,val); + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + + if (pci_range_ck(bus, dev)) { + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + if (offset & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (bus == 0) + *val = pci0ReadConfigReg(offset, device); +// if (bus == 1) *val = pci1ReadConfigReg (offset,device); + DBG(KERN_INFO "rr: rcd dev %d offset %x %x\n", dev, offset, *val); + + /* + * This is so that the upper PCI layer will get the correct return + * value if we're not attached to anything. + */ + if ((offset == 0) && (*val == 0xffffffff)) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_read_config_word(struct pci_dev *device, + int offset, u16 * val) +{ + int dev, bus; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + + if (pci_range_ck(bus, dev)) { + *val = 0xffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + if (offset & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (bus == 0) + *val = + (unsigned short) (pci0ReadConfigReg(offset, device) >> + ((offset & ~0x3) * 8)); +// if (bus == 1) *val = (unsigned short) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8)); + + DBG(KERN_INFO "rr: rcw dev %d offset %x %x\n", dev, offset, *val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_read_config_byte(struct pci_dev *device, + int offset, u8 * val) +{ + int dev, bus; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + + if (pci_range_ck(bus, dev)) { + *val = 0xff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + + if (bus == 0) + *val = + (unsigned char) (pci0ReadConfigReg(offset, device) >> + ((offset & ~0x3) * 8)); +// if (bus == 1) *val = (unsigned char) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8)); + + DBG(KERN_INFO "rr: rcb dev %d offset %x %x\n", dev, offset, *val); + + /* This is so that the upper PCI layer will get the correct return value if + we're not attached to anything. */ + if ((offset == 0xe) && (*val == 0xff)) { + u32 MasterAbort; + GT_READ(GT_INTRCAUSE_OFS, &MasterAbort); + if (MasterAbort & 0x40000) { + DBG(KERN_INFO "PCI Master Abort, ICR %x\n", + MasterAbort); + GT_WRITE(GT_INTRCAUSE_OFS, + (MasterAbort & 0xfffbffff)); + return PCIBIOS_DEVICE_NOT_FOUND; + } + } + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write_config_dword(struct pci_dev *device, + int offset, u32 val) +{ + int dev, bus; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + if (offset & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (bus == 0) + pci0WriteConfigReg(offset, device, val); +// if (bus == 1) pci1WriteConfigReg (offset,device,val); + + DBG(KERN_INFO "rr: wcd dev %d, offset %x, val %x\n", dev, offset, + val); + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_pcibios_write_config_word(struct pci_dev *device, + int offset, u16 val) +{ + int dev, bus; + unsigned long tmp; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + if (offset & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (bus == 0) + tmp = pci0ReadConfigReg(offset, device); +// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); + + if ((offset % 4) == 0) + tmp = (tmp & 0xffff0000) | (val & 0xffff); + if ((offset % 4) == 2) + tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16); + + if (bus == 0) + pci0WriteConfigReg(offset, device, tmp); +// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); + DBG(KERN_INFO "rr: wcw dev %d, offset %x, val %x\n", dev, offset, + val); + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write_config_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus; + unsigned long tmp; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + if (bus == 0) + tmp = pci0ReadConfigReg(offset, device); +// if (bus == 1) tmp = pci1ReadConfigReg (offset,device); + + if ((offset % 4) == 0) + tmp = (tmp & 0xffffff00) | (val & 0xff); + if ((offset % 4) == 1) + tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8); + if ((offset % 4) == 2) + tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16); + if ((offset % 4) == 3) + tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24); + + if (bus == 0) + pci0WriteConfigReg(offset, device, tmp); +// if (bus == 1) pci1WriteConfigReg (offset,device,tmp); + DBG(KERN_INFO "rr: wcb dev %d, offset %x, val %x\n", dev, offset, + val); + + return PCIBIOS_SUCCESSFUL; +} + +static void galileo_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + + DBG(KERN_INFO "rr: galileo_pcibios_set_master\n"); + + galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); + DBG("PCI: Enabling device %s (%04x)\n", dev->slot_name, cmd); +} + +/* Externally-expected functions. Do not change function names */ + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u16 tmp; + u8 tmp1; + int idx; + struct resource *r; + + DBG(KERN_INFO "rr: pcibios_enable_resources\n"); + + galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + DBG(KERN_INFO + "rr: BAR %d, start %lx, end %lx, flags %lx\n", idx, + r->start, r->end, r->flags); + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of resource collisions\n", + dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + DBG(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", + dev->slot_name, old_cmd, cmd); + galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); + } + + /* + Let's fix up the latency timer and cache line size here. Cache line size = + 32 bytes / sizeof dword (4) = 8. + Latency timer must be > 8. 32 is random but appears to work. + */ + galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); + if (tmp1 != 8) { + DBG(KERN_INFO + "rr: PCI setting cache line size to 8 from %d\n", + tmp1); + galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + 8); + } + galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); + if (tmp1 < 32) { + DBG(KERN_INFO + "rr: PCI setting latency timer to 32 from %d\n", tmp1); + galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, + 32); + } + + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + DBG(KERN_INFO "rr: pcibios_enable_device\n"); + return pcibios_enable_resources(dev); +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + DBG(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} + +/* + * structure galileo_pci_ops + * + * This structure holds the pointers for the PCI configuration space + * access, and the fixup for the interrupts. + * This structure is registered to the operating system in boot time + */ +struct pci_ops galileo_pci_ops = { + galileo_pcibios_read_config_byte, + galileo_pcibios_read_config_word, + galileo_pcibios_read_config_dword, + galileo_pcibios_write_config_byte, + galileo_pcibios_write_config_word, + galileo_pcibios_write_config_dword +}; + +/* + * galileo_pcibios_fixup_bus - + * + * After detecting all agents over the PCI , this function is called + * in order to give an interrupt number for each PCI device starting + * from IRQ 20. It does also enables master for each device. + * + * Inputs : + * mem_start , mem_end are not relevant in MIPS architecture. + * + * Outpus : + * return always mem_start + */ +static void __devinit galileo_pcibios_fixup_bus(struct pci_bus *bus) +{ + unsigned int Current_IRQ = 20; + struct pci_bus *current_bus = bus; + struct pci_dev *devices; + struct list_head *devices_link; + + list_for_each(devices_link, &(current_bus->devices)) { + devices = pci_dev_b(devices_link); + if (devices != NULL) { + devices->irq = Current_IRQ++; + + /* Assign an interrupt number for the device */ + galileo_pcibios_write_config_byte(devices, + PCI_INTERRUPT_LINE, + Current_IRQ); + galileo_pcibios_set_master(devices); + + } + } + +} + +struct pci_fixup pcibios_fixups[] = { +// { PCI_FIXUP_HEADER, 0x4620, 0x11ab, galileo_pcibios_fixup }, + {0} +}; + +void __devinit pcibios_fixup_bus(struct pci_bus *c) +{ + DBG(KERN_INFO "rr: pcibios_fixup_bus\n"); + galileo_pcibios_fixup_bus(c); +} + +/* + * This code was derived from Galileo Technology's example + * and significantly reworked. + * + * This is very simple. It does not scan multiple function devices. It does + * not scan behind bridges. Those would be simple to implement, but we don't + * currently need this. + */ +static void __init scan_and_initialize_pci(void) +{ + struct pci_device pci_devices[MAX_PCI_DEVS]; + + if (scan_pci_bus(pci_devices)) { + allocate_pci_space(pci_devices); + } +} + +/* + * This is your basic PCI scan. It goes through each slot and checks to + * see if there's something that responds. If so, then get the size and + * type of each of the responding BARs. Save them for later. + */ + +static u32 __init scan_pci_bus(struct pci_device *pci_devices) +{ + u32 arrayCounter = 0; + u32 memType; + u32 memSize; + u32 pci_slot, bar; + u32 id; + u32 c18RegValue; + struct pci_dev device; + + DBG(KERN_INFO "rr: scan_pci_bus\n"); + + /* + According to PCI REV 2.1 MAX agents on the bus are 21. + We don't bother scanning ourselves (slot 0). + */ + for (pci_slot = 1; pci_slot < 22; pci_slot++) { + + device.devfn = PCI_DEVFN(pci_slot, 0); + id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); + + /* Check for a PCI Master Abort (nothing responds in the slot) */ + GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); + /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */ + GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); + if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { + DBG(KERN_INFO "rr: found device %x, slot %d\n", id, + pci_slot); + pci_devices[arrayCounter].slot = pci_slot; + for (bar = 0; bar < 6; bar++) { + memType = + pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + + (bar * 4), &device); + pci_devices[arrayCounter].BARtype[bar] = + memType & 1; + pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + + (bar * 4), &device, + 0xffffffff); + memSize = + pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + + (bar * 4), &device); + if (memType & 1) { /* IO space */ + pci_devices[arrayCounter]. + BARsize[bar] = + ~(memSize & 0xfffffffc) + 1; + } else { /* memory space */ + pci_devices[arrayCounter]. + BARsize[bar] = + ~(memSize & 0xfffffff0) + 1; + } + DBG(KERN_INFO + "rr: BAR %d, type %d, size %x\n", bar, + (memType & 1), + pci_devices[arrayCounter]. + BARsize[bar]); + } /* BAR counter */ + + arrayCounter++; + } + /* found a device */ + } /* slot counter */ + + DBG(KERN_INFO "rr: found %d devices\n", arrayCounter); + if (arrayCounter < MAX_PCI_DEVS) { + pci_devices[arrayCounter].slot = -1; + } + return (arrayCounter); +} + +#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1)) +#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2)) + +/* + * This function goes through the list of devices and allocates the BARs in + * either IO or MEM space. It does it in order of size, which will limit the + * amount of fragmentation we have in the IO and MEM spaces. + */ + +static void __init allocate_pci_space(struct pci_device *pci_devices) +{ + u32 count, maxcount, bar; + u32 maxSize, maxDevice, maxBAR; + u32 alignto; + u32 base; + u32 pci0_mem_base = pci0GetMemory0Base(); + u32 pci0_io_base = pci0GetIOspaceBase(); + struct pci_dev device; + + DBG(KERN_INFO "rr: allocate_pci_space\n"); + + DBG(KERN_INFO "pci0_io_base %x\n", pci0_io_base); + DBG(KERN_INFO "pci0_mem_base %x\n", pci0_mem_base); + + /* How many PCI devices do we have? */ + maxcount = MAX_PCI_DEVS; + for (count = 0; count < MAX_PCI_DEVS; count++) { + if (pci_devices[count].slot == -1) { + maxcount = count; + break; + } + } + +// DBG(KERN_INFO "Found %d devices\n", maxcount); + + do { + /* Find the largest size BAR we need to allocate */ + maxSize = 0; + for (count = 0; count < maxcount; count++) { + for (bar = 0; bar < 6; bar++) { + if (pci_devices[count].BARsize[bar] > + maxSize) { + maxSize = + pci_devices[count]. + BARsize[bar]; + maxDevice = count; + maxBAR = bar; + } + } + } + + /* + We've found the largest BAR. Allocate it into IO or + mem space. We don't idiot check the bases to make + sure they haven't overflowed the current size for that aperture. + + Don't bother to enable the device's IO or MEM space here. That will + be done in pci_enable_resources if the device is activated by a driver. + */ + if (maxSize) { + device.devfn = + PCI_DEVFN(pci_devices[maxDevice].slot, 0); + if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { + alignto = MAX(0x1000, maxSize); + base = ALIGN(pci0_io_base, alignto); + pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + + (maxBAR * 4), &device, + base | 0x1); + pci0_io_base = base + alignto; + DBG(KERN_INFO + "Device %d BAR %d address %x\n", + pci_devices[maxDevice].slot, maxBAR, + base); + DBG(KERN_INFO "New IO base %x\n", + pci0_io_base); + } else { + alignto = MAX(0x1000, maxSize); + base = ALIGN(pci0_mem_base, alignto); + pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + + (maxBAR * 4), &device, + base); + pci0_mem_base = base + alignto; + DBG(KERN_INFO + "Device %d BAR %d address %x\n", + pci_devices[maxDevice].slot, maxBAR, + base); + DBG(KERN_INFO "New mem base %x\n", + pci0_mem_base); + } + /* + This entry is finished. Remove it from the list we'll scan. + */ + pci_devices[maxDevice].BARsize[maxBAR] = 0; + } + } while (maxSize); +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +static int __init pcibios_init(void) +{ + + u32 tmp; + struct pci_dev controller; + + controller.devfn = SELF; + + DBG(KERN_INFO "rr: pcibios_init\n"); + GT_READ(GT_PCI0_CMD_OFS, &tmp); + DBG(KERN_INFO "rr: PCI0 command - %x\n", tmp); + GT_READ(GT_PCI0_BARE_OFS, &tmp); + DBG(KERN_INFO "rr: BAR0 - %x\n", tmp); + + /* + * You have to enable bus mastering to configure any other + * card on the bus. + */ + tmp = pci0ReadConfigReg(PCI_COMMAND, &controller); + DBG(KERN_INFO "rr: command/status - %x\n", tmp); + tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; + DBG(KERN_INFO "rr: new command/status - %x\n", tmp); + pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); + + /* This scans the PCI bus and sets up initial values. */ + scan_and_initialize_pci(); + + /* + * Reset PCI I/O and PCI MEM values to ones supported by EVM. + */ + ioport_resource.start = 0x10000000; + ioport_resource.end = 0x11ffffff; /* 32 MB */ + iomem_resource.start = 0x12000000; + iomem_resource.end = 0x13ffffff; /* 32 MB */ + + pci_scan_bus(0, &galileo_pci_ops, NULL); + + return 0; +} + +subsys_initcall(pcibios_init); + +char *pcibios_setup(char *str) +{ + printk(KERN_INFO "rr: pcibios_setup\n"); + /* Nothing to do for now. */ + + return str; +} diff -Nru a/arch/mips/pci/ops-ev96100.c b/arch/mips/pci/ops-ev96100.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-ev96100.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,264 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 board specific pci support. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/pci.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/delay.h> +#include <asm //gt64120.h> +#include <asm/galileo-boards/ev96100.h> +#include <asm/pci_channel.h> + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#undef DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define GT_PCI_MEM_BASE 0x12000000 +#define GT_PCI_MEM_SIZE 0x02000000 +#define GT_PCI_IO_BASE 0x10000000 +#define GT_PCI_IO_SIZE 0x02000000 +static struct resource pci_io_resource = { + "io pci IO space", + 0x10000000, + 0x10000000 + 0x02000000, + IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + "ext pci memory space", + 0x12000000, + 0x12000000 + 0x02000000, + IORESOURCE_MEM +}; + +extern struct pci_ops gt96100_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {>96100_pci_ops, &pci_io_resource, &pci_mem_resource, 1, 0xff}, + {NULL, NULL, NULL, NULL, NULL} +}; + +int +static gt96100_config_access(unsigned char access_type, + struct pci_dev *dev, unsigned char where, + u32 * data) +{ + unsigned char bus = dev->bus->number; + unsigned char dev_fn = dev->devfn; + u32 intr; + + + if ((bus == 0) && (dev_fn >= PCI_DEVFN(31, 0))) { + return -1; /* Because of a bug in the galileo (for slot 31). */ + } + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + + + if (access_type == PCI_ACCESS_WRITE) { + if (dev_fn != 0) { + *data = le32_to_cpu(*data); + } + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + GT_READ(GT_PCI0_CFGDATA_OFS, *data); + if (dev_fn != 0) { + *data = le32_to_cpu(*data); + } + } + + udelay(2); + + /* Check for master or target abort */ + GT_READ(GT_INTRCAUSE_OFS, intr); + + if (intr & + (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) { + //printk("config access error: %x:%x\n", dev_fn,where); + /* Error occured */ + + /* Clear bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + if (access_type == PCI_ACCESS_READ) { + *data = 0xffffffff; + } + return -1; + } + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int read_config_byte(struct pci_dev *dev, int where, u8 * val) +{ + u32 data = 0; + + if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { + *val = 0xff; + return -1; + } + + *val = (data >> ((where & 3) << 3)) & 0xff; + DBG("cfg read byte: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, *val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int read_config_word(struct pci_dev *dev, int where, u16 * val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { + *val = 0xffff; + return -1; + } + + *val = (data >> ((where & 3) << 3)) & 0xffff; + DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, *val); + + return PCIBIOS_SUCCESSFUL; +} + +static int read_config_dword(struct pci_dev *dev, int where, u32 * val) +{ + u32 data = 0; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) { + *val = 0xffffffff; + return -1; + } + + *val = data; + DBG("cfg read dword: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, *val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int write_config_byte(struct pci_dev *dev, int where, u8 val) +{ + u32 data = 0; + + if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + DBG("cfg write byte: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, val); + + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_word(struct pci_dev *dev, int where, u16 val) +{ + u32 data = 0; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt96100_config_access(PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + DBG("cfg write word: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, val); + + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; +} + +static int write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + DBG("cfg write dword: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, val); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops gt96100_pci_ops = { + read_config_byte, + read_config_word, + read_config_dword, + write_config_byte, + write_config_word, + write_config_dword +}; diff -Nru a/arch/mips/pci/ops-it8172.c b/arch/mips/pci/ops-it8172.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-it8172.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,219 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * IT8172 system controller specific pci support. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/pci_channel.h> +#include <asm/it8172/it8172.h> +#include <asm/it8172/it8172_pci.h> + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +static struct resource pci_mem_resource_1; + +static struct resource pci_io_resource = { + "io pci IO space", + 0x14018000, + 0x17FFFFFF, + IORESOURCE_IO +}; + +static struct resource pci_mem_resource_0 = { + "ext pci memory space 0/1", + 0x10101000, + 0x13FFFFFF, + IORESOURCE_MEM, + &pci_mem_resource_0, + NULL, + &pci_mem_resource_1 +}; + +static struct resource pci_mem_resource_1 = { + "ext pci memory space 2/3", + 0x1A000000, + 0x1FBFFFFF, + IORESOURCE_MEM, + &pci_mem_resource_0, + NULL, + NULL +}; + +extern struct pci_ops it8172_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&it8172_pci_ops, &pci_io_resource, &pci_mem_resource_0, 0x10, + 0xff}, + {NULL, NULL, NULL, NULL, NULL} +}; + +static int it8172_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 * data) +{ + /* + * config cycles are on 4 byte boundary only + */ + + /* Setup address */ + IT_WRITE(IT_CONFADDR, (bus->number << IT_BUSNUM_SHF) | + (devfn << IT_FUNCNUM_SHF) | (where & ~0x3)); + + if (access_type == PCI_ACCESS_WRITE) { + IT_WRITE(IT_CONFDATA, *data); + } else { + IT_READ(IT_CONFDATA, *data); + } + + /* + * Revisit: check for master or target abort. + */ + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + u32 data = 0; + + switch (size) { + case 1: + if (it8172_pcibios_config_access + (PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xff; + + return PCIBIOS_SUCCESSFUL; + + case 2: + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (it8172_pcibios_config_access + (PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = (data >> ((where & 3) << 3)) & 0xffff; + DBG("cfg read word: bus %d dev_fn %x where %x: val %x\n", + dev->bus->number, dev->devfn, where, *val); + + return PCIBIOS_SUCCESSFUL; + + case 4: + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (it8172_pcibios_config_access + (PCI_ACCESS_READ, dev, where, &data)) + return -1; + + *val = data; + + return PCIBIOS_SUCCESSFUL; + } +} + + +static write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + u32 data = 0; + + switch (size) { + case 1: + if (it8172_pcibios_config_access + (PCI_ACCESS_READ, dev, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (it8172_pcibios_config_access + (PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; + + case 2: + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (it8172_pcibios_config_access + (PCI_ACCESS_READ, dev, where, &data)) + eturn - 1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (it8172_pcibios_config_access + (PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; + + case 4: + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (it8172_pcibios_config_access + (PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; + } +} + +struct pci_ops it8172_pci_ops = { + .read = read_config, + .write = write_config, +}; + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/ops-jmr3927.c b/arch/mips/pci/ops-jmr3927.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-jmr3927.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,491 @@ +/*********************************************************************** + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c + * + * Define the pci_ops for JMR3927. + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven <geert@sonycom.com> + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/addrspace.h> +#include <asm/pci_channel.h> +#include <asm/jmr3927/jmr3927.h> +#include <asm/debug.h> + +struct resource pci_io_resource = { + "pci IO space", + 0x1000, /* reserve regacy I/O space */ + 0x1000 + JMR3927_PCIIO_SIZE - 1, + IORESOURCE_IO +}; + +struct resource pci_mem_resource = { + "pci memory space", + JMR3927_PCIMEM, + JMR3927_PCIMEM + JMR3927_PCIMEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops jmr3927_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&jmr3927_pci_ops, &pci_io_resource, &pci_mem_resource, 0, 0xff}, + {NULL, NULL, NULL, NULL, NULL} +}; + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +static int +mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, + int *flagsp) +{ + if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0)) + return -1; + + tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + /* clear M_ABORT and Disable M_ABORT Int. */ + tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; + tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT; + return 0; +} + +static int check_abort(int flags) +{ + int code = PCIBIOS_SUCCESSFUL; + if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT) { + tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT; + tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT; + code = PCIBIOS_DEVICE_NOT_FOUND; + } + return code; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int jmr3927_pcibios_read_config_byte(struct pci_dev *dev, + int where, unsigned char *val) +{ + int flags; + unsigned char bus, func_num; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *val = + *(volatile u8 *) ((ulong) & tx3927_pcicptr->icd | (where & 3)); + return check_abort(flags); +} + +static int jmr3927_pcibios_read_config_word(struct pci_dev *dev, + int where, unsigned short *val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *val = + le16_to_cpu(*(volatile u16 *) + ((ulong) & tx3927_pcicptr->icd | (where & 3))); + return check_abort(flags); +} + +static int jmr3927_pcibios_read_config_dword(struct pci_dev *dev, + int where, unsigned int *val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *val = le32_to_cpu(tx3927_pcicptr->icd); + return check_abort(flags); +} + +static int jmr3927_pcibios_write_config_byte(struct pci_dev *dev, + int where, unsigned char val) +{ + int flags; + unsigned char bus, func_num; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *(volatile u8 *) ((ulong) & tx3927_pcicptr->icd | (where & 3)) = + val; + return check_abort(flags); +} + +static int jmr3927_pcibios_write_config_word(struct pci_dev *dev, + int where, unsigned short val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *(volatile u16 *) ((ulong) & tx3927_pcicptr->icd | (where & 3)) = + cpu_to_le16(val); + return check_abort(flags); +} + +static int jmr3927_pcibios_write_config_dword(struct pci_dev *dev, + int where, unsigned int val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + tx3927_pcicptr->icd = cpu_to_le32(val); + return check_abort(flags); +} +struct pci_ops jmr3927_pci_ops = { + jmr3927_pcibios_read_config_byte, + jmr3927_pcibios_read_config_word, + jmr3927_pcibios_read_config_dword, + jmr3927_pcibios_write_config_byte, + jmr3927_pcibios_write_config_word, + jmr3927_pcibios_write_config_dword +}; + +#ifndef JMR3927_INIT_INDIRECT_PCI +inline unsigned long tc_readl(volatile __u32 * addr) +{ + return readl(addr); +} +inline void tc_writel(unsigned long data, volatile __u32 * addr) +{ + writel(data, addr); +} +#else +unsigned long tc_readl(volatile __u32 * addr) +{ + unsigned long val; + + addr = PHYSADDR(addr); + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) addr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_MEMREAD << PCI_IPCIBE_ICMD_SHIFT) | + PCI_IPCIBE_IBE_LONG; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + val = + le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> + ipcidata); + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; + return val; +} +void tc_writel(unsigned long data, volatile __u32 * addr) +{ + addr = PHYSADDR(addr); + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = + cpu_to_le32(data); + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) addr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_MEMWRITE << PCI_IPCIBE_ICMD_SHIFT) | + PCI_IPCIBE_IBE_LONG; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; +} +unsigned char tx_ioinb(unsigned char *addr) +{ + unsigned long val; + __u32 ioaddr; + int offset; + int byte; + + ioaddr = (unsigned long) addr; + offset = ioaddr & 0x3; + if (offset == 0) + byte = 0x7; + else if (offset == 1) + byte = 0xb; + else if (offset == 2) + byte = 0xd; + else if (offset == 3) + byte = 0xe; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) ioaddr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + val = + le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> + ipcidata); + val = val & 0xff; + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; + return val; +} +void tx_iooutb(unsigned long data, unsigned char *addr) +{ + __u32 ioaddr; + int offset; + int byte; + + data = data | (data << 8) | (data << 16) | (data << 24); + ioaddr = (unsigned long) addr; + offset = ioaddr & 0x3; + if (offset == 0) + byte = 0x7; + else if (offset == 1) + byte = 0xb; + else if (offset == 2) + byte = 0xd; + else if (offset == 3) + byte = 0xe; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) ioaddr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; +} +unsigned short tx_ioinw(unsigned short *addr) +{ + unsigned long val; + __u32 ioaddr; + int offset; + int byte; + + ioaddr = (unsigned long) addr; + offset = ioaddr & 0x3; + if (offset == 0) + byte = 0x3; + else if (offset == 2) + byte = 0xc; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) ioaddr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | byte; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + val = + le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> + ipcidata); + val = val & 0xffff; + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; + return val; + +} +void tx_iooutw(unsigned long data, unsigned short *addr) +{ + __u32 ioaddr; + int offset; + int byte; + + data = data | (data << 16); + ioaddr = (unsigned long) addr; + offset = ioaddr & 0x3; + if (offset == 0) + byte = 0x3; + else if (offset == 2) + byte = 0xc; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = data; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) ioaddr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | byte; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; +} +unsigned long tx_ioinl(unsigned int *addr) +{ + unsigned long val; + __u32 ioaddr; + + ioaddr = (unsigned long) addr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) ioaddr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_IOREAD << PCI_IPCIBE_ICMD_SHIFT) | + PCI_IPCIBE_IBE_LONG; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + val = + le32_to_cpu(*(volatile u32 *) (ulong) & tx3927_pcicptr-> + ipcidata); + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; + return val; +} +void tx_iooutl(unsigned long data, unsigned int *addr) +{ + __u32 ioaddr; + + ioaddr = (unsigned long) addr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcidata = + cpu_to_le32(data); + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipciaddr = + (unsigned long) ioaddr; + *(volatile u32 *) (ulong) & tx3927_pcicptr->ipcibe = + (PCI_IPCIBE_ICMD_IOWRITE << PCI_IPCIBE_ICMD_SHIFT) | + PCI_IPCIBE_IBE_LONG; + while (!(tx3927_pcicptr->istat & PCI_ISTAT_IDICC)); + /* clear by setting */ + tx3927_pcicptr->istat |= PCI_ISTAT_IDICC; +} +void tx_insbyte(unsigned char *addr, void *buffer, unsigned int count) +{ + unsigned char *ptr = (unsigned char *) buffer; + + while (count--) { + *ptr++ = tx_ioinb(addr); + } +} +void tx_insword(unsigned short *addr, void *buffer, unsigned int count) +{ + unsigned short *ptr = (unsigned short *) buffer; + + while (count--) { + *ptr++ = tx_ioinw(addr); + } +} +void tx_inslong(unsigned int *addr, void *buffer, unsigned int count) +{ + unsigned long *ptr = (unsigned long *) buffer; + + while (count--) { + *ptr++ = tx_ioinl(addr); + } +} +void tx_outsbyte(unsigned char *addr, void *buffer, unsigned int count) +{ + unsigned char *ptr = (unsigned char *) buffer; + + while (count--) { + tx_iooutb(*ptr++, addr); + } +} +void tx_outsword(unsigned short *addr, void *buffer, unsigned int count) +{ + unsigned short *ptr = (unsigned short *) buffer; + + while (count--) { + tx_iooutw(*ptr++, addr); + } +} +void tx_outslong(unsigned int *addr, void *buffer, unsigned int count) +{ + unsigned long *ptr = (unsigned long *) buffer; + + while (count--) { + tx_iooutl(*ptr++, addr); + } +} +#endif diff -Nru a/arch/mips/pci/ops-ocelot.c b/arch/mips/pci/ops-ocelot.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-ocelot.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1056 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo Evaluation Boards PCI support. + * + * The general-purpose functions to read/write and configure the GT64120A's + * PCI registers (function names start with pci0 or pci1) are either direct + * copies of functions written by Galileo Technology, or are modifications + * of their functions to work with Linux 2.4 vs Linux 2.2. These functions + * are Copyright - Galileo Technology. + * + * Other functions are derived from other MIPS PCI implementations, or were + * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/version.h> +#include <linux/cache.h> +#include <asm/pci.h> +#include <asm/io.h> +#include <asm/gt64120/gt64120.h> + +#include <linux/init.h> + +#define SELF 0 + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +struct pci_device { + u32 slot; + u32 BARtype[6]; + u32 BARsize[6]; +}; + +static void __init scan_and_initialize_pci(void); +static u32 __init scan_pci_bus(struct pci_device *pci_devices); +static void __init allocate_pci_space(struct pci_device *pci_devices); + +/* + * The functions that actually read and write to the controller. + * + * Copied from or modified from Galileo Technology code. + */ +static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device); +static void pci0WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data); +static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device); +static void pci1WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data); + +static void pci0MapIOspace(unsigned int pci0IoBase, + unsigned int pci0IoLength); +static void pci1MapIOspace(unsigned int pci1IoBase, + unsigned int pci1IoLength); +static void pci0MapMemory0space(unsigned int pci0Mem0Base, + unsigned int pci0Mem0Length); +static void pci1MapMemory0space(unsigned int pci1Mem0Base, + unsigned int pci1Mem0Length); +static void pci0MapMemory1space(unsigned int pci0Mem1Base, + unsigned int pci0Mem1Length); +static void pci1MapMemory1space(unsigned int pci1Mem1Base, + unsigned int pci1Mem1Length); +static unsigned int pci0GetIOspaceBase(void); +static unsigned int pci0GetIOspaceSize(void); +static unsigned int pci0GetMemory0Base(void); +static unsigned int pci0GetMemory0Size(void); +static unsigned int pci0GetMemory1Base(void); +static unsigned int pci0GetMemory1Size(void); +static unsigned int pci1GetIOspaceBase(void); +static unsigned int pci1GetIOspaceSize(void); +static unsigned int pci1GetMemory0Base(void); +static unsigned int pci1GetMemory0Size(void); +static unsigned int pci1GetMemory1Base(void); +static unsigned int pci1GetMemory1Size(void); + + +/* Functions to implement "pci ops" */ +static int galileo_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 * val); +static int galileo_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 val); +static void galileo_pcibios_set_master(struct pci_dev *dev); + +/* + * General-purpose PCI functions. + */ + +/* + * pci0MapIOspace - Maps PCI0 IO space for the master. + * Inputs: base and length of pci0Io + */ + +static void pci0MapIOspace(unsigned int pci0IoBase, + unsigned int pci0IoLength) +{ + unsigned int pci0IoTop = + (unsigned int) (pci0IoBase + pci0IoLength); + + if (pci0IoLength == 0) + pci0IoTop++; + + pci0IoBase = (unsigned int) (pci0IoBase >> 21); + pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21); + GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase); + GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop); +} + +/* + * pci1MapIOspace - Maps PCI1 IO space for the master. + * Inputs: base and length of pci1Io + */ + +static void pci1MapIOspace(unsigned int pci1IoBase, + unsigned int pci1IoLength) +{ + unsigned int pci1IoTop = + (unsigned int) (pci1IoBase + pci1IoLength); + + if (pci1IoLength == 0) + pci1IoTop++; + + pci1IoBase = (unsigned int) (pci1IoBase >> 21); + pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21); + GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase); + GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop); +} + +/* + * pci0MapMemory0space - Maps PCI0 memory0 space for the master. + * Inputs: base and length of pci0Mem0 + */ + +static void pci0MapMemory0space(unsigned int pci0Mem0Base, + unsigned int pci0Mem0Length) +{ + unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length; + + if (pci0Mem0Length == 0) + pci0Mem0Top++; + + pci0Mem0Base = pci0Mem0Base >> 21; + pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base); + GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top); +} + +/* + * pci1MapMemory0space - Maps PCI1 memory0 space for the master. + * Inputs: base and length of pci1Mem0 + */ + +static void pci1MapMemory0space(unsigned int pci1Mem0Base, + unsigned int pci1Mem0Length) +{ + unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length; + + if (pci1Mem0Length == 0) + pci1Mem0Top++; + + pci1Mem0Base = pci1Mem0Base >> 21; + pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base); + GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top); +} + +/* + * pci0MapMemory1space - Maps PCI0 memory1 space for the master. + * Inputs: base and length of pci0Mem1 + */ + +static void pci0MapMemory1space(unsigned int pci0Mem1Base, + unsigned int pci0Mem1Length) +{ + unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length; + + if (pci0Mem1Length == 0) + pci0Mem1Top++; + + pci0Mem1Base = pci0Mem1Base >> 21; + pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base); + GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top); + +} + +/* + * pci1MapMemory1space - Maps PCI1 memory1 space for the master. + * Inputs: base and length of pci1Mem1 + */ + +static void pci1MapMemory1space(unsigned int pci1Mem1Base, + unsigned int pci1Mem1Length) +{ + unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length; + + if (pci1Mem1Length == 0) + pci1Mem1Top++; + + pci1Mem1Base = pci1Mem1Base >> 21; + pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21; + GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base); + GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top); +} + +/* + * pci0GetIOspaceBase - Return PCI0 IO Base Address. + * Inputs: N/A + * Returns: PCI0 IO Base Address. + */ + +static unsigned int pci0GetIOspaceBase(void) +{ + unsigned int base; + GT_READ(GT_PCI0IOLD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci0GetIOspaceSize - Return PCI0 IO Bar Size. + * Inputs: N/A + * Returns: PCI0 IO Bar Size. + */ + +static unsigned int pci0GetIOspaceSize(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI0IOLD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI0IOHD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci0GetMemory0Base - Return PCI0 Memory 0 Base Address. + * Inputs: N/A + * Returns: PCI0 Memory 0 Base Address. + */ + +static unsigned int pci0GetMemory0Base(void) +{ + unsigned int base; + GT_READ(GT_PCI0M0LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size. + * Inputs: N/A + * Returns: PCI0 Memory 0 Bar Size. + */ + +static unsigned int pci0GetMemory0Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI0M0LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI0M0HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci0GetMemory1Base - Return PCI0 Memory 1 Base Address. + * Inputs: N/A + * Returns: PCI0 Memory 1 Base Address. + */ + +static unsigned int pci0GetMemory1Base(void) +{ + unsigned int base; + GT_READ(GT_PCI0M1LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size. + * Inputs: N/A + * Returns: PCI0 Memory 1 Bar Size. + */ + +static unsigned int pci0GetMemory1Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI0M1LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI0M1HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci1GetIOspaceBase - Return PCI1 IO Base Address. + * Inputs: N/A + * Returns: PCI1 IO Base Address. + */ + +static unsigned int pci1GetIOspaceBase(void) +{ + unsigned int base; + GT_READ(GT_PCI1IOLD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci1GetIOspaceSize - Return PCI1 IO Bar Size. + * Inputs: N/A + * Returns: PCI1 IO Bar Size. + */ + +static unsigned int pci1GetIOspaceSize(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI1IOLD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI1IOHD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci1GetMemory0Base - Return PCI1 Memory 0 Base Address. + * Inputs: N/A + * Returns: PCI1 Memory 0 Base Address. + */ + +static unsigned int pci1GetMemory0Base(void) +{ + unsigned int base; + GT_READ(GT_PCI1M0LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size. + * Inputs: N/A + * Returns: PCI1 Memory 0 Bar Size. + */ + +static unsigned int pci1GetMemory0Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI1M1LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI1M1HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + +/* + * pci1GetMemory1Base - Return PCI1 Memory 1 Base Address. + * Inputs: N/A + * Returns: PCI1 Memory 1 Base Address. + */ + +static unsigned int pci1GetMemory1Base(void) +{ + unsigned int base; + GT_READ(GT_PCI1M1LD_OFS, &base); + base = base << 21; + return base; +} + +/* + * pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size. + * Inputs: N/A + * Returns: PCI1 Memory 1 Bar Size. + */ + +static unsigned int pci1GetMemory1Size(void) +{ + unsigned int top, base, size; + GT_READ(GT_PCI1M1LD_OFS, &base); + base = base << 21; + GT_READ(GT_PCI1M1HD_OFS, &top); + top = (top << 21); + size = ((top - base) & 0xfffffff); + size = size | 0x1fffff; + return (size + 1); +} + + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* + * We don't even pretend to handle other busses than bus 0 correctly. + * Accessing device 31 crashes the CP7000 for some reason. + */ + if ((bus == 0) && (dev != 31)) + return 0; + return -1; +} + +/* + * pciXReadConfigReg - Read from a PCI configuration register + * - Make sure the GT is configured as a master before + * reading from another device on the PCI. + * - The function takes care of Big/Little endian conversion. + * INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI + * spec) + * pciDevNum: The device number needs to be addressed. + * RETURNS: data , if the data == 0xffffffff check the master abort bit in the + * cause register to make sure the data is valid + * + * Configuration Address 0xCF8: + * + * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number + * |congif|Reserved| Bus |Device|Function|Register|00| + * |Enable| |Number|Number| Number | Number | | <=field Name + * + */ +static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device) +{ + unsigned int DataForRegCf8; + unsigned int data; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + + /* + * The casual observer might wonder why the READ is duplicated here, + * rather than immediately following the WRITE, and just have the swap + * in the "if". That's because there is a latency problem with trying + * to read immediately after setting up the address register. The "if" + * check gives enough time for the address to stabilize, so the READ + * can work. + */ + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_READ(GT_PCI0_CFGDATA_OFS, &data); + return data; + } else { /* The PCI is working in LE Mode so swap the Data. */ + GT_READ(GT_PCI0_CFGDATA_OFS, &data); + return cpu_to_le32(data); + } +} + +static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device) +{ + unsigned int DataForRegCf8; + unsigned int data; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + /* + * The casual observer might wonder why the READ is duplicated here, + * rather than immediately following the WRITE, and just have the + * swap in the "if". That's because there is a latency problem + * with trying to read immediately after setting up the address + * register. The "if" check gives enough time for the address + * to stabilize, so the READ can work. + */ + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + /* when configurating our own PCI 1 L-unit the access is through + the PCI 0 interface with reg number = reg number + 0x80 */ + DataForRegCf8 |= 0x80; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + } else { /* The PCI is working in LE Mode so swap the Data. */ + GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); + } + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_READ(GT_PCI0_CFGDATA_OFS, &data); + return data; + } else { + GT_READ(GT_PCI1_CFGDATA_OFS, &data); + return cpu_to_le32(data); + } +} + + + +/* + * pciXWriteConfigReg - Write to a PCI configuration register + * - Make sure the GT is configured as a master before + * writingto another device on the PCI. + * - The function takes care of Big/Little endian conversion. + * Inputs: unsigned int regOffset: The register offset as it apears in the + * GT spec + * (or any other PCI device spec) + * pciDevNum: The device number needs to be addressed. + * + * Configuration Address 0xCF8: + * + * 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number + * |congif|Reserved| Bus |Device|Function|Register|00| + * |Enable| |Number|Number| Number | Number | | <=field Name + * + */ +static void pci0WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data) +{ + unsigned int DataForRegCf8; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, data); + } else { /* configuration Transaction over the pci. */ + /* The PCI is working in LE Mode so swap the Data. */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data)); + } +} + +static void pci1WriteConfigReg(unsigned int offset, + struct pci_dev *device, unsigned int data) +{ + unsigned int DataForRegCf8; + + DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) | + (PCI_FUNC(device->devfn) << 8) | + (offset & ~0x3)) | 0x80000000; + /* + * There is a latency problem + * with trying to read immediately after setting up the address + * register. The "if" check gives enough time for the address + * to stabilize, so the WRITE can work. + */ + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + /* + * when configurating our own PCI 1 L-unit the access is through + * the PCI 0 interface with reg number = reg number + 0x80 + */ + DataForRegCf8 |= 0x80; + GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8); + } else { /* configuration Transaction over the pci. */ + /* The PCI is working in LE Mode so swap the Data. */ + GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8); + } + if (PCI_SLOT(device->devfn) == SELF) { /* This board */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, data); + } else { /* configuration Transaction over the pci. */ + GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data)); + } +} + + +/* + * galileo_pcibios_(read/write) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Inputs : + * bus - bus number + * devfn - device function index + * offset - register offset in the configuration space + * size - size of value (1=byte,2=word,4-dword) + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int galileo_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 * val) +{ + int dev, busnum; + + busnum = bus->number; + dev = PCI_SLOT(devfn); + + if (pci_range_ck(busnum, dev)) { + if (size == 1) + *val = (u8) 0xff; + else if (size == 2) + *val = (u16) 0xffff; + else if (size == 4) + *val = 0xffffffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + if ((size == 2) && (offset & 0x1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (offset & 0x3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (busnum == 0) { + if (size == 1) { + *val = (u8) (pci0ReadConfigReg(offset, bus->dev) >> + ((offset & ~0x3) * 8)); + } else if (size == 2) { + *val = + (u16) (pci0ReadConfigReg(offset, bus->dev) >> + ((offset & ~0x3) * 8)); + } else if (size == 4) { + *val = pci0ReadConfigReg(offset, bus->dev); + } + } + + /* + * This is so that the upper PCI layer will get the correct return + * value if we're not attached to anything. + */ + switch (size) { + case 1: + if ((offset == 0xe) && (*val == (u8) 0xff)) { + u32 MasterAbort; + GT_READ(GT_INTRCAUSE_OFS, &MasterAbort); + if (MasterAbort & 0x40000) { + GT_WRITE(GT_INTRCAUSE_OFS, + (MasterAbort & 0xfffbffff)); + return PCIBIOS_DEVICE_NOT_FOUND; + } + } + break; + case 4: + if ((offset == 0) && (*val == 0xffffffff)) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + break} + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int offset, int size, u32 val) +{ + int dev, busnum; + unsigned long tmp; + + busnum = bus->number; + dev = PCI_SLOT(devfn); + + if (pci_range_ck(busnum, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + if (size == 4) { + if (offset & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (busnum == 0) + pci0WriteConfigReg(offset, bus->dev, val); + //if (busnum == 1) pci1WriteConfigReg (offset,bus->dev,val); + return PCIBIOS_SUCCESSFUL; + } + if ((size == 2) && (offset & 0x1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (busnum == 0) { + tmp = pci0ReadConfigReg(offset, bus->dev); + //if (busnum == 1) tmp = pci1ReadConfigReg (offset,bus->dev); + if (size == 1) { + if ((offset % 4) == 0) + tmp = + (tmp & 0xffffff00) | (val & (u8) 0xff); + if ((offset % 4) == 1) + tmp = + (tmp & 0xffff00ff) | ((val & (u8) 0xff) + << 8); + if ((offset % 4) == 2) + tmp = + (tmp & 0xff00ffff) | ((val & (u8) 0xff) + << 16); + if ((offset % 4) == 3) + tmp = + (tmp & 0x00ffffff) | ((val & (u8) 0xff) + << 24); + } else if (size == 2) { + if ((offset % 4) == 0) + tmp = + (tmp & 0xffff0000) | (val & (u16) + 0xffff); + if ((offset % 4) == 2) + tmp = + (tmp & 0x0000ffff) | + ((val & (u16) 0xffff) << 16); + } + if (busnum == 0) + pci0WriteConfigReg(offset, bus->dev, tmp); + //if (busnum == 1) pci1WriteConfigReg (offset,bus->dev,tmp); + } + return PCIBIOS_SUCCESSFUL; +} + +static void galileo_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + + galileo_pcibios_read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd); + cmd |= PCI_COMMAND_MASTER; + galileo_pcibios_write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd); +} + +/* Externally-expected functions. Do not change function names */ + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u8 tmp1; + int idx; + struct resource *r; + + galileo_pcibios_read(dev->bus, dev->devfn, PCI_COMMAND, 2, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of " + "resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + galileo_pcibios_write(dev->bus, dev->devfn, PCI_COMMAND, 2, + cmd); + } + + /* + * Let's fix up the latency timer and cache line size here. Cache + * line size = 32 bytes / sizeof dword (4) = 8. + * Latency timer must be > 8. 32 is random but appears to work. + */ + galileo_pcibios_read(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 1, + &tmp1); + if (tmp1 != 8) { + printk(KERN_WARNING + "PCI setting cache line size to 8 from " "%d\n", + tmp1); + galileo_pcibios_write(dev->bus, dev->devfn, + PCI_CACHE_LINE_SIZE, 1, 8); + } + galileo_pcibios_read(dev->bus, dev->devfn, PCI_LATENCY_TIMER, 1, + &tmp1); + if (tmp1 < 32) { + printk(KERN_WARNING + "PCI setting latency timer to 32 from %d\n", tmp1); + galileo_pcibios_write(dev->bus, dev->devfn, + PCI_LATENCY_TIMER, 1, 32); + } + + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev); +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} + +struct pci_ops galileo_pci_ops = { + .read = galileo_pcibios_read, + .write = galileo_pcibios_write, +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __devinit pcibios_fixup_bus(struct pci_bus *c) +{ + gt64120_board_pcibios_fixup_bus(c); +} + +/* + * This code was derived from Galileo Technology's example + * and significantly reworked. + * + * This is very simple. It does not scan multiple function devices. It does + * not scan behind bridges. Those would be simple to implement, but we don't + * currently need this. + */ + +static void __init scan_and_initialize_pci(void) +{ + struct pci_device pci_devices[MAX_PCI_DEVS]; + + if (scan_pci_bus(pci_devices)) { + allocate_pci_space(pci_devices); + } +} + +/* + * This is your basic PCI scan. It goes through each slot and checks to + * see if there's something that responds. If so, then get the size and + * type of each of the responding BARs. Save them for later. + */ + +static u32 __init scan_pci_bus(struct pci_device *pci_devices) +{ + u32 arrayCounter = 0; + u32 memType; + u32 memSize; + u32 pci_slot, bar; + u32 id; + u32 c18RegValue; + struct pci_dev device; + + /* + * According to PCI REV 2.1 MAX agents on the bus are 21. + * We don't bother scanning ourselves (slot 0). + */ + for (pci_slot = 1; pci_slot < 22; pci_slot++) { + + device.devfn = PCI_DEVFN(pci_slot, 0); + id = pci0ReadConfigReg(PCI_VENDOR_ID, &device); + + /* + * Check for a PCI Master Abort (nothing responds in the + * slot) + */ + GT_READ(GT_INTRCAUSE_OFS, &c18RegValue); + /* + * Clearing bit 18 of in the Cause Register 0xc18 by + * writting 0. + */ + GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff)); + if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) { + pci_devices[arrayCounter].slot = pci_slot; + for (bar = 0; bar < 6; bar++) { + memType = + pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + + (bar * 4), &device); + pci_devices[arrayCounter].BARtype[bar] = + memType & 1; + pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + + (bar * 4), &device, + 0xffffffff); + memSize = + pci0ReadConfigReg(PCI_BASE_ADDRESS_0 + + (bar * 4), &device); + if (memType & 1) { /* IO space */ + pci_devices[arrayCounter]. + BARsize[bar] = + ~(memSize & 0xfffffffc) + 1; + } else { /* memory space */ + pci_devices[arrayCounter]. + BARsize[bar] = + ~(memSize & 0xfffffff0) + 1; + } + } /* BAR counter */ + + arrayCounter++; + } + /* found a device */ + } /* slot counter */ + + if (arrayCounter < MAX_PCI_DEVS) + pci_devices[arrayCounter].slot = -1; + + return arrayCounter; +} + +/* + * This function goes through the list of devices and allocates the BARs in + * either IO or MEM space. It does it in order of size, which will limit the + * amount of fragmentation we have in the IO and MEM spaces. + */ + +static void __init allocate_pci_space(struct pci_device *pci_devices) +{ + u32 count, maxcount, bar; + u32 maxSize, maxDevice, maxBAR; + u32 alignto; + u32 base; + u32 pci0_mem_base = pci0GetMemory0Base(); + u32 pci0_io_base = pci0GetIOspaceBase(); + struct pci_dev device; + + /* How many PCI devices do we have? */ + maxcount = MAX_PCI_DEVS; + for (count = 0; count < MAX_PCI_DEVS; count++) { + if (pci_devices[count].slot == -1) { + maxcount = count; + break; + } + } + + do { + /* Find the largest size BAR we need to allocate */ + maxSize = 0; + for (count = 0; count < maxcount; count++) { + for (bar = 0; bar < 6; bar++) { + if (pci_devices[count].BARsize[bar] > + maxSize) { + maxSize = + pci_devices[count]. + BARsize[bar]; + maxDevice = count; + maxBAR = bar; + } + } + } + + /* + * We've found the largest BAR. Allocate it into IO or + * mem space. We don't idiot check the bases to make + * sure they haven't overflowed the current size for that + * aperture. + * Don't bother to enable the device's IO or MEM space here. + * That will be done in pci_enable_resources if the device is + * activated by a driver. + */ + if (maxSize) { + device.devfn = + PCI_DEVFN(pci_devices[maxDevice].slot, 0); + if (pci_devices[maxDevice].BARtype[maxBAR] == 1) { + alignto = max(0x1000U, maxSize); + base = ALIGN(pci0_io_base, alignto); + pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + + (maxBAR * 4), &device, + base | 0x1); + pci0_io_base = base + alignto; + } else { + alignto = max(0x1000U, maxSize); + base = ALIGN(pci0_mem_base, alignto); + pci0WriteConfigReg(PCI_BASE_ADDRESS_0 + + (maxBAR * 4), &device, + base); + pci0_mem_base = base + alignto; + } + /* + * This entry is finished. Remove it from the list + * we'll scan. + */ + pci_devices[maxDevice].BARsize[maxBAR] = 0; + } + } while (maxSize); +} + +static int __init pcibios_init(void) +{ + u32 tmp; + struct pci_dev controller; + + controller.devfn = SELF; + + GT_READ(GT_PCI0_CMD_OFS, &tmp); + GT_READ(GT_PCI0_BARE_OFS, &tmp); + + /* + * You have to enable bus mastering to configure any other + * card on the bus. + */ + tmp = pci0ReadConfigReg(PCI_COMMAND, &controller); + tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR; + pci0WriteConfigReg(PCI_COMMAND, &controller, tmp); + + /* This scans the PCI bus and sets up initial values. */ + scan_and_initialize_pci(); + + /* + * Reset PCI I/O and PCI MEM values to ones supported by EVM. + */ + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; + iomem_resource.start = GT_PCI_MEM_BASE; + iomem_resource.end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; + + pci_scan_bus(0, &galileo_pci_ops, NULL); + + return 0; +} + +subsys_initcall(pcibios_init); + +/* + * for parsing "pci=" kernel boot arguments. + */ +char *pcibios_setup(char *str) +{ + printk(KERN_INFO "rr: pcibios_setup\n"); + /* Nothing to do for now. */ + + return str; +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/ops-vrc4173.c b/arch/mips/pci/ops-vrc4173.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/ops-vrc4173.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,120 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/vrc4173.c + * + * BRIEF MODULE DESCRIPTION + * Pre-setup for NEC VRC4173. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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 <linux/init.h> +#include <linux/pci.h> +#include <linux/module.h> + +#include <asm/io.h> +#include <asm/vr41xx/eagle.h> +#include <asm/vr41xx/vrc4173.h> + +#define PCI_CONFIG_ADDR KSEG1ADDR(0x0f000c18) +#define PCI_CONFIG_DATA KSEG1ADDR(0x0f000c14) + +static inline void config_writeb(u8 reg, u8 val) +{ + u32 data; + int shift; + + writel((1UL << 0x1e) | (reg & 0xfc), PCI_CONFIG_ADDR); + data = readl(PCI_CONFIG_DATA); + + shift = (reg & 3) << 3; + data &= ~(0xff << shift); + data |= (((u32) val) << shift); + + writel(data, PCI_CONFIG_DATA); +} + +static inline u16 config_readw(u8 reg) +{ + u32 data; + + writel(((1UL << 30) | (reg & 0xfc)), PCI_CONFIG_ADDR); + data = readl(PCI_CONFIG_DATA); + + return (u16) (data >> ((reg & 2) << 3)); +} + +static inline u32 config_readl(u8 reg) +{ + writel(((1UL << 30) | (reg & 0xfc)), PCI_CONFIG_ADDR); + + return readl(PCI_CONFIG_DATA); +} + +static inline void config_writel(u8 reg, u32 val) +{ + writel((1UL << 0x1e) | (reg & 0xfc), PCI_CONFIG_ADDR); + writel(val, PCI_CONFIG_DATA); +} + +void __init vrc4173_preinit(void) +{ + u32 cmdsts, base; + u16 cmu_mask; + + + if ((config_readw(PCI_VENDOR_ID) == PCI_VENDOR_ID_NEC) && + (config_readw(PCI_DEVICE_ID) == PCI_DEVICE_ID_NEC_VRC4173)) { + /* + * Initialized NEC VRC4173 Bus Control Unit + */ + cmdsts = config_readl(PCI_COMMAND); + config_writel(PCI_COMMAND, + cmdsts | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + + config_writeb(PCI_LATENCY_TIMER, 0x80); + + config_writel(PCI_BASE_ADDRESS_0, VR41XX_PCI_IO_START); + base = config_readl(PCI_BASE_ADDRESS_0); + base &= PCI_BASE_ADDRESS_IO_MASK; + config_writeb(0x40, 0x01); + + /* CARDU1 IDSEL = AD12, CARDU2 IDSEL = AD13 */ + config_writeb(0x41, 0); + + cmu_mask = 0x1000; + outw(cmu_mask, base + 0x040); + cmu_mask |= 0x0800; + outw(cmu_mask, base + 0x040); + + outw(0x000f, base + 0x042); /* Soft reset of CMU */ + cmu_mask |= 0x05e0; + outw(cmu_mask, base + 0x040); + cmu_mask = inw(base + 0x040); /* dummy read */ + outw(0x0000, base + 0x042); + } +} diff -Nru a/arch/mips/pci/pci-auto.c b/arch/mips/pci/pci-auto.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-auto.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,518 @@ +/* + * PCI autoconfiguration library + * + * Author: Matt Porter <mporter@mvista.com> + * + * Copyright 2000, 2001, 2002, 2003 MontaVista Software Inc. + * Copyright 2001 Bradley D. LaRonde <brad@ltc.com> + * + * 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. + */ + +/* + * Modified for MIPS by Jun Sun, jsun@mvista.com + * + * . Simplify the interface between pci_auto and the rest: a single function. + * . Assign resources from low address to upper address. + * . change most int to u32. + * + * Further modified to include it as mips generic code, ppopov@mvista.com. + * + * 2001-10-26 Bradley D. LaRonde <brad@ltc.com> + * - Add a top_bus argument to the "early config" functions so that + * they can set a fake parent bus pointer to convince the underlying + * pci ops to use type 1 configuration for sub busses. + * - Set bridge base and limit registers correctly. + * - Align io and memory base properly before and after bridge setup. + * - Don't fall through to pci_setup_bars for bridge. + * - Reformat the debug output to look more like lspci's output. + * + * 2003-04-09 Yoichi Yuasa, Alice Hennessy, Jun Sun + * - Add cardbus bridge support, mostly copied from PPC + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/pci.h> + +#include <asm/pci_channel.h> + +#define DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_dev *fake_pci_dev(struct pci_channel *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + + if (busnr != top_bus) + /* Fake a parent bus structure. */ + bus.parent = &bus; + else + bus.parent = NULL; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) + EARLY_PCI_OP(read, word, u16 *) + EARLY_PCI_OP(read, dword, u32 *) + EARLY_PCI_OP(write, byte, u8) + EARLY_PCI_OP(write, word, u16) + EARLY_PCI_OP(write, dword, u32) + +static struct resource *io_resource_inuse; +static struct resource *mem_resource_inuse; + +static u32 pciauto_lower_iospc; +static u32 pciauto_upper_iospc; + +static u32 pciauto_lower_memspc; +static u32 pciauto_upper_memspc; + +void __init +pciauto_setup_bars(struct pci_channel *hose, + int top_bus, + int current_bus, int pci_devfn, int bar_limit) +{ + u32 bar_response, bar_size, bar_value; + u32 bar, addr_mask, bar_nr = 0; + u32 *upper_limit; + u32 *lower_limit; + int found_mem64 = 0; + + for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar += 4) { + /* Tickle the BAR and get the response */ + early_write_config_dword(hose, top_bus, + current_bus, + pci_devfn, bar, 0xffffffff); + early_read_config_dword(hose, top_bus, + current_bus, + pci_devfn, bar, &bar_response); + + /* If BAR is not implemented go to the next BAR */ + if (!bar_response) + continue; + + /* + * Workaround for a BAR that doesn't use its upper word, + * like the ALi 1535D+ PCI DC-97 Controller Modem (M5457). + * bdl <brad@ltc.com> + */ + if (!(bar_response & 0xffff0000)) + bar_response |= 0xffff0000; + + retry: + /* 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; + lower_limit = &pciauto_lower_iospc; + DBG(" I/O"); + } 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; + lower_limit = &pciauto_lower_memspc; + DBG(" Mem"); + } + + + /* Calculate requested size */ + bar_size = ~(bar_response & addr_mask) + 1; + + /* Allocate a base address */ + bar_value = + ((*lower_limit - 1) & ~(bar_size - 1)) + bar_size; + + if ((bar_value + bar_size) > *upper_limit) { + if (bar_response & PCI_BASE_ADDRESS_SPACE) { + if (io_resource_inuse->child) { + io_resource_inuse = + io_resource_inuse->child; + pciauto_lower_iospc = + io_resource_inuse->start; + pciauto_upper_iospc = + io_resource_inuse->end + 1; + goto retry; + } + + } else { + if (mem_resource_inuse->child) { + mem_resource_inuse = + mem_resource_inuse->child; + pciauto_lower_memspc = + mem_resource_inuse->start; + pciauto_upper_memspc = + mem_resource_inuse->end + 1; + goto retry; + } + } + DBG(" unavailable -- skipping\n"); + continue; + } + + /* Write it out and update our limit */ + early_write_config_dword(hose, top_bus, current_bus, + pci_devfn, bar, bar_value); + + *lower_limit = bar_value + bar_size; + + /* + * 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, top_bus, + current_bus, + pci_devfn, + bar, 0x00000000); + } + + DBG(" at 0x%.8x [size=0x%x]\n", bar_value, bar_size); + + bar_nr++; + } + +} + +void __init +pciauto_prescan_setup_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, int pci_devfn, int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 1MB and 4KB boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) + & ~(0x100000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) + & ~(0x1000 - 1); + + /* Set base (lower limit) of address range behind bridge. */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_MEMORY_BASE, + pciauto_lower_memspc >> 16); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_IO_BASE, + (pciauto_lower_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_IO_BASE_UPPER16, + pciauto_lower_iospc >> 16); + + /* We don't support prefetchable memory for now, so disable */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_PREF_MEMORY_BASE, 0); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_PREF_MEMORY_LIMIT, 0); +} + +void __init +pciauto_postscan_setup_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, int pci_devfn, int sub_bus) +{ + u32 temp; + + /* + * [jsun] we always bump up baselines a little, so that if there + * nothing behind P2P bridge, we don't wind up overlapping IO/MEM + * spaces. + */ + pciauto_lower_memspc += 1; + pciauto_lower_iospc += 1; + + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* Set upper limit of address range behind bridge. */ + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_MEMORY_LIMIT, + pciauto_lower_memspc >> 16); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_IO_LIMIT, + (pciauto_lower_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, top_bus, current_bus, pci_devfn, + PCI_IO_LIMIT_UPPER16, + pciauto_lower_iospc >> 16); + + /* Align memory and I/O to 1MB and 4KB boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x100000 - 1)) + & ~(0x100000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x1000 - 1)) + & ~(0x1000 - 1); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, + temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY + | PCI_COMMAND_MASTER); +} + +void __init +pciauto_prescan_setup_cardbus_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_PRIMARY_BUS, current_bus); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SECONDARY_BUS, sub_bus + 1); + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, 0xff); + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_BASE_0, + pciauto_lower_memspc); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_BASE_0, pciauto_lower_iospc); +} + +void __init +pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, + int top_bus, + int current_bus, + int pci_devfn, int sub_bus) +{ + u32 temp; + + /* + * Configure subordinate bus number. The PCI subsystem + * bus scan will renumber buses (reserving three additional + * for this PCI<->CardBus bridge for the case where a CardBus + * adapter contains a P2P or CB2CB bridge. + */ + + early_write_config_byte(hose, top_bus, current_bus, pci_devfn, + PCI_SUBORDINATE_BUS, sub_bus); + + /* + * Reserve an additional 4MB for mem space and 16KB for + * I/O space. This should cover any additional space + * requirement of unusual CardBus devices with + * additional bridges that can consume more address space. + * + * Although pcmcia-cs currently will reprogram bridge + * windows, the goal is to add an option to leave them + * alone and use the bridge window ranges as the regions + * that are searched for free resources upon hot-insertion + * of a device. This will allow a PCI<->CardBus bridge + * configured by this routine to happily live behind a + * P2P bridge in a system. + */ + pciauto_lower_memspc += 0x00400000; + pciauto_lower_iospc += 0x00004000; + + /* Align memory and I/O to 4KB and 4 byte boundaries. */ + pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) + & ~(0x1000 - 1); + pciauto_lower_iospc = (pciauto_lower_iospc + (0x4 - 1)) + & ~(0x4 - 1); + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_MEMORY_LIMIT_0, + pciauto_lower_memspc - 1); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_CB_IO_LIMIT_0, + pciauto_lower_iospc - 1); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, &temp); + early_write_config_dword(hose, top_bus, current_bus, pci_devfn, + PCI_COMMAND, + temp | PCI_COMMAND_IO | PCI_COMMAND_MEMORY + | PCI_COMMAND_MASTER); +} + +#define PCIAUTO_IDE_MODE_MASK 0x05 + +int __init +pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) +{ + int sub_bus; + u32 pci_devfn, pci_class, cmdstat, found_multi = 0; + unsigned short vid, did; + unsigned char header_type; + int devfn_start = 0; + int devfn_stop = 0xff; + + sub_bus = current_bus; + + if (hose->first_devfn) + devfn_start = hose->first_devfn; + if (hose->last_devfn) + devfn_stop = hose->last_devfn; + + for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { + + if (PCI_FUNC(pci_devfn) && !found_multi) + continue; + + early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_VENDOR_ID, &vid); + + if (vid == 0xffff) + continue; + + early_read_config_byte(hose, top_bus, current_bus, + pci_devfn, PCI_HEADER_TYPE, + &header_type); + + if (!PCI_FUNC(pci_devfn)) + found_multi = header_type & 0x80; + + early_read_config_word(hose, top_bus, current_bus, + pci_devfn, PCI_DEVICE_ID, &did); + + early_read_config_dword(hose, top_bus, current_bus, + pci_devfn, PCI_CLASS_REVISION, + &pci_class); + + DBG("%.2x:%.2x.%x Class %.4x: %.4x:%.4x", + current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn), + pci_class >> 16, vid, did); + if (pci_class & 0xff) + DBG(" (rev %.2x)", pci_class & 0xff); + DBG("\n"); + + if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { + DBG(" Bridge: primary=%.2x, secondary=%.2x\n", current_bus, sub_bus + 1); + pciauto_setup_bars(hose, top_bus, current_bus, + pci_devfn, PCI_BASE_ADDRESS_1); + pciauto_prescan_setup_bridge(hose, top_bus, + current_bus, + pci_devfn, sub_bus); + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", sub_bus + 1, pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = + pciauto_bus_scan(hose, top_bus, sub_bus + 1); + DBG("Back to bus %.2x\n", current_bus); + pciauto_postscan_setup_bridge(hose, top_bus, + current_bus, + pci_devfn, sub_bus); + continue; + } else if ((pci_class >> 16) == PCI_CLASS_BRIDGE_CARDBUS) { + DBG(" CARDBUS Bridge: primary=%.2x, secondary=%.2x\n", current_bus, sub_bus + 1); + DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); + /* Place CardBus Socket/ExCA registers */ + pciauto_setup_bars(hose, top_bus, current_bus, + pci_devfn, PCI_BASE_ADDRESS_0); + + pciauto_prescan_setup_cardbus_bridge(hose, top_bus, + current_bus, + pci_devfn, + sub_bus); + + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", sub_bus + 1, pciauto_lower_iospc, pciauto_lower_memspc); + sub_bus = + pciauto_bus_scan(hose, top_bus, sub_bus + 1); + DBG("Back to bus %.2x, sub_bus is %x\n", + current_bus, sub_bus); + pciauto_postscan_setup_cardbus_bridge(hose, + top_bus, + current_bus, + pci_devfn, + sub_bus); + continue; + } else if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) { + + unsigned char prg_iface; + + early_read_config_byte(hose, top_bus, current_bus, + pci_devfn, PCI_CLASS_PROG, + &prg_iface); + if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) { + DBG("Skipping legacy mode IDE controller\n"); + continue; + } + } + + /* + * Found a peripheral, enable some standard + * settings + */ + early_read_config_dword(hose, top_bus, current_bus, + pci_devfn, PCI_COMMAND, &cmdstat); + early_write_config_dword(hose, top_bus, current_bus, + pci_devfn, PCI_COMMAND, + cmdstat | PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + early_write_config_byte(hose, top_bus, current_bus, + pci_devfn, PCI_LATENCY_TIMER, + 0x80); + + /* Allocate PCI I/O and/or memory space */ + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, + PCI_BASE_ADDRESS_5); + } + return sub_bus; +} + +int __init pciauto_assign_resources(int busno, struct pci_channel *hose) +{ + /* setup resource limits */ + io_resource_inuse = hose->io_resource; + mem_resource_inuse = hose->mem_resource; + + pciauto_lower_iospc = io_resource_inuse->start; + pciauto_upper_iospc = io_resource_inuse->end + 1; + pciauto_lower_memspc = mem_resource_inuse->start; + pciauto_upper_memspc = mem_resource_inuse->end + 1; + DBG("Autoconfig PCI channel 0x%p\n", hose); + DBG("Scanning bus %.2x, I/O 0x%.8x:0x%.8x, Mem 0x%.8x:0x%.8x\n", + busno, pciauto_lower_iospc, pciauto_upper_iospc, + pciauto_lower_memspc, pciauto_upper_memspc); + + return pciauto_bus_scan(hose, busno, busno); +} diff -Nru a/arch/mips/pci/pci-cobalt.c b/arch/mips/pci/pci-cobalt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-cobalt.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,433 @@ +/* + * Cobalt Qube/Raq PCI support + * + * 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) 1995, 1996, 1997, 2002 by Ralf Baechle + * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) + */ +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/pci.h> +#include <asm/io.h> +#include <asm/gt64120.h> + +#include <asm/cobalt/cobalt.h> + +int cobalt_board_id; + +static void qube_expansion_slot_bist(struct pci_dev *dev) +{ + unsigned char ctrl; + int timeout = 100000; + + pci_read_config_byte(dev, PCI_BIST, &ctrl); + if (!(ctrl & PCI_BIST_CAPABLE)) + return; + + pci_write_config_byte(dev, PCI_BIST, ctrl | PCI_BIST_START); + do { + pci_read_config_byte(dev, PCI_BIST, &ctrl); + if (!(ctrl & PCI_BIST_START)) + break; + } while (--timeout > 0); + if ((timeout <= 0) || (ctrl & PCI_BIST_CODE_MASK)) + printk + ("PCI: Expansion slot card failed BIST with code %x\n", + (ctrl & PCI_BIST_CODE_MASK)); +} + +static void qube_expansion_slot_fixup(struct pci_dev *dev) +{ + unsigned short pci_cmd; + unsigned long ioaddr_base = 0x10108000; /* It's magic, ask Doug. */ + unsigned long memaddr_base = 0x12001000; + int i; + + /* Enable bits in COMMAND so driver can talk to it. */ + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + pci_cmd |= + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Give it a working IRQ. */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_QUBE_SLOT_IRQ); + dev->irq = COBALT_QUBE_SLOT_IRQ; + + ioaddr_base += 0x2000 * PCI_FUNC(dev->devfn); + memaddr_base += 0x2000 * PCI_FUNC(dev->devfn); + + /* Fixup base addresses, we only support I/O at the moment. */ + for (i = 0; i <= 5; i++) { + unsigned int regaddr = (PCI_BASE_ADDRESS_0 + (i * 4)); + unsigned int rval, mask, size, alignme, aspace; + unsigned long *basep = &ioaddr_base; + + /* Check type first, punt if non-IO. */ + pci_read_config_dword(dev, regaddr, &rval); + aspace = (rval & PCI_BASE_ADDRESS_SPACE); + if (aspace != PCI_BASE_ADDRESS_SPACE_IO) + basep = &memaddr_base; + + /* Figure out how much it wants, if anything. */ + pci_write_config_dword(dev, regaddr, 0xffffffff); + pci_read_config_dword(dev, regaddr, &rval); + + /* Unused? */ + if (rval == 0) + continue; + + rval &= PCI_BASE_ADDRESS_IO_MASK; + mask = (~rval << 1) | 0x1; + size = (mask & rval) & 0xffffffff; + alignme = size; + if (alignme < 0x400) + alignme = 0x400; + rval = ((*basep + (alignme - 1)) & ~(alignme - 1)); + *basep = (rval + size); + pci_write_config_dword(dev, regaddr, rval | aspace); + dev->resource[i].start = rval; + dev->resource[i].end = *basep - 1; + if (aspace == PCI_BASE_ADDRESS_SPACE_IO) { + dev->resource[i].start -= 0x10000000; + dev->resource[i].end -= 0x10000000; + } + } + qube_expansion_slot_bist(dev); +} + +static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) +{ + unsigned short cfgword; + unsigned char lt; + + /* Enable Bus Mastering and fast back to back. */ + pci_read_config_word(dev, PCI_COMMAND, &cfgword); + cfgword |= (PCI_COMMAND_FAST_BACK | PCI_COMMAND_MASTER); + pci_write_config_word(dev, PCI_COMMAND, cfgword); + + /* Enable both ide interfaces. ROM only enables primary one. */ + pci_write_config_byte(dev, 0x40, 0xb); + + /* Set latency timer to reasonable value. */ + pci_read_config_byte(dev, PCI_LATENCY_TIMER, <); + if (lt < 64) + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); +} + +static void qube_raq_tulip_fixup(struct pci_dev *dev) +{ + unsigned short pci_cmd; + + /* Fixup the first tulip located at device PCICONF_ETH0 */ + if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH0) { + /* Setup the first Tulip */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_ETH0_IRQ); + dev->irq = COBALT_ETH0_IRQ; + + dev->resource[0].start = 0x100000; + dev->resource[0].end = 0x10007f; + + dev->resource[1].start = 0x12000000; + dev->resource[1].end = dev->resource[1].start + 0x3ff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, + dev->resource[1].start); + + /* Fixup the second tulip located at device PCICONF_ETH1 */ + } else if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_ETH1) { + + /* Enable the second Tulip device. */ + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + pci_cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MASTER); + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Give it it's IRQ. */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_ETH1_IRQ); + dev->irq = COBALT_ETH1_IRQ; + + /* And finally, a usable I/O space allocation, right after what + * the first Tulip uses. + */ + dev->resource[0].start = 0x101000; + dev->resource[0].end = 0x10107f; + + dev->resource[1].start = 0x12000400; + dev->resource[1].end = dev->resource[1].start + 0x3ff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, + dev->resource[1].start); + } +} + +static void qube_raq_scsi_fixup(struct pci_dev *dev) +{ + unsigned short pci_cmd; + + /* + * Tell the SCSI device that we expect an interrupt at + * IRQ 7 and not the default 0. + */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, COBALT_SCSI_IRQ); + dev->irq = COBALT_SCSI_IRQ; + + if (cobalt_board_id == COBALT_BRD_ID_RAQ2) { + + /* Enable the device. */ + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + + pci_cmd |= + (PCI_COMMAND_IO | PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | PCI_COMMAND_INVALIDATE); + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Give it it's RAQ IRQ. */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + COBALT_RAQ_SCSI_IRQ); + dev->irq = COBALT_RAQ_SCSI_IRQ; + + /* And finally, a usable I/O space allocation, right after what + * the second Tulip uses. + */ + dev->resource[0].start = 0x102000; + dev->resource[0].end = dev->resource[0].start + 0xff; + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, + 0x10102000); + + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, + 0x00002000); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, + 0x00100000); + } +} + +static void qube_raq_galileo_fixup(struct pci_dev *dev) +{ + unsigned short galileo_id; + + /* Fix PCI latency-timer and cache-line-size values in Galileo + * host bridge. + */ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); + + /* On all machines prior to Q2, we had the STOP line disconnected + * from Galileo to VIA on PCI. The new Galileo does not function + * correctly unless we have it connected. + * + * Therefore we must set the disconnect/retry cycle values to + * something sensible when using the new Galileo. + */ + pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id); + galileo_id &= 0xff; /* mask off class info */ + if (galileo_id >= 0x10) { + /* New Galileo, assumes PCI stop line to VIA is connected. */ + GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); + } else if (galileo_id == 0x1 || galileo_id == 0x2) { + signed int timeo; + /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ + timeo = GALILEO_INL(GT_PCI0_TOR_OFS); + /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ + GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS); + } +} + +static void qube_pcibios_fixup(struct pci_dev *dev) +{ + if (PCI_SLOT(dev->devfn) == COBALT_PCICONF_PCISLOT) { + unsigned int tmp; + + /* See if there is a device in the expansion slot, if so + * discover its resources and fixup whatever we need to + */ + pci_read_config_dword(dev, PCI_VENDOR_ID, &tmp); + if (tmp != 0xffffffff && tmp != 0x00000000) + qube_expansion_slot_fixup(dev); + } +} + +struct pci_fixup pcibios_fixups[] = { + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, + qube_raq_via_bmIDE_fixup}, + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, + qube_raq_tulip_fixup}, + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_GALILEO, PCI_ANY_ID, + qube_raq_galileo_fixup}, + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C860, + qube_raq_scsi_fixup}, + {PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, qube_pcibios_fixup} +}; + + +static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn) +{ + if ((bus->number == 0) + && ((PCI_SLOT(devfn) == 0) + || ((PCI_SLOT(devfn) > 6) + && (PCI_SLOT(devfn) <= 12)))) + return 0; /* OK device number */ + + return -1; /* NOT ok device number */ +} + +#define PCI_CFG_SET(devfn,where) \ + GALILEO_OUTL((0x80000000 | (PCI_SLOT (devfn) << 11) | \ + (PCI_FUNC (devfn) << 8) | (where)), \ + GT_PCI0_CFGADDR_OFS) + + +static int qube_pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + switch (size) { + case 4: + if (where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck(bus, devfn)) { + *val = 0xFFFFFFFF; + return PCIBIOS_DEVICE_NOT_FOUND; + } + PCI_CFG_SET(devfn, where); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + return PCIBIOS_SUCCESSFUL; + + case 2: + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck(bus, devfn)) { + *val = 0xffff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + PCI_CFG_SET(devfn, (where & ~0x3)); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) + >> ((where & 3) * 8); + return PCIBIOS_SUCCESSFUL; + + case 1: + if (pci_range_ck(bus, devfn)) { + *val = 0xff; + return PCIBIOS_DEVICE_NOT_FOUND; + } + PCI_CFG_SET(devfn, (where & ~0x3)); + *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) + >> ((where & 3) * 8); + return PCIBIOS_SUCCESSFUL; + } +} + +static int qube_pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 tmp; + + switch (size) { + case 4: + if (where & 0x3) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + PCI_CFG_SET(devfn, where); + GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS); + + return PCIBIOS_SUCCESSFUL; + + case 2: + if (where & 0x1) + return PCIBIOS_BAD_REGISTER_NUMBER; + if (pci_range_ck(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + PCI_CFG_SET(devfn, (where & ~0x3)); + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + tmp &= ~(0xffff << ((where & 0x3) * 8)); + tmp |= (val << ((where & 0x3) * 8)); + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); + + return PCIBIOS_SUCCESSFUL; + + case 1: + + if (pci_range_ck(bus, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + PCI_CFG_SET(devfn, (where & ~0x3)); + tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + tmp &= ~(0xff << ((where & 0x3) * 8)); + tmp |= (val << ((where & 0x3) * 8)); + GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); + + return PCIBIOS_SUCCESSFUL; + } +} + +struct pci_ops qube_pci_ops = { + .read = qube_pci_read_config, + .write = qube_pci_write_config, +}; + +static int __init pcibios_init(void) +{ + unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0); + + printk("PCI: Probing PCI hardware\n"); + + /* Read the cobalt id register out of the PCI config space */ + PCI_CFG_SET(devfn, (VIA_COBALT_BRD_ID_REG & ~0x3)); + cobalt_board_id = GALILEO_INL(GT_PCI0_CFGDATA_OFS) + >> ((VIA_COBALT_BRD_ID_REG & 3) * 8); + cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); + + printk("Cobalt Board ID: %d\n", cobalt_board_id); + + ioport_resource.start = 0x00000000; + ioport_resource.end = 0x0fffffff; + + iomem_resource.start = 0x01000000; + iomem_resource.end = 0xffffffff; + + pci_scan_bus(0, &qube_pci_ops, NULL); + + return 0; +} + +subsys_initcall(pcibios_init); + +char *pcibios_setup(char *str) +{ + return str; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + u16 cmd, status; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_read_config_word(dev, PCI_STATUS, &status); + printk("PCI: Enabling device %s (%04x %04x)\n", dev->slot_name, + cmd, status); + /* We'll sort this out when we know it isn't enabled ;) */ + + return 0; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + + panic("Uhhoh called pcibios_align_resource\n"); +} + +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + /* We don't have sub-busses to fixup here */ +} + +unsigned int __init pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/pci-ddb5074.c b/arch/mips/pci/pci-ddb5074.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ddb5074.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,129 @@ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/pci.h> + +#include <asm/pci_channel.h> +#include <asm/debug.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +static struct resource extpci_io_resource = { + "pci IO space", + 0x1000, /* leave some room for ISA bus */ + DDB_PCI_IO_SIZE - 1, + IORESOURCE_IO +}; + +static struct resource extpci_mem_resource = { + "pci memory space", + DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */ + DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops ddb5476_ext_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource}, + {NULL, NULL, NULL} +}; + +#define PCI_EXT_INTA 8 +#define PCI_EXT_INTB 9 +#define PCI_EXT_INTC 10 +#define PCI_EXT_INTD 11 +#define PCI_EXT_INTE 12 + +#define MAX_SLOT_NUM 14 + +static unsigned char irq_map[MAX_SLOT_NUM] = { + /* SLOT: 0 */ nile4_to_irq(PCI_EXT_INTE), + /* SLOT: 1 */ nile4_to_irq(PCI_EXT_INTA), + /* SLOT: 2 */ nile4_to_irq(PCI_EXT_INTA), + /* SLOT: 3 */ nile4_to_irq(PCI_EXT_INTB), + /* SLOT: 4 */ nile4_to_irq(PCI_EXT_INTC), + /* SLOT: 5 */ nile4_to_irq(NILE4_INT_UART), + /* SLOT: 6 */ 0xff, + /* SLOT: 7 */ 0xff, + /* SLOT: 8 */ 0xff, + /* SLOT: 9 */ 0xff, + /* SLOT: 10 */ nile4_to_irq(PCI_EXT_INTE), + /* SLOT: 11 */ 0xff, + /* SLOT: 12 */ 0xff, + /* SLOT: 13 */ nile4_to_irq(PCI_EXT_INTE), +}; + +void __init pcibios_fixup_irqs(void) +{ + + struct pci_dev *dev = NULL; + int slot_num; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot_num = PCI_SLOT(dev->devfn); + db_assert(slot_num < MAX_SLOT_NUM); + printk("irq_map[%d]: %02x\n", slot_num, irq_map[slot_num]); + db_assert(irq_map[slot_num] != 0xff); + + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + irq_map[slot_num]); + + dev->irq = irq_map[slot_num]; + } +} + +void __init ddb_pci_reset_bus(void) +{ + u32 temp; + + /* + * I am not sure about the "official" procedure, the following + * steps work as far as I know: + * We first set PCI cold reset bit (bit 31) in PCICTRL-H. + * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. + * The same is true for both PCI channels. + */ + temp = ddb_in32(DDB_PCICTRL + 4); + temp |= 0x80000000; + ddb_out32(DDB_PCICTRL + 4, temp); + temp &= ~0xc0000000; + ddb_out32(DDB_PCICTRL + 4, temp); + +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + /* we hope pci_auto has assigned the bus numbers to all buses */ + return 1; +} + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + while ((dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, + dev)) != NULL) { + /* + * It's nice to have the LEDs on the GPIO pins + * available for debugging + */ + extern struct pci_dev *pci_pmu; + u8 t8; + + pci_pmu = dev; /* for LEDs D2 and D3 */ + /* Program the lines for LEDs D2 and D3 to output */ + pci_read_config_byte(dev, 0x7d, &t8); + t8 |= 0xc0; + pci_write_config_byte(dev, 0x7d, t8); + /* Turn LEDs D2 and D3 off */ + pci_read_config_byte(dev, 0x7e, &t8); + t8 |= 0xc0; + pci_write_config_byte(dev, 0x7e, t8); + } +} diff -Nru a/arch/mips/pci/pci-ddb5476.c b/arch/mips/pci/pci-ddb5476.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ddb5476.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,145 @@ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/pci.h> + +#include <asm/pci_channel.h> +#include <asm/debug.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +static struct resource extpci_io_resource = { + "pci IO space", + 0x1000, /* leave some room for ISA bus */ + DDB_PCI_IO_SIZE - 1, + IORESOURCE_IO +}; + +static struct resource extpci_mem_resource = { + "pci memory space", + DDB_PCI_MEM_BASE + 0x00100000, /* leave 1 MB for RTC */ + DDB_PCI_MEM_BASE + DDB_PCI_MEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops ddb5476_ext_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&ddb5476_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource}, + {NULL, NULL, NULL} +}; + + +/* + * we fix up irqs based on the slot number. + * The first entry is at AD:11. + * + * This does not work for devices on sub-buses yet. + */ + +/* + * temporary + */ + +#define PCI_EXT_INTA 8 +#define PCI_EXT_INTB 9 +#define PCI_EXT_INTC 10 +#define PCI_EXT_INTD 11 +#define PCI_EXT_INTE 12 + +/* + * based on ddb5477 manual page 11 + */ +#define MAX_SLOT_NUM 21 +static unsigned char irq_map[MAX_SLOT_NUM] = { + /* SLOT: 0, AD:11 */ 0xff, + /* SLOT: 1, AD:12 */ 0xff, + /* SLOT: 2, AD:13 */ 9, + /* USB */ + /* SLOT: 3, AD:14 */ 10, + /* PMU */ + /* SLOT: 4, AD:15 */ 0xff, + /* SLOT: 5, AD:16 */ 0x0, + /* P2P bridge */ + /* SLOT: 6, AD:17 */ nile4_to_irq(PCI_EXT_INTB), + /* SLOT: 7, AD:18 */ nile4_to_irq(PCI_EXT_INTC), + /* SLOT: 8, AD:19 */ nile4_to_irq(PCI_EXT_INTD), + /* SLOT: 9, AD:20 */ nile4_to_irq(PCI_EXT_INTA), + /* SLOT: 10, AD:21 */ 0xff, + /* SLOT: 11, AD:22 */ 0xff, + /* SLOT: 12, AD:23 */ 0xff, + /* SLOT: 13, AD:24 */ 14, + /* HD controller, M5229 */ + /* SLOT: 14, AD:25 */ 0xff, + /* SLOT: 15, AD:26 */ 0xff, + /* SLOT: 16, AD:27 */ 0xff, + /* SLOT: 17, AD:28 */ 0xff, + /* SLOT: 18, AD:29 */ 0xff, + /* SLOT: 19, AD:30 */ 0xff, + /* SLOT: 20, AD:31 */ 0xff +}; + +extern int vrc5477_irq_to_irq(int irq); +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + int slot_num; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot_num = PCI_SLOT(dev->devfn); + + /* we don't do IRQ fixup for sub-bus yet */ + if (dev->bus->parent != NULL) { + db_run(printk + ("Don't know how to fixup irq for PCI device %d on sub-bus %d\n", + slot_num, dev->bus->number)); + continue; + } + + db_assert(slot_num < MAX_SLOT_NUM); + db_assert(irq_map[slot_num] != 0xff); + + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + irq_map[slot_num]); + dev->irq = irq_map[slot_num]; + } +} + +#if defined(CONFIG_RUNTIME_DEBUG) +extern void jsun_scan_pci_bus(void); +#endif + +void __init ddb_pci_reset_bus(void) +{ + u32 temp; + + /* + * I am not sure about the "official" procedure, the following + * steps work as far as I know: + * We first set PCI cold reset bit (bit 31) in PCICTRL-H. + * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. + * The same is true for both PCI channels. + */ + temp = ddb_in32(DDB_PCICTRL + 4); + temp |= 0x80000000; + ddb_out32(DDB_PCICTRL + 4, temp); + temp &= ~0xc0000000; + ddb_out32(DDB_PCICTRL + 4, temp); + +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + /* we hope pci_auto has assigned the bus numbers to all buses */ + return 1; +} + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +void __init pcibios_fixup(void) +{ +} diff -Nru a/arch/mips/pci/pci-ddb5477.c b/arch/mips/pci/pci-ddb5477.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ddb5477.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,299 @@ +/* + * PCI code for DDB5477. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/pci.h> + +#include <asm/bootinfo.h> +#include <asm/pci_channel.h> +#include <asm/debug.h> + +#include <asm/ddb5xxx/ddb5xxx.h> + +static struct resource extpci_io_resource = { + "ext pci IO space", + DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + 0x4000, + DDB_PCI0_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI0_IO_SIZE - 1, + IORESOURCE_IO +}; + +static struct resource extpci_mem_resource = { + "ext pci memory space", + DDB_PCI0_MEM_BASE + 0x100000, + DDB_PCI0_MEM_BASE + DDB_PCI0_MEM_SIZE - 1, + IORESOURCE_MEM +}; + +static struct resource iopci_io_resource = { + "io pci IO space", + DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE, + DDB_PCI1_IO_BASE - DDB_PCI_IO_BASE + DDB_PCI1_IO_SIZE - 1, + IORESOURCE_IO +}; + +static struct resource iopci_mem_resource = { + "ext pci memory space", + DDB_PCI1_MEM_BASE, + DDB_PCI1_MEM_BASE + DDB_PCI1_MEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops ddb5477_ext_pci_ops; +extern struct pci_ops ddb5477_io_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&ddb5477_ext_pci_ops, &extpci_io_resource, &extpci_mem_resource}, + {&ddb5477_io_pci_ops, &iopci_io_resource, &iopci_mem_resource}, + {NULL, NULL, NULL} +}; + + +/* + * we fix up irqs based on the slot number. + * The first entry is at AD:11. + * Fortunately this works because, although we have two pci buses, + * they all have different slot numbers (except for rockhopper slot 20 + * which is handled below). + * + */ + +/* + * irq mapping : device -> pci int # -> vrc4377 irq# , + * ddb5477 board manual page 4 and vrc5477 manual page 46 + */ + +/* + * based on ddb5477 manual page 11 + */ +#define MAX_SLOT_NUM 21 +static unsigned char irq_map[MAX_SLOT_NUM] = { + /* SLOT: 0, AD:11 */ 0xff, + /* SLOT: 1, AD:12 */ 0xff, + /* SLOT: 2, AD:13 */ 0xff, + /* SLOT: 3, AD:14 */ 0xff, + /* SLOT: 4, AD:15 */ VRC5477_IRQ_INTA, + /* onboard tulip */ + /* SLOT: 5, AD:16 */ VRC5477_IRQ_INTB, + /* slot 1 */ + /* SLOT: 6, AD:17 */ VRC5477_IRQ_INTC, + /* slot 2 */ + /* SLOT: 7, AD:18 */ VRC5477_IRQ_INTD, + /* slot 3 */ + /* SLOT: 8, AD:19 */ VRC5477_IRQ_INTE, + /* slot 4 */ + /* SLOT: 9, AD:20 */ 0xff, + /* SLOT: 10, AD:21 */ 0xff, + /* SLOT: 11, AD:22 */ 0xff, + /* SLOT: 12, AD:23 */ 0xff, + /* SLOT: 13, AD:24 */ 0xff, + /* SLOT: 14, AD:25 */ 0xff, + /* SLOT: 15, AD:26 */ 0xff, + /* SLOT: 16, AD:27 */ 0xff, + /* SLOT: 17, AD:28 */ 0xff, + /* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, + /* vrc5477 ac97 */ + /* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, + /* vrc5477 usb peri */ + /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, + /* vrc5477 usb host */ +}; +static unsigned char rockhopperII_irq_map[MAX_SLOT_NUM] = { + /* SLOT: 0, AD:11 */ 0xff, + /* SLOT: 1, AD:12 */ VRC5477_IRQ_INTB, + /* onboard AMD PCNET */ + /* SLOT: 2, AD:13 */ 0xff, + /* SLOT: 3, AD:14 */ 0xff, + /* SLOT: 4, AD:15 */ 14, + /* M5229 ide ISA irq */ + /* SLOT: 5, AD:16 */ VRC5477_IRQ_INTD, + /* slot 3 */ + /* SLOT: 6, AD:17 */ VRC5477_IRQ_INTA, + /* slot 4 */ + /* SLOT: 7, AD:18 */ VRC5477_IRQ_INTD, + /* slot 5 */ + /* SLOT: 8, AD:19 */ 0, + /* M5457 modem nop */ + /* SLOT: 9, AD:20 */ VRC5477_IRQ_INTA, + /* slot 2 */ + /* SLOT: 10, AD:21 */ 0xff, + /* SLOT: 11, AD:22 */ 0xff, + /* SLOT: 12, AD:23 */ 0xff, + /* SLOT: 13, AD:24 */ 0xff, + /* SLOT: 14, AD:25 */ 0xff, + /* SLOT: 15, AD:26 */ 0xff, + /* SLOT: 16, AD:27 */ 0xff, + /* SLOT: 17, AD:28 */ 0, + /* M7101 PMU nop */ + /* SLOT: 18, AD:29 */ VRC5477_IRQ_IOPCI_INTC, + /* vrc5477 ac97 */ + /* SLOT: 19, AD:30 */ VRC5477_IRQ_IOPCI_INTB, + /* vrc5477 usb peri */ + /* SLOT: 20, AD:31 */ VRC5477_IRQ_IOPCI_INTA, + /* vrc5477 usb host */ +}; + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + int slot_num; + unsigned char *slot_irq_map; + unsigned char irq; + + if (mips_machtype == MACH_NEC_ROCKHOPPERII) + slot_irq_map = rockhopperII_irq_map; + else + slot_irq_map = irq_map; + + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot_num = PCI_SLOT(dev->devfn); + irq = slot_irq_map[slot_num]; + + db_assert(slot_num < MAX_SLOT_NUM); + + db_assert(irq != 0xff); + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); + + dev->irq = irq; + + if (mips_machtype == MACH_NEC_ROCKHOPPERII) { + /* hack to distinquish overlapping slot 20s, one + * on bus 0 (ALI USB on the M1535 on the backplane), + * and one on bus 2 (NEC USB controller on the CPU board) + * Make the M1535 USB - ISA IRQ number 9. + */ + if (slot_num == 20 && dev->bus->number == 0) { + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + 9); + dev->irq = 9; + } + } + + } +} + +#if defined(CONFIG_RUNTIME_DEBUG) +extern void jsun_scan_pci_bus(void); +extern void jsun_assign_pci_resource(void); +#endif +void ddb_pci_reset_bus(void) +{ + u32 temp; + + /* + * I am not sure about the "official" procedure, the following + * steps work as far as I know: + * We first set PCI cold reset bit (bit 31) in PCICTRL-H. + * Then we clear the PCI warm reset bit (bit 30) to 0 in PCICTRL-H. + * The same is true for both PCI channels. + */ + temp = ddb_in32(DDB_PCICTL0_H); + temp |= 0x80000000; + ddb_out32(DDB_PCICTL0_H, temp); + temp &= ~0xc0000000; + ddb_out32(DDB_PCICTL0_H, temp); + + temp = ddb_in32(DDB_PCICTL1_H); + temp |= 0x80000000; + ddb_out32(DDB_PCICTL1_H, temp); + temp &= ~0xc0000000; + ddb_out32(DDB_PCICTL1_H, temp); +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + /* we hope pci_auto has assigned the bus numbers to all buses */ + return 1; +} + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ +} + +/* + * fixup baseboard AMD chip so that tx does not underflow. + * bcr_18 |= 0x0800 + * This sets NOUFLO bit which makes tx not start until whole pkt + * is fetched to the chip. + */ +#define PCNET32_WIO_RDP 0x10 +#define PCNET32_WIO_RAP 0x12 +#define PCNET32_WIO_RESET 0x14 +#define PCNET32_WIO_BDP 0x16 +void __init fix_amd_lance(struct pci_dev *dev) +{ + unsigned long ioaddr; + u16 temp; + + ioaddr = pci_resource_start(dev, 0); + + inw(ioaddr + PCNET32_WIO_RESET); /* reset chip */ + + /* bcr_18 |= 0x0800 */ + outw(18, ioaddr + PCNET32_WIO_RAP); + temp = inw(ioaddr + PCNET32_WIO_BDP); + temp |= 0x0800; + outw(18, ioaddr + PCNET32_WIO_RAP); + outw(temp, ioaddr + PCNET32_WIO_BDP); +} + +void __init pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + if (mips_machtype != MACH_NEC_ROCKHOPPERII) + return; + + +#define M1535_CONFIG_PORT 0x3f0 +#define M1535_INDEX_PORT 0x3f0 +#define M1535_DATA_PORT 0x3f1 + + printk("Configuring ALI M1535 Super I/O mouse irq.\n"); + + request_region(M1535_CONFIG_PORT, 2, "M1535 Super I/O config"); + + /* Enter config mode. */ + outb(0x51, M1535_CONFIG_PORT); + outb(0x23, M1535_CONFIG_PORT); + + /* Select device 0x07. */ + outb(0x07, M1535_INDEX_PORT); + outb(0x07, M1535_DATA_PORT); + + /* Set mouse irq (register 0x72) to 12. */ + outb(0x72, M1535_INDEX_PORT); + outb(0x0c, M1535_DATA_PORT); + + /* Exit config mode. */ + outb(0xbb, M1535_CONFIG_PORT); + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + if (dev->vendor == PCI_VENDOR_ID_AL) + if (dev->device == PCI_DEVICE_ID_AL_M1535 + || dev->device == PCI_DEVICE_ID_AL_M1533) { + u8 old; + printk + ("Enabling ALI M1533/35 PS2 keyboard/mouse.\n"); + pci_read_config_byte(dev, 0x41, &old); + pci_write_config_byte(dev, 0x41, old | 0xd0); + } + + if (dev->vendor == PCI_VENDOR_ID_AMD && + dev->device == PCI_DEVICE_ID_AMD_LANCE) + fix_amd_lance(dev); + } +} diff -Nru a/arch/mips/pci/pci-hplj.c b/arch/mips/pci/pci-hplj.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-hplj.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,252 @@ +/* + * 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. + * + * SNI specific PCI support for RM200/RM300. + * + * Copyright (C) 1997 - 2000 Ralf Baechle + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <asm/byteorder.h> +#include <asm/pci_channel.h> +#include <asm/hp-lj/asic.h> + +volatile u32 *pci_config_address_reg = (volatile u32 *) 0xfdead000; +volatile u32 *pci_config_data_reg = (volatile u32 *) 0xfdead000; + + + +#define cfgaddr(dev, where) (((dev->bus->number & 0xff) << 0x10) | \ + ((dev->devfn & 0xff) << 0x08) | \ + (where & 0xfc)) + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int pcimt_read_config_byte(struct pci_dev *dev, + int where, unsigned char *val) +{ + *pci_config_address_reg = cfgaddr(dev, where); + *val = + (le32_to_cpu(*pci_config_data_reg) >> ((where & 3) << 3)) & + 0xff; + //printk("pci_read_byte 0x%x == 0x%x\n", where, *val); + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_word(struct pci_dev *dev, + int where, unsigned short *val) +{ + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(dev, where); + *val = + (le32_to_cpu(*pci_config_data_reg) >> ((where & 3) << 3)) & + 0xffff; + //printk("pci_read_word 0x%x == 0x%x\n", where, *val); + return PCIBIOS_SUCCESSFUL; +} + +int pcimt_read_config_dword(struct pci_dev *dev, + int where, unsigned int *val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(dev, where); + *val = le32_to_cpu(*pci_config_data_reg); + //printk("pci_read_dword 0x%x == 0x%x\n", where, *val); + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_byte(struct pci_dev *dev, + int where, unsigned char val) +{ + *pci_config_address_reg = cfgaddr(dev, where); + *(volatile u8 *) (((int) pci_config_data_reg) + (where & 3)) = val; + //printk("pci_write_byte 0x%x = 0x%x\n", where, val); + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_word(struct pci_dev *dev, + int where, unsigned short val) +{ + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(dev, where); + *(volatile u16 *) (((int) pci_config_data_reg) + (where & 2)) = + le16_to_cpu(val); + //printk("pci_write_word 0x%x = 0x%x\n", where, val); + return PCIBIOS_SUCCESSFUL; +} + +int pcimt_write_config_dword(struct pci_dev *dev, + int where, unsigned int val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + *pci_config_address_reg = cfgaddr(dev, where); + *pci_config_data_reg = le32_to_cpu(val); + //printk("pci_write_dword 0x%x = 0x%x\n", where, val); + return PCIBIOS_SUCCESSFUL; +} + + + +struct pci_ops hp_pci_ops = { + pcimt_read_config_byte, + pcimt_read_config_word, + pcimt_read_config_dword, + pcimt_write_config_byte, + pcimt_write_config_word, + pcimt_write_config_dword +}; + + +struct pci_channel mips_pci_channels[] = { + {&hp_pci_ops, &ioport_resource, &iomem_resource}, + {NULL, NULL, NULL} +}; + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} + +void __init pcibios_fixup(void) +{ +} + + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + int slot_num; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot_num = PCI_SLOT(dev->devfn); + switch (slot_num) { + case 2: + dev->irq = 3; + break; + case 3: + dev->irq = 4; + break; + case 4: + dev->irq = 5; + break; + default: + break; + } + } +} + +#define IO_MEM_LOGICAL_START 0x3e000000 +#define IO_MEM_LOGICAL_END 0x3fefffff + +#define IO_PORT_LOGICAL_START 0x3ff00000 +#define IO_PORT_LOGICAL_END 0x3fffffff + + +#define IO_MEM_VIRTUAL_OFFSET 0xb0000000 +#define IO_PORT_VIRTUAL_OFFSET 0xb0000000 + +#define ONE_MEG (1024 * 1024) + +void __init pci_setup(void) +{ + u32 pci_regs_base_offset = 0xfdead000; + + switch (GetAsicId()) { + case AndrosAsic: + pci_regs_base_offset = 0xbff80000; + break; + case HarmonyAsic: + pci_regs_base_offset = 0xbff70000; + break; + default: + printk("ERROR: PCI does not support %s Asic\n", + GetAsicName()); + while (1); + break; + } + + // set bus stat/command reg + // REVIST this setting may need vary depending on the hardware + *((volatile unsigned int *) (pci_regs_base_offset | 0x0004)) = + 0x38000007; + + + iomem_resource.start = + IO_MEM_LOGICAL_START + IO_MEM_VIRTUAL_OFFSET; + iomem_resource.end = IO_MEM_LOGICAL_END + IO_MEM_VIRTUAL_OFFSET; + + ioport_resource.start = + IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET; + ioport_resource.end = IO_PORT_LOGICAL_END + IO_PORT_VIRTUAL_OFFSET; + + // KLUDGE (mips_io_port_base is screwed up, we've got to work around it here) + // by letting both low (illegal) and high (legal) addresses appear in pci io space + ioport_resource.start = 0x0; + + set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET); + + // map the PCI address space + // global map - all levels & processes can access + // except that the range is outside user space + // parameters: lo0, lo1, hi, pagemask + // lo indicates physical page, hi indicates virtual address + add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17, + ((IO_MEM_LOGICAL_START + + (16 * ONE_MEG)) >> 6) | 0x17, 0xee000000, + PM_16M); + + + // These are used in pci r/w routines so need to preceed bus scan + pci_config_data_reg = (u32 *) (((u32) mips_io_port_base) | 0xcfc); + pci_config_address_reg = + (u32 *) (((u32) pci_regs_base_offset) | 0xcf8); + +} + + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + int pos; + int bases; + + printk("adjusting pci device: %s\n", dev->name); + + switch (dev->hdr_type) { + case PCI_HEADER_TYPE_NORMAL: + bases = 6; + break; + case PCI_HEADER_TYPE_BRIDGE: + bases = 2; + break; + case PCI_HEADER_TYPE_CARDBUS: + bases = 1; + break; + default: + bases = 0; + break; + } + for (pos = 0; pos < bases; pos++) { + struct resource *res = &dev->resource[pos]; + if (res->start >= IO_MEM_LOGICAL_START && + res->end <= IO_MEM_LOGICAL_END) { + res->start += IO_MEM_VIRTUAL_OFFSET; + res->end += IO_MEM_VIRTUAL_OFFSET; + } + if (res->start >= IO_PORT_LOGICAL_START && + res->end <= IO_PORT_LOGICAL_END) { + res->start += IO_PORT_VIRTUAL_OFFSET; + res->end += IO_PORT_VIRTUAL_OFFSET; + } + } + +} diff -Nru a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ip27.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,391 @@ +/* + * 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) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <asm/sn/arch.h> +#include <asm/pci/bridge.h> +#include <asm/paccess.h> +#include <asm/sn/sn0/ip27.h> +#include <asm/sn/sn0/hub.h> + +/* + * Max #PCI busses we can handle; ie, max #PCI bridges. + */ +#define MAX_PCI_BUSSES 40 + +/* + * Max #PCI devices (like scsi controllers) we handle on a bus. + */ +#define MAX_DEVICES_PER_PCIBUS 8 + +/* + * No locking needed until PCI initialization is done parallely. + */ +int irqstore[MAX_PCI_BUSSES][MAX_DEVICES_PER_PCIBUS]; +int lastirq = BASE_PCI_IRQ; + +/* + * Translate from irq to software PCI bus number and PCI slot. + */ +int irq_to_bus[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; +int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; + +/* + * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is + * not really documented, so right now I can't write code which uses it. + * Therefore we use type 0 accesses for now even though they won't work + * correcly for PCI-to-PCI bridges. + */ +#define CF0_READ_PCI_CFG(bus,devfn,where,value,bm,mask) \ +do { \ + bridge_t *bridge; \ + int slot = PCI_SLOT(devfn); \ + int fn = PCI_FUNC(devfn); \ + volatile u32 *addr; \ + u32 cf, __bit; \ + unsigned int bus_id = (unsigned) bus->number; \ + \ + bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], \ + bus_to_wid[bus_id]); \ + \ + __bit = (((where) & (bm)) << 3); \ + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; \ + if (get_dbe(cf, addr)) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + *value = (cf >> __bit) & (mask); \ + return PCIBIOS_SUCCESSFUL; \ +} while (0) + +static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * value) +{ + u32 vprod; + + CF0_READ_PCI_CFG(bus, devfn, PCI_VENDOR_ID, &vprod, 0, 0xffffffff); + if (vprod == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)) + && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) { + *value = 0; + return PCIBIOS_SUCCESSFUL; + } + + if (size == 1) + CF0_READ_PCI_CFG(bus, devfn, where, (u8 *) value, 3, 0xff); + else if (size == 2) + CF0_READ_PCI_CFG(bus, devfn, where, (u16 *) value, 2, + 0xffff); + else + CF0_READ_PCI_CFG(bus, devfn, where, (u32 *) value, 0, + 0xffffffff); +} + +#define CF0_WRITE_PCI_CFG(bus,devfn,where,value,bm,mask) \ +do { \ + bridge_t *bridge; \ + int slot = PCI_SLOT(devfn); \ + int fn = PCI_FUNC(devfn); \ + volatile u32 *addr; \ + u32 cf, __bit; \ + unsigned int bus_id = (unsigned) bus->number; \ + \ + bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], \ + bus_to_wid[bus_id]); \ + \ + __bit = (((where) & (bm)) << 3); \ + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; \ + if (get_dbe(cf, addr)) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + cf &= (~mask); \ + cf |= (value); \ + put_dbe(cf, addr); \ + return PCIBIOS_SUCCESSFUL; \ +} while (0) + +static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ + u32 vprod; + + CF0_READ_PCI_CFG(bus, devfn, PCI_VENDOR_ID, &vprod, 0, 0xffffffff); + if (vprod == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)) + && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) { + return PCIBIOS_SUCCESSFUL; + } + + if (size == 1) + CF0_WRITE_PCI_CFG(bus, devfn, where, (u8) value, 3, 0xff); + else if (size == 2) + CF0_WRITE_PCI_CFG(bus, devfn, where, (u16) value, 2, + 0xffff); + else + CF0_WRITE_PCI_CFG(bus, devfn, where, (u32) value, 0, + 0xffffffff); +} + +static struct pci_ops bridge_pci_ops = { + .read = pci_conf0_read_config, + .write = pci_conf0_write_config, +}; + +static int __init pcibios_init(void) +{ + struct pci_ops *ops = &bridge_pci_ops; + int i; + + ioport_resource.end = ~0UL; + + for (i = 0; i < num_bridges; i++) { + printk("PCI: Probing PCI hardware on host bus %2d.\n", i); + pci_scan_bus(i, ops, NULL); + } + + return 0; +} + +subsys_initcall(pcibios_init); + +static inline u8 bridge_swizzle(u8 pin, u8 slot) +{ + return (((pin - 1) + slot) % 4) + 1; +} + +static u8 __devinit pci_swizzle(struct pci_dev *dev, u8 * pinp) +{ + u8 pin = *pinp; + + while (dev->bus->self) { /* Move up the chain of bridges. */ + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + dev = dev->bus->self; + } + *pinp = pin; + + return PCI_SLOT(dev->devfn); +} + +/* + * All observed requests have pin == 1. We could have a global here, that + * gets incremented and returned every time - unfortunately, pci_map_irq + * may be called on the same device over and over, and need to return the + * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7]. + * + * A given PCI device, in general, should be able to intr any of the cpus + * on any one of the hubs connected to its xbow. + */ +static int __devinit pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if ((dev->bus->number >= MAX_PCI_BUSSES) + || (pin != 1) + || (slot >= MAX_DEVICES_PER_PCIBUS)) + panic("Increase supported PCI busses %d,%d,%d", + dev->bus->number, slot, pin); + + /* + * Already assigned? Then return previously assigned value ... + */ + if (irqstore[dev->bus->number][slot]) + return irqstore[dev->bus->number][slot]; + + irq_to_bus[lastirq] = dev->bus->number; + irq_to_slot[lastirq] = slot; + irqstore[dev->bus->number][slot] = lastirq; + lastirq++; + return lastirq - 1; +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +void __devinit pcibios_fixup_bus(struct pci_bus *b) +{ + pci_fixup_irqs(pci_swizzle, pci_map_irq); +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + /* Not needed, since we enable all devices at startup. */ + return 0; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} + +char *__devinit pcibios_setup(char *str) +{ + /* Nothing to do for now. */ + + return str; +} + +/* + * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses + * to find the slot number in sense of the bridge device register. + * XXX This also means multiple devices might rely on conflicting bridge + * settings. + */ + +static void __init pci_disable_swapping(struct pci_dev *dev) +{ + unsigned int bus_id = (unsigned) dev->bus->number; + bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], + bus_to_wid[bus_id]); + int slot = PCI_SLOT(dev->devfn); + + /* Turn off byte swapping */ + bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR; + bridge->b_widget.w_tflush; /* Flush */ +} + +static void __init pci_enable_swapping(struct pci_dev *dev) +{ + unsigned int bus_id = (unsigned) dev->bus->number; + bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], + bus_to_wid[bus_id]); + int slot = PCI_SLOT(dev->devfn); + + /* Turn on byte swapping */ + bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR; + bridge->b_widget.w_tflush; /* Flush */ +} + +static void __init pci_fixup_ioc3(struct pci_dev *d) +{ + unsigned long bus_id = (unsigned) d->bus->number; + + printk("PCI: Fixing base addresses for IOC3 device %s\n", + d->slot_name); + + d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]); + d->resource[0].end |= NODE_OFFSET(bus_to_nid[bus_id]); + + pci_disable_swapping(d); +} + +static void __init pci_fixup_isp1020(struct pci_dev *d) +{ + unsigned short command; + + d->resource[0].start |= + ((unsigned long) (bus_to_nid[d->bus->number]) << 32); + printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name); + + /* + * Configure device to allow bus mastering, i/o and memory mapping. + * Older qlogicisp driver expects to have the IO space enable + * bit set. Things stop working if we program the controllers as not + * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags. + */ + + pci_set_master(d); + pci_read_config_word(d, PCI_COMMAND, &command); + command |= PCI_COMMAND_MEMORY; + command |= PCI_COMMAND_IO; + pci_write_config_word(d, PCI_COMMAND, command); + d->resource[1].flags |= 1; + + pci_enable_swapping(d); +} + +static void __init pci_fixup_isp2x00(struct pci_dev *d) +{ + unsigned int bus_id = (unsigned) d->bus->number; + bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], + bus_to_wid[bus_id]); + bridgereg_t devreg; + int i; + int slot = PCI_SLOT(d->devfn); + unsigned int start; + unsigned short command; + + printk("PCI: Fixing isp2x00 in [bus:slot.fn] %s\n", d->slot_name); + + /* set the resource struct for this device */ + start = (u32) (u64) bridge; /* yes, we want to lose the upper 32 bits here */ + start |= BRIDGE_DEVIO(slot); + + d->resource[0].start = start; + d->resource[0].end = d->resource[0].start + 0xff; + d->resource[0].flags = IORESOURCE_IO; + + d->resource[1].start = start; + d->resource[1].end = d->resource[0].start + 0xfff; + d->resource[1].flags = IORESOURCE_MEM; + + /* + * set the bridge device(x) reg for this device + */ + devreg = bridge->b_device[slot].reg; + /* point device(x) to it appropriate small window */ + devreg &= ~BRIDGE_DEV_OFF_MASK; + devreg |= (start >> 20) & BRIDGE_DEV_OFF_MASK; + bridge->b_device[slot].reg = devreg; + + pci_enable_swapping(d); + + /* set card's base addr reg */ + //pci_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x500001); + //pci_write_config_dword(d, PCI_BASE_ADDRESS_1, 0x8b00000); + //pci_write_config_dword(d, PCI_ROM_ADDRESS, 0x8b20000); + + /* I got these from booting irix on system... */ + pci_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x200001); + //pci_write_config_dword(d, PCI_BASE_ADDRESS_1, 0xf800000); + pci_write_config_dword(d, PCI_ROM_ADDRESS, 0x10200000); + + pci_write_config_dword(d, PCI_BASE_ADDRESS_1, start); + //pci_write_config_dword(d, PCI_ROM_ADDRESS, (start | 0x20000)); + + /* set cache line size */ + pci_write_config_dword(d, PCI_CACHE_LINE_SIZE, 0xf080); + + /* set pci bus timeout */ + bridge->b_bus_timeout |= BRIDGE_BUS_PCI_RETRY_HLD(0x3); + bridge->b_wid_tflush; + printk("PCI: bridge bus timeout= 0x%x \n", bridge->b_bus_timeout); + + /* set host error field */ + bridge->b_int_host_err = 0x44; + bridge->b_wid_tflush; + + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + for (i = 0; i < 8; i++) + printk("PCI: device(%d)= 0x%x\n", i, + bridge->b_device[i].reg); + + /* configure device to allow bus mastering, i/o and memory mapping */ + pci_set_master(d); + pci_read_config_word(d, PCI_COMMAND, &command); + command |= PCI_COMMAND_MEMORY; + command |= PCI_COMMAND_IO; + pci_write_config_word(d, PCI_COMMAND, command); + /*d->resource[1].flags |= 1; */ +} + +struct pci_fixup pcibios_fixups[] = { + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, + pci_fixup_ioc3}, + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, + PCI_DEVICE_ID_QLOGIC_ISP1020, + pci_fixup_isp1020}, + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, + PCI_DEVICE_ID_QLOGIC_ISP2100, + pci_fixup_isp2x00}, + {PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, + PCI_DEVICE_ID_QLOGIC_ISP2200, + pci_fixup_isp2x00}, + {0} +}; diff -Nru a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ip32.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,457 @@ +/* + * 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) 2000, 2001 Keith M Wesolowski + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <asm/pci.h> +#include <asm/ip32/mace.h> +#include <asm/ip32/crime.h> +#include <asm/ip32/ip32_ints.h> +#include <linux/delay.h> + +#undef DEBUG_MACE_PCI + +/* + * O2 has up to 5 PCI devices connected into the MACE bridge. The device + * map looks like this: + * + * 0 aic7xxx 0 + * 1 aic7xxx 1 + * 2 expansion slot + * 3 N/C + * 4 N/C + */ + +#define chkslot(_bus,_devfn) \ +do { \ + if ((_bus)->number > 0 || PCI_SLOT (_devfn) < 1 \ + || PCI_SLOT (_devfn) > 3) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ +} while (0) + +#define mkaddr(_devfn, where) \ +((((_devfn) & 0xffUL) << 8) | ((where) & 0xfcUL)) + +void macepci_error(int irq, void *dev, struct pt_regs *regs); + +static int macepci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + switch (size) { + case 1: + *val = 0xff; + chkslot(bus, devfn); + mace_write_32(MACEPCI_CONFIG_ADDR, mkaddr(devfn, where)); + *val = + mace_read_8(MACEPCI_CONFIG_DATA + + ((where & 3UL) ^ 3UL)); + + return PCIBIOS_SUCCESSFUL; + + case 2: + *val = 0xffff; + chkslot(bus, devfn); + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mace_write_32(MACEPCI_CONFIG_ADDR, mkaddr(devfn, where)); + *val = + mace_read_16(MACEPCI_CONFIG_DATA + + ((where & 2UL) ^ 2UL)); + + return PCIBIOS_SUCCESSFUL; + + case 4: + *val = 0xffffffff; + chkslot(bus, devfn); + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mace_write_32(MACEPCI_CONFIG_ADDR, mkaddr(devfn, where)); + *val = mace_read_32(MACEPCI_CONFIG_DATA); + + return PCIBIOS_SUCCESSFUL; + } +} + +static int macepci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + switch (size) { + case 1: + chkslot(bus, devfn); + mace_write_32(MACEPCI_CONFIG_ADDR, mkaddr(devfn, where)); + mace_write_8(MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), + val); + + return PCIBIOS_SUCCESSFUL; + + case 2: + chkslot(bus, devfn); + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mace_write_32(MACEPCI_CONFIG_ADDR, mkaddr(devfn, where)); + mace_write_16(MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), + val); + + return PCIBIOS_SUCCESSFUL; + + case 4: + chkslot(bus, devfn); + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mace_write_32(MACEPCI_CONFIG_ADDR, mkaddr(devfn, where)); + mace_write_32(MACEPCI_CONFIG_DATA, val); + + return PCIBIOS_SUCCESSFUL; + } +} + +static struct pci_ops macepci_ops = { + .read = macepci_read_config, + .write = macepci_write_config, +}; + +struct pci_fixup pcibios_fixups[] = { {0} }; + +static int __init pcibios_init(void) +{ + struct pci_dev *dev = NULL; + u32 start, size; + u16 cmd; + u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */ + u32 base_mem = 0x80100000; /* Likewise */ + u32 rev = mace_read_32(MACEPCI_REV); + int i; + + printk("MACE: PCI rev %d detected at %016lx\n", rev, + (u64) MACE_BASE + MACE_PCI); + + /* These are *bus* addresses */ + ioport_resource.start = 0; + ioport_resource.end = 0xffffffffUL; + iomem_resource.start = 0x80000000UL; + iomem_resource.end = 0xffffffffUL; + + /* Clear any outstanding errors and enable interrupts */ + mace_write_32(MACEPCI_ERROR_ADDR, 0); + mace_write_32(MACEPCI_ERROR_FLAGS, 0); + mace_write_32(MACEPCI_CONTROL, 0xff008500); + crime_write_64(CRIME_HARD_INT, 0UL); + crime_write_64(CRIME_SOFT_INT, 0UL); + crime_write_64(CRIME_INT_STAT, 0x000000000000ff00UL); + + if (request_irq(MACE_PCI_BRIDGE_IRQ, macepci_error, 0, + "MACE PCI error", NULL)) + panic("PCI bridge can't get interrupt; can't happen."); + + pci_scan_bus(0, &macepci_ops, NULL); + +#ifdef DEBUG_MACE_PCI + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + printk("Device: %d/%d/%d ARCS-assigned bus resource map\n", + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (dev->resource[i].start == 0) + continue; + printk("%d: %016lx - %016lx (flags %04lx)\n", + i, dev->resource[i].start, + dev->resource[i].end, + dev->resource[i].flags); + } + } +#endif + /* + * Assign sane resources to and enable all devices. The requirement + * for the SCSI controllers is well-known: a 256-byte I/O region + * which we must assign, and a 1-page memory region which is + * assigned by the system firmware. + */ + dev = NULL; + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + switch (PCI_SLOT(dev->devfn)) { + case 1: /* SCSI bus 0 */ + dev->resource[0].start = 0x1000UL; + dev->resource[0].end = 0x10ffUL; + break; + case 2: /* SCSI bus 1 */ + dev->resource[0].start = 0x2000UL; + dev->resource[0].end = 0x20ffUL; + break; + default: /* Slots - I guess we have only 1 */ + for (i = 0; i < 6; i++) { + size = dev->resource[i].end + - dev->resource[i].start; + if (!size + || !(dev->resource[i].flags + & (IORESOURCE_IO | + IORESOURCE_MEM))) { + dev->resource[i].start = + dev->resource[i].end = 0UL; + continue; + } + if (dev->resource[i].flags & IORESOURCE_IO) { + dev->resource[i].start = base_io; + base_io += PAGE_ALIGN(size); + } else { + dev->resource[i].start = base_mem; + base_mem += 0x100000UL; + } + dev->resource[i].end = + dev->resource[i].start + size; + } + break; + } + for (i = 0; i < 6; i++) { + if (dev->resource[i].start == 0) + continue; + start = dev->resource[i].start; + if (dev->resource[i].flags & IORESOURCE_IO) + start |= 1; + pci_write_config_dword(dev, + PCI_BASE_ADDRESS_0 + + (i << 2), (u32) start); + } + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x20); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x30); + pci_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | + PCI_COMMAND_PARITY); + pci_write_config_word(dev, PCI_COMMAND, cmd); + pci_set_master(dev); + } + /* + * Fixup O2 PCI slot. Bad hack. + */ +/* devtag = pci_make_tag(0, 0, 3, 0); + + slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG); + slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE; + macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot); + + slot = macepci_conf_read(0, devtag, PCI_MAPREG_START); + if (slot == 0xffffffe1) + macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000); + + slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2)); + if ((slot & 0xffff0000) == 0) { + slot += 0x00010000; + macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2), + 0x00000000); + } + */ +#ifdef DEBUG_MACE_PCI + printk("Triggering PCI bridge interrupt...\n"); + mace_write_32(MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST); + + dev = NULL; + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + printk("Device: %d/%d/%d final bus resource map\n", + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (dev->resource[i].start == 0) + continue; + printk("%d: %016lx - %016lx (flags %04lx)\n", + i, dev->resource[i].start, + dev->resource[i].end, + dev->resource[i].flags); + } + } +#endif + + return 0; +} + +subsys_initcall(pcibios_init); + +/* + * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of + * the device (1-4 => A-D), tell what irq to use. Note that we don't + * in theory have slots 4 and 5, and we never normally use the shared + * irqs. I suppose a device without a pin A will thank us for doing it + * right if there exists such a broken piece of crap. + */ +static int __devinit macepci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + chkslot(dev->bus, dev->devfn); + if (pin == 0) + pin = 1; + switch (slot) { + case 1: + return MACEPCI_SCSI0_IRQ; + case 2: + return MACEPCI_SCSI1_IRQ; + case 3: + switch (pin) { + case 2: + return MACEPCI_SHARED0_IRQ; + case 3: + return MACEPCI_SHARED1_IRQ; + case 4: + return MACEPCI_SHARED2_IRQ; + case 1: + default: + return MACEPCI_SLOT0_IRQ; + } + case 4: + switch (pin) { + case 2: + return MACEPCI_SHARED2_IRQ; + case 3: + return MACEPCI_SHARED0_IRQ; + case 4: + return MACEPCI_SHARED1_IRQ; + case 1: + default: + return MACEPCI_SLOT1_IRQ; + } + return MACEPCI_SLOT1_IRQ; + case 5: + switch (pin) { + case 2: + return MACEPCI_SHARED1_IRQ; + case 3: + return MACEPCI_SHARED2_IRQ; + case 4: + return MACEPCI_SHARED0_IRQ; + case 1: + default: + return MACEPCI_SLOT2_IRQ; + } + default: + return 0; + } +} + +/* + * It's not entirely clear what this does in a system with no bridges. + * In any case, bridges are not supported by Linux in O2. + */ +static u8 __init macepci_swizzle(struct pci_dev *dev, u8 * pinp) +{ + if (PCI_SLOT(dev->devfn) == 2) + *pinp = 2; + else + *pinp = 1; + return PCI_SLOT(dev->devfn); +} + +/* All devices are enabled during initialization. */ +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return PCIBIOS_SUCCESSFUL; +} + +char *__init pcibios_setup(char *str) +{ + return str; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ +} + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +void __devinit pcibios_fixup_bus(struct pci_bus *b) +{ + pci_fixup_irqs(macepci_swizzle, macepci_map_irq); +} + +/* + * Handle errors from the bridge. This includes master and target aborts, + * various command and address errors, and the interrupt test. This gets + * registered on the bridge error irq. It's conceivable that some of these + * conditions warrant a panic. Anybody care to say which ones? + */ +void macepci_error(int irq, void *dev, struct pt_regs *regs) +{ + u32 flags, error_addr; + char space; + + flags = mace_read_32(MACEPCI_ERROR_FLAGS); + error_addr = mace_read_32(MACEPCI_ERROR_ADDR); + + if (flags & MACEPCI_ERROR_MEMORY_ADDR) + space = 'M'; + else if (flags & MACEPCI_ERROR_CONFIG_ADDR) + space = 'C'; + else + space = 'X'; + + if (flags & MACEPCI_ERROR_MASTER_ABORT) { + printk("MACEPCI: Master abort at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, + flags & ~MACEPCI_ERROR_MASTER_ABORT); + } + if (flags & MACEPCI_ERROR_TARGET_ABORT) { + printk("MACEPCI: Target abort at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, + flags & ~MACEPCI_ERROR_TARGET_ABORT); + } + if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) { + printk("MACEPCI: Data parity error at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, flags + & ~MACEPCI_ERROR_DATA_PARITY_ERR); + } + if (flags & MACEPCI_ERROR_RETRY_ERR) { + printk("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr, + space); + mace_write_32(MACEPCI_ERROR_FLAGS, flags + & ~MACEPCI_ERROR_RETRY_ERR); + } + if (flags & MACEPCI_ERROR_ILLEGAL_CMD) { + printk("MACEPCI: Illegal command at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, + flags & ~MACEPCI_ERROR_ILLEGAL_CMD); + } + if (flags & MACEPCI_ERROR_SYSTEM_ERR) { + printk("MACEPCI: System error at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, flags + & ~MACEPCI_ERROR_SYSTEM_ERR); + } + if (flags & MACEPCI_ERROR_PARITY_ERR) { + printk("MACEPCI: Parity error at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, + flags & ~MACEPCI_ERROR_PARITY_ERR); + } + if (flags & MACEPCI_ERROR_OVERRUN) { + printk("MACEPCI: Overrun error at 0x%08x (%c)\n", + error_addr, space); + mace_write_32(MACEPCI_ERROR_FLAGS, flags + & ~MACEPCI_ERROR_OVERRUN); + } + if (flags & MACEPCI_ERROR_SIG_TABORT) { + printk("MACEPCI: Signaled target abort (clearing)\n"); + mace_write_32(MACEPCI_ERROR_FLAGS, flags + & ~MACEPCI_ERROR_SIG_TABORT); + } + if (flags & MACEPCI_ERROR_INTERRUPT_TEST) { + printk("MACEPCI: Interrupt test triggered (clearing)\n"); + mace_write_32(MACEPCI_ERROR_FLAGS, flags + & ~MACEPCI_ERROR_INTERRUPT_TEST); + } +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 0; +} diff -Nru a/arch/mips/pci/pci-lasat.c b/arch/mips/pci/pci-lasat.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-lasat.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,245 @@ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <asm/bootinfo.h> + +#include <asm/lasat/lasat.h> +#include <asm/gt64120.h> +#include <asm/nile4.h> + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +#undef DEBUG_PCI +#ifdef DEBUG_PCI +#define Dprintk(fmt...) printk(fmt) +#else +#define Dprintk(fmt...) +#endif + +static int (*lasat_pcibios_config_access) (unsigned char access_type, + struct pci_bus * bus, + unsigned int devfn, int where, + u32 * val); + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ +#define GT_WRITE(ofs, data) \ + *(volatile u32 *)(LASAT_GT_BASE+ofs) = cpu_to_le32(data) +#define GT_READ(ofs, data) \ + data = le32_to_cpu(*(volatile u32 *)(LASAT_GT_BASE+ofs)) + + +static int lasat_pcibios_config_access_100(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 * val) +{ + unsigned char busnum = bus->number; + u32 intr; + + if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0))) + return -1; /* Because of a bug in the Galileo (for slot 31). */ + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + if (access_type == PCI_ACCESS_WRITE) { + GT_WRITE(GT_PCI0_CFGDATA_OFS, *val); + } else { + GT_READ(GT_PCI0_CFGDATA_OFS, *val); + } + + /* Check for master or target abort */ + GT_READ(GT_INTRCAUSE_OFS, intr); + + if (intr & + (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) { + /* Error occurred */ + + /* Clear bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + return -1; + } + + return 0; +} + +#define LO(reg) (reg / 4) +#define HI(reg) (reg / 4 + 1) + +volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; + +static int lasat_pcibios_config_access_200(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 * val) +{ + unsigned char busnum = bus->number; + u32 adr, mask, err; + + if ((busnum == 0) && (PCI_SLOT(devfn) > 8)) + /* The addressing scheme chosen leaves room for just + * 8 devices on the first busnum (besides the PCI + * controller itself) */ + return -1; + + if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) { + /* Access controller registers directly */ + if (access_type == PCI_ACCESS_WRITE) { + vrc_pciregs[(0x200 + where) >> 2] = *val; + } else { + *val = vrc_pciregs[(0x200 + where) >> 2]; + } + return 0; + } + + /* Temporarily map PCI Window 1 to config space */ + mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; + vrc_pciregs[LO(NILE4_PCIINIT1)] = + 0x0000001a | (busnum ? 0x200 : 0); + + /* Clear PCI Error register. This also clears the Error Type + * bits in the Control register */ + vrc_pciregs[LO(NILE4_PCIERR)] = 0; + vrc_pciregs[HI(NILE4_PCIERR)] = 0; + + /* Setup address */ + if (busnum == 0) + adr = + KSEG1ADDR(PCI_WINDOW1) + + ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8) + | (where & ~3)); + else + adr = + KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) + | (where & ~3); + +#ifdef DEBUG_PCI + printk("PCI config %s: adr %x", + access_type == PCI_ACCESS_WRITE ? "write" : "read", adr); +#endif + + if (access_type == PCI_ACCESS_WRITE) { + *(u32 *) adr = *val; + } else { + *val = *(u32 *) adr; + } + +#ifdef DEBUG_PCI + printk(" value = %x\n", *val); +#endif + + /* Check for master or target abort */ + err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; + + /* Restore PCI Window 1 */ + vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; + + if (err) { + /* Error occured */ +#ifdef DEBUG_PCI + printk("\terror %x at adr %x\n", err, + vrc_pciregs[LO(NILE4_PCIERR)]); +#endif + return -1; + } + + return 0; +} + +static int lasat_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (lasat_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int lasat_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (lasat_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else + data = val; + + if (lasat_pcibios_config_access + (PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops lasat_pci_ops = { + .read = lasat_pcibios_read, + .write = lasat_pcibios_write, +}; + +static int __init pcibios_init(void) +{ + switch (mips_machtype) { + case MACH_LASAT_100: + lasat_pcibios_config_access = + &lasat_pcibios_config_access_100; + break; + case MACH_LASAT_200: + lasat_pcibios_config_access = + &lasat_pcibios_config_access_200; + break; + default: + panic("pcibios_init: mips_machtype incorrect"); + } + + Dprintk("pcibios_init()\n"); + pci_scan_bus(0, &lasat_pci_ops, NULL); + return 0; +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/pci-mips.c b/arch/mips/pci/pci-mips.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-mips.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,479 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * MIPS boards specific PCI support. + * + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/mips-boards/generic.h> +#include <asm/gt64120.h> +#include <asm/mips-boards/bonito64.h> +#ifdef CONFIG_MIPS_MALTA +#include <asm/mips-boards/malta.h> +#endif +#include <asm/mips-boards/msc01_pci.h> + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +/* + * PCI configuration cycle AD bus definition + */ +/* Type 0 */ +#define PCI_CFG_TYPE0_REG_SHF 0 +#define PCI_CFG_TYPE0_FUNC_SHF 8 + +/* Type 1 */ +#define PCI_CFG_TYPE1_REG_SHF 0 +#define PCI_CFG_TYPE1_FUNC_SHF 8 +#define PCI_CFG_TYPE1_DEV_SHF 11 +#define PCI_CFG_TYPE1_BUS_SHF 16 + +static int mips_pcibios_config_access(unsigned char access_type, + struct pci_bus *bus, + unsigned int devfn, int where, + u32 * data) +{ + unsigned char busnum = bus->number; + unsigned char type; + u32 intr, dummy; + u64 pci_addr; + + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + /* Galileo GT64120 system controller. */ + + if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0))) + return -1; /* Because of a bug in the galileo (for slot 31). */ + + /* Clear cause register bits */ + GT_READ(GT_INTRCAUSE_OFS, intr); + GT_WRITE(GT_INTRCAUSE_OFS, intr & + ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + if (access_type == PCI_ACCESS_WRITE) { + if (busnum == 0 && devfn == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } + } else { + if (busnum == 0 && devfn == 0) { + /* + * The Galileo system controller is acting + * differently than other devices. + */ + GT_READ(GT_PCI0_CFGDATA_OFS, *data); + } else { + GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data); + } + } + + /* Check for master or target abort */ + GT_READ(GT_INTRCAUSE_OFS, intr); + + if (intr & (GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)) { + /* Error occurred */ + + /* Clear bits */ + GT_READ(GT_INTRCAUSE_OFS, intr); + GT_WRITE(GT_INTRCAUSE_OFS, intr & + ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + return -1; + } + + break; + + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + /* Algorithmics Bonito64 system controller. */ + + if ((busnum == 0) && (PCI_SLOT(devfn) == 0)) { + return -1; + } + + /* Clear cause register bits */ + BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR); + + /* + * Setup pattern to be used as PCI "address" for + * Type 0 cycle + */ + if (busnum == 0) { + /* IDSEL */ + pci_addr = (u64) 1 << (PCI_SLOT(devfn) + 10); + } else { + /* Bus number */ + pci_addr = busnum << PCI_CFG_TYPE1_BUS_SHF; + + /* Device number */ + pci_addr |= + PCI_SLOT(devfn) << PCI_CFG_TYPE1_DEV_SHF; + } + + /* Function (same for Type 0/1) */ + pci_addr |= PCI_FUNC(devfn) << PCI_CFG_TYPE0_FUNC_SHF; + + /* Register number (same for Type 0/1) */ + pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF; + + if (busnum == 0) { + /* Type 0 */ + BONITO_PCIMAP_CFG = pci_addr >> 16; + } else { + /* Type 1 */ + BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000; + } + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + /* Perform access */ + if (access_type == PCI_ACCESS_WRITE) { + *(volatile u32 *) (KSEG1ADDR(BONITO_PCICFG_BASE + + (pci_addr & 0xffff))) + = *(u32 *) data; + + /* Wait till done */ + while (BONITO_PCIMSTAT & 0xF); + } else { + *(u32 *) data = + *(volatile u32 + *) (KSEG1ADDR(BONITO_PCICFG_BASE + + (pci_addr & 0xffff))); + } + + /* Detect Master/Target abort */ + if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR)) { + /* Error occurred */ + + /* Clear bits */ + BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | + BONITO_PCICMD_MTABORT_CLR); + + return -1; + } + break; + + case MIPS_REVISION_CORID_CORE_MSC: + /* MIPS system controller. */ + + if ((busnum == 0) && (PCI_SLOT(devfn) == 0)) { + return -1; + } + + /* Clear status register bits. */ + MSC_WRITE(MSC01_PCI_INTSTAT, + (MSC01_PCI_INTCFG_MA_BIT | + MSC01_PCI_INTCFG_TA_BIT)); + + /* Setup address */ + if (busnum == 0) + type = 0; /* Type 0 */ + else + type = 1; /* Type 1 */ + + MSC_WRITE(MSC01_PCI_CFGADDR, + ((busnum << MSC01_PCI_CFGADDR_BNUM_SHF) | + (PCI_SLOT(devfn) << MSC01_PCI_CFGADDR_DNUM_SHF) + | (PCI_FUNC(devfn) << + MSC01_PCI_CFGADDR_FNUM_SHF) | ((where / + 4) << + MSC01_PCI_CFGADDR_RNUM_SHF) + | (type))); + + /* Perform access */ + if (access_type == PCI_ACCESS_WRITE) { + MSC_WRITE(MSC01_PCI_CFGDATA, *data); + } else { + MSC_READ(MSC01_PCI_CFGDATA, *data); + } + + /* Detect Master/Target abort */ + MSC_READ(MSC01_PCI_INTSTAT, intr); + if (intr & (MSC01_PCI_INTCFG_MA_BIT | + MSC01_PCI_INTCFG_TA_BIT)) { + /* Error occurred */ + + /* Clear bits */ + MSC_READ(MSC01_PCI_INTSTAT, intr); + MSC_WRITE(MSC01_PCI_INTSTAT, + (MSC01_PCI_INTCFG_MA_BIT | + MSC01_PCI_INTCFG_TA_BIT)); + + return -1; + } + break; + default: + printk + ("Unknown Core card, don't know the system controller.\n"); + return -1; + } + + return 0; +} + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int mips_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int mips_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (mips_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, + &data)) + return -1; + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (mips_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where, + &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops mips_pci_ops = { + .read = mips_pcibios_read, + .write = mips_pcibios_write +}; + +int mips_pcibios_iack(void) +{ + int irq; + u32 dummy; + + /* + * Determine highest priority pending interrupt by performing + * a PCI Interrupt Acknowledge cycle. + */ + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_MSC: + if (mips_revision_corid == MIPS_REVISION_CORID_CORE_MSC) + MSC_READ(MSC01_PCI_IACK, irq); + else + GT_READ(GT_PCI0_IACK_OFS, irq); + irq &= 0xff; + break; + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + /* The following will generate a PCI IACK cycle on the + * Bonito controller. It's a little bit kludgy, but it + * was the easiest way to implement it in hardware at + * the given time. + */ + BONITO_PCIMAP_CFG = 0x20000; + + /* Flush Bonito register block */ + dummy = BONITO_PCIMAP_CFG; + iob(); /* sync */ + + irq = *(volatile u32 *) (KSEG1ADDR(BONITO_PCICFG_BASE)); + iob(); /* sync */ + irq &= 0xff; + BONITO_PCIMAP_CFG = 0; + break; + default: + printk + ("Unknown Core card, don't know the system controller.\n"); + return -1; + } + return irq; +} + +static int __init pcibios_init(void) +{ +#ifdef CONFIG_MIPS_MALTA + struct pci_dev *pdev = NULL; + unsigned char reg_val; +#endif + + printk("PCI: Probing PCI hardware on host bus 0.\n"); + pci_scan_bus(0, &mips_pci_ops, NULL); + + switch (mips_revision_corid) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + /* + * Due to a bug in the Galileo system controller, we need + * to setup the PCI BAR for the Galileo internal registers. + * This should be done in the bios/bootprom and will be + * fixed in a later revision of YAMON (the MIPS boards + * boot prom). + */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ + (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */ + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0 */ + ((0x20 / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4 */ + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + /* Perform the write */ + GT_WRITE(GT_PCI0_CFGDATA_OFS, PHYSADDR(MIPS_GT_BASE)); + break; + } + +#ifdef CONFIG_MIPS_MALTA + while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { + if ((pdev->vendor == PCI_VENDOR_ID_INTEL) + && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB) + && (PCI_SLOT(pdev->devfn) == 0x0a)) { + /* + * IDE Decode enable. + */ + pci_read_config_byte(pdev, 0x41, ®_val); + pci_write_config_byte(pdev, 0x41, reg_val | 0x80); + pci_read_config_byte(pdev, 0x43, ®_val); + pci_write_config_byte(pdev, 0x43, reg_val | 0x80); + } + + if ((pdev->vendor == PCI_VENDOR_ID_INTEL) + && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB_0) + && (PCI_SLOT(pdev->devfn) == 0x0a)) { + /* + * Set top of main memory accessible by ISA or DMA + * devices to 16 Mb. + */ + pci_read_config_byte(pdev, 0x69, ®_val); + pci_write_config_byte(pdev, 0x69, reg_val | 0xf0); + } + } + + /* + * Activate Floppy Controller in the SMSC FDC37M817 Super I/O + * Controller. + * This should be done in the bios/bootprom and will be fixed in + * a later revision of YAMON (the MIPS boards boot prom). + */ + /* Entering config state. */ + SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); + + /* Activate floppy controller. */ + SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); + SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); + SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); + SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); + + /* Exit config state. */ + SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); +#endif + + return 0; +} + +subsys_initcall(pcibios_init); + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + /* Not needed, since we enable all devices at startup. */ + return 0; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ +} + +char *__init pcibios_setup(char *str) +{ + /* Nothing to do for now. */ + + return str; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +/* + * Called after each bus is probed, but before its children + * are examined. + */ +void __devinit pcibios_fixup_bus(struct pci_bus *b) +{ + pci_read_bridge_bases(b); +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/pci-ocelot-c.c b/arch/mips/pci/pci-ocelot-c.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ocelot-c.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,458 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm <mdharm@momenco.com> + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/version.h> +#include <asm/pci.h> +#include <asm/io.h> +#include <asm/mv64340.h> + +#include <linux/init.h> + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +void mv64340_board_pcibios_fixup_bus(struct pci_bus *c); + +/* Functions to implement "pci ops" */ +static int marvell_pcibios_read_config_word(struct pci_dev *dev, + int offset, u16 * val); +static int marvell_pcibios_read_config_byte(struct pci_dev *dev, + int offset, u8 * val); +static int marvell_pcibios_read_config_dword(struct pci_dev *dev, + int offset, u32 * val); +static int marvell_pcibios_write_config_byte(struct pci_dev *dev, + int offset, u8 val); +static int marvell_pcibios_write_config_word(struct pci_dev *dev, + int offset, u16 val); +static int marvell_pcibios_write_config_dword(struct pci_dev *dev, + int offset, u32 val); +static void marvell_pcibios_set_master(struct pci_dev *dev); + +/* + * General-purpose PCI functions. + */ + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* Accessing device 31 crashes the MV-64340. */ + if (dev < 5) + return 0; + return -1; +} + +/* + * marvell_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int marvell_pcibios_read_config_dword(struct pci_dev *device, + int offset, u32 * val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int marvell_pcibios_read_config_word(struct pci_dev *device, + int offset, u16 * val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* read the data */ + MV_READ_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_read_config_byte(struct pci_dev *device, + int offset, u8 * val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_READ_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_write_config_dword(struct pci_dev *device, + int offset, u32 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int marvell_pcibios_write_config_word(struct pci_dev *device, + int offset, u16 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int marvell_pcibios_write_config_byte(struct pci_dev *device, + int offset, u8 val) +{ + int dev, bus, func; + uint32_t address_reg, data_reg; + uint32_t address; + + bus = device->bus->number; + dev = PCI_SLOT(device->devfn); + func = PCI_FUNC(device->devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the MV-64340 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = MV64340_PCI_0_CONFIG_ADDR; + data_reg = MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG; + } else { + address_reg = MV64340_PCI_1_CONFIG_ADDR; + data_reg = MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + MV_WRITE(address_reg, address); + + /* write the data */ + MV_WRITE_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static void marvell_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + + marvell_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + marvell_pcibios_write_config_word(dev, PCI_COMMAND, cmd); +} + +/* Externally-expected functions. Do not change function names */ + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u8 tmp1; + int idx; + struct resource *r; + + marvell_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of " + "resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + marvell_pcibios_write_config_word(dev, PCI_COMMAND, cmd); + } + + /* + * Let's fix up the latency timer and cache line size here. Cache + * line size = 32 bytes / sizeof dword (4) = 8. + * Latency timer must be > 8. 32 is random but appears to work. + */ + marvell_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); + if (tmp1 != 8) { + printk(KERN_WARNING + "PCI setting cache line size to 8 from " "%d\n", + tmp1); + marvell_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + 8); + } + marvell_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1); + if (tmp1 < 32) { + printk(KERN_WARNING + "PCI setting latency timer to 32 from %d\n", tmp1); + marvell_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER, + 32); + } + + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev); +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} + +struct pci_ops marvell_pci_ops = { + marvell_pcibios_read_config_byte, + marvell_pcibios_read_config_word, + marvell_pcibios_read_config_dword, + marvell_pcibios_write_config_byte, + marvell_pcibios_write_config_word, + marvell_pcibios_write_config_dword +}; + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __init pcibios_fixup_bus(struct pci_bus *c) +{ + mv64340_board_pcibios_fixup_bus(c); +} + +void __init pcibios_init(void) +{ + /* Reset PCI I/O and PCI MEM values */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + pci_scan_bus(0, &marvell_pci_ops, NULL); + pci_scan_bus(1, &marvell_pci_ops, NULL); +} + +/* + * for parsing "pci=" kernel boot arguments. + */ +char *pcibios_setup(char *str) +{ + printk(KERN_INFO "rr: pcibios_setup\n"); + /* Nothing to do for now. */ + + return str; +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/pci-ocelot-g.c b/arch/mips/pci/pci-ocelot-g.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-ocelot-g.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,572 @@ +/* + * Copyright 2002 Momentum Computer + * Author: Matthew Dharm <mdharm@momenco.com> + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/version.h> +#include <asm/pci.h> +#include <asm/io.h> +#include "gt64240.h" + +#include <linux/init.h> + +#define SELF 0 +#define MASTER_ABORT_BIT 0x100 + +/* + * These functions and structures provide the BIOS scan and mapping of the PCI + * devices. + */ + +#define MAX_PCI_DEVS 10 + +void gt64240_board_pcibios_fixup_bus(struct pci_bus *c); + +/* Functions to implement "pci ops" */ +static int galileo_pcibios_read_config_word(int bus, int devfn, + int offset, u16 * val); +static int galileo_pcibios_read_config_byte(int bus, int devfn, + int offset, u8 * val); +static int galileo_pcibios_read_config_dword(int bus, int devfn, + int offset, u32 * val); +static int galileo_pcibios_write_config_byte(int bus, int devfn, + int offset, u8 val); +static int galileo_pcibios_write_config_word(int bus, int devfn, + int offset, u16 val); +static int galileo_pcibios_write_config_dword(int bus, int devfn, + int offset, u32 val); +#if 0 +static void galileo_pcibios_set_master(struct pci_dev *dev); +#endif + +static int pci_read(struct pci_bus *bus, unsigned int devfs, int where, + int size, u32 * val); +static int pci_write(struct pci_bus *bus, unsigned int devfs, int where, + int size, u32 val); + +/* + * General-purpose PCI functions. + */ + + +/* + * pci_range_ck - + * + * Check if the pci device that are trying to access does really exists + * on the evaluation board. + * + * Inputs : + * bus - bus number (0 for PCI 0 ; 1 for PCI 1) + * dev - number of device on the specific pci bus + * + * Outpus : + * 0 - if OK , 1 - if failure + */ +static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev) +{ + /* Accessing device 31 crashes the GT-64240. */ + if (dev < 5) + return 0; + return -1; +} + +/* + * galileo_pcibios_(read/write)_config_(dword/word/byte) - + * + * reads/write a dword/word/byte register from the configuration space + * of a device. + * + * Note that bus 0 and bus 1 are local, and we assume all other busses are + * bridged from bus 1. This is a safe assumption, since any other + * configuration will require major modifications to the CP7000G + * + * Inputs : + * bus - bus number + * dev - device number + * offset - register offset in the configuration space + * val - value to be written / read + * + * Outputs : + * PCIBIOS_SUCCESSFUL when operation was succesfull + * PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous + * PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned + */ + +static int galileo_pcibios_read_config_dword(int bus, int devfn, + int offset, u32 * val) +{ + int dev, func; + uint32_t address_reg, data_reg; + uint32_t address; + + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the GT-64240 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = PCI_0CONFIGURATION_ADDRESS; + data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; + GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); + } else { + address_reg = PCI_1CONFIGURATION_ADDRESS; + data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; + GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); + if (bus == 1) + bus = 0; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + /* read the data */ + GT_READ(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_pcibios_read_config_word(int bus, int devfn, + int offset, u16 * val) +{ + int dev, func; + uint32_t address_reg, data_reg; + uint32_t address; + + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the GT-64240 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = PCI_0CONFIGURATION_ADDRESS; + data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; + GT_WRITE(PCI_0ERROR_CAUSE, ~MASTER_ABORT_BIT); + } else { + address_reg = PCI_1CONFIGURATION_ADDRESS; + data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; + GT_WRITE(PCI_1ERROR_CAUSE, ~MASTER_ABORT_BIT); + if (bus == 1) + bus = 0; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + /* read the data */ + GT_READ_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_read_config_byte(int bus, int devfn, + int offset, u8 * val) +{ + int dev, func; + uint32_t address_reg, data_reg; + uint32_t address; + + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the GT-64240 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = PCI_0CONFIGURATION_ADDRESS; + data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; + } else { + address_reg = PCI_1CONFIGURATION_ADDRESS; + data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; + if (bus == 1) + bus = 0; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + /* write the data */ + GT_READ_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write_config_dword(int bus, int devfn, + int offset, u32 val) +{ + int dev, func; + uint32_t address_reg, data_reg; + uint32_t address; + + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the GT-64240 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = PCI_0CONFIGURATION_ADDRESS; + data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; + } else { + address_reg = PCI_1CONFIGURATION_ADDRESS; + data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; + if (bus == 1) + bus = 0; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + /* write the data */ + GT_WRITE(data_reg, val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_pcibios_write_config_word(int bus, int devfn, + int offset, u16 val) +{ + int dev, func; + uint32_t address_reg, data_reg; + uint32_t address; + + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the GT-64240 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = PCI_0CONFIGURATION_ADDRESS; + data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; + } else { + address_reg = PCI_1CONFIGURATION_ADDRESS; + data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; + if (bus == 1) + bus = 0; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + /* write the data */ + GT_WRITE_16(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_pcibios_write_config_byte(int bus, int devfn, + int offset, u8 val) +{ + int dev, func; + uint32_t address_reg, data_reg; + uint32_t address; + + dev = PCI_SLOT(devfn); + func = PCI_FUNC(devfn); + + /* verify the range */ + if (pci_range_ck(bus, dev)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* select the GT-64240 registers to communicate with the PCI bus */ + if (bus == 0) { + address_reg = PCI_0CONFIGURATION_ADDRESS; + data_reg = PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER; + } else { + address_reg = PCI_1CONFIGURATION_ADDRESS; + data_reg = PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER; + if (bus == 1) + bus = 0; + } + + address = (bus << 16) | (dev << 11) | (func << 8) | + (offset & 0xfc) | 0x80000000; + + /* start the configuration cycle */ + GT_WRITE(address_reg, address); + + /* write the data */ + GT_WRITE_8(data_reg + (offset & 0x3), val); + + return PCIBIOS_SUCCESSFUL; +} + +#if 0 +static void galileo_pcibios_set_master(struct pci_dev *dev) +{ + u16 cmd; + + galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd); +} +#endif + +/* Externally-expected functions. Do not change function names */ + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + u8 tmp1; + int idx; + struct resource *r; + + pci_read(dev->bus, dev->devfn, PCI_COMMAND, 2, (u32 *) & cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because of " + "resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + pci_write(dev->bus, dev->devfn, PCI_COMMAND, 2, cmd); + } + + /* + * Let's fix up the latency timer and cache line size here. Cache + * line size = 32 bytes / sizeof dword (4) = 8. + * Latency timer must be > 8. 32 is random but appears to work. + */ + pci_read(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 1, + (u32 *) & tmp1); + if (tmp1 != 8) { + printk(KERN_WARNING + "PCI setting cache line size to 8 from " "%d\n", + tmp1); + pci_write(dev->bus, dev->devfn, PCI_CACHE_LINE_SIZE, 1, 8); + } + pci_read(dev->bus, dev->devfn, PCI_LATENCY_TIMER, 1, + (u32 *) & tmp1); + if (tmp1 < 32) { + printk(KERN_WARNING + "PCI setting latency timer to 32 from %d\n", tmp1); + pci_write(dev->bus, dev->devfn, PCI_LATENCY_TIMER, 1, 32); + } + + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + return pcibios_enable_resources(dev); +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + struct pci_dev *dev = data; + + if (res->flags & IORESOURCE_IO) { + unsigned long start = res->start; + + /* We need to avoid collisions with `mirrored' VGA ports + and other strange ISA hardware, so we always want the + addresses kilobyte aligned. */ + if (size > 0x100) { + printk(KERN_ERR "PCI: I/O Region %s/%d too large" + " (%ld bytes)\n", dev->slot_name, + dev->resource - res, size); + } + + start = (start + 1024 - 1) & ~(1024 - 1); + res->start = start; + } +} + +struct pci_ops galileo_pci_ops = { + .read = pci_read, + .write = pci_write +}; + +static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 * val) +{ + switch (size) { + case 1: + return galileo_pcibios_read_config_byte(bus->number, + devfn, where, + (u8 *) val); + case 2: + return galileo_pcibios_read_config_word(bus->number, + devfn, where, + (u16 *) val); + case 4: + return galileo_pcibios_read_config_dword(bus->number, + devfn, where, + (u32 *) val); + } + return PCIBIOS_FUNC_NOT_SUPPORTED; +} + +static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + switch (size) { + case 1: + return galileo_pcibios_write_config_byte(bus->number, + devfn, where, + val); + case 2: + return galileo_pcibios_write_config_word(bus->number, + devfn, where, + val); + case 4: + return galileo_pcibios_write_config_dword(bus->number, + devfn, where, + val); + } + return PCIBIOS_FUNC_NOT_SUPPORTED; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +void __devinit pcibios_fixup_bus(struct pci_bus *c) +{ + gt64240_board_pcibios_fixup_bus(c); +} + + +/******************************************************************** +* pci0P2PConfig - This function set the PCI_0 P2P configurate. +* For more information on the P2P read PCI spec. +* +* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower +* Boundry. +* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper +* Boundry. +* unsigned int busNum - The CPI bus number to which the PCI interface +* is connected. +* unsigned int devNum - The PCI interface's device number. +* +* Returns: true. +*/ +void pci0P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, + unsigned int busNum, unsigned int devNum) +{ + uint32_t regData; + + regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | + ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); + GT_WRITE(PCI_0P2P_CONFIGURATION, regData); +} + +/******************************************************************** +* pci1P2PConfig - This function set the PCI_1 P2P configurate. +* For more information on the P2P read PCI spec. +* +* Inputs: unsigned int SecondBusLow - Secondery PCI interface Bus Range Lower +* Boundry. +* unsigned int SecondBusHigh - Secondry PCI interface Bus Range upper +* Boundry. +* unsigned int busNum - The CPI bus number to which the PCI interface +* is connected. +* unsigned int devNum - The PCI interface's device number. +* +* Returns: true. +*/ +void pci1P2PConfig(unsigned int SecondBusLow, unsigned int SecondBusHigh, + unsigned int busNum, unsigned int devNum) +{ + uint32_t regData; + + regData = (SecondBusLow & 0xff) | ((SecondBusHigh & 0xff) << 8) | + ((busNum & 0xff) << 16) | ((devNum & 0x1f) << 24); + GT_WRITE(PCI_1P2P_CONFIGURATION, regData); +} + +#define PCI0_STATUS_COMMAND_REG 0x4 +#define PCI1_STATUS_COMMAND_REG 0x84 + +static int __init pcibios_init(void) +{ + /* Reset PCI I/O and PCI MEM values */ + ioport_resource.start = 0xe0000000; + ioport_resource.end = 0xe0000000 + 0x20000000 - 1; + iomem_resource.start = 0xc0000000; + iomem_resource.end = 0xc0000000 + 0x20000000 - 1; + + pci_scan_bus(0, &galileo_pci_ops, NULL); + pci_scan_bus(1, &galileo_pci_ops, NULL); + + return 0; +} + +subsys_initcall(pcibios_init); + +/* + * for parsing "pci=" kernel boot arguments. + */ +char *pcibios_setup(char *str) +{ + printk(KERN_INFO "rr: pcibios_setup\n"); + /* Nothing to do for now. */ + + return str; +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-sb1250.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2001,2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * BCM1250-specific PCI support + * + * This module provides the glue between Linux's PCI subsystem + * and the hardware. We basically provide glue for accessing + * configuration space, and set up the translation for I/O + * space accesses. + * + * To access configuration space, we use ioremap. In the 32-bit + * kernel, this consumes either 4 or 8 page table pages, and 16MB of + * kernel mapped memory. Hopefully neither of these should be a huge + * problem. + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/mm.h> +#include <linux/console.h> + +#include <asm/sibyte/sb1250_defs.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/io.h> + +/* + * Macros for calculating offsets into config space given a device + * structure or dev/fun/reg + */ +#define CFGOFFSET(bus,devfn,where) (((bus)<<16) + ((devfn)<<8) + (where)) +#define CFGADDR(bus,devfn,where) CFGOFFSET((bus)->number,(devfn),where) + +static void *cfg_space; + +#define PCI_BUS_ENABLED 1 +#define LDT_BUS_ENABLED 2 +#define PCI_DEVICE_MODE 4 + +static int sb1250_bus_status = 0; + +#define PCI_BRIDGE_DEVICE 0 +#define LDT_BRIDGE_DEVICE 1 + +#ifdef CONFIG_SIBYTE_HAS_LDT +/* + * HT's level-sensitive interrupts require EOI, which is generated + * through a 4MB memory-mapped region + */ +unsigned long ldt_eoi_space; +#endif + +/* + * Read/write 32-bit values in config space. + */ +static inline u32 READCFG32(u32 addr) +{ + return *(u32 *) (cfg_space + (addr & ~3)); +} + +static inline void WRITECFG32(u32 addr, u32 data) +{ + *(u32 *) (cfg_space + (addr & ~3)) = data; +} + +/* + * Some checks before doing config cycles: + * In PCI Device Mode, hide everything on bus 0 except the LDT host + * bridge. Otherwise, access is controlled by bridge MasterEn bits. + */ +static int sb1250_pci_can_access(struct pci_bus *bus, int devfn) +{ + u32 devno; + + if (!(sb1250_bus_status & (PCI_BUS_ENABLED | PCI_DEVICE_MODE))) + return 0; + + if (bus->number == 0) { + devno = PCI_SLOT(devfn); + if (devno == LDT_BRIDGE_DEVICE) + return (sb1250_bus_status & LDT_BUS_ENABLED) != 0; + else if (sb1250_bus_status & PCI_DEVICE_MODE) + return 0; + else + return 1; + } else + return 1; +} + +/* + * Read/write access functions for various sizes of values + * in config space. Return all 1's for disallowed accesses + * for a kludgy but adequate simulation of master aborts. + */ + +static int sb1250_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (sb1250_pci_can_access(bus, devfn)) + data = READCFG32(CFGADDR(bus, devfn, where)); + else + data = 0xFFFFFFFF; + + if (size == 1) + *val = (data >> ((where & 3) << 3)) & 0xff; + else if (size == 2) + *val = (data >> ((where & 3) << 3)) & 0xffff; + else + *val = data; + + return PCIBIOS_SUCCESSFUL; +} + +static int sb1250_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 cfgaddr = CFGADDR(bus, devfn, where); + u32 data = 0; + + if ((size == 2) && (where & 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + else if ((size == 4) && (where & 3)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (!sb1250_pci_can_access(bus, devfn)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + data = READCFG32(cfgaddr); + + if (size == 1) + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + else if (size == 2) + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + WRITECFG32(cfgaddr, data); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops sb1250_pci_ops = { + .read = sb1250_pcibios_read, + .write = sb1250_pcibios_write +}; + + +void __init pcibios_init(void) +{ + uint32_t cmdreg; + uint64_t reg; + + cfg_space = + ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024); + + /* + * See if the PCI bus has been configured by the firmware. + */ + reg = *((volatile uint64_t *) KSEG1ADDR(A_SCD_SYSTEM_CFG)); + if (!(reg & M_SYS_PCI_HOST)) { + sb1250_bus_status |= PCI_DEVICE_MODE; + } else { + cmdreg = + READCFG32(CFGOFFSET + (0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), + PCI_COMMAND)); + if (!(cmdreg & PCI_COMMAND_MASTER)) { + printk + ("PCI: Skipping PCI probe. Bus is not initialized.\n"); + iounmap(cfg_space); + return; + } + sb1250_bus_status |= PCI_BUS_ENABLED; + } + + /* + * Establish mappings in KSEG2 (kernel virtual) to PCI I/O + * space. Use "match bytes" policy to make everything look + * little-endian. So, you need to also set + * CONFIG_SWAP_IO_SPACE, but this is the combination that + * works correctly with most of Linux's drivers. + * XXX ehs: Should this happen in PCI Device mode? + */ + + set_io_port_base((unsigned long) + ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES, 65536)); + isa_slot_offset = (unsigned long) + ioremap(A_PHYS_LDTPCI_IO_MATCH_BYTES_32, 1024 * 1024); + +#ifdef CONFIG_SIBYTE_HAS_LDT + /* + * Also check the LDT bridge's enable, just in case we didn't + * initialize that one. + */ + + cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(LDT_BRIDGE_DEVICE, 0), + PCI_COMMAND)); + if (cmdreg & PCI_COMMAND_MASTER) { + sb1250_bus_status |= LDT_BUS_ENABLED; + + /* + * Need bits 23:16 to convey vector number. Note that + * this consumes 4MB of kernel-mapped memory + * (Kseg2/Kseg3) for 32-bit kernel. + */ + ldt_eoi_space = (unsigned long) + ioremap(A_PHYS_LDT_SPECIAL_MATCH_BYTES, + 4 * 1024 * 1024); + } +#endif + + /* Probe for PCI hardware */ + + printk("PCI: Probing PCI hardware on host bus 0.\n"); + pci_scan_bus(0, &sb1250_pci_ops, NULL); + +#ifdef CONFIG_VGA_CONSOLE + take_over_console(&vga_con, 0, MAX_NR_CONSOLES - 1, 1); +#endif +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + /* Not needed, since we enable all devices at startup. */ + return 0; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ +} + +char *__init pcibios_setup(char *str) +{ + /* Nothing to do for now. */ + + return str; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; + +/* + * Called after each bus is probed, but before its children + * are examined. + */ +void __devinit pcibios_fixup_bus(struct pci_bus *b) +{ + pci_read_bridge_bases(b); +} + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} diff -Nru a/arch/mips/pci/pci-sni.c b/arch/mips/pci/pci-sni.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-sni.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,175 @@ +/* + * 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. + * + * SNI specific PCI support for RM200/RM300. + * + * Copyright (C) 1997 - 2000 Ralf Baechle + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <asm/byteorder.h> +#include <asm/sni.h> + +#define mkaddr(bus, devfn, where) \ +do { \ + if (bus->number == 0) \ + return -1; \ + *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ + ((bus->number & 0xff) << 0x10) | \ + ((devfn & 0xff) << 0x08) | \ + (where & 0xfc); \ +} while(0) + +#if 0 +/* To do: Bring this uptodate ... */ +static void pcimt_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + /* + * TODO: Take care of RM300 revision D boards for where the + * network slot became an ordinary PCI slot. + */ + if (dev->devfn == PCI_DEVFN(1, 0)) { + /* Evil hack ... */ + set_cp0_config(CONF_CM_CMASK, + CONF_CM_CACHABLE_NO_WA); + dev->irq = PCIMT_IRQ_SCSI; + continue; + } + if (dev->devfn == PCI_DEVFN(2, 0)) { + dev->irq = PCIMT_IRQ_ETHERNET; + continue; + } + + switch (dev->irq) { + case 1...4: + dev->irq += PCIMT_IRQ_INTA - 1; + break; + case 0: + break; + default: + printk("PCI device on bus %d, dev %d, function %d " + "impossible interrupt configured.\n", + dev->bus->number, PCI_SLOT(dev->devfn), + PCI_SLOT(dev->devfn)); + } + } +} +#endif + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 * val) +{ + u32 res; + + switch (size) { + case 1: + mkaddr(bus, devfn, where); + res = *(volatile u32 *) PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; + *val = (u8) res; + break; + case 2: + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(bus, devfn, where); + res = *(volatile u32 *) PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; + *val = (u16) res; + break; + case 4: + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(bus, devfn, where); + res = *(volatile u32 *) PCIMT_CONFIG_DATA; + res = le32_to_cpu(res); + *val = res; + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 val) +{ + switch (size) { + case 1: + mkaddr(bus, devfn, where); + *(volatile u8 *) (PCIMT_CONFIG_DATA + (where & 3)) = + (u8) le32_to_cpu(val); + break; + case 2: + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(bus, devfn, where); + *(volatile u16 *) (PCIMT_CONFIG_DATA + (where & 3)) = + (u16) le32_to_cpu(val); + break; + case 4: + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(bus, devfn, where); + *(volatile u32 *) PCIMT_CONFIG_DATA = le32_to_cpu(val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops sni_pci_ops = { + .read = pcimt_read, + .write = pcimt_write, +}; + +void __devinit pcibios_fixup_bus(struct pci_bus *b) +{ +} + +static int __init pcibios_init(void) +{ + struct pci_ops *ops = &sni_pci_ops; + + pci_scan_bus(0, ops, NULL); + + return 0; +} + +subsys_initcall(pcibios_init); + +int __init pcibios_enable_device(struct pci_dev *dev, int mask) +{ + /* Not needed, since we enable all devices at startup. */ + return 0; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 0; +} + +char *__init pcibios_setup(char *str) +{ + /* Nothing to do for now. */ + + return str; +} + +struct pci_fixup pcibios_fixups[] = { + {0} +}; diff -Nru a/arch/mips/pci/pci-vr41xx.c b/arch/mips/pci/pci-vr41xx.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-vr41xx.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,233 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/pciu.c + * + * BRIEF MODULE DESCRIPTION + * PCI Control Unit routines for the NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * Paul Mundt <lethal@chaoticdreams.org> + * - Fix deadlock-causing PCIU access race for VR4131. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <linux/delay.h> + +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/pci_channel.h> +#include <asm/vr41xx/vr41xx.h> + +#include "pciu.h" + +extern unsigned long vr41xx_vtclock; + +static inline int vr41xx_pci_config_access(unsigned char bus, + unsigned int devfn, int where) +{ + if (bus == 0) { + /* + * Type 0 configuration + */ + if (PCI_SLOT(devfn) < 11 || where > 255) + return -1; + + writel((1UL << PCI_SLOT(devfn)) | + (PCI_FUNC(devfn) << 8) | + (where & 0xfc), PCICONFAREG); + } else { + /* + * Type 1 configuration + */ + if (where > 255) + return -1; + + writel((bus << 16) | + (devfn << 8) | (where & 0xfc) | 1UL, PCICONFAREG); + } + + return 0; +} + +static int vr41xx_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data; + + *val = 0xffffffffUL; + if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xffUL; + break; + case 2: + *val = (data >> ((where & 2) << 3)) & 0xffffUL; + break; + case 4: + *val = data; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int vr41xx_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data; + int shift; + + if (vr41xx_pci_config_access(bus->number, devfn, where) < 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + data = readl(PCICONFDREG); + + switch (size) { + case 1: + shift = (where & 3) << 3; + data &= ~(0xff << shift); + data |= ((val & 0xff) << shift); + break; + case 2: + shift = (where & 2) << 3; + data &= ~(0xffff << shift); + data |= ((val & 0xffff) << shift); + break; + case 4: + data = val; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + writel(data, PCICONFDREG); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops vr41xx_pci_ops = { + .read = vr41xx_pci_config_read, + .write = vr41xx_pci_config_write, +}; + +void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map) +{ + struct vr41xx_pci_address_space *s; + u32 config; + int n; + + if (!map) + return; + + /* Disable PCI interrupt */ + writew(0, MPCIINTREG); + + /* Supply VTClock to PCIU */ + vr41xx_clock_supply(PCIU_CLOCK); + + /* + * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK + * before doing any PCIU access to avoid deadlock on VR4131. + */ + udelay(1); + + /* Select PCI clock */ + if (vr41xx_vtclock < MAX_PCI_CLOCK) + writel(EQUAL_VTCLOCK, PCICLKSELREG); + else if ((vr41xx_vtclock / 2) < MAX_PCI_CLOCK) + writel(HALF_VTCLOCK, PCICLKSELREG); + else if ((vr41xx_vtclock / 4) < MAX_PCI_CLOCK) + writel(QUARTER_VTCLOCK, PCICLKSELREG); + else + printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n"); + + /* Supply PCI clock by PCI bus */ + vr41xx_clock_supply(PCI_CLOCK); + + /* + * Set PCI memory & I/O space address conversion registers + * for master transaction. + */ + if (map->mem1 != NULL) { + s = map->mem1; + config = (s->internal_base & 0xff000000) | + ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | + ((s->pci_base & 0xff000000) >> 24); + writel(config, PCIMMAW1REG); + } + if (map->mem2 != NULL) { + s = map->mem2; + config = (s->internal_base & 0xff000000) | + ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | + ((s->pci_base & 0xff000000) >> 24); + writel(config, PCIMMAW2REG); + } + if (map->io != NULL) { + s = map->io; + config = (s->internal_base & 0xff000000) | + ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) | + ((s->pci_base & 0xff000000) >> 24); + writel(config, PCIMIOAWREG); + } + + /* Set target memory windows */ + writel(0x00081000, PCITAW1REG); + writel(0UL, PCITAW2REG); + pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL); + pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL); + + /* Clear bus error */ + n = readl(BUSERRADREG); + + if (current_cpu_data.cputype == CPU_VR4122) { + writel(0UL, PCITRDYVREG); + pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804); + } else { + writel(100UL, PCITRDYVREG); + pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004); + } + + writel(CONFIG_DONE, PCIENREG); + pciu_write_config_dword(PCI_COMMAND, + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR); +} diff -Nru a/arch/mips/pci/pci-vr41xx.h b/arch/mips/pci/pci-vr41xx.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci-vr41xx.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,167 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/pciu.h + * + * BRIEF MODULE DESCRIPTION + * Include file for PCI Control Unit of the NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#ifndef __VR41XX_PCIU_H +#define __VR41XX_PCIU_H + +#include <linux/config.h> +#include <asm/addrspace.h> + +#define BIT(x) (1 << (x)) + +#define PCIMMAW1REG KSEG1ADDR(0x0f000c00) +#define PCIMMAW2REG KSEG1ADDR(0x0f000c04) +#define PCITAW1REG KSEG1ADDR(0x0f000c08) +#define PCITAW2REG KSEG1ADDR(0x0f000c0c) +#define PCIMIOAWREG KSEG1ADDR(0x0f000c10) +#define INTERNAL_BUS_BASE_ADDRESS 0xff000000 +#define ADDRESS_MASK 0x000fe000 +#define PCI_ACCESS_ENABLE BIT(12) +#define PCI_ADDRESS_SETTING 0x000000ff + +#define PCICONFDREG KSEG1ADDR(0x0f000c14) +#define PCICONFAREG KSEG1ADDR(0x0f000c18) +#define PCIMAILREG KSEG1ADDR(0x0f000c1c) + +#define BUSERRADREG KSEG1ADDR(0x0f000c24) +#define ERROR_ADDRESS 0xfffffffc + +#define INTCNTSTAREG KSEG1ADDR(0x0f000c28) +#define MABTCLR BIT(31) +#define TRDYCLR BIT(30) +#define PARCLR BIT(29) +#define MBCLR BIT(28) +#define SERRCLR BIT(27) + +#define PCIEXACCREG KSEG1ADDR(0x0f000c2c) +#define UNLOCK BIT(1) +#define EAREQ BIT(0) + +#define PCIRECONTREG KSEG1ADDR(0x0f000c30) +#define RTRYCNT 0x000000ff + +#define PCIENREG KSEG1ADDR(0x0f000c34) +#define CONFIG_DONE BIT(2) + +#define PCICLKSELREG KSEG1ADDR(0x0f000c38) +#define EQUAL_VTCLOCK 0x00000002 +#define HALF_VTCLOCK 0x00000000 +#define QUARTER_VTCLOCK 0x00000001 + +#define PCITRDYVREG KSEG1ADDR(0x0f000c3c) + +#define PCICLKRUNREG KSEG1ADDR(0x0f000c60) + +#define PCIU_CONFIGREGS_BASE KSEG1ADDR(0x0f000d00) +#define VENDORIDREG KSEG1ADDR(0x0f000d00) +#define DEVICEIDREG KSEG1ADDR(0x0f000d00) +#define COMMANDREG KSEG1ADDR(0x0f000d04) +#define STATUSREG KSEG1ADDR(0x0f000d04) +#define REVIDREG KSEG1ADDR(0x0f000d08) +#define CLASSREG KSEG1ADDR(0x0f000d08) +#define CACHELSREG KSEG1ADDR(0x0f000d0c) +#define LATTIMEREG KSEG1ADDR(0x0f000d0c) +#define MAILBAREG KSEG1ADDR(0x0f000d10) +#define PCIMBA1REG KSEG1ADDR(0x0f000d14) +#define PCIMBA2REG KSEG1ADDR(0x0f000d18) +#define INTLINEREG KSEG1ADDR(0x0f000d3c) +#define INTPINREG KSEG1ADDR(0x0f000d3c) +#define RETVALREG KSEG1ADDR(0x0f000d40) +#define PCIAPCNTREG KSEG1ADDR(0x0f000d40) + +#define MPCIINTREG KSEG1ADDR(0x0f0000b2) + +#define MAX_PCI_CLOCK 33333333 + +#define PCIU_CLOCK 0x0080 +#define PCI_CLOCK 0x2000 + +static inline int pciu_read_config_byte(int where, u8 * val) +{ + u32 data; + + data = readl(PCIU_CONFIGREGS_BASE + where); + *val = (u8) (data >> ((where & 3) << 3)); + + return PCIBIOS_SUCCESSFUL; +} + +static inline int pciu_read_config_word(int where, u16 * val) +{ + u32 data; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + data = readl(PCIU_CONFIGREGS_BASE + where); + *val = (u16) (data >> ((where & 2) << 3)); + + return PCIBIOS_SUCCESSFUL; +} + +static inline int pciu_read_config_dword(int where, u32 * val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + *val = readl(PCIU_CONFIGREGS_BASE + where); + + return PCIBIOS_SUCCESSFUL; +} + +static inline int pciu_write_config_byte(int where, u8 val) +{ + writel(val, PCIU_CONFIGREGS_BASE + where); + + return 0; +} + +static inline int pciu_write_config_word(int where, u16 val) +{ + writel(val, PCIU_CONFIGREGS_BASE + where); + + return 0; +} + +static inline int pciu_write_config_dword(int where, u32 val) +{ + writel(val, PCIU_CONFIGREGS_BASE + where); + + return 0; +} + +#endif /* __VR41XX_PCIU_H */ diff -Nru a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/pci/pci.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,233 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Modified to be mips generic, ppopov@mvista.com + * arch/mips/kernel/pci.c + * Common MIPS PCI routines. + * + * 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 contains common PCI routines meant to be shared for + * all MIPS machines. + * + * Strategies: + * + * . We rely on pci_auto.c file to assign PCI resources (MEM and IO) + * TODO: this should be optional for some machines where they do have + * a real "pcibios" that does resource assignment. + * + * . We then use pci_scan_bus() to "discover" all the resources for + * later use by Linux. + * + * . We finally reply on a board supplied function, pcibios_fixup_irq(), to + * to assign the interrupts. We may use setup-irq.c under drivers/pci + * later. + * + * . Specifically, we will *NOT* use pci_assign_unassigned_resources(), + * because we assume all PCI devices should have the resources correctly + * assigned and recorded. + * + * Limitations: + * + * . We "collapse" all IO and MEM spaces in sub-buses under a top-level bus + * into a contiguous range. + * + * . In the case of Memory space, the rnage is 1:1 mapping with CPU physical + * address space. + * + * . In the case of IO space, it starts from 0, and the beginning address + * is mapped to KSEG0ADDR(mips_io_port) in the CPU physical address. + * + * . These are the current MIPS limitations (by ioremap, etc). In the + * future, we may remove them. + * + * Credits: + * Most of the code are derived from the pci routines from PPC and Alpha, + * which were mostly writtne by + * Cort Dougan, cort@fsmlabs.com + * Matt Porter, mporter@mvista.com + * Dave Rusling david.rusling@reo.mts.dec.com + * David Mosberger davidm@cs.arizona.edu + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/pci.h> + +#include <asm/pci_channel.h> + +extern void pcibios_fixup(void); +extern void pcibios_fixup_irqs(void); + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = NULL; + int slot_num; + + + while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + slot_num = PCI_SLOT(dev->devfn); + switch (slot_num) { + case 2: + dev->irq = 3; + break; + case 3: + dev->irq = 4; + break; + case 4: + dev->irq = 5; + break; + default: + break; + } + } +} + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ /* HP-LJ */ + int pos; + int bases; + + printk("adjusting pci device: %s\n", dev->name); + + switch (dev->hdr_type) { + case PCI_HEADER_TYPE_NORMAL: + bases = 6; + break; + case PCI_HEADER_TYPE_BRIDGE: + bases = 2; + break; + case PCI_HEADER_TYPE_CARDBUS: + bases = 1; + break; + default: + bases = 0; + break; + } + for (pos = 0; pos < bases; pos++) { + struct resource *res = &dev->resource[pos]; + if (res->start >= IO_MEM_LOGICAL_START && + res->end <= IO_MEM_LOGICAL_END) { + res->start += IO_MEM_VIRTUAL_OFFSET; + res->end += IO_MEM_VIRTUAL_OFFSET; + } + if (res->start >= IO_PORT_LOGICAL_START && + res->end <= IO_PORT_LOGICAL_END) { + res->start += IO_PORT_VIRTUAL_OFFSET; + res->end += IO_PORT_VIRTUAL_OFFSET; + } + } + +} + +struct pci_fixup pcibios_fixups[] = { + {PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, + pcibios_fixup_resources}, + {0} +}; + +extern int pciauto_assign_resources(int busno, struct pci_channel *hose); + +static int __init pcibios_init(void) +{ + struct pci_channel *p; + struct pci_bus *bus; + int busno; + +#ifdef CONFIG_PCI_AUTO + /* assign resources */ + busno = 0; + for (p = mips_pci_channels; p->pci_ops != NULL; p++) { + busno = pciauto_assign_resources(busno, p) + 1; + } +#endif + + /* scan the buses */ + busno = 0; + for (p = mips_pci_channels; p->pci_ops != NULL; p++) { + bus = pci_scan_bus(busno, p->pci_ops, p); + busno = bus->subordinate + 1; + } + + /* machine dependent fixups */ + pcibios_fixup(); + /* fixup irqs (board specific routines) */ + pcibios_fixup_irqs(); + + return 0; +} + +subsys_initcall(pcibios_init); + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + /* pciauto_assign_resources() will enable all devices found */ + return 0; +} + +unsigned long __init pci_bridge_check_io(struct pci_dev *bridge) +{ + u16 io; + + pci_read_config_word(bridge, PCI_IO_BASE, &io); + if (!io) { + pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); + pci_read_config_word(bridge, PCI_IO_BASE, &io); + pci_write_config_word(bridge, PCI_IO_BASE, 0x0); + } + if (io) + return IORESOURCE_IO; + //printk(KERN_WARNING "PCI: bridge %s does not support I/O forwarding!\n", bridge->name); + return 0; +} + +void __devinit pcibios_fixup_bus(struct pci_bus *bus) +{ + /* Propogate hose info into the subordinate devices. */ + + struct pci_channel *hose = bus->sysdata; + struct pci_dev *dev = bus->self; + + if (!dev) { + /* Root bus */ + bus->resource[0] = hose->io_resource; + bus->resource[1] = hose->mem_resource; + } else { + /* This is a bridge. Do not care how it's initialized, + just link its resources to the bus ones */ + int i; + + for (i = 0; i < 3; i++) { + bus->resource[i] = + &dev->resource[PCI_BRIDGE_RESOURCES + i]; + bus->resource[i]->name = bus->name; + } + bus->resource[0]->flags |= pci_bridge_check_io(dev); + bus->resource[1]->flags |= IORESOURCE_MEM; + /* For now, propagate hose limits to the bus; + we'll adjust them later. */ + bus->resource[0]->end = hose->io_resource->end; + bus->resource[1]->end = hose->mem_resource->end; + /* Turn off downstream PF memory address range by default */ + bus->resource[2]->start = 1024 * 1024; + bus->resource[2]->end = bus->resource[2]->start - 1; + } +} + +char *pcibios_setup(char *str) +{ + return str; +} + +void pcibios_align_resource(void *data, struct resource *res, + unsigned long size, unsigned long align) +{ + /* this should not be called */ +} diff -Nru a/arch/mips/philips/nino/Makefile b/arch/mips/philips/nino/Makefile --- a/arch/mips/philips/nino/Makefile Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,17 +0,0 @@ -# -# Makefile for the Philips Nino specific parts of the kernel -# - -obj-y := int-handler.o setup.o irq.o time.o reset.o rtc.o prom.o power.o - -obj-$(CONFIG_REMOTE_DEBUG) += kgdb.o - -obj-$(CONFIG_BLK_DEV_INITRD) += ramdisk.o - -ramdisk.o: - $(MAKE) -C ramdisk - mv ramdisk/ramdisk.o ramdisk.o - -clean: - rm -f *.o - diff -Nru a/arch/mips/philips/nino/int-handler.S b/arch/mips/philips/nino/int-handler.S --- a/arch/mips/philips/nino/int-handler.S Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,137 +0,0 @@ -/* - * linux/arch/mips/philips/nino/int-handler.S - * - * Copyright (C) 1999 Harald Koerfgen - * Copyright (C) 2000 Jim Pick (jim@jimpick.com) - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Interrupt handler for Philips Nino. - */ -#include <asm/asm.h> -#include <asm/regdef.h> -#include <asm/mipsregs.h> -#include <asm/stackframe.h> -#include <asm/tx3912.h> - - .data - .globl HighPriVect - -HighPriVect: .word spurious # Reserved - .word io_posnegint0 # IOPOSINT(0) or IONEGINT(0) - .word spurious # CHIDMACNTINT - .word spurious # TELDMACNTINT - .word spurious # SNDDMACNTINT - .word spurious # Reserved - .word io_negint56 # IONEGINT(6) or IONEGINT(5) - .word spurious # Reserved - .word io_posint56 # IOPOSINT(6) or IOPOSINT(5) - .word spurious # Reserved - .word spurious # UARTBRXINT - .word uarta_rx # UARTARXINT - .word spurious # Reserved - .word periodic_timer # PERINT - .word spurious # ALARMINT - .word spurious # POSPWROKINT or NEGPWROKINT - -/* - * Here is the entry point to handle all interrupts. - */ - .text - .set noreorder - .align 5 - NESTED(nino_handle_int, PT_SIZE, ra) - .set noat - SAVE_ALL - CLI - .set at - - /* - * Get pending Interrupts - */ - mfc0 t0, CP0_CAUSE # Get pending interrupts - andi t2, t0, IE_IRQ4 # IRQ4 (high priority) - bne t2, IE_IRQ4, low_priority - nop - -/* - * Ok, we've got a high priority interrupt (a.k.a. an external interrupt). - * Read Interrupt Status Register 6 to get vector. - */ -high_priority: - lui t0, %hi(IntStatus6) - lw t1, %lo(IntStatus6)(t0) - andi t1, INT6_INTVECT - la t2, HighPriVect - addu t1, t1, t2 - lw t2, 0(t1) - jr t2 - nop - -/* - * Ok, we've got one of over a hundred other interrupts. - */ -low_priority: - lui t0, %hi(IntStatus1) - lw t1, %lo(IntStatus1)(t0) - j handle_it - li a0, 20 - -/* - * We don't currently handle spurious interrupts. - */ -spurious: - j spurious_interrupt - nop - -/* - * We have the IRQ number, dispatch to the real handler. - */ -handle_it: jal do_IRQ - move a1,sp - j ret_from_irq - nop - -/************************************ - * High priority interrupt mappings * - ************************************/ - -/* - * Periodic timer - IRQ 0 - */ -periodic_timer: - j handle_it - li a0, 0 - -/* - * UARTA RX - IRQ 3 - */ -uarta_rx: - j handle_it - li a0, 3 - -/* - * GPIO Pin 0 transition - IRQ 10 - */ -io_posnegint0: - j handle_it - li a0, 10 - -/* - * GPIO Pin 5 or 6 transition (0-to-1) - IRQ 11 - */ -io_posint56: - j handle_it - li a0, 11 - -/* - * GPIO Pin 5 or 6 transition (1-to-0) - IRQ 12 - */ -io_negint56: - j handle_it - li a0, 12 - - END(nino_handle_int) diff -Nru a/arch/mips/philips/nino/irq.c b/arch/mips/philips/nino/irq.c --- a/arch/mips/philips/nino/irq.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,319 +0,0 @@ -/* - * linux/arch/mips/philips/nino/irq.c - * - * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1999 Harald Koerfgen - * Copyright (C) 2000 Pavel Machek (pavel@suse.cz) - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Generic interrupt handler for Philips Nino. - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/seq_file.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/tx3912.h> - -unsigned long spurious_count = 0; - -irq_cpustat_t irq_stat [NR_CPUS]; - -static inline void mask_irq(unsigned int irq_nr) -{ - switch (irq_nr) { - case 0: /* Periodic Timer Interrupt */ - IntClear5 = INT5_PERIODICINT; - IntClear6 = INT6_PERIODICINT; - IntEnable6 &= ~INT6_PERIODICINT; - break; - - case 3: - /* Serial port receive interrupt */ - break; - - case 2: - /* Serial port transmit interrupt */ - break; - - default: - printk( "Attempt to mask unknown IRQ %d?\n", irq_nr ); - } -} - -static inline void unmask_irq(unsigned int irq_nr) -{ - switch (irq_nr) { - case 0: - IntEnable6 |= INT6_PERIODICINT; - break; - - case 3: - /* Serial port receive interrupt */ - break; - - case 2: - /* Serial port transmit interrupt */ - break; - - default: - printk( "Attempt to unmask unknown IRQ %d?\n", irq_nr ); - } -} - -void disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - mask_irq(irq_nr); - restore_flags(flags); -} - -void enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - unmask_irq(irq_nr); - restore_flags(flags); -} - -/* - * Pointers to the low-level handlers: first the general ones, then the - * fast ones, then the bad ones. - */ -extern void interrupt(void); - -static struct irqaction *irq_action[NR_IRQS] = -{ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL -}; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - struct irqaction *action; - unsigned long flags; - - for (i = 0; i < NR_IRQS; i++) { - local_irq_save(flags); - action = irq_action[i]; - if (!action) - goto skip; - seq_printf(p, "%2d: %8d %c %s", - i, kstat_cpu(0).irqs[i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action = action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_putc(p, '\n'); -skip: - local_irq_restore(flags); - } - return 0; -} - -atomic_t __mips_bh_counter; - -/* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. - */ -asmlinkage void do_IRQ(int irq, struct pt_regs *regs) -{ - struct irqaction *action; - int do_random, cpu; - - if (irq == 20) { - if (IntStatus2 & 0xfffff00) { - if (IntStatus2 & 0x0f000000) - return do_IRQ(2, regs); - } - } - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - - if (irq == 20) { - printk("20 %08lx %08lx\n %08lx %08lx\n %08lx\n", - IntStatus1, IntStatus2, IntStatus3, - IntStatus4, IntStatus5 ); - printk("20 %08lx %08lx\n %08lx %08lx\n %08lx\n", - IntEnable1, IntEnable2, IntEnable3, - IntEnable4, IntEnable5 ); - - } - - mask_irq(irq); - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - unmask_irq(irq); - local_irq_disable(); - } else { - IntClear1 = ~0; - IntClear3 = ~0; - IntClear4 = ~0; - IntClear5 = ~0; - unmask_irq(irq); - } - irq_exit(cpu, irq); - - /* unmasking and bottom half handling is done magically for us. */ -} - -/* - * Idea is to put all interrupts - * in a single table and differenciate them just by number. - */ -int setup_nino_irq(int irq, struct irqaction *new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; - - p = irq_action + irq; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - return -EBUSY; - - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_and_cli(flags); - *p = new; - - if (!shared) { - unmask_irq(irq); - } - restore_flags(flags); - return 0; -} - -int request_irq(unsigned int irq, - void (*handler) (int, void *, struct pt_regs *), - unsigned long irqflags, - const char *devname, - void *dev_id) -{ - int retval; - struct irqaction *action; - - if (irq >= NR_IRQS) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - retval = setup_nino_irq(irq, action); - - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *action, **p; - unsigned long flags; - - if (irq >= NR_IRQS) { - printk(KERN_CRIT __FUNCTION__ ": trying to free IRQ%d\n", irq); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - if (!irq[irq_action]) - mask_irq(irq); - restore_flags(flags); - kfree(action); - return; - } - printk(KERN_CRIT __FUNCTION__ ": trying to free free IRQ%d\n", irq); -} - -unsigned long probe_irq_on(void) -{ - /* TODO */ - return 0; -} - -int probe_irq_off(unsigned long irqs) -{ - /* TODO */ - return 0; -} - -void __init init_IRQ(void) -{ - irq_setup(); -} diff -Nru a/arch/mips/philips/nino/kgdb.c b/arch/mips/philips/nino/kgdb.c --- a/arch/mips/philips/nino/kgdb.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,83 +0,0 @@ -/* - * linux/arch/mips/philips/nino/kgdb.c - * - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Kernel debugging on the Philips Nino. - */ -#include <asm/system.h> -#include <asm/tx3912.h> - -static int remoteDebugInitialized = 0; - -void debugInit(void) -{ -/* - * If low-level debugging (before GDB or console operational) is - * configured, then we do not need to re-initialize the UART. - */ -#ifndef CONFIG_DEBUG_LL - earlyInitUartPR31700(); -#endif -} - -char getDebugChar(void) -{ - char buf; - unsigned long int2, flags; - - if (!remoteDebugInitialized) { - debugInit(); - remoteDebugInitialized = 1; - } - - save_and_cli(flags); - - int2 = IntEnable2; - - IntEnable2 = 0; - - while(!(UartA_Ctrl1 & UART_RX_HOLD_FULL)); - - buf = UartA_Data; - - IntEnable2 = int2; - - restore_flags(flags); - - return buf; -} - -int putDebugChar(char c) -{ - int i; - unsigned long int2; - - if (!remoteDebugInitialized) { - debugInit(); - remoteDebugInitialized = 1; - } - - int2 = IntEnable2; - - IntEnable2 &= - ~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY); - - for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < 10000); i++); - - IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY; - - UartA_Data = c; - - for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < 10000); i++); - - IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY; - - IntEnable2 = int2; - - return 1; -} diff -Nru a/arch/mips/philips/nino/power.c b/arch/mips/philips/nino/power.c --- a/arch/mips/philips/nino/power.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/* - * linux/arch/mips/philips/nino/power.c - * - * Copyright (C) 2000 Jim Pick <jim@jimpick.com> - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Power management routines on the Philips Nino. - */ -#include <asm/tx3912.h> - -void nino_wait(void) -{ - /* We stop the CPU to conserve power */ - PowerControl |= PWR_STOPCPU; - - /* - * We wait until an interrupt happens... - */ - - /* We resume here */ - PowerControl &= ~PWR_STOPCPU; - - /* Give ourselves a little delay */ - __asm__ __volatile__( - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t"); -} diff -Nru a/arch/mips/philips/nino/prom.c b/arch/mips/philips/nino/prom.c --- a/arch/mips/philips/nino/prom.c Fri Jun 27 14:19:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,80 +0,0 @@ -/* - * linux/arch/mips/philips/nino/prom.c - * - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Early initialization code for the Philips Nino. - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <asm/bootinfo.h> -#include <asm/addrspace.h> -#include <asm/page.h> - -char arcs_cmdline[COMMAND_LINE_SIZE]; - -#ifdef CONFIG_FB_TX3912 -extern u_long tx3912fb_paddr; -extern u_long tx3912fb_vaddr; -extern u_long tx3912fb_size; -#endif - -/* Do basic initialization */ -void __init prom_init(int argc, char **argv, - unsigned long magic, int *prom_vec) -{ - u_long free_end, mem_size; - u_int i; - - /* - * collect args and prepare cmd_line - */ - for (i = 1; i < argc; i++) { - strcat(arcs_cmdline, argv[i]); - if (i < (argc - 1)) - strcat(arcs_cmdline, " "); - } - - mips_machgroup = MACH_GROUP_PHILIPS; - mips_machtype = MACH_PHILIPS_NINO; - -#ifdef CONFIG_NINO_4MB - mem_size = 4 << 20; -#elif CONFIG_NINO_8MB - mem_size = 8 << 20; -#elif CONFIG_NINO_16MB - mem_size = 16 << 20; -#endif - -#ifdef CONFIG_FB_TX3912 - /* - * The LCD controller requires that the framebuffer - * start address fall within a 1MB segment and is - * aligned on a 16 byte boundary. The way to assure - * this is to place the framebuffer at the end of - * memory and mark it as reserved. - */ - free_end = (mem_size - tx3912fb_size) & PAGE_MASK; - add_memory_region(0, free_end, BOOT_MEM_RAM); - add_memory_region(free_end, (mem_size - free_end), BOOT_MEM_RESERVED); - - /* - * Calculate physical and virtual addresses for - * the beginning of the framebuffer. - */ - tx3912fb_paddr = PHYSADDR(free_end); - tx3912fb_vaddr = KSEG1ADDR(free_end); -#else - add_memory_region(0, mem_size, BOOT_MEM_RAM); -#endif -} - -void __init prom_free_prom_memory (void) -{ -} diff -Nru a/arch/mips/philips/nino/ramdisk/Makefile b/arch/mips/philips/nino/ramdisk/Makefile --- a/arch/mips/philips/nino/ramdisk/Makefile Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,10 +0,0 @@ -# -# Makefile for the Philips Nino ramdisk -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# - -ramdisk.o: ramdisk.gz ld.script - $(LD) $(LDFLAGS) -T ld.script -b binary -o $@ ramdisk.gz diff -Nru a/arch/mips/philips/nino/ramdisk/ld.script b/arch/mips/philips/nino/ramdisk/ld.script --- a/arch/mips/philips/nino/ramdisk/ld.script Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -OUTPUT_FORMAT("ecoff-littlemips") -OUTPUT_ARCH(mips) -SECTIONS -{ - .initrd : - { - *(.data) - } -} diff -Nru a/arch/mips/philips/nino/reset.c b/arch/mips/philips/nino/reset.c --- a/arch/mips/philips/nino/reset.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,37 +0,0 @@ -/* - * linux/arch/mips/philips/nino/reset.c - * - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Generic restart, halt and power off functions for Philips Nino. - */ -#include <linux/init.h> -#include <asm/reboot.h> - -void (*reset_vector)(void) = (void (*)(void)) 0xBFC00000; - -void nino_machine_restart(char *command) -{ - reset_vector(); -} - -void nino_machine_halt(void) -{ - reset_vector(); -} - -void nino_machine_power_off(void) -{ - reset_vector(); -} - -void __init setup_nino_reset_vectors(void) -{ - _machine_restart = nino_machine_restart; - _machine_halt = nino_machine_halt; - _machine_power_off = nino_machine_power_off; -} diff -Nru a/arch/mips/philips/nino/rtc.c b/arch/mips/philips/nino/rtc.c --- a/arch/mips/philips/nino/rtc.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,34 +0,0 @@ -/* - * linux/arch/mips/philips/nino/rtc.c - * - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Functions to access RTC on the Philips Nino. - */ -#include <linux/spinlock.h> -#include <linux/mc146818rtc.h> - -static unsigned char nino_rtc_read_data(unsigned long addr) -{ - return 0; -} - -static void nino_rtc_write_data(unsigned char data, unsigned long addr) -{ -} - -static int nino_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops nino_rtc_ops = -{ - &nino_rtc_read_data, - &nino_rtc_write_data, - &nino_rtc_bcd_mode -}; diff -Nru a/arch/mips/philips/nino/setup.c b/arch/mips/philips/nino/setup.c --- a/arch/mips/philips/nino/setup.c Fri Jun 27 14:19:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,120 +0,0 @@ -/* - * linux/arch/mips/philips/nino/setup.c - * - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Interrupt and exception initialization for Philips Nino. - */ -#include <linux/console.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/mc146818rtc.h> -#include <linux/sched.h> -#include <asm/addrspace.h> -#include <asm/gdb-stub.h> -#include <asm/irq.h> -#include <asm/wbflush.h> -#include <asm/tx3912.h> - -extern struct rtc_ops nino_rtc_ops; - -extern void nino_wait(void); -extern void setup_nino_reset_vectors(void); -extern asmlinkage void nino_handle_int(void); -extern int setup_nino_irq(int, struct irqaction *); -void (*board_time_init) (struct irqaction * irq); - -#ifdef CONFIG_REMOTE_DEBUG -extern void set_debug_traps(void); -extern void breakpoint(void); -static int remote_debug = 0; -#endif - -static void __init nino_irq_setup(void) -{ - unsigned int tmp; - - /* Turn all interrupts off */ - IntEnable1 = 0; - IntEnable2 = 0; - IntEnable3 = 0; - IntEnable4 = 0; - IntEnable5 = 0; - IntEnable6 = 0; - - /* Clear all interrupts */ - IntClear1 = 0xffffffff; - IntClear2 = 0xffffffff; - IntClear3 = 0xffffffff; - IntClear4 = 0xffffffff; - IntClear5 = 0xffffffff; - IntClear6 = 0xffffffff; - - /* - * Enable only the interrupts for the UART and negative - * edge (1-to-0) triggered multi-function I/O pins. - */ - change_cp0_status(ST0_BEV, 0); - tmp = read_32bit_cp0_register(CP0_STATUS); - change_cp0_status(ST0_IM, tmp | IE_IRQ2 | IE_IRQ4); - - /* Register the global interrupt handler */ - set_except_vector(0, nino_handle_int); - -#ifdef CONFIG_REMOTE_DEBUG - if (remote_debug) { - set_debug_traps(); - breakpoint(); - } -#endif -} - -static __init void nino_time_init(struct irqaction *irq) -{ - unsigned int scratch = 0; - - /* - * Enable periodic interrupts - */ - setup_nino_irq(0, irq); - - RTCperiodTimer = PER_TIMER_COUNT; - RTCtimerControl = TIM_ENPERTIMER; - IntEnable5 |= INT5_PERIODICINT; - - scratch = inl(TX3912_CLK_CTRL_BASE); - scratch |= TX3912_CLK_CTRL_ENTIMERCLK; - outl(scratch, TX3912_CLK_CTRL_BASE); - - /* Enable all interrupts */ - IntEnable6 |= INT6_GLOBALEN | INT6_PERIODICINT; -} - -void __init nino_setup(void) -{ - irq_setup = nino_irq_setup; - - board_time_init = nino_time_init; - - /* Base address to use for PC type I/O accesses */ - mips_io_port_base = KSEG1ADDR(0xB0C00000); - - setup_nino_reset_vectors(); - - /* Function called during process idle (cpu_idle) */ - cpu_wait = nino_wait; - -#ifdef CONFIG_FB - conswitchp = &dummy_con; -#endif - -#ifdef CONFIG_REMOTE_DEBUG - remote_debug = 1; -#endif - - rtc_ops = &nino_rtc_ops; -} diff -Nru a/arch/mips/philips/nino/time.c b/arch/mips/philips/nino/time.c --- a/arch/mips/philips/nino/time.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,218 +0,0 @@ -/* - * linux/arch/mips/philips/nino/time.c - * - * Copyright (C) 1999 Harald Koerfgen - * Copyright (C) 2000 Pavel Machek (pavel@suse.cz) - * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Time handling functinos for Philips Nino. - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/time.h> -#include <linux/timex.h> -#include <linux/delay.h> -#include <asm/tx3912.h> - -extern volatile unsigned long wall_jiffies; - -static struct timeval xbase; - -#define USECS_PER_JIFFY (1000000/HZ) - -/* - * Poll the Interrupt Status Registers - */ -#undef POLL_STATUS - -static unsigned long do_gettimeoffset(void) -{ - /* - * This is a kludge - */ - return 0; -} - -static -void inline readRTC(unsigned long *high, unsigned long *low) -{ - /* read twice, and keep reading till we find two - * the same pairs. This is needed in case the RTC - * was updating its registers and we read a old - * High but a new Low. */ - do { - *high = RTChigh & RTC_HIGHMASK; - *low = RTClow; - } while (*high != (RTChigh & RTC_HIGHMASK) || RTClow!=*low); -} - -/* - * This version of gettimeofday has near millisecond resolution. - */ -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - unsigned long high, low; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - // 40 bit RTC, driven by 32khz source: - // +-----------+-----------------------------------------+ - // | HHHH.HHHH | LLLL.LLLL.LLLL.LLLL.LMMM.MMMM.MMMM.MMMM | - // +-----------+-----------------------------------------+ - readRTC(&high,&low); - tv->tv_sec = (high << 17) | (low >> 15); - tv->tv_usec = (low % 32768) * 1953 / 64; - tv->tv_sec += xbase.tv_sec; - tv->tv_usec += xbase.tv_usec; - - tv->tv_usec += do_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } -} - -void do_settimeofday(struct timeval *tv) -{ - write_seqlock_irq(&xtime_lock); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ - tv->tv_usec -= do_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - /* reset RTC to 0 (real time is xbase + RTC) */ - xbase = *tv; - RTCtimerControl |= TIM_RTCCLEAR; - RTCtimerControl &= ~TIM_RTCCLEAR; - RTCalarmHigh = RTCalarmLow = ~0UL; - - xtime = *tv; - time_state = TIME_BAD; - time_maxerror = MAXPHASE; - time_esterror = MAXPHASE; - write_sequnlock_irq(&xtime_lock); -} - -static int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - - return retval; -} - -/* last time the cmos clock got updated */ -static long last_rtc_update = 0; - -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ - -int do_write = 1; - -static void -timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ -#ifdef POLL_STATUS - static unsigned long old_IntStatus1 = 0; - static unsigned long old_IntStatus3 = 0; - static unsigned long old_IntStatus4 = 0; - static unsigned long old_IntStatus5 = 0; - static int counter = 0; - int i; - - new_spircv = SPIData & 0xff; - if ((old_spircv != new_spircv) && (new_spircv != 0xff)) { - printk( "SPIData changed: %x\n", new_spircv ); - } - old_spircv = new_spircv; - if (do_write) - SPIData = 0; -#endif - - if (!user_mode(regs)) { - if (prof_buffer && current->pid) { - extern int _stext; - unsigned long pc = regs->cp0_epc; - - pc -= (unsigned long) &_stext; - pc >>= prof_shift; - /* - * Dont ignore out-of-bounds pc values silently, - * put them into the last histogram slot, so if - * present, they will show up as a sharp peak. - */ - if (pc > prof_len - 1) - pc = prof_len - 1; - atomic_inc((atomic_t *) & prof_buffer[pc]); - } - } - - /* - * aaaand... action! - */ - do_timer(regs); - - /* - * If we have an externally syncronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec > 500000 - (tick >> 1) && - xtime.tv_usec < 500000 + (tick >> 1)) - { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } -} - -static struct irqaction irq0 = {timer_interrupt, SA_INTERRUPT, 0, - "timer", NULL, NULL}; - -void (*board_time_init) (struct irqaction * irq); - -int __init time_init(void) -{ - struct timeval starttime; - - starttime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); - starttime.tv_usec = 0; - do_settimeofday(&starttime); - - board_time_init(&irq0); - - return 0; -} diff -Nru a/arch/mips/ramdisk/Makefile b/arch/mips/ramdisk/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ramdisk/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,9 @@ +# +# Makefile for a ramdisk image +# + +O_FORMAT = $(shell $(OBJDUMP) -i | head -2 | grep elf32) +img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE) +ramdisk.o: $(subst ",,$(img)) ld.script + echo "O_FORMAT: " $(O_FORMAT) + $(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img) diff -Nru a/arch/mips/ramdisk/ld.script b/arch/mips/ramdisk/ld.script --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/ramdisk/ld.script Fri Jun 27 14:20:07 2003 @@ -0,0 +1,9 @@ +OUTPUT_ARCH(mips) +SECTIONS +{ + .initrd : + { + *(.data) + } +} + diff -Nru a/arch/mips/sgi/kernel/Makefile b/arch/mips/sgi/kernel/Makefile --- a/arch/mips/sgi/kernel/Makefile Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -# -# Makefile for the SGI specific kernel interface routines -# under Linux. -# - -obj-y += indy_mc.o indy_sc.o indy_hpc.o indy_int.o indy_rtc.o system.o \ - indyIRQ.o reset.o setup.o time.o - -EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/sgi/kernel/indyIRQ.S b/arch/mips/sgi/kernel/indyIRQ.S --- a/arch/mips/sgi/kernel/indyIRQ.S Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,126 +0,0 @@ -/* - * indyIRQ.S: Interrupt exception dispatch code for FullHouse and - * Guiness. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ - -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - - /* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop - * and moving across all the pending IRQ bits in the cause - * register is _NOT_ the answer, the common case is one - * pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register - * IRQ mask, that would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs - * off, nothing in between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the INDY look basically (barring - * software IRQs which we don't use at all) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Local IRQ level zero - * 3 Local IRQ level one - * 4 8254 Timer zero - * 5 8254 Timer one - * 6 Bus Error - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Local IRQ zero - * Local IRQ one - * Bus Error - * 8254 Timer zero - * Lowest ---- 8254 Timer one - * - * then we just return, if multiple IRQs are pending then - * we will just take another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(indyIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 s0, CP0_CAUSE # get irq mask - - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP7 - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero - - /* Wheee, a timer interrupt. */ - move a0, sp - jal indy_r4k_timer_interrupt - nop # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one - - /* Wheee, local level zero interrupt. */ - jal indy_local0_irqdispatch - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error - - /* Wheee, local level one interrupt. */ - move a0, sp - jal indy_local1_irqdispatch - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, an asynchronous bus error... */ - move a0, sp - jal indy_buserror_irq - nop - - j ret_from_irq - nop - -1: - /* Here by mistake? This is possible, what can happen - * is that by the time we take the exception the IRQ - * pin goes low, so just leave if this is the case. - */ - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) - beq a0, zero, 1f - - /* Must be one of the 8254 timers... */ - move a0, sp - jal indy_8254timer_irq - nop -1: - j ret_from_irq - nop - END(indyIRQ) diff -Nru a/arch/mips/sgi/kernel/indy_hpc.c b/arch/mips/sgi/kernel/indy_hpc.c --- a/arch/mips/sgi/kernel/indy_hpc.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,106 +0,0 @@ -/* $Id: indy_hpc.c,v 1.9 1999/12/04 03:59:00 ralf Exp $ - * - * indy_hpc.c: Routines for generic manipulation of the HPC controllers. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1998 Ralf Baechle - */ -#include <linux/init.h> -#include <linux/types.h> - -#include <asm/addrspace.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> -#include <asm/sgialib.h> -#include <asm/bootinfo.h> - -/* #define DEBUG_SGIHPC */ - -struct hpc3_regs *hpc3c0, *hpc3c1; -struct hpc3_miscregs *hpc3mregs; - -/* We need software copies of these because they are write only. */ -unsigned int sgi_hpc_write1, sgi_hpc_write2; - -/* Machine specific identifier knobs. */ -int sgi_has_ioc2 = 0; -int sgi_guiness = 0; -int sgi_boardid; - -void __init sgihpc_init(void) -{ - unsigned long sid, crev, brev; - - hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE); - hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE); - hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE); - sid = hpc3mregs->sysid; - - sid &= 0xff; - crev = (sid & 0xe0) >> 5; - brev = (sid & 0x1e) >> 1; - -#ifdef DEBUG_SGIHPC - prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev); - prom_printf("sgihpc_init: "); -#endif - - /* This test works now thanks to William J. Earl */ - if ((sid & 1) == 0 ) { -#ifdef DEBUG_SGIHPC - prom_printf("GUINESS "); -#endif - sgi_guiness = 1; - mips_machtype = MACH_SGI_INDY; - } else { -#ifdef DEBUG_SGIHPC - prom_printf("FULLHOUSE "); -#endif - mips_machtype = MACH_SGI_INDIGO2; - sgi_guiness = 0; - } - sgi_boardid = brev; - -#ifdef DEBUG_SGIHPC - prom_printf("sgi_boardid<%d> ", sgi_boardid); -#endif - - if(crev == 1) { - if((sid & 1) || (brev >= 2)) { -#ifdef DEBUG_SGIHPC - prom_printf("IOC2 "); -#endif - sgi_has_ioc2 = 1; - } else { -#ifdef DEBUG_SGIHPC - prom_printf("IOC1 revision 1 "); -#endif - } - } else { -#ifdef DEBUG_SGIHPC - prom_printf("IOC1 revision 0 "); -#endif - } -#ifdef DEBUG_SGIHPC - prom_printf("\n"); -#endif - - sgi_hpc_write1 = (HPC3_WRITE1_PRESET | - HPC3_WRITE1_KMRESET | - HPC3_WRITE1_ERESET | - HPC3_WRITE1_LC0OFF); - - sgi_hpc_write2 = (HPC3_WRITE2_EASEL | - HPC3_WRITE2_NTHRESH | - HPC3_WRITE2_TPSPEED | - HPC3_WRITE2_EPSEL | - HPC3_WRITE2_U0AMODE | - HPC3_WRITE2_U1AMODE); - - if(!sgi_guiness) - sgi_hpc_write1 |= HPC3_WRITE1_GRESET; - hpc3mregs->write1 = sgi_hpc_write1; - hpc3mregs->write2 = sgi_hpc_write2; - - hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW; -} diff -Nru a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c --- a/arch/mips/sgi/kernel/indy_int.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,528 +0,0 @@ -/* - * indy_int.c: Routines for generic manipulation of the INT[23] ASIC - * found on INDY workstations.. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - * - Indigo2 changes - * - Interrupt handling fixes - */ -#include <linux/init.h> - -#include <linux/errno.h> -#include <linux/kernel_stat.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/mipsregs.h> -#include <asm/system.h> - -#include <asm/ptrace.h> -#include <asm/processor.h> -#include <asm/sgi/sgi.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> -#include <asm/sgialib.h> -#include <asm/gdb-stub.h> - -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -/* #define DEBUG_SGINT */ - -struct sgi_int2_regs *sgi_i2regs; -struct sgi_int3_regs *sgi_i3regs; -struct sgi_ioc_ints *ioc_icontrol; -struct sgi_ioc_timers *ioc_timers; -volatile unsigned char *ioc_tclear; - -static char lc0msk_to_irqnr[256]; -static char lc1msk_to_irqnr[256]; -static char lc2msk_to_irqnr[256]; -static char lc3msk_to_irqnr[256]; - -extern asmlinkage void indyIRQ(void); - -/* Local IRQ's are layed out logically like this: - * - * 0 --> 7 == local 0 interrupts - * 8 --> 15 == local 1 interrupts - * 16 --> 23 == vectored level 2 interrupts - * 24 --> 31 == vectored level 3 interrupts (not used) - */ -static void enable_local0_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0)); - restore_flags(flags); -} - -static unsigned int startup_local0_irq(unsigned int irq) -{ - enable_local0_irq(irq); - - return 0; /* Never anything pending */ -} - -static void disable_local0_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); - restore_flags(flags); -} - -#define shutdown_local0_irq disable_local0_irq -#define mask_and_ack_local0_irq disable_local0_irq - -static void end_local0_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local0_irq(irq); -} - -static struct hw_interrupt_type ip22_local0_irq_type = { - "IP22 local 0", - startup_local0_irq, - shutdown_local0_irq, - enable_local0_irq, - disable_local0_irq, - mask_and_ack_local0_irq, - end_local0_irq, - NULL -}; - -static void enable_local1_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1)); - restore_flags(flags); -} - -static unsigned int startup_local1_irq(unsigned int irq) -{ - enable_local1_irq(irq); - - return 0; /* Never anything pending */ -} - -void disable_local1_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - ioc_icontrol->imask1 &= ~(1 << (irq- SGINT_LOCAL1)); - restore_flags(flags); -} - -#define shutdown_local1_irq disable_local1_irq -#define mask_and_ack_local1_irq disable_local1_irq - -static void end_local1_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local1_irq(irq); -} - -static struct hw_interrupt_type ip22_local1_irq_type = { - "IP22 local 1", - startup_local1_irq, - shutdown_local1_irq, - enable_local1_irq, - disable_local1_irq, - mask_and_ack_local1_irq, - end_local1_irq, - NULL -}; - -static void enable_local2_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - enable_local0_irq(7); - ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); - restore_flags(flags); -} - -static unsigned int startup_local2_irq(unsigned int irq) -{ - enable_local2_irq(irq); - - return 0; /* Never anything pending */ -} - -void disable_local2_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); - restore_flags(flags); -} - -#define shutdown_local2_irq disable_local2_irq -#define mask_and_ack_local2_irq disable_local2_irq - -static void end_local2_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local2_irq(irq); -} - -static struct hw_interrupt_type ip22_local2_irq_type = { - "IP22 local 2", - startup_local2_irq, - shutdown_local2_irq, - enable_local2_irq, - disable_local2_irq, - mask_and_ack_local2_irq, - end_local2_irq, - NULL -}; - -static void enable_local3_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - printk("Yeeee, got passed irq_nr %d at enable_local3_irq\n", irq); - panic("INVALID IRQ level!"); - restore_flags(flags); -} - -static unsigned int startup_local3_irq(unsigned int irq) -{ - enable_local3_irq(irq); - - return 0; /* Never anything pending */ -} - -void disable_local3_irq(unsigned int irq) -{ - unsigned long flags; - - save_and_cli(flags); - /* - * This way we'll see if anyone would ever want vectored level 3 - * interrupts. Highly unlikely. - */ - printk("Yeeee, got passed irq_nr %d at disable_local3_irq\n", irq); - panic("INVALID IRQ level!"); - restore_flags(flags); -} - -#define shutdown_local3_irq disable_local3_irq -#define mask_and_ack_local3_irq disable_local3_irq - -static void end_local3_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local3_irq(irq); -} - -static struct hw_interrupt_type ip22_local3_irq_type = { - "IP22 local 3", - startup_local3_irq, - shutdown_local3_irq, - enable_local3_irq, - disable_local3_irq, - mask_and_ack_local3_irq, - end_local3_irq, - NULL -}; - -void enable_gio_irq(unsigned int irq) -{ - /* XXX TODO XXX */ -} - -static unsigned int startup_gio_irq(unsigned int irq) -{ - enable_gio_irq(irq); - - return 0; /* Never anything pending */ -} - -void disable_gio_irq(unsigned int irq) -{ - /* XXX TODO XXX */ -} - -#define shutdown_gio_irq disable_gio_irq -#define mask_and_ack_gio_irq disable_gio_irq - -static void end_gio_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_gio_irq(irq); -} - -static struct hw_interrupt_type ip22_gio_irq_type = { - "IP22 GIO", - startup_gio_irq, - shutdown_gio_irq, - enable_gio_irq, - disable_gio_irq, - mask_and_ack_gio_irq, - end_gio_irq, - NULL -}; - -void enable_hpcdma_irq(unsigned int irq) -{ - /* XXX TODO XXX */ -} - -static unsigned int startup_hpcdma_irq(unsigned int irq) -{ - enable_hpcdma_irq(irq); - - return 0; /* Never anything pending */ -} - -void disable_hpcdma_irq(unsigned int irq) -{ - /* XXX TODO XXX */ -} - -#define shutdown_hpcdma_irq disable_hpcdma_irq -#define mask_and_ack_hpcdma_irq disable_hpcdma_irq - -static void end_hpcdma_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_hpcdma_irq(irq); -} - -static struct hw_interrupt_type ip22_hpcdma_irq_type = { - "IP22 HPC DMA", - startup_hpcdma_irq, - shutdown_hpcdma_irq, - enable_hpcdma_irq, - disable_hpcdma_irq, - mask_and_ack_hpcdma_irq, - end_hpcdma_irq, - NULL -}; - -static struct irqaction r4ktimer_action = { - NULL, 0, 0, "R4000 timer/counter", NULL, NULL, -}; - -static struct irqaction indy_berr_action = { - NULL, 0, 0, "IP22 Bus Error", NULL, NULL, -}; - -static struct irqaction *irq_action[16] = { - NULL, NULL, NULL, NULL, - NULL, NULL, &indy_berr_action, &r4ktimer_action, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL -}; - -void indy_local0_irqdispatch(struct pt_regs *regs) -{ - unsigned char mask = ioc_icontrol->istat0; - unsigned char mask2 = 0; - int irq; - - mask &= ioc_icontrol->imask0; - if (mask & ISTAT0_LIO2) { - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask0; - irq = lc2msk_to_irqnr[mask2]; - } else { - irq = lc0msk_to_irqnr[mask]; - } - - /* if irq == 0, then the interrupt has already been cleared */ - if (irq == 0) - goto end; - - do_IRQ(irq, regs); - goto end; - -no_handler: - printk("No handler for local0 irq: %i\n", irq); - -end: - return; -} - -void indy_local1_irqdispatch(struct pt_regs *regs) -{ - unsigned char mask = ioc_icontrol->istat1; - unsigned char mask2 = 0; - int irq; - - mask &= ioc_icontrol->imask1; - if (mask & ISTAT1_LIO3) { - printk("WHee: Got an LIO3 irq, winging it...\n"); - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask1; - irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat]; - } else { - irq = lc1msk_to_irqnr[mask]; - } - - /* if irq == 0, then the interrupt has already been cleared */ - /* not sure if it is needed here, but it is needed for local0 */ - if (irq == 0) - goto end; - - do_IRQ(irq, regs); - goto end; - -no_handler: - printk("No handler for local1 irq: %i\n", irq); - -end: - return; -} - -void indy_buserror_irq(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - int irq = 6; - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - printk("Got a bus error IRQ, shouldn't happen yet\n"); - show_regs(regs); - printk("Spinning...\n"); - while(1); - irq_exit(cpu, irq); -} - -void __init init_IRQ(void) -{ - int i; - - sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE); - sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE); - - /* Init local mask --> irq tables. */ - for (i = 0; i < 256; i++) { - if (i & 0x80) { - lc0msk_to_irqnr[i] = 7; - lc1msk_to_irqnr[i] = 15; - lc2msk_to_irqnr[i] = 23; - lc3msk_to_irqnr[i] = 31; - } else if (i & 0x40) { - lc0msk_to_irqnr[i] = 6; - lc1msk_to_irqnr[i] = 14; - lc2msk_to_irqnr[i] = 22; - lc3msk_to_irqnr[i] = 30; - } else if (i & 0x20) { - lc0msk_to_irqnr[i] = 5; - lc1msk_to_irqnr[i] = 13; - lc2msk_to_irqnr[i] = 21; - lc3msk_to_irqnr[i] = 29; - } else if (i & 0x10) { - lc0msk_to_irqnr[i] = 4; - lc1msk_to_irqnr[i] = 12; - lc2msk_to_irqnr[i] = 20; - lc3msk_to_irqnr[i] = 28; - } else if (i & 0x08) { - lc0msk_to_irqnr[i] = 3; - lc1msk_to_irqnr[i] = 11; - lc2msk_to_irqnr[i] = 19; - lc3msk_to_irqnr[i] = 27; - } else if (i & 0x04) { - lc0msk_to_irqnr[i] = 2; - lc1msk_to_irqnr[i] = 10; - lc2msk_to_irqnr[i] = 18; - lc3msk_to_irqnr[i] = 26; - } else if (i & 0x02) { - lc0msk_to_irqnr[i] = 1; - lc1msk_to_irqnr[i] = 9; - lc2msk_to_irqnr[i] = 17; - lc3msk_to_irqnr[i] = 25; - } else if (i & 0x01) { - lc0msk_to_irqnr[i] = 0; - lc1msk_to_irqnr[i] = 8; - lc2msk_to_irqnr[i] = 16; - lc3msk_to_irqnr[i] = 24; - } else { - lc0msk_to_irqnr[i] = 0; - lc1msk_to_irqnr[i] = 0; - lc2msk_to_irqnr[i] = 0; - lc3msk_to_irqnr[i] = 0; - } - } - - /* Indy uses an INT3, Indigo2 uses an INT2 */ - if (sgi_guiness) { - ioc_icontrol = &sgi_i3regs->ints; - ioc_timers = &sgi_i3regs->timers; - ioc_tclear = &sgi_i3regs->tclear; - } else { - ioc_icontrol = &sgi_i2regs->ints; - ioc_timers = &sgi_i2regs->timers; - ioc_tclear = &sgi_i2regs->tclear; - } - - /* Mask out all interrupts. */ - ioc_icontrol->imask0 = 0; - ioc_icontrol->imask1 = 0; - ioc_icontrol->cmeimask0 = 0; - ioc_icontrol->cmeimask1 = 0; - - set_except_vector(0, indyIRQ); - - init_generic_irq(); - - for (i = SGINT_LOCAL0; i < SGINT_END; i++) { - hw_irq_controller *handler; - - if (i < SGINT_LOCAL1) - handler = &ip22_local0_irq_type; - else if (i < SGINT_LOCAL2) - handler = &ip22_local1_irq_type; - else if (i < SGINT_LOCAL3) - handler = &ip22_local2_irq_type; - else if (i < SGINT_GIO) - handler = &ip22_local3_irq_type; - else if (i < SGINT_HPCDMA) - handler = &ip22_gio_irq_type; - else if (i < SGINT_END) - handler = &ip22_hpcdma_irq_type; - - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].handler = handler; - } -} diff -Nru a/arch/mips/sgi/kernel/indy_mc.c b/arch/mips/sgi/kernel/indy_mc.c --- a/arch/mips/sgi/kernel/indy_mc.c Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,159 +0,0 @@ -/* - * indy_mc.c: Routines for manipulating the INDY memory controller. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes - * - * $Id: indy_mc.c,v 1.7 1999/12/04 03:59:00 ralf Exp $ - */ -#include <linux/init.h> -#include <linux/kernel.h> - -#include <asm/addrspace.h> -#include <asm/ptrace.h> -#include <asm/sgi/sgimc.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgialib.h> - -/* #define DEBUG_SGIMC */ - -struct sgimc_misc_ctrl *mcmisc_regs; -u32 *rpsscounter; -struct sgimc_dma_ctrl *dmactrlregs; - -static inline char *mconfig_string(unsigned long val) -{ - switch(val & SGIMC_MCONFIG_RMASK) { - case SGIMC_MCONFIG_FOURMB: - return "4MB"; - - case SGIMC_MCONFIG_EIGHTMB: - return "8MB"; - - case SGIMC_MCONFIG_SXTEENMB: - return "16MB"; - - case SGIMC_MCONFIG_TTWOMB: - return "32MB"; - - case SGIMC_MCONFIG_SFOURMB: - return "64MB"; - - case SGIMC_MCONFIG_OTEIGHTMB: - return "128MB"; - - default: - return "wheee, unknown"; - }; -} - -void __init sgimc_init(void) -{ - unsigned long tmpreg; - - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - rpsscounter = (unsigned int *) (KSEG1 + 0x1fa01004); - dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000); - - printk("MC: SGI memory controller Revision %d\n", - (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV); - -#if 0 /* XXX Until I figure out what this bit really indicates XXX */ - /* XXX Is this systemid bit reliable? */ - if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) { - EISA_bus = 1; - printk("with EISA\n"); - } else { - EISA_bus = 0; - printk("no EISA\n"); - } -#endif - -#ifdef DEBUG_SGIMC - prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n", - mconfig_string(mcmisc_regs->mconfig0), - mconfig_string(mcmisc_regs->mconfig1)); - - prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n", - mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1); - prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n", - mcmisc_regs->divider, mcmisc_regs->gioparm); -#endif - - /* Place the MC into a known state. This must be done before - * interrupts are first enabled etc. - */ - - /* Step 1: The CPU/GIO error status registers will not latch - * up a new error status until the register has been - * cleared by the cpu. These status registers are - * cleared by writing any value to them. - */ - mcmisc_regs->cstat = mcmisc_regs->gstat = 0; - - /* Step 2: Enable all parity checking in cpu control register - * zero. - */ - tmpreg = mcmisc_regs->cpuctrl0; - tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | - SGIMC_CCTRL0_R4KNOCHKPARR); - mcmisc_regs->cpuctrl0 = tmpreg; - - /* Step 3: Setup the MC write buffer depth, this is controlled - * in cpu control register 1 in the lower 4 bits. - */ - tmpreg = mcmisc_regs->cpuctrl1; - tmpreg &= ~0xf; - tmpreg |= 0xd; - mcmisc_regs->cpuctrl1 = tmpreg; - - /* Step 4: Initialize the RPSS divider register to run as fast - * as it can correctly operate. The register is laid - * out as follows: - * - * ---------------------------------------- - * | RESERVED | INCREMENT | DIVIDER | - * ---------------------------------------- - * 31 16 15 8 7 0 - * - * DIVIDER determines how often a 'tick' happens, - * INCREMENT determines by how the RPSS increment - * registers value increases at each 'tick'. Thus, - * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 - */ - mcmisc_regs->divider = 0x101; - - /* Step 5: Initialize GIO64 arbitrator configuration register. - * - * NOTE: If you dork with startup code the HPC init code in - * sgihpc_init() must run before us because of how we - * need to know Guiness vs. FullHouse and the board - * revision on this machine. You have been warned. - */ - - /* First the basic invariants across all gio64 implementations. */ - tmpreg = SGIMC_GIOPARM_HPC64; /* All 1st HPC's interface at 64bits. */ - tmpreg |= SGIMC_GIOPARM_ONEBUS; /* Only one physical GIO bus exists. */ - - if(sgi_guiness) { - /* Guiness specific settings. */ - tmpreg |= SGIMC_GIOPARM_EISA64; /* MC talks to EISA at 64bits */ - tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */ - } else { - /* Fullhouse specific settings. */ - if(sgi_boardid < 2) { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */ - tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */ - tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */ - } else { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP1; - tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */ - /* someone forgot this poor little guy... */ - tmpreg |= SGIMC_GIOPARM_GFX64; /* GFX at 64 bits */ - } - } - mcmisc_regs->gioparm = tmpreg; /* poof */ -} diff -Nru a/arch/mips/sgi/kernel/indy_rtc.c b/arch/mips/sgi/kernel/indy_rtc.c --- a/arch/mips/sgi/kernel/indy_rtc.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/* - * 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. - * - * RTC routines for Indy style attached Dallas chip. - * - * Copyright (C) 1998, 2001 by Ralf Baechle - */ -#include <linux/mc146818rtc.h> -#include <asm/sgi/sgihpc.h> - -static unsigned char indy_rtc_read_data(unsigned long addr) -{ - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - return rtcregs[addr]; -} - -static void indy_rtc_write_data(unsigned char data, unsigned long addr) -{ - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - rtcregs[addr] = data; -} - -static int indy_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops indy_rtc_ops = { - &indy_rtc_read_data, - &indy_rtc_write_data, - &indy_rtc_bcd_mode -}; diff -Nru a/arch/mips/sgi/kernel/indy_sc.c b/arch/mips/sgi/kernel/indy_sc.c --- a/arch/mips/sgi/kernel/indy_sc.c Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,226 +0,0 @@ -/* - * indy_sc.c: Indy cache management functions. - * - * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/bcache.h> -#include <asm/sgi/sgi.h> -#include <asm/sgi/sgimc.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/bootinfo.h> -#include <asm/sgialib.h> -#include <asm/mmu_context.h> - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#undef DEBUG_CACHE - -#define SC_SIZE 0x00080000 -#define SC_LINE 32 -#define CI_MASK (SC_SIZE - SC_LINE) -#define SC_INDEX(n) ((n) & CI_MASK) - -static inline void indy_sc_wipe(unsigned long first, unsigned long last) -{ - unsigned long tmp; - - __asm__ __volatile__( - ".set\tnoreorder\t\t\t# indy_sc_wipe\n\t" - ".set\tmips3\n\t" - ".set\tnoat\n\t" - "mfc0\t%2, $12\n\t" - "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" - "mtc0\t$1, $12\n\t" - - "dli\t$1, 0x9000000080000000\n\t" - "or\t%0, $1\t\t\t# first line to flush\n\t" - "or\t%1, $1\t\t\t# last line to flush\n\t" - ".set\tat\n\t" - - "1:\tsw\t$0, 0(%0)\n\t" - "bne\t%0, %1, 1b\n\t" - "daddu\t%0, 32\n\t" - - "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" - "nop; nop; nop; nop;\n\t" - ".set\tmips0\n\t" - ".set\treorder" - : "=r" (first), "=r" (last), "=&r" (tmp) - : "0" (first), "1" (last) - : "$1"); -} - -static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) -{ - unsigned long first_line, last_line; - unsigned int flags; - -#ifdef DEBUG_CACHE - printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); -#endif - - if (!size) - return; - - /* Which lines to flush? */ - first_line = SC_INDEX(addr); - last_line = SC_INDEX(addr + size - 1); - - local_irq_save(flags); - if (first_line <= last_line) { - indy_sc_wipe(first_line, last_line); - goto out; - } - - indy_sc_wipe(first_line, SC_SIZE - SC_LINE); - indy_sc_wipe(0, last_line); -out: - local_irq_restore(flags); -} - -static void indy_sc_enable(void) -{ - unsigned long addr, tmp1, tmp2; - - /* This is really cool... */ -#ifdef DEBUG_CACHE - printk("Enabling R4600 SCACHE\n"); -#endif - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - "mfc0\t%2, $12\n\t" - "nop; nop; nop; nop;\n\t" - "li\t%1, 0x80\n\t" - "mtc0\t%1, $12\n\t" - "nop; nop; nop; nop;\n\t" - "li\t%0, 0x1\n\t" - "dsll\t%0, 31\n\t" - "lui\t%1, 0x9000\n\t" - "dsll32\t%1, 0\n\t" - "or\t%0, %1, %0\n\t" - "sb\t$0, 0(%0)\n\t" - "mtc0\t$0, $12\n\t" - "nop; nop; nop; nop;\n\t" - "mtc0\t%2, $12\n\t" - "nop; nop; nop; nop;\n\t" - ".set\tpop" - : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); -} - -static void indy_sc_disable(void) -{ - unsigned long tmp1, tmp2, tmp3; - -#ifdef DEBUG_CACHE - printk("Disabling R4600 SCACHE\n"); -#endif - __asm__ __volatile__( - ".set\tpush\n\t" - ".set\tnoreorder\n\t" - ".set\tmips3\n\t" - "li\t%0, 0x1\n\t" - "dsll\t%0, 31\n\t" - "lui\t%1, 0x9000\n\t" - "dsll32\t%1, 0\n\t" - "or\t%0, %1, %0\n\t" - "mfc0\t%2, $12\n\t" - "nop; nop; nop; nop\n\t" - "li\t%1, 0x80\n\t" - "mtc0\t%1, $12\n\t" - "nop; nop; nop; nop\n\t" - "sh\t$0, 0(%0)\n\t" - "mtc0\t$0, $12\n\t" - "nop; nop; nop; nop\n\t" - "mtc0\t%2, $12\n\t" - "nop; nop; nop; nop\n\t" - ".set\tpop" - : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); -} - -static inline int __init indy_sc_probe(void) -{ - volatile unsigned int *cpu_control; - unsigned short cmd = 0xc220; - unsigned long data = 0; - int i, n; - -#ifdef __MIPSEB__ - cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00034); -#else - cpu_control = (volatile unsigned int *) KSEG1ADDR(0x1fa00030); -#endif -#define DEASSERT(bit) (*(cpu_control) &= (~(bit))) -#define ASSERT(bit) (*(cpu_control) |= (bit)) -#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("") - DEASSERT(SGIMC_EEPROM_PRE); - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_PRE); - DELAY; - ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK); - for(i = 0; i < 11; i++) { - if(cmd & (1<<15)) - ASSERT(SGIMC_EEPROM_SDATAO); - else - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - ASSERT(SGIMC_EEPROM_SECLOCK); - cmd <<= 1; - } - DEASSERT(SGIMC_EEPROM_SDATAO); - for(i = 0; i < (sizeof(unsigned short) * 8); i++) { - unsigned int tmp; - - DEASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - ASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - data <<= 1; - tmp = *cpu_control; - if(tmp & SGIMC_EEPROM_SDATAI) - data |= 1; - } - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_CSEL); - ASSERT(SGIMC_EEPROM_PRE); - ASSERT(SGIMC_EEPROM_SECLOCK); - - data <<= PAGE_SHIFT; - if (data == 0) - return 0; - - scache_size = data; - - printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -/* XXX Check with wje if the Indy caches can differenciate between - writeback + invalidate and just invalidate. */ -struct bcache_ops indy_sc_ops = { - indy_sc_enable, - indy_sc_disable, - indy_sc_wback_invalidate, - indy_sc_wback_invalidate -}; - -void __init indy_sc_init(void) -{ - if (indy_sc_probe()) { - indy_sc_enable(); - bcops = &indy_sc_ops; - } -} diff -Nru a/arch/mips/sgi/kernel/reset.c b/arch/mips/sgi/kernel/reset.c --- a/arch/mips/sgi/kernel/reset.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,241 +0,0 @@ -/* - * 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) 1997, 1998, 2001 by Ralf Baechle - */ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/notifier.h> -#include <linux/timer.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/reboot.h> -#include <asm/sgialib.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> - -/* - * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. - * I'm not shure if this feature is a good idea, for now it's here just to - * make the power button make behave just like under IRIX. - */ -#define POWERDOWN_TIMEOUT 120 - -/* - * Blink frequency during reboot grace period and when paniced. - */ -#define POWERDOWN_FREQ (HZ / 4) -#define PANIC_FREQ (HZ / 8) - -static unsigned char sgi_volume; - -static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; -static int shuting_down, has_paniced; - -static void sgi_machine_restart(char *command) __attribute__((noreturn)); -static void sgi_machine_halt(void) __attribute__((noreturn)); -static void sgi_machine_power_off(void) __attribute__((noreturn)); - -/* XXX How to pass the reboot command to the firmware??? */ -static void sgi_machine_restart(char *command) -{ - if (shuting_down) - sgi_machine_power_off(); - prom_reboot(); -} - -static void sgi_machine_halt(void) -{ - if (shuting_down) - sgi_machine_power_off(); - ArcEnterInteractiveMode(); -} - -static void sgi_machine_power_off(void) -{ - struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; - - cli(); - - clock->cmd |= 0x08; /* Disable watchdog */ - clock->whsec = 0; - clock->wsec = 0; - - while(1) { - hpc3mregs->panel=0xfe; - /* Good bye cruel world ... */ - - /* If we're still running, we probably got sent an alarm - interrupt. Read the flag to clear it. */ - clock->halarm; - } -} - -static void power_timeout(unsigned long data) -{ - sgi_machine_power_off(); -} - -static void blink_timeout(unsigned long data) -{ - /* XXX fix this for fullhouse */ - sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF); - hpc3mregs->write1 = sgi_hpc_write1; - - mod_timer(&blink_timer, jiffies+data); -} - -static void debounce(unsigned long data) -{ - del_timer(&debounce_timer); - if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent. */ - debounce_timer.expires = jiffies + 5; /* 0.05s */ - add_timer(&debounce_timer); - - hpc3mregs->panel = 0xf3; - - return; - } - - if (has_paniced) - prom_reboot(); - - enable_irq(SGI_PANEL_IRQ); -} - -static inline void power_button(void) -{ - if (has_paniced) - return; - - if (shuting_down || kill_proc(1, SIGINT, 1)) { - /* No init process or button pressed twice. */ - sgi_machine_power_off(); - } - - shuting_down = 1; - blink_timer.data = POWERDOWN_FREQ; - blink_timeout(POWERDOWN_FREQ); - - init_timer(&power_timer); - power_timer.function = power_timeout; - power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ; - add_timer(&power_timer); -} - -inline void sgi_volume_set(unsigned char volume) -{ - sgi_volume = volume; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; -} - -inline void sgi_volume_get(unsigned char *volume) -{ - *volume = sgi_volume; -} - -static inline void volume_up_button(unsigned long data) -{ - del_timer(&volume_timer); - - if (sgi_volume < 0xff) - sgi_volume++; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; - - if (ioc_icontrol->istat1 & 2) { - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } - -} - -static inline void volume_down_button(unsigned long data) -{ - del_timer(&volume_timer); - - if (sgi_volume > 0) - sgi_volume--; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; - - if (ioc_icontrol->istat1 & 2) { - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } -} - -static void panel_int(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int buttons; - - buttons = hpc3mregs->panel; - hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */ - - if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */ - disable_irq(SGI_PANEL_IRQ); - init_timer(&debounce_timer); - debounce_timer.function = debounce; - debounce_timer.expires = jiffies + 5; - add_timer(&debounce_timer); - } - - if (!(buttons & 2)) /* Power button was pressed */ - power_button(); - if (!(buttons & 0x40)) { /* Volume up button was pressed */ - init_timer(&volume_timer); - volume_timer.function = volume_up_button; - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } - if (!(buttons & 0x10)) { /* Volume down button was pressed */ - init_timer(&volume_timer); - volume_timer.function = volume_down_button; - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } -} - -static int panic_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - if (has_paniced) - return NOTIFY_DONE; - has_paniced = 1; - - blink_timer.data = PANIC_FREQ; - blink_timeout(PANIC_FREQ); - - return NOTIFY_DONE; -} - -static struct notifier_block panic_block = { - panic_event, - NULL, - 0 -}; - -void indy_reboot_setup(void) -{ - static int setup_done; - - if (setup_done) - return; - setup_done = 1; - - _machine_restart = sgi_machine_restart; - _machine_halt = sgi_machine_halt; - _machine_power_off = sgi_machine_power_off; - - request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); - init_timer(&blink_timer); - blink_timer.function = blink_timeout; - notifier_chain_register(&panic_notifier_list, &panic_block); -} diff -Nru a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c --- a/arch/mips/sgi/kernel/setup.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,308 +0,0 @@ -/* - * setup.c: SGI specific setup, including init of the feature struct. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kbd_ll.h> -#include <linux/kernel.h> -#include <linux/kdev_t.h> -#include <linux/types.h> -#include <linux/console.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/pc_keyb.h> - -#include <asm/addrspace.h> -#include <asm/bcache.h> -#include <asm/keyboard.h> -#include <asm/irq.h> -#include <asm/reboot.h> -#include <asm/sgialib.h> -#include <asm/sgi/sgimc.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> -#include <asm/time.h> -#include <asm/gdb-stub.h> - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -extern void breakpoint(void); -static int remote_debug = 0; -#endif - -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE) -extern void console_setup(char *); -#endif - -extern unsigned long r4k_interval; /* Cycle counter ticks per 1/HZ seconds */ - -extern struct rtc_ops indy_rtc_ops; -void indy_reboot_setup(void); -void sgi_volume_set(unsigned char); - -#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64)) - -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ - -static void sgi_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int sgi_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - /* Dirty hack, this get's called as a callback from the keyboard - driver. We piggyback the initialization of the front panel - button handling on it even though they're technically not - related with the keyboard driver in any way. Doing it from - indy_setup wouldn't work since kmalloc isn't initialized yet. */ - indy_reboot_setup(); - - return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL); -} - -static int sgi_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - /* Nothing to do, interrupt is shared with the keyboard hw */ - return 0; -} - -static void sgi_aux_free_irq(void) -{ - /* Nothing to do, interrupt is shared with the keyboard hw */ -} - -static unsigned char sgi_read_input(void) -{ - return sgi_kh->data; -} - -static void sgi_write_output(unsigned char val) -{ - int status; - - do { - status = sgi_kh->command; - } while (status & KBD_STAT_IBF); - sgi_kh->data = val; -} - -static void sgi_write_command(unsigned char val) -{ - int status; - - do { - status = sgi_kh->command; - } while (status & KBD_STAT_IBF); - sgi_kh->command = val; -} - -static unsigned char sgi_read_status(void) -{ - return sgi_kh->command; -} - -struct kbd_ops sgi_kbd_ops = { - sgi_request_region, - sgi_request_irq, - - sgi_aux_request_irq, - sgi_aux_free_irq, - - sgi_read_input, - sgi_write_output, - sgi_write_command, - sgi_read_status -}; - -static unsigned long dosample(volatile unsigned char *tcwp, - volatile unsigned char *tc2p) -{ - unsigned long ct0, ct1; - unsigned char msb, lsb; - - /* Start the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN); - *tc2p = (SGINT_TCSAMP_COUNTER & 0xff); - *tc2p = (SGINT_TCSAMP_COUNTER >> 8); - - /* Get initial counter invariant */ - ct0 = read_32bit_cp0_register(CP0_COUNT); - - /* Latch and spin until top byte of counter2 is zero */ - do { - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT); - lsb = *tc2p; - msb = *tc2p; - ct1 = read_32bit_cp0_register(CP0_COUNT); - } while(msb); - - /* Stop the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); - - /* - * Return the difference, this is how far the r4k counter increments - * for every 1/HZ seconds. We round off the nearest 1 MHz of master - * clock (= 1000000 / 100 / 2 = 5000 count). - */ - - return ((ct1 - ct0) / 5000) * 5000; -} - -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) - -void sgi_time_init (struct irqaction *irq) { - /* Here we need to calibrate the cycle counter to at least be close. - * We don't need to actually register the irq handler because that's - * all done in indyIRQ.S. - */ - struct sgi_ioc_timers *p; - volatile unsigned char *tcwp, *tc2p; - unsigned long r4k_ticks[3]; - unsigned long r4k_next; - - /* Figure out the r4k offset, the algorithm is very simple - * and works in _all_ cases as long as the 8254 counter - * register itself works ok (as an interrupt driving timer - * it does not because of bug, this is why we are using - * the onchip r4k counter/compare register to serve this - * purpose, but for r4k_offset calculation it will work - * ok for us). There are other very complicated ways - * of performing this calculation but this one works just - * fine so I am not going to futz around. ;-) - */ - p = ioc_timers; - tcwp = &p->tcword; - tc2p = &p->tcnt2; - - printk("Calibrating system timer... "); - dosample(tcwp, tc2p); /* Prime cache. */ - dosample(tcwp, tc2p); /* Prime cache. */ - /* Zero is NOT an option. */ - do { - r4k_ticks[0] = dosample (tcwp, tc2p); - } while (!r4k_ticks[0]); - do { - r4k_ticks[1] = dosample (tcwp, tc2p); - } while (!r4k_ticks[1]); - - if (r4k_ticks[0] != r4k_ticks[1]) { - printk ("warning: timer counts differ, retrying..."); - r4k_ticks[2] = dosample (tcwp, tc2p); - if (r4k_ticks[2] == r4k_ticks[0] - || r4k_ticks[2] == r4k_ticks[1]) - r4k_interval = r4k_ticks[2]; - else { - printk ("disagreement, using average..."); - r4k_interval = (r4k_ticks[0] + r4k_ticks[1] - + r4k_ticks[2]) / 3; - } - } else - r4k_interval = r4k_ticks[0]; - - printk("%d [%d.%02d MHz CPU]\n", (int) r4k_interval, - (int) (r4k_interval / 5000), (int) (r4k_interval % 5000) / 50); - - /* Set ourselves up for future interrupts */ - r4k_next = (read_32bit_cp0_register(CP0_COUNT) + r4k_interval); - write_32bit_cp0_register(CP0_COMPARE, r4k_next); - change_cp0_status(ST0_IM, ALLINTS); - sti (); -} - -void __init sgi_setup(void) -{ -#ifdef CONFIG_SERIAL_CONSOLE - char *ctype; -#endif -#ifdef CONFIG_REMOTE_DEBUG - char *kgdb_ttyd; -#endif - - board_time_init = sgi_time_init; - - /* Init the INDY HPC I/O controller. Need to call this before - * fucking with the memory controller because it needs to know the - * boardID and whether this is a Guiness or a FullHouse machine. - */ - sgihpc_init(); - - /* Init INDY memory controller. */ - sgimc_init(); - - /* Now enable boardcaches, if any. */ - indy_sc_init(); - -#ifdef CONFIG_SERIAL_CONSOLE - /* ARCS console environment variable is set to "g?" for - * graphics console, it is set to "d" for the first serial - * line and "d2" for the second serial line. - */ - ctype = ArcGetEnvironmentVariable("console"); - if(*ctype == 'd') { - if(*(ctype+1)=='2') - console_setup ("ttyS1"); - else - console_setup ("ttyS0"); - } -#endif - -#ifdef CONFIG_REMOTE_DEBUG - kgdb_ttyd = prom_getcmdline(); - if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) { - int line; - kgdb_ttyd += strlen("kgdb=ttyd"); - if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2') - printk("KGDB: Uknown serial line /dev/ttyd%c, " - "falling back to /dev/ttyd1\n", *kgdb_ttyd); - line = *kgdb_ttyd == '2' ? 0 : 1; - printk("KGDB: Using serial line /dev/ttyd%d for session\n", - line ? 1 : 2); - rs_kgdb_hook(line); - - printk("KGDB: Using serial line /dev/ttyd%d for session, " - "please connect your debugger\n", line ? 1 : 2); - - remote_debug = 1; - /* Breakpoints and stuff are in sgi_irq_setup() */ - } -#endif - -#ifdef CONFIG_ARC_CONSOLE - console_setup("ttyS0"); -#endif - - sgi_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), NULL, 10)); - -#ifdef CONFIG_VT -#ifdef CONFIG_SGI_NEWPORT_CONSOLE - conswitchp = &newport_con; - - screen_info = (struct screen_info) { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig_video_page */ - 0, /* orig_video_mode */ - 160, /* orig_video_cols */ - 0, 0, 0, /* unused, ega_bx, unused */ - 64, /* orig_video_lines */ - 0, /* orig_video_isVGA */ - 16 /* orig_video_points */ - }; -#else - conswitchp = &dummy_con; -#endif -#endif - - rtc_ops = &indy_rtc_ops; - kbd_ops = &sgi_kbd_ops; -#ifdef CONFIG_PSMOUSE - aux_device_present = 0xaa; -#endif -#ifdef CONFIG_VIDEO_VINO - init_vino(); -#endif -} diff -Nru a/arch/mips/sgi/kernel/system.c b/arch/mips/sgi/kernel/system.c --- a/arch/mips/sgi/kernel/system.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,132 +0,0 @@ -/* - * system.c: Probe the system type using ARCS prom interface library. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: system.c,v 1.8 1999/10/09 00:00:59 ralf Exp $ - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/string.h> - -#include <asm/sgi/sgi.h> -#include <asm/sgialib.h> -#include <asm/bootinfo.h> - -enum sgi_mach sgimach; - -struct smatch { - char *name; - int type; -}; - -static struct smatch sgi_cputable[] = { - { "MIPS-R2000", CPU_R2000 }, - { "MIPS-R3000", CPU_R3000 }, - { "MIPS-R3000A", CPU_R3000A }, - { "MIPS-R4000", CPU_R4000SC }, - { "MIPS-R4400", CPU_R4400SC }, - { "MIPS-R4600", CPU_R4600 }, - { "MIPS-R8000", CPU_R8000 }, - { "MIPS-R5000", CPU_R5000 }, - { "MIPS-R5000A", CPU_R5000A } -}; - -#define NUM_CPUS 9 /* for now */ - -static int __init string_to_cpu(char *s) -{ - int i; - - for(i = 0; i < NUM_CPUS; i++) { - if(!strcmp(s, sgi_cputable[i].name)) - return sgi_cputable[i].type; - } - prom_printf("\nYeee, could not determine MIPS cpu type <%s>\n", s); - prom_printf("press a key to reboot\n"); - prom_getchar(); - romvec->imode(); - return 0; -} - -/* - * We' call this early before loadmmu(). If we do the other way around - * the firmware will crash and burn. - */ -void __init sgi_sysinit(void) -{ - pcomponent *p, *toplev, *cpup = 0; - int cputype = -1; - - - /* The root component tells us what machine architecture we - * have here. - */ - p = prom_getchild(PROM_NULL_COMPONENT); - - /* Now scan for cpu(s). */ - toplev = p = prom_getchild(p); - while(p) { - int ncpus = 0; - - if(p->type == Cpu) { - if(++ncpus > 1) { - prom_printf("\nYeee, SGI MP not ready yet\n"); - prom_printf("press a key to reboot\n"); - prom_getchar(); - romvec->imode(); - } - printk("CPU: %s ", p->iname); - cpup = p; - cputype = string_to_cpu(cpup->iname); - } - p = prom_getsibling(p); - } - if(cputype == -1) { - prom_printf("\nYeee, could not find cpu ARCS component\n"); - prom_printf("press a key to reboot\n"); - prom_getchar(); - romvec->imode(); - } - p = prom_getchild(cpup); - while(p) { - switch(p->class) { - case processor: - switch(p->type) { - case Fpu: - printk("FPU<%s> ", p->iname); - break; - - default: - break; - }; - break; - - case cache: - switch(p->type) { - case picache: - printk("ICACHE "); - break; - - case pdcache: - printk("DCACHE "); - break; - - case sccache: - printk("SCACHE "); - break; - - default: - break; - - }; - break; - - default: - break; - }; - p = prom_getsibling(p); - } - printk("\n"); -} diff -Nru a/arch/mips/sgi/kernel/time.c b/arch/mips/sgi/kernel/time.c --- a/arch/mips/sgi/kernel/time.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,21 +0,0 @@ -/* - * time.c: Generic SGI handler for (spurious) 8254 interrupts - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <asm/sgialib.h> - -void indy_8254timer_irq(void) -{ - int cpu = smp_processor_id(); - int irq = 4; - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); - prom_getchar(); - ArcEnterInteractiveMode(); - irq_exit(cpu, irq); -} diff -Nru a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,12 @@ +# +# Makefile for the SGI specific kernel interface routines +# under Linux. +# + +obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ + ip22-time.o ip22-rtc.o ip22-nvram.o ip22-reset.o \ + ip22-setup.o ip22-ksyms.o + +obj-$(CONFIG_EISA) += ip22-eisa.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/sgi-ip22/ip22-berr.c b/arch/mips/sgi-ip22/ip22-berr.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-berr.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +/* + * ip22-berr.c: Bus error handling. + * + * Copyright (C) 2002 Ladislav Michl + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> + +#include <asm/addrspace.h> +#include <asm/system.h> +#include <asm/traps.h> +#include <asm/branch.h> +#include <asm/sgi/mc.h> +#include <asm/sgi/hpc3.h> + + +static unsigned int cpu_err_stat; /* Status reg for CPU */ +static unsigned int gio_err_stat; /* Status reg for GIO */ +static unsigned int cpu_err_addr; /* Error address reg for CPU */ +static unsigned int gio_err_addr; /* Error address reg for GIO */ + +static void save_and_clear_buserr(void) +{ + /* save memory controler's error status registers */ + cpu_err_addr = sgimc->cerr; + cpu_err_stat = sgimc->cstat; + gio_err_addr = sgimc->gerr; + gio_err_stat = sgimc->gstat; + + sgimc->cstat = sgimc->gstat = 0; +} + +#define GIO_ERRMASK 0xff00 +#define CPU_ERRMASK 0x3f00 + +static void print_buserr(void) +{ + if (cpu_err_stat & CPU_ERRMASK) + printk(KERN_ALERT "CPU error 0x%x<%s%s%s%s%s%s> @ 0x%08x\n", + cpu_err_stat, + cpu_err_stat & SGIMC_CSTAT_RD ? "RD " : "", + cpu_err_stat & SGIMC_CSTAT_PAR ? "PAR " : "", + cpu_err_stat & SGIMC_CSTAT_ADDR ? "ADDR " : "", + cpu_err_stat & SGIMC_CSTAT_SYSAD_PAR ? "SYSAD " : "", + cpu_err_stat & SGIMC_CSTAT_SYSCMD_PAR ? "SYSCMD " : "", + cpu_err_stat & SGIMC_CSTAT_BAD_DATA ? "BAD_DATA " : "", + cpu_err_addr); + if (gio_err_stat & GIO_ERRMASK) + printk(KERN_ALERT "GIO error 0x%x:<%s%s%s%s%s%s%s%s> @ 0x08%x\n", + gio_err_stat, + gio_err_stat & SGIMC_GSTAT_RD ? "RD " : "", + gio_err_stat & SGIMC_GSTAT_WR ? "WR " : "", + gio_err_stat & SGIMC_GSTAT_TIME ? "TIME " : "", + gio_err_stat & SGIMC_GSTAT_PROM ? "PROM " : "", + gio_err_stat & SGIMC_GSTAT_ADDR ? "ADDR " : "", + gio_err_stat & SGIMC_GSTAT_BC ? "BC " : "", + gio_err_stat & SGIMC_GSTAT_PIO_RD ? "PIO_RD " : "", + gio_err_stat & SGIMC_GSTAT_PIO_WR ? "PIO_WR " : "", + gio_err_addr); +} + +/* + * MC sends an interrupt whenever bus or parity errors occur. In addition, + * if the error happened during a CPU read, it also asserts the bus error + * pin on the R4K. Code in bus error handler save the MC bus error registers + * and then clear the interrupt when this happens. + */ + +void ip22_be_interrupt(int irq, struct pt_regs *regs) +{ + save_and_clear_buserr(); + print_buserr(); + panic("Bus error, epc == %08lx, ra == %08lx", + regs->cp0_epc, regs->regs[31]); +} + +int ip22_be_handler(struct pt_regs *regs, int is_fixup) +{ + save_and_clear_buserr(); + if (is_fixup) + return MIPS_BE_FIXUP; + print_buserr(); + return MIPS_BE_FATAL; +} + +void __init ip22_be_init(void) +{ + board_be_handler = ip22_be_handler; +} diff -Nru a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-eisa.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,307 @@ +/* + * Basic EISA bus support for the SGI Indigo-2. + * + * (C) 2002 Pascal Dameme <netinet@freesurf.fr> + * and Marc Zyngier <mzyngier@freesurf.fr> + * + * This code is released under both the GPL version 2 and BSD + * licenses. Either license may be used. + * + * This code offers a very basic support for this EISA bus present in + * the SGI Indigo-2. It currently only supports PIO (forget about DMA + * for the time being). This is enough for a low-end ethernet card, + * but forget about your favorite SCSI card... + * + * TODO : + * - Fix bugs... + * - Add ISA support + * - Add DMA (yeah, right...). + * - Fix more bugs. + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/processor.h> +#include <asm/sgi/ioc.h> +#include <asm/sgi/mc.h> +#include <asm/sgi/ip22.h> + +#define EISA_MAX_SLOTS 4 +#define EISA_MAX_IRQ 16 + +#define EISA_TO_PHYS(x) (0x00080000 | (x)) +#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x)))) + +#define EIU_MODE_REG 0x0009ffc0 +#define EIU_STAT_REG 0x0009ffc4 +#define EIU_PREMPT_REG 0x0009ffc8 +#define EIU_QUIET_REG 0x0009ffcc +#define EIU_INTRPT_ACK 0x00090004 + +#define EISA_DMA1_STATUS 8 +#define EISA_INT1_CTRL 0x20 +#define EISA_INT1_MASK 0x21 +#define EISA_INT2_CTRL 0xA0 +#define EISA_INT2_MASK 0xA1 +#define EISA_DMA2_STATUS 0xD0 +#define EISA_DMA2_WRITE_SINGLE 0xD4 +#define EISA_EXT_NMI_RESET_CTRL 0x461 +#define EISA_INT1_EDGE_LEVEL 0x4D0 +#define EISA_INT2_EDGE_LEVEL 0x4D1 +#define EISA_VENDOR_ID_OFFSET 0xC80 + +#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); } +#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x)) +#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); } +#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x)) + +static char *decode_eisa_sig(u8 * sig) +{ + static char sig_str[8]; + u16 rev; + + if (sig[0] & 0x80) + return NULL; + + sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1); + sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1); + sig_str[2] = (sig[1] & 0x1f) + ('A' - 1); + rev = (sig[2] << 8) | sig[3]; + sprintf(sig_str + 3, "%04X", rev); + + return sig_str; +} + +static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + u8 eisa_irq; + u8 dma1, dma2; + + eisa_irq = EIU_READ_8(EIU_INTRPT_ACK); + dma1 = EISA_READ_8(EISA_DMA1_STATUS); + dma2 = EISA_READ_8(EISA_DMA2_STATUS); + + if (eisa_irq >= EISA_MAX_IRQ) { + /* Oops, Bad Stuff Happened... */ + printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq); + + EISA_WRITE_8(EISA_INT2_CTRL, 0x20); + EISA_WRITE_8(EISA_INT1_CTRL, 0x20); + } else + do_IRQ(eisa_irq, regs); +} + +static void enable_eisa1_irq(unsigned int irq) +{ + unsigned long flags; + u8 mask; + + local_irq_save(flags); + + mask = EISA_READ_8(EISA_INT1_MASK); + mask &= ~((u8) (1 << irq)); + EISA_WRITE_8(EISA_INT1_MASK, mask); + + local_irq_restore(flags); +} + +static unsigned int startup_eisa1_irq(unsigned int irq) +{ + u8 edge; + + /* Only use edge interrupts for EISA */ + + edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL); + edge &= ~((u8) (1 << irq)); + EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge); + + enable_eisa1_irq(irq); + return 0; +} + +static void disable_eisa1_irq(unsigned int irq) +{ + u8 mask; + + mask = EISA_READ_8(EISA_INT1_MASK); + mask |= ((u8) (1 << irq)); + EISA_WRITE_8(EISA_INT1_MASK, mask); +} + +#define shutdown_eisa1_irq disable_eisa1_irq + +static void mask_and_ack_eisa1_irq(unsigned int irq) +{ + disable_eisa1_irq(irq); + + EISA_WRITE_8(EISA_INT1_CTRL, 0x20); +} + +static void end_eisa1_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_eisa1_irq(irq); +} + +static struct hw_interrupt_type ip22_eisa1_irq_type = { + .typename = "IP22 EISA", + .startup = startup_eisa1_irq, + .shutdown = shutdown_eisa1_irq, + .enable = enable_eisa1_irq, + .disable = disable_eisa1_irq, + .ack = mask_and_ack_eisa1_irq, + .end = end_eisa1_irq, +}; + +static void enable_eisa2_irq(unsigned int irq) +{ + unsigned long flags; + u8 mask; + + local_irq_save(flags); + + mask = EISA_READ_8(EISA_INT2_MASK); + mask &= ~((u8) (1 << (irq - 8))); + EISA_WRITE_8(EISA_INT2_MASK, mask); + + local_irq_restore(flags); +} + +static unsigned int startup_eisa2_irq(unsigned int irq) +{ + u8 edge; + + /* Only use edge interrupts for EISA */ + + edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL); + edge &= ~((u8) (1 << (irq - 8))); + EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge); + + enable_eisa2_irq(irq); + return 0; +} + +static void disable_eisa2_irq(unsigned int irq) +{ + u8 mask; + + mask = EISA_READ_8(EISA_INT2_MASK); + mask |= ((u8) (1 << (irq - 8))); + EISA_WRITE_8(EISA_INT2_MASK, mask); +} + +#define shutdown_eisa2_irq disable_eisa2_irq + +static void mask_and_ack_eisa2_irq(unsigned int irq) +{ + disable_eisa2_irq(irq); + + EISA_WRITE_8(EISA_INT2_CTRL, 0x20); + EISA_WRITE_8(EISA_INT1_CTRL, 0x20); +} + +static void end_eisa2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_eisa2_irq(irq); +} + +static struct hw_interrupt_type ip22_eisa2_irq_type = { + .typename = "IP22 EISA", + .startup = startup_eisa2_irq, + .shutdown = shutdown_eisa2_irq, + .enable = enable_eisa2_irq, + .disable = disable_eisa2_irq, + .ack = mask_and_ack_eisa2_irq, + .end = end_eisa2_irq, +}; + +static struct irqaction eisa_action = { + .handler = ip22_eisa_intr, + .name = "EISA", +}; + +static struct irqaction cascade_action = { + .handler = no_action, + .name = "EISA cascade", +}; + +int __init ip22_eisa_init(void) +{ + int i, c; + char *str; + u8 *slot_addr; + + if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { + printk(KERN_INFO "EISA: bus not present.\n"); + return 1; + } + + printk(KERN_INFO "EISA: Probing bus...\n"); + for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) { + slot_addr = + (u8 *) EISA_TO_KSEG1((0x1000 * i) + + EISA_VENDOR_ID_OFFSET); + if ((str = decode_eisa_sig(slot_addr))) { + printk(KERN_INFO "EISA: slot %d : %s detected.\n", + i, str); + c++; + } + } + printk(KERN_INFO "EISA: Detected %d card%s.\n", c, c < 2 ? "" : "s"); +#ifdef CONFIG_ISA + printk(KERN_INFO "ISA support compiled in.\n"); +#endif + + /* Warning : BlackMagicAhead(tm). + Please wave your favorite dead chicken over the busses */ + + /* First say hello to the EIU */ + EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF); + EIU_WRITE_32(EIU_QUIET_REG, 1); + EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F); + + /* Now be nice to the EISA chipset */ + EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1); + for (i = 0; i < 10000; i++); /* Wait long enough for the dust to settle */ + EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0); + EISA_WRITE_8(EISA_INT1_CTRL, 0x11); + EISA_WRITE_8(EISA_INT2_CTRL, 0x11); + EISA_WRITE_8(EISA_INT1_MASK, 0); + EISA_WRITE_8(EISA_INT2_MASK, 8); + EISA_WRITE_8(EISA_INT1_MASK, 4); + EISA_WRITE_8(EISA_INT2_MASK, 2); + EISA_WRITE_8(EISA_INT1_MASK, 1); + EISA_WRITE_8(EISA_INT2_MASK, 1); + EISA_WRITE_8(EISA_INT1_MASK, 0xfb); + EISA_WRITE_8(EISA_INT2_MASK, 0xff); + EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0); + + for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + if (i < (SGINT_EISA + 8)) + irq_desc[i].handler = &ip22_eisa1_irq_type; + else + irq_desc[i].handler = &ip22_eisa2_irq_type; + } + + /* Cannot use request_irq because of kmalloc not being ready at such + * an early stage. Yes, I've been bitten... */ + setup_irq(SGI_EISA_IRQ, &eisa_action); + setup_irq(SGINT_EISA + 2, &cascade_action); + + EISA_bus = 1; + return 0; +} diff -Nru a/arch/mips/sgi-ip22/ip22-hpc.c b/arch/mips/sgi-ip22/ip22-hpc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-hpc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,53 @@ +/* + * ip22-hpc.c: Routines for generic manipulation of the HPC controllers. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1998 Ralf Baechle + */ + +#include <linux/init.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ioc.h> +#include <asm/sgi/ip22.h> + +struct hpc3_regs *hpc3c0, *hpc3c1; +struct sgioc_regs *sgioc; + +/* We need software copies of these because they are write only. */ +u8 sgi_ioc_reset, sgi_ioc_write; + +extern char *system_type; + +void __init sgihpc_init(void) +{ + hpc3c0 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP0_BASE); + hpc3c1 = (struct hpc3_regs *)(KSEG1 + HPC3_CHIP1_BASE); + /* IOC lives in PBUS PIO channel 6 */ + sgioc = (struct sgioc_regs *)hpc3c0->pbus_extregs[6]; + + hpc3c0->pbus_piocfg[6][0] |= HPC3_PIOCFG_DS16; + if (ip22_is_fullhouse()) { + /* Full House comes with INT2 which lives in PBUS PIO + * channel 4 */ + sgint = (struct sgint_regs *)hpc3c0->pbus_extregs[4]; + system_type = "SGI Indigo2"; + } else { + /* Guiness comes with INT3 which is part of IOC */ + sgint = &sgioc->int3; + system_type = "SGI Indy"; + } + + sgi_ioc_reset = (SGIOC_RESET_PPORT | SGIOC_RESET_KBDMOUSE | + SGIOC_RESET_EISA | SGIOC_RESET_ISDN | + SGIOC_RESET_LC0OFF); + + sgi_ioc_write = (SGIOC_WRITE_EASEL | SGIOC_WRITE_NTHRESH | + SGIOC_WRITE_TPSPEED | SGIOC_WRITE_EPSEL | + SGIOC_WRITE_U0AMODE | SGIOC_WRITE_U1AMODE); + + sgioc->reset = sgi_ioc_reset; + sgioc->write = sgi_ioc_write; +} diff -Nru a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-int.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,412 @@ +/* + * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC + * found on INDY and Indigo2 workstations. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) + * - Indigo2 changes + * - Interrupt handling fixes + * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org) + */ + +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/irq.h> + +#include <asm/mipsregs.h> +#include <asm/addrspace.h> + +#include <asm/sgi/ioc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> + +/* #define DEBUG_SGINT */ + +/* So far nothing hangs here */ +#undef USE_LIO3_IRQ + +struct sgint_regs *sgint; + +static char lc0msk_to_irqnr[256]; +static char lc1msk_to_irqnr[256]; +static char lc2msk_to_irqnr[256]; +static char lc3msk_to_irqnr[256]; + +extern asmlinkage void indyIRQ(void); +extern int ip22_eisa_init(void); + +static void enable_local0_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + /* don't allow mappable interrupt to be enabled from setup_irq, + * we have our own way to do so */ + if (irq != SGI_MAP_0_IRQ) + sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); + local_irq_restore(flags); +} + +static unsigned int startup_local0_irq(unsigned int irq) +{ + enable_local0_irq(irq); + return 0; /* Never anything pending */ +} + +static void disable_local0_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); + local_irq_restore(flags); +} + +#define shutdown_local0_irq disable_local0_irq +#define mask_and_ack_local0_irq disable_local0_irq + +static void end_local0_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local0_irq(irq); +} + +static struct hw_interrupt_type ip22_local0_irq_type = { + .typename = "IP22 local 0", + .startup = startup_local0_irq, + .shutdown = shutdown_local0_irq, + .enable = enable_local0_irq, + .disable = disable_local0_irq, + .ack = mask_and_ack_local0_irq, + .end = end_local0_irq, +}; + +static void enable_local1_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + /* don't allow mappable interrupt to be enabled from setup_irq, + * we have our own way to do so */ + if (irq != SGI_MAP_1_IRQ) + sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); + local_irq_restore(flags); +} + +static unsigned int startup_local1_irq(unsigned int irq) +{ + enable_local1_irq(irq); + return 0; /* Never anything pending */ +} + +void disable_local1_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); + local_irq_restore(flags); +} + +#define shutdown_local1_irq disable_local1_irq +#define mask_and_ack_local1_irq disable_local1_irq + +static void end_local1_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local1_irq(irq); +} + +static struct hw_interrupt_type ip22_local1_irq_type = { + .typename = "IP22 local 1", + .startup = startup_local1_irq, + .shutdown = shutdown_local1_irq, + .enable = enable_local1_irq, + .disable = disable_local1_irq, + .ack = mask_and_ack_local1_irq, + .end = end_local1_irq, +}; + +static void enable_local2_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); + local_irq_restore(flags); +} + +static unsigned int startup_local2_irq(unsigned int irq) +{ + enable_local2_irq(irq); + return 0; /* Never anything pending */ +} + +void disable_local2_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); + if (!sgint->cmeimask0) + sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); + local_irq_restore(flags); +} + +#define shutdown_local2_irq disable_local2_irq +#define mask_and_ack_local2_irq disable_local2_irq + +static void end_local2_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local2_irq(irq); +} + +static struct hw_interrupt_type ip22_local2_irq_type = { + .typename = "IP22 local 2", + .startup = startup_local2_irq, + .shutdown = shutdown_local2_irq, + .enable = enable_local2_irq, + .disable = disable_local2_irq, + .ack = mask_and_ack_local2_irq, + .end = end_local2_irq, +}; + +static void enable_local3_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); + local_irq_restore(flags); +} + +static unsigned int startup_local3_irq(unsigned int irq) +{ + enable_local3_irq(irq); + return 0; /* Never anything pending */ +} + +void disable_local3_irq(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); + if (!sgint->cmeimask1) + sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); + local_irq_restore(flags); +} + +#define shutdown_local3_irq disable_local3_irq +#define mask_and_ack_local3_irq disable_local3_irq + +static void end_local3_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_local3_irq(irq); +} + +static struct hw_interrupt_type ip22_local3_irq_type = { + .typename = "IP22 local 3", + .startup = startup_local3_irq, + .shutdown = shutdown_local3_irq, + .enable = enable_local3_irq, + .disable = disable_local3_irq, + .ack = mask_and_ack_local3_irq, + .end = end_local3_irq, +}; + +void indy_local0_irqdispatch(struct pt_regs *regs) +{ + u8 mask = sgint->istat0 & sgint->imask0; + u8 mask2; + int irq; + + if (mask & SGINT_ISTAT0_LIO2) { + mask2 = sgint->vmeistat & sgint->cmeimask0; + irq = lc2msk_to_irqnr[mask2]; + } else + irq = lc0msk_to_irqnr[mask]; + + /* if irq == 0, then the interrupt has already been cleared */ + if (irq) + do_IRQ(irq, regs); + return; +} + +void indy_local1_irqdispatch(struct pt_regs *regs) +{ + u8 mask = sgint->istat1 & sgint->imask1; + u8 mask2; + int irq; + + if (mask & SGINT_ISTAT1_LIO3) { + mask2 = sgint->vmeistat & sgint->cmeimask1; + irq = lc3msk_to_irqnr[mask2]; + } else + irq = lc1msk_to_irqnr[mask]; + + /* if irq == 0, then the interrupt has already been cleared */ + if (irq) + do_IRQ(irq, regs); + return; +} + +extern void ip22_be_interrupt(int irq, struct pt_regs *regs); + +void indy_buserror_irq(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int irq = SGI_BUSERR_IRQ; + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + ip22_be_interrupt(irq, regs); + irq_exit(); +} + +static struct irqaction local0_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "local0 cascade", +}; + +static struct irqaction local1_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "local1 cascade", +}; + +static struct irqaction buserr = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "Bus Error", +}; + +static struct irqaction map0_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "mapable0 cascade", +}; + +#ifdef USE_LIO3_IRQ +static struct irqaction map1_cascade = { + .handler = no_action, + .flags = SA_INTERRUPT, + .name = "mapable1 cascade", +}; +#define SGI_INTERRUPTS SGINT_END +#else +#define SGI_INTERRUPTS SGINT_LOCAL3 +#endif + +extern void mips_cpu_irq_init(unsigned int irq_base); + +void __init init_IRQ(void) +{ + int i; + + /* Init local mask --> irq tables. */ + for (i = 0; i < 256; i++) { + if (i & 0x80) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7; + } else if (i & 0x40) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6; + } else if (i & 0x20) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5; + } else if (i & 0x10) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4; + } else if (i & 0x08) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3; + } else if (i & 0x04) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2; + } else if (i & 0x02) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1; + } else if (i & 0x01) { + lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0; + lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0; + lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0; + lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0; + } else { + lc0msk_to_irqnr[i] = 0; + lc1msk_to_irqnr[i] = 0; + lc2msk_to_irqnr[i] = 0; + lc3msk_to_irqnr[i] = 0; + } + } + + /* Mask out all interrupts. */ + sgint->imask0 = 0; + sgint->imask1 = 0; + sgint->cmeimask0 = 0; + sgint->cmeimask1 = 0; + + set_except_vector(0, indyIRQ); + + init_generic_irq(); + /* init CPU irqs */ + mips_cpu_irq_init(SGINT_CPU); + + for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) { + hw_irq_controller *handler; + + if (i < SGINT_LOCAL1) + handler = &ip22_local0_irq_type; + else if (i < SGINT_LOCAL2) + handler = &ip22_local1_irq_type; + else if (i < SGINT_LOCAL3) + handler = &ip22_local2_irq_type; + else + handler = &ip22_local3_irq_type; + + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = handler; + } + + /* vector handler. this register the IRQ as non-sharable */ + setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade); + setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade); + setup_irq(SGI_BUSERR_IRQ, &buserr); + + /* cascade in cascade. i love Indy ;-) */ + setup_irq(SGI_MAP_0_IRQ, &map0_cascade); +#ifdef USE_LIO3_IRQ + setup_irq(SGI_MAP_1_IRQ, &map1_cascade); +#endif + +#ifdef CONFIG_EISA + if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */ + ip22_eisa_init (); +#endif +} diff -Nru a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-irq.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,118 @@ +/* + * ip22-irq.S: Interrupt exception dispatch code for FullHouse and + * Guiness. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + */ + +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + +/* A lot of complication here is taken away because: + * + * 1) We handle one interrupt and return, sitting in a loop and moving across + * all the pending IRQ bits in the cause register is _NOT_ the answer, the + * common case is one pending IRQ so optimize in that direction. + * + * 2) We need not check against bits in the status register IRQ mask, that + * would make this routine slow as hell. + * + * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in + * between like BSD spl() brain-damage. + * + * Furthermore, the IRQs on the INDY look basically (barring software IRQs + * which we don't use at all) like: + * + * MIPS IRQ Source + * -------- ------ + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Local IRQ level zero + * 3 Local IRQ level one + * 4 8254 Timer zero + * 5 8254 Timer one + * 6 Bus Error + * 7 R4k timer (what we use) + * + * We handle the IRQ according to _our_ priority which is: + * + * Highest ---- R4k Timer + * Local IRQ zero + * Local IRQ one + * Bus Error + * 8254 Timer zero + * Lowest ---- 8254 Timer one + * + * then we just return, if multiple IRQs are pending then we will just take + * another exception, big deal. + */ + + .text + .set noreorder + .set noat + .align 5 + NESTED(indyIRQ, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + mfc0 s0, CP0_CAUSE # get irq mask + + /* First we check for r4k counter/timer IRQ. */ + andi a0, s0, CAUSEF_IP7 + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero + + /* Wheee, a timer interrupt. */ + jal indy_r4k_timer_interrupt + move a0, sp # delay slot + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP3 # delay slot, check local level one + + /* Wheee, local level zero interrupt. */ + jal indy_local0_irqdispatch + move a0, sp # delay slot + + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, CAUSEF_IP6 # delay slot, check bus error + + /* Wheee, local level one interrupt. */ + jal indy_local1_irqdispatch + move a0, sp # delay slot + j ret_from_irq + nop # delay slot + +1: + beq a0, zero, 1f + andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot + + /* Wheee, an asynchronous bus error... */ + jal indy_buserror_irq + move a0, sp # delay slot + j ret_from_irq + nop # delay slot + +1: + /* Here by mistake? It is possible, that by the time we take + * the exception the IRQ pin goes low, so just leave if this + * is the case. + */ + beq a0, zero, 1f + nop # delay slot + + /* Must be one of the 8254 timers... */ + jal indy_8254timer_irq + move a0, sp # delay slot +1: + j ret_from_irq + nop # delay slot + END(indyIRQ) diff -Nru a/arch/mips/sgi-ip22/ip22-ksyms.c b/arch/mips/sgi-ip22/ip22-ksyms.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-ksyms.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,21 @@ +/* + * ip22-ksyms.c: IP22 specific exports + */ + +#include <linux/module.h> + +#include <asm/sgi/mc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ioc.h> +#include <asm/sgi/ip22.h> + +EXPORT_SYMBOL(sgimc); +EXPORT_SYMBOL(hpc3c0); +EXPORT_SYMBOL(hpc3c1); +EXPORT_SYMBOL(sgioc); + +extern void (*indy_volume_button)(int); +EXPORT_SYMBOL(indy_volume_button); + +EXPORT_SYMBOL(ip22_eeprom_read); +EXPORT_SYMBOL(ip22_nvram_read); diff -Nru a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-mc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,201 @@ +/* + * ip22-mc.c: Routines for manipulating SGI Memory Controller. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes + * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) + */ + +#include <linux/init.h> +#include <linux/kernel.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/ptrace.h> +#include <asm/sgialib.h> +#include <asm/sgi/mc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> + +struct sgimc_regs *sgimc; + +static inline unsigned long get_bank_addr(unsigned int memconfig) +{ + return ((memconfig & SGIMC_MCONFIG_BASEADDR) << + ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22)); +} + +static inline unsigned long get_bank_size(unsigned int memconfig) +{ + return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << + ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); +} + +static inline unsigned int get_bank_config(int bank) +{ + unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0; + return bank % 2 ? res & 0xffff : res >> 16; +} + +struct mem { + unsigned long addr; + unsigned long size; +}; + +/* + * Detect installed memory, do some sanity checks and notify kernel about it + */ +static void probe_memory(void) +{ + int i, j, found, cnt = 0; + struct mem bank[4]; + struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}}; + + printk(KERN_INFO "MC: Probing memory configuration:\n"); + for (i = 0; i < ARRAY_SIZE(bank); i++) { + unsigned int tmp = get_bank_config(i); + if (!(tmp & SGIMC_MCONFIG_BVALID)) + continue; + + bank[cnt].size = get_bank_size(tmp); + bank[cnt].addr = get_bank_addr(tmp); + printk(KERN_INFO " bank%d: %3ldM @ %08lx\n", + i, bank[cnt].size / 1024 / 1024, bank[cnt].addr); + cnt++; + } + + /* And you thought bubble sort is dead algorithm... */ + do { + unsigned long addr, size; + + found = 0; + for (i = 1; i < cnt; i++) + if (bank[i-1].addr > bank[i].addr) { + addr = bank[i].addr; + size = bank[i].size; + bank[i].addr = bank[i-1].addr; + bank[i].size = bank[i-1].size; + bank[i-1].addr = addr; + bank[i-1].size = size; + found = 1; + } + } while (found); + + /* Figure out how are memory banks mapped into spaces */ + for (i = 0; i < cnt; i++) { + found = 0; + for (j = 0; j < ARRAY_SIZE(space) && !found; j++) + if (space[j].addr + space[j].size == bank[i].addr) { + space[j].size += bank[i].size; + found = 1; + } + /* There is either hole or overlapping memory */ + if (!found) + printk(KERN_CRIT "MC: Memory configuration mismatch " + "(%08lx), expect Bus Error soon\n", + bank[i].addr); + } + + for (i = 0; i < ARRAY_SIZE(space); i++) + if (space[i].size) + add_memory_region(space[i].addr, space[i].size, + BOOT_MEM_RAM); +} + +void __init sgimc_init(void) +{ + u32 tmp; + + sgimc = (struct sgimc_regs *)(KSEG1 + SGIMC_BASE); + + printk(KERN_INFO "MC: SGI memory controller Revision %d\n", + (int) sgimc->systemid & SGIMC_SYSID_MASKREV); + + /* Place the MC into a known state. This must be done before + * interrupts are first enabled etc. + */ + + /* Step 0: Make sure we turn off the watchdog in case it's + * still running (which might be the case after a + * soft reboot). + */ + tmp = sgimc->cpuctrl0; + tmp &= ~SGIMC_CCTRL0_WDOG; + sgimc->cpuctrl0 = tmp; + + /* Step 1: The CPU/GIO error status registers will not latch + * up a new error status until the register has been + * cleared by the cpu. These status registers are + * cleared by writing any value to them. + */ + sgimc->cstat = sgimc->gstat = 0; + + /* Step 2: Enable all parity checking in cpu control register + * zero. + */ + tmp = sgimc->cpuctrl0; + tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | + SGIMC_CCTRL0_R4KNOCHKPARR); + sgimc->cpuctrl0 = tmp; + + /* Step 3: Setup the MC write buffer depth, this is controlled + * in cpu control register 1 in the lower 4 bits. + */ + tmp = sgimc->cpuctrl1; + tmp &= ~0xf; + tmp |= 0xd; + sgimc->cpuctrl1 = tmp; + + /* Step 4: Initialize the RPSS divider register to run as fast + * as it can correctly operate. The register is laid + * out as follows: + * + * ---------------------------------------- + * | RESERVED | INCREMENT | DIVIDER | + * ---------------------------------------- + * 31 16 15 8 7 0 + * + * DIVIDER determines how often a 'tick' happens, + * INCREMENT determines by how the RPSS increment + * registers value increases at each 'tick'. Thus, + * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 + */ + sgimc->divider = 0x101; + + /* Step 5: Initialize GIO64 arbitrator configuration register. + * + * NOTE: HPC init code in sgihpc_init() must run before us because + * we need to know Guiness vs. FullHouse and the board + * revision on this machine. You have been warned. + */ + + /* First the basic invariants across all GIO64 implementations. */ + tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */ + tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */ + + if (ip22_is_fullhouse()) { + /* Fullhouse specific settings. */ + if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) { + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC at 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp0 pipelines */ + tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */ + tmp |= SGIMC_GIOPAR_RTIMEEXP0; /* exp0 is realtime */ + } else { + tmp |= SGIMC_GIOPAR_HPC264; /* 2nd HPC 64bits */ + tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */ + tmp |= SGIMC_GIOPAR_PLINEEXP1; + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */ + tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */ + } + } else { + /* Guiness specific settings. */ + tmp |= SGIMC_GIOPAR_EISA64; /* MC talks to EISA at 64bits */ + tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */ + } + sgimc->giopar = tmp; /* poof */ + + probe_memory(); +} + +void __init prom_meminit(void) {} +void __init prom_free_prom_memory (void) {} diff -Nru a/arch/mips/sgi-ip22/ip22-nvram.c b/arch/mips/sgi-ip22/ip22-nvram.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-nvram.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,114 @@ +/* + * ip22-nvram.c: NVRAM and serial EEPROM handling. + * + * Copyright (C) 2003 Ladislav Michl (ladis@linux-mips.org) + */ + +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> + +/* Control opcode for serial eeprom */ +#define EEPROM_READ 0xc000 /* serial memory read */ +#define EEPROM_WEN 0x9800 /* write enable before prog modes */ +#define EEPROM_WRITE 0xa000 /* serial memory write */ +#define EEPROM_WRALL 0x8800 /* write all registers */ +#define EEPROM_WDS 0x8000 /* disable all programming */ +#define EEPROM_PRREAD 0xc000 /* read protect register */ +#define EEPROM_PREN 0x9800 /* enable protect register mode */ +#define EEPROM_PRCLEAR 0xffff /* clear protect register */ +#define EEPROM_PRWRITE 0xa000 /* write protect register */ +#define EEPROM_PRDS 0x8000 /* disable protect register, forever */ + +#define EEPROM_EPROT 0x01 /* Protect register enable */ +#define EEPROM_CSEL 0x02 /* Chip select */ +#define EEPROM_ECLK 0x04 /* EEPROM clock */ +#define EEPROM_DATO 0x08 /* Data out */ +#define EEPROM_DATI 0x10 /* Data in */ + +/* We need to use this functions early... */ +#define delay() ({ \ + int x; \ + for (x=0; x<100000; x++) __asm__ __volatile__(""); }) + +#define eeprom_cs_on(ptr) ({ \ + *ptr &= ~EEPROM_DATO; \ + *ptr &= ~EEPROM_ECLK; \ + *ptr &= ~EEPROM_EPROT; \ + delay(); \ + *ptr |= EEPROM_CSEL; \ + *ptr |= EEPROM_ECLK; }) + + +#define eeprom_cs_off(ptr) ({ \ + *ptr &= ~EEPROM_ECLK; \ + *ptr &= ~EEPROM_CSEL; \ + *ptr |= EEPROM_EPROT; \ + *ptr |= EEPROM_ECLK; }) + +#define BITS_IN_COMMAND 11 +/* + * clock in the nvram command and the register number. For the + * national semiconductor nv ram chip the op code is 3 bits and + * the address is 6/8 bits. + */ +static inline void eeprom_cmd(volatile unsigned int *ctrl, unsigned cmd, + unsigned reg) +{ + unsigned short ser_cmd; + int i; + + ser_cmd = cmd | (reg << (16 - BITS_IN_COMMAND)); + for (i = 0; i < BITS_IN_COMMAND; i++) { + if (ser_cmd & (1<<15)) /* if high order bit set */ + *ctrl |= EEPROM_DATO; + else + *ctrl &= ~EEPROM_DATO; + *ctrl &= ~EEPROM_ECLK; + *ctrl |= EEPROM_ECLK; + ser_cmd <<= 1; + } + *ctrl &= ~EEPROM_DATO; /* see data sheet timing diagram */ +} + +unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg) +{ + unsigned short res = 0; + int i; + + *ctrl &= ~EEPROM_EPROT; + eeprom_cs_on(ctrl); + eeprom_cmd(ctrl, EEPROM_READ, reg); + + /* clock the data ouf of serial mem */ + for (i = 0; i < 16; i++) { + *ctrl &= ~EEPROM_ECLK; + delay(); + *ctrl |= EEPROM_ECLK; + delay(); + res <<= 1; + if (*ctrl & EEPROM_DATI) + res |= 1; + } + + eeprom_cs_off(ctrl); + + return res; +} + +/* + * Read specified register from main NVRAM + */ +unsigned short ip22_nvram_read(int reg) +{ + if (ip22_is_fullhouse()) + /* IP22 (Indigo2 aka FullHouse) stores env variables into + * 93CS56 Microwire Bus EEPROM 2048 Bit (128x16) */ + return ip22_eeprom_read(&hpc3c0->eeprom, reg); + else { + unsigned short tmp; + /* IP24 (Indy aka Guiness) uses DS1386 8K version */ + reg <<= 1; + tmp = hpc3c0->bbram[reg++] & 0xff; + return (tmp << 8) | (hpc3c0->bbram[reg] & 0xff); + } +} diff -Nru a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-reset.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,245 @@ +/* + * 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) 1997, 1998, 2001, 2003 by Ralf Baechle + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/notifier.h> +#include <linux/timer.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/reboot.h> +#include <asm/ds1286.h> +#include <asm/sgialib.h> +#include <asm/sgi/ioc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> + +/* + * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. + * I'm not sure if this feature is a good idea, for now it's here just to + * make the power button make behave just like under IRIX. + */ +#define POWERDOWN_TIMEOUT 120 + +/* + * Blink frequency during reboot grace period and when paniced. + */ +#define POWERDOWN_FREQ (HZ / 4) +#define PANIC_FREQ (HZ / 8) + +static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; + +#define MACHINE_PANICED 1 +#define MACHINE_SHUTTING_DOWN 2 +static int machine_state = 0; + +static void sgi_machine_restart(char *command) __attribute__((noreturn)); +static void sgi_machine_halt(void) __attribute__((noreturn)); +static void sgi_machine_power_off(void) __attribute__((noreturn)); + +/* XXX How to pass the reboot command to the firmware??? */ +static void sgi_machine_restart(char *command) +{ + if (machine_state & MACHINE_SHUTTING_DOWN) + sgi_machine_power_off(); + ArcReboot(); +} + +static void sgi_machine_halt(void) +{ + if (machine_state & MACHINE_SHUTTING_DOWN) + sgi_machine_power_off(); + ArcEnterInteractiveMode(); +} + +static void sgi_machine_power_off(void) +{ + unsigned char val; + + local_irq_disable(); + + /* Disable watchdog */ + val = CMOS_READ(RTC_CMD); + CMOS_WRITE(val | RTC_WAM, RTC_CMD); + CMOS_WRITE(0, RTC_WSEC); + CMOS_WRITE(0, RTC_WHSEC); + + while(1) { + sgioc->panel = ~SGIOC_PANEL_POWERON; + /* Good bye cruel world ... */ + + /* If we're still running, we probably got sent an alarm + interrupt. Read the flag to clear it. */ + val = CMOS_READ(RTC_HOURS_ALARM); + } +} + +static void power_timeout(unsigned long data) +{ + sgi_machine_power_off(); +} + +static void blink_timeout(unsigned long data) +{ + /* XXX fix this for fullhouse */ + sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF); + sgioc->reset = sgi_ioc_reset; + + mod_timer(&blink_timer, jiffies+data); +} + +static void debounce(unsigned long data) +{ + del_timer(&debounce_timer); + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + /* Interrupt still being sent. */ + debounce_timer.expires = jiffies + 5; /* 0.05s */ + add_timer(&debounce_timer); + + sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR | + SGIOC_PANEL_VOLDNINTR | SGIOC_PANEL_VOLDNHOLD | + SGIOC_PANEL_VOLUPINTR | SGIOC_PANEL_VOLUPHOLD; + + return; + } + + if (machine_state & MACHINE_PANICED) + ArcReboot(); + + enable_irq(SGI_PANEL_IRQ); +} + +static inline void power_button(void) +{ + if (machine_state & MACHINE_PANICED) + return; + + if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { + /* No init process or button pressed twice. */ + sgi_machine_power_off(); + } + + machine_state |= MACHINE_SHUTTING_DOWN; + blink_timer.data = POWERDOWN_FREQ; + blink_timeout(POWERDOWN_FREQ); + + init_timer(&power_timer); + power_timer.function = power_timeout; + power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ; + add_timer(&power_timer); +} + +void (*indy_volume_button)(int) = NULL; + +static inline void volume_up_button(unsigned long data) +{ + del_timer(&volume_timer); + + if (indy_volume_button) + indy_volume_button(1); + + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } +} + +static inline void volume_down_button(unsigned long data) +{ + del_timer(&volume_timer); + + if (indy_volume_button) + indy_volume_button(-1); + + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } +} + +static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned int buttons; + + buttons = sgioc->panel; + sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR; + + if (sgint->istat1 & SGINT_ISTAT1_PWR) { + /* Wait until interrupt goes away */ + disable_irq(SGI_PANEL_IRQ); + init_timer(&debounce_timer); + debounce_timer.function = debounce; + debounce_timer.expires = jiffies + 5; + add_timer(&debounce_timer); + } + + /* Power button was pressed + * + * ioc.ps page 22: "The Panel Register is called Power Control by Full + * House. Only lowest 2 bits are used. Guiness uses upper four bits + * for volume control". This is not true, all bits are pulled high + * on fullhouse + */ + if (ip22_is_fullhouse() || !(buttons & SGIOC_PANEL_POWERINTR)) { + power_button(); + return IRQ_HANDLED; + } + /* TODO: mute/unmute */ + /* Volume up button was pressed */ + if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { + init_timer(&volume_timer); + volume_timer.function = volume_up_button; + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } + /* Volume down button was pressed */ + if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { + init_timer(&volume_timer); + volume_timer.function = volume_down_button; + volume_timer.expires = jiffies + 1; + add_timer(&volume_timer); + } + + return IRQ_HANDLED; +} + +static int panic_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + if (machine_state & MACHINE_PANICED) + return NOTIFY_DONE; + machine_state |= MACHINE_PANICED; + + blink_timer.data = PANIC_FREQ; + blink_timeout(PANIC_FREQ); + + return NOTIFY_DONE; +} + +static struct notifier_block panic_block = { + .notifier_call = panic_event, +}; + +static int __init reboot_setup(void) +{ + _machine_restart = sgi_machine_restart; + _machine_halt = sgi_machine_halt; + _machine_power_off = sgi_machine_power_off; + + request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); + init_timer(&blink_timer); + blink_timer.function = blink_timeout; + notifier_chain_register(&panic_notifier_list, &panic_block); + + return 0; +} + +subsys_initcall(reboot_setup); diff -Nru a/arch/mips/sgi-ip22/ip22-rtc.c b/arch/mips/sgi-ip22/ip22-rtc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-rtc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,32 @@ +/* + * 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. + * + * RTC routines for Indy style attached Dallas chip. + * + * Copyright (C) 1998, 2001 by Ralf Baechle + */ +#include <asm/ds1286.h> +#include <asm/sgi/hpc3.h> + +static unsigned char ip22_rtc_read_data(unsigned long addr) +{ + return hpc3c0->rtcregs[addr]; +} + +static void ip22_rtc_write_data(unsigned char data, unsigned long addr) +{ + hpc3c0->rtcregs[addr] = data; +} + +static int ip22_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops ip22_rtc_ops = { + &ip22_rtc_read_data, + &ip22_rtc_write_data, + &ip22_rtc_bcd_mode +}; diff -Nru a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,181 @@ +/* + * ip22-setup.c: SGI specific setup, including init of the feature struct. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/kdev_t.h> +#include <linux/types.h> +#include <linux/console.h> +#include <linux/sched.h> +#include <linux/tty.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/bootinfo.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/ds1286.h> +#include <asm/time.h> +#include <asm/gdb-stub.h> +#include <asm/io.h> +#include <asm/traps.h> +#include <asm/sgialib.h> +#include <asm/sgi/mc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> + +#ifdef CONFIG_KGDB +extern void rs_kgdb_hook(int); +extern void breakpoint(void); +static int remote_debug = 0; +#endif + +#if defined(CONFIG_IP22_SERIAL_CONSOLE) || defined(CONFIG_ARC_CONSOLE) +extern void console_setup(char *); +#endif + +extern struct rtc_ops ip22_rtc_ops; + +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ + +unsigned long sgi_gfxaddr; + +/* + * Stop-A is originally a Sun thing that isn't standard on IP22 so to avoid + * accidents it's disabled by default on IP22. + * + * FIXME: provide a mechanism to change the value of stop_a_enabled. + */ +int serial_console; +int stop_a_enabled; + +void ip22_do_break(void) +{ + if (!stop_a_enabled) + return; + + printk("\n"); + ArcEnterInteractiveMode(); +} + +extern void ip22_be_init(void) __init; +extern void ip22_time_init(void) __init; + +void __init ip22_setup(void) +{ + char *ctype; +#ifdef CONFIG_KGDB + char *kgdb_ttyd; +#endif + + board_be_init = ip22_be_init; + ip22_time_init(); + + /* Init the INDY HPC I/O controller. Need to call this before + * fucking with the memory controller because it needs to know the + * boardID and whether this is a Guiness or a FullHouse machine. + */ + sgihpc_init(); + + /* Init INDY memory controller. */ + sgimc_init(); + +#ifdef CONFIG_BOARD_SCACHE + /* Now enable boardcaches, if any. */ + indy_sc_init(); +#endif +#ifdef CONFIG_VT + conswitchp = NULL; +#endif + /* Set the IO space to some sane value */ + set_io_port_base (KSEG1ADDR (0x00080000)); + + /* ARCS console environment variable is set to "g?" for + * graphics console, it is set to "d" for the first serial + * line and "d2" for the second serial line. + */ + ctype = ArcGetEnvironmentVariable("console"); + if (ctype && *ctype == 'd') { +#ifdef CONFIG_IP22_SERIAL_CONSOLE + if (*(ctype + 1) == '2') + console_setup("ttyS1"); + else + console_setup("ttyS0"); +#endif + } +#ifdef CONFIG_ARC_CONSOLE + else if (!ctype || *ctype != 'g') { + /* Use ARC if we don't want serial ('d') or Newport ('g'). */ + prom_flags |= PROM_FLAG_USE_AS_CONSOLE; + console_setup("arc"); + } +#endif + +#ifdef CONFIG_KGDB + kgdb_ttyd = prom_getcmdline(); + if ((kgdb_ttyd = strstr(kgdb_ttyd, "kgdb=ttyd")) != NULL) { + int line; + kgdb_ttyd += strlen("kgdb=ttyd"); + if (*kgdb_ttyd != '1' && *kgdb_ttyd != '2') + printk(KERN_INFO "KGDB: Uknown serial line /dev/ttyd%c" + ", falling back to /dev/ttyd1\n", *kgdb_ttyd); + line = *kgdb_ttyd == '2' ? 0 : 1; + printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for " + "session\n", line ? 1 : 2); + rs_kgdb_hook(line); + + printk(KERN_INFO "KGDB: Using serial line /dev/ttyd%d for " + "session, please connect your debugger\n", line ? 1:2); + + remote_debug = 1; + /* Breakpoints and stuff are in sgi_irq_setup() */ + } +#endif + +#ifdef CONFIG_VT +#ifdef CONFIG_SGI_NEWPORT_CONSOLE + if (ctype && *ctype == 'g'){ + unsigned long *gfxinfo; + long (*__vec)(void) = + (void *) *(long *)(long)((PROMBLOCK)->pvector + 0x20); + + gfxinfo = (unsigned long *)__vec(); + sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000 + && gfxinfo[1] <= 0xc0000000) + ? gfxinfo[1] - 0xa0000000 : 0); + + /* newport addresses? */ + if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) { + conswitchp = &newport_con; + + screen_info = (struct screen_info) { + 0, 0, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig_video_page */ + 0, /* orig_video_mode */ + 160, /* orig_video_cols */ + 0, 0, 0, /* unused, ega_bx, unused */ + 64, /* orig_video_lines */ + 0, /* orig_video_isVGA */ + 16 /* orig_video_points */ + }; + } + } +#endif +#ifdef CONFIG_DUMMY_CONSOLE + /* Either if newport console wasn't used or failed to initialize. */ +#ifdef CONFIG_SGI_NEWPORT_CONSOLE + if(conswitchp != &newport_con) +#endif + conswitchp = &dummy_con; +#endif +#endif + rtc_ops = &ip22_rtc_ops; +#ifdef CONFIG_PSMOUSE + aux_device_present = 0xaa; +#endif +} diff -Nru a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip22/ip22-time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,219 @@ +/* + * 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. + * + * Time operations for IP22 machines. Original code may come from + * Ralf Baechle or David S. Miller (sorry guys, i'm really not sure) + * + * Copyright (C) 2001 by Ladislav Michl + */ + +#include <linux/bcd.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/time.h> + +#include <asm/cpu.h> +#include <asm/mipsregs.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/time.h> +#include <asm/ds1286.h> +#include <asm/sgialib.h> +#include <asm/sgi/ioc.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> + +/* + * note that mktime uses month from 1 to 12 while to_tm + * uses 0 to 11. + */ +static unsigned long indy_rtc_get_time(void) +{ + unsigned int yrs, mon, day, hrs, min, sec; + unsigned int save_control; + + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; + + sec = BCD2BIN(hpc3c0->rtcregs[RTC_SECONDS] & 0xff); + min = BCD2BIN(hpc3c0->rtcregs[RTC_MINUTES] & 0xff); + hrs = BCD2BIN(hpc3c0->rtcregs[RTC_HOURS] & 0x1f); + day = BCD2BIN(hpc3c0->rtcregs[RTC_DATE] & 0xff); + mon = BCD2BIN(hpc3c0->rtcregs[RTC_MONTH] & 0x1f); + yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff); + + hpc3c0->rtcregs[RTC_CMD] = save_control; + + if (yrs < 45) + yrs += 30; + if ((yrs += 40) < 70) + yrs += 100; + + return mktime(yrs + 1900, mon, day, hrs, min, sec); +} + +static int indy_rtc_set_time(unsigned long tim) +{ + struct rtc_time tm; + unsigned int save_control; + + to_tm(tim, &tm); + + tm.tm_mon += 1; /* tm_mon starts at zero */ + tm.tm_year -= 1940; + if (tm.tm_year >= 100) + tm.tm_year -= 100; + + save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; + hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; + + hpc3c0->rtcregs[RTC_YEAR] = BIN2BCD(tm.tm_sec); + hpc3c0->rtcregs[RTC_MONTH] = BIN2BCD(tm.tm_mon); + hpc3c0->rtcregs[RTC_DATE] = BIN2BCD(tm.tm_mday); + hpc3c0->rtcregs[RTC_HOURS] = BIN2BCD(tm.tm_hour); + hpc3c0->rtcregs[RTC_MINUTES] = BIN2BCD(tm.tm_min); + hpc3c0->rtcregs[RTC_SECONDS] = BIN2BCD(tm.tm_sec); + hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; + + hpc3c0->rtcregs[RTC_CMD] = save_control; + + return 0; +} + +static unsigned long dosample(void) +{ + u32 ct0, ct1; + volatile u8 msb, lsb; + + /* Start the counter. */ + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MRGEN); + sgint->tcnt2 = (SGINT_TCSAMP_COUNTER & 0xff); + sgint->tcnt2 = (SGINT_TCSAMP_COUNTER >> 8); + + /* Get initial counter invariant */ + ct0 = read_c0_count(); + + /* Latch and spin until top byte of counter2 is zero */ + do { + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT); + lsb = sgint->tcnt2; + msb = sgint->tcnt2; + ct1 = read_c0_count(); + } while (msb); + + /* Stop the counter. */ + sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | + SGINT_TCWORD_MSWST); + /* + * Return the difference, this is how far the r4k counter increments + * for every 1/HZ seconds. We round off the nearest 1 MHz of master + * clock (= 1000000 / 100 / 2 = 5000 count). + */ + return ((ct1 - ct0) / 5000) * 5000; +} + +/* + * Here we need to calibrate the cycle counter to at least be close. + */ +static __init void indy_time_init(void) +{ + unsigned long r4k_ticks[3]; + unsigned long r4k_tick; + + /* + * Figure out the r4k offset, the algorithm is very simple + * and works in _all_ cases as long as the 8254 counter + * register itself works ok (as an interrupt driving timer + * it does not because of bug, this is why we are using + * the onchip r4k counter/compare register to serve this + * purpose, but for r4k_offset calculation it will work + * ok for us). There are other very complicated ways + * of performing this calculation but this one works just + * fine so I am not going to futz around. ;-) + */ + printk(KERN_INFO "Calibrating system timer... "); + dosample(); /* Prime cache. */ + dosample(); /* Prime cache. */ + /* Zero is NOT an option. */ + do { + r4k_ticks[0] = dosample(); + } while (!r4k_ticks[0]); + do { + r4k_ticks[1] = dosample(); + } while (!r4k_ticks[1]); + + if (r4k_ticks[0] != r4k_ticks[1]) { + printk("warning: timer counts differ, retrying... "); + r4k_ticks[2] = dosample(); + if (r4k_ticks[2] == r4k_ticks[0] + || r4k_ticks[2] == r4k_ticks[1]) + r4k_tick = r4k_ticks[2]; + else { + printk("disagreement, using average... "); + r4k_tick = (r4k_ticks[0] + r4k_ticks[1] + + r4k_ticks[2]) / 3; + } + } else + r4k_tick = r4k_ticks[0]; + + printk("%d [%d.%02d MHz CPU]\n", (int) r4k_tick, + (int) (r4k_tick / 5000), (int) (r4k_tick % 5000) / 50); + + mips_counter_frequency = r4k_tick * HZ; +} + +/* Generic SGI handler for (spurious) 8254 interrupts */ +void indy_8254timer_irq(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int irq = SGI_8254_0_IRQ; + ULONG cnt; + char c; + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + printk(KERN_ALERT "Oops, got 8254 interrupt.\n"); + ArcRead(0, &c, 1, &cnt); + ArcEnterInteractiveMode(); + irq_exit(); +} + +void indy_r4k_timer_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int irq = SGI_TIMER_IRQ; + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + timer_interrupt(irq, NULL, regs); + irq_exit(); + + if (softirq_pending(cpu)) + do_softirq(); +} + +extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + +static void indy_timer_setup(struct irqaction *irq) +{ + /* over-write the handler, we use our own way */ + irq->handler = no_action; + + /* setup irqaction */ + setup_irq(SGI_TIMER_IRQ, irq); +} + +void __init ip22_time_init(void) +{ + /* setup hookup functions */ + rtc_get_time = indy_rtc_get_time; + rtc_set_time = indy_rtc_set_time; + + board_time_init = indy_time_init; + board_timer_setup = indy_timer_setup; +} diff -Nru a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/Makefile Fri Jun 27 14:20:04 2003 @@ -0,0 +1,9 @@ +# +# Makefile for the IP27 specific kernel interface routines under Linux. +# + +obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ + ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ + ip27-setup.o ip27-timer.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/TODO Fri Jun 27 14:19:58 2003 @@ -0,0 +1,23 @@ +1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay +not to write to the IOC3 ever. +2. Need to figure out RRB allocation in bridge_startup(). +3. Need to figure out why address swaizzling is needed in inw/outw for +Qlogic scsi controllers. +4. Need to integrate ip27-klconfig.c:find_lboard and +ip27-init.c:find_lbaord_real. DONE +5. Is it okay to set calias space on all nodes as 0, instead of 8k as +in irix? +6. Investigate why things do not work without the setup_test() call +being invoked on all nodes in ip27-memory.c. +7. Too many CLIs in the locore handlers : +For the low level handlers set up by set_except_vector(), +__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror, +investigate whether the code should do CLI, STI or KMODE. +8. Too many do_page_faults invoked - investigate. +9. start_thread must turn off UX64 ... and define tlb_refill_debug. +10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable +does not agree with pgd_bad/pmd_bad. +11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node. +This might need to change later. Only the timer intr is set up to be +received on both Cpu A and B. (ip27_do_irq()/bridge_startup()) +13. Cache flushing (specially the SMP version) has to be investigated. diff -Nru a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-berr.c Fri Jun 27 14:19:54 2003 @@ -0,0 +1,94 @@ +/* + * 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, 1995, 1996, 1999, 2000 by Ralf Baechle + * Copyright (C) 1999, 2000 by Silicon Graphics + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> + +#include <asm/module.h> +#include <asm/sn/addrs.h> +#include <asm/sn/arch.h> +#include <asm/sn/sn0/hub.h> +#include <asm/tlbdebug.h> +#include <asm/traps.h> +#include <asm/uaccess.h> + +extern void dump_tlb_addr(unsigned long addr); +extern void dump_tlb_all(void); + +static void dump_hub_information(unsigned long errst0, unsigned long errst1) +{ + static char *err_type[2][8] = { + { NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout", + NULL, NULL, NULL, NULL }, + { "WERR", "Uncached Partial Write", "PWERR", "Write Timeout", + NULL, NULL, NULL, NULL } + }; + int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK; + + if (!(errst0 & PI_ERR_ST0_VALID_MASK)) { + printk("Hub does not contain valid error information\n"); + return; + } + + + printk("Hub has valid error information:\n"); + if (errst0 & PI_ERR_ST0_OVERRUN_MASK) + printk("Overrun is set. Error stack may contain additional " + "information.\n"); + printk("Hub error address is %08lx\n", + (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3)); + printk("Incoming message command 0x%lx\n", + (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT); + printk("Supplemental field of incoming message is 0x%lx\n", + (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT); + printk("T5 Rn (for RRB only) is 0x%lx\n", + (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT); + printk("Error type is %s\n", err_type[wrb] + [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT] + ? : "invalid"); +} + +int ip27_be_handler(struct pt_regs *regs, int is_fixup) +{ + unsigned long errst0, errst1; + int data = regs->cp0_cause & 4; + int cpu = LOCAL_HUB_L(PI_CPU_NUM); + + if (is_fixup) + return MIPS_BE_FIXUP; + + printk("Slice %c got %cbe at 0x%lx\n", 'A' + cpu, data ? 'd' : 'i', + regs->cp0_epc); + printk("Hub information:\n"); + printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND)); + errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A); + errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A); + dump_hub_information(errst0, errst1); + show_regs(regs); + dump_tlb_all(); + while(1); + force_sig(SIGBUS, current); +} + +void __init ip27_be_init(void) +{ + /* XXX Initialize all the Hub & Bridge error handling here. */ + int cpu = LOCAL_HUB_L(PI_CPU_NUM); + int cpuoff = cpu << 8; + + board_be_handler = ip27_be_handler; + + LOCAL_HUB_S(PI_ERR_INT_PEND, + cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A); + LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0); + LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0); + LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0); /* Disable error stack */ + LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL); +} diff -Nru a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-console.c Fri Jun 27 14:19:59 2003 @@ -0,0 +1,65 @@ +/* + * 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) 2001, 2002 Ralf Baechle + */ +#include <linux/init.h> +#include <linux/console.h> +#include <linux/kdev_t.h> +#include <linux/major.h> +#include <linux/serial.h> +#include <asm/page.h> +#include <asm/sn/addrs.h> +#include <asm/sn/sn0/hub.h> +#include <asm/sn/klconfig.h> +#include <asm/sn/ioc3.h> +#include <asm/sn/sn_private.h> + +#define IOC3_BAUD (22000000 / (3*16)) +#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) + +static inline struct ioc3_uartregs *console_uart(void) +{ + struct ioc3 *ioc3; + + ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base; + + return &ioc3->sregs.uarta; +} + +void prom_putchar(char c) +{ + struct ioc3_uartregs *uart = console_uart(); + + while ((uart->iu_lsr & 0x20) == 0); + uart->iu_thr = c; +} + +char __init prom_getchar(void) +{ + return 0; +} + +static void inline ioc3_console_probe(void) +{ + struct serial_struct req; + + /* Register to interrupt zero because we share the interrupt with + the serial driver which we don't properly support yet. */ + memset(&req, 0, sizeof(req)); + req.irq = 0; + req.flags = IOC3_COM_FLAGS; + req.io_type = SERIAL_IO_MEM; + req.iomem_reg_shift = 0; + req.baud_base = IOC3_BAUD; + + req.iomem_base = (unsigned char *) console_uart(); + register_serial(&req); +} + +__init void ip27_setup_console(void) +{ + ioc3_console_probe(); +} diff -Nru a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-init.c Fri Jun 27 14:20:04 2003 @@ -0,0 +1,821 @@ +/* + * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com) + * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mmzone.h> /* for numnodes */ +#include <linux/mm.h> +#include <asm/cpu.h> +#include <asm/pgalloc.h> +#include <asm/pgtable.h> +#include <asm/sn/types.h> +#include <asm/sn/sn0/addrs.h> +#include <asm/sn/sn0/hubni.h> +#include <asm/sn/sn0/hubio.h> +#include <asm/sn/klconfig.h> +#include <asm/sn/ioc3.h> +#include <asm/mipsregs.h> +#include <asm/sn/gda.h> +#include <asm/sn/intr.h> +#include <asm/current.h> +#include <asm/smp.h> +#include <asm/processor.h> +#include <asm/mmu_context.h> +#include <asm/thread_info.h> +#include <asm/sn/launch.h> +#include <asm/sn/sn_private.h> +#include <asm/sn/sn0/ip27.h> +#include <asm/sn/mapped_kernel.h> +#include <asm/sn/sn0/addrs.h> +#include <asm/sn/gda.h> + +#define CPU_NONE (cpuid_t)-1 + +/* + * The following should work till 64 nodes, ie 128p SN0s. + */ +#define CNODEMASK_CLRALL(p) (p) = 0 +#define CNODEMASK_TSTB(p, bit) ((p) & (1ULL << (bit))) +#define CNODEMASK_SETB(p, bit) ((p) |= 1ULL << (bit)) + +cpumask_t boot_cpumask; +hubreg_t region_mask; +static int fine_mode; +int maxcpus; +static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED; +static cnodemask_t hub_init_mask; +static atomic_t numstarted = ATOMIC_INIT(1); +static int router_distance; +nasid_t master_nasid = INVALID_NASID; + +cnodeid_t nasid_to_compact_node[MAX_NASIDS]; +nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; +cnodeid_t cpuid_to_compact_node[MAXCPUS]; +char node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; + +hubreg_t get_region(cnodeid_t cnode) +{ + if (fine_mode) + return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; + else + return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; +} + +static void gen_region_mask(hubreg_t *region_mask, int maxnodes) +{ + cnodeid_t cnode; + + (*region_mask) = 0; + for (cnode = 0; cnode < maxnodes; cnode++) { + (*region_mask) |= 1ULL << get_region(cnode); + } +} + +int is_fine_dirmode(void) +{ + return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) + >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE); +} + +nasid_t get_actual_nasid(lboard_t *brd) +{ + klhub_t *hub; + + if (!brd) + return INVALID_NASID; + + /* find out if we are a completely disabled brd. */ + hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); + if (!hub) + return INVALID_NASID; + if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */ + return hub->hub_info.physid; + else + return brd->brd_nasid; +} + +/* Tweak this for maximum number of CPUs to activate */ +static int max_cpus = NR_CPUS; + +int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask, + int *highest) +{ + static int tot_cpus_found = 0; + lboard_t *brd; + klcpu_t *acpu; + int cpus_found = 0; + cpuid_t cpuid; + + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); + + do { + acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU); + while (acpu) { + cpuid = acpu->cpu_info.virtid; + /* cnode is not valid for completely disabled brds */ + if (get_actual_nasid(brd) == brd->brd_nasid) + cpuid_to_compact_node[cpuid] = cnode; + if (cpuid > *highest) + *highest = cpuid; + /* Only let it join in if it's marked enabled */ + if ((acpu->cpu_info.flags & KLINFO_ENABLE) && + (tot_cpus_found != max_cpus)) { + CPUMASK_SETB(*boot_cpumask, cpuid); + cpus_found++; + tot_cpus_found++; + } + acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, + KLSTRUCT_CPU); + } + brd = KLCF_NEXT(brd); + if (brd) + brd = find_lboard(brd,KLTYPE_IP27); + else + break; + } while (brd); + + return cpus_found; +} + +cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes) +{ + int i, cpus = 0, highest = 0; + gda_t *gdap = GDA; + nasid_t nasid; + + /* + * Initialize the arrays to invalid nodeid (-1) + */ + for (i = 0; i < MAX_COMPACT_NODES; i++) + compact_to_nasid_node[i] = INVALID_NASID; + for (i = 0; i < MAX_NASIDS; i++) + nasid_to_compact_node[i] = INVALID_CNODEID; + for (i = 0; i < MAXCPUS; i++) + cpuid_to_compact_node[i] = INVALID_CNODEID; + + *numnodes = 0; + for (i = 0; i < MAX_COMPACT_NODES; i++) { + if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) { + break; + } else { + compact_to_nasid_node[i] = nasid; + nasid_to_compact_node[nasid] = i; + (*numnodes)++; + cpus += do_cpumask(i, nasid, boot_cpumask, &highest); + } + } + + /* + * Cpus are numbered in order of cnodes. Currently, disabled + * cpus are not numbered. + */ + + return highest + 1; +} + +int cpu_enabled(cpuid_t cpu) +{ + if (cpu == CPU_NONE) + return 0; + return CPUMASK_TSTB(boot_cpumask, cpu) != 0; +} + +void mlreset(void) +{ + int i; + void init_topology_matrix(void); + void dump_topology(void); + + + master_nasid = get_nasid(); + fine_mode = is_fine_dirmode(); + + /* + * Probe for all CPUs - this creates the cpumask and + * sets up the mapping tables. + */ + CPUMASK_CLRALL(boot_cpumask); + maxcpus = cpu_node_probe(&boot_cpumask, &numnodes); + printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes); + + init_topology_matrix(); + dump_topology(); + + gen_region_mask(®ion_mask, numnodes); + CNODEMASK_CLRALL(hub_init_mask); + + setup_replication_mask(numnodes); + + /* + * Set all nodes' calias sizes to 8k + */ + for (i = 0; i < numnodes; i++) { + nasid_t nasid; + + nasid = COMPACT_TO_NASID_NODEID(i); + + /* + * Always have node 0 in the region mask, otherwise + * CALIAS accesses get exceptions since the hub + * thinks it is a node 0 address. + */ + REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1)); +#ifdef CONFIG_REPLICATE_EXHANDLERS + REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K); +#else + REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0); +#endif + +#ifdef LATER + /* + * Set up all hubs to have a big window pointing at + * widget 0. Memory mode, widget 0, offset 0 + */ + REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN), + ((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) | + (0 << IIO_ITTE_WIDGET_SHIFT))); +#endif + } +} + + +void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level, + char *name) +{ + volatile hubreg_t bits; + int i; + + /* Check pending interrupts */ + if ((bits = HUB_L(pend)) != 0) + for (i = 0; i < N_INTPEND_BITS; i++) + if (bits & (1 << i)) + LOCAL_HUB_CLR_INTR(base_level + i); +} + +void intr_clear_all(nasid_t nasid) +{ + REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0); + REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0); + REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0); + REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0); + intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0), + INT_PEND0_BASELVL, "INT_PEND0"); + intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1), + INT_PEND1_BASELVL, "INT_PEND1"); +} + +void sn_mp_setup(void) +{ + cnodeid_t cnode; +#if 0 + cpuid_t cpu; +#endif + + for (cnode = 0; cnode < numnodes; cnode++) { +#if 0 + init_platform_nodepda(); +#endif + intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); + } +#if 0 + for (cpu = 0; cpu < maxcpus; cpu++) { + init_platform_pda(); + } +#endif +} + +void per_hub_init(cnodeid_t cnode) +{ + extern void pcibr_setup(cnodeid_t); + cnodemask_t done; + nasid_t nasid; + + nasid = COMPACT_TO_NASID_NODEID(cnode); + + spin_lock(&hub_mask_lock); + /* Test our bit. */ + if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) { + /* Turn our bit on in the mask. */ + CNODEMASK_SETB(hub_init_mask, cnode); + /* + * Do the actual initialization if it hasn't been done yet. + * We don't need to hold a lock for this work. + */ + /* + * Set CRB timeout at 5ms, (< PI timeout of 10ms) + */ + REMOTE_HUB_S(nasid, IIO_ICTP, 0x800); + REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); + hub_rtc_init(cnode); + pcibr_setup(cnode); +#ifdef CONFIG_REPLICATE_EXHANDLERS + /* + * If this is not a headless node initialization, + * copy over the caliased exception handlers. + */ + if (get_compact_nodeid() == cnode) { + extern char except_vec0, except_vec1_r10k; + extern char except_vec2_generic, except_vec3_generic; + + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, + 0x80); + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, + 0x80); + memcpy((void *)KSEG0, &except_vec0, 0x80); + memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80); + memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, + 0x100); + __flush_cache_all(); + } +#endif + } + spin_unlock(&hub_mask_lock); +} + +/* + * This is similar to hard_smp_processor_id(). + */ +cpuid_t getcpuid(void) +{ + klcpu_t *klcpu; + + klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM)); + return klcpu->cpu_info.virtid; +} + +void per_cpu_init(void) +{ + extern void install_cpu_nmi_handler(int slice); + extern void load_mmu(void); + static int is_slave = 0; + int cpu = smp_processor_id(); + cnodeid_t cnode = get_compact_nodeid(); + + TLBMISS_HANDLER_SETUP(); +#if 0 + intr_init(); +#endif + clear_c0_status(ST0_IM); + per_hub_init(cnode); + cpu_time_init(); + if (smp_processor_id()) /* master can't do this early, no kmalloc */ + install_cpuintr(cpu); + /* Install our NMI handler if symmon hasn't installed one. */ + install_cpu_nmi_handler(cputoslice(cpu)); +#if 0 + install_tlbintr(cpu); +#endif + set_c0_status(SRB_DEV0 | SRB_DEV1); + if (is_slave) { + clear_c0_status(ST0_BEV); + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); + set_c0_status(ST0_KX|ST0_SX|ST0_UX); + local_irq_enable(); + load_mmu(); + atomic_inc(&numstarted); + } else { + is_slave = 1; + } +} + +cnodeid_t get_compact_nodeid(void) +{ + nasid_t nasid; + + nasid = get_nasid(); + /* + * Map the physical node id to a virtual node id (virtual node ids + * are contiguous). + */ + return NASID_TO_COMPACT_NODEID(nasid); +} + +#ifdef CONFIG_SMP + +/* + * Takes as first input the PROM assigned cpu id, and the kernel + * assigned cpu id as the second. + */ +static void alloc_cpupda(cpuid_t cpu, int cpunum) +{ + cnodeid_t node; + nasid_t nasid; + + node = get_cpu_cnode(cpu); + nasid = COMPACT_TO_NASID_NODEID(node); + + cputonasid(cpunum) = nasid; + cputocnode(cpunum) = node; + cputoslice(cpunum) = get_cpu_slice(cpu); + cpu_data[cpunum].p_cpuid = cpu; +} + +static struct task_struct * __init fork_by_hand(void) +{ + struct pt_regs regs; + /* + * don't care about the eip and regs settings since + * we'll never reschedule the forked task. + */ + return copy_process(CLONE_VM|CLONE_IDLETASK, 0, ®s, 0, NULL, NULL); +} + +static int __init do_boot_cpu(int cpu, int num_cpus) +{ + extern void smp_bootstrap(void); + cpuid_t mycpuid = getcpuid(); + struct task_struct *idle; + + if (cpu == mycpuid) { + alloc_cpupda(cpu, num_cpus); + return 1; + } + + /* Skip holes in CPU space */ + if (!CPUMASK_TSTB(boot_cpumask, cpu)) + return 0; + + /* + * The following code is purely to make sure + * Linux can schedule processes on this slave. + */ + idle = fork_by_hand(); + if (IS_ERR(idle)) + panic("failed fork for CPU %d", cpu); + + /* + * We remove it from the pidhash and the runqueue + * once we got the process: + */ + init_idle(idle, cpu); + + alloc_cpupda(cpu, num_cpus); + + unhash_process(idle); + + /* + * Launch a slave into smp_bootstrap(). It doesn't take an + * argument, and we set sp to the kernel stack of the newly + * created idle process, gp to the proc struct so that + * current_thread_info() will work. + */ + LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), + (launch_proc_t)MAPPED_KERN_RW_TO_K0(smp_bootstrap), + 0, (void *)((unsigned long)idle->thread_info + + KERNEL_STACK_SIZE - 32), (void *)idle); + + /* + * Now optimistically set the mapping arrays. We + * need to wait here, verify the cpu booted up, then + * fire up the next cpu. + */ + __cpu_number_map[cpu] = num_cpus; + __cpu_logical_map[num_cpus] = cpu; + CPUMASK_SETB(cpu_online_map, cpu); + + /* + * Wait this cpu to start up and initialize its hub, + * and discover the io devices it will control. + * + * XXX: We really want to fire up launch all the CPUs + * at once. We have to preserve the order of the + * devices on the bridges first though. + */ + while (atomic_read(&numstarted) != num_cpus); + + return 1; +} + +void __init smp_boot_cpus(void) +{ + int num_cpus = 0; + cpuid_t cpu; + cnodeid_t cnode; + + init_new_context(current, &init_mm); + current_thread_info()->cpu = 0; + smp_tune_scheduling(); + + sn_mp_setup(); + /* Master has already done per_cpu_init() */ + install_cpuintr(smp_processor_id()); +#if 0 + bte_lateinit(); + ecc_init(); +#endif + + replicate_kernel_text(numnodes); + /* Launch slaves. */ + for (cpu = 0; cpu < maxcpus; cpu++) { + num_cpus += do_boot_cpu(cpu, num_cpus); + } + +#ifdef LATER + Wait logic goes here. +#endif + for (cnode = 0; cnode < numnodes; cnode++) { +#if 0 + if (cnodetocpu(cnode) == -1) { + printk("Initializing headless hub,cnode %d", cnode); + per_hub_init(cnode); + } +#endif + } +#if 0 + cpu_io_setup(); + init_mfhi_war(); +#endif +} + +#else /* CONFIG_SMP */ +void __init start_secondary(void) +{ + /* XXX Why do we need this empty definition at all? */ +} +#endif /* CONFIG_SMP */ + + +#define rou_rflag rou_flags + +void router_recurse(klrou_t *router_a, klrou_t *router_b, int depth) +{ + klrou_t *router; + lboard_t *brd; + int port; + + if (router_a->rou_rflag == 1) + return; + + if (depth >= router_distance) + return; + + router_a->rou_rflag = 1; + + for (port = 1; port <= MAX_ROUTER_PORTS; port++) { + if (router_a->rou_port[port].port_nasid == INVALID_NASID) + continue; + + brd = (lboard_t *)NODE_OFFSET_TO_K0( + router_a->rou_port[port].port_nasid, + router_a->rou_port[port].port_offset); + + if (brd->brd_type == KLTYPE_ROUTER) { + router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); + if (router == router_b) { + if (depth < router_distance) + router_distance = depth; + } + else + router_recurse(router, router_b, depth + 1); + } + } + + router_a->rou_rflag = 0; +} + +int node_distance(nasid_t nasid_a, nasid_t nasid_b) +{ + nasid_t nasid; + cnodeid_t cnode; + lboard_t *brd, *dest_brd; + int port; + klrou_t *router, *router_a = NULL, *router_b = NULL; + + /* Figure out which routers nodes in question are connected to */ + for (cnode = 0; cnode < numnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + + if (nasid == -1) continue; + + brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_ROUTER); + + if (!brd) + continue; + + do { + if (brd->brd_flags & DUPLICATE_BOARD) + continue; + + router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); + router->rou_rflag = 0; + + for (port = 1; port <= MAX_ROUTER_PORTS; port++) { + if (router->rou_port[port].port_nasid == INVALID_NASID) + continue; + + dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( + router->rou_port[port].port_nasid, + router->rou_port[port].port_offset); + + if (dest_brd->brd_type == KLTYPE_IP27) { + if (dest_brd->brd_nasid == nasid_a) + router_a = router; + if (dest_brd->brd_nasid == nasid_b) + router_b = router; + } + } + + } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); + } + + if (router_a == NULL) { + printk("node_distance: router_a NULL\n"); + return -1; + } + if (router_b == NULL) { + printk("node_distance: router_b NULL\n"); + return -1; + } + + if (nasid_a == nasid_b) + return 0; + + if (router_a == router_b) + return 1; + + router_distance = 100; + router_recurse(router_a, router_b, 2); + + return router_distance; +} + +void init_topology_matrix(void) +{ + nasid_t nasid, nasid2; + cnodeid_t row, col; + + for (row = 0; row < MAX_COMPACT_NODES; row++) + for (col = 0; col < MAX_COMPACT_NODES; col++) + node_distances[row][col] = -1; + + for (row = 0; row < numnodes; row++) { + nasid = COMPACT_TO_NASID_NODEID(row); + for (col = 0; col < numnodes; col++) { + nasid2 = COMPACT_TO_NASID_NODEID(col); + node_distances[row][col] = node_distance(nasid, nasid2); + } + } +} + +void dump_topology(void) +{ + nasid_t nasid; + cnodeid_t cnode; + lboard_t *brd, *dest_brd; + int port; + int router_num = 0; + klrou_t *router; + cnodeid_t row, col; + + printk("************** Topology ********************\n"); + + printk(" "); + for (col = 0; col < numnodes; col++) + printk("%02d ", col); + printk("\n"); + for (row = 0; row < numnodes; row++) { + printk("%02d ", row); + for (col = 0; col < numnodes; col++) + printk("%2d ", node_distances[row][col]); + printk("\n"); + } + + for (cnode = 0; cnode < numnodes; cnode++) { + nasid = COMPACT_TO_NASID_NODEID(cnode); + + if (nasid == -1) continue; + + brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_ROUTER); + + if (!brd) + continue; + + do { + if (brd->brd_flags & DUPLICATE_BOARD) + continue; + printk("Router %d:", router_num); + router_num++; + + router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); + + for (port = 1; port <= MAX_ROUTER_PORTS; port++) { + if (router->rou_port[port].port_nasid == INVALID_NASID) + continue; + + dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( + router->rou_port[port].port_nasid, + router->rou_port[port].port_offset); + + if (dest_brd->brd_type == KLTYPE_IP27) + printk(" %d", dest_brd->brd_nasid); + if (dest_brd->brd_type == KLTYPE_ROUTER) + printk(" r"); + } + printk("\n"); + + } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); + } +} + +#if 0 +#define brd_widgetnum brd_slot +#define NODE_OFFSET_TO_KLINFO(n,off) ((klinfo_t*) TO_NODE_CAC(n,off)) +void +dump_klcfg(void) +{ + cnodeid_t cnode; + int i; + nasid_t nasid; + lboard_t *lbptr; + gda_t *gdap; + + gdap = (gda_t *)GDA_ADDR(get_nasid()); + if (gdap->g_magic != GDA_MAGIC) { + printk("dumpklcfg_cmd: Invalid GDA MAGIC\n"); + return; + } + + for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) { + nasid = gdap->g_nasidtable[cnode]; + + if (nasid == INVALID_NASID) + continue; + + printk("\nDumpping klconfig Nasid %d:\n", nasid); + + lbptr = KL_CONFIG_INFO(nasid); + + while (lbptr) { + printk(" %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx", + "board name here", /* BOARD_NAME(lbptr->brd_type), */ + lbptr->brd_nasid, lbptr->brd_module, + lbptr->brd_widgetnum, + lbptr->brd_partition, + (lbptr->brd_nic), lbptr); + if (lbptr->brd_flags & DUPLICATE_BOARD) + printk(" -D"); + printk("\n"); + for (i = 0; i < lbptr->brd_numcompts; i++) { + klinfo_t *kli; + kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]); + printk(" type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n", + kli->struct_type, + kli->flags, + kli->diagval, + kli->physid, + kli->virtid, + "comp. name here"); + /* COMPONENT_NAME(kli->struct_type)); */ + } + lbptr = KLCF_NEXT(lbptr); + } + } + printk("\n"); + + /* Useful to print router maps also */ + + for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) { + klrou_t *kr; + int i; + + nasid = gdap->g_nasidtable[cnode]; + if (nasid == INVALID_NASID) + continue; + lbptr = KL_CONFIG_INFO(nasid); + + while (lbptr) { + + lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER); + if(!lbptr) + break; + if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) { + printk("%llx -> \n", lbptr->brd_nic); + kr = (klrou_t *)find_first_component(lbptr, + KLSTRUCT_ROU); + for (i = 1; i <= MAX_ROUTER_PORTS; i++) { + printk("[%d, %llx]; ", + kr->rou_port[i].port_nasid, + kr->rou_port[i].port_offset); + } + printk("\n"); + } + lbptr = KLCF_NEXT(lbptr); + } + printk("\n"); + } + + dump_topology(); +} +#endif diff -Nru a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-irq-glue.S Fri Jun 27 14:19:54 2003 @@ -0,0 +1,64 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + .text + .set noat + .align 5 +NESTED(ip27_irq, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + /* IP27 may signal interrupt which we're not interested in. + Mask them out. */ + mfc0 s0, CP0_CAUSE + mfc0 t0, CP0_STATUS + and s0, t0 + + /* First check for RT interrupt. */ + andi a0, s0, CAUSEF_IP4 + beqz a0, 1f + + /* Ok, a timer interrupt. */ + move a0, sp + jal rt_timer_interrupt + + j ret_from_irq + +1: andi a0, s0, (CAUSEF_IP2 | CAUSEF_IP3) + beqz a0, 1f + + /* ... a device interrupt ... */ + move a0, sp + jal ip27_do_irq + + j ret_from_irq + +1: +#if 1 + mfc0 a1, CP0_STATUS + srl a1, a1, 8 + andi a1, 0xff + + mfc0 a2, CP0_CAUSE + srl a2, a2, 8 + andi a2, 0xff + + move a3, s0 + PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n") + ld a1, PT_EPC(sp) +0: b 0b +#endif + + j ret_from_irq + END(ip27_irq) diff -Nru a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-irq.c Fri Jun 27 14:19:56 2003 @@ -0,0 +1,488 @@ +/* + * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. + * + * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 1999 - 2001 Kanoj Sarcar + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/smp_lock.h> +#include <linux/kernel_stat.h> +#include <linux/delay.h> + +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + +#include <asm/ptrace.h> +#include <asm/processor.h> +#include <asm/pci/bridge.h> +#include <asm/sn/sn0/hub.h> +#include <asm/sn/sn0/ip27.h> +#include <asm/sn/addrs.h> +#include <asm/sn/agent.h> +#include <asm/sn/arch.h> +#include <asm/sn/intr.h> +#include <asm/sn/intr_public.h> + + +#undef DEBUG_IRQ +#ifdef DEBUG_IRQ +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* These should die */ +unsigned char bus_to_wid[256]; /* widget id for linux pci bus */ +unsigned char bus_to_nid[256]; /* nasid for linux pci bus */ +unsigned char num_bridges; /* number of bridges in the system */ + +/* + * Linux has a controller-independent x86 interrupt architecture. + * every controller has a 'controller-template', that is used + * by the main code to do the right thing. Each driver-visible + * interrupt source is transparently wired to the apropriate + * controller. Thus drivers need not be aware of the + * interrupt-controller. + * + * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, + * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. + * (IO-APICs assumed to be messaging to Pentium local-APICs) + * + * the code is designed to be easily extended with new/different + * interrupt controllers, without having to do assembly magic. + */ + +extern asmlinkage void ip27_irq(void); + +extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[]; +int intr_connect_level(int cpu, int bit); +int intr_disconnect_level(int cpu, int bit); + +/* + * There is a single intpend register per node, and we want to have + * distinct levels for intercpu intrs for both cpus A and B on a node. + */ +int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS]; + +/* + * use these macros to get the encoded nasid and widget id + * from the irq value + */ +#define IRQ_TO_BUS(i) irq_to_bus[(i)] +#define IRQ_TO_CPU(i) bus_to_cpu[IRQ_TO_BUS(i)] +#define NASID_FROM_PCI_IRQ(i) bus_to_nid[IRQ_TO_BUS(i)] +#define WID_FROM_PCI_IRQ(i) bus_to_wid[IRQ_TO_BUS(i)] +#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i] + +static inline int alloc_level(cpuid_t cpunum, int irq) +{ + cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum); + int j = LEAST_LEVEL + 3; /* resched & crosscall entries taken */ + + while (++j < PERNODE_LEVELS) { + if (node_level_to_irq[nodenum][j] == -1) { + node_level_to_irq[nodenum][j] = irq; + return j; + } + } + printk("Cpu %ld flooded with devices\n", cpunum); + while(1); + return -1; +} + +static inline int find_level(cpuid_t *cpunum, int irq) +{ + int j; + cnodeid_t nodenum = INVALID_CNODEID; + + while (++nodenum < MAX_COMPACT_NODES) { + j = LEAST_LEVEL + 3; /* resched & crosscall entries taken */ + while (++j < PERNODE_LEVELS) + if (node_level_to_irq[nodenum][j] == irq) { + *cpunum = 0; /* XXX Fixme */ + return(j); + } + } + printk("Could not identify cpu/level for irq %d\n", irq); + while(1); + return(-1); +} + +/* + * Find first bit set + */ +static int ms1bit(unsigned long x) +{ + int b = 0, s; + + s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s; + s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s; + s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s; + s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s; + s = 1; if (x >> 1 == 0) s = 0; b += s; + + return b; +} + +/* + * This code is unnecessarily complex, because we do SA_INTERRUPT + * intr enabling. Basically, once we grab the set of intrs we need + * to service, we must mask _all_ these interrupts; firstly, to make + * sure the same intr does not intr again, causing recursion that + * can lead to stack overflow. Secondly, we can not just mask the + * one intr we are do_IRQing, because the non-masked intrs in the + * first set might intr again, causing multiple servicings of the + * same intr. This effect is mostly seen for intercpu intrs. + * Kanoj 05.13.00 + */ +void ip27_do_irq(struct pt_regs *regs) +{ + int irq, swlevel; + hubreg_t pend0, mask0; + cpuid_t thiscpu = smp_processor_id(); + int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ? + PI_INT_MASK0_A : PI_INT_MASK0_B); + + /* copied from Irix intpend0() */ + while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) & + (mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) { + pend0 &= mask0; /* Pick intrs we should look at */ + if (pend0) { + /* Prevent any of the picked intrs from recursing */ + LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0)); + do { + swlevel = ms1bit(pend0); + LOCAL_HUB_CLR_INTR(swlevel); + /* "map" swlevel to irq */ + irq = LEVEL_TO_IRQ(thiscpu, swlevel); + do_IRQ(irq, regs); + /* clear bit in pend0 */ + pend0 ^= 1ULL << swlevel; + } while(pend0); + /* Now allow the set of serviced intrs again */ + LOCAL_HUB_S(pi_int_mask0, mask0); + LOCAL_HUB_L(PI_INT_PEND0); + } + } +} + + +/* Startup one of the (PCI ...) IRQs routes over a bridge. */ +static unsigned int startup_bridge_irq(unsigned int irq) +{ + bridgereg_t device; + bridge_t *bridge; + int pin, swlevel; + cpuid_t cpu; + nasid_t master = NASID_FROM_PCI_IRQ(irq); + + if (irq < BASE_PCI_IRQ) + return 0; + + bridge = (bridge_t *) NODE_SWIN_BASE(master, WID_FROM_PCI_IRQ(irq)); + pin = SLOT_FROM_PCI_IRQ(irq); + cpu = IRQ_TO_CPU(irq); + + DBG("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); + /* + * "map" irq to a swlevel greater than 6 since the first 6 bits + * of INT_PEND0 are taken + */ + swlevel = alloc_level(cpu, irq); + intr_connect_level(cpu, swlevel); + + bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8)); + bridge->b_int_enable |= (1 << pin); + /* more stuff in int_enable reg */ + bridge->b_int_enable |= 0x7ffffe00; + + /* + * XXX This only works if b_int_device is initialized to 0! + * We program the bridge to have a 1:1 mapping between devices + * (slots) and intr pins. + */ + device = bridge->b_int_device; + device |= (pin << (pin*3)); + bridge->b_int_device = device; + + bridge->b_widget.w_tflush; /* Flush */ + + return 0; /* Never anything pending. */ +} + +/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ +static unsigned int shutdown_bridge_irq(unsigned int irq) +{ + bridge_t *bridge; + int pin, swlevel; + cpuid_t cpu; + + if (irq < BASE_PCI_IRQ) + return 0; + + bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq), + WID_FROM_PCI_IRQ(irq)); + DBG("bridge_shutdown: irq 0x%x\n", irq); + pin = SLOT_FROM_PCI_IRQ(irq); + + /* + * map irq to a swlevel greater than 6 since the first 6 bits + * of INT_PEND0 are taken + */ + swlevel = find_level(&cpu, irq); + intr_disconnect_level(cpu, swlevel); + LEVEL_TO_IRQ(cpu, swlevel) = -1; + + bridge->b_int_enable &= ~(1 << pin); + bridge->b_widget.w_tflush; /* Flush */ + + return 0; /* Never anything pending. */ +} + +static inline void enable_bridge_irq(unsigned int irq) +{ + /* All the braindamage happens magically for us in ip27_do_irq */ +} + +static void disable_bridge_irq(unsigned int irq) +{ + /* All the braindamage happens magically for us in ip27_do_irq */ +} + +static void mask_and_ack_bridge_irq(unsigned int irq) +{ + /* All the braindamage happens magically for us in ip27_do_irq */ +} + +static void end_bridge_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_bridge_irq(irq); +} + +static struct hw_interrupt_type bridge_irq_type = { + "bridge", + startup_bridge_irq, + shutdown_bridge_irq, + enable_bridge_irq, + disable_bridge_irq, + mask_and_ack_bridge_irq, + end_bridge_irq +}; + +void irq_debug(void) +{ + bridge_t *bridge = (bridge_t *) 0x9200000008000000; + + printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status); + printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable); + printk("PI_INT_PEND0 = 0x%lx\n", LOCAL_HUB_L(PI_INT_PEND0)); + printk("PI_INT_MASK0_A = 0x%lx\n", LOCAL_HUB_L(PI_INT_MASK0_A)); +} + +void __init init_IRQ(void) +{ + int i; + + set_except_vector(0, ip27_irq); + + /* + * Right now the bridge irq is our kitchen sink interrupt type + */ + for (i = 0; i <= NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &bridge_irq_type; + } +} + +/* + * Get values that vary depending on which CPU and bit we're operating on. + */ +static hub_intmasks_t *intr_get_ptrs(cpuid_t cpu, int bit, int *new_bit, + hubreg_t **intpend_masks, int *ip) +{ + hub_intmasks_t *hub_intmasks; + + hub_intmasks = &cpu_data[cpu].p_intmasks; + if (bit < N_INTPEND_BITS) { + *intpend_masks = hub_intmasks->intpend0_masks; + *ip = 0; + *new_bit = bit; + } else { + *intpend_masks = hub_intmasks->intpend1_masks; + *ip = 1; + *new_bit = bit - N_INTPEND_BITS; + } + return hub_intmasks; +} + +int intr_connect_level(int cpu, int bit) +{ + int ip; + int slice = cputoslice(cpu); + volatile hubreg_t *mask_reg; + hubreg_t *intpend_masks; + nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu)); + + (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip); + + /* Make sure it's not already pending when we connect it. */ + REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS); + + intpend_masks[0] |= (1ULL << (u64)bit); + + if (ip == 0) { + mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + + PI_INT_MASK_OFFSET * slice); + } else { + mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + + PI_INT_MASK_OFFSET * slice); + } + HUB_S(mask_reg, intpend_masks[0]); + return(0); +} + +int intr_disconnect_level(int cpu, int bit) +{ + int ip; + int slice = cputoslice(cpu); + volatile hubreg_t *mask_reg; + hubreg_t *intpend_masks; + nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu)); + + (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip); + intpend_masks[0] &= ~(1ULL << (u64)bit); + if (ip == 0) { + mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + + PI_INT_MASK_OFFSET * slice); + } else { + mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + + PI_INT_MASK_OFFSET * slice); + } + HUB_S(mask_reg, intpend_masks[0]); + return(0); +} + + +irqreturn_t handle_resched_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + /* Nothing, the return from intr will work for us */ + return IRQ_NONE; +} + +#ifdef CONFIG_SMP + +void core_send_ipi(int destid, unsigned int action) +{ + int irq; + +#if (CPUS_PER_NODE == 2) + switch (action) { + case SMP_RESCHEDULE_YOURSELF: + irq = CPU_RESCHED_A_IRQ; + break; + case SMP_CALL_FUNCTION: + irq = CPU_CALL_A_IRQ; + break; + default: + panic("sendintr"); + } + irq += cputoslice(destid); + + /* + * Convert the compact hub number to the NASID to get the correct + * part of the address space. Then set the interrupt bit associated + * with the CPU we want to send the interrupt to. + */ + REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)), + FAST_IRQ_TO_LEVEL(irq)); +#else + << Bomb! Must redefine this for more than 2 CPUS. >> +#endif +} + +#endif + +extern irqreturn_t smp_call_function_interrupt(int irq, void *dev, + struct pt_regs *regs); + +void install_cpuintr(int cpu) +{ +#ifdef CONFIG_SMP +#if (CPUS_PER_NODE == 2) + static int done = 0; + + /* + * This is a hack till we have a pernode irqlist. Currently, + * just have the master cpu set up the handlers for the per + * cpu irqs. + */ + if (done == 0) { + int j; + + if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr, + 0, "resched", 0)) + panic("intercpu intr unconnectible"); + if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr, + 0, "resched", 0)) + panic("intercpu intr unconnectible"); + if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt, + 0, "callfunc", 0)) + panic("intercpu intr unconnectible"); + if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt, + 0, "callfunc", 0)) + panic("intercpu intr unconnectible"); + + for (j = 0; j < PERNODE_LEVELS; j++) + LEVEL_TO_IRQ(0, j) = -1; + LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) = + CPU_RESCHED_A_IRQ; + LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) = + CPU_RESCHED_B_IRQ; + LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) = + CPU_CALL_A_IRQ; + LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) = + CPU_CALL_B_IRQ; + for (j = 1; j < MAX_COMPACT_NODES; j++) + memcpy(&node_level_to_irq[j][0], + &node_level_to_irq[0][0], + sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS); + + done = 1; + } + + intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ + + cputoslice(cpu))); + intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ + + cputoslice(cpu))); +#else /* CPUS_PER_NODE */ +#error Must redefine this for more than 2 CPUS. +#endif /* CPUS_PER_NODE */ +#endif /* CONFIG_SMP */ +} + +void install_tlbintr(int cpu) +{ +#if 0 + int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu); + + intr_connect_level(cpu, intr_bit); +#endif +} diff -Nru a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-klconfig.c Fri Jun 27 14:19:59 2003 @@ -0,0 +1,135 @@ +/* + * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/param.h> +#include <linux/timex.h> +#include <linux/mm.h> + +#include <asm/sn/klconfig.h> +#include <asm/sn/arch.h> +#include <asm/sn/gda.h> + +klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type) +{ + int index, j; + + if (kli == (klinfo_t *)NULL) { + index = 0; + } else { + for (j = 0; j < KLCF_NUM_COMPS(brd); j++) + if (kli == KLCF_COMP(brd, j)) + break; + index = j; + if (index == KLCF_NUM_COMPS(brd)) { + printk("find_component: Bad pointer: 0x%p\n", kli); + return (klinfo_t *)NULL; + } + index++; /* next component */ + } + + for (; index < KLCF_NUM_COMPS(brd); index++) { + kli = KLCF_COMP(brd, index); + if (KLCF_COMP_TYPE(kli) == struct_type) + return kli; + } + + /* Didn't find it. */ + return (klinfo_t *)NULL; +} + +klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type) +{ + return find_component(brd, (klinfo_t *)NULL, struct_type); +} + +lboard_t * find_lboard(lboard_t *start, unsigned char brd_type) +{ + /* Search all boards stored on this node. */ + while (start) { + if (start->brd_type == brd_type) + return start; + start = KLCF_NEXT(start); + } + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type) +{ + /* Search all boards stored on this node. */ + while (start) { + if (KLCLASS(start->brd_type) == KLCLASS(brd_type)) + return start; + start = KLCF_NEXT(start); + } + + /* Didn't find it. */ + return (lboard_t *)NULL; +} + +cnodeid_t get_cpu_cnode(cpuid_t cpu) +{ + return CPUID_TO_COMPACT_NODEID(cpu); +} + +klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice) +{ + lboard_t *brd; + klcpu_t *acpu; + + if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27))) + return (klcpu_t *)NULL; + + if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU))) + return (klcpu_t *)NULL; + + do { + if ((acpu->cpu_info.physid) == slice) + return acpu; + } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, + KLSTRUCT_CPU))); + return (klcpu_t *)NULL; +} + +klcpu_t * sn_get_cpuinfo(cpuid_t cpu) +{ + nasid_t nasid; + int slice; + klcpu_t *acpu; + gda_t *gdap = GDA; + cnodeid_t cnode; + + if (!(cpu < MAXCPUS)) { + printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu); + return NULL; + } + + cnode = get_cpu_cnode(cpu); + if (cnode == INVALID_CNODEID) + return NULL; + + if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID) + return NULL; + + for (slice = 0; slice < CPUS_PER_NODE; slice++) { + acpu = nasid_slice_to_cpuinfo(nasid, slice); + if (acpu && acpu->cpu_info.virtid == cpu) + return acpu; + } + return NULL; +} + +int get_cpu_slice(cpuid_t cpu) +{ + klcpu_t *acpu; + + if ((acpu = sn_get_cpuinfo(cpu)) == NULL) + return -1; + return acpu->cpu_info.physid; +} diff -Nru a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-klnuma.c Fri Jun 27 14:19:55 2003 @@ -0,0 +1,143 @@ +/* + * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00. + * Copyright 2000 - 2001 Silicon Graphics, Inc. + * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com) + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/mmzone.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/page.h> +#include <asm/smp.h> +#include <asm/sn/types.h> +#include <asm/sn/arch.h> +#include <asm/sn/gda.h> +#include <asm/mmzone.h> +#include <asm/sn/klkernvars.h> +#include <asm/sn/mapped_kernel.h> +#include <asm/sn/sn_private.h> + +extern char _end; +static cpumask_t ktext_repmask; + +/* + * XXX - This needs to be much smarter about where it puts copies of the + * kernel. For example, we should never put a copy on a headless node, + * and we should respect the topology of the machine. + */ +void __init setup_replication_mask(int maxnodes) +{ + static int numa_kernel_replication_ratio; + cnodeid_t cnode; + + /* Set only the master cnode's bit. The master cnode is always 0. */ + CPUMASK_CLRALL(ktext_repmask); + CPUMASK_SETB(ktext_repmask, 0); + + numa_kernel_replication_ratio = 0; +#ifdef CONFIG_REPLICATE_KTEXT +#ifndef CONFIG_MAPPED_KERNEL +#error Kernel replication works with mapped kernel support. No calias support. +#endif + numa_kernel_replication_ratio = 1; +#endif + + for (cnode = 1; cnode < numnodes; cnode++) { + /* See if this node should get a copy of the kernel */ + if (numa_kernel_replication_ratio && + !(cnode % numa_kernel_replication_ratio)) { + + /* Advertise that we have a copy of the kernel */ + CPUMASK_SETB(ktext_repmask, cnode); + } + } + + /* Set up a GDA pointer to the replication mask. */ + GDA->g_ktext_repmask = &ktext_repmask; +} + + +static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid) +{ + kern_vars_t *kvp; + cnodeid_t client_cnode; + + client_cnode = NASID_TO_COMPACT_NODEID(client_nasid); + + kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars); + + KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp; + + kvp->kv_magic = KV_MAGIC; + + kvp->kv_ro_nasid = server_nasid; + kvp->kv_rw_nasid = master_nasid; + kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid); + kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid); + printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid); +} + +/* XXX - When the BTE works, we should use it instead of this. */ +static __init void copy_kernel(nasid_t dest_nasid) +{ + extern char _stext, _etext; + unsigned long dest_kern_start, source_start, source_end, kern_size; + + source_start = (unsigned long)&_stext; + source_end = (unsigned long)&_etext; + kern_size = source_end - source_start; + + dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start), + dest_nasid); + memcpy((void *)dest_kern_start, (void *)source_start, kern_size); +} + +void __init replicate_kernel_text(int maxnodes) +{ + cnodeid_t cnode; + nasid_t client_nasid; + nasid_t server_nasid; + + server_nasid = master_nasid; + + /* Record where the master node should get its kernel text */ + set_ktext_source(master_nasid, master_nasid); + + for (cnode = 1; cnode < maxnodes; cnode++) { + client_nasid = COMPACT_TO_NASID_NODEID(cnode); + + /* Check if this node should get a copy of the kernel */ + if (CPUMASK_TSTB(ktext_repmask, cnode)) { + server_nasid = client_nasid; + copy_kernel(server_nasid); + } + + /* Record where this node should get its kernel text */ + set_ktext_source(client_nasid, server_nasid); + } +} + +/* + * Return pfn of first free page of memory on a node. PROM may allocate + * data structures on the first couple of pages of the first slot of each + * node. If this is the case, getfirstfree(node) > getslotstart(node, 0). + */ +pfn_t node_getfirstfree(cnodeid_t cnode) +{ + unsigned long loadbase = CKSEG0; + nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); + unsigned long offset; + +#ifdef CONFIG_MAPPED_KERNEL + loadbase = CKSSEG + 16777216; +#endif + offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; + if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode))) + return (TO_NODE(nasid, offset) >> PAGE_SHIFT); + else + return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> + PAGE_SHIFT); +} + diff -Nru a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-memory.c Fri Jun 27 14:19:54 2003 @@ -0,0 +1,337 @@ +/* + * 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) 2000 by Ralf Baechle + * Copyright (C) 2000 by Silicon Graphics, Inc. + * + * On SGI IP27 the ARC memory configuration data is completly bogus but + * alternate easier to use mechanisms are available. + */ +#include <linux/init.h> +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/swap.h> + +#include <asm/page.h> +#include <asm/bootinfo.h> +#include <asm/addrspace.h> +#include <asm/pgtable.h> +#include <asm/pgalloc.h> +#include <asm/sn/types.h> +#include <asm/sn/addrs.h> +#include <asm/sn/klconfig.h> +#include <asm/sn/arch.h> +#include <asm/mmzone.h> + +/* ip27-klnuma.c */ +extern pfn_t node_getfirstfree(cnodeid_t cnode); + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define SLOT_IGNORED 0xffff + +short slot_lastfilled_cache[MAX_COMPACT_NODES]; +unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS]; +static pfn_t numpages; + +plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES]; +bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES]; + +int numa_debug(void) +{ + printk("NUMA debug\n"); + *(int *)0 = 0; + return(0); +} + +/* + * Return the number of pages of memory provided by the given slot + * on the specified node. + */ +pfn_t slot_getsize(cnodeid_t node, int slot) +{ + return (pfn_t) slot_psize_cache[node][slot]; +} + +/* + * Return highest slot filled + */ +int node_getlastslot(cnodeid_t node) +{ + return (int) slot_lastfilled_cache[node]; +} + +/* + * Return the pfn of the last free page of memory on a node. + */ +pfn_t node_getmaxclick(cnodeid_t node) +{ + pfn_t slot_psize; + int slot; + + /* + * Start at the top slot. When we find a slot with memory in it, + * that's the winner. + */ + for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) { + if ((slot_psize = slot_getsize(node, slot))) { + if (slot_psize == SLOT_IGNORED) + continue; + /* Return the basepfn + the slot size, minus 1. */ + return slot_getbasepfn(node, slot) + slot_psize - 1; + } + } + + /* + * If there's no memory on the node, return 0. This is likely + * to cause problems. + */ + return (pfn_t)0; +} + +static pfn_t slot_psize_compute(cnodeid_t node, int slot) +{ + nasid_t nasid; + lboard_t *brd; + klmembnk_t *banks; + unsigned long size; + + nasid = COMPACT_TO_NASID_NODEID(node); + /* Find the node board */ + brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); + if (!brd) + return 0; + + /* Get the memory bank structure */ + banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK); + if (!banks) + return 0; + + /* Size in _Megabytes_ */ + size = (unsigned long)banks->membnk_bnksz[slot/4]; + + /* hack for 128 dimm banks */ + if (size <= 128) { + if (slot%4 == 0) { + size <<= 20; /* size in bytes */ + return(size >> PAGE_SHIFT); + } else { + return 0; + } + } else { + size /= 4; + size <<= 20; + return(size >> PAGE_SHIFT); + } +} + +pfn_t szmem(pfn_t fpage, pfn_t maxpmem) +{ + cnodeid_t node; + int slot, numslots; + pfn_t num_pages = 0, slot_psize; + pfn_t slot0sz = 0, nodebytes; /* Hack to detect problem configs */ + int ignore; + + for (node = 0; node < numnodes; node++) { + numslots = node_getnumslots(node); + ignore = nodebytes = 0; + for (slot = 0; slot < numslots; slot++) { + slot_psize = slot_psize_compute(node, slot); + if (slot == 0) slot0sz = slot_psize; + /* + * We need to refine the hack when we have replicated + * kernel text. + */ + nodebytes += SLOT_SIZE; + if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > + (slot0sz << PAGE_SHIFT)) + ignore = 1; + if (ignore && slot_psize) { + printk("Ignoring slot %d onwards on node %d\n", + slot, node); + slot_psize_cache[node][slot] = SLOT_IGNORED; + slot = numslots; + continue; + } + num_pages += slot_psize; + slot_psize_cache[node][slot] = + (unsigned short) slot_psize; + if (slot_psize) + slot_lastfilled_cache[node] = slot; + } + } + if (maxpmem) + return((maxpmem > num_pages) ? num_pages : maxpmem); + else + return num_pages; +} + +/* + * Currently, the intranode memory hole support assumes that each slot + * contains at least 32 MBytes of memory. We assume all bootmem data + * fits on the first slot. + */ +void __init prom_meminit(void) +{ + extern void mlreset(void); + cnodeid_t node; + pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn; + unsigned long bootmap_size; + int node_datasz; + + node_datasz = PFN_UP(sizeof(plat_pg_data_t)); + mlreset(); + numpages = szmem(0, 0); + for (node = (numnodes - 1); node >= 0; node--) { + slot_firstpfn = slot_getbasepfn(node, 0); + slot_lastpfn = slot_firstpfn + slot_getsize(node, 0); + slot_freepfn = node_getfirstfree(node); + /* Foll line hack for non discontigmem; remove once discontigmem + * becomes the default. */ + max_low_pfn = (slot_lastpfn - slot_firstpfn); + + /* + * Allocate the node data structure on the node first. + */ + plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \ + << PAGE_SHIFT)); + NODE_DATA(node)->bdata = plat_node_bdata + node; + slot_freepfn += node_datasz; + bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, + slot_firstpfn, slot_lastpfn); + free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, + (slot_lastpfn - slot_firstpfn) << PAGE_SHIFT); + reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, + ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size); + } + printk("Total memory probed : 0x%lx pages\n", numpages); +} + +int __init page_is_ram(unsigned long pagenr) +{ + return 1; +} + +void __init +prom_free_prom_memory (void) +{ + /* We got nothing to free here ... */ +} + +#ifdef CONFIG_DISCONTIGMEM + +static pfn_t pagenr; + +void __init paging_init(void) +{ + pmd_t *pmd = kpmdtbl; + pte_t *pte = kptbl; + + cnodeid_t node; + unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; + int i; + + /* Initialize the entire pgd. */ + pgd_init((unsigned long)swapper_pg_dir); + pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); + memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); + + /* This is for vmalloc */ + memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER); + memset((void *)kpmdtbl, 0, PAGE_SIZE); + set_pgd(swapper_pg_dir, __pgd(kpmdtbl)); + for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE) + pmd_val(*pmd) = (unsigned long)pte; + + for (node = 0; node < numnodes; node++) { + pfn_t start_pfn = slot_getbasepfn(node, 0); + pfn_t end_pfn = node_getmaxclick(node); + + zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn; + free_area_init_node(node, NODE_DATA(node), 0, zones_size, + start_pfn, 0); + } +} + +void __init mem_init(void) +{ + extern char _stext, _etext, _fdata, _edata; + extern char __init_begin, __init_end; + extern unsigned long setup_zero_pages(void); + cnodeid_t nid; + unsigned long tmp; + unsigned long codesize, datasize, initsize; + int slot, numslots; + struct page *pg, *pslot; + + num_physpages = numpages; /* memory already sized by szmem */ + max_mapnr = pagenr; /* already found during paging_init */ + high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); + + for (nid = 0; nid < numnodes; nid++) { + + /* + * Hack till free_area_init_core() zeroes free_pages + */ + for (tmp = 0; tmp < MAX_NR_ZONES; tmp++) + PLAT_NODE_DATA(nid)->gendata.node_zones[tmp].free_pages=0; + /* + * This will free up the bootmem, ie, slot 0 memory. + */ + totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); + + /* + * We need to manually do the other slots. + */ + pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0); + numslots = node_getlastslot(nid); + for (slot = 1; slot <= numslots; slot++) { + pslot = NODE_DATA(nid)->node_mem_map + + slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0); + + /* + * Mark holes in previous slot. May also want to + * free up the pages that hold the memmap entries. + */ + while (pg < pslot) { + pg++; + } + + /* + * Free valid memory in current slot. + */ + pslot += slot_getsize(nid, slot); + while (pg < pslot) { + /* if (!page_is_ram(pgnr)) continue; */ + /* commented out until page_is_ram works */ + ClearPageReserved(pg); + atomic_set(&pg->count, 1); + __free_page(pg); + totalram_pages++; + pg++; pgnr++; + } + } + } + + totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ + + codesize = (unsigned long) &_etext - (unsigned long) &_stext; + datasize = (unsigned long) &_edata - (unsigned long) &_fdata; + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + + tmp = (unsigned long) nr_free_pages(); + printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " + "%ldk data, %ldk init)\n", + tmp << (PAGE_SHIFT-10), + num_physpages << (PAGE_SHIFT-10), + codesize >> 10, + (num_physpages - tmp) << (PAGE_SHIFT-10), + datasize >> 10, + initsize >> 10); +} + +#endif /* CONFIG_DISCONTIGMEM */ diff -Nru a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-nmi.c Fri Jun 27 14:19:52 2003 @@ -0,0 +1,168 @@ +#include <linux/kernel.h> +#include <linux/mmzone.h> +#include <linux/spinlock.h> +#include <linux/smp.h> +#include <asm/atomic.h> +#include <asm/sn/types.h> +#include <asm/sn/addrs.h> +#include <asm/sn/nmi.h> +#include <asm/sn/arch.h> +#include <asm/sn/sn0/hub.h> + +#if 0 +#define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n) +#else +#define NODE_NUM_CPUS(n) CPUS_PER_NODE +#endif + +#define CNODEID_NONE (cnodeid_t)-1 +#define enter_panic_mode() spin_lock(&nmi_lock) + +typedef unsigned long machreg_t; + +spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED; + +/* + * Lets see what else we need to do here. Set up sp, gp? + */ +void nmi_dump(void) +{ + void cont_nmi_dump(void); + + cont_nmi_dump(); +} + +void install_cpu_nmi_handler(int slice) +{ + nmi_t *nmi_addr; + + nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice); + if (nmi_addr->call_addr) + return; + nmi_addr->magic = NMI_MAGIC; + nmi_addr->call_addr = (void *)nmi_dump; + nmi_addr->call_addr_c = + (void *)(~((unsigned long)(nmi_addr->call_addr))); + nmi_addr->call_parm = 0; +} + +/* + * Copy the cpu registers which have been saved in the IP27prom format + * into the eframe format for the node under consideration. + */ + +void +nmi_cpu_eframe_save(nasid_t nasid, + int slice) +{ + int i, numberof_nmi_cpu_regs; + machreg_t *prom_format; + + /* Get the total number of registers being saved by the prom */ + numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t); + + /* Get the pointer to the current cpu's register set. */ + prom_format = + (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + + slice * IP27_NMI_KREGS_CPU_SIZE); + + printk("NMI nasid %d: slice %d\n", nasid, slice); + for (i = 0; i < numberof_nmi_cpu_regs; i++) + printk("0x%lx ", prom_format[i]); + printk("\n\n"); +} + +/* + * Copy the cpu registers which have been saved in the IP27prom format + * into the eframe format for the node under consideration. + */ +void +nmi_node_eframe_save(cnodeid_t cnode) +{ + int cpu; + nasid_t nasid; + + /* Make sure that we have a valid node */ + if (cnode == CNODEID_NONE) + return; + + nasid = COMPACT_TO_NASID_NODEID(cnode); + if (nasid == INVALID_NASID) + return; + + /* Save the registers into eframe for each cpu */ + for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++) + nmi_cpu_eframe_save(nasid, cpu); +} + +/* + * Save the nmi cpu registers for all cpus in the system. + */ +void +nmi_eframes_save(void) +{ + cnodeid_t cnode; + + for(cnode = 0 ; cnode < numnodes; cnode++) + nmi_node_eframe_save(cnode); +} + +void +cont_nmi_dump(void) +{ +#ifndef REAL_NMI_SIGNAL + static atomic_t nmied_cpus = ATOMIC_INIT(0); + + atomic_inc(&nmied_cpus); +#endif + /* + * Use enter_panic_mode to allow only 1 cpu to proceed + */ + enter_panic_mode(); + +#ifdef REAL_NMI_SIGNAL + /* + * Wait up to 15 seconds for the other cpus to respond to the NMI. + * If a cpu has not responded after 10 sec, send it 1 additional NMI. + * This is for 2 reasons: + * - sometimes a MMSC fail to NMI all cpus. + * - on 512p SN0 system, the MMSC will only send NMIs to + * half the cpus. Unfortunately, we don't know which cpus may be + * NMIed - it depends on how the site chooses to configure. + * + * Note: it has been measure that it takes the MMSC up to 2.3 secs to + * send NMIs to all cpus on a 256p system. + */ + for (i=0; i < 1500; i++) { + for (node=0; node < numnodes; node++) + if (NODEPDA(node)->dump_count == 0) + break; + if (node == numnodes) + break; + if (i == 1000) { + for (node=0; node < numnodes; node++) + if (NODEPDA(node)->dump_count == 0) { + cpu = CNODE_TO_CPU_BASE(node); + for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) { + CPUMASK_SETB(nmied_cpus, cpu); + /* + * cputonasid, cputoslice + * needs kernel cpuid + */ + SEND_NMI((cputonasid(cpu)), (cputoslice(cpu))); + } + } + + } + udelay(10000); + } +#else + while (atomic_read(&nmied_cpus) != num_online_cpus()); +#endif + + /* + * Save the nmi cpu registers for all cpu in the eframe format. + */ + nmi_eframes_save(); + LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); +} diff -Nru a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-reset.c Fri Jun 27 14:19:57 2003 @@ -0,0 +1,80 @@ +/* + * 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. + * + * Reset an IP27. + * + * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/timer.h> +#include <linux/smp.h> +#include <linux/mmzone.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/system.h> +#include <asm/sgialib.h> +#include <asm/sn/addrs.h> +#include <asm/sn/arch.h> +#include <asm/sn/gda.h> +#include <asm/sn/sn0/hub.h> + +void machine_restart(char *command) __attribute__((noreturn)); +void machine_halt(void) __attribute__((noreturn)); +void machine_power_off(void) __attribute__((noreturn)); + +#define noreturn while(1); /* Silence gcc. */ + +/* XXX How to pass the reboot command to the firmware??? */ +static void ip27_machine_restart(char *command) +{ +#if 0 + int i; +#endif + + printk("Reboot started from CPU %d\n", smp_processor_id()); +#ifdef CONFIG_SMP + smp_send_stop(); +#endif +#if 0 + for (i = 0; i < numnodes; i++) + REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, + PROMOP_REBOOT); +#else + LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); +#endif + noreturn; +} + +static void ip27_machine_halt(void) +{ + int i; + +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + for (i = 0; i < numnodes; i++) + REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, + PROMOP_RESTART); + LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); + noreturn; +} + +static void ip27_machine_power_off(void) +{ + /* To do ... */ + noreturn; +} + +void ip27_reboot_setup(void) +{ + _machine_restart = ip27_machine_restart; + _machine_halt = ip27_machine_halt; + _machine_power_off = ip27_machine_power_off; +} diff -Nru a/arch/mips/sgi-ip27/ip27-setup.c b/arch/mips/sgi-ip27/ip27-setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-setup.c Fri Jun 27 14:19:55 2003 @@ -0,0 +1,319 @@ +/* + * 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. + * + * SGI IP27 specific setup. + * + * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silcon Graphics, Inc. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/sched.h> +#include <linux/smp.h> + +#include <asm/io.h> +#include <asm/sn/types.h> +#include <asm/sn/sn0/addrs.h> +#include <asm/sn/sn0/hubni.h> +#include <asm/sn/sn0/hubio.h> +#include <asm/sn/klconfig.h> +#include <asm/sn/ioc3.h> +#include <asm/time.h> +#include <asm/mipsregs.h> +#include <asm/sn/arch.h> +#include <asm/sn/sn_private.h> +#include <asm/pci/bridge.h> +#include <asm/paccess.h> +#include <asm/sn/sn0/ip27.h> +#include <asm/traps.h> + +/* Check against user dumbness. */ +#ifdef CONFIG_VT +#error CONFIG_VT not allowed for IP27. +#endif + +#undef DEBUG_SETUP +#ifdef DEBUG_SETUP +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +extern void ip27_be_init(void) __init; + +/* + * get_nasid() returns the physical node id number of the caller. + */ +nasid_t +get_nasid(void) +{ + return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK) + >> NSRI_NODEID_SHFT); +} + +/* Extracted from the IOC3 meta driver. FIXME. */ +static inline void ioc3_sio_init(void) +{ + struct ioc3 *ioc3; + nasid_t nid; + long loops; + + nid = get_nasid(); + ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; + + ioc3->sscr_a = 0; /* PIO mode for uarta. */ + ioc3->sscr_b = 0; /* PIO mode for uartb. */ + ioc3->sio_iec = ~0; + ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT); + + loops=1000000; while(loops--); + ioc3->sregs.uarta.iu_fcr = 0; + ioc3->sregs.uartb.iu_fcr = 0; + loops=1000000; while(loops--); +} + +static inline void ioc3_eth_init(void) +{ + struct ioc3 *ioc3; + nasid_t nid; + + nid = get_nasid(); + ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; + + ioc3->eier = 0; +} + +/* Try to catch kernel missconfigurations and give user an indication what + option to select. */ +static void __init verify_mode(void) +{ + int n_mode; + + n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK; + printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M'); +#ifdef CONFIG_SGI_SN0_N_MODE + if (!n_mode) + panic("Kernel compiled for M mode."); +#else + if (n_mode) + panic("Kernel compiled for N mode."); +#endif +} + +#define XBOW_WIDGET_PART_NUM 0x0 +#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ +#define BASE_XBOW_PORT 8 /* Lowest external port */ + +unsigned int bus_to_cpu[256]; +unsigned long bus_to_baddr[256]; + +void __init pcibr_setup(cnodeid_t nid) +{ + int i, start, num; + unsigned long masterwid; + bridge_t *bridge; + volatile u64 hubreg; + nasid_t nasid, masternasid; + xwidget_part_num_t partnum; + widgetreg_t widget_id; + static spinlock_t pcibr_setup_lock = SPIN_LOCK_UNLOCKED; + + /* + * If the master is doing this for headless node, nothing to do. + * This is because currently we require at least one of the hubs + * (master hub) connected to the xbow to have at least one enabled + * cpu to receive intrs. Else we need an array bus_to_intrnasid[] + * that bridge_startup() needs to use to target intrs. All dma is + * routed thru the widget of the master hub. The master hub wid + * is selectable by WIDGET_A below. + */ + if (nid != get_compact_nodeid()) + return; + /* + * find what's on our local node + */ + spin_lock(&pcibr_setup_lock); + start = num_bridges; /* Remember where we start from */ + nasid = COMPACT_TO_NASID_NODEID(nid); + hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); + if (hubreg & IIO_LLP_CSR_IS_UP) { + /* link is up */ + widget_id = *(volatile widgetreg_t *) + (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); + partnum = XWIDGET_PART_NUM(widget_id); + printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x", + smp_processor_id(), nasid, partnum); + if (partnum == BRIDGE_WIDGET_PART_NUM) { + /* + * found direct connected bridge so must be Origin200 + */ + printk("...is bridge\n"); + num_bridges = 1; + bus_to_wid[0] = 0x8; + bus_to_nid[0] = 0; + masterwid = 0xa; + bus_to_baddr[0] = 0xa100000000000000UL; + } else if (partnum == XBOW_WIDGET_PART_NUM) { + lboard_t *brd; + klxbow_t *xbow_p; + /* + * found xbow, so may have multiple bridges + * need to probe xbow + */ + printk("...is xbow\n"); + + if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), + KLTYPE_MIDPLANE8)) == NULL) + printk("argh\n"); + else + printk("brd = 0x%lx\n", (unsigned long) brd); + if ((xbow_p = (klxbow_t *) + find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL) + printk("argh\n"); + else { + /* + * Okay, here's a xbow. Lets arbitrate and find + * out if we should initialize it. Set enabled + * hub connected at highest or lowest widget as + * master. + */ +#ifdef WIDGET_A + i = HUB_WIDGET_ID_MAX + 1; + do { + i--; + } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) || + (!XBOW_PORT_IS_ENABLED(xbow_p, i))); +#else + i = HUB_WIDGET_ID_MIN - 1; + do { + i++; + } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) || + (!XBOW_PORT_IS_ENABLED(xbow_p, i))); +#endif + masterwid = i; + masternasid = XBOW_PORT_NASID(xbow_p, i); + if (nasid == masternasid) + for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) { + if (!XBOW_PORT_IS_ENABLED(xbow_p, i)) + continue; + if (XBOW_PORT_TYPE_IO(xbow_p, i)) { + widget_id = *(volatile widgetreg_t *) + (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID); + partnum = XWIDGET_PART_NUM(widget_id); + if (partnum == BRIDGE_WIDGET_PART_NUM) { + printk("widget 0x%x is a bridge\n", i); + bus_to_wid[num_bridges] = i; + bus_to_nid[num_bridges] = nasid; + bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56)); /* Barrier set */ + num_bridges++; + } + } + } + } + } else if (partnum == XXBOW_WIDGET_PART_NUM) { + /* + * found xbridge, assume ibrick for now + */ + printk("...is xbridge\n"); + bus_to_wid[0] = 0xb; + bus_to_wid[1] = 0xe; + bus_to_wid[2] = 0xf; + + bus_to_nid[0] = 0; + bus_to_nid[1] = 0; + bus_to_nid[2] = 0; + + bus_to_baddr[0] = 0xa100000000000000UL; + bus_to_baddr[1] = 0xa100000000000000UL; + bus_to_baddr[2] = 0xa100000000000000UL; + masterwid = 0xa; + num_bridges = 3; + } + } + num = num_bridges - start; + spin_unlock(&pcibr_setup_lock); + /* + * set bridge registers + */ + for (i = start; i < (start + num); i++) { + + DBG("pcibr_setup: bus= %d bus_to_wid[%2d]= %d bus_to_nid[%2d]= %d\n", + i, i, bus_to_wid[i], i, bus_to_nid[i]); + + bus_to_cpu[i] = smp_processor_id(); + /* + * point to this bridge + */ + bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]); + /* + * Clear all pending interrupts. + */ + bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR); + /* + * Until otherwise set up, assume all interrupts are from slot 0 + */ + bridge->b_int_device = (u32) 0x0; + /* + * swap pio's to pci mem and io space (big windows) + */ + bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP; + bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP; + + /* + * Hmm... IRIX sets additional bits in the address which + * are documented as reserved in the bridge docs. + */ + bridge->b_int_mode = 0x0; /* Don't clear ints */ + bridge->b_wid_int_upper = 0x8000 | (masterwid << 16); + bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/ + bridge->b_dir_map = (masterwid << 20); /* DMA */ + bridge->b_int_enable = 0; + + bridge->b_wid_tflush; /* wait until Bridge PIO complete */ + } +} + +extern void ip27_setup_console(void); +extern void ip27_time_init(void); +extern void ip27_reboot_setup(void); + +void __init ip27_setup(void) +{ + nasid_t nid; + hubreg_t p, e; + + ip27_setup_console(); + ip27_reboot_setup(); + + num_bridges = 0; + /* + * hub_rtc init and cpu clock intr enabled for later calibrate_delay. + */ + DBG("ip27_setup(): Entered.\n"); + nid = get_nasid(); + printk("IP27: Running on node %d.\n", nid); + + p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1; + e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1; + printk("Node %d has %s primary CPU%s.\n", nid, + p ? "a" : "no", + e ? ", CPU is running" : ""); + + p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1; + e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1; + printk("Node %d has %s secondary CPU%s.\n", nid, + p ? "a" : "no", + e ? ", CPU is running" : ""); + + verify_mode(); + ioc3_sio_init(); + ioc3_eth_init(); + per_cpu_init(); + + mips_io_port_base = IO_BASE; + board_time_init = ip27_time_init; +} diff -Nru a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip27/ip27-timer.c Fri Jun 27 14:19:55 2003 @@ -0,0 +1,238 @@ +/* + * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) + * Copytight (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <linux/bcd.h> +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/param.h> +#include <linux/time.h> +#include <linux/timex.h> +#include <linux/mm.h> +#include <linux/bcd.h> + +#include <asm/time.h> +#include <asm/pgtable.h> +#include <asm/sgialib.h> +#include <asm/sn/ioc3.h> +#include <asm/m48t35.h> +#include <asm/sn/klconfig.h> +#include <asm/sn/arch.h> +#include <asm/sn/addrs.h> +#include <asm/sn/sn_private.h> +#include <asm/sn/sn0/ip27.h> +#include <asm/sn/sn0/hub.h> + +/* + * This is a hack; we really need to figure these values out dynamically + * + * Since 800 ns works very well with various HUB frequencies, such as + * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. + * + * Ralf: which clock rate is used to feed the counter? + */ +#define NSEC_PER_CYCLE 800 +#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE) +#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ) + +#define TICK_SIZE (tick_nsec / 1000) + +static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ +static long last_rtc_update; /* Last time the rtc clock got updated */ + +extern volatile unsigned long wall_jiffies; + + +static int set_rtc_mmss(unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + struct m48t35_rtc *rtc; + nasid_t nid; + + nid = get_nasid(); + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + + IOC3_BYTEBUS_DEV0); + + rtc->control |= M48T35_RTC_READ; + cmos_minutes = BCD2BIN(rtc->min); + rtc->control &= ~M48T35_RTC_READ; + + /* + * Since we're only adjusting minutes and seconds, don't interfere with + * hour overflow. This avoids messing with unknown time zones but + * requires your RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + real_seconds = BIN2BCD(real_seconds); + real_minutes = BIN2BCD(real_minutes); + rtc->control |= M48T35_RTC_SET; + rtc->sec = real_seconds; + rtc->min = real_minutes; + rtc->control &= ~M48T35_RTC_SET; + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + return retval; +} + +void rt_timer_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int cpuA = ((cputoslice(cpu)) == 0); + int irq = 9; /* XXX Assign number */ + + irq_enter(); + write_seqlock(&xtime_lock); + +again: + LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ + ct_cur[cpu] += CYCLES_PER_JIFFY; + LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]); + + if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu]) + goto again; + + kstat_cpu(cpu).irqs[irq]++; /* kstat only for bootcpu? */ + + if (cpu == 0) + do_timer(regs); + +#ifdef CONFIG_SMP + update_process_times(user_mode(regs)); +#endif /* CONFIG_SMP */ + + /* + * If we have an externally synchronized Linux clock, then update + * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to when a second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && + (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { + if (rtc_set_time(xtime.tv_sec) == 0) { + last_rtc_update = xtime.tv_sec; + } else { + last_rtc_update = xtime.tv_sec - 600; + /* do it again in 60 s */ + } + } + + write_sequnlock(&xtime_lock); + irq_exit(); + + if (softirq_pending(cpu)) + do_softirq(); +} + +unsigned long ip27_do_gettimeoffset(void) +{ + unsigned long ct_cur1; + ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; + return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; +} + +/* Includes for ioc3_init(). */ +#include <asm/sn/types.h> +#include <asm/sn/sn0/addrs.h> +#include <asm/sn/sn0/hubni.h> +#include <asm/sn/sn0/hubio.h> +#include <asm/pci/bridge.h> + +static __init unsigned long get_m48t35_time(void) +{ + unsigned int year, month, date, hour, min, sec; + struct m48t35_rtc *rtc; + nasid_t nid; + + nid = get_nasid(); + rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + + IOC3_BYTEBUS_DEV0); + + rtc->control |= M48T35_RTC_READ; + sec = rtc->sec; + min = rtc->min; + hour = rtc->hour; + date = rtc->date; + month = rtc->month; + year = rtc->year; + rtc->control &= ~M48T35_RTC_READ; + + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + date = BCD2BIN(date); + month = BCD2BIN(month); + year = BCD2BIN(year); + + year += 1970; + + return mktime(year, month, date, hour, min, sec); +} + +void __init ip27_time_init(void) +{ + xtime.tv_sec = get_m48t35_time(); + xtime.tv_nsec = 0; + + do_gettimeoffset = ip27_do_gettimeoffset; +} + +void __init cpu_time_init(void) +{ + lboard_t *board; + klcpu_t *cpu; + int cpuid; + + /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */ + board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27); + if (!board) + panic("Can't find board info for myself."); + + cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX; + cpu = (klcpu_t *) KLCF_COMP(board, cpuid); + if (!cpu) + panic("No information about myself?"); + + printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); + + set_c0_status(SRB_TIMOCLK); +} + +void __init hub_rtc_init(cnodeid_t cnode) +{ + /* + * We only need to initialize the current node. + * If this is not the current node then it is a cpuless + * node and timeouts will not happen there. + */ + if (get_compact_nodeid() == cnode) { + int cpu = smp_processor_id(); + LOCAL_HUB_S(PI_RT_EN_A, 1); + LOCAL_HUB_S(PI_RT_EN_B, 1); + LOCAL_HUB_S(PI_PROF_EN_A, 0); + LOCAL_HUB_S(PI_PROF_EN_B, 0); + ct_cur[cpu] = CYCLES_PER_JIFFY; + LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]); + LOCAL_HUB_S(PI_RT_COUNT, 0); + LOCAL_HUB_S(PI_RT_PEND_A, 0); + LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]); + LOCAL_HUB_S(PI_RT_COUNT, 0); + LOCAL_HUB_S(PI_RT_PEND_B, 0); + } +} diff -Nru a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/Makefile Fri Jun 27 14:19:57 2003 @@ -0,0 +1,9 @@ +# +# Makefile for the SGI specific kernel interface routines +# under Linux. +# + +obj-y += ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \ + ip32-timer.o crime.o ip32-reset.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/sgi-ip32/crime.c b/arch/mips/sgi-ip32/crime.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/crime.c Fri Jun 27 14:19:54 2003 @@ -0,0 +1,49 @@ +/* + * 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) 2001 Keith M Wesolowski + */ +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <asm/ip32/crime.h> +#include <asm/ptrace.h> + +void __init crime_init (void) +{ + u64 id = crime_read_64 (CRIME_ID); + u64 rev = id & CRIME_ID_REV; + + id = (id & CRIME_ID_IDBITS) >> 4; + + printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev, + (unsigned long) CRIME_BASE); +} + +/* XXX Like on Sun, these give us various useful information to printk. */ +void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) +{ + u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT); + u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR); + memerr &= CRIME_MEM_ERROR_STAT_MASK; + + printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n", + addr << 2, memerr); + + crime_write_64 (CRIME_MEM_ERROR_STAT, 0); +} + +void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) +{ + u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT); + u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR); + cpuerr &= CRIME_CPU_ERROR_MASK; + addr <<= 2UL; + + printk ("CRIME CPU interface error detected at %09lx status %08lx\n", + addr, cpuerr); + + crime_write_64 (CRIME_CPU_ERROR_STAT, 0); +} diff -Nru a/arch/mips/sgi-ip32/ip32-berr.c b/arch/mips/sgi-ip32/ip32-berr.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-berr.c Fri Jun 27 14:19:59 2003 @@ -0,0 +1,35 @@ +/* + * 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, 1995, 1996, 1999, 2000 by Ralf Baechle + * Copyright (C) 1999, 2000 by Silicon Graphics + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <asm/traps.h> +#include <asm/uaccess.h> +#include <asm/addrspace.h> +#include <asm/ptrace.h> +#include <asm/tlbdebug.h> + +int ip32_be_handler(struct pt_regs *regs, int is_fixup) +{ + int data = regs->cp0_cause & 4; + + if (is_fixup) + return MIPS_BE_FIXUP; + + printk("Got %cbe at 0x%lx\n", data ? 'd' : 'i', regs->cp0_epc); + show_regs(regs); + dump_tlb_all(); + while(1); + force_sig(SIGBUS, current); +} + +void __init ip32_be_init(void) +{ + board_be_handler = ip32_be_handler; +} diff -Nru a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-irq-glue.S Fri Jun 27 14:19:55 2003 @@ -0,0 +1,87 @@ +/* + * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead + * + * 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) 2000 Harald Koerfgen + * Copyright (C) 2001 Keith M Wesolowski + */ +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> +#include <asm/addrspace.h> +#include <asm/ip32/ip32_ints.h> + + .text + .set noreorder + .set noat + .align 5 + NESTED(ip32_handle_int, PT_SIZE, ra) + .set noat + SAVE_ALL + CLI # TEST: interrupts should be off + .set at + .set noreorder + + mfc0 s0,CP0_CAUSE + + andi t1, s0, IE_IRQ0 + bnez t1, handle_irq0 + andi t1, s0, IE_IRQ1 + bnez t1, handle_irq1 + andi t1, s0, IE_IRQ2 + bnez t1, handle_irq2 + andi t1, s0, IE_IRQ3 + bnez t1, handle_irq3 + andi t1, s0, IE_IRQ4 + bnez t1, handle_irq4 + andi t1, s0, IE_IRQ5 + bnez t1, handle_irq5 + nop + + /* Either someone has triggered the "software interrupts" + * or we lost an interrupt somehow. Ignore it. + */ + j ret_from_irq + nop + +handle_irq0: + jal ip32_irq0 + move a0, sp + j ret_from_irq + nop + +handle_irq1: + jal ip32_irq1 + move a0, sp + j ret_from_irq + nop + +handle_irq2: + jal ip32_irq2 + move a0, sp + j ret_from_irq + nop + +handle_irq3: + jal ip32_irq3 + move a0, sp + j ret_from_irq + nop + +handle_irq4: + jal ip32_irq4 + move a0, sp + j ret_from_irq + nop + +handle_irq5: + jal ip32_irq5 + move a0, sp + j ret_from_irq + nop + + END(ip32_handle_int) diff -Nru a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-irq.c Fri Jun 27 14:19:56 2003 @@ -0,0 +1,584 @@ +/* + * Code to handle IP32 IRQs + * + * 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) 2000 Harald Koerfgen + * Copyright (C) 2001 Keith M Wesolowski + */ +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/bitops.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/random.h> +#include <linux/sched.h> + +#include <asm/bitops.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/ip32/ip32_ints.h> +#include <asm/ip32/crime.h> +#include <asm/ip32/mace.h> +#include <asm/signal.h> + +#undef DEBUG_IRQ +#ifdef DEBUG_IRQ +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +/* O2 irq map + * + * IP0 -> software (ignored) + * IP1 -> software (ignored) + * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ??? + * IP3 -> (irq1) X unknown + * IP4 -> (irq2) X unknown + * IP5 -> (irq3) X unknown + * IP6 -> (irq4) X unknown + * IP7 -> (irq5) 0 CPU count/compare timer (system timer) + * + * crime: (C) + * + * CRIME_INT_STAT 31:0: + * + * 0 -> 1 Video in 1 + * 1 -> 2 Video in 2 + * 2 -> 3 Video out + * 3 -> 4 Mace ethernet + * 4 -> S SuperIO sub-interrupt + * 5 -> M Miscellaneous sub-interrupt + * 6 -> A Audio sub-interrupt + * 7 -> 8 PCI bridge errors + * 8 -> 9 PCI SCSI aic7xxx 0 + * 9 -> 10 PCI SCSI aic7xxx 1 + * 10 -> 11 PCI slot 0 + * 11 -> 12 unused (PCI slot 1) + * 12 -> 13 unused (PCI slot 2) + * 13 -> 14 unused (PCI shared 0) + * 14 -> 15 unused (PCI shared 1) + * 15 -> 16 unused (PCI shared 2) + * 16 -> 17 GBE0 (E) + * 17 -> 18 GBE1 (E) + * 18 -> 19 GBE2 (E) + * 19 -> 20 GBE3 (E) + * 20 -> 21 CPU errors + * 21 -> 22 Memory errors + * 22 -> 23 RE empty edge (E) + * 23 -> 24 RE full edge (E) + * 24 -> 25 RE idle edge (E) + * 25 -> 26 RE empty level + * 26 -> 27 RE full level + * 27 -> 28 RE idle level + * 28 -> 29 unused (software 0) (E) + * 29 -> 30 unused (software 1) (E) + * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E) + * 31 -> 32 VICE + * + * S, M, A: Use the MACE ISA interrupt register + * MACE_ISA_INT_STAT 31:0 + * + * 0-7 -> 33-40 Audio + * 8 -> 41 RTC + * 9 -> 42 Keyboard + * 10 -> X Keyboard polled + * 11 -> 44 Mouse + * 12 -> X Mouse polled + * 13-15 -> 46-48 Count/compare timers + * 16-19 -> 49-52 Parallel (16 E) + * 20-25 -> 53-58 Serial 1 (22 E) + * 26-31 -> 59-64 Serial 2 (28 E) + * + * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a + * different IRQ map than IRIX uses, but that's OK as Linux irq handling + * is quite different anyway. + */ + +/* Some initial interrupts to set up */ +extern void crime_memerr_intr (unsigned int irq, void *dev_id, + struct pt_regs *regs); +extern void crime_cpuerr_intr (unsigned int irq, void *dev_id, + struct pt_regs *regs); + +struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, + 0, "CRIME memory error", NULL, + NULL }; +struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, + 0, "CRIME CPU error", NULL, + NULL }; + +extern void ip32_handle_int (void); + +/* + * For interrupts wired from a single device to the CPU. Only the clock + * uses this it seems, which is IRQ 0 and IP7. + */ + +static void enable_cpu_irq(unsigned int irq) +{ + set_c0_status(STATUSF_IP7); +} + +static unsigned int startup_cpu_irq(unsigned int irq) +{ + enable_cpu_irq(irq); + return 0; +} + +static void disable_cpu_irq(unsigned int irq) +{ + clear_c0_status(STATUSF_IP7); +} + +static void end_cpu_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_cpu_irq (irq); +} + +#define shutdown_cpu_irq disable_cpu_irq +#define mask_and_ack_cpu_irq disable_cpu_irq + +static struct hw_interrupt_type ip32_cpu_interrupt = { + "IP32 CPU", + startup_cpu_irq, + shutdown_cpu_irq, + enable_cpu_irq, + disable_cpu_irq, + mask_and_ack_cpu_irq, + end_cpu_irq, + NULL +}; + +/* + * This is for pure CRIME interrupts - ie not MACE. The advantage? + * We get to split the register in half and do faster lookups. + */ + +static void enable_crime_irq(unsigned int irq) +{ + u64 crime_mask; + unsigned long flags; + + local_irq_save(flags); + crime_mask = crime_read_64(CRIME_INT_MASK); + crime_mask |= 1 << (irq - 1); + crime_write_64(CRIME_INT_MASK, crime_mask); + local_irq_restore(flags); +} + +static unsigned int startup_crime_irq(unsigned int irq) +{ + enable_crime_irq(irq); + return 0; /* This is probably not right; we could have pending irqs */ +} + +static void disable_crime_irq(unsigned int irq) +{ + u64 crime_mask; + unsigned long flags; + + local_irq_save(flags); + crime_mask = crime_read_64(CRIME_INT_MASK); + crime_mask &= ~(1 << (irq - 1)); + crime_write_64(CRIME_INT_MASK, crime_mask); + local_irq_restore(flags); +} + +static void mask_and_ack_crime_irq (unsigned int irq) +{ + u64 crime_mask; + unsigned long flags; + + /* Edge triggered interrupts must be cleared. */ + if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) + || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) + || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { + local_irq_save(flags); + crime_mask = crime_read_64(CRIME_HARD_INT); + crime_mask &= ~(1 << (irq - 1)); + crime_write_64(CRIME_HARD_INT, crime_mask); + local_irq_restore(flags); + } + disable_crime_irq(irq); +} + +static void end_crime_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_crime_irq (irq); +} + +#define shutdown_crime_irq disable_crime_irq + +static struct hw_interrupt_type ip32_crime_interrupt = { + "IP32 CRIME", + startup_crime_irq, + shutdown_crime_irq, + enable_crime_irq, + disable_crime_irq, + mask_and_ack_crime_irq, + end_crime_irq, + NULL +}; + +/* + * This is for MACE PCI interrupts. We can decrease bus traffic by masking + * as close to the source as possible. This also means we can take the + * next chunk of the CRIME register in one piece. + */ + +static void enable_macepci_irq(unsigned int irq) +{ + u32 mace_mask; + u64 crime_mask; + unsigned long flags; + + local_irq_save(flags); + mace_mask = mace_read_32(MACEPCI_CONTROL); + mace_mask |= MACEPCI_CONTROL_INT(irq - 9); + mace_write_32(MACEPCI_CONTROL, mace_mask); + /* + * In case the CRIME interrupt isn't enabled, we must enable it; + * however, we never disable interrupts at that level. + */ + crime_mask = crime_read_64(CRIME_INT_MASK); + crime_mask |= 1 << (irq - 1); + crime_write_64(CRIME_INT_MASK, crime_mask); + local_irq_restore(flags); +} + +static unsigned int startup_macepci_irq(unsigned int irq) +{ + enable_macepci_irq (irq); + + return 0; /* XXX */ +} + +static void disable_macepci_irq(unsigned int irq) +{ + u32 mace_mask; + unsigned long flags; + + local_irq_save(flags); + mace_mask = mace_read_32(MACEPCI_CONTROL); + mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9); + mace_write_32(MACEPCI_CONTROL, mace_mask); + local_irq_restore(flags); +} + +static void end_macepci_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_macepci_irq (irq); +} + +#define shutdown_macepci_irq disable_macepci_irq +#define mask_and_ack_macepci_irq disable_macepci_irq + +static struct hw_interrupt_type ip32_macepci_interrupt = { + "IP32 MACE PCI", + startup_macepci_irq, + shutdown_macepci_irq, + enable_macepci_irq, + disable_macepci_irq, + mask_and_ack_macepci_irq, + end_macepci_irq, + NULL +}; + +/* This is used for MACE ISA interrupts. That means bits 4-6 in the + * CRIME register. + */ + +static void enable_maceisa_irq (unsigned int irq) +{ + u64 crime_mask; + u32 mace_mask; + unsigned int crime_int = 0; + unsigned long flags; + + DBG ("maceisa enable: %u\n", irq); + + switch (irq) { + case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: + crime_int = MACE_AUDIO_INT; + break; + case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ: + crime_int = MACE_MISC_INT; + break; + case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ: + crime_int = MACE_SUPERIO_INT; + break; + } + DBG ("crime_int %016lx enabled\n", crime_int); + local_irq_save(flags); + crime_mask = crime_read_64(CRIME_INT_MASK); + crime_mask |= crime_int; + crime_write_64(CRIME_INT_MASK, crime_mask); + mace_mask = mace_read_32(MACEISA_INT_MASK); + mace_mask |= 1 << (irq - 33); + mace_write_32(MACEISA_INT_MASK, mace_mask); + local_irq_restore(flags); +} + +static unsigned int startup_maceisa_irq (unsigned int irq) +{ + enable_maceisa_irq(irq); + return 0; +} + +static void disable_maceisa_irq(unsigned int irq) +{ + u32 mace_mask; + unsigned long flags; + + local_irq_save(flags); + mace_mask = mace_read_32(MACEISA_INT_MASK); + mace_mask &= ~(1 << (irq - 33)); + mace_write_32(MACEISA_INT_MASK, mace_mask); + local_irq_restore(flags); +} + +static void mask_and_ack_maceisa_irq(unsigned int irq) +{ + u32 mace_mask; + unsigned long flags; + + switch (irq) { + case MACEISA_PARALLEL_IRQ: + case MACEISA_SERIAL1_TDMAPR_IRQ: + case MACEISA_SERIAL2_TDMAPR_IRQ: + local_irq_save(flags); + mace_mask = mace_read_32(MACEISA_INT_STAT); + mace_mask &= ~(1 << (irq - 33)); + mace_write_32(MACEISA_INT_STAT, mace_mask); + local_irq_restore(flags); + break; + } + disable_maceisa_irq(irq); +} + +static void end_maceisa_irq(unsigned irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_maceisa_irq (irq); +} + +#define shutdown_maceisa_irq disable_maceisa_irq + +static struct hw_interrupt_type ip32_maceisa_interrupt = { + "IP32 MACE ISA", + startup_maceisa_irq, + shutdown_maceisa_irq, + enable_maceisa_irq, + disable_maceisa_irq, + mask_and_ack_maceisa_irq, + end_maceisa_irq, + NULL +}; + +/* This is used for regular non-ISA, non-PCI MACE interrupts. That means + * bits 0-3 and 7 in the CRIME register. + */ + +static void enable_mace_irq(unsigned int irq) +{ + u64 crime_mask; + unsigned long flags; + + local_irq_save(flags); + crime_mask = crime_read_64 (CRIME_INT_MASK); + crime_mask |= 1 << (irq - 1); + crime_write_64 (CRIME_INT_MASK, crime_mask); + local_irq_restore (flags); +} + +static unsigned int startup_mace_irq(unsigned int irq) +{ + enable_mace_irq(irq); + return 0; +} + +static void disable_mace_irq(unsigned int irq) +{ + u64 crime_mask; + unsigned long flags; + + local_irq_save(flags); + crime_mask = crime_read_64 (CRIME_INT_MASK); + crime_mask &= ~(1 << (irq - 1)); + crime_write_64 (CRIME_INT_MASK, crime_mask); + local_irq_restore(flags); +} + +static void end_mace_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_mace_irq (irq); +} + +#define shutdown_mace_irq disable_mace_irq +#define mask_and_ack_mace_irq disable_mace_irq + +static struct hw_interrupt_type ip32_mace_interrupt = { + "IP32 MACE", + startup_mace_irq, + shutdown_mace_irq, + enable_mace_irq, + disable_mace_irq, + mask_and_ack_mace_irq, + end_mace_irq, + NULL +}; + +static void ip32_unknown_interrupt (struct pt_regs *regs) +{ + u64 crime; + u32 mace; + + printk ("Unknown interrupt occurred!\n"); + printk ("cp0_status: %08x\tcp0_cause: %08x\n", + read_c0_status(), + read_c0_cause()); + crime = crime_read_64 (CRIME_INT_MASK); + printk ("CRIME interrupt mask: %016lx\n", crime); + crime = crime_read_64 (CRIME_INT_STAT); + printk ("CRIME interrupt status: %016lx\n", crime); + crime = crime_read_64 (CRIME_HARD_INT); + printk ("CRIME hardware interrupt register: %016lx\n", crime); + mace = mace_read_32 (MACEISA_INT_MASK); + printk ("MACE ISA interrupt mask: %08x\n", mace); + mace = mace_read_32 (MACEISA_INT_STAT); + printk ("MACE ISA interrupt status: %08x\n", mace); + mace = mace_read_32 (MACEPCI_CONTROL); + printk ("MACE PCI control register: %08x\n", mace); + + printk("Register dump:\n"); + show_regs(regs); + + printk("Please mail this report to linux-mips@oss.sgi.com\n"); + printk("Spinning..."); + while(1) ; +} + +/* CRIME 1.1 appears to deliver all interrupts to this one pin. */ +void ip32_irq0(struct pt_regs *regs) +{ + u64 crime_int; + u64 crime_mask; + int irq = 0; + unsigned long flags; + + local_irq_save(flags); + /* disable crime interrupts */ + crime_mask = crime_read_64(CRIME_INT_MASK); + crime_write_64(CRIME_INT_MASK, 0); + + crime_int = crime_read_64(CRIME_INT_STAT); + + if (crime_int & CRIME_MACE_INT_MASK) { + crime_int &= CRIME_MACE_INT_MASK; + irq = ffs (crime_int); + } else if (crime_int & CRIME_MACEISA_INT_MASK) { + u32 mace_int; + mace_int = mace_read_32 (MACEISA_INT_STAT); + if (mace_int == 0) + irq = 0; + else + irq = ffs (mace_int) + 32; + } else if (crime_int & CRIME_MACEPCI_INT_MASK) { + crime_int &= CRIME_MACEPCI_INT_MASK; + crime_int >>= 8; + irq = ffs (crime_int) + 8; + } else if (crime_int & 0xffff0000) { + crime_int >>= 16; + irq = ffs (crime_int) + 16; + } + if (irq == 0) + ip32_unknown_interrupt(regs); + DBG("*irq %u*\n", irq); + do_IRQ(irq, regs); + + /* enable crime interrupts */ + crime_write_64(CRIME_INT_MASK, crime_mask); + local_irq_restore (flags); +} + +void ip32_irq1(struct pt_regs *regs) +{ + ip32_unknown_interrupt (regs); +} + +void ip32_irq2(struct pt_regs *regs) +{ + ip32_unknown_interrupt (regs); +} + +void ip32_irq3(struct pt_regs *regs) +{ + ip32_unknown_interrupt (regs); +} + +void ip32_irq4(struct pt_regs *regs) +{ + ip32_unknown_interrupt (regs); +} + +void ip32_irq5(struct pt_regs *regs) +{ + do_IRQ (CLOCK_IRQ, regs); +} + +void __init init_IRQ(void) +{ + unsigned int irq; + int i; + + /* Install our interrupt handler, then clear and disable all + * CRIME and MACE interrupts. + */ + crime_write_64(CRIME_INT_MASK, 0); + crime_write_64(CRIME_HARD_INT, 0); + crime_write_64(CRIME_SOFT_INT, 0); + mace_write_32(MACEISA_INT_STAT, 0); + mace_write_32(MACEISA_INT_MASK, 0); + set_except_vector(0, ip32_handle_int); + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &no_irq_type; + } + + for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { + hw_irq_controller *controller; + + if (irq == CLOCK_IRQ) + controller = &ip32_cpu_interrupt; + else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ) + controller = &ip32_mace_interrupt; + else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ) + controller = &ip32_macepci_interrupt; + else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ) + controller = &ip32_crime_interrupt; + else + controller = &ip32_maceisa_interrupt; + + irq_desc[irq].status = IRQ_DISABLED; + irq_desc[irq].action = 0; + irq_desc[irq].depth = 0; + irq_desc[irq].handler = controller; + } + setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); + setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); +} diff -Nru a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,208 @@ +/* + * 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) 2001 Keith M Wesolowski + * Copyright (C) 2001 Paul Mundt + * Copyright (C) 2003 Guido Guenther <agx@sigxcpu.org> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/notifier.h> +#include <linux/delay.h> +#include <linux/ds17287rtc.h> + +#include <asm/irq.h> +#include <asm/reboot.h> +#include <asm/sgialib.h> +#include <asm/addrspace.h> +#include <asm/types.h> +#include <asm/system.h> +#include <asm/wbflush.h> +#include <asm/ip32/ip32_ints.h> + +#define POWERDOWN_TIMEOUT 120 +/* + * Blink frequency during reboot grace period and when paniced. + */ +#define POWERDOWN_FREQ (HZ / 4) +#define PANIC_FREQ (HZ / 8) + +static struct timer_list power_timer, blink_timer, debounce_timer; +static int shuting_down = 0, has_paniced = 0; + +static void ip32_machine_restart(char *command) __attribute__((noreturn)); +static void ip32_machine_halt(void) __attribute__((noreturn)); +static void ip32_machine_power_off(void) __attribute__((noreturn)); + +static void ip32_machine_restart(char *cmd) +{ + if (shuting_down) + ip32_machine_power_off(); + ArcReboot(); +} + +static inline void ip32_machine_halt(void) +{ + if (shuting_down) + ip32_machine_power_off(); + ArcEnterInteractiveMode(); +} + +static void ip32_machine_power_off(void) +{ + volatile unsigned char reg_a, xctrl_a, xctrl_b; + + disable_irq(MACEISA_RTC_IRQ); + reg_a = CMOS_READ(RTC_REG_A); + + /* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */ + reg_a &= ~DS_REGA_DV2; + reg_a |= DS_REGA_DV1; + + CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A); + wbflush(); + xctrl_b = CMOS_READ(DS_B1_XCTRL4B) + | DS_XCTRL4B_ABE | DS_XCTRL4B_KFE; + CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B); + xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS; + CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A); + wbflush(); + /* adios amigos... */ + CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A); + CMOS_WRITE(reg_a, RTC_REG_A); + wbflush(); + + while(1) { + printk(KERN_DEBUG "Power off!\n"); + } +} + +static void power_timeout(unsigned long data) +{ + ip32_machine_power_off(); +} + +static void blink_timeout(unsigned long data) +{ + u64 mc_led = mace_read_64(MACEISA_FLASH_NIC_REG); + + mc_led ^= MACEISA_LED_RED; + mace_write_64(MACEISA_FLASH_NIC_REG, mc_led); + mod_timer(&blink_timer, jiffies+data); +} + +static void debounce(unsigned long data) +{ + volatile unsigned char reg_a,reg_c,xctrl_a; + + reg_c = CMOS_READ(RTC_INTR_FLAGS); + CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A); + wbflush(); + xctrl_a = CMOS_READ(DS_B1_XCTRL4A); + if( (xctrl_a & DS_XCTRL4A_IFS ) || ( reg_c & RTC_IRQF ) ) { + /* Interrupt still being sent. */ + debounce_timer.expires = jiffies + 50; + add_timer(&debounce_timer); + + /* clear interrupt source */ + CMOS_WRITE( xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A); + CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A); + return; + } + CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A); + + if (has_paniced) + ArcReboot(); + + enable_irq(MACEISA_RTC_IRQ); +} + +static inline void ip32_power_button(void) +{ + if (has_paniced) + return; + + if (shuting_down || kill_proc(1, SIGINT, 1)) { + /* No init process or button pressed twice. */ + ip32_machine_power_off(); + } + + shuting_down = 1; + blink_timer.data = POWERDOWN_FREQ; + blink_timeout(POWERDOWN_FREQ); + + init_timer(&power_timer); + power_timer.function = power_timeout; + power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ; + add_timer(&power_timer); +} + +static void ip32_rtc_int(int irq, void *dev_id, struct pt_regs *regs) +{ + volatile unsigned char reg_c; + + reg_c = CMOS_READ(RTC_INTR_FLAGS); + if( ! (reg_c & RTC_IRQF) ) { + printk(KERN_WARNING + "%s: RTC IRQ without RTC_IRQF\n", __FUNCTION__); + } + /* Wait until interrupt goes away */ + disable_irq(MACEISA_RTC_IRQ); + init_timer(&debounce_timer); + debounce_timer.function = debounce; + debounce_timer.expires = jiffies + 50; + add_timer(&debounce_timer); + + printk(KERN_DEBUG "Power button pressed\n"); + ip32_power_button(); +} + +static int panic_event(struct notifier_block *this, unsigned long event, + void *ptr) +{ + u64 mc_led; + + if (has_paniced) + return NOTIFY_DONE; + has_paniced = 1; + + /* turn off the green LED */ + mc_led = mace_read_64(MACEISA_FLASH_NIC_REG); + mc_led |= MACEISA_LED_GREEN; + mace_write_64(MACEISA_FLASH_NIC_REG, mc_led); + + blink_timer.data = PANIC_FREQ; + blink_timeout(PANIC_FREQ); + + return NOTIFY_DONE; +} + +static struct notifier_block panic_block = { + .notifier_call = panic_event, +}; + +static __init int ip32_reboot_setup(void) +{ + u64 mc_led = mace_read_64(MACEISA_FLASH_NIC_REG); + + _machine_restart = ip32_machine_restart; + _machine_halt = ip32_machine_halt; + _machine_power_off = ip32_machine_power_off; + request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL); + init_timer(&blink_timer); + blink_timer.function = blink_timeout; + notifier_chain_register(&panic_notifier_list, &panic_block); + + /* turn on the green led only */ + mc_led |= MACEISA_LED_RED; + mc_led &= ~MACEISA_LED_GREEN; + mace_write_64(MACEISA_FLASH_NIC_REG, mc_led); + + return 0; +} + +subsys_initcall(ip32_reboot_setup); diff -Nru a/arch/mips/sgi-ip32/ip32-rtc.c b/arch/mips/sgi-ip32/ip32-rtc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-rtc.c Fri Jun 27 14:19:59 2003 @@ -0,0 +1,32 @@ +/* + * RTC routines for IP32 style attached Dallas chip. + * + * 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) 2000 Harald Koerfgen + */ +#include <linux/mc146818rtc.h> +#include <asm/ip32/mace.h> + +static unsigned char ip32_rtc_read_data(unsigned long addr) +{ + return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8)); +} + +static void ip32_rtc_write_data(unsigned char data, unsigned long addr) +{ + mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data); +} + +static int ip32_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops ip32_rtc_ops = { + &ip32_rtc_read_data, + &ip32_rtc_write_data, + &ip32_rtc_bcd_mode +}; diff -Nru a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-setup.c Fri Jun 27 14:20:02 2003 @@ -0,0 +1,105 @@ +/* + * IP32 basic setup + * + * 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) 2000 Harald Koerfgen + */ +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/mc146818rtc.h> +#include <linux/param.h> +#include <linux/init.h> + +#include <asm/time.h> +#include <asm/mipsregs.h> +#include <asm/bootinfo.h> +#include <asm/mmu_context.h> +#include <asm/ip32/crime.h> +#include <asm/ip32/mace.h> +#include <asm/ip32/ip32_ints.h> +#include <asm/sgialib.h> +#include <asm/traps.h> + +extern struct rtc_ops ip32_rtc_ops; +extern u32 cc_interval; + +#ifdef CONFIG_SGI_O2MACE_ETH + +/* + * This is taken care of in here 'cause they say using Arc later on is + * problematic + */ +extern char o2meth_eaddr[8]; +static inline unsigned char str2hexnum(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; /* foo */ +} + +static inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for (i = 0; i < 6; i++) { + unsigned char num; + + if(*str == ':') + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} +#endif + +extern void ip32_time_init(void); +extern void ip32_reboot_setup(void); + +void __init ip32_setup(void) +{ +#ifdef CONFIG_SERIAL_CONSOLE + char *ctype; +#endif + TLBMISS_HANDLER_SETUP (); + + mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);; + +#ifdef CONFIG_SERIAL_CONSOLE + ctype = ArcGetEnvironmentVariable("console"); + if (*ctype == 'd') { + if (ctype[1] == '2') + console_setup ("ttyS1"); + else + console_setup ("ttyS0"); + } +#endif +#ifdef CONFIG_SGI_O2MACE_ETH + { + char *mac=ArcGetEnvironmentVariable("eaddr"); + str2eaddr(o2meth_eaddr, mac); + } +#endif + +#ifdef CONFIG_VT + conswitchp = &dummy_con; +#endif + + rtc_ops = &ip32_rtc_ops; + board_be_init = ip32_be_init; + board_time_init = ip32_time_init; + + crime_init (); +} + +int __init page_is_ram (unsigned long pagenr) +{ + /* XXX: to do? */ + return 1; +} diff -Nru a/arch/mips/sgi-ip32/ip32-timer.c b/arch/mips/sgi-ip32/ip32-timer.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sgi-ip32/ip32-timer.c Fri Jun 27 14:20:00 2003 @@ -0,0 +1,238 @@ +/* + * IP32 timer calibration + * + * 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) 2001 Keith M Wesolowski + */ +#include <linux/bcd.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/param.h> +#include <linux/string.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/mc146818rtc.h> +#include <linux/timex.h> + +#include <asm/mipsregs.h> +#include <asm/param.h> +#include <asm/ip32/crime.h> +#include <asm/ip32/ip32_ints.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/mipsregs.h> +#include <asm/io.h> +#include <asm/irq.h> + +extern volatile unsigned long wall_jiffies; + +u32 cc_interval; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + +/* An arbitrary time; this can be decreased if reliability looks good */ +#define WAIT_MS 10 +#define PER_MHZ (1000000 / 2 / HZ) +/* + * Change this if you have some constant time drift + */ +#define USECS_PER_JIFFY (1000000/HZ) + + +void __init ip32_timer_setup (struct irqaction *irq) +{ + u64 crime_time; + u32 cc_tick; + + printk("Calibrating system timer... "); + + crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK; + cc_tick = read_c0_count(); + + while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time + < WAIT_MS * 1000000 / CRIME_NS_PER_TICK) + ; + cc_tick = read_c0_count() - cc_tick; + cc_interval = cc_tick / HZ * (1000 / WAIT_MS); + /* The round-off seems unnecessary; in testing, the error of the + * above procedure is < 100 ticks, which means it gets filtered + * out by the HZ adjustment. + */ + cc_interval = (cc_interval / PER_MHZ) * PER_MHZ; + + printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ)); + + setup_irq (CLOCK_IRQ, irq); +} + +struct irqaction irq0 = { NULL, SA_INTERRUPT, 0, + "timer", NULL, NULL}; + +void cc_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) +{ + u32 count; + + /* + * The cycle counter is only 32 bit which is good for about + * a minute at current count rates of upto 150MHz or so. + */ + count = read_c0_count(); + timerhi += (count < timerlo); /* Wrap around */ + timerlo = count; + + write_c0_compare( + (u32) (count + cc_interval)); + kstat_cpu(0).irqs[irq]++; + do_timer (regs); + + if (!jiffies) + { + /* + * If jiffies has overflowed in this timer_interrupt we must + * update the timer[hi]/[lo] to make do_fast_gettimeoffset() + * quotient calc still valid. -arca + */ + timerhi = timerlo = 0; + } +} + +/* + * On MIPS only R4000 and better have a cycle counter. + * + * FIXME: Does playing with the RP bit in c0_status interfere with this code? + */ +static unsigned long do_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + + /* Last jiffy when do_fast_gettimeoffset() was called. */ + static unsigned long last_jiffies; + u32 quotient; + + /* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ + static u32 cached_quotient; + + tmp = jiffies; + + quotient = cached_quotient; + + if (tmp && last_jiffies != tmp) { + last_jiffies = tmp; + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "lwu\t%0,%2\n\t" + "dsll32\t$1,%1,0\n\t" + "or\t$1,$1,%0\n\t" + "ddivu\t$0,$1,%3\n\t" + "mflo\t$1\n\t" + "dsll32\t%0,%4,0\n\t" + "nop\n\t" + "ddivu\t$0,%0,$1\n\t" + "mflo\t%0\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=&r" (quotient) + :"r" (timerhi), + "m" (timerlo), + "r" (tmp), + "r" (USECS_PER_JIFFY) + :"$1"); + cached_quotient = quotient; + } + + /* Get last timer tick in absolute kernel time */ + count = read_c0_count(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu\t%1,%2\n\t" + "mfhi\t%0" + :"=r" (res) + :"r" (count), + "r" (quotient)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + + return res; +} + +void __init ip32_time_init(void) +{ + unsigned int epoch = 0, year, mon, day, hour, min, sec; + int i; + + /* The Linux interpretation of the CMOS clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. + */ + /* read RTC exactly on falling edge of update flag */ + for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + do { /* Isn't this overkill ? UIP above should guarantee consistency */ + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + day = BCD2BIN(day); + mon = BCD2BIN(mon); + year = BCD2BIN(year); + } + + /* Attempt to guess the epoch. This is the same heuristic as in + * rtc.c so no stupid things will happen to timekeeping. Who knows, + * maybe Ultrix also uses 1952 as epoch ... + */ + if (year > 10 && year < 44) + epoch = 1980; + else if (year < 96) + epoch = 1952; + year += epoch; + + write_seqlock_irq(&xtime_lock); + xtime.tv_sec = mktime(year, mon, day, hour, min, sec); + xtime.tv_nsec = 0; + write_sequnlock_irq(&xtime_lock); + + write_c0_count(0); + irq0.handler = cc_timer_interrupt; + + ip32_timer_setup (&irq0); + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) + /* Set ourselves up for future interrupts */ + write_c0_compare( + read_c0_count() + + cc_interval); + change_c0_status(ST0_IM, ALLINTS); + sti (); +} diff -Nru a/arch/mips/sibyte/cfe/Makefile b/arch/mips/sibyte/cfe/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,3 @@ +lib-y = cfe_api.o setup.o +lib-$(CONFIG_SMP) += smp.o +lib-$(CONFIG_SIBYTE_CFE_CONSOLE) += console.o diff -Nru a/arch/mips/sibyte/cfe/cfe_api.c b/arch/mips/sibyte/cfe/cfe_api.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/cfe_api.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,502 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* ********************************************************************* + * + * Broadcom Common Firmware Environment (CFE) + * + * Device Function stubs File: cfe_api.c + * + * This module contains device function stubs (small routines to + * call the standard "iocb" interface entry point to CFE). + * There should be one routine here per iocb function call. + * + * Authors: Mitch Lichtenberg, Chris Demetriou + * + ********************************************************************* */ + +#include "cfe_api.h" +#include "cfe_api_int.h" + +/* Cast from a native pointer to a cfe_xptr_t and back. */ +#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) +#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) + +#ifdef CFE_API_IMPL_NAMESPACE +#define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a) +#endif +int cfe_iocb_dispatch(cfe_xiocb_t * xiocb); + +#if defined(CFE_API_common) || defined(CFE_API_ALL) +/* + * Declare the dispatch function with args of "intptr_t". + * This makes sure whatever model we're compiling in + * puts the pointers in a single register. For example, + * combining -mlong64 and -mips1 or -mips2 would lead to + * trouble, since the handle and IOCB pointer will be + * passed in two registers each, and CFE expects one. + */ + +static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; +static cfe_xuint_t cfe_handle = 0; + +int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) +{ + cfe_dispfunc = NATIVE_FROM_XPTR(ept); + cfe_handle = handle; + return 0; +} + +int cfe_iocb_dispatch(cfe_xiocb_t * xiocb) +{ + if (!cfe_dispfunc) + return -1; + return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); +} +#endif /* CFE_API_common || CFE_API_ALL */ + +#if defined(CFE_API_close) || defined(CFE_API_ALL) +int cfe_close(int handle) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = 0; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; + +} +#endif /* CFE_API_close || CFE_API_ALL */ + +#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL) +int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); + xiocb.plist.xiocb_cpuctl.cpu_number = cpu; + xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; + xiocb.plist.xiocb_cpuctl.gp_val = gp; + xiocb.plist.xiocb_cpuctl.sp_val = sp; + xiocb.plist.xiocb_cpuctl.a1_val = a1; + xiocb.plist.xiocb_cpuctl.start_addr = (long) fn; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_cpu_start || CFE_API_ALL */ + +#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL) +int cfe_cpu_stop(int cpu) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); + xiocb.plist.xiocb_cpuctl.cpu_number = cpu; + xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_cpu_stop || CFE_API_ALL */ + +#if defined(CFE_API_enumenv) || defined(CFE_API_ALL) +int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = idx; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = namelen; + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); + xiocb.plist.xiocb_envbuf.val_length = vallen; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_enumenv || CFE_API_ALL */ + +#if defined(CFE_API_enummem) || defined(CFE_API_ALL) +int +cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length, + cfe_xuint_t * type) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flags; + xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); + xiocb.plist.xiocb_meminfo.mi_idx = idx; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + + *start = xiocb.plist.xiocb_meminfo.mi_addr; + *length = xiocb.plist.xiocb_meminfo.mi_size; + *type = xiocb.plist.xiocb_meminfo.mi_type; + + return 0; +} +#endif /* CFE_API_enummem || CFE_API_ALL */ + +#if defined(CFE_API_exit) || defined(CFE_API_ALL) +int cfe_exit(int warm, int status) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; + xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); + xiocb.plist.xiocb_exitstat.status = status; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_exit || CFE_API_ALL */ + +#if defined(CFE_API_flushcache) || defined(CFE_API_ALL) +int cfe_flushcache(int flg) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flg; + xiocb.xiocb_psize = 0; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_flushcache || CFE_API_ALL */ + +#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL) +int cfe_getdevinfo(char *name) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = 0; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_devflags; +} +#endif /* CFE_API_getdevinfo || CFE_API_ALL */ + +#if defined(CFE_API_getenv) || defined(CFE_API_ALL) +int cfe_getenv(char *name, char *dest, int destlen) +{ + cfe_xiocb_t xiocb; + + *dest = 0; + + xiocb.xiocb_fcode = CFE_CMD_ENV_GET; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = 0; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); + xiocb.plist.xiocb_envbuf.val_length = destlen; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_getenv || CFE_API_ALL */ + +#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL) +int cfe_getfwinfo(cfe_fwinfo_t * info) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + + info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version; + info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem; + info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags; + info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid; + info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va; + info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa; + info->fwi_bootarea_size = + xiocb.plist.xiocb_fwinfo.fwi_bootarea_size; +#if 0 + info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1; + info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2; + info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3; +#endif + + return 0; +} +#endif /* CFE_API_getfwinfo || CFE_API_ALL */ + +#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL) +int cfe_getstdhandle(int flg) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = flg; + xiocb.xiocb_psize = 0; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.xiocb_handle; +} +#endif /* CFE_API_getstdhandle || CFE_API_ALL */ + +#if defined(CFE_API_getticks) || defined(CFE_API_ALL) +int64_t +#ifdef CFE_API_IMPL_NAMESPACE +__cfe_getticks(void) +#else +cfe_getticks(void) +#endif +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_time_t); + xiocb.plist.xiocb_time.ticks = 0; + + cfe_iocb_dispatch(&xiocb); + + return xiocb.plist.xiocb_time.ticks; + +} +#endif /* CFE_API_getticks || CFE_API_ALL */ + +#if defined(CFE_API_inpstat) || defined(CFE_API_ALL) +int cfe_inpstat(int handle) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); + xiocb.plist.xiocb_inpstat.inp_status = 0; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_inpstat.inp_status; +} +#endif /* CFE_API_inpstat || CFE_API_ALL */ + +#if defined(CFE_API_ioctl) || defined(CFE_API_ALL) +int +cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, + int length, int *retlen, cfe_xuint_t offset) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; + + cfe_iocb_dispatch(&xiocb); + + if (retlen) + *retlen = xiocb.plist.xiocb_buffer.buf_retlen; + return xiocb.xiocb_status; +} +#endif /* CFE_API_ioctl || CFE_API_ALL */ + +#if defined(CFE_API_open) || defined(CFE_API_ALL) +int cfe_open(char *name) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = 0; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.xiocb_handle; +} +#endif /* CFE_API_open || CFE_API_ALL */ + +#if defined(CFE_API_read) || defined(CFE_API_ALL) +int cfe_read(int handle, unsigned char *buffer, int length) +{ + return cfe_readblk(handle, 0, buffer, length); +} +#endif /* CFE_API_read || CFE_API_ALL */ + +#if defined(CFE_API_readblk) || defined(CFE_API_ALL) +int +cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer, + int length) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_READ; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_retlen; +} +#endif /* CFE_API_readblk || CFE_API_ALL */ + +#if defined(CFE_API_setenv) || defined(CFE_API_ALL) +int cfe_setenv(char *name, char *val) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = 0; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); + xiocb.plist.xiocb_envbuf.enum_idx = 0; + xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); + xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); + xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); + xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); + + cfe_iocb_dispatch(&xiocb); + + return xiocb.xiocb_status; +} +#endif /* CFE_API_setenv || CFE_API_ALL */ + +#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \ + && !defined(CFE_API_STRLEN_CUSTOM) +int cfe_strlen(char *name) +{ + int count = 0; + + while (*name++) + count++; + + return count; +} +#endif /* CFE_API_strlen || CFE_API_ALL */ + +#if defined(CFE_API_write) || defined(CFE_API_ALL) +int cfe_write(int handle, unsigned char *buffer, int length) +{ + return cfe_writeblk(handle, 0, buffer, length); +} +#endif /* CFE_API_write || CFE_API_ALL */ + +#if defined(CFE_API_writeblk) || defined(CFE_API_ALL) +int +cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer, + int length) +{ + cfe_xiocb_t xiocb; + + xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; + xiocb.xiocb_status = 0; + xiocb.xiocb_handle = handle; + xiocb.xiocb_flags = 0; + xiocb.xiocb_psize = sizeof(xiocb_buffer_t); + xiocb.plist.xiocb_buffer.buf_offset = offset; + xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); + xiocb.plist.xiocb_buffer.buf_length = length; + + cfe_iocb_dispatch(&xiocb); + + if (xiocb.xiocb_status < 0) + return xiocb.xiocb_status; + return xiocb.plist.xiocb_buffer.buf_retlen; +} +#endif /* CFE_API_writeblk || CFE_API_ALL */ diff -Nru a/arch/mips/sibyte/cfe/cfe_api.h b/arch/mips/sibyte/cfe/cfe_api.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/cfe_api.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* ********************************************************************* + * + * Broadcom Common Firmware Environment (CFE) + * + * Device function prototypes File: cfe_api.h + * + * This file contains declarations for doing callbacks to + * cfe from an application. It should be the only header + * needed by the application to use this library + * + * Authors: Mitch Lichtenberg, Chris Demetriou + * + ********************************************************************* */ + +#ifndef CFE_API_H +#define CFE_API_H + +/* + * Apply customizations here for different OSes. These need to: + * * typedef uint64_t, int64_t, intptr_t, uintptr_t. + * * define cfe_strlen() if use of an existing function is desired. + * * define CFE_API_IMPL_NAMESPACE if API functions are to use + * names in the implementation namespace. + * Also, optionally, if the build environment does not do so automatically, + * CFE_API_* can be defined here as desired. + */ +/* Begin customization. */ +#include <linux/types.h> +#include <linux/string.h> + +typedef long intptr_t; + +#define cfe_strlen strlen + +#define CFE_API_ALL +#define CFE_API_STRLEN_CUSTOM +/* End customization. */ + + +/* ********************************************************************* + * Constants + ********************************************************************* */ + +/* Seal indicating CFE's presence, passed to user program. */ +#define CFE_EPTSEAL 0x43464531 + +#define CFE_MI_RESERVED 0 /* memory is reserved, do not use */ +#define CFE_MI_AVAILABLE 1 /* memory is available */ + +#define CFE_FLG_WARMSTART 0x00000001 +#define CFE_FLG_FULL_ARENA 0x00000001 +#define CFE_FLG_ENV_PERMANENT 0x00000001 + +#define CFE_CPU_CMD_START 1 +#define CFE_CPU_CMD_STOP 0 + +#define CFE_STDHANDLE_CONSOLE 0 + +#define CFE_DEV_NETWORK 1 +#define CFE_DEV_DISK 2 +#define CFE_DEV_FLASH 3 +#define CFE_DEV_SERIAL 4 +#define CFE_DEV_CPU 5 +#define CFE_DEV_NVRAM 6 +#define CFE_DEV_CLOCK 7 +#define CFE_DEV_OTHER 8 +#define CFE_DEV_MASK 0x0F + +#define CFE_CACHE_FLUSH_D 1 +#define CFE_CACHE_INVAL_I 2 +#define CFE_CACHE_INVAL_D 4 +#define CFE_CACHE_INVAL_L2 8 + +#define CFE_FWI_64BIT 0x00000001 +#define CFE_FWI_32BIT 0x00000002 +#define CFE_FWI_RELOC 0x00000004 +#define CFE_FWI_UNCACHED 0x00000008 +#define CFE_FWI_MULTICPU 0x00000010 +#define CFE_FWI_FUNCSIM 0x00000020 +#define CFE_FWI_RTLSIM 0x00000040 + +typedef struct { + int64_t fwi_version; /* major, minor, eco version */ + int64_t fwi_totalmem; /* total installed mem */ + int64_t fwi_flags; /* various flags */ + int64_t fwi_boardid; /* board ID */ + int64_t fwi_bootarea_va; /* VA of boot area */ + int64_t fwi_bootarea_pa; /* PA of boot area */ + int64_t fwi_bootarea_size; /* size of boot area */ +} cfe_fwinfo_t; + + +/* + * cfe_strlen is handled specially: If already defined, it has been + * overridden in this environment with a standard strlen-like function. + */ +#ifdef cfe_strlen +# define CFE_API_STRLEN_CUSTOM +#else +# ifdef CFE_API_IMPL_NAMESPACE +# define cfe_strlen(a) __cfe_strlen(a) +# endif +int cfe_strlen(char *name); +#endif + +/* + * Defines and prototypes for functions which take no arguments. + */ +#ifdef CFE_API_IMPL_NAMESPACE +int64_t __cfe_getticks(void); +#define cfe_getticks() __cfe_getticks() +#else +int64_t cfe_getticks(void); +#endif + +/* + * Defines and prototypes for the rest of the functions. + */ +#ifdef CFE_API_IMPL_NAMESPACE +#define cfe_close(a) __cfe_close(a) +#define cfe_cpu_start(a,b,c,d,e) __cfe_cpu_start(a,b,c,d,e) +#define cfe_cpu_stop(a) __cfe_cpu_stop(a) +#define cfe_enumenv(a,b,d,e,f) __cfe_enumenv(a,b,d,e,f) +#define cfe_enummem(a,b,c,d,e) __cfe_enummem(a,b,c,d,e) +#define cfe_exit(a,b) __cfe_exit(a,b) +#define cfe_flushcache(a) __cfe_cacheflush(a) +#define cfe_getdevinfo(a) __cfe_getdevinfo(a) +#define cfe_getenv(a,b,c) __cfe_getenv(a,b,c) +#define cfe_getfwinfo(a) __cfe_getfwinfo(a) +#define cfe_getstdhandle(a) __cfe_getstdhandle(a) +#define cfe_init(a,b) __cfe_init(a,b) +#define cfe_inpstat(a) __cfe_inpstat(a) +#define cfe_ioctl(a,b,c,d,e,f) __cfe_ioctl(a,b,c,d,e,f) +#define cfe_open(a) __cfe_open(a) +#define cfe_read(a,b,c) __cfe_read(a,b,c) +#define cfe_readblk(a,b,c,d) __cfe_readblk(a,b,c,d) +#define cfe_setenv(a,b) __cfe_setenv(a,b) +#define cfe_write(a,b,c) __cfe_write(a,b,c) +#define cfe_writeblk(a,b,c,d) __cfe_writeblk(a,b,c,d) +#endif /* CFE_API_IMPL_NAMESPACE */ + +int cfe_close(int handle); +int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1); +int cfe_cpu_stop(int cpu); +int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen); +int cfe_enummem(int idx, int flags, uint64_t * start, uint64_t * length, + uint64_t * type); +int cfe_exit(int warm, int status); +int cfe_flushcache(int flg); +int cfe_getdevinfo(char *name); +int cfe_getenv(char *name, char *dest, int destlen); +int cfe_getfwinfo(cfe_fwinfo_t * info); +int cfe_getstdhandle(int flg); +int cfe_init(uint64_t handle, uint64_t ept); +int cfe_inpstat(int handle); +int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, + int length, int *retlen, uint64_t offset); +int cfe_open(char *name); +int cfe_read(int handle, unsigned char *buffer, int length); +int cfe_readblk(int handle, int64_t offset, unsigned char *buffer, + int length); +int cfe_setenv(char *name, char *val); +int cfe_write(int handle, unsigned char *buffer, int length); +int cfe_writeblk(int handle, int64_t offset, unsigned char *buffer, + int length); + +#endif /* CFE_API_H */ diff -Nru a/arch/mips/sibyte/cfe/cfe_api_int.h b/arch/mips/sibyte/cfe/cfe_api_int.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/cfe_api_int.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* ********************************************************************* + * + * Broadcom Common Firmware Environment (CFE) + * + * Device function prototypes File: cfe_api_int.h + * + * This header defines all internal types and macros for the + * library. This is stuff that's not exported to an app + * using the library. + * + * Authors: Mitch Lichtenberg, Chris Demetriou + * + ********************************************************************* */ + +#ifndef CFE_API_INT_H +#define CFE_API_INT_H + +/* ********************************************************************* + * Constants + ********************************************************************* */ + +#define CFE_CMD_FW_GETINFO 0 +#define CFE_CMD_FW_RESTART 1 +#define CFE_CMD_FW_BOOT 2 +#define CFE_CMD_FW_CPUCTL 3 +#define CFE_CMD_FW_GETTIME 4 +#define CFE_CMD_FW_MEMENUM 5 +#define CFE_CMD_FW_FLUSHCACHE 6 + +#define CFE_CMD_DEV_GETHANDLE 9 +#define CFE_CMD_DEV_ENUM 10 +#define CFE_CMD_DEV_OPEN 11 +#define CFE_CMD_DEV_INPSTAT 12 +#define CFE_CMD_DEV_READ 13 +#define CFE_CMD_DEV_WRITE 14 +#define CFE_CMD_DEV_IOCTL 15 +#define CFE_CMD_DEV_CLOSE 16 +#define CFE_CMD_DEV_GETINFO 17 + +#define CFE_CMD_ENV_ENUM 20 +#define CFE_CMD_ENV_GET 22 +#define CFE_CMD_ENV_SET 23 +#define CFE_CMD_ENV_DEL 24 + +#define CFE_CMD_MAX 32 + +#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */ + +/* ********************************************************************* + * Structures + ********************************************************************* */ + +typedef uint64_t cfe_xuint_t; +typedef int64_t cfe_xint_t; +typedef int64_t cfe_xptr_t; + +typedef struct xiocb_buffer_s { + cfe_xuint_t buf_offset; /* offset on device (bytes) */ + cfe_xptr_t buf_ptr; /* pointer to a buffer */ + cfe_xuint_t buf_length; /* length of this buffer */ + cfe_xuint_t buf_retlen; /* returned length (for read ops) */ + cfe_xuint_t buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */ +} xiocb_buffer_t; + +#define buf_devflags buf_ioctlcmd /* returned device info flags */ + +typedef struct xiocb_inpstat_s { + cfe_xuint_t inp_status; /* 1 means input available */ +} xiocb_inpstat_t; + +typedef struct xiocb_envbuf_s { + cfe_xint_t enum_idx; /* 0-based enumeration index */ + cfe_xptr_t name_ptr; /* name string buffer */ + cfe_xint_t name_length; /* size of name buffer */ + cfe_xptr_t val_ptr; /* value string buffer */ + cfe_xint_t val_length; /* size of value string buffer */ +} xiocb_envbuf_t; + +typedef struct xiocb_cpuctl_s { + cfe_xuint_t cpu_number; /* cpu number to control */ + cfe_xuint_t cpu_command; /* command to issue to CPU */ + cfe_xuint_t start_addr; /* CPU start address */ + cfe_xuint_t gp_val; /* starting GP value */ + cfe_xuint_t sp_val; /* starting SP value */ + cfe_xuint_t a1_val; /* starting A1 value */ +} xiocb_cpuctl_t; + +typedef struct xiocb_time_s { + cfe_xint_t ticks; /* current time in ticks */ +} xiocb_time_t; + +typedef struct xiocb_exitstat_s { + cfe_xint_t status; +} xiocb_exitstat_t; + +typedef struct xiocb_meminfo_s { + cfe_xint_t mi_idx; /* 0-based enumeration index */ + cfe_xint_t mi_type; /* type of memory block */ + cfe_xuint_t mi_addr; /* physical start address */ + cfe_xuint_t mi_size; /* block size */ +} xiocb_meminfo_t; + +typedef struct xiocb_fwinfo_s { + cfe_xint_t fwi_version; /* major, minor, eco version */ + cfe_xint_t fwi_totalmem; /* total installed mem */ + cfe_xint_t fwi_flags; /* various flags */ + cfe_xint_t fwi_boardid; /* board ID */ + cfe_xint_t fwi_bootarea_va; /* VA of boot area */ + cfe_xint_t fwi_bootarea_pa; /* PA of boot area */ + cfe_xint_t fwi_bootarea_size; /* size of boot area */ + cfe_xint_t fwi_reserved1; + cfe_xint_t fwi_reserved2; + cfe_xint_t fwi_reserved3; +} xiocb_fwinfo_t; + +typedef struct cfe_xiocb_s { + cfe_xuint_t xiocb_fcode; /* IOCB function code */ + cfe_xint_t xiocb_status; /* return status */ + cfe_xint_t xiocb_handle; /* file/device handle */ + cfe_xuint_t xiocb_flags; /* flags for this IOCB */ + cfe_xuint_t xiocb_psize; /* size of parameter list */ + union { + xiocb_buffer_t xiocb_buffer; /* buffer parameters */ + xiocb_inpstat_t xiocb_inpstat; /* input status parameters */ + xiocb_envbuf_t xiocb_envbuf; /* environment function parameters */ + xiocb_cpuctl_t xiocb_cpuctl; /* CPU control parameters */ + xiocb_time_t xiocb_time; /* timer parameters */ + xiocb_meminfo_t xiocb_meminfo; /* memory arena info parameters */ + xiocb_fwinfo_t xiocb_fwinfo; /* firmware information */ + xiocb_exitstat_t xiocb_exitstat; /* Exit Status */ + } plist; +} cfe_xiocb_t; + +#endif /* CFE_API_INT_H */ diff -Nru a/arch/mips/sibyte/cfe/cfe_error.h b/arch/mips/sibyte/cfe/cfe_error.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/cfe_error.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* ********************************************************************* + * + * Broadcom Common Firmware Environment (CFE) + * + * Error codes File: cfe_error.h + * + * CFE's global error code list is here. + * + * Author: Mitch Lichtenberg + * + ********************************************************************* */ + + +#define CFE_OK 0 +#define CFE_ERR -1 /* generic error */ +#define CFE_ERR_INV_COMMAND -2 +#define CFE_ERR_EOF -3 +#define CFE_ERR_IOERR -4 +#define CFE_ERR_NOMEM -5 +#define CFE_ERR_DEVNOTFOUND -6 +#define CFE_ERR_DEVOPEN -7 +#define CFE_ERR_INV_PARAM -8 +#define CFE_ERR_ENVNOTFOUND -9 +#define CFE_ERR_ENVREADONLY -10 + +#define CFE_ERR_NOTELF -11 +#define CFE_ERR_NOT32BIT -12 +#define CFE_ERR_WRONGENDIAN -13 +#define CFE_ERR_BADELFVERS -14 +#define CFE_ERR_NOTMIPS -15 +#define CFE_ERR_BADELFFMT -16 +#define CFE_ERR_BADADDR -17 + +#define CFE_ERR_FILENOTFOUND -18 +#define CFE_ERR_UNSUPPORTED -19 + +#define CFE_ERR_HOSTUNKNOWN -20 + +#define CFE_ERR_TIMEOUT -21 + +#define CFE_ERR_PROTOCOLERR -22 + +#define CFE_ERR_NETDOWN -23 +#define CFE_ERR_NONAMESERVER -24 + +#define CFE_ERR_NOHANDLES -25 +#define CFE_ERR_ALREADYBOUND -26 + +#define CFE_ERR_CANNOTSET -27 +#define CFE_ERR_NOMORE -28 +#define CFE_ERR_BADFILESYS -29 +#define CFE_ERR_FSNOTAVAIL -30 + +#define CFE_ERR_INVBOOTBLOCK -31 +#define CFE_ERR_WRONGDEVTYPE -32 +#define CFE_ERR_BBCHECKSUM -33 +#define CFE_ERR_BOOTPROGCHKSUM -34 + +#define CFE_ERR_LDRNOTAVAIL -35 + +#define CFE_ERR_NOTREADY -36 + +#define CFE_ERR_GETMEM -37 +#define CFE_ERR_SETMEM -38 + +#define CFE_ERR_NOTCONN -39 +#define CFE_ERR_ADDRINUSE -40 diff -Nru a/arch/mips/sibyte/cfe/console.c b/arch/mips/sibyte/cfe/console.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/console.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +#include <linux/init.h> +#include <linux/major.h> +#include <linux/errno.h> +#include <linux/console.h> + +#include <asm/sibyte/board.h> + +#include "cfe_api.h" +#include "cfe_error.h" + +extern int cfe_cons_handle; +static kdev_t cfe_consdev; + +#define SB1250_DUART_MINOR_BASE 192 + +static void cfe_console_write(struct console *cons, const char *str, + unsigned int count) +{ + int i, last, written; + + for (i=0,last=0; i<count; i++) { + if (!str[i]) + /* XXXKW can/should this ever happen? */ + return; + if (str[i] == '\n') { + do { + written = cfe_write(cfe_cons_handle, &str[last], i-last); + if (written < 0) + ; + last += written; + } while (last < i); + while (cfe_write(cfe_cons_handle, "\r", 1) <= 0) + ; + } + } + if (last != count) { + do { + written = cfe_write(cfe_cons_handle, &str[last], count-last); + if (written < 0) + ; + last += written; + } while (last < count); + } + +} + +static kdev_t cfe_console_device(struct console *c) +{ + return cfe_consdev; +} + +static int cfe_console_setup(struct console *cons, char *str) +{ + char consdev[32]; + /* XXXKW think about interaction with 'console=' cmdline arg */ + /* If none of the console options are configured, the build will break. */ + if (cfe_getenv("BOOT_CONSOLE", consdev, 32) >= 0) { +#ifdef CONFIG_SIBYTE_SB1250_DUART + if (!strcmp(consdev, "uart0")) { + setleds("u0cn"); + cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 0); +#ifndef CONFIG_SIBYTE_SB1250_DUART_NO_PORT_1 + } else if (!strcmp(consdev, "uart1")) { + setleds("u1cn"); + cfe_consdev = MKDEV(TTY_MAJOR, SB1250_DUART_MINOR_BASE + 1); +#endif +#endif +#ifdef CONFIG_VGA_CONSOLE + } else if (!strcmp(consdev, "pcconsole0")) { + setleds("pccn"); + cfe_consdev = MKDEV(TTY_MAJOR, 0); +#endif + } else + return -ENODEV; + } + return 0; +} + +static struct console sb1250_cfe_cons = { + name: "cfe", + write: cfe_console_write, + device: cfe_console_device, + setup: cfe_console_setup, + flags: CON_PRINTBUFFER, + index: -1, +}; + +void __init sb1250_cfe_console_init(void) +{ + register_console(&sb1250_cfe_cons); +} diff -Nru a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2000, 2001, 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/blk.h> +#include <linux/bootmem.h> +#include <linux/smp.h> + +#include <asm/bootinfo.h> +#include <asm/reboot.h> +#include <asm/sibyte/board.h> + +#include "cfe_api.h" +#include "cfe_error.h" + +/* Max ram addressable in 32-bit segments */ +#ifdef CONFIG_MIPS64 +#define MAX_RAM_SIZE (~0ULL) +#else +#ifdef CONFIG_HIGHMEM +#ifdef CONFIG_64BIT_PHYS_ADDR +#define MAX_RAM_SIZE (~0ULL) +#else +#define MAX_RAM_SIZE (0xffffffffULL) +#endif +#else +#define MAX_RAM_SIZE (0x1fffffffULL) +#endif +#endif + +#define SIBYTE_MAX_MEM_REGIONS 8 +phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; +phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; +unsigned int board_mem_region_count; + +/* This is the kernel command line. Actually, it's + copied, eventually, to command_line, and looks to be + quite redundant. But not something to fix just now */ +extern char arcs_cmdline[]; + +int cfe_cons_handle; + +#ifdef CONFIG_EMBEDDED_RAMDISK +/* These are symbols defined by the ramdisk linker script */ +extern unsigned char __rd_start; +extern unsigned char __rd_end; +#endif + +#ifdef CONFIG_SMP +static int reboot_smp = 0; +#endif + +static void cfe_linux_exit(void) +{ +#ifdef CONFIG_SMP + if (smp_processor_id()) { + if (reboot_smp) { + /* Don't repeat the process from another CPU */ + for (;;); + } else { + /* Get CPU 0 to do the cfe_exit */ + reboot_smp = 1; + smp_call_function((void *)_machine_restart, NULL, 1, 0); + for (;;); + } + } +#endif + printk("passing control back to CFE\n"); + cfe_exit(1, 0); + printk("cfe_exit returned??\n"); + while(1); +} + +static __init void prom_meminit(void) +{ + u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ + int mem_flags = 0; + unsigned int idx; + int rd_flag; +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long initrd_pstart; + unsigned long initrd_pend; + +#ifdef CONFIG_EMBEDDED_RAMDISK + /* If we're using an embedded ramdisk, then __rd_start and __rd_end + are defined by the linker to be on either side of the ramdisk + area. Otherwise, initrd_start should be defined by kernel command + line arguments */ + if (initrd_start == 0) { + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; + } +#endif + + initrd_pstart = CPHYSADDR(initrd_start); + initrd_pend = CPHYSADDR(initrd_end); + if (initrd_start && + ((initrd_pstart > MAX_RAM_SIZE) + || (initrd_pend > MAX_RAM_SIZE))) { + panic("initrd out of addressable memory"); + } + +#endif /* INITRD */ + + for (idx = 0; cfe_enummem(idx, mem_flags, &addr, &size, &type) != CFE_ERR_NOMORE; + idx++) { + rd_flag = 0; + if (type == CFE_MI_AVAILABLE) { + /* + * See if this block contains (any portion of) the + * ramdisk + */ +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + if ((initrd_pstart > addr) && + (initrd_pstart < (addr + size))) { + add_memory_region(addr, + initrd_pstart - addr, + BOOT_MEM_RAM); + rd_flag = 1; + } + if ((initrd_pend > addr) && + (initrd_pend < (addr + size))) { + add_memory_region(initrd_pend, + (addr + size) - initrd_pend, + BOOT_MEM_RAM); + rd_flag = 1; + } + } +#endif + if (!rd_flag) { + if (addr > MAX_RAM_SIZE) + continue; + if (addr+size > MAX_RAM_SIZE) + size = MAX_RAM_SIZE - (addr+size) + 1; + /* + * memcpy/__copy_user prefetch, which + * will cause a bus error for + * KSEG/KUSEG addrs not backed by RAM. + * Hence, reserve some padding for the + * prefetch distance. + */ + if (size > 512) + size -= 512; + add_memory_region(addr, size, BOOT_MEM_RAM); + } + board_mem_region_addrs[board_mem_region_count] = addr; + board_mem_region_sizes[board_mem_region_count] = size; + board_mem_region_count++; + if (board_mem_region_count == + SIBYTE_MAX_MEM_REGIONS) { + /* + * Too many regions. Need to configure more + */ + while(1); + } + } + } +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + add_memory_region(initrd_pstart, initrd_pend - initrd_pstart, + BOOT_MEM_RESERVED); + } +#endif +} + +#ifdef CONFIG_BLK_DEV_INITRD +static int __init initrd_setup(char *str) +{ + /* + *Initrd location comes in the form "<hex size of ramdisk in bytes>@<location in memory>" + * e.g. initrd=3abfd@80010000. This is set up by the loader. + */ + char *tmp, *endptr; + unsigned long initrd_size; + for (tmp = str; *tmp != '@'; tmp++) { + if (!*tmp) { + goto fail; + } + } + *tmp = 0; + tmp++; + if (!*tmp) { + goto fail; + } + initrd_size = simple_strtoul(str, &endptr, 16); + if (*endptr) { + *(tmp-1) = '@'; + goto fail; + } + *(tmp-1) = '@'; + initrd_start = simple_strtoul(tmp, &endptr, 16); + if (*endptr) { + goto fail; + } + initrd_end = initrd_start + initrd_size; + printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start); + return 1; + fail: + printk("Bad initrd argument. Disabling initrd\n"); + initrd_start = 0; + initrd_end = 0; + return 1; +} + +#endif + +/* + * prom_init is called just after the cpu type is determined, from init_arch() + */ +__init int prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + uint64_t cfe_ept, cfe_handle; + unsigned int cfe_eptseal; + + _machine_restart = (void (*)(char *))cfe_linux_exit; + _machine_halt = cfe_linux_exit; + _machine_power_off = cfe_linux_exit; + + /* + * Check if a loader was used; if NOT, the 4 arguments are + * what CFE gives us (handle, 0, EPT and EPTSEAL) + */ + if (argc < 0) { + cfe_handle = (uint64_t)(long)argc; + cfe_ept = (long)envp; + cfe_eptseal = (uint32_t)(unsigned long)prom_vec; + } else { + if ((int32_t)(long)prom_vec < 0) { + /* + * Old loader; all it gives us is the handle, + * so use the "known" entrypoint and assume + * the seal. + */ + cfe_handle = (uint64_t)(long)prom_vec; + cfe_ept = (uint64_t)((int32_t)0x9fc00500); + cfe_eptseal = CFE_EPTSEAL; + } else { + /* + * Newer loaders bundle the handle/ept/eptseal + * Note: prom_vec is in the loader's useg + * which is still alive in the TLB. + */ + cfe_handle = (uint64_t)((int32_t *)prom_vec)[0]; + cfe_ept = (uint64_t)((int32_t *)prom_vec)[2]; + cfe_eptseal = (unsigned int)((uint32_t *)prom_vec)[3]; + } + } + if (cfe_eptseal != CFE_EPTSEAL) { + /* XXXKW what? way too early to panic... */ + } + cfe_init(cfe_handle, cfe_ept); + /* + * Get the handle for (at least) prom_putchar, possibly for + * boot console + */ + cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); + if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) { + if (argc < 0) { + /* + * It's OK for direct boot to not provide a + * command line + */ + strcpy(arcs_cmdline, "root=/dev/ram0 "); +#ifdef CONFIG_SIBYTE_PTSWARM + strcat(arcs_cmdline, "console=ttyS0,115200 "); +#endif + } else { + /* The loader should have set the command line */ + panic("LINUX_CMDLINE not defined in cfe."); + } + } + +#ifdef CONFIG_BLK_DEV_INITRD + { + char *ptr; + /* Need to find out early whether we've got an initrd. So scan + the list looking now */ + for (ptr = arcs_cmdline; *ptr; ptr++) { + while (*ptr == ' ') { + ptr++; + } + if (!strncmp(ptr, "initrd=", 7)) { + initrd_setup(ptr+7); + break; + } else { + while (*ptr && (*ptr != ' ')) { + ptr++; + } + } + } + } +#endif /* CONFIG_BLK_DEV_INITRD */ + + /* Not sure this is needed, but it's the safe way. */ + arcs_cmdline[CL_SIZE-1] = 0; + + mips_machgroup = MACH_GROUP_SIBYTE; + prom_meminit(); + + return 0; +} + +void prom_free_prom_memory(void) +{ + /* Not sure what I'm supposed to do here. Nothing, I think */ +} + +int page_is_ram(unsigned long pagenr) +{ + phys_t addr = pagenr << PAGE_SHIFT; + int i; + for (i = 0; i < board_mem_region_count; i++) { + if ((addr >= board_mem_region_addrs[i]) + && (addr < (board_mem_region_addrs[i] + board_mem_region_sizes[i]))) { + return 1; + } + } + return 0; +} + +void prom_putchar(char c) +{ + int ret; + + while ((ret = cfe_write(cfe_cons_handle, &c, 1)) == 0) + ; +} diff -Nru a/arch/mips/sibyte/cfe/smp.c b/arch/mips/sibyte/cfe/smp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/cfe/smp.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/sched.h> +#include <linux/smp.h> + +#include <asm/mipsregs.h> + +#include "cfe_api.h" +#include "cfe_error.h" + +extern void asmlinkage smp_bootstrap(void); + +/* Boot all other cpus in the system, initialize them, and + bring them into the boot fn */ +int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp) +{ + int retval; + + retval = cfe_cpu_start(cpu, &smp_bootstrap, sp, gp, 0); + if (retval != 0) { + printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); + return 0; + } else { + return 1; + } +} + +void prom_init_secondary(void) +{ + /* Set up kseg0 to be cachable coherent */ + clear_c0_config(CONF_CM_CMASK); + set_c0_config(0x5); + + /* Enable interrupts for lines 0-4 */ + clear_c0_status(0xe000); + set_c0_status(0x1f01); +} + +/* + * Set up state, return the total number of cpus in the system, including + * the master + */ +void prom_setup_smp(void) +{ + int i; + + /* Use CFE to find out how many CPUs are available */ + for (i=1; i<NR_CPUS; i++) { + if (cfe_cpu_stop(i) == 0) { + CPUMASK_SETB(cpu_online_map, i); + } + } + printk("Detected %i available CPU(s)\n", num_online_cpus()); +} + +void prom_smp_finish(void) +{ + extern void sb1250_smp_finish(void); + sb1250_smp_finish(); +} diff -Nru a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,8 @@ +obj-y := setup.o irq.o irq_handler.o time.o + +obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o +obj-$(CONFIG_SIBYTE_STANDALONE) += prom.o +obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#define SBPROF_TB_DEBUG 0 + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/reboot.h> +#include <linux/devfs_fs_kernel.h> +#include <asm/uaccess.h> +#include <asm/smplock.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/64bit.h> +#include <asm/sibyte/trace_prof.h> + +static struct sbprof_tb sbp; + +#define TB_FULL (sbp.next_tb_sample == MAX_TB_SAMPLES) + +/************************************************************************ + * Support for ZBbus sampling using the trace buffer + * + * We use the SCD performance counter interrupt, caused by a Zclk counter + * overflow, to trigger the start of tracing. + * + * We set the trace buffer to sample everything and freeze on + * overflow. + * + * We map the interrupt for trace_buffer_freeze to handle it on CPU 0. + * + ************************************************************************/ + +/* 100 samples per second on a 500 Mhz 1250 (default) */ +static u_int64_t tb_period = 2500000ULL; + +static void arm_tb(void) +{ + u_int64_t scdperfcnt; + u_int64_t next = (1ULL << 40) - tb_period; + /* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to + trigger start of trace. XXX vary sampling period */ + out64(0, KSEG1 + A_SCD_PERF_CNT_1); + scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG); + /* Unfortunately, in Pass 2 we must clear all counters to knock down + a previous interrupt request. This means that bus profiling + requires ALL of the SCD perf counters. */ + out64((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is + M_SPC_CFG_ENABLE | // enable counting + M_SPC_CFG_CLEAR | // clear all counters + V_SPC_CFG_SRC1(1), // counter 1 counts cycles + KSEG1 + A_SCD_PERF_CNT_CFG); + out64(next, KSEG1 + A_SCD_PERF_CNT_1); + /* Reset the trace buffer */ + out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); + out64(M_SCD_TRACE_CFG_FREEZE_FULL +#if 0 && defined(M_SCD_TRACE_CFG_FORCECNT) + /* XXXKW may want to expose control to the data-collector */ + | M_SCD_TRACE_CFG_FORCECNT +#endif + , KSEG1 + A_SCD_TRACE_CFG); + sbp.tb_armed = 1; +} + +static void sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + int i; + DBG(printk(DEVNAME ": tb_intr\n")); + if (sbp.next_tb_sample < MAX_TB_SAMPLES) { + /* XXX should use XKPHYS to make writes bypass L2 */ + u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++]; + /* Read out trace */ + out64(M_SCD_TRACE_CFG_START_READ, KSEG1 + A_SCD_TRACE_CFG); + __asm__ __volatile__ ("sync" : : : "memory"); + /* Loop runs backwards because bundles are read out in reverse order */ + for (i = 256 * 6; i > 0; i -= 6) { + // Subscripts decrease to put bundle in the order + // t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi + p[i-1] = in64(KSEG1 + A_SCD_TRACE_READ); // read t2 hi + p[i-2] = in64(KSEG1 + A_SCD_TRACE_READ); // read t2 lo + p[i-3] = in64(KSEG1 + A_SCD_TRACE_READ); // read t1 hi + p[i-4] = in64(KSEG1 + A_SCD_TRACE_READ); // read t1 lo + p[i-5] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 hi + p[i-6] = in64(KSEG1 + A_SCD_TRACE_READ); // read t0 lo + } + if (!sbp.tb_enable) { + DBG(printk(DEVNAME ": tb_intr shutdown\n")); + out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); + sbp.tb_armed = 0; + wake_up(&sbp.tb_sync); + } else { + arm_tb(); // knock down current interrupt and get another one later + } + } else { + /* No more trace buffer samples */ + DBG(printk(DEVNAME ": tb_intr full\n")); + out64(M_SCD_TRACE_CFG_RESET, KSEG1 + A_SCD_TRACE_CFG); + sbp.tb_armed = 0; + if (!sbp.tb_enable) { + wake_up(&sbp.tb_sync); + } + wake_up(&sbp.tb_read); + } +} + +static void sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + printk(DEVNAME ": unexpected pc_intr"); +} + +static int sbprof_zbprof_start(struct file *filp) +{ + u_int64_t scdperfcnt; + + if (sbp.tb_enable) + return -EBUSY; + + DBG(printk(DEVNAME ": starting\n")); + + sbp.tb_enable = 1; + sbp.next_tb_sample = 0; + filp->f_pos = 0; + + if (request_irq + (K_INT_TRACE_FREEZE, sbprof_tb_intr, 0, DEVNAME " trace freeze", &sbp)) { + return -EBUSY; + } + /* Make sure there isn't a perf-cnt interrupt waiting */ + scdperfcnt = in64(KSEG1 + A_SCD_PERF_CNT_CFG); + /* Disable and clear counters, override SRC_1 */ + out64((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) | + M_SPC_CFG_ENABLE | + M_SPC_CFG_CLEAR | + V_SPC_CFG_SRC1(1), + KSEG1 + A_SCD_PERF_CNT_CFG); + + /* We grab this interrupt to prevent others from trying to use + it, even though we don't want to service the interrupts + (they only feed into the trace-on-interrupt mechanism) */ + if (request_irq + (K_INT_PERF_CNT, sbprof_pc_intr, 0, DEVNAME " scd perfcnt", &sbp)) { + free_irq(K_INT_TRACE_FREEZE, &sbp); + return -EBUSY; + } + + /* I need the core to mask these, but the interrupt mapper to + pass them through. I am exploiting my knowledge that + cp0_status masks out IP[5]. krw */ + out64(K_INT_MAP_I3, + KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_PERF_CNT<<3)); + + /* Initialize address traps */ + out64(0, KSEG1 + A_ADDR_TRAP_UP_0); + out64(0, KSEG1 + A_ADDR_TRAP_UP_1); + out64(0, KSEG1 + A_ADDR_TRAP_UP_2); + out64(0, KSEG1 + A_ADDR_TRAP_UP_3); + + out64(0, KSEG1 + A_ADDR_TRAP_DOWN_0); + out64(0, KSEG1 + A_ADDR_TRAP_DOWN_1); + out64(0, KSEG1 + A_ADDR_TRAP_DOWN_2); + out64(0, KSEG1 + A_ADDR_TRAP_DOWN_3); + + out64(0, KSEG1 + A_ADDR_TRAP_CFG_0); + out64(0, KSEG1 + A_ADDR_TRAP_CFG_1); + out64(0, KSEG1 + A_ADDR_TRAP_CFG_2); + out64(0, KSEG1 + A_ADDR_TRAP_CFG_3); + + /* Initialize Trace Event 0-7 */ + // when interrupt + out64(M_SCD_TREVT_INTERRUPT, KSEG1 + A_SCD_TRACE_EVENT_0); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_1); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_2); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_3); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_4); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_5); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_6); + out64(0, KSEG1 + A_SCD_TRACE_EVENT_7); + + /* Initialize Trace Sequence 0-7 */ + // Start on event 0 (interrupt) + out64(V_SCD_TRSEQ_FUNC_START|0x0fff, + KSEG1 + A_SCD_TRACE_SEQUENCE_0); + // dsamp when d used | asamp when a used + out64(M_SCD_TRSEQ_ASAMPLE|M_SCD_TRSEQ_DSAMPLE|K_SCD_TRSEQ_TRIGGER_ALL, + KSEG1 + A_SCD_TRACE_SEQUENCE_1); + out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_2); + out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_3); + out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_4); + out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_5); + out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_6); + out64(0, KSEG1 + A_SCD_TRACE_SEQUENCE_7); + + /* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */ + out64((1ULL << K_INT_PERF_CNT), KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)); + + arm_tb(); + + DBG(printk(DEVNAME ": done starting\n")); + + return 0; +} + +static int sbprof_zbprof_stop(void) +{ + DBG(printk(DEVNAME ": stopping\n")); + + if (sbp.tb_enable) { + sbp.tb_enable = 0; + /* XXXKW there is a window here where the intr handler + may run, see the disable, and do the wake_up before + this sleep happens. */ + if (sbp.tb_armed) { + DBG(printk(DEVNAME ": wait for disarm\n")); + interruptible_sleep_on(&sbp.tb_sync); + DBG(printk(DEVNAME ": disarm complete\n")); + } + free_irq(K_INT_TRACE_FREEZE, &sbp); + free_irq(K_INT_PERF_CNT, &sbp); + } + + DBG(printk(DEVNAME ": done stopping\n")); + + return 0; +} + +static int sbprof_tb_open(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor != 0) { + return -ENODEV; + } + if (sbp.open) { + return -EBUSY; + } + + memset(&sbp, 0, sizeof(struct sbprof_tb)); + sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); + if (!sbp.sbprof_tbbuf) { + return -ENOMEM; + } + memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); + init_waitqueue_head(&sbp.tb_sync); + init_waitqueue_head(&sbp.tb_read); + sbp.open = 1; + + return 0; +} + +static int sbprof_tb_release(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor != 0 || !sbp.open) { + return -ENODEV; + } + + if (sbp.tb_armed || sbp.tb_enable) { + sbprof_zbprof_stop(); + } + + vfree(sbp.sbprof_tbbuf); + sbp.open = 0; + + return 0; +} + +static ssize_t sbprof_tb_read(struct file *filp, char *buf, + size_t size, loff_t *offp) +{ + int cur_sample, sample_off, cur_count, sample_left; + char *src; + int count = 0; + char *dest = buf; + long cur_off = *offp; + + count = 0; + cur_sample = cur_off / TB_SAMPLE_SIZE; + sample_off = cur_off % TB_SAMPLE_SIZE; + sample_left = TB_SAMPLE_SIZE - sample_off; + while (size && (cur_sample < sbp.next_tb_sample)) { + cur_count = size < sample_left ? size : sample_left; + src = (char *)(((long)sbp.sbprof_tbbuf[cur_sample])+sample_off); + copy_to_user(dest, src, cur_count); + DBG(printk(DEVNAME ": read from sample %d, %d bytes\n", cur_sample, cur_count)); + size -= cur_count; + sample_left -= cur_count; + if (!sample_left) { + cur_sample++; + sample_off = 0; + sample_left = TB_SAMPLE_SIZE; + } else { + sample_off += cur_count; + } + cur_off += cur_count; + dest += cur_count; + count += cur_count; + } + *offp = cur_off; + + return count; +} + +static int sbprof_tb_ioctl(struct inode *inode, + struct file *filp, + unsigned int command, + unsigned long arg) +{ + int error = 0; + + switch (command) { + case SBPROF_ZBSTART: + error = sbprof_zbprof_start(filp); + break; + case SBPROF_ZBSTOP: + error = sbprof_zbprof_stop(); + break; + case SBPROF_ZBWAITFULL: + interruptible_sleep_on(&sbp.tb_read); + /* XXXKW check if interrupted? */ + return put_user(TB_FULL, (int *) arg); + default: + error = -EINVAL; + break; + } + + return error; +} + +static struct file_operations sbprof_tb_fops = { + .owner = THIS_MODULE, + .open = sbprof_tb_open, + .release = sbprof_tb_release, + .read = sbprof_tb_read, + .ioctl = sbprof_tb_ioctl, + .mmap = NULL, +}; + +static devfs_handle_t devfs_handle; + +#define UNDEF 0 +static unsigned long long pll_div_to_mhz[32] = { + UNDEF, + UNDEF, + UNDEF, + UNDEF, + 200, + 250, + 300, + 350, + 400, + 450, + 500, + 550, + 600, + 650, + 700, + 750, + 800, + 850, + 900, + 950, + 1000, + 1050, + 1100, + UNDEF, + UNDEF, + UNDEF, + UNDEF, + UNDEF, + UNDEF, + UNDEF, + UNDEF, + UNDEF +}; + +static int __init sbprof_tb_init(void) +{ + unsigned int pll_div; + + if (devfs_register_chrdev(SBPROF_TB_MAJOR, DEVNAME, &sbprof_tb_fops)) { + printk(KERN_WARNING DEVNAME ": initialization failed (dev %d)\n", + SBPROF_TB_MAJOR); + return -EIO; + } + devfs_handle = devfs_register(NULL, DEVNAME, + DEVFS_FL_DEFAULT, SBPROF_TB_MAJOR, 0, + S_IFCHR | S_IRUGO | S_IWUGO, + &sbprof_tb_fops, NULL); + sbp.open = 0; + pll_div = pll_div_to_mhz[G_SYS_PLL_DIV(in64(KSEG1 + A_SCD_SYSTEM_CFG))]; + if (pll_div != UNDEF) { + tb_period = (pll_div / 2) * 10000; + } else { + printk(KERN_INFO DEVNAME ": strange PLL divide\n"); + } + printk(KERN_INFO DEVNAME ": initialized - tb_period = %lld\n", tb_period); + return 0; +} + +static void __exit sbprof_tb_cleanup(void) +{ + devfs_unregister_chrdev(SBPROF_TB_MAJOR, DEVNAME); + devfs_unregister(devfs_handle); +} + +module_init(sbprof_tb_init); +module_exit(sbprof_tb_cleanup); diff -Nru a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/bus_watcher.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * The Bus Watcher monitors internal bus transactions and maintains + * counts of transactions with error status, logging details and + * causing one of several interrupts. This driver provides a handler + * for those interrupts which aggregates the counts (to avoid + * saturating the 8-bit counters) and provides a presence in + * /proc/bus_watcher if PROC_FS is on. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <asm/system.h> + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/64bit.h> + + +struct bw_stats_struct { + uint64_t status; + uint32_t l2_err; + uint32_t memio_err; + int status_printed; + unsigned long l2_cor_d; + unsigned long l2_bad_d; + unsigned long l2_cor_t; + unsigned long l2_bad_t; + unsigned long mem_cor_d; + unsigned long mem_bad_d; + unsigned long bus_error; +} bw_stats; + + +static void print_summary(uint32_t status, uint32_t l2_err, + uint32_t memio_err) +{ + printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + printk("\nLast recorded signature:\n"); + printk("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); +} + +/* + * check_bus_watcher is exported for use in situations where we want + * to see the most recent status of the bus watcher, which might have + * already been destructively read out of the registers. + * + * notes: this is currently used by the cache error handler + * should provide locking against the interrupt handler + */ +void check_bus_watcher(void) +{ + u32 status, l2_err, memio_err; + +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); +#else + /* Use non-destructive register */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS_DEBUG); +#endif + if (!(status & 0x7fffffff)) { + printk("Using last values reaped by bus watcher driver\n"); + status = bw_stats.status; + l2_err = bw_stats.l2_err; + memio_err = bw_stats.memio_err; + } else { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + } + if (status & ~(1UL << 31)) + print_summary(status, l2_err, memio_err); + else + printk("Bus watcher indicates no error\n"); +} + +static int bw_print_buffer(char *page, struct bw_stats_struct *stats) +{ + int len; + + len = sprintf(page, "SiByte Bus Watcher statistics\n"); + len += sprintf(page+len, "-----------------------------\n"); + len += sprintf(page+len, "L2-d-cor %8ld\nL2-d-bad %8ld\n", + stats->l2_cor_d, stats->l2_bad_d); + len += sprintf(page+len, "L2-t-cor %8ld\nL2-t-bad %8ld\n", + stats->l2_cor_t, stats->l2_bad_t); + len += sprintf(page+len, "MC-d-cor %8ld\nMC-d-bad %8ld\n", + stats->mem_cor_d, stats->mem_bad_d); + len += sprintf(page+len, "IO-err %8ld\n", stats->bus_error); + len += sprintf(page+len, "\nLast recorded signature:\n"); + len += sprintf(page+len, "Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(stats->status) & 0x3f), + (int)(G_SCD_BERR_TID(stats->status) >> 6), + (int)G_SCD_BERR_RID(stats->status), + (int)G_SCD_BERR_DCODE(stats->status)); + /* XXXKW indicate multiple errors between printings, or stats + collection (or both)? */ + if (stats->status & M_SCD_BERR_MULTERRS) + len += sprintf(page+len, "Multiple errors observed since last check.\n"); + if (stats->status_printed) { + len += sprintf(page+len, "(no change since last printing)\n"); + } else { + stats->status_printed = 1; + } + + return len; +} + +#ifdef CONFIG_PROC_FS + +/* For simplicity, I want to assume a single read is required each + time */ +static int bw_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + if (off == 0) { + len = bw_print_buffer(page, data); + *start = page; + } else { + len = 0; + *eof = 1; + } + return len; +} + +static void create_proc_decoder(struct bw_stats_struct *stats) +{ + struct proc_dir_entry *ent; + + ent = create_proc_read_entry("bus_watcher", S_IWUSR | S_IRUGO, NULL, + bw_read_proc, stats); + if (!ent) { + printk(KERN_INFO "Unable to initialize bus_watcher /proc entry\n"); + return; + } +} + +#endif /* CONFIG_PROC_FS */ + +/* + * sibyte_bw_int - handle bus watcher interrupts and accumulate counts + * + * notes: possible re-entry due to multiple sources + * should check/indicate saturation + */ +static void sibyte_bw_int(int irq, void *data, struct pt_regs *regs) +{ + struct bw_stats_struct *stats = data; + unsigned long cntr; +#ifndef CONFIG_PROC_FS + char bw_buf[1024]; +#endif + + /* Destructive read, clears register and interrupt */ + stats->status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + stats->status_printed = 0; + + stats->l2_err = cntr = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + stats->l2_cor_d += G_SCD_L2ECC_CORR_D(cntr); + stats->l2_bad_d += G_SCD_L2ECC_BAD_D(cntr); + stats->l2_cor_t += G_SCD_L2ECC_CORR_T(cntr); + stats->l2_bad_t += G_SCD_L2ECC_BAD_T(cntr); + csr_out32(0, IO_SPACE_BASE | A_BUS_L2_ERRORS); + + stats->memio_err = cntr = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + stats->mem_cor_d += G_SCD_MEM_ECC_CORR(cntr); + stats->mem_bad_d += G_SCD_MEM_ECC_BAD(cntr); + stats->bus_error += G_SCD_MEM_BUSERR(cntr); + csr_out32(0, IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + +#ifndef CONFIG_PROC_FS + bw_print_buffer(bw_buf, stats); + printk(bw_buf); +#endif +} + +int __init sibyte_bus_watcher(void) +{ + memset(&bw_stats, 0, sizeof(struct bw_stats_struct)); + bw_stats.status_printed = 1; + + if (request_irq(K_INT_BAD_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + printk("Failed to register bus watcher BAD_ECC irq\n"); + return -1; + } + if (request_irq(K_INT_COR_ECC, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + free_irq(K_INT_BAD_ECC, &bw_stats); + printk("Failed to register bus watcher COR_ECC irq\n"); + return -1; + } + if (request_irq(K_INT_IO_BUS, sibyte_bw_int, 0, "Bus watcher", &bw_stats)) { + free_irq(K_INT_BAD_ECC, &bw_stats); + free_irq(K_INT_COR_ECC, &bw_stats); + printk("Failed to register bus watcher IO_BUS irq\n"); + return -1; + } + +#ifdef CONFIG_PROC_FS + create_proc_decoder(&bw_stats); +#endif + + return 0; +} + +__initcall(sibyte_bus_watcher); diff -Nru a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/linkage.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/mm.h> +#include <linux/slab.h> + +#include <asm/errno.h> +#include <asm/signal.h> +#include <asm/system.h> +#include <asm/ptrace.h> + +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/sb1250_uart.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/64bit.h> + +/* + * These are the routines that handle all the low level interrupt stuff. + * Actions handled here are: initialization of the interrupt map, requesting of + * interrupt lines by handlers, dispatching if interrupts to handlers, probing + * for interrupt lines + */ + + +#define shutdown_sb1250_irq disable_sb1250_irq +static void end_sb1250_irq(unsigned int irq); +static void enable_sb1250_irq(unsigned int irq); +static void disable_sb1250_irq(unsigned int irq); +static unsigned int startup_sb1250_irq(unsigned int irq); +static void ack_sb1250_irq(unsigned int irq); +#ifdef CONFIG_SMP +static void sb1250_set_affinity(unsigned int irq, unsigned long mask); +#endif + +#ifdef CONFIG_SIBYTE_HAS_LDT +extern unsigned long ldt_eoi_space; +#endif + +#ifdef CONFIG_KGDB +extern void breakpoint(void); +extern void set_debug_traps(void); + +/* kgdb is on when configured. Pass "nokgdb" kernel arg to turn it off */ +static int kgdb_flag = 1; +static int __init nokgdb(char *str) +{ + kgdb_flag = 0; +} +__setup("nokgdb", nokgdb); +#endif + +static struct hw_interrupt_type sb1250_irq_type = { + "SB1250-IMR", + startup_sb1250_irq, + shutdown_sb1250_irq, + enable_sb1250_irq, + disable_sb1250_irq, + ack_sb1250_irq, + end_sb1250_irq, +#ifdef CONFIG_SMP + sb1250_set_affinity +#else + NULL +#endif +}; + +/* Store the CPU id (not the logical number) */ +int sb1250_irq_owner[SB1250_NR_IRQS]; + +spinlock_t sb1250_imr_lock = SPIN_LOCK_UNLOCKED; + +void sb1250_mask_irq(int cpu, int irq) +{ + unsigned long flags; + u64 cur_ints; + + spin_lock_irqsave(&sb1250_imr_lock, flags); + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints |= (((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + spin_unlock_irqrestore(&sb1250_imr_lock, flags); +} + +void sb1250_unmask_irq(int cpu, int irq) +{ + unsigned long flags; + u64 cur_ints; + + spin_lock_irqsave(&sb1250_imr_lock, flags); + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints &= ~(((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + spin_unlock_irqrestore(&sb1250_imr_lock, flags); +} + +#ifdef CONFIG_SMP +static void sb1250_set_affinity(unsigned int irq, unsigned long mask) +{ + int i = 0, old_cpu, cpu, int_on; + u64 cur_ints; + irq_desc_t *desc = irq_desc + irq; + unsigned int flags; + + while (mask) { + if (mask & 1) { + mask >>= 1; + break; + } + mask >>= 1; + i++; + } + + if (mask) { + printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); + return; + } + + /* Convert logical CPU to physical CPU */ + cpu = cpu_logical_map(i); + + /* Protect against other affinity changers and IMR manipulation */ + spin_lock_irqsave(&desc->lock, flags); + spin_lock(&sb1250_imr_lock); + + /* Swizzle each CPU's IMR (but leave the IP selection alone) */ + old_cpu = sb1250_irq_owner[irq]; + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK); + int_on = !(cur_ints & (((u64) 1) << irq)); + if (int_on) { + /* If it was on, mask it */ + cur_ints |= (((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK); + } + sb1250_irq_owner[irq] = cpu; + if (int_on) { + /* unmask for the new CPU */ + cur_ints = __in64(KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + cur_ints &= ~(((u64) 1) << irq); + __out64(cur_ints, KSEG1 + A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK); + } + spin_unlock(&sb1250_imr_lock); + spin_unlock_irqrestore(&desc->lock, flags); +} +#endif + + +/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */ +extern void sb1250_irq_handler(void); + +/*****************************************************************************/ + +static unsigned int startup_sb1250_irq(unsigned int irq) +{ + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); + + return 0; /* never anything pending */ +} + + +static void disable_sb1250_irq(unsigned int irq) +{ + sb1250_mask_irq(sb1250_irq_owner[irq], irq); +} + +static void enable_sb1250_irq(unsigned int irq) +{ + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); +} + + +static void ack_sb1250_irq(unsigned int irq) +{ +#ifdef CONFIG_SIBYTE_HAS_LDT + u64 pending; + + /* + * If the interrupt was an HT interrupt, now is the time to + * clear it. NOTE: we assume the HT bridge was set up to + * deliver the interrupts to all CPUs (which makes affinity + * changing easier for us) + */ + pending = in64(KSEG1 + A_IMR_REGISTER(sb1250_irq_owner[irq], + R_IMR_LDT_INTERRUPT)); + pending &= ((u64)1 << (irq)); + if (pending) { + int i; + for (i=0; i<smp_num_cpus; i++) { + /* + * Clear for all CPUs so an affinity switch + * doesn't find an old status + */ + out64(pending, + KSEG1+A_IMR_REGISTER(cpu_logical_map(i), + R_IMR_LDT_INTERRUPT_CLR)); + } + + /* + * Generate EOI. For Pass 1 parts, EOI is a nop. For + * Pass 2, the LDT world may be edge-triggered, but + * this EOI shouldn't hurt. If they are + * level-sensitive, the EOI is required. + */ + *(uint32_t *)(ldt_eoi_space+(irq<<16)+(7<<2)) = 0; + } +#endif + sb1250_mask_irq(sb1250_irq_owner[irq], irq); +} + + +static void end_sb1250_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + sb1250_unmask_irq(sb1250_irq_owner[irq], irq); + } +} + + +void __init init_sb1250_irqs(void) +{ + int i; + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + if (i < SB1250_NR_IRQS) { + irq_desc[i].handler = &sb1250_irq_type; + sb1250_irq_owner[i] = 0; + } else { + irq_desc[i].handler = &no_irq_type; + } + } +} + + +static irqreturn_t sb1250_dummy_handler(int irq, void *dev_id, + struct pt_regs *regs) +{ + return IRQ_NONE; +} + +static struct irqaction sb1250_dummy_action = { + .handler = sb1250_dummy_handler, + .flags = 0, + .mask = 0, + .name = "sb1250-private", + .next = NULL, + .dev_id = 0 +}; + +int sb1250_steal_irq(int irq) +{ + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + int retval = 0; + + if (irq >= SB1250_NR_IRQS) + return -EINVAL; + + spin_lock_irqsave(&desc->lock,flags); + /* Don't allow sharing at all for these */ + if (desc->action != NULL) + retval = -EBUSY; + else { + desc->action = &sb1250_dummy_action; + desc->depth = 0; + } + spin_unlock_irqrestore(&desc->lock,flags); + return 0; +} + +/* + * init_IRQ is called early in the boot sequence from init/main.c. It + * is responsible for setting up the interrupt mapper and installing the + * handler that will be responsible for dispatching interrupts to the + * "right" place. + */ +/* + * For now, map all interrupts to IP[2]. We could save + * some cycles by parceling out system interrupts to different + * IP lines, but keep it simple for bringup. We'll also direct + * all interrupts to a single CPU; we should probably route + * PCI and LDT to one cpu and everything else to the other + * to balance the load a bit. + * + * On the second cpu, everything is set to IP5, which is + * ignored, EXCEPT the mailbox interrupt. That one is + * set to IP[2] so it is handled. This is needed so we + * can do cross-cpu function calls, as requred by SMP + */ + +#define IMR_IP2_VAL K_INT_MAP_I0 +#define IMR_IP3_VAL K_INT_MAP_I1 +#define IMR_IP4_VAL K_INT_MAP_I2 +#define IMR_IP5_VAL K_INT_MAP_I3 +#define IMR_IP6_VAL K_INT_MAP_I4 + +void __init init_IRQ(void) +{ + + unsigned int i; + u64 tmp; + unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 | + STATUSF_IP1 | STATUSF_IP0; + + /* Default everything to IP2 */ + for (i = 0; i < SB1250_NR_IRQS; i++) { /* was I0 */ + out64(IMR_IP2_VAL, + KSEG1 + A_IMR_REGISTER(0, + R_IMR_INTERRUPT_MAP_BASE) + + (i << 3)); + out64(IMR_IP2_VAL, + KSEG1 + A_IMR_REGISTER(1, + R_IMR_INTERRUPT_MAP_BASE) + + (i << 3)); + } + + init_sb1250_irqs(); + + /* + * Map the high 16 bits of the mailbox registers to IP[3], for + * inter-cpu messages + */ + /* Was I1 */ + out64(IMR_IP3_VAL, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + + (K_INT_MBOX_0 << 3)); + out64(IMR_IP3_VAL, KSEG1 + A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) + + (K_INT_MBOX_0 << 3)); + + /* Clear the mailboxes. The firmware may leave them dirty */ + out64(0xffffffffffffffff, + KSEG1 + A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)); + out64(0xffffffffffffffff, + KSEG1 + A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)); + + /* Mask everything except the mailbox registers for both cpus */ + tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0); + out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)); + out64(tmp, KSEG1 + A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)); + + sb1250_steal_irq(K_INT_MBOX_0); + + /* + * Note that the timer interrupts are also mapped, but this is + * done in sb1250_time_init() + */ + +#ifdef CONFIG_BCM1250_PROF + imask |= STATUSF_IP7; +#endif +#ifdef CONFIG_KGDB + imask |= STATUSF_IP6; +#endif + /* Enable necessary IPs, disable the rest */ + change_c0_status(ST0_IM, imask); + set_except_vector(0, sb1250_irq_handler); + +#ifdef CONFIG_KGDB + if (kgdb_flag) { + /* Setup uart 1 settings, mapper */ + out64(M_DUART_IMR_BRK, KSEG1 + A_DUART + R_DUART_IMR_B); + + out64(IMR_IP6_VAL, + KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_UART_1<<3)); + tmp = in64(KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)); + tmp &= ~(1<<K_INT_UART_1); + out64(tmp, KSEG1 + A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)); + + set_debug_traps(); + breakpoint(); + } +#endif +} + +#ifdef CONFIG_KGDB + +#include <linux/delay.h> + +extern void set_async_breakpoint(unsigned int epc); + +#define duart_out(reg, val) out64(val, KSEG1 + A_DUART_CHANREG(1,reg)) +#define duart_in(reg) in64(KSEG1 + A_DUART_CHANREG(1,reg)) + +void sb1250_kgdb_interrupt(struct pt_regs *regs) +{ + /* + * Clear break-change status (allow some time for the remote + * host to stop the break, since we would see another + * interrupt on the end-of-break too) + */ + mdelay(500); + duart_out(R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT | + M_DUART_RX_EN | M_DUART_TX_EN); + if (!user_mode(regs)) + set_async_breakpoint(regs->cp0_epc); +} +#endif /* CONFIG_KGDB */ diff -Nru a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/irq_handler.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * sb1250_handle_int() is the routine that is actually called when an interrupt + * occurs. It is installed as the exception vector handler in init_IRQ() in + * arch/mips/sibyte/sb1250/irq.c + * + * In the handle we figure out which interrupts need handling, and use that to + * call the dispatcher, which will take care of actually calling registered + * handlers + * + * Note that we take care of all raised interrupts in one go at the handler. + * This is more BSDish than the Indy code, and also, IMHO, more sane. + */ +#include <linux/config.h> + +#include <asm/addrspace.h> +#include <asm/processor.h> +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/sibyte/sb1250_defs.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> + +/* + * What a pain. We have to be really careful saving the upper 32 bits of any + * register across function calls if we don't want them trashed--since were + * running in -o32, the calling routing never saves the full 64 bits of a + * register across a function call. Being the interrupt handler, we're + * guaranteed that interrupts are disabled during this code so we don't have + * to worry about random interrupts blasting the high 32 bits. + */ + + .text + .set push + .set noreorder + .set noat + #.set mips64 + .set mips4 + .align 5 + NESTED(sb1250_irq_handler, PT_SIZE, sp) + SAVE_ALL + CLI + +#ifdef CONFIG_SIBYTE_SB1250_PROF + /* Set compare to count to silence count/compare timer interrupts */ + mfc0 t1, CP0_COUNT + mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ +#endif + /* Read cause */ + mfc0 s0, CP0_CAUSE + +#ifdef CONFIG_SIBYTE_SB1250_PROF + /* Cpu performance counter interrupt is routed to IP[7] */ + andi t1, s0, CAUSEF_IP7 + beqz t1, 0f + srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ + and t1, t1, 0x4 /* mask to get just BD bit */ + mfc0 a0, CP0_EPC + jal sbprof_cpu_intr + addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ + /* Re-enable interrupts here so that events due to sbprof_cpu_intr + get charged to ret_from_irq (via a recursive interrupt) + rather than the restart pc. */ + mfc0 t0, CP0_STATUS + or t0, ST0_IE + j ret_from_irq + mtc0 t0, CP0_STATUS # delay slot +0: +#endif + /* Timer interrupt is routed to IP[4] */ + andi t1, s0, CAUSEF_IP4 + beqz t1, 1f + nop + jal sb1250_timer_interrupt + move a0, sp /* Pass the registers along */ + j ret_from_irq + nop # delay slot +1: + +#ifdef CONFIG_SMP + /* Mailbox interrupt is routed to IP[3] */ + andi t1, s0, CAUSEF_IP3 + beqz t1, 2f + nop + jal sb1250_mailbox_interrupt + move a0, sp + j ret_from_irq + nop # delay slot +2: +#endif + +#ifdef CONFIG_KGDB + /* KGDB (uart 1) interrupt is routed to IP[6] */ + andi t1, s0, CAUSEF_IP6 + beqz t1, 1f + nop # delay slot + jal sb1250_kgdb_interrupt + move a0, sp + j ret_from_irq + nop # delay slot +1: +#endif + + and t1, s0, CAUSEF_IP2 + beqz t1, 4f + nop + + /* + * Default...we've hit an IP[2] interrupt, which means we've got to + * check the 1250 interrupt registers to figure out what to do + * Need to detect which CPU we're on, now that smp_affinity is supported. + */ + la v0, KSEG1 + A_IMR_CPU0_BASE +#ifdef CONFIG_SMP + lw t1, TI_CPU($28) + sll t1, IMR_REGISTER_SPACING_SHIFT + addu v0, t1 +#endif + ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */ + + beqz s0, 4f /* No interrupts. Return */ + move a1, sp + +3: #dclz s1, s0 /* Find the next interrupt */ + .word 0x72118824 # dclz s1, s0 + dsubu a0, zero, s1 + daddiu a0, a0, 63 + jal do_IRQ + nop + +4: j ret_from_irq + nop + + .set pop + END(sb1250_irq_handler) diff -Nru a/arch/mips/sibyte/sb1250/prom.c b/arch/mips/sibyte/sb1250/prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/prom.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/blk.h> +#include <linux/bootmem.h> +#include <linux/smp.h> + +#include <asm/bootinfo.h> +#include <asm/reboot.h> + +extern char arcs_cmdline[]; + +#ifdef CONFIG_EMBEDDED_RAMDISK +/* These are symbols defined by the ramdisk linker script */ +extern unsigned char __rd_start; +extern unsigned char __rd_end; +#endif + +#define MAX_RAM_SIZE ((CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - 1) + +static __init void prom_meminit(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long initrd_pstart; + unsigned long initrd_pend; + +#ifdef CONFIG_EMBEDDED_RAMDISK + /* If we're using an embedded ramdisk, then __rd_start and __rd_end + are defined by the linker to be on either side of the ramdisk + area. Otherwise, initrd_start should be defined by kernel command + line arguments */ + if (initrd_start == 0) { + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; + } +#endif + + initrd_pstart = __pa(initrd_start); + initrd_pend = __pa(initrd_end); + if (initrd_start && + ((initrd_pstart > MAX_RAM_SIZE) + || (initrd_pend > MAX_RAM_SIZE))) { + panic("initrd out of addressable memory"); + } + + add_memory_region(0, initrd_pstart, + BOOT_MEM_RAM); + add_memory_region(initrd_pstart, initrd_pend - initrd_pstart, + BOOT_MEM_RESERVED); + add_memory_region(initrd_pend, + (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024) - initrd_pend, + BOOT_MEM_RAM); +#else + add_memory_region(0, CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024, + BOOT_MEM_RAM); +#endif +} + +void prom_cpu0_exit(void *unused) +{ + while (1) ; +} + +static void prom_linux_exit(void) +{ +#ifdef CONFIG_SMP + if (smp_processor_id()) { + smp_call_function(prom_cpu0_exit,NULL,1,1); + } +#endif + while(1); +} + +/* + * prom_init is called just after the cpu type is determined, from init_arch() + */ +__init int prom_init(int argc, char **argv, char **envp, int *prom_vec) +{ + _machine_restart = (void (*)(char *))prom_linux_exit; + _machine_halt = prom_linux_exit; + _machine_power_off = prom_linux_exit; + + strcpy(arcs_cmdline, "root=/dev/ram0 "); + + mips_machgroup = MACH_GROUP_SIBYTE; + prom_meminit(); + + return 0; +} + +void prom_free_prom_memory(void) +{ + /* Not sure what I'm supposed to do here. Nothing, I think */ +} + +int page_is_ram(unsigned long pagenr) +{ + phys_t addr = pagenr << PAGE_SHIFT; + return (addr < (CONFIG_SIBYTE_STANDALONE_RAM_SIZE * 1024 * 1024)); +} + +void prom_putchar(char c) +{ +} diff -Nru a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/kernel.h> +#include <linux/reboot.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> +#include <asm/mipsregs.h> +#include <asm/io.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/64bit.h> + +unsigned int sb1_pass; +unsigned int soc_pass; +unsigned int soc_type; +unsigned int periph_rev; + +static char *soc_str; +static char *pass_str; +static unsigned int war_pass; /* XXXKW don't overload PASS defines? */ + +static inline int setup_bcm1250(void); +static inline int setup_bcm112x(void); + +/* Setup code likely to be common to all SiByte platforms */ + +static inline int sys_rev_decode(void) +{ + int ret = 0; + + war_pass = soc_pass; + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + case K_SYS_SOC_TYPE_BCM1250_ALT2: + soc_str = "BCM1250"; + ret = setup_bcm1250(); + break; + case K_SYS_SOC_TYPE_BCM1120: + soc_str = "BCM1120"; + ret = setup_bcm112x(); + break; + case K_SYS_SOC_TYPE_BCM1125: + soc_str = "BCM1125"; + ret = setup_bcm112x(); + break; + case K_SYS_SOC_TYPE_BCM1125H: + soc_str = "BCM1125H"; + ret = setup_bcm112x(); + break; + default: + prom_printf("Unknown SOC type %x\n", soc_type); + ret = 1; + break; + } + return ret; +} + +static inline int setup_bcm1250(void) +{ + int ret = 0; + + switch (soc_pass) { + case K_SYS_REVISION_BCM1250_PASS1: + periph_rev = 1; + pass_str = "Pass 1"; + break; + case K_SYS_REVISION_BCM1250_A10: + periph_rev = 2; + pass_str = "A8/A10"; + /* XXXKW different war_pass? */ + war_pass = K_SYS_REVISION_BCM1250_PASS2; + break; + case K_SYS_REVISION_BCM1250_PASS2_2: + periph_rev = 2; + pass_str = "B1"; + break; + case K_SYS_REVISION_BCM1250_B2: + periph_rev = 2; + pass_str = "B2"; + war_pass = K_SYS_REVISION_BCM1250_PASS2_2; + break; + case K_SYS_REVISION_BCM1250_PASS3: + periph_rev = 3; + pass_str = "C0"; + break; + default: + if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) { + periph_rev = 2; + pass_str = "A0-A6"; + war_pass = K_SYS_REVISION_BCM1250_PASS2; + } else { + prom_printf("Unknown BCM1250 rev %x\n", soc_pass); + ret = 1; + } + break; + } + return ret; +} + +static inline int setup_bcm112x(void) +{ + int ret = 0; + + switch (soc_pass) { + case 0: + /* Early build didn't have revid set */ + periph_rev = 3; + pass_str = "A1"; + war_pass = K_SYS_REVISION_BCM112x_A1; + break; + case K_SYS_REVISION_BCM112x_A1: + periph_rev = 3; + pass_str = "A1"; + break; + case K_SYS_REVISION_BCM112x_A2: + periph_rev = 3; + pass_str = "A2"; + break; + default: + prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); + ret = 1; + } + return ret; +} + +void sb1250_setup(void) +{ + uint64_t sys_rev; + int bad_config = 0; + + sb1_pass = read_c0_prid() & 0xff; + sys_rev = in64(IO_SPACE_BASE | A_SCD_SYSTEM_REVISION); + soc_type = SYS_SOC_TYPE(sys_rev); + soc_pass = G_SYS_REVISION(sys_rev); + + if (sys_rev_decode()) { + prom_printf("Restart after failure to identify SiByte chip\n"); + machine_restart(NULL); + } + + prom_printf("SiByte %s %s (SB1 rev %d)\n", + soc_str, pass_str, sb1_pass); + prom_printf("Board type: %s\n", get_system_type()); + + switch(war_pass) { + case K_SYS_REVISION_BCM1250_PASS1: +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif + break; + case K_SYS_REVISION_BCM1250_PASS2: + /* Pass 2 - easiest as default for now - so many numbers */ +#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) + prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif +#ifdef CONFIG_CPU_HAS_PREFETCH + prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board. @@@@\n"); + bad_config = 1; +#endif + break; + case K_SYS_REVISION_BCM1250_PASS2_2: +#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS + prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); + bad_config = 1; +#endif +#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH) + prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n"); +#endif + break; + default: + break; + } + if (bad_config) { + prom_printf("Invalid configuration for this chip.\n"); + machine_restart(NULL); + } +} diff -Nru a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/smp.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/smp.h> +#include <linux/kernel_stat.h> + +#include <asm/mmu_context.h> +#include <asm/sibyte/64bit.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> + +extern irqreturn_t smp_call_function_interrupt(int irq, void *dev, + struct pt_regs *regs); +extern void smp_tune_scheduling(void); + +/* + * These are routines for dealing with the sb1250 smp capabilities + * independent of board/firmware + */ + +static u64 mailbox_set_regs[] = { + KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_SET_CPU, + KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_SET_CPU +}; + +static u64 mailbox_clear_regs[] = { + KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CLR_CPU, + KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CLR_CPU +}; + +static u64 mailbox_regs[] = { + KSEG1 + A_IMR_CPU0_BASE + R_IMR_MAILBOX_CPU, + KSEG1 + A_IMR_CPU1_BASE + R_IMR_MAILBOX_CPU +}; + + +/* + * Simple enough; everything is set up, so just poke the appropriate mailbox + * register, and we should be set + */ +void core_send_ipi(int cpu, unsigned int action) +{ + out64((((u64)action)<< 48), mailbox_set_regs[cpu]); +} + + +void sb1250_smp_finish(void) +{ + extern void sb1_sanitize_tlb(void); + + sb1_sanitize_tlb(); + sb1250_time_init(); +} + +void sb1250_mailbox_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + unsigned int action; + + kstat_cpu(cpu).irqs[K_INT_MBOX_0]++; + /* Load the mailbox register to figure out what we're supposed to do */ + action = (in64(mailbox_regs[cpu]) >> 48) & 0xffff; + + /* Clear the mailbox to clear the interrupt */ + out64(((u64)action)<<48, mailbox_clear_regs[cpu]); + + /* + * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the + * interrupt will do the reschedule for us + */ + + if (action & SMP_CALL_FUNCTION) { + smp_call_function_interrupt(0, NULL, regs); + } +} + +extern atomic_t cpus_booted; +extern void prom_setup_smp(void); +extern int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); + +void __init smp_boot_cpus(void) +{ + int cur_cpu = 0; + int cpu; + + prom_setup_smp(); + init_new_context(current, &init_mm); + current_thread_info()->cpu = 0; + cpu_data[0].udelay_val = loops_per_jiffy; + cpu_data[0].asid_cache = ASID_FIRST_VERSION; + CPUMASK_CLRALL(cpu_online_map); + CPUMASK_SETB(cpu_online_map, 0); + atomic_set(&cpus_booted, 1); /* Master CPU is already booted... */ + smp_tune_scheduling(); + + /* + * This loop attempts to compensate for "holes" in the CPU + * numbering. It's overkill, but general. + */ + for (cpu = 1; cpu < num_online_cpus(); ) { + struct task_struct *idle; + struct pt_regs regs; + int retval; + printk("Starting CPU %d... ", cpu); + + /* Spawn a new process normally. Grab a pointer to + its task struct so we can mess with it */ + idle = copy_process(CLONE_VM | CLONE_IDLETASK, 0, ®s, 0, + NULL, NULL); + if (IS_ERR(idle)) + panic("failed fork for CPU %d", cpu); + + /* + * We remove it from the pidhash and the runqueue + * once we got the process: + */ + init_idle(idle, cpu); + + unhash_process(idle); + + do { + /* Iterate until we find a CPU that comes up */ + cur_cpu++; + retval = prom_boot_secondary(cur_cpu, + (unsigned long)idle + KERNEL_STACK_SIZE - 32, + (unsigned long)idle); + } while (!retval && (cur_cpu < NR_CPUS)); + if (retval) { + cpu++; + } else { + panic("CPU discovery disaster"); + } + } + + /* Wait for everyone to come up */ + while (atomic_read(&cpus_booted) != num_online_cpus()); + smp_threads_ready = 1; +} diff -Nru a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/sb1250/time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * These are routines to set up and handle interrupts from the + * sb1250 general purpose timer 0. We're using the timer as a + * system clock, so we set it up to run at 100 Hz. On every + * interrupt, we update our idea of what the time of day is, + * then call do_timer() in the architecture-independent kernel + * code to do general bookkeeping (e.g. update jiffies, run + * bottom halves, etc.) + */ +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/kernel_stat.h> + +#include <asm/irq.h> +#include <asm/ptrace.h> +#include <asm/addrspace.h> +#include <asm/time.h> + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/64bit.h> + + +#define IMR_IP2_VAL K_INT_MAP_I0 +#define IMR_IP3_VAL K_INT_MAP_I1 +#define IMR_IP4_VAL K_INT_MAP_I2 + +extern int sb1250_steal_irq(int irq); + +void sb1250_time_init(void) +{ + int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0+cpu; + + /* Only have 4 general purpose timers */ + if (cpu > 3) { + BUG(); + } + + if (!cpu) { + /* Use our own gettimeoffset() routine */ + do_gettimeoffset = sb1250_gettimeoffset; + } + + sb1250_mask_irq(cpu, irq); + + /* Map the timer interrupt to ip[4] of this cpu */ + out64(IMR_IP4_VAL, KSEG1 + A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) + + (irq<<3)); + + /* the general purpose timer ticks at 1 Mhz independent if the rest of the system */ + /* Disable the timer and set up the count */ + out64(0, KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + out64( +#ifndef CONFIG_SIMULATION + 1000000/HZ +#else + 50000/HZ +#endif + , KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + /* Set the timer running */ + out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, + KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + + sb1250_unmask_irq(cpu, irq); + sb1250_steal_irq(irq); + /* + * This interrupt is "special" in that it doesn't use the request_irq + * way to hook the irq line. The timer interrupt is initialized early + * enough to make this a major pain, and it's also firing enough to + * warrant a bit of special case code. sb1250_timer_interrupt is + * called directly from irq_handler.S when IP[4] is set during an + * interrupt + */ +} + +void sb1250_timer_interrupt(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0 + cpu; + + kstat_cpu(cpu).irqs[irq]++; + /* Reset the timer */ + out64(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, + KSEG1 + A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + + /* + * CPU 0 handles the global timer interrupt job + */ + if (cpu == 0) { + ll_timer_interrupt(irq, regs); + } + + /* + * every CPU should do profiling and process accouting + */ + ll_local_timer_interrupt(irq, regs); +} + +/* + * We use our own do_gettimeoffset() instead of the generic one, + * because the generic one does not work for SMP case. + * In addition, since we use general timer 0 for system time, + * we can get accurate intra-jiffy offset without calibration. + */ +unsigned long sb1250_gettimeoffset(void) +{ + unsigned long count = + in64(KSEG1 + A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)); + + return 1000000/HZ - count; + } diff -Nru a/arch/mips/sibyte/swarm/Makefile b/arch/mips/sibyte/swarm/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,3 @@ +lib-y = setup.o cmdline.o rtc_xicor1241.o rtc_m41t81.o + +lib-$(CONFIG_KGDB) += dbg_io.o diff -Nru a/arch/mips/sibyte/swarm/cmdline.c b/arch/mips/sibyte/swarm/cmdline.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/cmdline.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <asm/bootinfo.h> + +/* + * The naming of this variable is a remnant of the initial mips port to + * ARC-firmware based SGI consoles. We don't really need to do anything for + * the variable other than provide an instantiation. Everything about + * arcs_cmdline seems more than a little bit hackish... + */ +char arcs_cmdline[CL_SIZE]; diff -Nru a/arch/mips/sibyte/swarm/dbg_io.c b/arch/mips/sibyte/swarm/dbg_io.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/dbg_io.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,78 @@ +/* + * kgdb debug routines for swarm board. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +/* -------------------- BEGINNING OF CONFIG --------------------- */ + +#include <linux/delay.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_uart.h> +#include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/64bit.h> +#include <asm/addrspace.h> + +/* + * We use the second serial port for kgdb traffic. + * 115200, 8, N, 1. + */ + +#define BAUD_RATE 115200 +#define CLK_DIVISOR V_DUART_BAUD_RATE(BAUD_RATE) +#define DATA_BITS V_DUART_BITS_PER_CHAR_8 /* or 7 */ +#define PARITY V_DUART_PARITY_MODE_NONE /* or even */ +#define STOP_BITS M_DUART_STOP_BIT_LEN_1 /* or 2 */ + +static int duart_initialized = 0; /* 0: need to be init'ed by kgdb */ + +/* -------------------- END OF CONFIG --------------------- */ + + +#define duart_out(reg, val) out64(val, KSEG1 + A_DUART_CHANREG(1,reg)) +#define duart_in(reg) in64(KSEG1 + A_DUART_CHANREG(1,reg)) + +extern void set_async_breakpoint(unsigned int epc); + +void putDebugChar(unsigned char c); +unsigned char getDebugChar(void); +static void +duart_init(int clk_divisor, int data, int parity, int stop) +{ + duart_out(R_DUART_MODE_REG_1, data | parity); + duart_out(R_DUART_MODE_REG_2, stop); + duart_out(R_DUART_CLK_SEL, clk_divisor); + + duart_out(R_DUART_CMD, M_DUART_RX_EN | M_DUART_TX_EN); /* enable rx and tx */ +} + +void +putDebugChar(unsigned char c) +{ + if (!duart_initialized) { + duart_initialized = 1; + duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS); + } + while ((duart_in(R_DUART_STATUS) & M_DUART_TX_RDY) == 0); + duart_out(R_DUART_TX_HOLD, c); +} + +unsigned char +getDebugChar(void) +{ + if (!duart_initialized) { + duart_initialized = 1; + duart_init(CLK_DIVISOR, DATA_BITS, PARITY, STOP_BITS); + } + while ((duart_in(R_DUART_STATUS) & M_DUART_RX_RDY) == 0) ; + return duart_in(R_DUART_RX_HOLD); +} + diff -Nru a/arch/mips/sibyte/swarm/rtc.c b/arch/mips/sibyte/swarm/rtc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/rtc.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Not really sure what is supposed to be here, yet + */ + +#include <linux/spinlock.h> +#include <linux/mc146818rtc.h> + +static unsigned char swarm_rtc_read_data(unsigned long addr) +{ + return 0; +} + +static void swarm_rtc_write_data(unsigned char data, unsigned long addr) +{ +} + +static int swarm_rtc_bcd_mode(void) +{ + return 0; +} + +struct rtc_ops swarm_rtc_ops = { + &swarm_rtc_read_data, + &swarm_rtc_write_data, + &swarm_rtc_bcd_mode +}; diff -Nru a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/rtc_m41t81.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include <linux/bcd.h> +#include <linux/types.h> +#include <linux/time.h> + +#include <asm/time.h> +#include <asm/addrspace.h> + +#include <asm/sibyte/64bit.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_smbus.h> + + +/* M41T81 definitions */ + +/* + * Register bits + */ + +#define M41T81REG_SC_ST 0x80 /* stop bit */ +#define M41T81REG_HR_CB 0x40 /* century bit */ +#define M41T81REG_HR_CEB 0x80 /* century enable bit */ +#define M41T81REG_CTL_S 0x20 /* sign bit */ +#define M41T81REG_CTL_FT 0x40 /* frequency test bit */ +#define M41T81REG_CTL_OUT 0x80 /* output level */ +#define M41T81REG_WD_RB0 0x01 /* watchdog resolution bit 0 */ +#define M41T81REG_WD_RB1 0x02 /* watchdog resolution bit 1 */ +#define M41T81REG_WD_BMB0 0x04 /* watchdog multiplier bit 0 */ +#define M41T81REG_WD_BMB1 0x08 /* watchdog multiplier bit 1 */ +#define M41T81REG_WD_BMB2 0x10 /* watchdog multiplier bit 2 */ +#define M41T81REG_WD_BMB3 0x20 /* watchdog multiplier bit 3 */ +#define M41T81REG_WD_BMB4 0x40 /* watchdog multiplier bit 4 */ +#define M41T81REG_AMO_ABE 0x20 /* alarm in "battery back-up mode" enable bit */ +#define M41T81REG_AMO_SQWE 0x40 /* square wave enable */ +#define M41T81REG_AMO_AFE 0x80 /* alarm flag enable flag */ +#define M41T81REG_ADT_RPT5 0x40 /* alarm repeat mode bit 5 */ +#define M41T81REG_ADT_RPT4 0x80 /* alarm repeat mode bit 4 */ +#define M41T81REG_AHR_RPT3 0x80 /* alarm repeat mode bit 3 */ +#define M41T81REG_AHR_HT 0x40 /* halt update bit */ +#define M41T81REG_AMN_RPT2 0x80 /* alarm repeat mode bit 2 */ +#define M41T81REG_ASC_RPT1 0x80 /* alarm repeat mode bit 1 */ +#define M41T81REG_FLG_AF 0x40 /* alarm flag (read only) */ +#define M41T81REG_FLG_WDF 0x80 /* watchdog flag (read only) */ +#define M41T81REG_SQW_RS0 0x10 /* sqw frequency bit 0 */ +#define M41T81REG_SQW_RS1 0x20 /* sqw frequency bit 1 */ +#define M41T81REG_SQW_RS2 0x40 /* sqw frequency bit 2 */ +#define M41T81REG_SQW_RS3 0x80 /* sqw frequency bit 3 */ + + +/* + * Register numbers + */ + +#define M41T81REG_TSC 0x00 /* tenths/hundredths of second */ +#define M41T81REG_SC 0x01 /* seconds */ +#define M41T81REG_MN 0x02 /* minute */ +#define M41T81REG_HR 0x03 /* hour/century */ +#define M41T81REG_DY 0x04 /* day of week */ +#define M41T81REG_DT 0x05 /* date of month */ +#define M41T81REG_MO 0x06 /* month */ +#define M41T81REG_YR 0x07 /* year */ +#define M41T81REG_CTL 0x08 /* control */ +#define M41T81REG_WD 0x09 /* watchdog */ +#define M41T81REG_AMO 0x0A /* alarm: month */ +#define M41T81REG_ADT 0x0B /* alarm: date */ +#define M41T81REG_AHR 0x0C /* alarm: hour */ +#define M41T81REG_AMN 0x0D /* alarm: minute */ +#define M41T81REG_ASC 0x0E /* alarm: second */ +#define M41T81REG_FLG 0x0F /* flags */ +#define M41T81REG_SQW 0x13 /* square wave register */ + +#define M41T81_CCR_ADDRESS 0x68 +#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg)) + +static int m41t81_read(uint8_t addr) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64(addr & 0xff, SMB_CSR(R_SMB_CMD)); + out64((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + return (in64(SMB_CSR(R_SMB_DATA)) & 0xff); +} + +static int m41t81_write(uint8_t addr, int b) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((addr & 0xFF), SMB_CSR(R_SMB_CMD)); + out64((b & 0xff), SMB_CSR(R_SMB_DATA)); + out64(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + /* read the same byte again to make sure it is written */ + out64(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + return 0; +} + +int m41t81_set_time(unsigned long t) +{ + struct rtc_time tm; + + to_tm(t, &tm); + + /* + * Note the write order matters as it ensures the correctness. + * When we write sec, 10th sec is clear. It is reasonable to + * believe we should finish writing min within a second. + */ + + tm.tm_sec = BIN2BCD(tm.tm_sec); + m41t81_write(M41T81REG_SC, tm.tm_sec); + + tm.tm_min = BIN2BCD(tm.tm_min); + m41t81_write(M41T81REG_MN, tm.tm_min); + + tm.tm_hour = BIN2BCD(tm.tm_hour); + tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0); + m41t81_write(M41T81REG_HR, tm.tm_hour); + + /* tm_wday starts from 0 to 6 */ + if (tm.tm_wday == 0) tm.tm_wday = 7; + tm.tm_wday = BIN2BCD(tm.tm_wday); + m41t81_write(M41T81REG_DY, tm.tm_wday); + + tm.tm_mday = BIN2BCD(tm.tm_mday); + m41t81_write(M41T81REG_DT, tm.tm_mday); + + /* tm_mon starts from 0, *ick* */ + tm.tm_mon ++; + tm.tm_mon = BIN2BCD(tm.tm_mon); + m41t81_write(M41T81REG_MO, tm.tm_mon); + + /* we don't do century, everything is beyond 2000 */ + tm.tm_year %= 100; + tm.tm_year = BIN2BCD(tm.tm_year); + m41t81_write(M41T81REG_YR, tm.tm_year); + + return 0; +} + +unsigned long m41t81_get_time(void) +{ + unsigned int year, mon, day, hour, min, sec; + + /* + * min is valid if two reads of sec are the same. + */ + for (;;) { + sec = m41t81_read(M41T81REG_SC); + min = m41t81_read(M41T81REG_MN); + if (sec == m41t81_read(M41T81REG_SC)) break; + } + hour = m41t81_read(M41T81REG_HR) & 0x3f; + day = m41t81_read(M41T81REG_DT); + mon = m41t81_read(M41T81REG_MO); + year = m41t81_read(M41T81REG_YR); + + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + day = BCD2BIN(day); + mon = BCD2BIN(mon); + year = BCD2BIN(year); + + year += 2000; + + return mktime(year, mon, day, hour, min, sec); +} + +int m41t81_probe(void) +{ + unsigned int tmp; + + /* enable chip if it is not enabled yet */ + tmp = m41t81_read(M41T81REG_SC); + m41t81_write(M41T81REG_SC, tmp & 0x7f); + + return (m41t81_read(M41T81REG_SC) != -1); +} diff -Nru a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/bcd.h> +#include <linux/types.h> +#include <linux/time.h> + +#include <asm/time.h> +#include <asm/addrspace.h> + +#include <asm/sibyte/64bit.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_smbus.h> + + +/* Xicor 1241 definitions */ + +/* + * Register bits + */ + +#define X1241REG_SR_BAT 0x80 /* currently on battery power */ +#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */ +#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */ +#define X1241REG_SR_RTCF 0x01 /* clock failed */ +#define X1241REG_BL_BP2 0x80 /* block protect 2 */ +#define X1241REG_BL_BP1 0x40 /* block protect 1 */ +#define X1241REG_BL_BP0 0x20 /* block protect 0 */ +#define X1241REG_BL_WD1 0x10 +#define X1241REG_BL_WD0 0x08 +#define X1241REG_HR_MIL 0x80 /* military time format */ + +/* + * Register numbers + */ + +#define X1241REG_BL 0x10 /* block protect bits */ +#define X1241REG_INT 0x11 /* */ +#define X1241REG_SC 0x30 /* Seconds */ +#define X1241REG_MN 0x31 /* Minutes */ +#define X1241REG_HR 0x32 /* Hours */ +#define X1241REG_DT 0x33 /* Day of month */ +#define X1241REG_MO 0x34 /* Month */ +#define X1241REG_YR 0x35 /* Year */ +#define X1241REG_DW 0x36 /* Day of Week */ +#define X1241REG_Y2K 0x37 /* Year 2K */ +#define X1241REG_SR 0x3F /* Status register */ + +#define X1241_CCR_ADDRESS 0x6F + +#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg)) + +static int xicor_read(uint8_t addr) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); + out64((addr & 0xff), SMB_CSR(R_SMB_DATA)); + out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + return (in64(SMB_CSR(R_SMB_DATA)) & 0xff); +} + +static int xicor_write(uint8_t addr, int b) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64(addr, SMB_CSR(R_SMB_CMD)); + out64((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); + out64(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } else { + return 0; + } +} + +int xicor_set_time(unsigned long t) +{ + struct rtc_time tm; + int tmp; + + to_tm(t, &tm); + + /* unlock writes to the CCR */ + xicor_write(X1241REG_SR, X1241REG_SR_WEL); + xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); + + /* trivial ones */ + tm.tm_sec = BIN2BCD(tm.tm_sec); + xicor_write(X1241REG_SC, tm.tm_sec); + + tm.tm_min = BIN2BCD(tm.tm_min); + xicor_write(X1241REG_MN, tm.tm_min); + + tm.tm_mday = BIN2BCD(tm.tm_mday); + xicor_write(X1241REG_DT, tm.tm_mday); + + /* tm_mon starts from 0, *ick* */ + tm.tm_mon ++; + tm.tm_mon = BIN2BCD(tm.tm_mon); + xicor_write(X1241REG_MO, tm.tm_mon); + + /* year is split */ + tmp = tm.tm_year / 100; + tm.tm_year %= 100; + xicor_write(X1241REG_YR, tm.tm_year); + xicor_write(X1241REG_Y2K, tmp); + + /* hour is the most tricky one */ + tmp = xicor_read(X1241REG_HR); + if (tmp & X1241REG_HR_MIL) { + /* 24 hour format */ + tm.tm_hour = BIN2BCD(tm.tm_hour); + tmp = (tmp & ~0x3f) | (tm.tm_hour & 0x3f); + } else { + /* 12 hour format, with 0x2 for pm */ + tmp = tmp & ~0x3f; + if (tm.tm_hour >= 12) { + tmp |= 0x20; + tm.tm_hour -= 12; + } + tm.tm_hour = BIN2BCD(tm.tm_hour); + tmp |= tm.tm_hour; + } + xicor_write(X1241REG_HR, tmp); + + xicor_write(X1241REG_SR, 0); + + return 0; +} + +unsigned long xicor_get_time(void) +{ + unsigned int year, mon, day, hour, min, sec, y2k; + + sec = xicor_read(X1241REG_SC); + min = xicor_read(X1241REG_MN); + hour = xicor_read(X1241REG_HR); + + if (hour & X1241REG_HR_MIL) { + hour &= 0x3f; + } else { + if (hour & 0x20) + hour = (hour & 0xf) + 0x12; + } + + day = xicor_read(X1241REG_DT); + mon = xicor_read(X1241REG_MO); + year = xicor_read(X1241REG_YR); + y2k = xicor_read(X1241REG_Y2K); + + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + day = BCD2BIN(day); + mon = BCD2BIN(mon); + year = BCD2BIN(year); + y2k = BCD2BIN(y2k); + + year += (y2k * 100); + + return mktime(year, mon, day, hour, min, sec); +} + +int xicor_probe(void) +{ + return (xicor_read(X1241REG_SC) != -1); +} diff -Nru a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Setup code for the SWARM board + */ + +#include <linux/spinlock.h> +#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include <linux/init.h> +#include <linux/ide.h> +#include <linux/console.h> + +#include <asm/irq.h> +#include <asm/io.h> +#include <asm/bootinfo.h> +#include <asm/mipsregs.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/traps.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_genbus.h> +#include <asm/sibyte/64bit.h> +#include <asm/sibyte/board.h> + +extern struct rtc_ops *rtc_ops; +extern struct rtc_ops swarm_rtc_ops; + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops sibyte_ide_ops; +#endif + +extern void sb1250_setup(void); + +extern int xicor_probe(void); +extern int xicor_set_time(unsigned long); +extern unsigned long xicor_get_time(void); + +extern int m41t81_probe(void); +extern int m41t81_set_time(unsigned long); +extern unsigned long m41t81_get_time(void); + +const char *get_system_type(void) +{ + return "SiByte " SIBYTE_BOARD_NAME; +} + +void __init swarm_timer_setup(struct irqaction *irq) +{ + /* + * we don't set up irqaction, because we will deliver timer + * interrupts through low-level (direct) meachanism. + */ + + /* We only need to setup the generic timer */ + sb1250_time_init(); +} + +int swarm_be_handler(struct pt_regs *regs, int is_fixup) +{ + if (!is_fixup && (regs->cp0_cause & 4)) { + /* Data bus error - print PA */ +#ifdef CONFIG_MIPS64 + printk("DBE physical address: %010lx\n", + __read_64bit_c0_register($26, 1)); +#else + printk("DBE physical address: %010llx\n", + __read_64bit_c0_split($26, 1)); +#endif + } + return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); +} + +void __init swarm_setup(void) +{ + extern int panic_timeout; + + sb1250_setup(); + + panic_timeout = 5; /* For debug. */ + + board_timer_setup = swarm_timer_setup; + board_be_handler = swarm_be_handler; + + if (xicor_probe()) { + printk("swarm setup: Xicor 1241 RTC detected.\n"); + rtc_get_time = xicor_get_time; + rtc_set_time = xicor_set_time; + } + + if (m41t81_probe()) { + printk("swarm setup: M41T81 RTC detected.\n"); + rtc_get_time = m41t81_get_time; + rtc_set_time = m41t81_set_time; + } + + printk("This kernel optimized for " +#ifdef CONFIG_SIMULATION + "simulation" +#else + "board" +#endif + " runs " +#ifdef CONFIG_SIBYTE_CFE + "with" +#else + "without" +#endif + " CFE\n"); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &sibyte_ide_ops; +#endif + +#ifdef CONFIG_VT +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + screen_info = (struct screen_info) { + 0, 0, /* orig-x, orig-y */ + 0, /* unused */ + 52, /* orig_video_page */ + 3, /* orig_video_mode */ + 80, /* orig_video_cols */ + 4626, 3, 9, /* unused, ega_bx, unused */ + 25, /* orig_video_lines */ + 0x22, /* orig_video_isVGA */ + 16 /* orig_video_points */ + }; + /* XXXKW for CFE, get lines/cols from environment */ +#endif +} + +#ifdef LEDS_PHYS + +#ifdef CONFIG_SIBYTE_CARMEL +/* XXXKW need to detect Monterey/LittleSur/etc */ +#undef LEDS_PHYS +#define LEDS_PHYS MLEDS_PHYS +#endif + +#define setled(index, c) \ + ((unsigned char *)(LEDS_PHYS|IO_SPACE_BASE|0x20))[(3-(index))<<3] = (c) +void setleds(char *str) +{ + int i; + for (i = 0; i < 4; i++) { + if (!str[i]) { + setled(i, ' '); + } else { + setled(i, str[i]); + } + } +} +#endif diff -Nru a/arch/mips/sibyte/swarm/time.c b/arch/mips/sibyte/swarm/time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/sibyte/swarm/time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Time routines for the swarm board. We pass all the hard stuff + * through to the sb1250 handling code. Only thing we really keep + * track of here is what time of day we think it is. And we don't + * really even do a good job of that... + */ + + +#include <linux/bcd.h> +#include <linux/init.h> +#include <linux/time.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <asm/system.h> +#include <asm/addrspace.h> + +#include <asm/sibyte/64bit.h> +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_smbus.h> + +static unsigned long long sec_bias = 0; +static unsigned int usec_bias = 0; + +/* Xicor 1241 definitions */ + +/* + * Register bits + */ + +#define X1241REG_SR_BAT 0x80 /* currently on battery power */ +#define X1241REG_SR_RWEL 0x04 /* r/w latch is enabled, can write RTC */ +#define X1241REG_SR_WEL 0x02 /* r/w latch is unlocked, can enable r/w now */ +#define X1241REG_SR_RTCF 0x01 /* clock failed */ +#define X1241REG_BL_BP2 0x80 /* block protect 2 */ +#define X1241REG_BL_BP1 0x40 /* block protect 1 */ +#define X1241REG_BL_BP0 0x20 /* block protect 0 */ +#define X1241REG_BL_WD1 0x10 +#define X1241REG_BL_WD0 0x08 +#define X1241REG_HR_MIL 0x80 /* military time format */ + +/* + * Register numbers + */ + +#define X1241REG_BL 0x10 /* block protect bits */ +#define X1241REG_INT 0x11 /* */ +#define X1241REG_SC 0x30 /* Seconds */ +#define X1241REG_MN 0x31 /* Minutes */ +#define X1241REG_HR 0x32 /* Hours */ +#define X1241REG_DT 0x33 /* Day of month */ +#define X1241REG_MO 0x34 /* Month */ +#define X1241REG_YR 0x35 /* Year */ +#define X1241REG_DW 0x36 /* Day of Week */ +#define X1241REG_Y2K 0x37 /* Year 2K */ +#define X1241REG_SR 0x3F /* Status register */ + +#define X1241_CCR_ADDRESS 0x6F + +#define SMB_CSR(reg) (KSEG1 | A_SMB_REGISTER(1, reg)) + +static int xicor_read(uint8_t addr) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD)); + out64((addr & 0xff), SMB_CSR(R_SMB_DATA)); + out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } + + return (in64(SMB_CSR(R_SMB_DATA)) & 0xff); +} + +static int xicor_write(uint8_t addr, int b) +{ + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + out64(addr, SMB_CSR(R_SMB_CMD)); + out64((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA)); + out64(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE, + SMB_CSR(R_SMB_START)); + + while (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY) + ; + + if (in64(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) { + /* Clear error bit by writing a 1 */ + out64(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS)); + return -1; + } else { + return 0; + } +} + +/* + * In order to set the CMOS clock precisely, set_rtc_mmss has to be + * called 500 ms after the second nowtime has started, because when + * nowtime is written into the registers of the CMOS clock, it will + * jump to the next second precisely 500 ms later. Check the Motorola + * MC146818A or Dallas DS12887 data sheet for details. + * + * BUG: This routine does not handle hour overflow properly; it just + * sets the minutes. Usually you'll only notice that after reboot! + */ +int set_rtc_mmss(unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + + cmos_minutes = xicor_read(X1241REG_MN); + cmos_minutes = BCD2BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + /* unlock writes to the CCR */ + xicor_write(X1241REG_SR, X1241REG_SR_WEL); + xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL); + + if (abs(real_minutes - cmos_minutes) < 30) { + real_seconds = BIN2BCD(real_seconds); + real_minutes = BIN2BCD(real_minutes); + xicor_write(X1241REG_SC, real_seconds); + xicor_write(X1241REG_MN, real_minutes); + } else { + printk(KERN_WARNING + "set_rtc_mmss: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + xicor_write(X1241REG_SR, 0); + + printk("set_rtc_mmss: %02d:%02d\n", real_minutes, real_seconds); + + return retval; +} + +static unsigned long __init get_swarm_time(void) +{ + unsigned int year, mon, day, hour, min, sec, y2k; + + sec = xicor_read(X1241REG_SC); + min = xicor_read(X1241REG_MN); + hour = xicor_read(X1241REG_HR); + + if (hour & X1241REG_HR_MIL) { + hour &= 0x3f; + } else { + if (hour & 0x20) + hour = (hour & 0xf) + 0x12; + } + + sec = BCD2BIN(sec); + min = BCD2BIN(min); + hour = BCD2BIN(hour); + + day = xicor_read(X1241REG_DT); + mon = xicor_read(X1241REG_MO); + year = xicor_read(X1241REG_YR); + y2k = xicor_read(X1241REG_Y2K); + + day = BCD2BIN(day); + mon = BCD2BIN(mon); + year = BCD2BIN(year); + y2k = BCD2BIN(y2k); + + year += (y2k * 100); + + return mktime(year, mon, day, hour, min, sec); +} + +/* + * Bring up the timer at 100 Hz. + */ +void __init swarm_time_init(void) +{ + unsigned int flags; + int status; + + /* Set up the scd general purpose timer 0 to cpu 0 */ + sb1250_time_init(); + + /* Establish communication with the Xicor 1241 RTC */ + /* XXXKW how do I share the SMBus with the I2C subsystem? */ + + out64(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ)); + out64(0, SMB_CSR(R_SMB_CONTROL)); + + if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) { + printk("x1241: couldn't detect on SWARM SMBus 1\n"); + } else { + if (status & X1241REG_SR_RTCF) + printk("x1241: battery failed -- time is probably wrong\n"); + write_seqlock_irqsave(&xtime_lock, flags); + xtime.tv_sec = get_swarm_time(); + xtime.tv_nsec = 0; + write_sequnlock_irqrestore(&xtime_lock, flags); + } +} diff -Nru a/arch/mips/tools/Makefile b/arch/mips/tools/Makefile --- a/arch/mips/tools/Makefile Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,23 +0,0 @@ -# Makefile for MIPS kernel build tools. -# -# Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) -# Copyright (C) 1997 Ralf Baechle (ralf@gnu.ai.mit.edu) -# -# $Id: Makefile,v 1.2 1997/09/23 06:23:49 ralf Exp $ -# -TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h - -$(TARGET): offset.h - cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET)) - -offset.h: offset.s - sed -n '/^@@@/s///p' $^ >$@ - -offset.s: offset.c $(TOPDIR)/include/linux/autoconf.h - -clean: - rm -f offset.[hs] $(TARGET).new - -mrproper: - rm -f offset.[hs] $(TARGET).new - rm -f $(TARGET) diff -Nru a/arch/mips/tools/offset.c b/arch/mips/tools/offset.c --- a/arch/mips/tools/offset.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,157 +0,0 @@ -/* - * offset.c: Calculate pt_regs and task_struct offsets. - * - * Copyright (C) 1996 David S. Miller - * Copyright (C) 1997, 1998, 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - * - * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. - */ -#include <linux/types.h> -#include <linux/sched.h> - -#include <asm/ptrace.h> -#include <asm/processor.h> - -#define text(t) __asm__("\n@@@" t) -#define _offset(type, member) (&(((type *)NULL)->member)) - -#define offset(string, ptr, member) \ - __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) -#define size(string, size) \ - __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) -#define linefeed text("") - -text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */"); -linefeed; -text("#ifndef _MIPS_OFFSET_H"); -text("#define _MIPS_OFFSET_H"); -linefeed; - -void output_ptreg_defines(void) -{ - text("/* MIPS pt_regs offsets. */"); - offset("#define PT_R0 ", struct pt_regs, regs[0]); - offset("#define PT_R1 ", struct pt_regs, regs[1]); - offset("#define PT_R2 ", struct pt_regs, regs[2]); - offset("#define PT_R3 ", struct pt_regs, regs[3]); - offset("#define PT_R4 ", struct pt_regs, regs[4]); - offset("#define PT_R5 ", struct pt_regs, regs[5]); - offset("#define PT_R6 ", struct pt_regs, regs[6]); - offset("#define PT_R7 ", struct pt_regs, regs[7]); - offset("#define PT_R8 ", struct pt_regs, regs[8]); - offset("#define PT_R9 ", struct pt_regs, regs[9]); - offset("#define PT_R10 ", struct pt_regs, regs[10]); - offset("#define PT_R11 ", struct pt_regs, regs[11]); - offset("#define PT_R12 ", struct pt_regs, regs[12]); - offset("#define PT_R13 ", struct pt_regs, regs[13]); - offset("#define PT_R14 ", struct pt_regs, regs[14]); - offset("#define PT_R15 ", struct pt_regs, regs[15]); - offset("#define PT_R16 ", struct pt_regs, regs[16]); - offset("#define PT_R17 ", struct pt_regs, regs[17]); - offset("#define PT_R18 ", struct pt_regs, regs[18]); - offset("#define PT_R19 ", struct pt_regs, regs[19]); - offset("#define PT_R20 ", struct pt_regs, regs[20]); - offset("#define PT_R21 ", struct pt_regs, regs[21]); - offset("#define PT_R22 ", struct pt_regs, regs[22]); - offset("#define PT_R23 ", struct pt_regs, regs[23]); - offset("#define PT_R24 ", struct pt_regs, regs[24]); - offset("#define PT_R25 ", struct pt_regs, regs[25]); - offset("#define PT_R26 ", struct pt_regs, regs[26]); - offset("#define PT_R27 ", struct pt_regs, regs[27]); - offset("#define PT_R28 ", struct pt_regs, regs[28]); - offset("#define PT_R29 ", struct pt_regs, regs[29]); - offset("#define PT_R30 ", struct pt_regs, regs[30]); - offset("#define PT_R31 ", struct pt_regs, regs[31]); - offset("#define PT_LO ", struct pt_regs, lo); - offset("#define PT_HI ", struct pt_regs, hi); - offset("#define PT_EPC ", struct pt_regs, cp0_epc); - offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); - offset("#define PT_STATUS ", struct pt_regs, cp0_status); - offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); - size("#define PT_SIZE ", struct pt_regs); - linefeed; -} - -void output_task_defines(void) -{ - text("/* MIPS task_struct offsets. */"); - offset("#define TASK_STATE ", struct task_struct, state); - offset("#define TASK_FLAGS ", struct task_struct, flags); -#error offset("#define TASK_SIGPENDING ", struct task_struct, work.sigpending); -#error offset("#define TASK_NEED_RESCHED ", struct task_struct, work.need_resched); -#error offset("#define TASK_PTRACE ", struct task_struct, ptrace); - offset("#define TASK_COUNTER ", struct task_struct, counter); - offset("#define TASK_NICE ", struct task_struct, nice); - offset("#define TASK_MM ", struct task_struct, mm); - offset("#define TASK_PID ", struct task_struct, pid); - size("#define TASK_STRUCT_SIZE ", struct task_struct); - linefeed; -} - -void output_thread_defines(void) -{ - text("/* MIPS specific thread_struct offsets. */"); - offset("#define THREAD_REG16 ", struct task_struct, thread.reg16); - offset("#define THREAD_REG17 ", struct task_struct, thread.reg17); - offset("#define THREAD_REG18 ", struct task_struct, thread.reg18); - offset("#define THREAD_REG19 ", struct task_struct, thread.reg19); - offset("#define THREAD_REG20 ", struct task_struct, thread.reg20); - offset("#define THREAD_REG21 ", struct task_struct, thread.reg21); - offset("#define THREAD_REG22 ", struct task_struct, thread.reg22); - offset("#define THREAD_REG23 ", struct task_struct, thread.reg23); - offset("#define THREAD_REG29 ", struct task_struct, thread.reg29); - offset("#define THREAD_REG30 ", struct task_struct, thread.reg30); - offset("#define THREAD_REG31 ", struct task_struct, thread.reg31); - offset("#define THREAD_STATUS ", struct task_struct, \ - thread.cp0_status); - offset("#define THREAD_FPU ", struct task_struct, thread.fpu); - offset("#define THREAD_BVADDR ", struct task_struct, \ - thread.cp0_badvaddr); - offset("#define THREAD_BUADDR ", struct task_struct, \ - thread.cp0_baduaddr); - offset("#define THREAD_ECODE ", struct task_struct, \ - thread.error_code); - offset("#define THREAD_TRAPNO ", struct task_struct, thread.trap_no); - offset("#define THREAD_MFLAGS ", struct task_struct, thread.mflags); - offset("#define THREAD_CURDS ", struct task_struct, \ - thread.current_ds); - offset("#define THREAD_TRAMP ", struct task_struct, \ - thread.irix_trampoline); - offset("#define THREAD_OLDCTX ", struct task_struct, \ - thread.irix_oldctx); - offset("#define THREAD_DSEEPC ", struct task_struct, \ - thread.dsemul_epc); - offset("#define THREAD_DSEAERPC ", struct task_struct, \ - thread.dsemul_aerpc); - linefeed; -} - -void output_mm_defines(void) -{ - text("/* Linux mm_struct offsets. */"); - offset("#define MM_USERS ", struct mm_struct, mm_users); - offset("#define MM_PGD ", struct mm_struct, pgd); - offset("#define MM_CONTEXT ", struct mm_struct, context); - linefeed; -} - -void output_sc_defines(void) -{ - text("/* Linux sigcontext offsets. */"); - offset("#define SC_REGS ", struct sigcontext, sc_regs); - offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); - offset("#define SC_MDHI ", struct sigcontext, sc_mdhi); - offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); - offset("#define SC_PC ", struct sigcontext, sc_pc); - offset("#define SC_STATUS ", struct sigcontext, sc_status); - offset("#define SC_OWNEDFP ", struct sigcontext, sc_ownedfp); - offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); - offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); - offset("#define SC_CAUSE ", struct sigcontext, sc_cause); - offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); - linefeed; -} - -text("#endif /* !(_MIPS_OFFSET_H) */"); diff -Nru a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/common/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,14 @@ +# +# Makefile for common code for Toshiba TX4927 based systems +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := tx4927_prom.o +obj-y += tx4927_setup.o +obj-y += tx4927_irq.o +obj-y += tx4927_irq_handler.o + +obj-$(CONFIG_KGDB) += tx4927_dbgio.o diff -Nru a/arch/mips/tx4927/common/tx4927_dbgio.c b/arch/mips/tx4927/common/tx4927_dbgio.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/common/tx4927_dbgio.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,47 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_dbgio.c + * + * kgdb interface for gdb + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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 <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/tx4927/tx4927_mips.h> + +u8 getDebugChar(void) +{ + extern u8 txx9_sio_kdbg_rd(void); + return (txx9_sio_kdbg_rd()); +} + + +int putDebugChar(u8 byte) +{ + extern int txx9_sio_kdbg_wr( u8 ch ); + return (txx9_sio_kdbg_wr(byte)); +} diff -Nru a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/common/tx4927_irq.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,705 @@ +/* + * Common tx4927 irq handler + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * 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 <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/irq.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/tx4927/tx4927.h> + +/* + * DEBUG + */ +#define TX4927_IRQ_CHECK_CP0 +#define TX4927_IRQ_CHECK_PIC + +#undef TX4927_IRQ_DEBUG + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_NONE 0x00000000 + +#define TX4927_IRQ_INFO ( 1 << 0 ) +#define TX4927_IRQ_WARN ( 1 << 1 ) +#define TX4927_IRQ_EROR ( 1 << 2 ) + +#define TX4927_IRQ_INIT ( 1 << 5 ) +#define TX4927_IRQ_NEST1 ( 1 << 6 ) +#define TX4927_IRQ_NEST2 ( 1 << 7 ) +#define TX4927_IRQ_NEST3 ( 1 << 8 ) +#define TX4927_IRQ_NEST4 ( 1 << 9 ) + +#define TX4927_IRQ_CP0_INIT ( 1 << 10 ) +#define TX4927_IRQ_CP0_STARTUP ( 1 << 11 ) +#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 ) +#define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) +#define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) +#define TX4927_IRQ_CP0_MASK ( 1 << 15 ) +#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) + +#define TX4927_IRQ_PIC_INIT ( 1 << 20 ) +#define TX4927_IRQ_PIC_STARTUP ( 1 << 21 ) +#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 ) +#define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) +#define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) +#define TX4927_IRQ_PIC_MASK ( 1 << 25 ) +#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) + +#define TX4927_IRQ_ALL 0xffffffff +#endif + +#ifdef TX4927_IRQ_DEBUG +static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE + | TX4927_IRQ_INFO + | TX4927_IRQ_WARN | TX4927_IRQ_EROR +// | TX4927_IRQ_CP0_INIT +// | TX4927_IRQ_CP0_STARTUP +// | TX4927_IRQ_CP0_SHUTDOWN +// | TX4927_IRQ_CP0_ENABLE +// | TX4927_IRQ_CP0_DISABLE +// | TX4927_IRQ_CP0_MASK +// | TX4927_IRQ_CP0_ENDIRQ +// | TX4927_IRQ_PIC_INIT +// | TX4927_IRQ_PIC_STARTUP +// | TX4927_IRQ_PIC_SHUTDOWN +// | TX4927_IRQ_PIC_ENABLE +// | TX4927_IRQ_PIC_DISABLE +// | TX4927_IRQ_PIC_MASK +// | TX4927_IRQ_PIC_ENDIRQ +// | TX4927_IRQ_INIT +// | TX4927_IRQ_NEST1 +// | TX4927_IRQ_NEST2 +// | TX4927_IRQ_NEST3 +// | TX4927_IRQ_NEST4 + ); +#endif + +#ifdef TX4927_IRQ_DEBUG +#define TX4927_IRQ_DPRINTK(flag,str...) \ + if ( (tx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TX4927_IRQ_DPRINTK(flag,str...) +#endif + +/* + * Forwad definitions for all pic's + */ + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq); +static void tx4927_irq_cp0_shutdown(unsigned int irq); +static void tx4927_irq_cp0_enable(unsigned int irq); +static void tx4927_irq_cp0_disable(unsigned int irq); +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq); +static void tx4927_irq_cp0_end(unsigned int irq); + +static unsigned int tx4927_irq_pic_startup(unsigned int irq); +static void tx4927_irq_pic_shutdown(unsigned int irq); +static void tx4927_irq_pic_enable(unsigned int irq); +static void tx4927_irq_pic_disable(unsigned int irq); +static void tx4927_irq_pic_mask_and_ack(unsigned int irq); +static void tx4927_irq_pic_end(unsigned int irq); + +/* + * Kernel structs for all pic's + */ + +static spinlock_t tx4927_cp0_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t tx4927_pic_lock = SPIN_LOCK_UNLOCKED; + +#define TX4927_CP0_NAME "TX4927-CP0" +static struct hw_interrupt_type tx4927_irq_cp0_type = { + typename: TX4927_CP0_NAME, + startup: tx4927_irq_cp0_startup, + shutdown: tx4927_irq_cp0_shutdown, + enable: tx4927_irq_cp0_enable, + disable: tx4927_irq_cp0_disable, + ack: tx4927_irq_cp0_mask_and_ack, + end: tx4927_irq_cp0_end, + set_affinity: NULL +}; + +#define TX4927_PIC_NAME "TX4927-PIC" +static struct hw_interrupt_type tx4927_irq_pic_type = { + typename: TX4927_PIC_NAME, + startup: tx4927_irq_pic_startup, + shutdown: tx4927_irq_pic_shutdown, + enable: tx4927_irq_pic_enable, + disable: tx4927_irq_pic_disable, + ack: tx4927_irq_pic_mask_and_ack, + end: tx4927_irq_pic_end, + set_affinity: NULL +}; + +#define TX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +static struct irqaction tx4927_irq_pic_action = +TX4927_PIC_ACTION(TX4927_PIC_NAME); + +#define CCP0_STATUS 12 +#define CCP0_CAUSE 13 + +/* + * Functions for cp0 + */ + +#define tx4927_irq_cp0_mask(irq) ( 1 << ( irq-TX4927_IRQ_CP0_BEG+8 ) ) + +static void +tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, unsigned set_bits) +{ + unsigned long val = 0; + + switch (cp0_reg) { + case CCP0_STATUS: + val = read_c0_status(); + break; + + case CCP0_CAUSE: + val = read_c0_cause(); + break; + + } + + val &= (~clr_bits); + val |= (set_bits); + + switch (cp0_reg) { + case CCP0_STATUS:{ + write_c0_status(val); + break; + } + case CCP0_CAUSE:{ + write_c0_cause(val); + break; + } + } + + return; +} + +static void __init tx4927_irq_cp0_init(void) +{ + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", + TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); + + for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &tx4927_irq_cp0_type; + } + + return; +} + +static unsigned int tx4927_irq_cp0_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_enable(irq); + + return (0); +} + +static void tx4927_irq_cp0_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_cp0_lock, flags); + + tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_cp0_lock, flags); + + return; +} + +static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_cp0_disable(irq); + + return; +} + +static void tx4927_irq_cp0_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); + +#ifdef TX4927_IRQ_CHECK_CP0 + { + if (irq < TX4927_IRQ_CP0_BEG || irq > TX4927_IRQ_CP0_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_cp0_enable(irq); + } + + return; +} + +/* + * Functions for pic + */ +u32 tx4927_irq_pic_addr(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 17: + case 16: + case 1: + case 0: + return (0xff1ff610); + + case 19: + case 18: + case 3: + case 2: + return (0xff1ff614); + + case 21: + case 20: + case 5: + case 4: + return (0xff1ff618); + + case 23: + case 22: + case 7: + case 6: + return (0xff1ff61c); + + case 25: + case 24: + case 9: + case 8: + return (0xff1ff620); + + case 27: + case 26: + case 11: + case 10: + return (0xff1ff624); + + case 29: + case 28: + case 13: + case 12: + return (0xff1ff628); + + case 31: + case 30: + case 15: + case 14: + return (0xff1ff62c); + + } + return (0); +} + +u32 tx4927_irq_pic_mask(int irq) +{ + /* MVMCP -- need to formulize this */ + irq -= TX4927_IRQ_PIC_BEG; + switch (irq) { + case 31: + case 29: + case 27: + case 25: + case 23: + case 21: + case 19: + case 17:{ + return (0x07000000); + } + case 30: + case 28: + case 26: + case 24: + case 22: + case 20: + case 18: + case 16:{ + return (0x00070000); + } + case 15: + case 13: + case 11: + case 9: + case 7: + case 5: + case 3: + case 1:{ + return (0x00000700); + } + case 14: + case 12: + case 10: + case 8: + case 6: + case 4: + case 2: + case 0:{ + return (0x00000007); + } + } + return (0x00000000); +} + +static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, + unsigned set_bits) +{ + unsigned long val = 0; + + val = TX4927_RD(pic_reg); + val &= (~clr_bits); + val |= (set_bits); + TX4927_WR(pic_reg, val); + + return; +} + +static void __init tx4927_irq_pic_init(void) +{ + unsigned long flags; + int i; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", + TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); + + for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 2; + irq_desc[i].handler = &tx4927_irq_pic_type; + } + + setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ + TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static unsigned int tx4927_irq_pic_startup(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_enable(irq); + + return (0); +} + +static void tx4927_irq_pic_shutdown(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_enable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, + tx4927_irq_pic_mask(irq)); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_disable(unsigned int irq) +{ + unsigned long flags; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + spin_lock_irqsave(&tx4927_pic_lock, flags); + + tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), + tx4927_irq_pic_mask(irq), 0); + + spin_unlock_irqrestore(&tx4927_pic_lock, flags); + + return; +} + +static void tx4927_irq_pic_mask_and_ack(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + tx4927_irq_pic_disable(irq); + + return; +} + +static void tx4927_irq_pic_end(unsigned int irq) +{ + TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); + +#ifdef TX4927_IRQ_CHECK_PIC + { + if (irq < TX4927_IRQ_PIC_BEG || irq > TX4927_IRQ_PIC_END) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_EROR, + "bad irq=%d \n", irq); + panic("\n"); + } + } +#endif + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + tx4927_irq_pic_enable(irq); + } + + return; +} + +/* + * Main init functions + */ +void __init tx4927_irq_init(void) +{ + extern asmlinkage void tx4927_irq_handler(void); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); + tx4927_irq_cp0_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); + tx4927_irq_pic_init(); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, + "=Calling set_except_vector(tx4927_irq_handler)\n"); + set_except_vector(0, tx4927_irq_handler); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); + + return; +} + +int tx4927_irq_nested(void) +{ + int sw_irq = 0; + u32 level2; + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "-\n"); + + level2 = TX4927_RD(0xff1ff6a0); + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=level2a=0x%x\n", level2); + + if ((level2 & 0x10000) == 0) { + level2 &= 0x1f; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=level2b=0x%x\n", level2); + + sw_irq = TX4927_IRQ_PIC_BEG + level2; + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST3, "=sw_irq=%d\n", sw_irq); + + if (sw_irq == 27) { + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq-%d\n", + sw_irq); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + sw_irq = toshiba_rbtx4927_irq_nested(sw_irq); + } +#endif + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST4, "=irq+%d\n", + sw_irq); + } + } + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST2, "=sw_irq=%d\n", sw_irq); + + TX4927_IRQ_DPRINTK(TX4927_IRQ_NEST1, "+\n"); + + return (sw_irq); +} diff -Nru a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/common/tx4927_irq_handler.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,104 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_irq_handler.S + * + * Primary interrupt handler for tx4927 based systems + * + * Author: MontaVista Software, Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * source@mvista.com + * + * Copyright 2001-2002 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 <linux/config.h> +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/tx4927/tx4927.h> + + .align 5 + NESTED(tx4927_irq_handler, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + mfc0 t0, CP0_CAUSE + mfc0 t1, CP0_STATUS + and t0, t1 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_ip7 + + /* IP6..IP3 multiplexed -- do not use */ + + andi t1, t0, STATUSF_IP2 /* tx4927 pic */ + bnez t1, ll_ip2 + + andi t1, t0, STATUSF_IP0 /* user line 0 */ + bnez t1, ll_ip0 + + andi t1, t0, STATUSF_IP1 /* user line 1 */ + bnez t1, ll_ip1 + + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(tx4927_irq_handler) + + .align 5 + + +ll_ip7: + li a0, TX4927_IRQ_CPU_TIMER + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip2: + jal tx4927_irq_nested + nop + beqz v0, goto_spurious_interrupt + nop + move a0, v0 + move a1, sp + jal do_IRQ + j ret_from_irq + +goto_spurious_interrupt: + j spurious_interrupt + nop + +ll_ip1: + li a0, TX4927_IRQ_USER1 + move a1, sp + jal do_IRQ + j ret_from_irq + +ll_ip0: + li a0, TX4927_IRQ_USER0 + move a1, sp + jal do_IRQ + j ret_from_irq diff -Nru a/arch/mips/tx4927/common/tx4927_prom.c b/arch/mips/tx4927/common/tx4927_prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/common/tx4927_prom.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,146 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_prom.c + * + * common tx4927 memory interface + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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 <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/tx4927/tx4927.h> + +static unsigned int __init tx4927_process_sdccr(u64 * addr) +{ + u64 val; + unsigned int sdccr_ce; + unsigned int sdccr_bs; + unsigned int sdccr_rs; + unsigned int sdccr_cs; + unsigned int sdccr_mw; + unsigned int bs = 0; + unsigned int rs = 0; + unsigned int cs = 0; + unsigned int mw = 0; + unsigned int msize = 0; + + val = (*((vu64 *) (addr))); + + /* MVMCP -- need #defs for these bits masks */ + sdccr_ce = ((val & (1 << 10)) >> 10); + sdccr_bs = ((val & (1 << 8)) >> 8); + sdccr_rs = ((val & (3 << 5)) >> 5); + sdccr_cs = ((val & (3 << 2)) >> 2); + sdccr_mw = ((val & (1 << 0)) >> 0); + + if (sdccr_ce) { + switch (sdccr_bs) { + case 0:{ + bs = 2; + break; + } + case 1:{ + bs = 4; + break; + } + } + switch (sdccr_rs) { + case 0:{ + rs = 2048; + break; + } + case 1:{ + rs = 4096; + break; + } + case 2:{ + rs = 8192; + break; + } + case 3:{ + rs = 0; + break; + } + } + switch (sdccr_cs) { + case 0:{ + cs = 256; + break; + } + case 1:{ + cs = 512; + break; + } + case 2:{ + cs = 1024; + break; + } + case 3:{ + cs = 2048; + break; + } + } + switch (sdccr_mw) { + case 0:{ + mw = 8; + break; + } /* 8 bytes = 64 bits */ + case 1:{ + mw = 4; + break; + } /* 4 bytes = 32 bits */ + } + } + + /* bytes per chip MB per chip num chips */ + msize = (((rs * cs * mw) / (1024 * 1024)) * bs); + + return (msize); +} + + +unsigned int __init tx4927_get_mem_size(void) +{ + unsigned int c0; + unsigned int c1; + unsigned int c2; + unsigned int c3; + unsigned int total; + + /* MVMCP -- need #defs for these registers */ + c0 = tx4927_process_sdccr((u64 *) 0xff1f8000); + c1 = tx4927_process_sdccr((u64 *) 0xff1f8008); + c2 = tx4927_process_sdccr((u64 *) 0xff1f8010); + c3 = tx4927_process_sdccr((u64 *) 0xff1f8018); + total = c0 + c1 + c2 + c3; + + return (total); +} diff -Nru a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/common/tx4927_setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,251 @@ +/* + * linux/arch/mips/tx4927/common/tx4927_setup.c + * + * common tx4927 setup stuff + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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 <linux/errno.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timex.h> +#include <linux/slab.h> +#include <linux/random.h> +#include <linux/irq.h> +#include <asm/bitops.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mipsregs.h> +#include <asm/system.h> +#include <asm/time.h> +#include <asm/time.h> +#include <asm/tx4927/tx4927.h> + + +#undef DEBUG + +void __init tx4927_setup(void); +void __init tx4927_time_init(void); +void __init tx4927_timer_setup(struct irqaction *irq); +void dump_cp0(char *key); + + +void (*__wbflush) (void); + +static void tx4927_write_buffer_flush(void) +{ + __asm__ __volatile__ + ("sync\n\t" "nop\n\t" "loop: bc0f loop\n\t" "nop\n\t"); +} + + +void __init tx4927_setup(void) +{ + board_time_init = tx4927_time_init; + board_timer_setup = tx4927_timer_setup; + __wbflush = tx4927_write_buffer_flush; + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_setup(void); + toshiba_rbtx4927_setup(); + } +#endif + + return; +} + + +void __init tx4927_time_init(void) +{ + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_time_init(void); + toshiba_rbtx4927_time_init(); + } +#endif + +#ifdef CONFIG_KGDB + { + printk("Calling breakpoint() -- start remote kgdb\n"); + set_debug_traps(); + breakpoint(); + printk("Calling breakpoint() -- done\n"); + } +#endif + + return; +} + + +void __init tx4927_timer_setup(struct irqaction *irq) +{ + u32 count; + u32 c1; + u32 c2; + + setup_irq(TX4927_IRQ_CPU_TIMER, irq); + + /* to generate the first timer interrupt */ + c1 = read_c0_count(); + count = c1 + (mips_counter_frequency / HZ); + write_c0_compare(count); + c2 = read_c0_count(); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_timer_setup(struct irqaction + *irq); + toshiba_rbtx4927_timer_setup(irq); + } +#endif + + return; +} + + +#ifdef DEBUG +void print_cp0(char *key, int num, char *name, u32 val) +{ + printk("%s cp0:%02d:%s=0x%08x\n", key, num, name, val); + return; +} + +indent: Standard input:25: Error:Unexpected end of file + +void +dump_cp0(char *key) +{ + if (key == NULL) + key = ""; + + print_cp0(key, 0, "INDEX ", read_c0_index()); + print_cp0(key, 2, "ENTRYLO1", read_c0_entrylo0()); + print_cp0(key, 3, "ENTRYLO2", read_c0_entrylo1()); + print_cp0(key, 4, "CONTEXT ", read_c0_context()); + print_cp0(key, 5, "PAGEMASK", read_c0_pagemask()); + print_cp0(key, 6, "WIRED ", read_c0_wired()); + //print_cp0(key, 8, "BADVADDR", read_c0_badvaddr()); + print_cp0(key, 9, "COUNT ", read_c0_count()); + print_cp0(key, 10, "ENTRYHI ", read_c0_entryhi()); + print_cp0(key, 11, "COMPARE ", read_c0_compare()); + print_cp0(key, 12, "STATUS ", read_c0_status()); + print_cp0(key, 13, "CAUSE ", read_c0_cause() & 0xffff87ff); + print_cp0(key, 16, "CONFIG ", read_c0_config()); + return; +} + +void print_pic(char *key, u32 reg, char *name) +{ + printk("%s pic:0x%08x:%s=0x%08x\n", key, reg, name, + TX4927_RD(reg)); + return; +} + + +void dump_pic(char *key) +{ + if (key == NULL) + key = ""; + + print_pic(key, 0xff1ff600, "IRDEN "); + print_pic(key, 0xff1ff604, "IRDM0 "); + print_pic(key, 0xff1ff608, "IRDM1 "); + + print_pic(key, 0xff1ff610, "IRLVL0 "); + print_pic(key, 0xff1ff614, "IRLVL1 "); + print_pic(key, 0xff1ff618, "IRLVL2 "); + print_pic(key, 0xff1ff61c, "IRLVL3 "); + print_pic(key, 0xff1ff620, "IRLVL4 "); + print_pic(key, 0xff1ff624, "IRLVL5 "); + print_pic(key, 0xff1ff628, "IRLVL6 "); + print_pic(key, 0xff1ff62c, "IRLVL7 "); + + print_pic(key, 0xff1ff640, "IRMSK "); + print_pic(key, 0xff1ff660, "IREDC "); + print_pic(key, 0xff1ff680, "IRPND "); + print_pic(key, 0xff1ff6a0, "IRCS "); + + print_pic(key, 0xff1ff514, "IRFLAG1 "); /* don't read IRLAG0 -- it hangs system */ + + print_pic(key, 0xff1ff518, "IRPOL "); + print_pic(key, 0xff1ff51c, "IRRCNT "); + print_pic(key, 0xff1ff520, "IRMASKINT"); + print_pic(key, 0xff1ff524, "IRMASKEXT"); + + return; +} + + +void print_addr(char *hdr, char *key, u32 addr) +{ + printk("%s %s:0x%08x=0x%08x\n", hdr, key, addr, TX4927_RD(addr)); + return; +} + + +void dump_180(char *key) +{ + u32 i; + + for (i = 0x80000180; i < 0x80000180 + 0x80; i += 4) { + print_addr("180", key, i); + } + return; +} + + +void dump_eh0(char *key) +{ + int i; + extern unsigned long exception_handlers[]; + + for (i = (int) exception_handlers; + i < (int) (exception_handlers + 20); i += 4) { + print_addr("eh0", key, i); + } + + return; +} + +void pk0(void) +{ + volatile u32 val; + + __asm__ __volatile__("ori %0, $26, 0":"=r"(val) + ); + printk("k0=[0x%08x]\n", val); +} +#endif diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/Makefile b/arch/mips/tx4927/toshiba_rbtx4927/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/toshiba_rbtx4927/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,8 @@ +obj-y += toshiba_rbtx4927_prom.o +obj-y += toshiba_rbtx4927_setup.o +obj-y += toshiba_rbtx4927_irq.o + +obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_fixup.o +obj-$(CONFIG_PCI) += toshiba_rbtx4927_pci_ops.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,795 @@ +/* + * linux/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c + * + * Toshiba RBTX4927 specific interrupt handlers + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ + + +/* +IRQ Device +00 RBTX4927-ISA/00 +01 RBTX4927-ISA/01 PS2/Keyboard +02 RBTX4927-ISA/02 Cascade RBTX4927-ISA (irqs 8-15) +03 RBTX4927-ISA/03 +04 RBTX4927-ISA/04 +05 RBTX4927-ISA/05 +06 RBTX4927-ISA/06 +07 RBTX4927-ISA/07 +08 RBTX4927-ISA/08 +09 RBTX4927-ISA/09 +10 RBTX4927-ISA/10 +11 RBTX4927-ISA/11 +12 RBTX4927-ISA/12 PS2/Mouse (not supported at this time) +13 RBTX4927-ISA/13 +14 RBTX4927-ISA/14 IDE +15 RBTX4927-ISA/15 + +16 TX4927-CP0/00 Software 0 +17 TX4927-CP0/01 Software 1 +18 TX4927-CP0/02 Cascade TX4927-CP0 +19 TX4927-CP0/03 Multiplexed -- do not use +20 TX4927-CP0/04 Multiplexed -- do not use +21 TX4927-CP0/05 Multiplexed -- do not use +22 TX4927-CP0/06 Multiplexed -- do not use +23 TX4927-CP0/07 CPU TIMER + +24 TX4927-PIC/00 +25 TX4927-PIC/01 +26 TX4927-PIC/02 +27 TX4927-PIC/03 Cascade RBTX4927-IOC +28 TX4927-PIC/04 +29 TX4927-PIC/05 RBTX4927 RTL-8019AS ethernet +30 TX4927-PIC/06 +31 TX4927-PIC/07 +32 TX4927-PIC/08 TX4927 SerialIO Channel 0 +33 TX4927-PIC/09 TX4927 SerialIO Channel 1 +34 TX4927-PIC/10 +35 TX4927-PIC/11 +36 TX4927-PIC/12 +37 TX4927-PIC/13 +38 TX4927-PIC/14 +39 TX4927-PIC/15 +40 TX4927-PIC/16 TX4927 PCI PCI-C +41 TX4927-PIC/17 +42 TX4927-PIC/18 +43 TX4927-PIC/19 +44 TX4927-PIC/20 +45 TX4927-PIC/21 +46 TX4927-PIC/22 TX4927 PCI PCI-ERR +47 TX4927-PIC/23 TX4927 PCI PCI-PMA (not used) +48 TX4927-PIC/24 +49 TX4927-PIC/25 +50 TX4927-PIC/26 +51 TX4927-PIC/27 +52 TX4927-PIC/28 +53 TX4927-PIC/29 +54 TX4927-PIC/30 +55 TX4927-PIC/31 + +56 RBTX4927-IOC/00 FPCIB0 PCI-D PJ4/A PJ5/B SB/C PJ6/D PJ7/A (SouthBridge/NotUsed) [RTL-8139=PJ4] +57 RBTX4927-IOC/01 FPCIB0 PCI-C PJ4/D PJ5/A SB/B PJ6/C PJ7/D (SouthBridge/NotUsed) [RTL-8139=PJ5] +58 RBTX4927-IOC/02 FPCIB0 PCI-B PJ4/C PJ5/D SB/A PJ6/B PJ7/C (SouthBridge/IDE/pin=1,INTR) [RTL-8139=NotSupported] +59 RBTX4927-IOC/03 FPCIB0 PCI-A PJ4/B PJ5/C SB/D PJ6/A PJ7/B (SouthBridge/USB/pin=4) [RTL-8139=PJ6] +60 RBTX4927-IOC/04 +61 RBTX4927-IOC/05 +62 RBTX4927-IOC/06 +63 RBTX4927-IOC/07 + +NOTES: +SouthBridge/INTR is mapped to SouthBridge/A=PCI-B/#58 +SouthBridge/ISA/pin=0 no pci irq used by this device +SouthBridge/IDE/pin=1 no pci irq used by this device, using INTR via ISA IRQ14 +SouthBridge/USB/pin=4 using pci irq SouthBridge/D=PCI-A=#59 +SouthBridge/PMC/pin=0 no pci irq used by this device +SuperIO/PS2/Keyboard, using INTR via ISA IRQ1 +SuperIO/PS2/Mouse, using INTR via ISA IRQ12 (mouse not currently supported) +JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthBridge, JP4, JP5, JP6 +*/ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <linux/version.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#ifdef CONFIG_RTC_DS1742 +#include <asm/rtc_ds1742.h> +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include <asm/smsc_fdc37m81x.h> +#endif +#include <asm/tx4927/toshiba_rbtx4927.h> + + +#undef TOSHIBA_RBTX4927_IRQ_DEBUG + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_IRQ_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_IRQ_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP ( 1 << 11 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN ( 1 << 12 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_MASK ( 1 << 15 ) +#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) + +#define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP ( 1 << 21 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN ( 1 << 22 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) +#define TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ ( 1 << 26 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +static const u32 toshiba_rbtx4927_irq_debug_flag = + (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | + TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR +// | TOSHIBA_RBTX4927_IRQ_IOC_INIT +// | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP +// | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE +// | TOSHIBA_RBTX4927_IRQ_IOC_MASK +// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ +// | TOSHIBA_RBTX4927_IRQ_ISA_INIT +// | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP +// | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN +// | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE +// | TOSHIBA_RBTX4927_IRQ_ISA_MASK +// | TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ + ); +#endif + + +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_irq_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_IRQ_DPRINTK(flag,str...) +#endif + + + + +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG 0 +#define TOSHIBA_RBTX4927_IRQ_IOC_RAW_END 7 + +#define TOSHIBA_RBTX4927_IRQ_IOC_BEG ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_BEG) /* 56 */ +#define TOSHIBA_RBTX4927_IRQ_IOC_END ((TX4927_IRQ_PIC_END+1)+TOSHIBA_RBTX4927_IRQ_IOC_RAW_END) /* 63 */ + + +#define TOSHIBA_RBTX4927_IRQ_ISA_BEG MI8259_IRQ_ISA_BEG +#define TOSHIBA_RBTX4927_IRQ_ISA_END MI8259_IRQ_ISA_END +#define TOSHIBA_RBTX4927_IRQ_ISA_MID ((TOSHIBA_RBTX4927_IRQ_ISA_BEG+TOSHIBA_RBTX4927_IRQ_ISA_END+1)/2) + + +#define TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC TX4927_IRQ_NEST_EXT_ON_PIC +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC (TOSHIBA_RBTX4927_IRQ_IOC_BEG+2) +#define TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA (TOSHIBA_RBTX4927_IRQ_ISA_BEG+2) + +extern int tx4927_using_backplane; + +#ifdef CONFIG_TOSHIBA_FPCIB0 +extern void enable_8259A_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void mask_and_ack_8259A(unsigned int irq); +#endif + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); +#endif + +static spinlock_t toshiba_rbtx4927_ioc_lock = SPIN_LOCK_UNLOCKED; + + +#define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" +static struct hw_interrupt_type toshiba_rbtx4927_irq_ioc_type = { + typename:TOSHIBA_RBTX4927_IOC_NAME, + startup:toshiba_rbtx4927_irq_ioc_startup, + shutdown:toshiba_rbtx4927_irq_ioc_shutdown, + enable:toshiba_rbtx4927_irq_ioc_enable, + disable:toshiba_rbtx4927_irq_ioc_disable, + ack:toshiba_rbtx4927_irq_ioc_mask_and_ack, + end:toshiba_rbtx4927_irq_ioc_end, + set_affinity:NULL +}; +#define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 +#define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +#define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" +static struct hw_interrupt_type toshiba_rbtx4927_irq_isa_type = { + typename:TOSHIBA_RBTX4927_ISA_NAME, + startup:toshiba_rbtx4927_irq_isa_startup, + shutdown:toshiba_rbtx4927_irq_isa_shutdown, + enable:toshiba_rbtx4927_irq_isa_enable, + disable:toshiba_rbtx4927_irq_isa_disable, + ack:toshiba_rbtx4927_irq_isa_mask_and_ack, + end:toshiba_rbtx4927_irq_isa_end, + set_affinity:NULL +}; +#endif + + +u32 bit2num(u32 num) +{ + u32 i; + + for (i = 0; i < (sizeof(num) * 8); i++) { + if (num & (1 << i)) { + return (i); + } + } + return (0); +} + +int toshiba_rbtx4927_irq_nested(int sw_irq) +{ + u32 level3; + u32 level4; + u32 level5; + + level3 = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + if (level3) { + sw_irq = TOSHIBA_RBTX4927_IRQ_IOC_BEG + bit2num(level3); + if (sw_irq != TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC) { + goto RETURN; + } + } +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + outb(0x0A, 0x20); + level4 = inb(0x20) & 0xff; + if (level4) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_BEG + + bit2num(level4); + if (sw_irq != + TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA) { + goto RETURN; + } + } + + outb(0x0A, 0xA0); + level5 = inb(0xA0) & 0xff; + if (level5) { + sw_irq = + TOSHIBA_RBTX4927_IRQ_ISA_MID + + bit2num(level5); + goto RETURN; + } + } + } +#endif + + RETURN: + return (sw_irq); +} + +//#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, 0, 0, s, NULL, NULL } +#define TOSHIBA_RBTX4927_PIC_ACTION(s) { no_action, SA_SHIRQ, 0, s, NULL, NULL } +static struct irqaction toshiba_rbtx4927_irq_ioc_action = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_IOC_NAME); +#ifdef CONFIG_TOSHIBA_FPCIB0 +static struct irqaction toshiba_rbtx4927_irq_isa_master = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/M"); +static struct irqaction toshiba_rbtx4927_irq_isa_slave = +TOSHIBA_RBTX4927_PIC_ACTION(TOSHIBA_RBTX4927_ISA_NAME "/S"); +#endif + + +/**********************************************************************************/ +/* Functions for ioc */ +/**********************************************************************************/ + + +static void __init toshiba_rbtx4927_irq_ioc_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_IOC_BEG, + TOSHIBA_RBTX4927_IRQ_IOC_END); + + for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 3; + irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, + &toshiba_rbtx4927_irq_ioc_action); + + return; +} + +static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_enable(irq); + + return (0); +} + + +static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) +{ + unsigned long flags; + volatile unsigned char v; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); + + v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); + v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); + TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); + + spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_ioc_disable(irq); + + return; +} + + +static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG + || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_ioc_enable(irq); + } + + return; +} + + +/**********************************************************************************/ +/* Functions for isa */ +/**********************************************************************************/ + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void __init toshiba_rbtx4927_irq_isa_init(void) +{ + int i; + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_INIT, + "beg=%d end=%d\n", + TOSHIBA_RBTX4927_IRQ_ISA_BEG, + TOSHIBA_RBTX4927_IRQ_ISA_END); + + for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; + i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = + ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); + irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; + } + + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, + &toshiba_rbtx4927_irq_isa_master); + setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_ISA, + &toshiba_rbtx4927_irq_isa_slave); + + /* make sure we are looking at IRR (not ISR) */ + outb(0x0A, 0x20); + outb(0x0A, 0xA0); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_enable(irq); + + return (0); +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + toshiba_rbtx4927_irq_isa_disable(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + enable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_DISABLE, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + disable_8259A_irq(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_MASK, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + mask_and_ack_8259A(irq); + + return; +} +#endif + + +#ifdef CONFIG_TOSHIBA_FPCIB0 +static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) +{ + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ, + "irq=%d\n", irq); + + if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG + || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, + "bad irq=%d\n", irq); + panic("\n"); + } + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + toshiba_rbtx4927_irq_isa_enable(irq); + } + + return; +} +#endif + + +void __init init_IRQ(void) +{ + extern void tx4927_irq_init(void); + + cli(); + + tx4927_irq_init(); + toshiba_rbtx4927_irq_ioc_init(); +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + toshiba_rbtx4927_irq_isa_init(); + } + } +#endif + +#ifdef CONFIG_PCI + { + extern void toshiba_rbtx4927_pci_irq_init(void); + toshiba_rbtx4927_pci_irq_init(); + } +#endif + + wbflush(); + + return; +} + +void toshiba_rbtx4927_irq_dump(char *key) +{ +#ifdef TOSHIBA_RBTX4927_IRQ_DEBUG + { + u32 i, j = 0; + for (i = 0; i < NR_IRQS; i++) { + if (strcmp(irq_desc[i].handler->typename, "none") + == 0) + continue; + + if ((i >= 1) + && (irq_desc[i - 1].handler->typename == + irq_desc[i].handler->typename)) { + j++; + } else { + j = 0; + } + TOSHIBA_RBTX4927_IRQ_DPRINTK + (TOSHIBA_RBTX4927_IRQ_INFO, + "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", + key, i, i, irq_desc[i].status, + (u32) irq_desc[i].handler, + (u32) irq_desc[i].action, + (u32) (irq_desc[i].action ? irq_desc[i]. + action->handler : 0), + irq_desc[i].depth, + irq_desc[i].handler->typename, j); + } + } +#endif + return; +} + +void toshiba_rbtx4927_irq_dump_pics(char *s) +{ + u32 level0_m; + u32 level0_s; + u32 level1_m; + u32 level1_s; + u32 level2; + u32 level2_p; + u32 level2_s; + u32 level3_m; + u32 level3_s; + u32 level4_m; + u32 level4_s; + u32 level5_m; + u32 level5_s; + + if (s == NULL) + s = "null"; + + level0_m = (read_c0_status() & 0x0000ff00) >> 8; + level0_s = (read_c0_cause() & 0x0000ff00) >> 8; + + level1_m = level0_m; + level1_s = level0_s & 0x87; + + level2 = TX4927_RD(0xff1ff6a0); + level2_p = (((level2 & 0x10000)) ? 0 : 1); + level2_s = (((level2 & 0x1f) == 0x1f) ? 0 : (level2 & 0x1f)); + + level3_m = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_ENAB) & 0x1f; + level3_s = reg_rd08(TOSHIBA_RBTX4927_IOC_INTR_STAT) & 0x1f; + + level4_m = inb(0x21); + outb(0x0A, 0x20); + level4_s = inb(0x20); + + level5_m = inb(0xa1); + outb(0x0A, 0xa0); + level5_s = inb(0xa0); + + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "dump_raw_pic() "); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level0_m, + level0_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "cp0:m=0x%02x/s=0x%02x ", level1_m, + level1_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "pic:e=0x%02x/s=0x%02x ", level2_p, + level2_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "ioc:m=0x%02x/s=0x%02x ", level3_m, + level3_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbm:m=0x%02x/s=0x%02x ", level4_m, + level4_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, + "sbs:m=0x%02x/s=0x%02x ", level5_m, + level5_s); + TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", + s); + + return; +} diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_fixup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,329 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Board specific pci fixups for the Toshiba rbtx4927 + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/tx4927/tx4927.h> +#include <asm/tx4927/tx4927_pci.h> + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +void __init pcibios_fixup_resources(struct pci_dev *dev) +{ + /* will need to fixup IO resources */ +} + +void __init pcibios_fixup(void) +{ + /* nothing to do here */ +} + +/* look up table for backplane pci irq for slots 17-20 by pin # */ +static unsigned char backplane_pci_irq[4][4] = { + /* PJ6 SLOT: 17, PIN: 1 */ {TX4927_IRQ_IOC_PCIA, + /* PJ6 SLOT: 17, PIN: 2 */ + TX4927_IRQ_IOC_PCIB, + /* PJ6 SLOT: 17, PIN: 3 */ + TX4927_IRQ_IOC_PCIC, + /* PJ6 SLOT: 17, PIN: 4 */ + TX4927_IRQ_IOC_PCID}, + /* SB SLOT: 18, PIN: 1 */ {TX4927_IRQ_IOC_PCIB, + /* SB SLOT: 18, PIN: 2 */ + TX4927_IRQ_IOC_PCIC, + /* SB SLOT: 18, PIN: 3 */ + TX4927_IRQ_IOC_PCID, + /* SB SLOT: 18, PIN: 4 */ + TX4927_IRQ_IOC_PCIA}, + /* PJ5 SLOT: 19, PIN: 1 */ {TX4927_IRQ_IOC_PCIC, + /* PJ5 SLOT: 19, PIN: 2 */ + TX4927_IRQ_IOC_PCID, + /* PJ5 SLOT: 19, PIN: 3 */ + TX4927_IRQ_IOC_PCIA, + /* PJ5 SLOT: 19, PIN: 4 */ + TX4927_IRQ_IOC_PCIB}, + /* PJ4 SLOT: 20, PIN: 1 */ {TX4927_IRQ_IOC_PCID, + /* PJ4 SLOT: 20, PIN: 2 */ + TX4927_IRQ_IOC_PCIA, + /* PJ4 SLOT: 20, PIN: 3 */ + TX4927_IRQ_IOC_PCIB, + /* PJ4 SLOT: 20, PIN: 4 */ + TX4927_IRQ_IOC_PCIC} +}; + +int pci_get_irq(struct pci_dev *dev, int pin) +{ + unsigned char irq = pin; + + DBG("pci_get_irq: pin is %d\n", pin); + /* IRQ rotation */ + irq--; /* 0-3 */ + if (dev->bus->parent == NULL && + PCI_SLOT(dev->devfn) == TX4927_PCIC_IDSEL_AD_TO_SLOT(23)) { + printk("Onboard PCI_SLOT(dev->devfn) is %d\n", + PCI_SLOT(dev->devfn)); + /* IDSEL=A23 is tx4927 onboard pci slot */ + irq = (irq + PCI_SLOT(dev->devfn)) % 4; + irq++; /* 1-4 */ + DBG("irq is now %d\n", irq); + + switch (irq) { + case 1: + irq = TX4927_IRQ_IOC_PCIA; + break; + case 2: + irq = TX4927_IRQ_IOC_PCIB; + break; + case 3: + irq = TX4927_IRQ_IOC_PCIC; + break; + case 4: + irq = TX4927_IRQ_IOC_PCID; + break; + } + } else { + /* PCI Backplane */ + DBG("PCI Backplane PCI_SLOT(dev->devfn) is %d\n", + PCI_SLOT(dev->devfn)); + irq = backplane_pci_irq[PCI_SLOT(dev->devfn) - 17][irq]; + } + DBG("assigned irq %d\n", irq); + return irq; +} + + +#ifdef TX4927_SUPPORT_PCI_66 +extern int tx4927_pci66; +extern void tx4927_pci66_setup(void); +#endif +extern void tx4927_pci_setup(void); + +#ifdef TX4927_SUPPORT_PCI_66 +int tx4927_pci66_check(void) +{ + struct pci_dev *dev; + unsigned short stat; + int cap66 = 1; + + if (tx4927_pci66 < 0) + return 0; + + /* check 66MHz capability */ + pci_for_each_dev(dev) { + if (cap66) { + pci_read_config_word(dev, PCI_STATUS, &stat); + if (!(stat & PCI_STATUS_66MHZ)) { + printk(KERN_INFO + "PCI: %02x:%02x not 66MHz capable.\n", + dev->bus->number, dev->devfn); + cap66 = 0; + } + } + } + return cap66; +} +#endif + +#ifdef DEBUG +void do_it(u32 offset, u32 reg) +{ + volatile u32 a1; + volatile u32 a2; + volatile u32 v1; + volatile u32 v2; + + a1 = 0xff1f0000 + offset + reg; + a2 = a1 + 4; + + v1 = *(volatile u32 *) a1; + v2 = *(volatile u32 *) a2; + + if (v1) + printk("TX4927 0x%08x 0x%08x\n", a1, v1); + if (v2) + printk("TX4927 0x%08x 0x%08x\n", a2, v2); +} + +void do_it1(u32 base, u32 r) +{ + do_it(base, r); +} + +void do_it2(u32 base, u32 start, u32 stop) +{ + u32 r; + + for (r = start; r <= stop; r += 8) { + do_it(base, r); + } +} +void dump_config(void) +{ + unsigned long id; + unsigned long j; + struct pci_dev *dev; + + printk("----------------------pci\n"); + pci_for_each_dev(dev) { + for (j = 0; j < 64; j++) { + pci_read_config_dword(dev, j * 4, &id); + if (id == 0) + continue; + printk + ("dev 0x%02x 0x%02x:0x%02x -- 0x%02x-0x%02x 0x%08x\n", + dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), (j * 4) + 3, (j * 4), + id); + } + printk("dev 0x%02x \n", dev->devfn); + } + printk("----------------------sdram\n"); + do_it2(0x8000, 0x00, 0x18); + do_it1(0x8000, 0x40); + do_it1(0x8000, 0x58); + printk("----------------------ebus\n"); + do_it2(0x9000, 0x00, 0x38); + printk("----------------------ecc\n"); + do_it2(0xa000, 0x00, 0x08); + printk("----------------------dmac\n"); + do_it2(0xb000, 0x00, 0xf8); + /* b1xx */ + printk("----------------------pci\n"); + /* d */ + printk("----------------------cfg\n"); + do_it2(0xe000, 0x00, 0x20); + do_it1(0xe000, 0x30); + do_it1(0xe000, 0x48); + printk("----------------------timers\n"); + do_it2(0xf000, 0x00, 0xf0); + do_it2(0xf100, 0x00, 0xf0); + do_it2(0xf200, 0x00, 0xf0); + printk("----------------------serial\n"); + do_it2(0xf300, 0x00, 0x20); + do_it2(0xf400, 0x00, 0x20); + printk("----------------------parallel\n"); + do_it2(0xf500, 0x00, 0x0c); + printk("----------------------pic\n"); + do_it2(0xf500, 0x10, 0x24); + do_it2(0xf600, 0x00, 0x2c); + do_it1(0xf600, 0x40); + do_it1(0xf600, 0x60); + do_it1(0xf600, 0x80); + do_it1(0xf600, 0xa0); + printk("----------------------aclink\n"); + do_it2(0xf700, 0x00, 0xfc); + printk("----------------------done\n"); +} +#endif + + +void __init pcibios_fixup_irqs(void) +{ + unsigned char pin; + unsigned char irq; + struct pci_dev *dev; + unsigned int id; + +#ifdef TX4927_SUPPORT_PCI_66 + { + if (tx4927_pci66_check()) { + tx4927_pci66_setup(); + tx4927_pci_setup(); /* Reinitialize PCIC */ + } + } +#endif + + pci_for_each_dev(dev) { + DBG("FIXUP:\n"); + DBG(" devfn=0x%02x (0x%02x:0x%02x)\n", + dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + + pci_read_config_dword(dev, PCI_VENDOR_ID, &id); + DBG(" id=0x%08x\n", id); + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + DBG(" line=0x%02x/%d\n", irq, irq); + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + DBG(" pin=%d\n", pin); + +#ifdef DEBUG + { + unsigned int tmp; + pci_read_config_dword(dev, 0x10, &tmp); + DBG(" bar0:0x10=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x14, &tmp); + DBG(" bar1:0x14=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x1c, &tmp); + DBG(" bar2:0x1c=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x20, &tmp); + DBG(" bar3:0x20=0x%08x\n", tmp); + pci_read_config_dword(dev, 0x24, &tmp); + DBG(" bar4:0x24=0x%08x\n", tmp); + } +#endif + + irq = 0; + + if (id == 0x91301055) { /* ide */ + irq = 14; + } + + if (pin == 0) { + DBG(" auto irq (now=%d) -- skipping pin=0\n", irq); + } else if (irq) { + DBG(" auto irq (now=%d) -- skipping hardcoded irq\n", irq); + } else { + DBG(" auto irq (was=%d)\n", irq); + irq = pci_get_irq(dev, pin); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, + irq); + dev->irq = irq; + DBG(" auto irq (now=%d)\n", irq); + } + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + printk(KERN_INFO + "PCI: 0x%02x:0x%02x(0x%02x,0x%02x) IRQ=%d\n", + dev->bus->number, dev->devfn, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), irq); + + } + +} diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_pci_ops.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,317 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c + * + * Define the pci_ops for the Toshiba rbtx4927 + * + * Much of the code is derived from the original DDB5074 port by + * Geert Uytterhoeven <geert@sonycom.com> + * + * 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 <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/addrspace.h> +#include <asm/pci_channel.h> +#include <asm/tx4927/tx4927_pci.h> +#include <asm/debug.h> + +/* initialize in setup */ +struct resource pci_io_resource = { + "pci IO space", + (PCIBIOS_MIN_IO), + ((PCIBIOS_MIN_IO) + (TX4927_PCIIO_SIZE)) - 1, + IORESOURCE_IO +}; + +/* initialize in setup */ +struct resource pci_mem_resource = { + "pci memory space", + TX4927_PCIMEM, + TX4927_PCIMEM + TX4927_PCIMEM_SIZE - 1, + IORESOURCE_MEM +}; + +extern struct pci_ops tx4927_pci_ops; + +struct pci_channel mips_pci_channels[] = { + /* h/w only supports devices 0x00 to 0x14 */ + {&tx4927_pci_ops, &pci_io_resource, &pci_mem_resource, + PCI_DEVFN(0x00, 0), PCI_DEVFN(0x14, 7)}, + {NULL, NULL, NULL, 0, 0} +}; + +unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} + +static int +mkaddr(unsigned char bus, unsigned char dev_fn, unsigned char where, + int *flagsp) +{ + if (bus > 0) { + /* Type 1 configuration */ + tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1; + } else { + if (dev_fn >= PCI_DEVFN(TX4927_PCIC_MAX_DEVNU, 0)) + return -1; + + /* Type 0 configuration */ + tx4927_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) | + ((dev_fn & 0xff) << 0x08) | (where & 0xfc); + } + /* clear M_ABORT and Disable M_ABORT Int. */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (PCI_STATUS_REC_MASTER_ABORT << 16); + tx4927_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT; + return 0; +} + +static int check_abort(int flags) +{ + int code = PCIBIOS_SUCCESSFUL; + if (tx4927_pcicptr-> + pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + tx4927_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT; + code = PCIBIOS_DEVICE_NOT_FOUND; + // printk("returning PCIBIOS_DEVICE_NOT_FOUND\n"); + } + return code; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int tx4927_pcibios_read_config_byte(struct pci_dev *dev, + int where, unsigned char *val) +{ + int flags, retval; + unsigned char bus, func_num; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *val = + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 3)); +#else + *val = + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)); +#endif + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xff; +//printk("CFG R1 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_read_config_word(struct pci_dev *dev, + int where, unsigned short *val) +{ + int flags, retval; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *val = + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 2)); +#else + *val = + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)); +#endif + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xffff; +//printk("CFG R2 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_read_config_dword(struct pci_dev *dev, + int where, unsigned int *val) +{ + int flags, retval; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + *val = tx4927_pcicptr->g2pcfgdata; + retval = check_abort(flags); + if (retval == PCIBIOS_DEVICE_NOT_FOUND) + *val = 0xffffffff; + +//printk("CFG R4 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, *val ); + return retval; +} + +static int tx4927_pcibios_write_config_byte(struct pci_dev *dev, + int where, unsigned char val) +{ + int flags; + unsigned char bus, func_num; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 3)) = val; +#else + *(volatile u8 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)) = val; +#endif +//printk("CFG W1 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +static int tx4927_pcibios_write_config_word(struct pci_dev *dev, + int where, unsigned short val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; +#ifdef __BIG_ENDIAN + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | ((where & 3) ^ 2)) = val; +#else + *(volatile u16 *) ((ulong) & tx4927_pcicptr-> + g2pcfgdata | (where & 3)) = val; +#endif +//printk("CFG W2 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +static int tx4927_pcibios_write_config_dword(struct pci_dev *dev, + int where, unsigned int val) +{ + int flags; + unsigned char bus, func_num; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + + /* check if the bus is top-level */ + if (dev->bus->parent != NULL) { + bus = dev->bus->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + func_num = PCI_FUNC(dev->devfn); + if (mkaddr(bus, dev->devfn, where, &flags)) + return -1; + tx4927_pcicptr->g2pcfgdata = val; +//printk("CFG W4 0x%02x 0x%02x 0x%08x\n", dev->devfn, where, val ); + return check_abort(flags); +} + +struct pci_ops tx4927_pci_ops = { + tx4927_pcibios_read_config_byte, + tx4927_pcibios_read_config_word, + tx4927_pcibios_read_config_dword, + tx4927_pcibios_write_config_byte, + tx4927_pcibios_write_config_word, + tx4927_pcibios_write_config_dword +}; diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,96 @@ +/* + * rbtx4927 specific prom routines + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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 <linux/init.h> +#include <linux/mm.h> +#include <linux/sched.h> +#include <linux/bootmem.h> + +#include <asm/addrspace.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/tx4927/tx4927.h> + +#ifndef COMMAND_LINE_SIZE +#define COMMAND_LINE_SIZE CL_SIZE +#endif + +char arcs_cmdline[COMMAND_LINE_SIZE] = "console=ttyS0,38400 ip=any root=nfs rw"; + +void __init prom_init_cmdline(int argc, char **argv) +{ + int i; /* Always ignore the "-c" at argv[0] */ + + /* ignore all built-in args if any f/w args given */ + if (argc > 1) { + *arcs_cmdline = '\0'; + } + + for (i = 1; i < argc; i++) { + if (i != 1) { + strcat(arcs_cmdline, " "); + } + strcat(arcs_cmdline, argv[i]); + } +} + +void __init prom_init(int argc, char **argv, char **envp, int *pvec) +{ + extern int tx4927_get_mem_size(void); + int msize; + const char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES; + extern char* toshiba_name; + + prom_init_cmdline(argc, argv); + + mips_machgroup = MACH_GROUP_TOSHIBA; + + if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) + mips_machtype = MACH_TOSHIBA_RBTX4927; + else + mips_machtype = MACH_TOSHIBA_RBTX4937; + + toshiba_name = toshiba_name_list[mips_machtype]; + + msize = tx4927_get_mem_size(); + add_memory_region(0, msize << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory(void) +{ +} + + +void __init prom_fixup_mem_map(unsigned long start, unsigned long end) +{ +} + +const char *get_system_type(void) +{ + return "Toshiba RBTX4927/RBTX4937"; +} diff -Nru a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1218 @@ +/* + * Toshiba rbtx4927 specific setup + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 MontaVista Software Inc. + * + * Copyright (C) 1996, 1997, 2001 Ralf Baechle + * Copyright (C) 2000 RidgeRun, Inc. + * Author: RidgeRun, Inc. + * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com + * + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * Copyright 2002 MontaVista Software Inc. + * Author: Michael Pruznick, michael_pruznick@mvista.com + * + * Copyright (C) 2000-2001 Toshiba Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS 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 <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/timex.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/bootinfo.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/pci.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <linux/version.h> +#include <linux/bootmem.h> +#include <linux/blk.h> +#include <linux/console.h> +#ifdef CONFIG_RTC_DS1742 +#include <asm/rtc_ds1742.h> +#endif +#ifdef CONFIG_TOSHIBA_FPCIB0 +#include <asm/smsc_fdc37m81x.h> +#endif +#include <asm/tx4927/toshiba_rbtx4927.h> +#ifdef CONFIG_PCI +#include <asm/tx4927/tx4927_pci.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <asm/pci_channel.h> +#endif +#ifdef CONFIG_PC_KEYB +#include <asm/keyboard.h> +#endif +#ifdef CONFIG_BLK_DEV_IDEPCI +#include <linux/hdreg.h> +#include <asm/ptrace.h> +#include <linux/ide.h> +extern struct ide_ops std_ide_ops; +#endif + +#undef TOSHIBA_RBTX4927_SETUP_DEBUG + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_NONE 0x00000000 + +#define TOSHIBA_RBTX4927_SETUP_INFO ( 1 << 0 ) +#define TOSHIBA_RBTX4927_SETUP_WARN ( 1 << 1 ) +#define TOSHIBA_RBTX4927_SETUP_EROR ( 1 << 2 ) + +#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) +#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) +#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 ) +#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 ) +#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) +#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) +#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) +#define TOSHIBA_RBTX4927_SETUP_PCI66 ( 1 << 10 ) + +#define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +static const u32 toshiba_rbtx4927_setup_debug_flag = + (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | + TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR | + TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP | + TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP + | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | + TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); +#endif + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) \ + if ( (toshiba_rbtx4927_setup_debug_flag) & (flag) ) \ + { \ + char tmp[100]; \ + sprintf( tmp, str ); \ + printk( "%s(%s:%u)::%s", __FUNCTION__, __FILE__, __LINE__, tmp ); \ + } +#else +#define TOSHIBA_RBTX4927_SETUP_DPRINTK(flag,str...) +#endif + +/* These functions are used for rebooting or halting the machine*/ +extern void toshiba_rbtx4927_restart(char *command); +extern void toshiba_rbtx4927_halt(void); +extern void toshiba_rbtx4927_power_off(void); + +int tx4927_using_backplane = 0; + +extern void gt64120_time_init(void); +extern void toshiba_rbtx4927_irq_setup(void); + +#ifdef CONFIG_PCI +#define CONFIG_TX4927BUG_WORKAROUND +#undef TX4927_SUPPORT_COMMAND_IO +#undef TX4927_SUPPORT_PCI_66 +int tx4927_cpu_clock = 100000000; /* 100MHz */ +unsigned long mips_pci_io_base; +unsigned long mips_pci_io_size; +unsigned long mips_pci_mem_base; +unsigned long mips_pci_mem_size; +/* for legacy I/O, PCI I/O PCI Bus address must be 0 */ +unsigned long mips_pci_io_pciaddr = 0; +unsigned long mips_memory_upper; +static int tx4927_ccfg_toeon = 1; +static int tx4927_pcic_trdyto = 0; /* default: disabled */ +unsigned long tx4927_ce_base[8]; +void tx4927_pci_setup(void); +void tx4927_reset_pci_pcic(void); +#ifdef TX4927_SUPPORT_PCI_66 +void tx4927_pci66_setup(void); +extern int tx4927_pci66_check(void); +#endif +int tx4927_pci66 = 0; /* 0:auto */ +#endif + +char *toshiba_name = ""; + +#ifdef CONFIG_PCI +void tx4927_dump_pcic_settings(void) +{ + printk("%s pcic settings:",toshiba_name); + { + int i; + unsigned long *preg = (unsigned long *) tx4927_pcicptr; + for (i = 0; i < sizeof(struct tx4927_pcic_reg); i += 4) { + if (i % 32 == 0) + printk("\n%04x:", i); + if (preg == &tx4927_pcicptr->g2pintack + || preg == &tx4927_pcicptr->g2pspc +#ifdef CONFIG_TX4927BUG_WORKAROUND + || preg == &tx4927_pcicptr->g2pcfgadrs + || preg == &tx4927_pcicptr->g2pcfgdata +#endif + ) { + printk(" XXXXXXXX"); + preg++; + continue; + } + printk(" %08lx", *preg++); + if (preg == &tx4927_pcicptr->g2pcfgadrs) + break; + } + printk("\n"); + } +} + +static void tx4927_pcierr_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + extern void tx4927_dump_pcic_settings(void); + +#ifdef CONFIG_BLK_DEV_IDEPCI + /* ignore MasterAbort for ide probing... */ + if (irq == TX4927_IRQ_IRC_PCIERR && + ((tx4927_pcicptr->pcistatus >> 16) & 0xf900) == + PCI_STATUS_REC_MASTER_ABORT) { + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr-> + pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT + << 16); + + return; + } +#endif + printk("PCI error interrupt (irq 0x%x).\n", irq); + printk("pcistat:%04x, g2pstatus:%08lx, pcicstatus:%08lx\n", + (unsigned short) (tx4927_pcicptr->pcistatus >> 16), + tx4927_pcicptr->g2pstatus, tx4927_pcicptr->pcicstatus); + printk("ccfg:%08lx, tear:%02lx_%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg, + (unsigned long) (tx4927_ccfgptr->tear >> 32), + (unsigned long) tx4927_ccfgptr->tear); + show_regs(regs); + //tx4927_dump_pcic_settings(); + panic("PCI error at PC:%08lx.", regs->cp0_epc); +} + +static struct irqaction pcic_action = { + tx4927_pcierr_interrupt, 0, 0, "PCI-C", NULL, NULL +}; + +static struct irqaction pcierr_action = { + tx4927_pcierr_interrupt, 0, 0, "PCI-ERR", NULL, NULL +}; + + +void __init toshiba_rbtx4927_pci_irq_init(void) +{ + setup_irq(TX4927_IRQ_IRC_PCIC, &pcic_action); + setup_irq(TX4927_IRQ_IRC_PCIERR, &pcierr_action); + return; +} + +void tx4927_reset_pci_pcic(void) +{ + /* Reset PCI Bus */ + *tx4927_pcireset_ptr = 1; + /* Reset PCIC */ + tx4927_ccfgptr->clkctr |= TX4927_CLKCTR_PCIRST; + udelay(10000); + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + *tx4927_pcireset_ptr = 0; +} +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_PCI +#ifdef TX4927_SUPPORT_PCI_66 +void tx4927_pci66_setup(void) +{ + int pciclk, pciclkin = 1; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, + "-\n"); + + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) + return; + + tx4927_reset_pci_pcic(); + + /* Assert M66EN */ + tx4927_ccfgptr->ccfg |= TX4927_CCFG_PCI66; + /* set PCICLK 66MHz */ + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + unsigned int pcidivmode = 0; + pcidivmode = + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK; + if (tx4927_cpu_clock >= 170000000) { + /* CPU 200MHz */ + pcidivmode = TX4927_CCFG_PCIDIVMODE_3; + pciclk = tx4927_cpu_clock / 3; + } else { + /* CPU 166MHz */ + pcidivmode = TX4927_CCFG_PCIDIVMODE_2_5; + pciclk = tx4927_cpu_clock * 2 / 5; + } + tx4927_ccfgptr->ccfg = + (tx4927_ccfgptr->ccfg & ~TX4927_CCFG_PCIDIVMODE_MASK) + | pcidivmode; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCI66, + ":PCICLK: ccfg:0x%08lx\n", + (unsigned long) tx4927_ccfgptr->ccfg); + } else { + int pciclk_setting = *tx4927_pci_clk_ptr; + pciclkin = 0; + pciclk = 66666666; + pciclk_setting &= ~TX4927_PCI_CLK_MASK; + pciclk_setting |= TX4927_PCI_CLK_66; + *tx4927_pci_clk_ptr = pciclk_setting; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCI66, + "PCICLK: pci_clk:%02x\n", *tx4927_pci_clk_ptr); + } + + udelay(10000); + + /* clear PCIC reset */ + tx4927_ccfgptr->clkctr &= ~TX4927_CLKCTR_PCIRST; + /* clear PCI reset */ + *tx4927_pcireset_ptr = 0; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI66, + "+\n"); + return; +} +#endif /* TX4927_SUPPORT_PCI_66 */ + +void print_pci_status(void) +{ + printk("PCI STATUS %lx\n", tx4927_pcicptr->pcistatus); + printk("PCIC STATUS %lx\n", tx4927_pcicptr->pcicstatus); +} + +static struct pci_dev *fake_pci_dev(struct pci_channel *hose, + int top_bus, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose->pci_ops; + + if (busnr != top_bus) + /* Fake a parent bus structure. */ + bus.parent = &bus; + else + bus.parent = NULL; + + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +static int early_##rw##_config_##size(struct pci_channel *hose, \ + int top_bus, int bus, int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size( \ + fake_pci_dev(hose, top_bus, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) + +static int __init tx4927_pcibios_init(int busno, struct pci_channel *hose) +{ + u32 pci_devfn; + int devfn_start = 0; + int devfn_stop = 0xff; + unsigned int id; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "-\n"); + + if (hose->first_devfn) + devfn_start = hose->first_devfn; + if (hose->last_devfn) + devfn_stop = hose->last_devfn; + + for (pci_devfn = devfn_start; pci_devfn < devfn_stop; pci_devfn++) { + early_read_config_dword(hose, busno, busno, pci_devfn, + PCI_VENDOR_ID, &id); + + if (id == 0xffffffff) { + continue; + } + + if (id == 0x94601055) { + u8 v08_64; + u32 v32_b0; + u8 v08_e1; + char *s = " sb/isa --"; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, &v08_e1); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0xe1 = 0x%02x\n", s, v08_e1); + + /* serial irq control */ + v08_64 = 0xd0; + + /* serial irq pin */ + v32_b0 |= 0x00010000; + + /* ide irq on isa14 */ + v08_e1 &= 0xf0; + v08_e1 |= 0x0d; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0xe1 = 0x%02x\n", s, v08_e1); + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x64, v08_64); + early_write_config_dword(hose, busno, busno, + pci_devfn, 0xb0, v32_b0); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0xe1, v08_e1); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x64, + &v08_64); + early_read_config_dword(hose, busno, busno, + pci_devfn, 0xb0, + &v32_b0); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0xe1, + &v08_e1); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x64 = 0x%02x\n", s, v08_64); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xb0 = 0x%02x\n", s, v32_b0); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0xe1 = 0x%02x\n", s, v08_e1); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + if (id == 0x91301055) { + u8 v08_04; + u8 v08_09; + u8 v08_41; + u8 v08_43; + u8 v08_5c; + char *s = " sb/ide --"; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s beg\n", + s); + + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, &v08_5c); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s beg 0x5c = 0x%02x\n", s, v08_5c); + + /* enable ide master/io */ + v08_04 |= (PCI_COMMAND_MASTER | PCI_COMMAND_IO); + + /* enable ide native mode */ + v08_09 |= 0x05; + + /* enable primary ide */ + v08_41 |= 0x80; + + /* enable secondary ide */ + v08_43 |= 0x80; + + /* + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + * + * This line of code is intended to provide the user with a work + * around solution to the anomalies cited in SMSC's anomaly sheet + * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"". + * + * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! + */ + v08_5c |= 0x01; + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s mid 0x5c = 0x%02x\n", s, v08_5c); + + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x5c, v08_5c); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x04, v08_04); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x09, v08_09); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x41, v08_41); + early_write_config_byte(hose, busno, busno, + pci_devfn, 0x43, v08_43); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x04, + &v08_04); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x09, + &v08_09); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x41, + &v08_41); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x43, + &v08_43); + early_read_config_byte(hose, busno, busno, + pci_devfn, 0x5c, + &v08_5c); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x04 = 0x%02x\n", s, v08_04); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x09 = 0x%02x\n", s, v08_09); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x41 = 0x%02x\n", s, v08_41); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x43 = 0x%02x\n", s, v08_43); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, + ":%s end 0x5c = 0x%02x\n", s, v08_5c); + } +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_PCIBIOS, ":%s end\n", + s); + } + + } + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCIBIOS, + "+\n"); + + return (busno); +} + +extern struct resource pci_io_resource; +extern struct resource pci_mem_resource; + +void tx4927_pci_setup(void) +{ + static int called = 0; + extern unsigned int tx4927_get_mem_size(void); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "-\n"); + +#ifndef TX4927_SUPPORT_PCI_66 + if (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) + printk("PCI 66 current unsupported\n"); +#endif + + mips_memory_upper = tx4927_get_mem_size() << 20; + mips_memory_upper += KSEG0; + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_memory_upper\n", + mips_memory_upper); + mips_pci_io_base = TX4927_PCIIO; + mips_pci_io_size = TX4927_PCIIO_SIZE; + mips_pci_mem_base = TX4927_PCIMEM; + mips_pci_mem_size = TX4927_PCIMEM_SIZE; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_base\n", + mips_pci_io_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_io_size\n", + mips_pci_io_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_base\n", + mips_pci_mem_base); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_pci_mem_size\n", + mips_pci_mem_size); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.start\n", + pci_io_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_io_resource.end\n", + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.start\n", + pci_mem_resource.start); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=pci_mem_resource.end\n", + pci_mem_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "0x%08lx=mips_io_port_base", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_io_resource to 0x%08lx 0x%08lx\n", + pci_io_resource.start, + pci_io_resource.end); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + "setup pci_mem_resource to 0x%08lx 0x%08lx\n", + pci_mem_resource.start, + pci_mem_resource.end); + + if (!called) { + printk + ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", + (unsigned short) (tx4927_pcicptr->pciid >> 16), + (unsigned short) (tx4927_pcicptr->pciid & 0xffff), + (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), + (!(tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB)) ? "External" : + "Internal"); + called = 1; + } + printk("%s PCIC --%s PCICLK:",toshiba_name, + (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); + if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { + int pciclk = 0; + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + pciclk = tx4927_cpu_clock * 2 / 5; + break; + case TX4927_CCFG_PCIDIVMODE_3: + pciclk = tx4927_cpu_clock / 3; + break; + case TX4927_CCFG_PCIDIVMODE_5: + pciclk = tx4927_cpu_clock / 5; + break; + case TX4927_CCFG_PCIDIVMODE_6: + pciclk = tx4927_cpu_clock / 6; + break; + } + printk("Internal(%dMHz)", pciclk / 1000000); + } else { + int pciclk = 0; + int pciclk_setting = *tx4927_pci_clk_ptr; + switch (pciclk_setting & TX4927_PCI_CLK_MASK) { + case TX4927_PCI_CLK_33: + pciclk = 33333333; + break; + case TX4927_PCI_CLK_25: + pciclk = 25000000; + break; + case TX4927_PCI_CLK_66: + pciclk = 66666666; + break; + case TX4927_PCI_CLK_50: + pciclk = 50000000; + break; + } + printk("External(%dMHz)", pciclk / 1000000); + } + printk("\n"); + + + + /* GB->PCI mappings */ + tx4927_pcicptr->g2piomask = (mips_pci_io_size - 1) >> 4; + tx4927_pcicptr->g2piogbase = mips_pci_io_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PIOGBASE_ECHG +#else + TX4927_PCIC_G2PIOGBASE_BSDIS +#endif + ; + + tx4927_pcicptr->g2piopbase = 0; + + tx4927_pcicptr->g2pmmask[0] = (mips_pci_mem_size - 1) >> 4; + tx4927_pcicptr->g2pmgbase[0] = mips_pci_mem_base | +#ifdef __BIG_ENDIAN + TX4927_PCIC_G2PMnGBASE_ECHG +#else + TX4927_PCIC_G2PMnGBASE_BSDIS +#endif + ; + tx4927_pcicptr->g2pmpbase[0] = mips_pci_mem_base; + + tx4927_pcicptr->g2pmmask[1] = 0; + tx4927_pcicptr->g2pmgbase[1] = 0; + tx4927_pcicptr->g2pmpbase[1] = 0; + tx4927_pcicptr->g2pmmask[2] = 0; + tx4927_pcicptr->g2pmgbase[2] = 0; + tx4927_pcicptr->g2pmpbase[2] = 0; + + + /* PCI->GB mappings (I/O 256B) */ + tx4927_pcicptr->p2giopbase = 0; /* 256B */ + + +#ifdef TX4927_SUPPORT_COMMAND_IO + tx4927_pcicptr->p2giogbase = 0 | TX4927_PCIC_P2GIOGBASE_TIOEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GIOGBASE_TECHG +#else + TX4927_PCIC_P2GIOGBASE_TBSDIS +#endif + ; +#else + tx4927_pcicptr->p2giogbase = 0; +#endif + + /* PCI->GB mappings (MEM 512MB) M0 gets all of memory */ + tx4927_pcicptr->p2gm0plbase = 0; + tx4927_pcicptr->p2gm0pubase = 0; + tx4927_pcicptr->p2gmgbase[0] = 0 | TX4927_PCIC_P2GMnGBASE_TMEMEN | +#ifdef __BIG_ENDIAN + TX4927_PCIC_P2GMnGBASE_TECHG +#else + TX4927_PCIC_P2GMnGBASE_TBSDIS +#endif + ; + + /* PCI->GB mappings (MEM 16MB) -not used */ + tx4927_pcicptr->p2gm1plbase = 0xffffffff; +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-PCIC-BUG: P2GM1PUBASE must be 0 + * if P2GM0PUBASE was 0. + */ + tx4927_pcicptr->p2gm1pubase = 0; +#else + tx4927_pcicptr->p2gm1pubase = 0xffffffff; +#endif + tx4927_pcicptr->p2gmgbase[1] = 0; + + /* PCI->GB mappings (MEM 1MB) -not used */ + tx4927_pcicptr->p2gm2pbase = 0xffffffff; + tx4927_pcicptr->p2gmgbase[2] = 0; + + + /* Enable Initiator Memory 0 Space, I/O Space, Config */ + tx4927_pcicptr->pciccfg &= TX4927_PCIC_PCICCFG_LBWC_MASK; + tx4927_pcicptr->pciccfg |= + TX4927_PCIC_PCICCFG_IMSE0 | TX4927_PCIC_PCICCFG_IISE | + TX4927_PCIC_PCICCFG_ICAE | TX4927_PCIC_PCICCFG_ATR; + + + /* Do not use MEMMUL, MEMINF: YMFPCI card causes M_ABORT. */ + tx4927_pcicptr->pcicfg1 = 0; + + if (tx4927_pcic_trdyto >= 0) { + tx4927_pcicptr->g2ptocnt &= ~0xff; + tx4927_pcicptr->g2ptocnt |= (tx4927_pcic_trdyto & 0xff); + //printk("%s PCIC -- TRDYTO:%02lx\n",toshiba_name, + // tx4927_pcicptr->g2ptocnt & 0xff); + } + + /* Clear All Local Bus Status */ + tx4927_pcicptr->pcicstatus = TX4927_PCIC_PCICSTATUS_ALL; + /* Enable All Local Bus Interrupts */ + tx4927_pcicptr->pcicmask = TX4927_PCIC_PCICSTATUS_ALL; + /* Clear All Initiator Status */ + tx4927_pcicptr->g2pstatus = TX4927_PCIC_G2PSTATUS_ALL; + /* Enable All Initiator Interrupts */ + tx4927_pcicptr->g2pmask = TX4927_PCIC_G2PSTATUS_ALL; + /* Clear All PCI Status Error */ + tx4927_pcicptr->pcistatus = + (tx4927_pcicptr->pcistatus & 0x0000ffff) | + (TX4927_PCIC_PCISTATUS_ALL << 16); + /* Enable All PCI Status Error Interrupts */ + tx4927_pcicptr->pcimask = TX4927_PCIC_PCISTATUS_ALL; + + /* PCIC Int => IRC IRQ16 */ + tx4927_pcicptr->pcicfg2 = + (tx4927_pcicptr->pcicfg2 & 0xffffff00) | TX4927_IR_PCIC; + + if (!(tx4927_ccfgptr->ccfg & TX4927_CCFG_PCIXARB)) { + /* XXX */ + } else { + /* Reset Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_RPBA; + /* Enable Bus Arbiter */ + tx4927_pcicptr->pbacfg = TX4927_PCIC_PBACFG_PBAEN; + } + + tx4927_pcicptr->pcistatus = PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY | +#ifdef TX4927_SUPPORT_COMMAND_IO + PCI_COMMAND_IO | +#endif + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, + ":pci setup complete:\n"); + //tx4927_dump_pcic_settings(); + + { + struct pci_channel *p; + int busno; + + busno = 0; + for (p = mips_pci_channels; p->pci_ops != NULL; p++) { + busno = tx4927_pcibios_init(busno, p) + 1; + } + } + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, "+\n"); +} + +#endif /* CONFIG_PCI */ + +void toshiba_rbtx4927_restart(char *command) +{ + printk(KERN_NOTICE "System Rebooting...\n"); + + /* enable the s/w reset register */ + reg_wr08(RBTX4927_SW_RESET_ENABLE, RBTX4927_SW_RESET_ENABLE_SET); + + /* wait for enable to be seen */ + while ((reg_rd08(RBTX4927_SW_RESET_ENABLE) & + RBTX4927_SW_RESET_ENABLE_SET) == 0x00); + + /* do a s/w reset */ + reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET); + + /* do something passive while waiting for reset */ + cli(); + while (1) + asm_wait(); + + /* no return */ +} + + +void toshiba_rbtx4927_halt(void) +{ + printk(KERN_NOTICE "System Halted\n"); + cli(); + while (1) { + asm_wait(); + } + /* no return */ +} + +void toshiba_rbtx4927_power_off(void) +{ + toshiba_rbtx4927_halt(); + /* no return */ +} + +void __init toshiba_rbtx4927_setup(void) +{ + vu32 cp0_config; + + printk("CPU is %s\n", toshiba_name); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "-\n"); + + /* f/w leaves this on at startup */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Clearing STO_ERL.\n"); + clear_c0_status(ST0_ERL); + + /* enable caches -- HCP5 does this, pmon does not */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Enabling TX49_CONF_IC,TX49_CONF_DC.\n"); + cp0_config = read_c0_config(); + cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC); + write_c0_config(cp0_config); + +#ifdef TOSHIBA_RBTX4927_SETUP_DEBUG + { + extern void dump_cp0(char *); + dump_cp0("toshiba_rbtx4927_early_fw_fixup"); + } +#endif + + /* setup irq stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 pic.\n"); + TX4927_WR(0xff1ff604, 0x00000400); /* irq trigger */ + TX4927_WR(0xff1ff608, 0x00000000); /* irq trigger */ + + /* setup serial stuff */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Setting up tx4927 sio.\n"); + TX4927_WR(0xff1ff314, 0x00000000); /* h/w flow control off */ + TX4927_WR(0xff1ff414, 0x00000000); /* h/w flow control off */ + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); + + + + mips_io_port_base = KSEG1 + TBTX4927_ISA_IO_OFFSET; + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":mips_io_port_base=0x%08lx\n", + mips_io_port_base); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":Resource\n"); + ioport_resource.start = 0; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0; + iomem_resource.end = 0xffffffff; + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + ":ResetRoutines\n"); + _machine_restart = toshiba_rbtx4927_restart; + _machine_halt = toshiba_rbtx4927_halt; + _machine_power_off = toshiba_rbtx4927_power_off; + + +#ifdef CONFIG_BLK_DEV_IDEPCI + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":ide_ops=&std_ide_ops(modified)\n"); + ide_ops = &std_ide_ops; + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":ide_ops=<NOT_CONFIG>\n"); + } +#endif + +#ifdef CONFIG_FB + { + conswitchp = &dummy_con; + } +#endif + + + + +#ifdef CONFIG_PCI + + /* PCIC */ + /* + * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. + * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1). + * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) + * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) + * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) + * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) + * i.e. S9[3]: ON (83MHz), OFF (100MHz) + */ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "ccfg is %lx, DIV is %x\n", + (unsigned long) tx4927_ccfgptr-> + ccfg, TX4927_CCFG_PCIDIVMODE_MASK); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCI66, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIMIDE, + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIXARB); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, + "PCIDIVMODE is %lx\n", + (unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK); + + switch ((unsigned long) tx4927_ccfgptr-> + ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { + case TX4927_CCFG_PCIDIVMODE_2_5: + case TX4927_CCFG_PCIDIVMODE_5: + tx4927_cpu_clock = 166000000; /* 166MHz */ + break; + default: + tx4927_cpu_clock = 200000000; /* 200MHz */ + } + + /* CCFG */ + /* enable Timeout BusError */ + if (tx4927_ccfg_toeon) + tx4927_ccfgptr->ccfg |= TX4927_CCFG_TOE; + + /* SDRAMC fixup */ +#ifdef CONFIG_TX4927BUG_WORKAROUND + /* + * TX4927-BUG: INF 01-01-18/ BUG 01-01-22 + * G-bus timeout error detection is incorrect + */ + if (tx4927_ccfg_toeon) + tx4927_sdramcptr->tr |= 0x02000000; /* RCD:3tck */ +#endif + +#ifdef TX4927_SUPPORT_PCI_66 + tx4927_pci66_setup(); +#endif + + tx4927_pci_setup(); +#endif + + + { + u32 id = 0; + early_read_config_dword(&mips_pci_channels[0], 0, 0, 0x90, + PCI_VENDOR_ID, &id); + if (id == 0x94601055) { + tx4927_using_backplane = 1; + printk("backplane board IS installed\n"); + } else { + printk("backplane board NOT installed\n"); + } + } + + + /* this is only done if backplane board installed, so must wait for pci */ +#ifdef CONFIG_PC_KEYB + { + if (tx4927_using_backplane) { + extern struct kbd_ops std_kbd_ops; + kbd_ops = &std_kbd_ops; + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=&std_kbd_ops\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=<NO_BACKPLANE>\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":kbd_ops=<NOT_CONFIG>\n"); + } +#endif + + /* this is on ISA bus behind PCI bus, so need PCI up first */ +#ifdef CONFIG_TOSHIBA_FPCIB0 + { + if (tx4927_using_backplane) { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=yes\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_init()\n"); + smsc_fdc37m81x_init(0x3f0); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_beg()\n"); + smsc_fdc37m81x_config_beg(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_set(KBD)\n"); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM, + SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12); + smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE, + 1); + + smsc_fdc37m81x_config_end(); + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":smsc_fdc37m81x_config_end()\n"); + } else { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, + ":fpcibo=not_found\n"); + } + } +#else + { + TOSHIBA_RBTX4927_SETUP_DPRINTK + (TOSHIBA_RBTX4927_SETUP_SETUP, ":fpcibo=no\n"); + } +#endif + + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_SETUP, + "+\n"); +} + +void __init +toshiba_rbtx4927_time_init(void) +{ + u32 c1; + u32 c2; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); + +#ifdef CONFIG_RTC_DS1742 + + rtc_get_time = rtc_ds1742_get_time; + rtc_set_time = rtc_ds1742_set_time; + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()-\n"); + rtc_ds1742_init(0xbc010000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":rtc_ds1742_init()+\n"); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_counter_frequency-\n"); + rtc_ds1742_wait(); + + /* get the count */ + c1 = read_c0_count(); + + /* wait for the seconds to change again */ + rtc_ds1742_wait(); + + /* get the count again */ + c2 = read_c0_count(); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":Calibrate mips_counter_frequency+\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c1=%12u\n", c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":c2=%12u\n", c2); + + /* this diff is as close as we are going to get to counter ticks per sec */ + mips_counter_frequency = abs(c2 - c1); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f1=%12u\n", mips_counter_frequency); + + /* round to 1/10th of a MHz */ + mips_counter_frequency /= (100 * 1000); + mips_counter_frequency *= (100 * 1000); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, + ":f2=%12u\n", mips_counter_frequency); + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO, + ":mips_counter_frequency=%uHz (%uMHz)\n", + mips_counter_frequency, + mips_counter_frequency / 1000000); +#else + mips_counter_frequency = 100000000; +#endif + + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); + +} + +void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq) +{ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "-\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "+\n"); +} diff -Nru a/arch/mips/vmlinux.lds.S b/arch/mips/vmlinux.lds.S --- a/arch/mips/vmlinux.lds.S Fri Jun 27 14:19:55 2003 +++ b/arch/mips/vmlinux.lds.S Fri Jun 27 14:19:55 2003 @@ -2,19 +2,20 @@ OUTPUT_ARCH(mips) ENTRY(kernel_entry) +jiffies = JIFFIES32; SECTIONS { - /* Read-only sections, merged into text segment: */ . = LOADADDR; - .init : { *(.init) } =0 - .text : - { - _ftext = . ; + /* read-only */ + _text = .; /* Text and read-only data */ + .text : { *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ + *(.fixup) *(.gnu.warning) } =0 + _etext = .; /* End of text section */ + . = ALIGN(16); /* Exception table */ __start___ex_table = .; __ex_table : { *(__ex_table) } @@ -25,29 +26,73 @@ __stop___dbe_table = .; RODATA - - _etext = .; - . = ALIGN(8192); - .data.init_task : { *(.data.init_task) } + . = ALIGN(64); + + /* writeable */ + .data : { /* Data */ + *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + + CONSTRUCTORS + } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; - /* Startup code */ . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + + . = ALIGN(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + + /* will be freed after init */ + . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } + /* /DISCARD/ doesn't work for .reginfo */ + .reginfo : { *(.reginfo) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .; - .setup.init : { *(.setup.init) } + .init.setup : { *(.init.setup) } __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) *(.initcall7.init) } __initcall_end = .; @@ -55,80 +100,35 @@ .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT - . = ALIGN(4096); /* Align double page for init_task_union */ - __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - .fini : { *(.fini) } =0 - .reginfo : { *(.reginfo) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. It would - be more correct to do this: - . = .; - The current expression does not correctly handle the case of a - text segment ending precisely at the end of a page; it causes the - data segment to skip a page. The above expression does not have - this problem, but it will currently (2/95) cause BFD to allocate - a single segment, combining both text and data, for this case. - This will prevent the text segment from being shared among - multiple executions of the program; I think that is more - important than losing a page of the virtual address space (note - that no actual memory is lost; the page which is skipped can not - be referenced). */ - . = .; - .data : - { - _fdata = . ; - *(.data) - - /* Align the initial ramdisk image (INITRD) on page boundaries. */ - . = ALIGN(4096); - __rd_start = .; - *(.initrd) - __rd_end = .; - . = ALIGN(4096); + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + /* freed after init ends here */ - CONSTRUCTORS + __bss_start = .; /* BSS */ + .sbss : { + *(.sbss) + *(.scommon) } - .data1 : { *(.data1) } - _gp = . + 0x8000; - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - .got : { *(.got.plt) *(.got) } - .dynamic : { *(.dynamic) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } - . = ALIGN(4); - _edata = .; - PROVIDE (edata = .); - - __bss_start = .; - _fbss = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - . = ALIGN(4); - _end = . ; - PROVIDE (end = .); + .bss : { + *(.bss) + *(COMMON) } + __bss_stop = .; + + _end = . ; /* Sections to be discarded */ - /DISCARD/ : - { - *(.text.exit) - *(.data.exit) + /DISCARD/ : { + *(.exit.text) + *(.exit.data) *(.exitcall.exit) } diff -Nru a/arch/mips/vr41xx/casio-e55/Makefile b/arch/mips/vr41xx/casio-e55/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/casio-e55/Makefile Fri Jun 27 14:20:07 2003 @@ -0,0 +1,7 @@ +# +# Makefile for the CASIO CASSIOPEIA E-55/65 specific parts of the kernel +# + +obj-y += init.o setup.o + +obj-$(CONFIG_IDE) += ide-e55.o diff -Nru a/arch/mips/vr41xx/casio-e55/ide-e55.c b/arch/mips/vr41xx/casio-e55/ide-e55.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/casio-e55/ide-e55.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,99 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations + * for the CASIO CASSIOPEIA E-55/65. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> Sun, 24 Feb 2002 + * - Added CASIO CASSIOPEIA E-55/65 support. + */ +#include <linux/sched.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/hdreg.h> +#include <asm/ptrace.h> +#include <asm/hdreg.h> + +static int e55_ide_default_irq(ide_ioreg_t base) +{ + return 40; +} + +static ide_ioreg_t e55_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0xc1f0; + case 1: return 0xc170; + case 2: return 0xc1e8; + case 3: return 0xc168; + case 4: return 0xc1e0; + case 5: return 0xc160; + } + return 0; +} + +static void e55_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; + + 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; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int e55_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void e55_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int e55_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void e55_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void e55_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops e55_ide_ops = { + &e55_ide_default_irq, + &e55_ide_default_io_base, + &e55_ide_init_hwif_ports, + &e55_ide_request_irq, + &e55_ide_free_irq, + &e55_ide_check_region, + &e55_ide_request_region, + &e55_ide_release_region +}; diff -Nru a/arch/mips/vr41xx/casio-e55/init.c b/arch/mips/vr41xx/casio-e55/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/casio-e55/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,49 @@ +/* + * FILE NAME + * arch/mips/vr41xx/casio-e55/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the CASIO CASSIOPEIA E-55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "CASIO CASSIOPEIA E-11/15/55/65"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_CASIO_E55; +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/casio-e55/setup.c b/arch/mips/vr41xx/casio-e55/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/casio-e55/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,74 @@ +/* + * FILE NAME + * arch/mips/vr41xx/casio-e55/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the CASIO CASSIOPEIA E-11/15/55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/e55.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops e55_ide_ops; +#endif + +void __init casio_e55_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &e55_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + +#ifdef CONFIG_SERIAL_8250 + vr41xx_siu_init(SIU_RS232C, 0); +#endif +} diff -Nru a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,10 @@ +# +# Makefile for common code of the NEC VR4100 series. +# + +obj-y += bcu.o cmu.o giu.o icu.o int-handler.o reset.o +obj-$(CONFIG_SERIAL_8250) += serial.o +obj-$(CONFIG_VR41XX_TIME_C) += time.o +obj-$(CONFIG_VRC4173) += vrc4173.o + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips/vr41xx/common/bcu.c b/arch/mips/vr41xx/common/bcu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/bcu.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,206 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/bcu.c + * + * BRIEF MODULE DESCRIPTION + * Bus Control Unit routines for the NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC VR4111 and VR4121. + * + * Paul Mundt <lethal@chaoticdreams.org> + * - Calculate mips_counter_frequency properly on VR4131. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include <linux/init.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/time.h> +#include <asm/vr41xx/vr41xx.h> + +#define VR4111_CLKSPEEDREG KSEG1ADDR(0x0b000014) +#define VR4122_CLKSPEEDREG KSEG1ADDR(0x0f000014) +#define VR4131_CLKSPEEDREG VR4122_CLKSPEEDREG + #define CLKSP(x) ((x) & 0x001f) + + #define DIV2B 0x8000 + #define DIV3B 0x4000 + #define DIV4B 0x2000 + + #define DIVT(x) (((x) & 0xf000) >> 12) + #define DIVVT(x) (((x) & 0x0f00) >> 8) + + #define TDIVMODE(x) (2 << (((x) & 0x1000) >> 12)) + #define VTDIVMODE(x) (((x) & 0x0700) >> 8) + +unsigned long vr41xx_vtclock = 0; + +static inline u16 read_clkspeed(void) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: return readw(VR4111_CLKSPEEDREG); + case CPU_VR4122: return readw(VR4122_CLKSPEEDREG); + case CPU_VR4131: return readw(VR4131_CLKSPEEDREG); + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + break; + } + + return 0; +} + +static inline unsigned long calculate_pclock(u16 clkspeed) +{ + unsigned long pclock = 0; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + pclock = 18432000 * 64; + break; + case CPU_VR4122: + pclock = 18432000 * 98; + break; + case CPU_VR4131: + pclock = 18432000 * 108; + break; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + break; + } + + pclock /= CLKSP(clkspeed); + printk(KERN_INFO "PClock: %ldHz\n", pclock); + + return pclock; +} + +static inline unsigned long calculate_vtclock(u16 clkspeed, unsigned long pclock) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + /* The NEC VR4111 doesn't have the VTClock. */ + break; + case CPU_VR4121: + vr41xx_vtclock = pclock; + /* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */ + if (DIVVT(clkspeed) == 9) + vr41xx_vtclock = pclock * 6; + /* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */ + else if (DIVVT(clkspeed) == 10) + vr41xx_vtclock = pclock * 4; + vr41xx_vtclock /= DIVVT(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + break; + case CPU_VR4122: + if(VTDIVMODE(clkspeed) == 7) + vr41xx_vtclock = pclock / 1; + else if(VTDIVMODE(clkspeed) == 1) + vr41xx_vtclock = pclock / 2; + else + vr41xx_vtclock = pclock / VTDIVMODE(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + break; + case CPU_VR4131: + vr41xx_vtclock = pclock / VTDIVMODE(clkspeed); + printk(KERN_INFO "VTClock: %ldHz\n", vr41xx_vtclock); + break; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + break; + } + + return vr41xx_vtclock; +} + +static inline unsigned long calculate_tclock(u16 clkspeed, unsigned long pclock, + unsigned long vtclock) +{ + unsigned long tclock = 0; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + if (!(clkspeed & DIV2B)) + tclock = pclock / 2; + else if (!(clkspeed & DIV3B)) + tclock = pclock / 3; + else if (!(clkspeed & DIV4B)) + tclock = pclock / 4; + break; + case CPU_VR4121: + tclock = pclock / DIVT(clkspeed); + break; + case CPU_VR4122: + case CPU_VR4131: + tclock = vtclock / TDIVMODE(clkspeed); + break; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + break; + } + + printk(KERN_INFO "TClock: %ldHz\n", tclock); + + return tclock; +} + +static inline unsigned long calculate_mips_counter_frequency(unsigned long tclock) +{ + /* + * VR4131 Revision 2.0 and 2.1 use a value of (tclock / 2). + */ + if ((current_cpu_data.processor_id == PRID_VR4131_REV2_0) || + (current_cpu_data.processor_id == PRID_VR4131_REV2_1)) + tclock /= 2; + else + tclock /= 4; + + return tclock; +} + +void __init vr41xx_bcu_init(void) +{ + unsigned long pclock, vtclock, tclock; + u16 clkspeed; + + clkspeed = read_clkspeed(); + + pclock = calculate_pclock(clkspeed); + vtclock = calculate_vtclock(clkspeed, pclock); + tclock = calculate_tclock(clkspeed, pclock, vtclock); + + mips_counter_frequency = calculate_mips_counter_frequency(tclock); +} diff -Nru a/arch/mips/vr41xx/common/cmu.c b/arch/mips/vr41xx/common/cmu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/cmu.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,84 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/cmu.c + * + * BRIEF MODULE DESCRIPTION + * Clock Mask Unit routines for the NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC VR4111 and VR4121. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include <linux/init.h> +#include <linux/types.h> + +#include <asm/cpu.h> +#include <asm/io.h> + +#define VR4111_CMUCLKMSK KSEG1ADDR(0x0b000060) +#define VR4122_CMUCLKMSK KSEG1ADDR(0x0f000060) + +static u32 vr41xx_cmu_base = 0; +static u16 cmuclkmsk = 0; + +#define write_cmu(mask) writew((mask), vr41xx_cmu_base) + +void vr41xx_clock_supply(u16 mask) +{ + cmuclkmsk |= mask; + write_cmu(cmuclkmsk); +} + +void vr41xx_clock_mask(u16 mask) +{ + cmuclkmsk &= ~mask; + write_cmu(cmuclkmsk); +} + +void __init vr41xx_cmu_init(u16 mask) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + vr41xx_cmu_base = VR4111_CMUCLKMSK; + break; + case CPU_VR4122: + case CPU_VR4131: + vr41xx_cmu_base = VR4122_CMUCLKMSK; + break; + default: + panic("Unexpected CPU of NEC VR4100 series"); + break; + } + + cmuclkmsk = mask; +} diff -Nru a/arch/mips/vr41xx/common/giu.c b/arch/mips/vr41xx/common/giu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/giu.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,267 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/giu.c + * + * BRIEF MODULE DESCRIPTION + * General-purpose I/O Unit Interrupt routines for NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4111, VR4121, VR4122 and VR4131 are supported. + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/vr41xx/vr41xx.h> + +#define VR4111_GIUIOSELL KSEG1ADDR(0x0b000100) +#define VR4122_GIUIOSELL KSEG1ADDR(0x0f000140) + +#define GIUIOSELL 0x00 +#define GIUIOSELH 0x02 +#define GIUINTSTATL 0x08 +#define GIUINTSTATH 0x0a +#define GIUINTENL 0x0c +#define GIUINTENH 0x0e +#define GIUINTTYPL 0x10 +#define GIUINTTYPH 0x12 +#define GIUINTALSELL 0x14 +#define GIUINTALSELH 0x16 +#define GIUINTHTSELL 0x18 +#define GIUINTHTSELH 0x1a + +u32 vr41xx_giu_base = 0; + +#define read_giuint(offset) readw(vr41xx_giu_base + (offset)) +#define write_giuint(val, offset) writew((val), vr41xx_giu_base + (offset)) + +static inline u16 set_giuint(u16 offset, u16 set) +{ + u16 res; + + res = read_giuint(offset); + res |= set; + write_giuint(res, offset); + + return res; +} + +static inline u16 clear_giuint(u16 offset, u16 clear) +{ + u16 res; + + res = read_giuint(offset); + res &= ~clear; + write_giuint(res, offset); + + return res; +} + +void vr41xx_enable_giuint(int pin) +{ + if (pin < 16) + set_giuint(GIUINTENL, (u16)1 << pin); + else + set_giuint(GIUINTENH, (u16)1 << (pin - 16)); +} + +void vr41xx_disable_giuint(int pin) +{ + if (pin < 16) + clear_giuint(GIUINTENL, (u16)1 << pin); + else + clear_giuint(GIUINTENH, (u16)1 << (pin - 16)); +} + +void vr41xx_clear_giuint(int pin) +{ + if (pin < 16) + write_giuint((u16)1 << pin, GIUINTSTATL); + else + write_giuint((u16)1 << (pin - 16), GIUINTSTATH); +} + +void vr41xx_set_irq_trigger(int pin, int trigger, int hold) +{ + u16 mask; + + if (pin < 16) { + mask = (u16)1 << pin; + if (trigger == TRIGGER_EDGE) { + set_giuint(GIUINTTYPL, mask); + if (hold == SIGNAL_HOLD) + set_giuint(GIUINTHTSELL, mask); + else + clear_giuint(GIUINTHTSELL, mask); + } else { + clear_giuint(GIUINTTYPL, mask); + clear_giuint(GIUINTHTSELL, mask); + } + } else { + mask = (u16)1 << (pin - 16); + if (trigger == TRIGGER_EDGE) { + set_giuint(GIUINTTYPH, mask); + if (hold == SIGNAL_HOLD) + set_giuint(GIUINTHTSELH, mask); + else + clear_giuint(GIUINTHTSELH, mask); + } else { + clear_giuint(GIUINTTYPH, mask); + clear_giuint(GIUINTHTSELH, mask); + } + } + + vr41xx_clear_giuint(pin); +} + +void vr41xx_set_irq_level(int pin, int level) +{ + u16 mask; + + if (pin < 16) { + mask = (u16)1 << pin; + if (level == LEVEL_HIGH) + set_giuint(GIUINTALSELL, mask); + else + clear_giuint(GIUINTALSELL, mask); + } else { + mask = (u16)1 << (pin - 16); + if (level == LEVEL_HIGH) + set_giuint(GIUINTALSELH, mask); + else + clear_giuint(GIUINTALSELH, mask); + } + + vr41xx_clear_giuint(pin); +} + +#define GIUINT_NR_IRQS 32 + +enum { + GIUINT_NO_CASCADE, + GIUINT_CASCADE +}; + +struct vr41xx_giuint_cascade { + unsigned int flag; + int (*get_irq_number)(int irq); +}; + +static struct vr41xx_giuint_cascade giuint_cascade[GIUINT_NR_IRQS]; +static struct irqaction giu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; + +static int no_irq_number(int irq) +{ + return -EINVAL; +} + +int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)) +{ + unsigned int pin; + int retval; + + if (irq < GIU_IRQ(0) || irq > GIU_IRQ(31)) + return -EINVAL; + + if(!get_irq_number) + return -EINVAL; + + pin = irq - GIU_IRQ(0); + giuint_cascade[pin].flag = GIUINT_CASCADE; + giuint_cascade[pin].get_irq_number = get_irq_number; + + retval = setup_irq(irq, &giu_cascade); + if (retval) { + giuint_cascade[pin].flag = GIUINT_NO_CASCADE; + giuint_cascade[pin].get_irq_number = no_irq_number; + } + + return retval; +} + +unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs) +{ + struct vr41xx_giuint_cascade *cascade; + unsigned int retval = 0; + int giuint_irq, cascade_irq; + + disable_irq(GIUINT_CASCADE_IRQ); + cascade = &giuint_cascade[pin]; + giuint_irq = pin + GIU_IRQ(0); + if (cascade->flag == GIUINT_CASCADE) { + cascade_irq = cascade->get_irq_number(giuint_irq); + disable_irq(giuint_irq); + if (cascade_irq > 0) + retval = do_IRQ(cascade_irq, regs); + enable_irq(giuint_irq); + } else + retval = do_IRQ(giuint_irq, regs); + enable_irq(GIUINT_CASCADE_IRQ); + + return retval; +} + +void (*board_irq_init)(void) = NULL; + +void __init vr41xx_giuint_init(void) +{ + int i; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + vr41xx_giu_base = VR4111_GIUIOSELL; + break; + case CPU_VR4122: + case CPU_VR4131: + vr41xx_giu_base = VR4122_GIUIOSELL; + break; + default: + panic("GIU: Unexpected CPU of NEC VR4100 series"); + break; + } + + for (i = 0; i < GIUINT_NR_IRQS; i++) { + vr41xx_disable_giuint(i); + giuint_cascade[i].flag = GIUINT_NO_CASCADE; + giuint_cascade[i].get_irq_number = no_irq_number; + } + + if (setup_irq(GIUINT_CASCADE_IRQ, &giu_cascade)) + printk("GIUINT: Can not cascade IRQ %d.\n", GIUINT_CASCADE_IRQ); + + if (board_irq_init) + board_irq_init(); +} diff -Nru a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/icu.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,407 @@ +/* + * FILE NAME + * arch/mips/vr41xx/vr4122/common/icu.c + * + * BRIEF MODULE DESCRIPTION + * Interrupt Control Unit routines for the NEC VR4122 and VR4131. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC VR4111 and VR4121. + * + * Paul Mundt <lethal@chaoticdreams.org> + * - kgdb support. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/types.h> + +#include <asm/addrspace.h> +#include <asm/cpu.h> +#include <asm/gdb-stub.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/vr41xx/vr41xx.h> + +extern asmlinkage void vr41xx_handle_interrupt(void); + +extern void __init init_generic_irq(void); +extern void mips_cpu_irq_init(u32 irq_base); + +extern void vr41xx_giuint_init(void); +extern unsigned int giuint_do_IRQ(int pin, struct pt_regs *regs); + +static u32 vr41xx_icu1_base = 0; +static u32 vr41xx_icu2_base = 0; + +#define VR4111_SYSINT1REG KSEG1ADDR(0x0b000080) +#define VR4111_SYSINT2REG KSEG1ADDR(0x0b000200) + +#define VR4122_SYSINT1REG KSEG1ADDR(0x0f000080) +#define VR4122_SYSINT2REG KSEG1ADDR(0x0f0000a0) + +#define SYSINT1REG 0x00 +#define GIUINTLREG 0x08 +#define MSYSINT1REG 0x0c +#define MGIUINTLREG 0x14 +#define NMIREG 0x18 +#define SOFTREG 0x1a + +#define SYSINT2REG 0x00 +#define GIUINTHREG 0x02 +#define MSYSINT2REG 0x06 +#define MGIUINTHREG 0x08 + +#define read_icu1(offset) readw(vr41xx_icu1_base + (offset)) +#define write_icu1(val, offset) writew((val), vr41xx_icu1_base + (offset)) + +#define read_icu2(offset) readw(vr41xx_icu2_base + (offset)) +#define write_icu2(val, offset) writew((val), vr41xx_icu2_base + (offset)) + +static inline u16 set_icu1(u16 offset, u16 set) +{ + u16 res; + + res = read_icu1(offset); + res |= set; + write_icu1(res, offset); + + return res; +} + +static inline u16 clear_icu1(u16 offset, u16 clear) +{ + u16 res; + + res = read_icu1(offset); + res &= ~clear; + write_icu1(res, offset); + + return res; +} + +static inline u16 set_icu2(u16 offset, u16 set) +{ + u16 res; + + res = read_icu2(offset); + res |= set; + write_icu2(res, offset); + + return res; +} + +static inline u16 clear_icu2(u16 offset, u16 clear) +{ + u16 res; + + res = read_icu2(offset); + res &= ~clear; + write_icu2(res, offset); + + return res; +} + +/*=======================================================================*/ + +static void enable_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); +} + +static void disable_sysint1_irq(unsigned int irq) +{ + clear_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); +} + +static unsigned int startup_sysint1_irq(unsigned int irq) +{ + set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); + + return 0; /* never anything pending */ +} + +#define shutdown_sysint1_irq disable_sysint1_irq +#define ack_sysint1_irq disable_sysint1_irq + +static void end_sysint1_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_icu1(MSYSINT1REG, (u16)1 << (irq - SYSINT1_IRQ_BASE)); +} + +static struct hw_interrupt_type sysint1_irq_type = { + "SYSINT1", + startup_sysint1_irq, + shutdown_sysint1_irq, + enable_sysint1_irq, + disable_sysint1_irq, + ack_sysint1_irq, + end_sysint1_irq, + NULL +}; + +/*=======================================================================*/ + +static void enable_sysint2_irq(unsigned int irq) +{ + set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); +} + +static void disable_sysint2_irq(unsigned int irq) +{ + clear_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); +} + +static unsigned int startup_sysint2_irq(unsigned int irq) +{ + set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); + + return 0; /* never anything pending */ +} + +#define shutdown_sysint2_irq disable_sysint2_irq +#define ack_sysint2_irq disable_sysint2_irq + +static void end_sysint2_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + set_icu2(MSYSINT2REG, (u16)1 << (irq - SYSINT2_IRQ_BASE)); +} + +static struct hw_interrupt_type sysint2_irq_type = { + "SYSINT2", + startup_sysint2_irq, + shutdown_sysint2_irq, + enable_sysint2_irq, + disable_sysint2_irq, + ack_sysint2_irq, + end_sysint2_irq, + NULL +}; + +/*=======================================================================*/ + +static void enable_giuint_irq(unsigned int irq) +{ + int pin; + + pin = irq - GIU_IRQ_BASE; + if (pin < 16) + set_icu1(MGIUINTLREG, (u16)1 << pin); + else + set_icu2(MGIUINTHREG, (u16)1 << (pin - 16)); + + vr41xx_enable_giuint(pin); +} + +static void disable_giuint_irq(unsigned int irq) +{ + int pin; + + pin = irq - GIU_IRQ_BASE; + vr41xx_disable_giuint(pin); + + if (pin < 16) + clear_icu1(MGIUINTLREG, (u16)1 << pin); + else + clear_icu2(MGIUINTHREG, (u16)1 << (pin - 16)); +} + +static unsigned int startup_giuint_irq(unsigned int irq) +{ + vr41xx_clear_giuint(irq - GIU_IRQ_BASE); + + enable_giuint_irq(irq); + + return 0; /* never anything pending */ +} + +#define shutdown_giuint_irq disable_giuint_irq + +static void ack_giuint_irq(unsigned int irq) +{ + disable_giuint_irq(irq); + + vr41xx_clear_giuint(irq - GIU_IRQ_BASE); +} + +static void end_giuint_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_giuint_irq(irq); +} + +static struct hw_interrupt_type giuint_irq_type = { + "GIUINT", + startup_giuint_irq, + shutdown_giuint_irq, + enable_giuint_irq, + disable_giuint_irq, + ack_giuint_irq, + end_giuint_irq, + NULL +}; + +/*=======================================================================*/ + +static struct irqaction icu_cascade = {no_action, 0, 0, "cascade", NULL, NULL}; + +static void __init vr41xx_icu_init(void) +{ + int i; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + vr41xx_icu1_base = VR4111_SYSINT1REG; + vr41xx_icu2_base = VR4111_SYSINT2REG; + break; + case CPU_VR4122: + case CPU_VR4131: + vr41xx_icu1_base = VR4122_SYSINT1REG; + vr41xx_icu2_base = VR4122_SYSINT2REG; + break; + default: + panic("Unexpected CPU of NEC VR4100 series"); + break; + } + + write_icu1(0, MSYSINT1REG); + write_icu1(0, MGIUINTLREG); + + write_icu2(0, MSYSINT2REG); + write_icu2(0, MGIUINTHREG); + + for (i = SYSINT1_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + if (i >= SYSINT1_IRQ_BASE && i <= SYSINT1_IRQ_LAST) + irq_desc[i].handler = &sysint1_irq_type; + else if (i >= SYSINT2_IRQ_BASE && i <= SYSINT2_IRQ_LAST) + irq_desc[i].handler = &sysint2_irq_type; + else if (i >= GIU_IRQ_BASE && i <= GIU_IRQ_LAST) + irq_desc[i].handler = &giuint_irq_type; + } + + setup_irq(ICU_CASCADE_IRQ, &icu_cascade); +} + +void __init init_IRQ(void) +{ + memset(irq_desc, 0, sizeof(irq_desc)); + + init_generic_irq(); + mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); + vr41xx_icu_init(); + + vr41xx_giuint_init(); + + set_except_vector(0, vr41xx_handle_interrupt); + +#ifdef CONFIG_KGDB + printk("Setting debug traps - please connect the remote debugger.\n"); + set_debug_traps(); + breakpoint(); +#endif +} + +/*=======================================================================*/ + +static inline void giuint_irqdispatch(u16 pendl, u16 pendh, struct pt_regs *regs) +{ + int i; + + if (pendl) { + for (i = 0; i < 16; i++) { + if (pendl & (0x0001 << i)) { + giuint_do_IRQ(i, regs); + return; + } + } + } + else if (pendh) { + for (i = 0; i < 16; i++) { + if (pendh & (0x0001 << i)) { + giuint_do_IRQ(i + 16, regs); + return; + } + } + } +} + +asmlinkage void icu_irqdispatch(struct pt_regs *regs) +{ + u16 pend1, pend2, pendl, pendh; + u16 mask1, mask2, maskl, maskh; + int i; + + pend1 = read_icu1(SYSINT1REG); + mask1 = read_icu1(MSYSINT1REG); + + pend2 = read_icu2(SYSINT2REG); + mask2 = read_icu2(MSYSINT2REG); + + pendl = read_icu1(GIUINTLREG); + maskl = read_icu1(MGIUINTLREG); + + pendh = read_icu2(GIUINTHREG); + maskh = read_icu2(MGIUINTHREG); + + pend1 &= mask1; + pend2 &= mask2; + pendl &= maskl; + pendh &= maskh; + + if (pend1) { + if ((pend1 & 0x01ff) == 0x0100) { + giuint_irqdispatch(pendl, pendh, regs); + } + else { + for (i = 0; i < 16; i++) { + if (pend1 & (0x0001 << i)) { + do_IRQ(SYSINT1_IRQ_BASE + i, regs); + break; + } + } + } + return; + } + else if (pend2) { + for (i = 0; i < 16; i++) { + if (pend2 & (0x0001 << i)) { + do_IRQ(SYSINT2_IRQ_BASE + i, regs); + break; + } + } + } +} diff -Nru a/arch/mips/vr41xx/common/int-handler.S b/arch/mips/vr41xx/common/int-handler.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/int-handler.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,114 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/int-handler.S + * + * BRIEF MODULE DESCRIPTION + * Interrupt dispatcher for the NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@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 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4100 series are supported. + */ +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> + + .text + .set noreorder + + .align 5 + NESTED(vr41xx_handle_interrupt, PT_SIZE, ra) + .set noat + SAVE_ALL + CLI + .set at + .set noreorder + + /* + * Get the pending interrupts + */ + mfc0 t0, CP0_CAUSE + mfc0 t1, CP0_STATUS + andi t0, 0xff00 + and t0, t0, t1 + + andi t1, t0, CAUSEF_IP7 # timer interrupt + beqz t1, 1f + li a0, 7 + jal ll_timer_interrupt + move a1, sp + j ret_from_irq + +1: + andi t1, t0, 0x7800 # check for IP3-6 + beqz t1, 2f + + andi t1, t0, CAUSEF_IP3 # check for IP3 + bnez t1, handle_it + li a0, 3 + + andi t1, t0, CAUSEF_IP4 # check for IP4 + bnez t1, handle_it + li a0, 4 + + andi t1, t0, CAUSEF_IP5 # check for IP5 + bnez t1, handle_it + li a0, 5 + + andi t1, t0, CAUSEF_IP6 # check for IP6 + bnez t1, handle_it + li a0, 6 + +2: + andi t1, t0, CAUSEF_IP2 # check for IP2 + beqz t1, 3f + move a0, sp + jal icu_irqdispatch + nop + j ret_from_irq + nop + +3: + andi t1, t0, CAUSEF_IP0 # check for IP0 + bnez t1, handle_it + li a0, 0 + + andi t1, t0, CAUSEF_IP1 # check for IP1 + bnez t1, handle_it + li a0, 1 + + j spurious_interrupt + nop + +handle_it: + jal do_IRQ + move a1, sp + j ret_from_irq + END(vr41xx_handle_interrupt) diff -Nru a/arch/mips/vr41xx/common/reset.c b/arch/mips/vr41xx/common/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/reset.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,37 @@ +/* + * 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. + * + * Copyright (C) 1997, 2001 Ralf Baechle + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + */ +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/io.h> +#include <asm/cacheflush.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/system.h> + +void vr41xx_restart(char *command) +{ + change_c0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL)); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); +} + +void vr41xx_halt(void) +{ + printk(KERN_NOTICE "\n** You can safely turn off the power\n"); + while (1); +} + +void vr41xx_power_off(void) +{ + vr41xx_halt(); +} diff -Nru a/arch/mips/vr41xx/common/serial.c b/arch/mips/vr41xx/common/serial.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/serial.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,177 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/serial.c + * + * BRIEF MODULE DESCRIPTION + * Serial Interface Unit routines for NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC VR4111 and VR4121. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4122 and VR4131 are supported. + */ +#include <linux/init.h> +#include <linux/types.h> +#include <linux/serial.h> + +#include <asm/addrspace.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/vr41xx/vr41xx.h> + +/* VR4111 and VR4121 SIU Registers */ +#define VR4111_SIURB KSEG1ADDR(0x0c000000) +#define VR4111_SIUIRSEL KSEG1ADDR(0x0c000008) + +/* VR4122 and VR4131 SIU Registers */ +#define VR4122_SIURB KSEG1ADDR(0x0f000800) +#define VR4122_SIUIRSEL KSEG1ADDR(0x0f000808) + + #define USE_RS232C 0x00 + #define USE_IRDA 0x01 + #define SIU_USES_IRDA 0x00 + #define FIR_USES_IRDA 0x02 + #define IRDA_MODULE_SHARP 0x00 + #define IRDA_MODULE_TEMIC 0x04 + #define IRDA_MODULE_HP 0x08 + #define TMICTX 0x10 + #define TMICMODE 0x20 + +#define SIU_BASE_BAUD 1152000 +#define SIU_CLOCK 0x0102 + +/* VR4122 and VR4131 DSIU Registers */ +#define DSIURB KSEG1ADDR(0x0f000820) + +#define MDSIUINTREG KSEG1ADDR(0x0f000096) + #define INTDSIU 0x0800 + +#define DSIU_BASE_BAUD 1152000 +#define DSIU_CLOCK 0x0802 + +int vr41xx_serial_ports = 0; + +void vr41xx_siu_ifselect(int interface, int module) +{ + u16 val = USE_RS232C; /* Select RS-232C */ + + /* Select IrDA */ + if (interface == SIU_IRDA) { + switch (module) { + case IRDA_SHARP: + val = IRDA_MODULE_SHARP; + break; + case IRDA_TEMIC: + val = IRDA_MODULE_TEMIC; + break; + case IRDA_HP: + val = IRDA_MODULE_HP; + break; + } + val |= USE_IRDA | SIU_USES_IRDA; + } + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + writew(val, VR4111_SIUIRSEL); + break; + case CPU_VR4122: + case CPU_VR4131: + writew(val, VR4122_SIUIRSEL); + break; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + break; + } +} + +void __init vr41xx_siu_init(int interface, int module) +{ + struct serial_struct s; + + vr41xx_siu_ifselect(interface, module); + + memset(&s, 0, sizeof(s)); + + s.line = vr41xx_serial_ports; + s.baud_base = SIU_BASE_BAUD; + s.irq = SIU_IRQ; + s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + s.iomem_base = (unsigned char *)VR4111_SIURB; + break; + case CPU_VR4122: + case CPU_VR4131: + s.iomem_base = (unsigned char *)VR4122_SIURB; + break; + default: + panic("Unexpected CPU of NEC VR4100 series"); + break; + } + s.iomem_reg_shift = 0; + s.io_type = SERIAL_IO_MEM; + if (early_serial_setup(&s) != 0) + printk(KERN_ERR "SIU setup failed!\n"); + + vr41xx_clock_supply(SIU_CLOCK); + + vr41xx_serial_ports++; +} + +void __init vr41xx_dsiu_init(void) +{ + struct serial_struct s; + + if (current_cpu_data.cputype != CPU_VR4122 && + current_cpu_data.cputype != CPU_VR4131) + return; + + memset(&s, 0, sizeof(s)); + + s.line = vr41xx_serial_ports; + s.baud_base = DSIU_BASE_BAUD; + s.irq = DSIU_IRQ; + s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + s.iomem_base = (unsigned char *)DSIURB; + s.iomem_reg_shift = 0; + s.io_type = SERIAL_IO_MEM; + if (early_serial_setup(&s) != 0) + printk(KERN_ERR "DSIU setup failed!\n"); + + vr41xx_clock_supply(DSIU_CLOCK); + + writew(INTDSIU, MDSIUINTREG); + + vr41xx_serial_ports++; +} diff -Nru a/arch/mips/vr41xx/common/time.c b/arch/mips/vr41xx/common/time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,93 @@ +/* + * FILE NAME + * arch/mips/vr41xx/common/time.c + * + * BRIEF MODULE DESCRIPTION + * Timer routines for the NEC VR4100 series. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC VR4100 series RTC Unit. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC VR4100 series are supported. + */ +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/types.h> + +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/param.h> +#include <asm/time.h> +#include <asm/vr41xx/vr41xx.h> + +#define VR4111_ETIMELREG KSEG1ADDR(0x0b0000c0) +#define VR4122_ETIMELREG KSEG1ADDR(0x0f000100) + +u32 vr41xx_rtc_base = 0; + +#ifdef CONFIG_VR41XX_RTC +extern unsigned long vr41xx_rtc_get_time(void); +extern int vr41xx_rtc_set_time(unsigned long sec); +#endif + +void vr41xx_time_init(void) +{ + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + vr41xx_rtc_base = VR4111_ETIMELREG; + break; + case CPU_VR4122: + case CPU_VR4131: + vr41xx_rtc_base = VR4122_ETIMELREG; + break; + default: + panic("Unexpected CPU of NEC VR4100 series"); + break; + } + +#ifdef CONFIG_VR41XX_RTC + rtc_get_time = vr41xx_rtc_get_time; + rtc_set_time = vr41xx_rtc_set_time; +#endif +} + +void vr41xx_timer_setup(struct irqaction *irq) +{ + u32 count; + + setup_irq(MIPS_COUNTER_IRQ, irq); + + count = read_c0_count(); + write_c0_compare(count + (mips_counter_frequency / HZ)); +} diff -Nru a/arch/mips/vr41xx/common/vrc4173.c b/arch/mips/vr41xx/common/vrc4173.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/common/vrc4173.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,279 @@ +/* + * FILE NAME + * drivers/char/vrc4173.c + * + * BRIEF MODULE DESCRIPTION + * NEC VRC4173 driver for NEC VR4122/VR4131. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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 <linux/config.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/pci.h> +#include <linux/types.h> + +#include <asm/vr41xx/vr41xx.h> +#include <asm/vr41xx/vrc4173.h> + +MODULE_DESCRIPTION("NEC VRC4173 driver for NEC VR4122/4131"); +MODULE_AUTHOR("Yoichi Yuasa <yyuasa@mvista.com>"); +MODULE_LICENSE("GPL"); + +#define VRC4173_CMUCLKMSK 0x040 +#define VRC4173_CMUSRST 0x042 + +#define VRC4173_SELECTREG 0x09e + +#define VRC4173_SYSINT1REG 0x060 +#define VRC4173_MSYSINT1REG 0x06c + +static struct pci_device_id vrc4173_table[] __devinitdata = { + {PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0, } +}; + +unsigned long vrc4173_io_offset = 0; + +EXPORT_SYMBOL(vrc4173_io_offset); + +static u16 vrc4173_cmuclkmsk; +static int vrc4173_initialized; + +void vrc4173_clock_supply(u16 mask) +{ + if (vrc4173_initialized) { + vrc4173_cmuclkmsk |= mask; + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + } +} + +void vrc4173_clock_mask(u16 mask) +{ + if (vrc4173_initialized) { + vrc4173_cmuclkmsk &= ~mask; + vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK); + } +} + +static inline void vrc4173_cmu_init(void) +{ + vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK); +} + +EXPORT_SYMBOL(vrc4173_clock_supply); +EXPORT_SYMBOL(vrc4173_clock_mask); + +void vrc4173_select_function(int func) +{ + u16 val; + + if (vrc4173_initialized) { + val = vrc4173_inw(VRC4173_SELECTREG); + switch(func) { + case PS2CH1_SELECT: + val |= 0x0004; + break; + case PS2CH2_SELECT: + val |= 0x0002; + break; + case TOUCHPANEL_SELECT: + val &= 0x0007; + break; + case KIU8_SELECT: + val &= 0x000e; + break; + case KIU10_SELECT: + val &= 0x000c; + break; + case KIU12_SELECT: + val &= 0x0008; + break; + case GPIO_SELECT: + val |= 0x0008; + break; + } + vrc4173_outw(val, VRC4173_SELECTREG); + } +} + +EXPORT_SYMBOL(vrc4173_select_function); + +static void enable_vrc4173_irq(unsigned int irq) +{ + u16 val; + + val = vrc4173_inw(VRC4173_MSYSINT1REG); + val |= (u16)1 << (irq - VRC4173_IRQ_BASE); + vrc4173_outw(val, VRC4173_MSYSINT1REG); +} + +static void disable_vrc4173_irq(unsigned int irq) +{ + u16 val; + + val = vrc4173_inw(VRC4173_MSYSINT1REG); + val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE)); + vrc4173_outw(val, VRC4173_MSYSINT1REG); +} + +static unsigned int startup_vrc4173_irq(unsigned int irq) +{ + enable_vrc4173_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_vrc4173_irq disable_vrc4173_irq +#define ack_vrc4173_irq disable_vrc4173_irq + +static void end_vrc4173_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_vrc4173_irq(irq); +} + +static struct hw_interrupt_type vrc4173_irq_type = { + "VRC4173", + startup_vrc4173_irq, + shutdown_vrc4173_irq, + enable_vrc4173_irq, + disable_vrc4173_irq, + ack_vrc4173_irq, + end_vrc4173_irq, + NULL +}; + +static int vrc4173_get_irq_number(int irq) +{ + u16 status, mask; + int i; + + status = vrc4173_inw(VRC4173_SYSINT1REG); + mask = vrc4173_inw(VRC4173_MSYSINT1REG); + + status &= mask; + if (status) { + for (i = 0; i < 16; i++) + if (status & (0x0001 << i)) + return VRC4173_IRQ_BASE + i; + } + + return -EINVAL; +} + +static inline void vrc4173_icu_init(int cascade_irq) +{ + int i; + + if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15)) + return; + + vrc4173_outw(0, VRC4173_MSYSINT1REG); + + vr41xx_set_irq_trigger(cascade_irq - GIU_IRQ(0), TRIGGER_LEVEL, SIGNAL_THROUGH); + vr41xx_set_irq_level(cascade_irq - GIU_IRQ(0), LEVEL_LOW); + + for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) + irq_desc[i].handler = &vrc4173_irq_type; +} + +static int __devinit vrc4173_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + unsigned long start, flags; + int err; + + if ((err = pci_enable_device(pdev)) < 0) { + printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err); + return err; + } + + pci_set_master(pdev); + + start = pci_resource_start(pdev, 0); + if (!start) { + printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n"); + return -ENODEV; + } + + if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) { + printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n"); + return -ENODEV; + } + + if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) { + printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n"); + return err; + } + + set_vrc4173_io_offset(start); + + vrc4173_cmu_init(); + + vrc4173_icu_init(pdev->irq); + + if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) { + printk(KERN_ERR + "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq); + return err; + } + + printk(KERN_INFO + "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq); + + return 0; +} + +static struct pci_driver vrc4173_driver = { + name: "NEC VRC4173", + probe: vrc4173_probe, + remove: NULL, + id_table: vrc4173_table, +}; + +static int __devinit vrc4173_init(void) +{ + int err; + + if ((err = pci_module_init(&vrc4173_driver)) < 0) + return err; + + vrc4173_initialized = 1; + + return 0; +} + +static void __devexit vrc4173_exit(void) +{ + vrc4173_initialized = 0; + + pci_unregister_driver(&vrc4173_driver); +} + +module_init(vrc4173_init); +module_exit(vrc4173_exit); diff -Nru a/arch/mips/vr41xx/ibm-workpad/Makefile b/arch/mips/vr41xx/ibm-workpad/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/ibm-workpad/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +# +# Makefile for the IBM WorkPad z50 specific parts of the kernel +# + +obj-y += init.o setup.o +obj-$(CONFIG_IDE) += ide-workpad.o diff -Nru a/arch/mips/vr41xx/ibm-workpad/ide-workpad.c b/arch/mips/vr41xx/ibm-workpad/ide-workpad.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/ibm-workpad/ide-workpad.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,98 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations for the IBM WorkPad z50. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> Sun, 24 Feb 2002 + * - Added IBM WorkPad z50 support. + */ +#include <linux/sched.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/hdreg.h> +#include <asm/ptrace.h> +#include <asm/hdreg.h> + +static int workpad_ide_default_irq(ide_ioreg_t base) +{ + return 49; +} + +static ide_ioreg_t workpad_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x1f0; + case 1: return 0x170; + case 2: return 0x1e8; + case 3: return 0x168; + case 4: return 0x1e0; + case 5: return 0x160; + } + return 0; +} + +static void workpad_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; + + 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; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int workpad_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, SA_SHIRQ, device, dev_id); +} + +static void workpad_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int workpad_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void workpad_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void workpad_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops workpad_ide_ops = { + &workpad_ide_default_irq, + &workpad_ide_default_io_base, + &workpad_ide_init_hwif_ports, + &workpad_ide_request_irq, + &workpad_ide_free_irq, + &workpad_ide_check_region, + &workpad_ide_request_region, + &workpad_ide_release_region +}; diff -Nru a/arch/mips/vr41xx/ibm-workpad/init.c b/arch/mips/vr41xx/ibm-workpad/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/ibm-workpad/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,49 @@ +/* + * FILE NAME + * arch/mips/vr41xx/ibm-workpad/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "IBM WorkPad z50"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_IBM_WORKPAD; +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/ibm-workpad/setup.c b/arch/mips/vr41xx/ibm-workpad/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/ibm-workpad/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,74 @@ +/* + * FILE NAME + * arch/mips/vr41xx/workpad/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/workpad.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops workpad_ide_ops; +#endif + +void __init ibm_workpad_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM_RESOURCE_START; + iomem_resource.end = IO_MEM_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &workpad_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + +#ifdef CONFIG_SERIAL_8250 + vr41xx_siu_init(SIU_RS232C, 0); +#endif +} diff -Nru a/arch/mips/vr41xx/nec-eagle/Makefile b/arch/mips/vr41xx/nec-eagle/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/nec-eagle/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,11 @@ +# +# Makefile for the NEC Eagle/Hawk specific parts of the kernel +# +# Author: Yoichi Yuasa +# yyuasa@mvista.com or source@mvista.com +# +# Copyright 2001,2002 MontaVista Software Inc. +# + +obj-y += init.o irq.o setup.o +obj-$(CONFIG_IDE) += ide-eagle.o diff -Nru a/arch/mips/vr41xx/nec-eagle/ide-eagle.c b/arch/mips/vr41xx/nec-eagle/ide-eagle.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/nec-eagle/ide-eagle.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,96 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations + * for the NEC Eagle/Hawk board. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * Fri, 5 Apr 2002 + * - Added support for NEC Hawk. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * Fri, 1 Mar 2002 + * - Added support for NEC Eagle. + */ +#include <linux/sched.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/hdreg.h> +#include <asm/ptrace.h> +#include <asm/hdreg.h> + +static int eagle_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t eagle_ide_default_io_base(int index) +{ + return 0; +} + +static void eagle_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; + + 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; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int eagle_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, SA_SHIRQ, device, dev_id); +} + +static void eagle_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int eagle_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void eagle_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void eagle_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops eagle_ide_ops = { + &eagle_ide_default_irq, + &eagle_ide_default_io_base, + &eagle_ide_init_hwif_ports, + &eagle_ide_request_irq, + &eagle_ide_free_irq, + &eagle_ide_check_region, + &eagle_ide_request_region, + &eagle_ide_release_region +}; diff -Nru a/arch/mips/vr41xx/nec-eagle/init.c b/arch/mips/vr41xx/nec-eagle/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/nec-eagle/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,74 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the NEC Eagle/Hawk board. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC Hawk. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC Eagle is supported. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "NEC Eagle/Hawk"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_NEC_EAGLE; +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/nec-eagle/irq.c b/arch/mips/vr41xx/nec-eagle/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/nec-eagle/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,183 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/irq.c + * + * BRIEF MODULE DESCRIPTION + * Interrupt routines for the NEC Eagle/Hawk board. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Added support for NEC Hawk. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC Eagle is supported. + */ +#include <linux/init.h> +#include <linux/interrupt.h> + +#include <asm/io.h> +#include <asm/vr41xx/eagle.h> + +static void enable_pciint_irq(unsigned int irq) +{ + u8 val; + + val = readb(NEC_EAGLE_PCIINTMSKREG); + val |= (u8)1 << (irq - PCIINT_IRQ_BASE); + writeb(val, NEC_EAGLE_PCIINTMSKREG); +} + +static void disable_pciint_irq(unsigned int irq) +{ + u8 val; + + val = readb(NEC_EAGLE_PCIINTMSKREG); + val &= ~((u8)1 << (irq - PCIINT_IRQ_BASE)); + writeb(val, NEC_EAGLE_PCIINTMSKREG); +} + +static unsigned int startup_pciint_irq(unsigned int irq) +{ + enable_pciint_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_pciint_irq disable_pciint_irq +#define ack_pciint_irq disable_pciint_irq + +static void end_pciint_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_pciint_irq(irq); +} + +static struct hw_interrupt_type pciint_irq_type = { + "PCIINT", + startup_pciint_irq, + shutdown_pciint_irq, + enable_pciint_irq, + disable_pciint_irq, + ack_pciint_irq, + end_pciint_irq, + NULL +}; + +static void enable_sdbint_irq(unsigned int irq) +{ + u8 val; + + val = readb(NEC_EAGLE_SDBINTMSK); + val |= (u8)1 << (irq - SDBINT_IRQ_BASE); + writeb(val, NEC_EAGLE_SDBINTMSK); +} + +static void disable_sdbint_irq(unsigned int irq) +{ + u8 val; + + val = readb(NEC_EAGLE_SDBINTMSK); + val &= ~((u8)1 << (irq - SDBINT_IRQ_BASE)); + writeb(val, NEC_EAGLE_SDBINTMSK); +} + +static unsigned int startup_sdbint_irq(unsigned int irq) +{ + enable_sdbint_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_sdbint_irq disable_sdbint_irq +#define ack_sdbint_irq disable_sdbint_irq + +static void end_sdbint_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_sdbint_irq(irq); +} + +static struct hw_interrupt_type sdbint_irq_type = { + "SDBINT", + startup_sdbint_irq, + shutdown_sdbint_irq, + enable_sdbint_irq, + disable_sdbint_irq, + ack_sdbint_irq, + end_sdbint_irq, + NULL +}; + +static int eagle_get_irq_number(int irq) +{ + u8 sdbint, pciint; + int i; + + sdbint = readb(NEC_EAGLE_SDBINT); + sdbint &= (NEC_EAGLE_SDBINT_DEG | NEC_EAGLE_SDBINT_ENUM | + NEC_EAGLE_SDBINT_SIO1INT | NEC_EAGLE_SDBINT_SIO2INT | + NEC_EAGLE_SDBINT_PARINT); + pciint = readb(NEC_EAGLE_PCIINTREG); + pciint &= (NEC_EAGLE_PCIINT_CP_INTA | NEC_EAGLE_PCIINT_CP_INTB | + NEC_EAGLE_PCIINT_CP_INTC | NEC_EAGLE_PCIINT_CP_INTD | + NEC_EAGLE_PCIINT_LANINT); + + for (i = 1; i < 6; i++) + if (sdbint & (0x01 << i)) + return SDBINT_IRQ_BASE + i; + + for (i = 0; i < 5; i++) + if (pciint & (0x01 << i)) + return PCIINT_IRQ_BASE + i; + + return -EINVAL; +} + +void __init eagle_irq_init(void) +{ + int i; + + writeb(0, NEC_EAGLE_SDBINTMSK); + writeb(0, NEC_EAGLE_PCIINTMSKREG); + + vr41xx_set_irq_trigger(PCISLOT_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); + vr41xx_set_irq_level(PCISLOT_PIN, LEVEL_HIGH); + + vr41xx_set_irq_trigger(FPGA_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH); + vr41xx_set_irq_level(FPGA_PIN, LEVEL_HIGH); + + vr41xx_set_irq_trigger(DCD_PIN, TRIGGER_EDGE, SIGNAL_HOLD); + vr41xx_set_irq_level(DCD_PIN, LEVEL_LOW); + + for (i = SDBINT_IRQ_BASE; i <= SDBINT_IRQ_LAST; i++) + irq_desc[i].handler = &sdbint_irq_type; + + for (i = PCIINT_IRQ_BASE; i <= PCIINT_IRQ_LAST; i++) + irq_desc[i].handler = &pciint_irq_type; + + vr41xx_cascade_irq(FPGA_CASCADE_IRQ, eagle_get_irq_number); +} diff -Nru a/arch/mips/vr41xx/nec-eagle/setup.c b/arch/mips/vr41xx/nec-eagle/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/nec-eagle/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,162 @@ +/* + * FILE NAME + * arch/mips/vr41xx/nec-eagle/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the NEC Eagle/Hawk board. + * + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001,2002 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. + */ +/* + * Changes: + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - Moved mips_pci_channels[] from arch/mips/vr41xx/vr4122/eagle/setup.c. + * - Added support for NEC Hawk. + * + * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> + * - New creation, NEC Eagle is supported. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/pci_channel.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/eagle.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops eagle_ide_ops; +#endif + +extern void eagle_irq_init(void); + +#ifdef CONFIG_PCI + +extern void vrc4173_preinit(void); + +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init nec_eagle_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + + board_irq_init = eagle_irq_init; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &eagle_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + +#ifdef CONFIG_SERIAL_8250 + vr41xx_dsiu_init(); + vr41xx_siu_init(SIU_RS232C, 0); +#endif + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); + + vrc4173_preinit(); +#endif +} diff -Nru a/arch/mips/vr41xx/tanbac-tb0226/Makefile b/arch/mips/vr41xx/tanbac-tb0226/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0226/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,5 @@ +# +# Makefile for the TANBAC TB0226 specific parts of the kernel +# + +obj-y += init.o setup.o diff -Nru a/arch/mips/vr41xx/tanbac-tb0226/init.c b/arch/mips/vr41xx/tanbac-tb0226/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0226/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,64 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/mipsregs.h> +#include <asm/vr41xx/vr41xx.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "TANBAC TB0226"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_TANBAC_TB0226; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/tanbac-tb0226/setup.c b/arch/mips/vr41xx/tanbac-tb0226/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0226/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,121 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0226/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/ioport.h> + +#include <asm/pci_channel.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/tb0226.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + .name = "PCI I/O space", + .start = VR41XX_PCI_IO_START, + .end = VR41XX_PCI_IO_END, + .flags = IORESOURCE_IO, +}; + +static struct resource vr41xx_pci_mem_resource = { + .name = "PCI memory space", + .start = VR41XX_PCI_MEM_START, + .end = VR41XX_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + { .pci_ops = &vr41xx_pci_ops, + .io_resource = &vr41xx_pci_io_resource, + .mem_resource = &vr41xx_pci_mem_resource, + .first_devfn = 0, + .last_devfn = 256, }, + { .pci_ops = NULL, + .io_resource = NULL, + .mem_resource = NULL, + .first_devfn = 0, + .last_devfn = 0, }, +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + .internal_base = VR41XX_PCI_MEM1_BASE, + .address_mask = VR41XX_PCI_MEM1_MASK, + .pci_base = IO_MEM1_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + .internal_base = VR41XX_PCI_MEM2_BASE, + .address_mask = VR41XX_PCI_MEM2_MASK, + .pci_base = IO_MEM2_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + .internal_base = VR41XX_PCI_IO_BASE, + .address_mask = VR41XX_PCI_IO_MASK, + .pci_base = IO_PORT_RESOURCE_START, +}; + +static struct vr41xx_pci_address_map pci_address_map = { + .mem1 = &vr41xx_pci_mem1, + .mem2 = &vr41xx_pci_mem2, + .io = &vr41xx_pci_io, +}; +#endif + +void __init tanbac_tb0226_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/Makefile b/arch/mips/vr41xx/tanbac-tb0229/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0229/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,5 @@ +# +# Makefile for the TANBAC TB0229(VR4131DIMM) specific parts of the kernel +# + +obj-y := init.o reboot.o setup.o diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/init.c b/arch/mips/vr41xx/tanbac-tb0229/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0229/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,69 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the TANBAC TB0229(VR4131DIMM) + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/mipsregs.h> +#include <asm/vr41xx/vr41xx.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "TANBAC TB0229"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_TANBAC_TB0229; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/reboot.c b/arch/mips/vr41xx/tanbac-tb0229/reboot.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0229/reboot.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,30 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/reboot.c + * + * BRIEF MODULE DESCRIPTION + * Depending on TANBAC TB0229(VR4131DIMM) of reboot system call. + * + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * 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 <asm/io.h> +#include <asm/vr41xx/tb0229.h> + +#define tb0229_hard_reset() writew(0, TB0219_RESET_REGS) + +void tanbac_tb0229_restart(char *command) +{ +#ifdef CONFIG_TANBAC_TB0219 + local_irq_disable(); + tb0229_hard_reset(); + while (1); +#else + vr41xx_restart(command); +#endif +} diff -Nru a/arch/mips/vr41xx/tanbac-tb0229/setup.c b/arch/mips/vr41xx/tanbac-tb0229/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/tanbac-tb0229/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,127 @@ +/* + * FILE NAME + * arch/mips/vr41xx/tanbac-tb0229/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the TANBAC TB0229 (VR4131DIMM) + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/blk.h> +#include <linux/console.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/root_dev.h> + +#include <asm/pci_channel.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/tb0229.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + .name = "PCI I/O space", + .start = VR41XX_PCI_IO_START, + .end = VR41XX_PCI_IO_END, + .flags = IORESOURCE_IO, +}; + +static struct resource vr41xx_pci_mem_resource = { + .name = "PCI memory space", + .start = VR41XX_PCI_MEM_START, + .end = VR41XX_PCI_MEM_END, + .flags = IORESOURCE_MEM, +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + { .pci_ops = &vr41xx_pci_ops, + .io_resource = &vr41xx_pci_io_resource, + .mem_resource = &vr41xx_pci_mem_resource, + .first_devfn = 0, + .last_devfn = 256, }, + { .pci_ops = NULL, + .io_resource = NULL, + .mem_resource = NULL, + .first_devfn = 0, + .last_devfn = 0, } +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + .internal_base = VR41XX_PCI_MEM1_BASE, + .address_mask = VR41XX_PCI_MEM1_MASK, + .pci_base = IO_MEM1_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + .internal_base = VR41XX_PCI_MEM2_BASE, + .address_mask = VR41XX_PCI_MEM2_MASK, + .pci_base = IO_MEM2_RESOURCE_START, +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + .internal_base = VR41XX_PCI_IO_BASE, + .address_mask = VR41XX_PCI_IO_MASK, + .pci_base = IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + .mem1 = &vr41xx_pci_mem1, + .mem2 = &vr41xx_pci_mem2, + .io = &vr41xx_pci_io, +}; +#endif + +void __init tanbac_tb0229_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = tanbac_tb0229_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + + vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} + diff -Nru a/arch/mips/vr41xx/victor-mpc30x/Makefile b/arch/mips/vr41xx/victor-mpc30x/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/victor-mpc30x/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +# +# Makefile for the Victor MP-C303/304 specific parts of the kernel +# + +obj-y += init.o setup.o +obj-$(CONFIG_IDE) += ide-mpc30x.o diff -Nru a/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c b/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,91 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations + * for the ZAO Networks Capcella. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> Fri, 23 Aug 2002 + * - Added Victor MP-C303/304 support. + */ +#include <linux/sched.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/hdreg.h> +#include <asm/ptrace.h> +#include <asm/hdreg.h> + +static int mpc30x_ide_default_irq(ide_ioreg_t base) +{ + return 0; +} + +static ide_ioreg_t mpc30x_ide_default_io_base(int index) +{ + return 0; +} + +static void mpc30x_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; + + 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; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int mpc30x_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void mpc30x_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int mpc30x_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void mpc30x_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void mpc30x_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops mpc30x_ide_ops = { + &mpc30x_ide_default_irq, + &mpc30x_ide_default_io_base, + &mpc30x_ide_init_hwif_ports, + &mpc30x_ide_request_irq, + &mpc30x_ide_free_irq, + &mpc30x_ide_check_region, + &mpc30x_ide_request_region, + &mpc30x_ide_release_region +}; diff -Nru a/arch/mips/vr41xx/victor-mpc30x/init.c b/arch/mips/vr41xx/victor-mpc30x/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/victor-mpc30x/init.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,54 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the Victor MP-C303/304. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/mipsregs.h> +#include <asm/vr41xx/vr41xx.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "Victor MP-C303/304"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_VICTOR_MPC30X; + + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/victor-mpc30x/setup.c b/arch/mips/vr41xx/victor-mpc30x/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/victor-mpc30x/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,126 @@ +/* + * FILE NAME + * arch/mips/vr41xx/victor-mpc30x/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the Victor MP-C303/304. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/pci_channel.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/mpc30x.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops mpc30x_ide_ops; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init victor_mpc30x_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &mpc30x_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0); + +#ifdef CONFIG_SERIAL_8250 + vr41xx_siu_init(SIU_RS232C, 0); +#endif + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -Nru a/arch/mips/vr41xx/zao-capcella/Makefile b/arch/mips/vr41xx/zao-capcella/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/zao-capcella/Makefile Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +# +# Makefile for the ZAO Networks Capcella specific parts of the kernel +# + +obj-y += init.o setup.o +obj-$(CONFIG_IDE) += ide-capcella.o diff -Nru a/arch/mips/vr41xx/zao-capcella/ide-capcella.c b/arch/mips/vr41xx/zao-capcella/ide-capcella.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/zao-capcella/ide-capcella.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,99 @@ +/* + * 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. + * + * IDE routines for typical pc-like standard configurations + * for the ZAO Networks Capcella. + * + * Copyright (C) 1998, 1999, 2001 by Ralf Baechle + */ +/* + * Changes: + * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> Sun, 24 Feb 2002 + * - Added ZAO Networks Capcella support. + */ +#include <linux/sched.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/hdreg.h> +#include <asm/ptrace.h> +#include <asm/hdreg.h> + +static int capcella_ide_default_irq(ide_ioreg_t base) +{ + switch (base) { + case 0x8300: return 42; + } + + return 0; +} + +static ide_ioreg_t capcella_ide_default_io_base(int index) +{ + switch (index) { + case 0: return 0x8300; + } + + return 0; +} + +static void capcella_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; + + 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; + hw->io_ports[IDE_IRQ_OFFSET] = 0; +} + +static int capcella_ide_request_irq(unsigned int irq, + void (*handler)(int,void *, struct pt_regs *), + unsigned long flags, const char *device, + void *dev_id) +{ + return request_irq(irq, handler, flags, device, dev_id); +} + +static void capcella_ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + +static int capcella_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void capcella_ide_request_region(ide_ioreg_t from, unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +static void capcella_ide_release_region(ide_ioreg_t from, unsigned int extent) +{ + release_region(from, extent); +} + +struct ide_ops capcella_ide_ops = { + &capcella_ide_default_irq, + &capcella_ide_default_io_base, + &capcella_ide_init_hwif_ports, + &capcella_ide_request_irq, + &capcella_ide_free_irq, + &capcella_ide_check_region, + &capcella_ide_request_region, + &capcella_ide_release_region +}; diff -Nru a/arch/mips/vr41xx/zao-capcella/init.c b/arch/mips/vr41xx/zao-capcella/init.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/zao-capcella/init.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,64 @@ +/* + * FILE NAME + * arch/mips/vr41xx/zao-capcella/init.c + * + * BRIEF MODULE DESCRIPTION + * Initialisation code for the ZAO Networks Capcella. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/mipsregs.h> +#include <asm/vr41xx/vr41xx.h> + +char arcs_cmdline[CL_SIZE]; + +const char *get_system_type(void) +{ + return "ZAO Networks Capcella"; +} + +void __init prom_init(int argc, char **argv, unsigned long magic, int *prom_vec) +{ + u32 config; + int i; + + /* + * collect args and prepare cmd_line + */ + for (i = 1; i < argc; i++) { + strcat(arcs_cmdline, argv[i]); + if (i < (argc - 1)) + strcat(arcs_cmdline, " "); + } + + mips_machgroup = MACH_GROUP_NEC_VR41XX; + mips_machtype = MACH_ZAO_CAPCELLA; + + switch (current_cpu_data.processor_id) { + case PRID_VR4131_REV1_2: + config = read_c0_config(); + config &= ~0x00000030UL; + config |= 0x00410000UL; + write_c0_config(config); + break; + default: + break; + } +} + +void __init prom_free_prom_memory (void) +{ +} diff -Nru a/arch/mips/vr41xx/zao-capcella/setup.c b/arch/mips/vr41xx/zao-capcella/setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips/vr41xx/zao-capcella/setup.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,127 @@ +/* + * FILE NAME + * arch/mips/vr41xx/zao-capcella/setup.c + * + * BRIEF MODULE DESCRIPTION + * Setup for the ZAO Networks Capcella. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/console.h> +#include <linux/ide.h> +#include <linux/ioport.h> +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> + +#include <asm/pci_channel.h> +#include <asm/reboot.h> +#include <asm/time.h> +#include <asm/vr41xx/capcella.h> + +#ifdef CONFIG_BLK_DEV_INITRD +extern unsigned long initrd_start, initrd_end; +extern void * __rd_start, * __rd_end; +#endif + +#ifdef CONFIG_BLK_DEV_IDE +extern struct ide_ops capcella_ide_ops; +#endif + +#ifdef CONFIG_PCI +static struct resource vr41xx_pci_io_resource = { + "PCI I/O space", + VR41XX_PCI_IO_START, + VR41XX_PCI_IO_END, + IORESOURCE_IO +}; + +static struct resource vr41xx_pci_mem_resource = { + "PCI memory space", + VR41XX_PCI_MEM_START, + VR41XX_PCI_MEM_END, + IORESOURCE_MEM +}; + +extern struct pci_ops vr41xx_pci_ops; + +struct pci_channel mips_pci_channels[] = { + {&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256}, + {NULL, NULL, NULL, 0, 0} +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem1 = { + VR41XX_PCI_MEM1_BASE, + VR41XX_PCI_MEM1_MASK, + IO_MEM1_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_mem2 = { + VR41XX_PCI_MEM2_BASE, + VR41XX_PCI_MEM2_MASK, + IO_MEM2_RESOURCE_START +}; + +struct vr41xx_pci_address_space vr41xx_pci_io = { + VR41XX_PCI_IO_BASE, + VR41XX_PCI_IO_MASK, + IO_PORT_RESOURCE_START +}; + +static struct vr41xx_pci_address_map pci_address_map = { + &vr41xx_pci_mem1, + &vr41xx_pci_mem2, + &vr41xx_pci_io +}; +#endif + +void __init zao_capcella_setup(void) +{ + set_io_port_base(IO_PORT_BASE); + ioport_resource.start = IO_PORT_RESOURCE_START; + ioport_resource.end = IO_PORT_RESOURCE_END; + iomem_resource.start = IO_MEM1_RESOURCE_START; + iomem_resource.end = IO_MEM2_RESOURCE_END; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; +#endif + + _machine_restart = vr41xx_restart; + _machine_halt = vr41xx_halt; + _machine_power_off = vr41xx_power_off; + + board_time_init = vr41xx_time_init; + board_timer_setup = vr41xx_timer_setup; + +#ifdef CONFIG_FB + conswitchp = &dummy_con; +#endif + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &capcella_ide_ops; +#endif + + vr41xx_bcu_init(); + + vr41xx_cmu_init(0x0102); + +#ifdef CONFIG_SERIAL_8250 + vr41xx_siu_init(SIU_RS232C, 0); + vr41xx_dsiu_init(); +#endif + +#ifdef CONFIG_PCI + vr41xx_pciu_init(&pci_address_map); +#endif +} diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig --- a/arch/mips64/Kconfig Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/Kconfig Fri Jun 27 14:19:54 2003 @@ -2,586 +2,16 @@ # For a description of the syntax of this configuration file, # see Documentation/kbuild/kconfig-language.txt. # - -mainmenu "Linux Kernel Configuration" - -config MIPS64 - bool - default y - -config MMU - bool - default y - -source "init/Kconfig" - - -menu "Machine selection" - -choice - prompt "Machine type" - default SGI_IP27 - -config SGI_IP22 - bool "SGI-IP22,Indy/Indigo2" - help - This are the SGI Indy, Challenge S and Indigo2, as well as certain - OEM variants like the Tandem CMN B006S. To compile a Linux kernel - that runs on these, say Y here. - -config SGI_IP27 - bool "SGI-IP27,Origin200/2000" - help - This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics - workstations. To compile a Linux kernel that runs on these, say Y - here. - -endchoice - -config SGI_SN0_N_MODE - bool "IP27 N-Mode" - depends on SGI_IP27 - help - The nodes of Origin 200, Origin 2000 and Onyx 2 systems can be - configured in either N-Modes which allows for more nodes or M-Mode - which allows for more memory. Your system is most probably - running in M-Mode, so you should say N here. - -config DISCONTIGMEM - bool "Discontiguous Memory Support" - depends on SGI_IP27 - help - Say Y to upport efficient handling of discontiguous physical memory, - for architectures which are either NUMA (Non-Uniform Memory Access) - or have huge holes in the physical address space for other reasons. - See <file:Documentation/vm/numa> for more. - -config NUMA - bool "NUMA Support" - depends on SGI_IP27 - help - Say Y to compile the kernel to support NUMA (Non-Uniform Memory - Access). This option is for configuring high-end multiprocessor - server machines. If in doubt, say N. - -config MAPPED_KERNEL - bool "Mapped kernel support" - depends on SGI_IP27 - help - Change the way a Linux kernel is loaded unto memory on a MIPS64 - machine. This is required in order to support text replication and - NUMA. If you need to undersatand it, read the source code. - -config REPLICATE_KTEXT - bool "Kernel text replication support" - depends on SGI_IP27 - help - Say Y here to enable replicating the kernel text across multiple - nodes in a NUMA cluster. This trades memory for speed. - -config REPLICATE_EXHANDLERS - bool "Exception handler replication support" - depends on SGI_IP27 - help - Say Y here to enable replicating the kernel exception handlers - across multiple nodes in a NUMA cluster. This trades memory for - speed. - -config SMP - bool "Multi-Processing support" - depends on SGI_IP27 - ---help--- - This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. - - If you say N here, the kernel will run on single and multiprocessor - machines, but will use only one CPU of a multiprocessor machine. If - you say Y here, the kernel will run on many, but not all, - singleprocessor machines. On a singleprocessor machine, the kernel - will run faster if you say N here. - - Note that if you say Y here and choose architecture "586" or - "Pentium" under "Processor family", the kernel will not work on 486 - architectures. Similarly, multiprocessor kernels for the "PPro" - architecture may not work on all Pentium based boards. - - People using multiprocessor machines who say Y here should also say - Y to "Enhanced Real Time Clock Support", below. The "Advanced Power - Management" code will be disabled if you say Y here. - - See also the <file:Documentation/smp.tex>, - <file:Documentation/smp.txt>, <file:Documentation/i386/IO-APIC.txt>, - <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at - <http://www.tldp.org/docs.html#howto>. - - If you don't know what to do here, say N. - -#bool ' IP27 XXL' CONFIG_SGI_SN0_XXL -endmenu - -# -# Select some configuration options automatically based on user selections -# -config RWSEM_GENERIC_SPINLOCK - bool - default y - -config RWSEM_XCHGADD_ALGORITHM - bool - -config GENERIC_ISA_DMA - bool - default y - -config PCI - bool - depends on SGI_IP27 - default y - help - Find out whether you have a PCI motherboard. PCI is the name of a - bus system, i.e. the way the CPU talks to the other stuff inside - your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or - VESA. If you have PCI, say Y, otherwise N. - - The PCI-HOWTO, available from - <http://www.tldp.org/docs.html#howto>, contains valuable - information about which PCI hardware does work under Linux and which - doesn't. - -config ISA - bool - help - Find out whether you have ISA slots on your motherboard. ISA is the - name of a bus system, i.e. the way the CPU talks to the other stuff - inside your box. Other bus systems are PCI, EISA, MicroChannel - (MCA) or VESA. ISA is an older system, now being displaced by PCI; - newer boards don't support it. If you have ISA, say Y, otherwise N. - -config EISA - bool - depends on ISA - default y - ---help--- - The Extended Industry Standard Architecture (EISA) bus was - developed as an open alternative to the IBM MicroChannel bus. - - The EISA bus provided some of the features of the IBM MicroChannel - bus while maintaining backward compatibility with cards made for - the older ISA bus. The EISA bus saw limited use between 1988 and - 1995 when it was made obsolete by the PCI bus. - - Say Y here if you are building a kernel for an EISA-based machine. - - Otherwise, say N. - -config BOOT_ELF32 - bool - depends on SGI_IP22 - default y - -config ARC32 - bool - depends on SGI_IP22 - default y - -config BOARD_SCACHE - bool - depends on SGI_IP22 - default y - -config ARC_MEMORY - bool - depends on SGI_IP22 - default y - -config SGI - bool - depends on SGI_IP22 - default y - -config L1_CACHE_SHIFT - int - default "7" if SGI_IP27 - default "5" if SGI_IP22 - -config BOOT_ELF64 - bool - depends on SGI_IP27 - default y - -config ARC64 - bool - depends on SGI_IP27 - default y - -config COHERENT_IO - bool - depends on SGI_IP27 - default y - -config MAPPED_PCI_IO - bool - depends on SGI_IP27 - default y - -config QL_ISP_A64 - bool - depends on SGI_IP27 - default y - -config MCA - bool - help - MicroChannel Architecture is found in some IBM PS/2 machines and - laptops. It is a bus system similar to PCI or ISA. See - <file:Documentation/mca.txt> (and especially the web page given - there) before attempting to build an MCA bus kernel. - -config SBUS - bool - - -menu "CPU selection" - -choice - prompt "CPU type" - default CPU_R4X00 - -config CPU_R4300 - bool "R4300" - help - MIPS Technologies R4300-series processors. - -config CPU_R4X00 - bool "R4x00" - help - MIPS Technologies R4000-series processors other than 4300, including - the 4640, 4650, and 4700. - -config CPU_R5000 - bool "R5000" - help - MIPS Technologies R5000-series processors other than the Nevada. - -config CPU_NEVADA - bool "R52x0" - help - MIPS Technologies R52x0-series ("Nevada") processors. - -config CPU_R8000 - bool "R8000" - help - MIPS Technologies R8000-series processors. - -config CPU_R10000 - bool "R10000" - help - MIPS Technologies R10000-series processors. - -endchoice - -endmenu - - -menu "General setup" - -config MIPS_INSANE_LARGE - bool "Support for large 64-bit configurations" - depends on CPU_R10000 - help - MIPS R10000 does support a 44 bit / 16TB address space as opposed to - previous 64-bit processors which only supported 40 bit / 1TB. If you - need processes of more than 1TB virtual address space, say Y here. - This will result in additional memory usage, so it is not - recommended for normal users. - -config CPU_LITTLE_ENDIAN - bool "Generate little endian code" - help - Some MIPS machines can be configured for either little or big endian - byte order. These modes require different kernels. Say Y if your - machine is little endian, N if it's a big endian machine. - -config MIPS_FPU_EMULATOR - bool "Kernel floating-point emulation" - depends on EXPERIMENTAL - help - This option enables the MIPS software floatingpoint support. Due to - the way floating point works you should always enable this option - unless you exactly know what you're doing. - -config HOTPLUG - bool "Support for hot-pluggable devices" - ---help--- - Say Y here if you want to plug devices into your computer while - the system is running, and be able to use them quickly. In many - cases, the devices can likewise be unplugged at any time too. - - One well known example of this is PCMCIA- or PC-cards, credit-card - size devices such as network cards, modems or hard drives which are - plugged into slots found on all modern laptop computers. Another - example, used on modern desktops as well as laptops, is USB. - - Enable HOTPLUG and KMOD, and build a modular kernel. Get agent - software (at <http://linux-hotplug.sourceforge.net/>) and install it. - Then your kernel will automatically call out to a user mode "policy - agent" (/sbin/hotplug) to load modules and set up software needed - to use devices as you hotplug them. - -source "drivers/pcmcia/Kconfig" - -config ARC_CONSOLE - bool "ARC console support" - depends on ARC32 - -source "fs/Kconfig.binfmt" - -config MIPS32_COMPAT - bool "Kernel support for Linux/MIPS 32-bit binary compatibility" - help - Select this option if you want Linux/MIPS 32-bit binary - compatibility. Since all software available for Linux/MIPS is - currently 32-bit you should say Y here. - -config COMPAT +config MIPS bool - depends on MIPS32_COMPAT default y -config BINFMT_ELF32 +config MIPS32 bool - depends on BINFMT_ELF && MIPS32_COMPAT - default y - help - This allows you to run 32-bit Linux/ELF binaries on your Ultra. - Everybody wants this; say Y. - -endmenu - -source "drivers/pci/Kconfig" - -source "drivers/base/Kconfig" - -source "drivers/mtd/Kconfig" - -source "drivers/parport/Kconfig" - -source "drivers/block/Kconfig" - -source "drivers/md/Kconfig" - -source "drivers/ide/Kconfig" - - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - -source "drivers/scsi/Kconfig" - -endmenu - -#source drivers/message/i2o/Config.in -source "net/Kconfig" - -source "net/ax25/Kconfig" - -source "net/irda/Kconfig" + default n -source "drivers/isdn/Kconfig" - -source "drivers/telephony/Kconfig" - - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - -source "drivers/cdrom/Kconfig" - -endmenu - -source "drivers/input/Kconfig" - -source "drivers/char/Kconfig" - -#source drivers/misc/Config.in -source "drivers/media/Kconfig" - -source "fs/Kconfig" - -source "drivers/video/Kconfig" - -config KCORE_ELF +config MIPS64 bool - depends on PROC_FS default y - ---help--- - If you enabled support for /proc file system then the file - /proc/kcore will contain the kernel core image. This can be used - in gdb: - - $ cd /usr/src/linux ; gdb vmlinux /proc/kcore - - You have two choices here: ELF and A.OUT. Selecting ELF will make - /proc/kcore appear in ELF core format as defined by the Executable - and Linking Format specification. Selecting A.OUT will choose the - old "a.out" format which may be necessary for some old versions - of binutils or on some architectures. - - This is especially useful if you have compiled the kernel with the - "-g" option to preserve debugging information. It is mainly used - for examining kernel data structures on the live kernel so if you - don't understand what this means or are not a kernel hacker, just - leave it at its default value ELF. - - -menu "Sound" - -config SOUND - tristate "Sound card support" - ---help--- - If you have a sound card in your computer, i.e. if it can say more - than an occasional beep, say Y. Be sure to have all the information - about your sound card and its configuration down (I/O port, - interrupt and DMA channel), because you will be asked for it. - - You want to read the Sound-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. General information about - the modular sound system is contained in the files - <file:Documentation/sound/Introduction>. The file - <file:Documentation/sound/README.OSS> contains some slightly - outdated but still useful information as well. - - If you have a PnP sound card and you want to configure it at boot - time using the ISA PnP tools (read - <http://www.roestock.demon.co.uk/isapnptools/>), then you need to - compile the sound card support as a module ( = code which can be - inserted in and removed from the running kernel whenever you want) - and load that module after the PnP configuration is finished. To do - this, say M here and read <file:Documentation/modules.txt> as well - as <file:Documentation/sound/README.modules>; the module will be - called soundcore. - - I'm told that even without a sound card, you can make your computer - say more than an occasional beep, by programming the PC speaker. - Kernel patches and supporting utilities to do that are in the pcsp - package, available at <ftp://ftp.infradead.org/pub/pcsp/>. - -source "sound/Kconfig" - -endmenu - -source "drivers/sgi/Kconfig" - -source "drivers/usb/Kconfig" - - -menu "Kernel hacking" - -#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC -config CROSSCOMPILE - bool "Are you using a crosscompiler" - help - Say Y here if you are compiling the kernel on a different - architecture than the one it is intended to run on. - -config MIPS_FPE_MODULE - bool "Build fp exception handler module" - depends on MODULES - help - Build the floating point exception handler module. This option is - only useful for people working on the floating point exception - handler. If you don't, say N. - -config REMOTE_DEBUG - bool "Remote GDB kernel debugging" - help - If you say Y here, it will be possible to remotely debug the MIPS - kernel using gdb. This enlarges your kernel image disk size by - several megabytes and requires a machine with more than 16 MB, - better 32 MB RAM to avoid excessive linking time. This is only - useful for kernel hackers. If unsure, say N. - -config MAGIC_SYSRQ - bool "Magic SysRq key" - help - If you say Y here, you will have some control over the system even - if the system crashes for example during kernel debugging (e.g., you - will be able to flush the buffer cache to disk, reboot the system - immediately or dump some status information). This is accomplished - by pressing various keys while holding SysRq (Alt+PrintScreen). It - also works on a serial console (on PC hardware at least), if you - send a BREAK and then within 5 seconds a command keypress. The - keys are documented in <file:Documentation/sysrq.txt>. Don't say Y - unless you really know what this hack does. - -config MIPS_UNCACHED - bool "Run uncached" - depends on !SMP - help - If you say Y here there kernel will disable all CPU caches. This will - reduce the system's performance dramatically but can help finding - otherwise hard to track bugs. It can also useful if you're doing - hardware debugging with a logic analyzer and need to see all traffic - on the bus. - -config NR_CPUS - int "Maximum number of CPUs (2-64)" - depends on SMP - default "64" - -endmenu - -source "security/Kconfig" - -source "crypto/Kconfig" - -source "lib/Kconfig" +source "arch/mips/Kconfig-shared" diff -Nru a/arch/mips64/Makefile b/arch/mips64/Makefile --- a/arch/mips64/Makefile Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/Makefile Fri Jun 27 14:19:54 2003 @@ -3,10 +3,11 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # +# Copyright (C) 2002 Maciej W. Rozycki +# # 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 -# this architecture +# for "archclean" cleaning up for this architecture. # # @@ -14,16 +15,20 @@ # ifdef CONFIG_CPU_LITTLE_ENDIAN tool-prefix = mips64el-linux- +32bit-bfd = elf32-tradlittlemips +64bit-bfd = elf64-tradlittlemips else tool-prefix = mips64-linux- +32bit-bfd = elf32-tradbigmips +64bit-bfd = elf64-tradbigmips endif ifdef CONFIG_CROSSCOMPILE -CROSS_COMPILE = $(tool-prefix) +CROSS_COMPILE := $(tool-prefix) endif # -# The ELF GCC uses -G0 -mabicalls -fpic as default. We don't need PIC +# The ELF GCC uses -G 0 -mabicalls -fpic as default. We don't need PIC # code in the kernel since it only slows down the whole thing. For the # old GCC these options are just the defaults. At some point we might # make use of global pointer optimizations. @@ -32,117 +37,235 @@ # machines may also. Since BFD is incredibly buggy with respect to # crossformat linking we rely on the elf2ecoff tool for format conversion. # -CFLAGS += -I $(TOPDIR)/include/asm/gcc $(CFLAGS) -CFLAGS += -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe -LDFLAGS_vmlinux += -G 0 -static # -N -MODFLAGS += -mlong-calls +cflags-y := -I $(TOPDIR)/include/asm/gcc +cflags-y += -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe +LDFLAGS_vmlinux += -G 0 -static # -N +MODFLAGS += -mlong-calls -ifdef CONFIG_REMOTE_DEBUG -CFLAGS := $(CFLAGS) -g -endif +cflags-$(CONFIG_KGDB) += -g +cflags-$(CONFIG_SB1XXX_CORELIS) += -mno-sched-prolog -fno-omit-frame-pointer + +check_gcc = $(shell if $(AS) $(1) -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) +check_warning = $(shell if $(CC) $(1) -c -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi) # # CPU-dependent compiler/assembler options for optimization. # -ifdef CONFIG_CPU_R4300 -CFLAGS := $(CFLAGS) -mcpu=r4300 -mips3 -endif -ifdef CONFIG_CPU_R4X00 -CFLAGS := $(CFLAGS) -mcpu=r4600 -mips3 -endif -ifdef CONFIG_CPU_R5000 -CFLAGS := $(CFLAGS) -mcpu=r8000 -mips4 +cflags-$(CONFIG_CPU_R4300) += -mcpu=r4300 -mips3 +cflags-$(CONFIG_CPU_R4X00) += -mcpu=r4600 -mips3 +cflags-$(CONFIG_CPU_R5000) += -mcpu=r8000 -mips4 +cflags-$(CONFIG_CPU_NEVADA) += -mcpu=r8000 -mips3 -mmad +cflags-$(CONFIG_CPU_RM7000) += $(call check_gcc, -mcpu=r7000, -mcpu=r5000) \ + -mips4 +cflags-$(CONFIG_CPU_SB1) += $(call check_gcc, -mcpu=sb1, -mcpu=r8000) \ + $(call check_gcc, -mips64, -mips4) +cflags-$(CONFIG_CPU_R8000) += -mcpu=r8000 -mips4 +cflags-$(CONFIG_CPU_R10000) += -mcpu=r8000 -mips4 +ifdef CONFIG_CPU_SB1 +ifdef CONFIG_SB1_PASS_1_WORKAROUNDS +MODFLAGS += -msb1-pass1-workarounds endif -ifdef CONFIG_CPU_NEVADA -CFLAGS := $(CFLAGS) -mcpu=r8000 -mips3 -mmad endif -ifdef CONFIG_CPU_R8000 -CFLAGS := $(CFLAGS) -mcpu=r8000 -mips4 -endif -ifdef CONFIG_CPU_R10000 -CFLAGS := $(CFLAGS) -mcpu=r8000 -mips4 +# Should be used then we get a MIPS64 compiler +#cflags-$(CONFIG_CPU_MIPS64) += -mips64 +cflags-$(CONFIG_CPU_MIPS64) += -mcpu=r8000 -mips4 + +# +# ramdisk/initrd support +# You need a compressed ramdisk image, named ramdisk.gz in +# arch/mips/ramdisk +# +ifdef CONFIG_EMBEDDED_RAMDISK +CORE_FILES += arch/mips/ramdisk/ramdisk.o +SUBDIRS += arch/mips/ramdisk endif -core-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips64/math-emu/ +# +# Firmware support +# +libs-$(CONFIG_ARC) += arch/mips/arc/ +libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/ # # Board-dependent options and extra files # -ifdef CONFIG_SGI_IP22 -libs-y += arch/mips64/sgi-ip22/ \ - arch/mips64/arc/ -# -# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon, -# 0x88004000 for production kernels. Note that the value must be -# 16kb aligned or the handling of the current variable will break. # -LOADADDR += 0x88004000 +# DECstation family +# +ifdef CONFIG_DECSTATION +CORE_FILES += arch/mips/dec/dec.o +SUBDIRS += arch/mips/dec arch/mips/dec/prom +LIBS += arch/mips/dec/prom/rexlib.a +LOADADDR := 0x80040000 endif -ifdef CONFIG_SGI_IP27 -core-y += arch/mips64/sgi-ip27/ -libs-y += arch/mips64/arc/ # -# Set LOADADDR to >= 0xc000000000300000 if you want to leave space for +# MIPS Atlas board +# +core-$(CONFIG_MIPS_BOARDS_GEN) += arch/mips/mips-boards/generic/ +core-$(CONFIG_MIPS_ATLAS) += arch/mips/mips-boards/atlas/ +load-$(CONFIG_MIPS_ATLAS) += 0x80100000 + +# +# MIPS Malta board +# +core-$(CONFIG_MIPS_MALTA) += arch/mips/mips-boards/malta/ +load-$(CONFIG_MIPS_MALTA) += 0x80100000 + +# +# MIPS SEAD board +# +core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/ +load-$(CONFIG_MIPS_SEAD) += 0x80100000 + +# +# Momentum Ocelot board +# +# The Ocelot setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +# +core-$(CONFIG_MOMENCO_OCELOT) += arch/mips/gt64120/common/ \ + arch/mips/gt64120/momenco_ocelot/ +load-$(CONFIG_MOMENCO_OCELOT) += 0x80100000 + +# +# Momentum Ocelot-G board +# +# The Ocelot-G setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +# +core-$(CONFIG_MOMENCO_OCELOT_G) += arch/mips/momentum/ocelot_g/ +load-$(CONFIG_MOMENCO_OCELOT_G) += 0x80100000 + +# +# Momentum Ocelot-C and -CS boards +# +# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the +# mips_io_port_base. +core-$(CONFIG_MOMENCO_OCELOT_C) += arch/mips/momentum/ocelot_c/ +load-$(CONFIG_MOMENCO_OCELOT_C) += 0x80100000 + +# +# SGI IP22 (Indy/Indigo2) +# +# Set the load address to >= 0x88069000 if you want to leave space for symmon, +# 0x88004000 for production kernels. Note that the value must be 16kb aligned +# or the handling of the current variable will break. +# +core-$(CONFIG_SGI_IP22) += arch/mips/sgi-ip22/ +load-$(CONFIG_SGI_IP22) += 0x88004000 + +# +# SGI-IP27 (Origin200/2000) +# +# Set the load address to >= 0xc000000000300000 if you want to leave space for # symmon, 0xc00000000001c000 for production kernels. Note that the value # must be 16kb aligned or the handling of the current variable will break. # -#LOADADDR += 0xa80000000001c000 +ifdef CONFIG_SGI_IP27 +core-$(CONFIG_SGI_IP27) += arch/mips/sgi-ip27/ +#load-$(CONFIG_SGI_IP27) += 0xa80000000001c000 ifdef CONFIG_MAPPED_KERNEL -LOADADDR += 0xc001c000 +load-$(CONFIG_SGI_IP27) += 0xc001c000 else -LOADADDR += 0x8001c000 +load-$(CONFIG_SGI_IP27) += 0x8001c000 endif endif -ifdef CONFIG_SGI_IP32 -libs-y += arch/mips64/sgi-ip32/ - arch/mips64/arc/ # -# Set LOADADDR to >= 0x????????? if you want to leave space for symmon, -# 0x80002000 for production kernels. Note that the value must be -# 16kb aligned or the handling of the current variable will break. +# SGI-IP32 (O2) # -LOADADDR += 0x80002000 +# Set the load address to >= 0x????????? if you want to leave space for symmon, +# 0x80002000 for production kernels. Note that the value must be 16kb aligned +# or the handling of the current variable will break. +# +core-$(CONFIG_SGI_IP32) += arch/mips/sgi-ip32/ +load-$(CONFIG_SGI_IP32) += 0x80002000 + +# +# Sibyte SB1250 SOC +# +# This is a LIB so that it links at the end, and initcalls are later +# the sequence; but it is built as an object so that modules don't get +# removed (as happens, even if they have __initcall/module_init) +# +core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/sb1250/ +ifdef CONFIG_SIBYTE_BCM112X +ifdef CONFIG_MIPS_UNCACHED +load-y += 0xa0100000 +else +load-y += 0x80100000 +endif +endif +ifdef CONFIG_SIBYTE_SB1250 +ifdef CONFIG_MIPS_UNCACHED +load-y += 0xa0100000 +else +load-y += 0x80100000 +endif endif # +# Sibyte BCM91120x (Carmel) board +# Sibyte BCM91120C (CRhine) board +# Sibyte BCM91125C (CRhone) board +# Sibyte BCM91125E (Rhone) board +# Sibyte SWARM board +# +libs-$(CONFIG_SIBYTE_CARMEL) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_CARMEL) := 0x80100000 +libs-$(CONFIG_SIBYTE_CRHINE) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_CRHINE) := 0x80100000 +libs-$(CONFIG_SIBYTE_CRHONE) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_CRHONE) := 0x80100000 +libs-$(CONFIG_SIBYTE_RHONE) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_RHONE) := 0x80100000 +libs-$(CONFIG_SIBYTE_SENTOSA) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_SENTOSA) := 0x80100000 +libs-$(CONFIG_SIBYTE_SWARM) += arch/mips/sibyte/swarm/ +load-$(CONFIG_SIBYTE_SWARM) := 0x80100000 + +# +# SNI RM200 PCI +# +core-$(CONFIG_SNI_RM200_PCI) += arch/mips/sni/ +load-$(CONFIG_SNI_RM200_PCI) += 0x80080000 + +drivers-$(CONFIG_PCI) += arch/mips/pci/ + +# # Some machines like the Indy need 32-bit ELF binaries for booting purposes. # Other need ECOFF, so we build a 32-bit ELF binary for them which we then # convert to ECOFF using elf2ecoff. # -ifdef CONFIG_BOOT_ELF32 -CFLAGS += -Wa,-32 -endif -# # The 64-bit ELF tools are pretty broken so at this time we generate 64-bit # ELF files from 32-bit files by conversion. # -ifdef CONFIG_BOOT_ELF64 -CFLAGS += -Wa,-32 #AS += -64 #LDFLAGS += -m elf64bmip -#LDFLAGS_vmlinux += -T arch/mips64/ld.script.elf64 -endif +cflags-$(CONFIG_BOOT_ELF32) += -Wa,-32 +cflags-$(CONFIG_BOOT_ELF64) += -Wa,-32 -LDFLAGS_vmlinux += -Ttext $(LOADADDR) +GRRR=-Wa,-mgp64 +cflags-$(CONFIG_BOOT_ELF32) += -Wa,-32 $(call check_warning, $(GRRR),) +cflags-$(CONFIG_BOOT_ELF64) += -Wa,-32 $(call check_warning, $(GRRR),) -head-y := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o +AFLAGS_vmlinux.lds.o := -imacros $(srctree)/include/asm-mips64/sn/mapped_kernel.h \ + -D"LOADADDR=$(load-y)" -SUBDIRS := arch/mips64/tools $(SUBDIRS) -core-y += arch/mips64/kernel/ arch/mips64/mm/ -libs-y += arch/mips64/lib/lib.a +AFLAGS += $(cflags-y) +CFLAGS += $(cflags-y) -MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot +LDFLAGS += --oformat $(32bit-bfd) +LDFLAGS_BLOB := --format binary --oformat $(64bit-bfd) -ifdef CONFIG_CPU_LITTLE_ENDIAN -64bit-bfd = elf64-littlemips -else -64bit-bfd = elf64-bigmips -endif +head-y := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o + +libs-y += arch/mips64/lib/ +core-y += arch/mips64/kernel/ arch/mips64/mm/ arch/mips/math-emu/ -AFLAGS_vmlinux.lds.o := -imacros $(srctree)/include/asm-mips64/sn/mapped_kernel.h +MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot ifdef CONFIG_MAPPED_KERNEL vmlinux.64: vmlinux @@ -152,18 +275,59 @@ $(OBJCOPY) -O $(64bit-bfd) --change-addresses=0xa7ffffff80000000 $< $@ endif -zImage: vmlinux - @$(MAKEBOOT) zImage +makeboot =$(Q)$(MAKE) -f scripts/Makefile.build obj=arch/mips/boot $(1) -compressed: zImage +# +# SNI firmware is f*cked in interesting ways ... +# +ifdef CONFIG_SNI_RM200_PCI +all: vmlinux.rm200 +endif + +vmlinux.ecoff vmlinux.rm200: vmlinux + +@$(call makeboot,$@) -zdisk: vmlinux - @$(MAKEBOOT) zdisk +CLEAN_FILES += vmlinux.ecoff \ + vmlinux.rm200.tmp \ + vmlinux.rm200 archclean: - @$(MAKEBOOT) clean - $(MAKE) -C arch/$(ARCH)/tools clean + @$(MAKE) -f scripts/Makefile.clean obj=arch/mips/boot + @$(MAKE) -f scripts/Makefile.clean obj=arch/mips/baget + @$(MAKE) -f scripts/Makefile.clean obj=arch/mips/lasat archmrproper: @$(MAKEBOOT) mrproper - $(MAKE) -C arch/$(ARCH)/tools mrproper + +# Generate <asm/offset.h +# +# The default rule is suffering from funny problems on MIPS so we using our +# own ... +# +# --------------------------------------------------------------------------- + +define filechk_gen-asm-offset.h + (set -e; \ + echo "#ifndef __ASM_OFFSET_H"; \ + echo "#define __ASM_OFFSET_H"; \ + echo "/*"; \ + echo " * DO NOT MODIFY."; \ + echo " *"; \ + echo " * This file was generated by arch/$(ARCH)/Makefile"; \ + echo " *"; \ + echo " */"; \ + echo ""; \ + sed -ne "/^@@@/s///p"; \ + echo "#endif /* __ASM_OFFSET_H */" ) +endef + +prepare: include/asm-$(ARCH)/offset.h + +arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \ + include/config/MARKER + +include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s + $(call filechk,gen-asm-offset.h) + +CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \ + include/asm-$(ARCH)/offset.h diff -Nru a/arch/mips64/arc/Makefile b/arch/mips64/arc/Makefile --- a/arch/mips64/arc/Makefile Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -# -# Makefile for the ARC prom monitor library routines under Linux. -# - -lib-y := console.o init.o identify.o tree.o env.o cmdline.o misc.o time.o \ - file.o - -lib-$(CONFIG_ARC_MEMORY) += memory.o -lib-$(CONFIG_ARC_CONSOLE) += arc_con.o diff -Nru a/arch/mips64/arc/arc_con.c b/arch/mips64/arc/arc_con.c --- a/arch/mips64/arc/arc_con.c Fri Jun 27 14:20:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,78 +0,0 @@ -/* - * Wrap-around code for a console using the - * ARC io-routines. - * - * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 2001 Ralf Baechle - */ -#include <linux/tty.h> -#include <linux/major.h> -#include <linux/ptrace.h> -#include <linux/init.h> -#include <linux/console.h> -#include <linux/fs.h> - -#include <asm/sgialib.h> - -extern void prom_printf (char *, ...); - -void prom_putchar(char c) -{ - ULONG cnt; - CHAR it = c; - - ArcWrite(1, &it, 1, &cnt); -} - -static void prom_console_write(struct console *co, const char *s, - unsigned count) -{ - unsigned i; - - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - if (*s == 10) - prom_printf("%c", 13); - prom_printf("%c", *s++); - } -} - -static int prom_console_wait_key(struct console *co) -{ - return 0; -} - -static int __init prom_console_setup(struct console *co, char *options) -{ - return 0; -} - -static kdev_t prom_console_device(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -static struct console arc_cons = { - "ttyS", - prom_console_write, - NULL, - prom_console_device, - prom_console_wait_key, - NULL, - prom_console_setup, - CON_PRINTBUFFER, - -1, - 0, - NULL -}; - -/* - * Register console. - */ - -void __init arc_console_init(void) -{ - register_console(&arc_cons); -} diff -Nru a/arch/mips64/arc/cmdline.c b/arch/mips64/arc/cmdline.c --- a/arch/mips64/arc/cmdline.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,111 +0,0 @@ -/* - * 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. - * - * cmdline.c: Kernel command line creation using ARCS argc/argv. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> - -#include <asm/sgialib.h> -#include <asm/bootinfo.h> - -/* #define DEBUG_CMDLINE */ - -char arcs_cmdline[CL_SIZE]; - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - -static char *ignored[] = { - "ConsoleIn=", - "ConsoleOut=", - "SystemPartition=", - "OSLoader=", - "OSLoadPartition=", - "OSLoadFilename=", - "OSLoadOptions=" -}; -#define NENTS(foo) ((sizeof((foo)) / (sizeof((foo[0]))))) - -static char *used_arc[][2] = { - { "OSLoadPartition=", "root=" }, - { "OSLoadOptions=", "" } -}; - -static char * __init move_firmware_args(char* cp) -{ - char *s; - int actr, i; - - actr = 1; /* Always ignore argv[0] */ - - while (actr < prom_argc) { - for(i = 0; i < NENTS(used_arc); i++) { - int len = strlen(used_arc[i][0]); - - if (!strncmp(prom_argv(actr), used_arc[i][0], len)) { - /* Ok, we want it. First append the replacement... */ - strcat(cp, used_arc[i][1]); - cp += strlen(used_arc[i][1]); - /* ... and now the argument */ - s = strstr(prom_argv(actr), "="); - if (s) { - s++; - strcpy(cp, s); - cp += strlen(s); - } - *cp++ = ' '; - break; - } - } - actr++; - } - - return cp; -} - - -void __init prom_init_cmdline(void) -{ - char *cp; - int actr, i; - - actr = 1; /* Always ignore argv[0] */ - - cp = &(arcs_cmdline[0]); - /* - * Move ARC variables to the beginning to make sure they can be - * overridden by later arguments. - */ - cp = move_firmware_args(cp); - - while (actr < prom_argc) { - for (i = 0; i < NENTS(ignored); i++) { - int len = strlen(ignored[i]); - - if (!strncmp(prom_argv(actr), ignored[i], len)) - goto pic_cont; - } - /* Ok, we want it. */ - strcpy(cp, prom_argv(actr)); - cp += strlen(prom_argv(actr)); - *cp++ = ' '; - - pic_cont: - actr++; - } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ - --cp; - *cp = '\0'; - -#ifdef DEBUG_CMDLINE - prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); -#endif -} diff -Nru a/arch/mips64/arc/console.c b/arch/mips64/arc/console.c --- a/arch/mips64/arc/console.c Fri Jun 27 14:20:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,33 +0,0 @@ -/* - * 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) 1996 David S. Miller (dm@sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <asm/sgialib.h> - -static char ppbuf[1024]; - -void prom_printf(char *fmt, ...) -{ - va_list args; - char ch, *bptr; - int i; - - va_start(args, fmt); - i = vsprintf(ppbuf, fmt, args); - - bptr = ppbuf; - - while((ch = *(bptr++)) != 0) { - if(ch == '\n') - prom_putchar('\r'); - - prom_putchar(ch); - } - va_end(args); - return; -} diff -Nru a/arch/mips64/arc/env.c b/arch/mips64/arc/env.c --- a/arch/mips64/arc/env.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,27 +0,0 @@ -/* - * 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. - * - * env.c: ARCS environment variable routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/string.h> - -#include <asm/arc/types.h> -#include <asm/sgialib.h> - -PCHAR __init -ArcGetEnvironmentVariable(CHAR *name) -{ - return (CHAR *) ARC_CALL1(get_evar, name); -} - -LONG __init -ArcSetEnvironmentVariable(PCHAR name, PCHAR value) -{ - return ARC_CALL2(set_evar, name, value); -} diff -Nru a/arch/mips64/arc/file.c b/arch/mips64/arc/file.c --- a/arch/mips64/arc/file.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,75 +0,0 @@ -/* - * 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. - * - * ARC firmware interface. - * - * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include <linux/init.h> - -#include <asm/arc/types.h> -#include <asm/sgialib.h> - -LONG __init -ArcGetDirectoryEntry(ULONG FileID, struct linux_vdirent *Buffer, - ULONG N, ULONG *Count) -{ - return ARC_CALL4(get_vdirent, FileID, Buffer, N, Count); -} - -LONG __init -ArcOpen(CHAR *Path, enum linux_omode OpenMode, ULONG *FileID) -{ - return ARC_CALL3(open, Path, OpenMode, FileID); -} - -LONG __init -ArcClose(ULONG FileID) -{ - return ARC_CALL1(close, FileID); -} - -LONG __init -ArcRead(ULONG FileID, VOID *Buffer, ULONG N, ULONG *Count) -{ - return ARC_CALL4(read, FileID, Buffer, N, Count); -} - -LONG __init -ArcGetReadStatus(ULONG FileID) -{ - return ARC_CALL1(get_rstatus, FileID); -} - -LONG __init -ArcWrite(ULONG FileID, PVOID Buffer, ULONG N, PULONG Count) -{ - return ARC_CALL4(write, FileID, Buffer, N, Count); -} - -LONG __init -ArcSeek(ULONG FileID, struct linux_bigint *Position, enum linux_seekmode SeekMode) -{ - return ARC_CALL3(seek, FileID, Position, SeekMode); -} - -LONG __init -ArcMount(char *name, enum linux_mountops op) -{ - return ARC_CALL2(mount, name, op); -} - -LONG __init -ArcGetFileInformation(ULONG FileID, struct linux_finfo *Information) -{ - return ARC_CALL2(get_finfo, FileID, Information); -} - -LONG __init ArcSetFileInformation(ULONG FileID, ULONG AttributeFlags, - ULONG AttributeMask) -{ - return ARC_CALL3(set_finfo, FileID, AttributeFlags, AttributeMask); -} diff -Nru a/arch/mips64/arc/identify.c b/arch/mips64/arc/identify.c --- a/arch/mips64/arc/identify.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,79 +0,0 @@ -/* - * 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. - * - * identify.c: identify machine by looking up system identifier - * - * Copyright (C) 1998 Thomas Bogendoerfer - * - * This code is based on arch/mips/sgi/kernel/system.c, which is - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/string.h> - -#include <asm/sgialib.h> -#include <asm/bootinfo.h> - -struct smatch { - char *name; - int group; - int type; - int flags; -}; - -static struct smatch mach_table[] = { - { "SGI-IP22", MACH_GROUP_SGI, MACH_SGI_INDY, PROM_FLAG_ARCS }, - { "SGI-IP27", MACH_GROUP_SGI, MACH_SGI_IP27, PROM_FLAG_ARCS }, - { "Microsoft-Jazz", MACH_GROUP_JAZZ, MACH_MIPS_MAGNUM_4000, 0 }, - { "PICA-61", MACH_GROUP_JAZZ, MACH_ACER_PICA_61, 0 }, - { "RM200PCI", MACH_GROUP_SNI_RM, MACH_SNI_RM200_PCI, 0 } -}; - -int prom_flags; - -static struct smatch * __init -string_to_mach(const char *s) -{ - int i; - - for (i = 0; i < (sizeof (mach_table) / sizeof (mach_table[0])); i++) { - if(!strcmp(s, mach_table[i].name)) - return &mach_table[i]; - } - panic("\nYeee, could not determine architecture type <%s>", s); - - return NULL; -} - -void __init -prom_identify_arch(void) -{ - pcomponent *p; - struct smatch *mach; - const char *iname; - - /* The root component tells us what machine architecture we - have here. */ - p = ArcGetChild(PROM_NULL_COMPONENT); - if (p == NULL) { -#ifdef CONFIG_SGI_IP27 - /* IP27 PROM bisbehaves, seems to not implement ARC - GetChild(). So we just assume it's an IP27. */ - iname = "SGI-IP27"; -#endif - } else - iname = (char *) (long) p->iname; - - printk("ARCH: %s\n", iname); - mach = string_to_mach(iname); - - mips_machgroup = mach->group; - mips_machtype = mach->type; - prom_flags = mach->flags; -} diff -Nru a/arch/mips64/arc/init.c b/arch/mips64/arc/init.c --- a/arch/mips64/arc/init.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,60 +0,0 @@ -/* - * 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. - * - * PROM library initialisation code. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> - -#include <asm/sgialib.h> - -#undef DEBUG_PROM_INIT - -/* Master romvec interface. */ -struct linux_romvec *romvec; -PSYSTEM_PARAMETER_BLOCK sgi_pblock; -int prom_argc; -LONG *_prom_argv, *_prom_envp; -unsigned short prom_vers, prom_rev; - -extern void prom_testtree(void); - -int __init -prom_init(int argc, char **argv, char **envp) -{ - PSYSTEM_PARAMETER_BLOCK pb; - - romvec = ROMVECTOR; - pb = sgi_pblock = PROMBLOCK; - prom_argc = argc; - _prom_argv = (LONG *) argv; - _prom_envp = (LONG *) envp; - - if(pb->magic != 0x53435241) { - prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic); - while(1) - ; - } - - prom_init_cmdline(); - - prom_vers = pb->ver; - prom_rev = pb->rev; - prom_identify_arch(); - printk("PROMLIB: ARC firmware Version %d Revision %d\n", - prom_vers, prom_rev); - prom_meminit(); - -#ifdef DEBUG_PROM_INIT - { - prom_printf("Press a key to reboot\n"); - (void) prom_getchar(); - ArcEnterInteractiveMode(); - } -#endif - return 0; -} diff -Nru a/arch/mips64/arc/memory.c b/arch/mips64/arc/memory.c --- a/arch/mips64/arc/memory.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,163 +0,0 @@ -/* - * memory.c: PROM library functions for acquiring/using memory descriptors - * given to us from the ARCS firmware. - * - * Copyright (C) 1996 by David S. Miller - * Copyright (C) 1999, 2000, 2001 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics, Inc. - * - * PROM library functions for acquiring/using memory descriptors given to us - * from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set - * because on some machines like SGI IP27 the ARC memory configuration data - * completly bogus and alternate easier to use mechanisms are available. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/swap.h> - -#include <asm/sgialib.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/bootinfo.h> - -#undef DEBUG - -struct linux_mdesc * __init -ArcGetMemoryDescriptor(struct linux_mdesc *Current) -{ - return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current); -} - -#ifdef DEBUG /* convenient for debugging */ -static char *arcs_mtypes[8] = { - "Exception Block", - "ARCS Romvec Page", - "Free/Contig RAM", - "Generic Free RAM", - "Bad Memory", - "Standalone Program Pages", - "ARCS Temp Storage Area", - "ARCS Permanent Storage Area" -}; - -static char *arc_mtypes[8] = { - "Exception Block", - "SystemParameterBlock", - "FreeMemory", - "Bad Memory", - "LoadedProgram", - "FirmwareTemporary", - "FirmwarePermanent", - "FreeContiguous" -}; -#define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] \ - : arc_mtypes[a.arc] -#endif - -static inline int memtype_classify_arcs (union linux_memtypes type) -{ - switch (type.arcs) { - case arcs_fcontig: - case arcs_free: - return BOOT_MEM_RAM; - case arcs_atmp: - return BOOT_MEM_ROM_DATA; - case arcs_eblock: - case arcs_rvpage: - case arcs_bmem: - case arcs_prog: - case arcs_aperm: - return BOOT_MEM_RESERVED; - default: - BUG(); - } - while(1); /* Nuke warning. */ -} - -static inline int memtype_classify_arc (union linux_memtypes type) -{ - switch (type.arc) { - case arc_free: - case arc_fcontig: - return BOOT_MEM_RAM; - case arc_atmp: - return BOOT_MEM_ROM_DATA; - case arc_eblock: - case arc_rvpage: - case arc_bmem: - case arc_prog: - case arc_aperm: - return BOOT_MEM_RESERVED; - default: - BUG(); - } - while(1); /* Nuke warning. */ -} - -static int __init prom_memtype_classify (union linux_memtypes type) -{ - if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */ - return memtype_classify_arcs(type); - - return memtype_classify_arc(type); -} - -void __init prom_meminit(void) -{ - struct linux_mdesc *p; - -#ifdef DEBUG - int i = 0; - - prom_printf("ARCS MEMORY DESCRIPTOR dump:\n"); - i=0; - prom_printf ("i=%d\n", i); - p = ArcGetMemoryDescriptor(PROM_NULL_MDESC); - prom_printf ("i=%d\n", i); - while(p) { - prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n", - i, p, p->base, p->pages, mtypes(p->type)); - p = ArcGetMemoryDescriptor(p); - i++; - } -#endif - - p = PROM_NULL_MDESC; - while ((p = ArcGetMemoryDescriptor(p))) { - unsigned long base, size; - long type; - - base = p->base << PAGE_SHIFT; - size = p->pages << PAGE_SHIFT; - type = prom_memtype_classify(p->type); - - add_memory_region(base, size, type); - } -} - -void __init prom_free_prom_memory (void) -{ - unsigned long freed = 0; - unsigned long addr; - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) - continue; - - addr = boot_mem_map.map[i].addr; - while (addr < boot_mem_map.map[i].addr - + boot_mem_map.map[i].size) { - ClearPageReserved(virt_to_page(__va(addr))); - set_page_count(virt_to_page(__va(addr)), 1); - free_page((unsigned long)__va(addr)); - addr += PAGE_SIZE; - freed += PAGE_SIZE; - } - } - printk(KERN_INFO "Freeing prom memory: %ldkb freed\n", freed >> 10); -} diff -Nru a/arch/mips64/arc/misc.c b/arch/mips64/arc/misc.c --- a/arch/mips64/arc/misc.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,104 +0,0 @@ -/* - * 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. - * - * Miscellaneous ARCS PROM routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kernel.h> - -#include <asm/bcache.h> - -#include <asm/arc/types.h> -#include <asm/sgialib.h> -#include <asm/bootinfo.h> -#include <asm/system.h> - -extern unsigned long mips_cputype; -extern void *sgiwd93_host; -extern void reset_wd33c93(void *instance); - -VOID -ArcHalt(VOID) -{ - bc_disable(); - cli(); -#ifdef CONFIG_SCSI_SGIWD93 - reset_wd33c93(sgiwd93_host); -#endif - ARC_CALL0(halt); -never: goto never; -} - -VOID -ArcPowerDown(VOID) -{ - bc_disable(); - cli(); -#ifdef CONFIG_SCSI_SGIWD93 - reset_wd33c93(sgiwd93_host); -#endif - ARC_CALL0(pdown); -never: goto never; -} - -/* XXX is this a soft reset basically? XXX */ -VOID -ArcRestart(VOID) -{ - bc_disable(); - cli(); -#ifdef CONFIG_SCSI_SGIWD93 - reset_wd33c93(sgiwd93_host); -#endif - ARC_CALL0(restart); -never: goto never; -} - -VOID -ArcReboot(VOID) -{ - bc_disable(); - cli(); -#ifdef CONFIG_SCSI_SGIWD93 - reset_wd33c93(sgiwd93_host); -#endif - ARC_CALL0(reboot); -never: goto never; -} - -VOID -ArcEnterInteractiveMode(VOID) -{ - bc_disable(); - cli(); -#ifdef CONFIG_SCSI_SGIWD93 - reset_wd33c93(sgiwd93_host); -#endif - ARC_CALL0(imode); -never: goto never; -} - -LONG -ArcSaveConfiguration(VOID) -{ - return ARC_CALL0(cfg_save); -} - -struct linux_sysid * -ArcGetSystemId(VOID) -{ - return (struct linux_sysid *) ARC_CALL0(get_sysid); -} - -VOID __init -ArcFlushAllCaches(VOID) -{ - ARC_CALL0(cache_flush); -} diff -Nru a/arch/mips64/arc/salone.c b/arch/mips64/arc/salone.c --- a/arch/mips64/arc/salone.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,27 +0,0 @@ -/* - * Routines to load into memory and execute stand-along program images using - * ARCS PROM firmware. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> -#include <asm/sgialib.h> - -LONG __init -ArcLoad(CHAR *Path, ULONG TopAddr, ULONG *ExecAddr, ULONG *LowAddr) -{ - return ARC_CALL4(load, Path, TopAddr, ExecAddr, LowAddr); -} - -LONG __init -ArcInvoke(ULONG ExecAddr, ULONG StackAddr, ULONG Argc, CHAR *Argv[], - CHAR *Envp[]) -{ - return ARC_CALL5(invoke, ExecAddr, StackAddr, Argc, Argv, Envp); -} - -LONG __init -ArcExecute(CHAR *Path, LONG Argc, CHAR *Argv[], CHAR *Envp[]) -{ - return ARC_CALL4(exec, Path, Argc, Argv, Envp); -} diff -Nru a/arch/mips64/arc/time.c b/arch/mips64/arc/time.c --- a/arch/mips64/arc/time.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,25 +0,0 @@ -/* - * 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. - * - * Extracting time information from ARCS prom. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> - -#include <asm/arc/types.h> -#include <asm/sgialib.h> - -struct linux_tinfo * __init -ArcGetTime(VOID) -{ - return (struct linux_tinfo *) ARC_CALL0(get_tinfo); -} - -ULONG __init -ArcGetRelativeTime(VOID) -{ - return ARC_CALL0(get_rtime); -} diff -Nru a/arch/mips64/arc/tree.c b/arch/mips64/arc/tree.c --- a/arch/mips64/arc/tree.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,127 +0,0 @@ -/* - * 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. - * - * PROM component device tree code. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include <linux/init.h> -#include <asm/arc/types.h> -#include <asm/sgialib.h> - -#undef DEBUG_PROM_TREE - -pcomponent * __init -ArcGetPeer(pcomponent *Current) -{ - if (Current == PROM_NULL_COMPONENT) - return PROM_NULL_COMPONENT; - - return (pcomponent *) ARC_CALL1(next_component, Current); -} - -pcomponent * __init -ArcGetChild(pcomponent *Current) -{ - return (pcomponent *) ARC_CALL1(child_component, Current); -} - -pcomponent * __init -ArcGetParent(pcomponent *Current) -{ - if (Current == PROM_NULL_COMPONENT) - return PROM_NULL_COMPONENT; - - return (pcomponent *) ARC_CALL1(parent_component, Current); -} - -LONG __init -ArcGetConfigurationData(VOID *Buffer, pcomponent *Current) -{ - return ARC_CALL2(component_data, Buffer, Current); -} - -pcomponent * __init -ArcAddChild(pcomponent *Current, pcomponent *Template, VOID *ConfigurationData) -{ - return (pcomponent *) - ARC_CALL3(child_add, Current, Template, ConfigurationData); -} - -LONG __init -ArcDeleteComponent(pcomponent *ComponentToDelete) -{ - return ARC_CALL1(comp_del, ComponentToDelete); -} - -pcomponent * __init -ArcGetComponent(CHAR *Path) -{ - return (pcomponent *)ARC_CALL1(component_by_path, Path); -} - -#ifdef DEBUG_PROM_TREE - -static char *classes[] = { - "system", "processor", "cache", "adapter", "controller", "peripheral", - "memory" -}; - -static char *types[] = { - "arc", "cpu", "fpu", "picache", "pdcache", "sicache", "sdcache", - "sccache", "memdev", "eisa adapter", "tc adapter", "scsi adapter", - "dti adapter", "multi-func adapter", "disk controller", - "tp controller", "cdrom controller", "worm controller", - "serial controller", "net controller", "display controller", - "parallel controller", "pointer controller", "keyboard controller", - "audio controller", "misc controller", "disk peripheral", - "floppy peripheral", "tp peripheral", "modem peripheral", - "monitor peripheral", "printer peripheral", "pointer peripheral", - "keyboard peripheral", "terminal peripheral", "line peripheral", - "net peripheral", "misc peripheral", "anonymous" -}; - -static char *iflags[] = { - "bogus", "read only", "removable", "console in", "console out", - "input", "output" -}; - -static void __init -dump_component(pcomponent *p) -{ - prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", - p, classes[p->class], types[p->type], - iflags[p->iflags], p->vers, p->rev); - prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n", - p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); -} - -static void __init -traverse(pcomponent *p, int op) -{ - dump_component(p); - if(ArcGetChild(p)) - traverse(ArcGetChild(p), 1); - if(ArcGetPeer(p) && op) - traverse(ArcGetPeer(p), 1); -} - -void __init -prom_testtree(void) -{ - pcomponent *p; - - p = ArcGetChild(PROM_NULL_COMPONENT); - dump_component(p); - p = ArcGetChild(p); - while(p) { - dump_component(p); - p = ArcGetPeer(p); - } -} - -#endif /* DEBUG_PROM_TREE */ diff -Nru a/arch/mips64/boot/Makefile b/arch/mips64/boot/Makefile --- a/arch/mips64/boot/Makefile Fri Jun 27 14:20:03 2003 +++ b/arch/mips64/boot/Makefile Fri Jun 27 14:20:03 2003 @@ -15,16 +15,30 @@ E2EFLAGS = endif +# +# Drop some uninteresting sections in the kernel. +# This is only relevant for ELF kernels but doesn't hurt a.out +# +drop-sections = .reginfo .mdebug .comment .note +strip-flags = $(addprefix --remove-section=,$(drop-sections)) + all: vmlinux.ecoff addinitrd +vmlinux.rm200: vmlinux + $(OBJCOPY) \ + --change-addresses=0xfffffffc \ + -O elf32-littlemips \ + $(strip-flags) \ + $< $@ + vmlinux.ecoff: elf2ecoff $(TOPDIR)/vmlinux ./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS) -elf2ecoff: elf2ecoff.c - $(HOSTCC) -o $@ $^ +elf2ecoff: $(TOPDIR)/arch/mips/boot/elf2ecoff.c + $(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^ -addinitrd: addinitrd.c - $(HOSTCC) -o $@ $^ +addinitrd: $(TOPDIR)/arch/mips/boot/addinitrd.c + $(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^ clean: rm -f vmlinux.ecoff diff -Nru a/arch/mips64/defconfig b/arch/mips64/defconfig --- a/arch/mips64/defconfig Fri Jun 27 14:19:59 2003 +++ b/arch/mips64/defconfig Fri Jun 27 14:19:59 2003 @@ -1,71 +1,133 @@ # # Automatically generated make config: don't edit # +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y # # Code maturity level options # -# CONFIG_EXPERIMENTAL is not set +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set # # Machine selection # +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set CONFIG_SGI_IP27=y # CONFIG_SGI_SN0_N_MODE is not set -CONFIG_DISCONTIGMEM=y -CONFIG_NUMA=y +# CONFIG_DISCONTIGMEM is not set +# CONFIG_NUMA is not set # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -CONFIG_SMP=y +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BOOT_ELF64=y +CONFIG_ARC=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_L1_CACHE_SHIFT=7 +# CONFIG_FB is not set CONFIG_ARC64=y -CONFIG_COHERENT_IO=y -CONFIG_MAPPED_PCI_IO=y -CONFIG_PCI=y +CONFIG_BOOT_ELF64=y CONFIG_QL_ISP_A64=y -CONFIG_L1_CACHE_SHIFT=7 -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_NR_CPUS=64 # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set CONFIG_CPU_R10000=y +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_MIPS_INSANE_LARGE is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_MIPS_INSANE_LARGE is not set -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_NET=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +CONFIG_MMU=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_BINFMT_ELF=y -CONFIG_MIPS32_COMPAT=y -CONFIG_BINFMT_ELF32=y -# CONFIG_BINFMT_MISC is not set # -# Loadable module support +# Executable file formats # -# CONFIG_MODULES is not set -CONFIG_PCI_NAMES=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y # # Memory Technology Devices (MTD) @@ -78,83 +140,35 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y -CONFIG_NETLINK_DEV=y -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# SCSI device support # CONFIG_SCSI=y @@ -162,7 +176,6 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set @@ -171,8 +184,8 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -180,52 +193,116 @@ # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -CONFIG_SCSI_QLOGIC_ISP=y +# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set # -# Network device support +# IEEE 1394 (FireWire) support (EXPERIMENTAL) # +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -236,39 +313,44 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set CONFIG_SGI_IOC3_ETH=y -# CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set -# CONFIG_PLIP is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -278,10 +360,11 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set # CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set # # Wan interfaces @@ -301,21 +384,69 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input Device Drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -325,32 +456,33 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +CONFIG_SGI_IP27_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -361,6 +493,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -368,79 +502,92 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +CONFIG_JBD_DEBUG=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -457,12 +604,15 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set -CONFIG_KCORE_ELF=y +# CONFIG_EFI_PARTITION is not set + +# +# Graphics support +# # # Sound @@ -473,113 +623,30 @@ # USB support # # CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# USB Controllers +# Bluetooth support # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set +# CONFIG_BT is not set # -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/defconfig-atlas b/arch/mips64/defconfig-atlas --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/defconfig-atlas Fri Jun 27 14:20:06 2003 @@ -0,0 +1,547 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +CONFIG_MIPS_ATLAS=y +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_MIPS_BOARDS_GEN=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EFS_FS=y +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/defconfig-decstation b/arch/mips64/defconfig-decstation --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/defconfig-decstation Fri Jun 27 14:20:06 2003 @@ -0,0 +1,573 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +CONFIG_DECSTATION=y +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=4 +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +CONFIG_CPU_R4X00=y +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_TC=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SCSI_DECNCR=y +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_DECLANCE=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ATKBD is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_DZ=y +CONFIG_SERIAL_DZ_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_EXPORTFS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +CONFIG_ULTRIX_PARTITION=y +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22 --- a/arch/mips64/defconfig-ip22 Fri Jun 27 14:19:57 2003 +++ b/arch/mips64/defconfig-ip22 Fri Jun 27 14:19:57 2003 @@ -1,6 +1,9 @@ # # Automatically generated make config: don't edit # +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y # # Code maturity level options @@ -8,57 +11,122 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Machine selection # +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set CONFIG_SGI_IP22=y # CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_ARC=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_IRQ_CPU=y +CONFIG_SWAP_IO_SPACE=y CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 CONFIG_ARC32=y +# CONFIG_FB is not set +CONFIG_ARC_CONSOLE=y +CONFIG_ARC_PROMLIB=y CONFIG_BOARD_SCACHE=y -CONFIG_ARC_MEMORY=y -CONFIG_SGI=y -CONFIG_L1_CACHE_SHIFT=5 -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_PCI is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_MIPS_FPU_EMULATOR is not set -CONFIG_NET=y +# CONFIG_ISA is not set +CONFIG_MMU=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_ARC_CONSOLE is not set -CONFIG_BINFMT_ELF=y -CONFIG_MIPS32_COMPAT=y -CONFIG_BINFMT_ELF32=y -# CONFIG_BINFMT_MISC is not set # -# Loadable module support +# Executable file formats # -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y +CONFIG_BINFMT_ELF32=y # # Memory Technology Devices (MTD) @@ -71,41 +139,90 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_SGIWD93_SCSI=y +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# # Multi-device support (RAID and LVM) # # CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y # # Networking options # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y CONFIG_NETLINK_DEV=y # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y +CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set @@ -119,20 +236,24 @@ # CONFIG_ARPD is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set # CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set +# CONFIG_XFRM_USER is not set # -# +# SCTP Configuration (EXPERIMENTAL) # -# CONFIG_IPX is not set -# CONFIG_ATALK is not set +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_LLC is not set # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -145,94 +266,10 @@ # CONFIG_NET_SCHED is not set # -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_SR_EXTRA_DEVS=2 -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI low-level drivers -# -CONFIG_SGIWD93_SCSI=y -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support +# Network testing # +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set @@ -243,33 +280,16 @@ # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set +# CONFIG_MII is not set CONFIG_SGISEEQ=y # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set + +# +# Ethernet (10000 Mbit) +# # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -279,11 +299,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set # CONFIG_SHAPER is not set # @@ -304,21 +321,69 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input I/O drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y -# CONFIG_SERIAL is not set -# CONFIG_SERIAL_EXTENDED is not set +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_IP22_ZILOG=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -328,36 +393,58 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_SCx200_WDT is not set +# CONFIG_60XX_WDT is not set +# CONFIG_W83877F_WDT is not set +# CONFIG_MACHZ_WDT is not set +CONFIG_INDYDOG=y +# CONFIG_SC520_WDT is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC1200_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_CPU5_WDT is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +CONFIG_SGI_DS1286=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set # # Ftape, the floppy tape device driver @@ -365,6 +452,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -372,78 +461,92 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set CONFIG_NFSD=y # CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -460,150 +563,82 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set +# CONFIG_EFI_PARTITION is not set # -# Console drivers +# Graphics support # # -# Frame-buffer support +# Console display driver support # -# CONFIG_FB is not set +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set CONFIG_SGI_NEWPORT_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y CONFIG_FONT_8x16=y -CONFIG_KCORE_ELF=y # -# Sound +# Logo configuration # -# CONFIG_SOUND is not set +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +# CONFIG_LOGO_LINUX_CLUT224 is not set +CONFIG_LOGO_SGI_CLUT224=y # -# SGI devices +# Sound # -CONFIG_SGI_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -CONFIG_SGI_DS1286=y -# CONFIG_SGI_NEWPORT_GFX is not set +# CONFIG_SOUND is not set # # USB support # -# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# USB Controllers +# Bluetooth support # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set +# CONFIG_BT is not set # -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_MIPS_FPE_MODULE is not set -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MIPS_UNCACHED is not set +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27 --- a/arch/mips64/defconfig-ip27 Fri Jun 27 14:19:56 2003 +++ b/arch/mips64/defconfig-ip27 Fri Jun 27 14:19:56 2003 @@ -1,70 +1,133 @@ # # Automatically generated make config: don't edit # +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y # # Code maturity level options # -# CONFIG_EXPERIMENTAL is not set +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set # # Machine selection # +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set CONFIG_SGI_IP27=y # CONFIG_SGI_SN0_N_MODE is not set -CONFIG_DISCONTIGMEM=y -CONFIG_NUMA=y +# CONFIG_DISCONTIGMEM is not set +# CONFIG_NUMA is not set # CONFIG_MAPPED_KERNEL is not set # CONFIG_REPLICATE_KTEXT is not set # CONFIG_REPLICATE_EXHANDLERS is not set -CONFIG_SMP=y +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BOOT_ELF64=y +CONFIG_ARC=y +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_L1_CACHE_SHIFT=7 +# CONFIG_FB is not set CONFIG_ARC64=y -CONFIG_COHERENT_IO=y -CONFIG_MAPPED_PCI_IO=y -CONFIG_PCI=y +CONFIG_BOOT_ELF64=y CONFIG_QL_ISP_A64=y -CONFIG_L1_CACHE_SHIFT=7 -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set CONFIG_CPU_R10000=y +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_MIPS_INSANE_LARGE is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_MIPS_INSANE_LARGE is not set -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_NET=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +CONFIG_MMU=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_BINFMT_ELF=y -CONFIG_MIPS32_COMPAT=y -CONFIG_BINFMT_ELF32=y -# CONFIG_BINFMT_MISC is not set # -# Loadable module support +# Executable file formats # -# CONFIG_MODULES is not set -CONFIG_PCI_NAMES=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y # # Memory Technology Devices (MTD) @@ -77,83 +140,35 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK=y -CONFIG_RTNETLINK=y -CONFIG_NETLINK_DEV=y -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# SCSI device support # CONFIG_SCSI=y @@ -161,7 +176,6 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set @@ -170,8 +184,8 @@ # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -179,52 +193,116 @@ # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR_D700 is not set -# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -CONFIG_SCSI_QLOGIC_ISP=y +# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set # -# Network device support +# IEEE 1394 (FireWire) support (EXPERIMENTAL) # +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -235,39 +313,44 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set CONFIG_SGI_IOC3_ETH=y -# CONFIG_SUNLANCE is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNLANCE is not set # CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set # CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set -# CONFIG_PLIP is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set @@ -277,10 +360,11 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set # CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set # # Wan interfaces @@ -300,21 +384,69 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input Device Drivers # -# CONFIG_CD_NO_IDESCSI is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -324,32 +456,33 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_INPUT_GAMEPORT is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for gameports +# Mice # +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set # -# Input core support is needed for joysticks +# IPMI # -# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set # # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +CONFIG_SGI_IP27_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -360,6 +493,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -367,79 +502,92 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_JBD=y +CONFIG_JBD_DEBUG=y +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_CMS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set -# CONFIG_FREEVXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set +# CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -456,12 +604,15 @@ # CONFIG_SOLARIS_X86_PARTITION is not set # CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set -CONFIG_KCORE_ELF=y +# CONFIG_EFI_PARTITION is not set + +# +# Graphics support +# # # Sound @@ -472,113 +623,30 @@ # USB support # # CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# USB Controllers +# Bluetooth support # -# CONFIG_USB_UHCI is not set -# CONFIG_USB_UHCI_ALT is not set -# CONFIG_USB_OHCI is not set +# CONFIG_BT is not set # -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# - -# -# Input core support is needed for USB HID -# - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# -# CONFIG_USB_DABUSB is not set - -# -# USB Network adaptors -# -# CONFIG_USB_PLUSB is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support +# Kernel hacking # -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set # -# Miscellaneous USB drivers +# Security options # -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_ID75 is not set +# CONFIG_SECURITY is not set # -# Input core support +# Cryptographic options # -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set +# CONFIG_CRYPTO is not set # -# Kernel hacking +# Library routines # -CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/defconfig-ip32 b/arch/mips64/defconfig-ip32 --- a/arch/mips64/defconfig-ip32 Fri Jun 27 14:20:05 2003 +++ b/arch/mips64/defconfig-ip32 Fri Jun 27 14:20:05 2003 @@ -1,6 +1,9 @@ # # Automatically generated make config: don't edit # +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y # # Code maturity level options @@ -8,57 +11,118 @@ CONFIG_EXPERIMENTAL=y # +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# # Machine selection # +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set CONFIG_SGI_IP32=y +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_ARC=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_NONCOHERENT_IO=y +# CONFIG_CPU_LITTLE_ENDIAN is not set CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 CONFIG_ARC32=y -CONFIG_PC_KEYB=y -CONFIG_PCI=y +# CONFIG_FB is not set CONFIG_ARC_MEMORY=y -CONFIG_L1_CACHE_SHIFT=5 -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set +CONFIG_ARC_PROMLIB=y +CONFIG_BOARD_SCACHE=y # # CPU selection # +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set # CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set CONFIG_CPU_R5000=y +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set # CONFIG_CPU_NEVADA is not set # CONFIG_CPU_R8000 is not set # CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_R5000_CPU_SCACHE=y +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set # -# General setup +# Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_CPU_LITTLE_ENDIAN is not set -# CONFIG_MIPS_FPU_EMULATOR is not set -CONFIG_NET=y +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +CONFIG_MMU=y # CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -# CONFIG_PROM_CONSOLE is not set -CONFIG_BINFMT_ELF=y -CONFIG_MIPS32_COMPAT=y -CONFIG_BINFMT_ELF32=y -CONFIG_BINFMT_MISC=y # -# Loadable module support +# Executable file formats # -# CONFIG_MODULES is not set -CONFIG_PCI_NAMES=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y # # Memory Technology Devices (MTD) @@ -71,90 +135,35 @@ # CONFIG_PARPORT is not set # +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set - -# -# ATA/IDE/MFM/RLL support +# ATA/ATAPI/MFM/RLL support # # CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set # -# SCSI support +# SCSI device support # CONFIG_SCSI=y @@ -162,19 +171,17 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=2 CONFIG_CHR_DEV_SG=y # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -CONFIG_SCSI_DEBUG_QUEUES=y CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_REPORT_LUNS is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y @@ -182,63 +189,122 @@ # SCSI low-level drivers # # CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AACRAID is not set CONFIG_SCSI_AIC7XXX=y CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set # CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set # +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# # I2O device support # # CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set # -# Network device support +# Networking support # +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set CONFIG_NETDEVICES=y # @@ -249,58 +315,42 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_NET_SB1000 is not set +# CONFIG_ETHERTAP is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_SGI_O2MACE_ETH=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_TULIP=y -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=y -# CONFIG_EEPRO100_PM is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_LAN_SAA9730 is not set -# CONFIG_NET_POCKET is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_PPP is not set @@ -312,9 +362,8 @@ # CONFIG_NET_RADIO is not set # -# Token Ring devices +# Token Ring devices (depends on LLC=y) # -# CONFIG_TR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -337,21 +386,65 @@ # # ISDN subsystem # -# CONFIG_ISDN is not set +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set # -# Old CD-ROM drivers (not SCSI, not IDE) +# Input device support # -# CONFIG_CD_NO_IDESCSI is not set +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Character devices # # CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_UNIX98_PTY_COUNT=256 @@ -361,31 +454,32 @@ # CONFIG_I2C is not set # -# Mice +# I2C Hardware Sensors Mainboard support # -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set # -# Joysticks +# I2C Hardware Sensors Chip support # -# CONFIG_JOYSTICK is not set +# CONFIG_I2C_SENSOR is not set # -# Input core support is needed for joysticks +# Mice # +# CONFIG_BUSMOUSE is not set # CONFIG_QIC02_TAPE is not set # +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -396,6 +490,8 @@ # CONFIG_FTAPE is not set # CONFIG_AGP is not set # CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set # # Multimedia devices @@ -403,73 +499,84 @@ # CONFIG_VIDEO_DEV is not set # +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +CONFIG_TMPFS=y +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -# CONFIG_RAMFS is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set -# CONFIG_SYSV_FS_WRITE is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set # # Network File Systems # -# CONFIG_CODA_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y +# CONFIG_NFS_V4 is not set # CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y +CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set # # Partition Types @@ -481,12 +588,16 @@ # CONFIG_ATARI_PARTITION is not set # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set -CONFIG_KCORE_ELF=y +# CONFIG_EFI_PARTITION is not set + +# +# Graphics support +# # # Sound @@ -497,16 +608,30 @@ # USB support # # CONFIG_USB is not set +# CONFIG_USB_GADGET is not set # -# Input core support +# Bluetooth support # -# CONFIG_INPUT is not set +# CONFIG_BT is not set # # Kernel hacking # CONFIG_CROSSCOMPILE=y -# CONFIG_REMOTE_DEBUG is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_MIPS_UNCACHED=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/defconfig-malta b/arch/mips64/defconfig-malta --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/defconfig-malta Fri Jun 27 14:20:06 2003 @@ -0,0 +1,558 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +CONFIG_MIPS_MALTA=y +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_I8259=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_BOARDS_GEN=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +CONFIG_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set +CONFIG_HAVE_STD_PC_SERIAL_PORT=y + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +CONFIG_CPU_R4X00=y +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_PCI is not set +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_REPORT_LUNS is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_EATA_PIO is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# I2O device support +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_PACKET is not set +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +CONFIG_DEVPTS_FS_XATTR=y +CONFIG_DEVPTS_FS_SECURITY=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_EFS_FS=y +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/defconfig-sb1250-swarm b/arch/mips64/defconfig-sb1250-swarm --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/defconfig-sb1250-swarm Fri Jun 27 14:20:06 2003 @@ -0,0 +1,611 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=15 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +CONFIG_SIBYTE_SB1xxx_SOC=y +CONFIG_SIBYTE_SB1250=y +# CONFIG_SIMULATION is not set +CONFIG_SIBYTE_CFE=y +# CONFIG_SIBYTE_CFE_CONSOLE is not set +# CONFIG_SIBYTE_BUS_WATCHER is not set +# CONFIG_SIBYTE_SB1250_PROF is not set +# CONFIG_SIBYTE_TBPROF is not set +CONFIG_SIBYTE_SWARM=y +CONFIG_SIBYTE_BOARD=y +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_DUMMY_KEYB=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +CONFIG_CPU_SB1=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_VTAG_ICACHE=y +CONFIG_CPU_SB1_PASS_1=y +# CONFIG_CPU_SB1_PASS_2 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_SB1_PASS_1_WORKAROUNDS=y +CONFIG_SB1_CACHE_ERROR=y +CONFIG_SB1_CERR_IGNORE_RECOVERABLE=y +# CONFIG_SB1_CERR_SPIN is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y +CONFIG_PCI_NAMES=y +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=9220 +# CONFIG_BLK_DEV_INITRD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=y +# CONFIG_NETFILTER is not set +CONFIG_UNIX=y +CONFIG_NET_KEY=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_IPV6 is not set +# CONFIG_XFRM_USER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +CONFIG_NET_SB1250_MAC=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PCIPS2 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_DIGI is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINK is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_N_HDLC is not set +# CONFIG_RISCOM8 is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_RIO is not set +# CONFIG_STALDRV is not set +CONFIG_SIBYTE_SB1250_DUART=y +CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y +CONFIG_SERIAL_CONSOLE=y + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_SERPENT=y +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_TEST is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff -Nru a/arch/mips64/defconfig-sead b/arch/mips64/defconfig-sead --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/defconfig-sead Fri Jun 27 14:20:06 2003 @@ -0,0 +1,391 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +# CONFIG_MIPS32 is not set +CONFIG_MIPS64=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# General setup +# +CONFIG_SWAP=y +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_EMBEDDED is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_LASAT is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +CONFIG_MIPS_SEAD=y +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TANBAC_TB0226 is not set +# CONFIG_TANBAC_TB0229 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_NONCOHERENT_IO=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_BOARDS_GEN=y +CONFIG_L1_CACHE_SHIFT=5 +# CONFIG_FB is not set + +# +# CPU selection +# +# CONFIG_CPU_MIPS32 is not set +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +CONFIG_CPU_R4X00=y +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_LLDSCD=y +CONFIG_CPU_HAS_SYNC=y +# CONFIG_PREEMPT is not set +CONFIG_KALLSYMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_MMU=y +# CONFIG_HOTPLUG is not set + +# +# Executable file formats +# +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=18432 +CONFIG_BLK_DEV_INITRD=y + +# +# MIPS initrd options +# +# CONFIG_EMBEDDED_RAMDISK is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# I2O device support +# + +# +# Networking support +# +# CONFIG_NET is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Graphics support +# + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_GADGET is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_DEBUG_KERNEL is not set + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC32 is not set diff -Nru a/arch/mips64/kernel/Makefile b/arch/mips64/kernel/Makefile --- a/arch/mips64/kernel/Makefile Fri Jun 27 14:19:55 2003 +++ b/arch/mips64/kernel/Makefile Fri Jun 27 14:19:55 2003 @@ -2,18 +2,29 @@ # Makefile for the Linux/MIPS kernel. # -extra-y := head.o init_task.o +extra-y := head.o init_task.o -obj-y := branch.o entry.o proc.o process.o ptrace.o r4k_cache.o r4k_fpu.o \ - r4k_genex.o r4k_switch.o r4k_tlb.o r4k_tlb_debug.o r4k_tlb_glue.o \ - scall_64.o semaphore.o setup.o signal.o softfp.o syscall.o \ - traps.o unaligned.o +obj-y := branch.o cpu-probe.o entry.o irq.o proc.o process.o \ + ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \ + reset.o scall_64.o semaphore.o setup.o signal.o syscall.o \ + time.o traps.o unaligned.o + +obj-$(CONFIG_I8259) += i8259.o +obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_MODULES) += mips64_ksyms.o -obj-$(CONFIG_MIPS32_COMPAT) += linux32.o scall_o32.o signal32.o ioctl32.o -obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o +obj-$(CONFIG_MIPS32_COMPAT) += linux32.o signal32.o ioctl32.o +obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall_n32.o +obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall_o32.o obj-$(CONFIG_SMP) += smp.o -AFLAGS_r4k_genex.o := -P -AFLAGS_r4k_tlb_glue.o := -P +ifndef CONFIG_MAPPED_PCI_IO +obj-y += pci-dma.o +endif + +obj-$(CONFIG_MODULES) += module.o + +CFLAGS_cpu-probe.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) +AFLAGS_r4k_genex.o = -P + EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips64/kernel/binfmt_elf32.c b/arch/mips64/kernel/binfmt_elf32.c --- a/arch/mips64/kernel/binfmt_elf32.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,99 +0,0 @@ -/* - * Support for 32-bit Linux/MIPS ELF binaries. - * - * Copyright (C) 1999, 2001 Ralf Baechle - * Copyright (C) 1999, 2001 Silicon Graphics, Inc. - * - * Heavily inspired by the 32-bit Sparc compat code which is - * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) - */ - -#define ELF_ARCH EM_MIPS -#define ELF_CLASS ELFCLASS32 -#ifdef __MIPSEB__ -#define ELF_DATA ELFDATA2MSB; -#else /* __MIPSEL__ */ -#define ELF_DATA ELFDATA2LSB; -#endif - -/* ELF register definitions */ -#define ELF_NGREG 45 -#define ELF_NFPREG 33 - -typedef unsigned int elf_greg_t; -typedef elf_greg_t elf_gregset_t[ELF_NGREG]; - -typedef double elf_fpreg_t; -typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; - -#define elf_check_arch(x) \ - ((x)->e_machine == EM_MIPS) - -#define TASK32_SIZE 0x80000000UL -#undef ELF_ET_DYN_BASE -#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) - -#include <asm/processor.h> -#include <linux/module.h> -#include <linux/config.h> -#include <linux/elfcore.h> - -struct timeval32 -{ - unsigned int tv_sec, tv_usec; -}; - -#define elf_prstatus elf_prstatus32 -struct elf_prstatus32 -{ - struct elf_siginfo pr_info; /* Info associated with signal */ - short pr_cursig; /* Current signal */ - unsigned int pr_sigpend; /* Set of pending signals */ - unsigned int pr_sighold; /* Set of held signals */ - pid_t pr_pid; - pid_t pr_ppid; - pid_t pr_pgrp; - pid_t pr_sid; - struct timeval32 pr_utime; /* User time */ - struct timeval32 pr_stime; /* System time */ - struct timeval32 pr_cutime; /* Cumulative user time */ - struct timeval32 pr_cstime; /* Cumulative system time */ - elf_gregset_t pr_reg; /* GP registers */ - int pr_fpvalid; /* True if math co-processor being used. */ -}; - -#define elf_prpsinfo elf_prpsinfo32 -struct elf_prpsinfo32 -{ - char pr_state; /* numeric process state */ - char pr_sname; /* char for pr_state */ - char pr_zomb; /* zombie */ - char pr_nice; /* nice val */ - unsigned int pr_flag; /* flags */ - u16 pr_uid; - u16 pr_gid; - pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; - /* Lots missing */ - char pr_fname[16]; /* filename of executable */ - char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ -}; - -#define elf_addr_t u32 -#define init_elf_binfmt init_elf32_binfmt -#undef CONFIG_BINFMT_ELF -#ifdef CONFIG_BINFMT_ELF32 -#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 -#endif -#undef CONFIG_BINFMT_ELF_MODULE -#ifdef CONFIG_BINFMT_ELF32_MODULE -#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE -#endif - -MODULE_DESCRIPTION("Binary format loader for compatibility with 32bit Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@oss.sgi.com)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - -#include "../../../fs/binfmt_elf.c" diff -Nru a/arch/mips64/kernel/binfmt_elfn32.c b/arch/mips64/kernel/binfmt_elfn32.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/binfmt_elfn32.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,115 @@ +/* + * Support for n32 Linux/MIPS ELF binaries. + * + * Copyright (C) 1999, 2001 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * + * Heavily inspired by the 32-bit Sparc compat code which is + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#define ELF_ARCH EM_MIPS +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#else /* __MIPSEL__ */ +#define ELF_DATA ELFDATA2LSB; +#endif + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned long elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(hdr) \ +({ \ + int __res = 1; \ + struct elfhdr *__h = (hdr); \ + \ + if (__h->e_machine != EM_MIPS) \ + __res = 0; \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \ + ((__h->e_flags & EF_MIPS_ABI) != 0)) \ + __res = 0; \ + \ + __res; \ +}) + +#define TASK32_SIZE 0x7fff8000UL +#undef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + +#include <asm/processor.h> +#include <linux/module.h> +#include <linux/config.h> +#include <linux/elfcore.h> +#include <linux/compat.h> + +#define elf_prstatus elf_prstatus32 +struct elf_prstatus32 +{ + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + unsigned int pr_sigpend; /* Set of pending signals */ + unsigned int pr_sighold; /* Set of held signals */ + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct compat_timeval pr_utime; /* User time */ + struct compat_timeval pr_stime; /* System time */ + struct compat_timeval pr_cutime;/* Cumulative user time */ + struct compat_timeval pr_cstime;/* Cumulative system time */ + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define elf_prpsinfo elf_prpsinfo32 +struct elf_prpsinfo32 +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned int pr_flag; /* flags */ + __kernel_uid_t pr_uid; + __kernel_gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#define elf_addr_t u32 +#define elf_caddr_t u32 +#define init_elf_binfmt init_elfn32_binfmt + +#define ELF_CORE_EFLAGS EF_MIPS_ABI2 + +#undef CONFIG_BINFMT_ELF +#ifdef CONFIG_BINFMT_ELF32 +#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 +#endif +#undef CONFIG_BINFMT_ELF_MODULE +#ifdef CONFIG_BINFMT_ELF32_MODULE +#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE +#endif + +MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries"); +MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); + +#undef MODULE_DESCRIPTION +#undef MODULE_AUTHOR + +#include "../../../fs/binfmt_elf.c" diff -Nru a/arch/mips64/kernel/binfmt_elfo32.c b/arch/mips64/kernel/binfmt_elfo32.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/binfmt_elfo32.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,136 @@ +/* + * Support for o32 Linux/MIPS ELF binaries. + * + * Copyright (C) 1999, 2001 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * + * Heavily inspired by the 32-bit Sparc compat code which is + * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com) + * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz) + */ + +#define ELF_ARCH EM_MIPS +#define ELF_CLASS ELFCLASS32 +#ifdef __MIPSEB__ +#define ELF_DATA ELFDATA2MSB; +#else /* __MIPSEL__ */ +#define ELF_DATA ELFDATA2LSB; +#endif + +/* ELF register definitions */ +#define ELF_NGREG 45 +#define ELF_NFPREG 33 + +typedef unsigned int elf_greg_t; +typedef elf_greg_t elf_gregset_t[ELF_NGREG]; + +typedef double elf_fpreg_t; +typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(hdr) \ +({ \ + int __res = 1; \ + struct elfhdr *__h = (hdr); \ + \ + if (__h->e_machine != EM_MIPS) \ + __res = 0; \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ + ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ + __res = 0; \ + \ + __res; \ +}) + +#define TASK32_SIZE 0x7fff8000UL +#undef ELF_ET_DYN_BASE +#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) + +#include <asm/processor.h> +#include <linux/module.h> +#include <linux/config.h> +#include <linux/elfcore.h> +#include <linux/compat.h> + +#define elf_prstatus elf_prstatus32 +struct elf_prstatus32 +{ + struct elf_siginfo pr_info; /* Info associated with signal */ + short pr_cursig; /* Current signal */ + unsigned int pr_sigpend; /* Set of pending signals */ + unsigned int pr_sighold; /* Set of held signals */ + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct compat_timeval pr_utime; /* User time */ + struct compat_timeval pr_stime; /* System time */ + struct compat_timeval pr_cutime;/* Cumulative user time */ + struct compat_timeval pr_cstime;/* Cumulative system time */ + elf_gregset_t pr_reg; /* GP registers */ + int pr_fpvalid; /* True if math co-processor being used. */ +}; + +#define elf_prpsinfo elf_prpsinfo32 +struct elf_prpsinfo32 +{ + char pr_state; /* numeric process state */ + char pr_sname; /* char for pr_state */ + char pr_zomb; /* zombie */ + char pr_nice; /* nice val */ + unsigned int pr_flag; /* flags */ + __kernel_uid_t pr_uid; + __kernel_gid_t pr_gid; + pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; + /* Lots missing */ + char pr_fname[16]; /* filename of executable */ + char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ +}; + +#define elf_addr_t u32 +#define elf_caddr_t u32 +#define init_elf_binfmt init_elf32_binfmt + + +#undef ELF_CORE_COPY_REGS +#define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs); + +void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs) +{ + int i; + + memset(_dest, 0, sizeof(elf_gregset_t)); + + /* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */ + for (i=6; i<38; i++) + _dest[i] = (elf_greg_t) _regs->regs[i-6]; + _dest[i++] = (elf_greg_t) _regs->lo; + _dest[i++] = (elf_greg_t) _regs->hi; + _dest[i++] = (elf_greg_t) _regs->cp0_epc; + _dest[i++] = (elf_greg_t) _regs->cp0_badvaddr; + _dest[i++] = (elf_greg_t) _regs->cp0_status; + _dest[i++] = (elf_greg_t) _regs->cp0_cause; +} + +#undef CONFIG_BINFMT_ELF +#ifdef CONFIG_BINFMT_ELF32 +#define CONFIG_BINFMT_ELF CONFIG_BINFMT_ELF32 +#endif +#undef CONFIG_BINFMT_ELF_MODULE +#ifdef CONFIG_BINFMT_ELF32_MODULE +#define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE +#endif + +MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); +MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); + +#undef MODULE_DESCRIPTION +#undef MODULE_AUTHOR + +#include "../../../fs/binfmt_elf.c" diff -Nru a/arch/mips64/kernel/branch.c b/arch/mips64/kernel/branch.c --- a/arch/mips64/kernel/branch.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/kernel/branch.c Fri Jun 27 14:19:54 2003 @@ -11,6 +11,7 @@ #include <linux/sched.h> #include <linux/signal.h> #include <asm/branch.h> +#include <asm/cpu.h> #include <asm/inst.h> #include <asm/ptrace.h> #include <asm/uaccess.h> @@ -163,7 +164,10 @@ * And now the FPA/cp1 branch instructions. */ case cop1_op: - asm ("cfc1\t%0,$31":"=r" (fcr31)); + if (!cpu_has_fpu) + fcr31 = current->thread.fpu.soft.sr; + else + asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -Nru a/arch/mips64/kernel/cpu-probe.c b/arch/mips64/kernel/cpu-probe.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/cpu-probe.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,746 @@ +/* + * arch/mips64/kernel/cpu-probe.c + * + * Processor capabilities determination functions. + * + * Copyright (C) xxxx the Anonymous + * Copyright (C) 2003 Maciej W. Rozycki + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/ptrace.h> +#include <linux/stddef.h> + +#include <asm/bugs.h> +#include <asm/cpu.h> +#include <asm/fpu.h> +#include <asm/mipsregs.h> +#include <asm/system.h> + +/* + * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, + * the implementation of the "wait" feature differs between CPU families. This + * points to the function that implements CPU specific wait. + * The wait instruction stops the pipeline and reduces the power consumption of + * the CPU very much. + */ +void (*cpu_wait)(void) = NULL; + +static void r3081_wait(void) +{ + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | R30XX_CONF_HALT); +} + +static void r39xx_wait(void) +{ + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); +} + +static void r4k_wait(void) +{ + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void au1k_wait(void) +{ +#ifdef CONFIG_PM + /* using the wait instruction makes CP0 counter unusable */ + __asm__(".set\tmips3\n\t" + "wait\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set\tmips0"); +#else + __asm__("nop\n\t" + "nop"); +#endif +} + +static inline void check_wait(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("Checking for 'wait' instruction... "); + switch (c->cputype) { + case CPU_R3081: + case CPU_R3081E: + cpu_wait = r3081_wait; + printk(" available.\n"); + break; + case CPU_TX3927: + cpu_wait = r39xx_wait; + printk(" available.\n"); + break; + case CPU_R4200: +/* case CPU_R4300: */ + case CPU_R4600: + case CPU_R4640: + case CPU_R4650: + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + case CPU_RM7000: + case CPU_TX49XX: + case CPU_4KC: + case CPU_4KEC: + case CPU_4KSC: + case CPU_5KC: +/* case CPU_20KC:*/ + cpu_wait = r4k_wait; + printk(" available.\n"); + break; + case CPU_AU1000: + case CPU_AU1100: + case CPU_AU1500: + cpu_wait = au1k_wait; + printk(" available.\n"); + break; + default: + printk(" unavailable.\n"); + break; + } +} + +static inline void check_mult_sh(void) +{ + unsigned long flags; + int m1, m2; + long p, s, v; + + printk("Checking for the multiply/shift bug... "); + + local_irq_save(flags); + /* + * The following code leads to a wrong result of dsll32 when + * executed on R4000 rev. 2.2 or 3.0. + * + * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and + * 3.0" by MIPS Technologies, Inc., errata #16 and #28 for + * details. I got no permission to duplicate them here, + * sigh... --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" + "mult %1, %2\n\t" + "dsll32 %0, %3, %4\n\t" + "mflo $0\n\t" + ".set pop" + : "=r" (v) + : "r" (5), "r" (8), "r" (5), "I" (0) + : "hi", "lo", "accum"); + local_irq_restore(flags); + + if (v == 5L << 32) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + local_irq_save(flags); + /* + * We want the multiply and the shift to be isolated from the + * rest of the code to disable gcc optimizations. Hence the + * asm statements that execute nothing, but make gcc not know + * what the values of m1, m2 and s are and what v and p are + * used for. + * + * We have to use single integers for m1 and m2 and a double + * one for p to be sure the mulsidi3 gcc's RTL multiplication + * instruction has the workaround applied. Older versions of + * gcc have correct mulsi3, but other multiplication variants + * lack the workaround. + */ + asm volatile( + "" + : "=r" (m1), "=r" (m2), "=r" (s) + : "0" (5), "1" (8), "2" (5)); + p = m1 * m2; + v = s << 32; + asm volatile( + "" + : "=r" (v) + : "0" (v), "r" (p)); + local_irq_restore(flags); + + if (v == 5L << 32) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#ifndef CONFIG_CPU_R4000 + "Configure for R4000 to enable the workaround." +#else + "Please report to <linux-mips@linux-mips.org>." +#endif + ); +} + +static volatile int daddi_ov __initdata = 0; + +asmlinkage void __init do_daddi_ov(struct pt_regs *regs) +{ + daddi_ov = 1; + regs->cp0_epc += 4; +} + +static inline void check_daddi(void) +{ + extern asmlinkage void handle_daddi_ov(void); + unsigned long flags; + void *handler; + long v; + + printk("Checking for the daddi bug... "); + + local_irq_save(flags); + handler = set_except_vector(12, handle_daddi_ov); + /* + * The following code fails to trigger an overflow exception + * when executed on R4000 rev. 2.2 or 3.0. + * + * See "MIPS R4000PC/SC Errata, Processor Revision 2.2 and + * 3.0" by MIPS Technologies, Inc., erratum #23 for details. + * I got no permission to duplicate it here, sigh... --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" +#ifdef HAVE_AS_SET_DADDI + ".set daddi\n\t" +#endif + "daddi %0, %1, %2\n\t" + ".set pop" + : "=r" (v) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + set_except_vector(12, handler); + local_irq_restore(flags); + + if (daddi_ov) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + local_irq_save(flags); + handler = set_except_vector(12, handle_daddi_ov); + asm volatile( + "daddi %0, %1, %2" + : "=r" (v) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + set_except_vector(12, handler); + local_irq_restore(flags); + + if (daddi_ov) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400) + "Configure for R4000 or R4400 to enable the workaround." +#else + "Please report to <linux-mips@linux-mips.org>." +#endif + ); +} + +static inline void check_daddiu(void) +{ + long v, w; + + printk("Checking for the daddiu bug... "); + + /* + * The following code leads to a wrong result of daddiu when + * executed on R4400 rev. 1.0. + * + * See "MIPS R4400PC/SC Errata, Processor Revision 1.0" by + * MIPS Technologies, Inc., erratum #7 for details. + * + * According to "MIPS R4000PC/SC Errata, Processor Revision + * 2.2 and 3.0" by MIPS Technologies, Inc., erratum #41 this + * problem affects R4000 rev. 2.2 and 3.0, too. Testing + * failed to trigger it so far. + * + * I got no permission to duplicate the errata here, sigh... + * --macro + */ + asm volatile( + ".set push\n\t" + ".set noat\n\t" + ".set noreorder\n\t" + ".set nomacro\n\t" +#ifdef HAVE_AS_SET_DADDI + ".set daddi\n\t" +#endif + "daddiu %0, %2, %3\n\t" + "addiu %1, $0, %3\n\t" + "daddu %1, %2\n\t" + ".set pop" + : "=&r" (v), "=&r" (w) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + + if (v == w) { + printk("no.\n"); + return; + } + + printk("yes, workaround... "); + + asm volatile( + "daddiu %0, %2, %3\n\t" + "addiu %1, $0, %3\n\t" + "daddu %1, %2" + : "=&r" (v), "=&r" (w) + : "r" (0x7fffffffffffedcd), "I" (0x1234)); + + if (v == w) { + printk("yes.\n"); + return; + } + + printk("no.\n"); + panic("Reliable operation impossible!\n" +#if !defined(CONFIG_CPU_R4000) && !defined(CONFIG_CPU_R4400) + "Configure for R4000 or R4400 to enable the workaround." +#else + "Please report to <linux-mips@linux-mips.org>." +#endif + ); +} + +void __init check_bugs(void) +{ + check_wait(); + check_mult_sh(); + check_daddi(); + check_daddiu(); +} + +/* + * Probe whether cpu has config register by trying to play with + * alternate cache bit and see whether it matters. + * It's used by cpu_probe to distinguish between R3000A and R3081. + */ +static inline int cpu_has_confreg(void) +{ +#ifdef CONFIG_CPU_R3000 + extern unsigned long r3k_cache_size(unsigned long); + unsigned long size1, size2; + unsigned long cfg = read_c0_conf(); + + size1 = r3k_cache_size(ST0_ISC); + write_c0_conf(cfg ^ R30XX_CONF_AC); + size2 = r3k_cache_size(ST0_ISC); + write_c0_conf(cfg); + return size1 != size2; +#else + return 0; +#endif +} + +/* + * Get the FPU Implementation/Revision. + */ +static inline unsigned long cpu_get_fpu_id(void) +{ + unsigned long tmp, fpu_id; + + tmp = read_c0_status(); + __enable_fpu(); + fpu_id = read_32bit_cp1_register(CP1_REVISION); + write_c0_status(tmp); + return fpu_id; +} + +/* + * Check the CPU has an FPU the official way. + */ +static inline int __cpu_has_fpu(void) +{ + return ((cpu_get_fpu_id() & 0xff00) != FPIR_IMP_NONE); +} + +#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4KTLB \ + | MIPS_CPU_COUNTER | MIPS_CPU_CACHE_CDEX) + +__init void cpu_probe(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long config0 = read_c0_config(); + unsigned long config1; + + c->processor_id = PRID_IMP_UNKNOWN; + c->fpu_id = FPIR_IMP_NONE; + c->cputype = CPU_UNKNOWN; + + if (config0 & (1 << 31)) { + /* MIPS32 or MIPS64 compliant CPU. Read Config 1 register. */ + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_LLSC; + config1 = read_c0_config1(); + if (config1 & (1 << 3)) + c->options |= MIPS_CPU_WATCH; + if (config1 & (1 << 2)) + c->options |= MIPS_CPU_MIPS16; + if (config1 & (1 << 1)) + c->options |= MIPS_CPU_EJTAG; + if (config1 & 1) { + c->options |= MIPS_CPU_FPU; + c->options |= MIPS_CPU_32FPR; + } + c->scache.flags = MIPS_CACHE_NOT_PRESENT; + + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + + c->processor_id = read_c0_prid(); + switch (c->processor_id & 0xff0000) { + case PRID_COMP_LEGACY: + switch (c->processor_id & 0xff00) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_IMP_R3000: + if ((c->processor_id & 0xff) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else + c->cputype = CPU_R3000A; + else + c->cputype = CPU_R3000; + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX | + MIPS_CPU_LLSC; + if (__cpu_has_fpu()) + c->options |= MIPS_CPU_FPU; + c->tlbsize = 64; + break; + case PRID_IMP_R4000: + if ((c->processor_id & 0xff) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_VCE | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_VR41XX: + switch (c->processor_id & 0xf0) { +#ifndef CONFIG_VR4181 + case PRID_REV_VR4111: + c->cputype = CPU_VR4111; + break; +#else + case PRID_REV_VR4181: + c->cputype = CPU_VR4181; + break; +#endif + case PRID_REV_VR4121: + c->cputype = CPU_VR4121; + break; + case PRID_REV_VR4122: + if ((c->processor_id & 0xf) < 0x3) + c->cputype = CPU_VR4122; + else + c->cputype = CPU_VR4181A; + break; + case PRID_REV_VR4131: + c->cputype = CPU_VR4131; + break; + default: + printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n"); + c->cputype = CPU_VR41XX; + break; + } + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS; + c->tlbsize = 32; + break; + case PRID_IMP_R4300: + c->cputype = CPU_R4300; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R4600: + c->cputype = CPU_R4600; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #if 0 + case PRID_IMP_R4650: + /* + * This processor doesn't have an MMU, so it's not + * "real easy" to run Linux on it. It is left purely + * for documentation. Commented out because it shares + * it's c0_prid id number with the TX3900. + */ + c->cputype = CPU_R4650; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + #endif + case PRID_IMP_TX39: + c->isa_level = MIPS_CPU_ISA_I; + c->options = MIPS_CPU_TLB; + + if ((c->processor_id & 0xf0) == + (PRID_REV_TX3927 & 0xf0)) { + c->cputype = CPU_TX3927; + c->tlbsize = 64; + } else { + switch (c->processor_id & 0xff) { + case PRID_REV_TX3912: + c->cputype = CPU_TX3912; + c->tlbsize = 32; + break; + case PRID_REV_TX3922: + c->cputype = CPU_TX3922; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + } + break; + case PRID_IMP_R4700: + c->cputype = CPU_R4700; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_TX49: + c->cputype = CPU_TX49XX; + c->isa_level = MIPS_CPU_ISA_III; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5000: + c->cputype = CPU_R5000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5432: + c->cputype = CPU_R5432; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R5500: + c->cputype = CPU_R5500; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_NEVADA: + c->cputype = CPU_NEVADA; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_DIVEC | MIPS_CPU_LLSC; + c->tlbsize = 48; + break; + case PRID_IMP_R6000: + c->cputype = CPU_R6000; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_R6000A: + c->cputype = CPU_R6000A; + c->isa_level = MIPS_CPU_ISA_II; + c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | + MIPS_CPU_LLSC; + c->tlbsize = 32; + break; + case PRID_IMP_RM7000: + c->cputype = CPU_RM7000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + /* + * Undocumented RM7000: Bit 29 in the info register of + * the RM7000 v2.0 indicates if the TLB has 48 or 64 + * entries. + * + * 29 1 => 64 entry JTLB + * 0 => 48 entry JTLB + */ + c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; + break; + case PRID_IMP_R8000: + c->cputype = CPU_R8000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_LLSC; + c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ + break; + case PRID_IMP_R10000: + c->cputype = CPU_R10000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + case PRID_IMP_R12000: + c->cputype = CPU_R12000; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_COUNTER | MIPS_CPU_WATCH | + MIPS_CPU_LLSC; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + case PRID_COMP_MIPS: + switch (c->processor_id & 0xff00) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KEC: + c->cputype = CPU_4KEC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_4KSC: + c->cputype = CPU_4KSC; + c->isa_level = MIPS_CPU_ISA_M32; + break; + case PRID_IMP_5KC: + c->cputype = CPU_5KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + case PRID_IMP_20KC: + c->cputype = CPU_20KC; + c->isa_level = MIPS_CPU_ISA_M64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + case PRID_COMP_ALCHEMY: + switch (c->processor_id & 0xff00) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: + switch ((c->processor_id >> 24) & 0xff) { + case 0: + c->cputype = CPU_AU1000; + break; + case 1: + c->cputype = CPU_AU1500; + break; + case 2: + c->cputype = CPU_AU1100; + break; + default: + panic("Unknown Au Core!"); + break; + } + c->isa_level = MIPS_CPU_ISA_M32; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + case PRID_COMP_SIBYTE: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_COUNTER | MIPS_CPU_DIVEC | + MIPS_CPU_MCHECK | MIPS_CPU_EJTAG | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; +#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS + /* FPU in pass1 is known to have issues. */ + c->options |= MIPS_CPU_FPU | MIPS_CPU_32FPR; +#endif + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + + case PRID_COMP_SANDCRAFT: + switch (c->processor_id & 0xff00) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; + c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | + MIPS_CPU_4KTLB | MIPS_CPU_FPU | + MIPS_CPU_COUNTER | MIPS_CPU_MCHECK; + c->scache.ways = 8; + c->tlbsize = 64; + break; + default: + c->cputype = CPU_UNKNOWN; + break; + } + break; + default: + c->cputype = CPU_UNKNOWN; + c->tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + if (c->options & MIPS_CPU_FPU) + c->fpu_id = cpu_get_fpu_id(); +} + +__init void cpu_report(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + + printk("CPU revision is: %08x\n", c->processor_id); + if (c->options & MIPS_CPU_FPU) + printk("FPU revision is: %08x\n", c->fpu_id); +} diff -Nru a/arch/mips64/kernel/entry.S b/arch/mips64/kernel/entry.S --- a/arch/mips64/kernel/entry.S Fri Jun 27 14:19:53 2003 +++ b/arch/mips64/kernel/entry.S Fri Jun 27 14:19:53 2003 @@ -9,67 +9,88 @@ * Copyright (C) 1999, 2000 Silicon Graphics * Copyright (C) 2001 MIPS Technologies, Inc. */ -#include <linux/config.h> - #include <asm/asm.h> #include <asm/regdef.h> #include <asm/mipsregs.h> #include <asm/stackframe.h> - -/* This duplicates the definition from <linux/sched.h> */ -#error #define PT_TRACESYS 0x00000002 /* tracing system calls */ +#include <asm/thread_info.h> #define KU_USER 0x10 .text - .align 4 -FEXPORT(ret_from_fork) - move a0, v0 # prev - jal schedule_tail -#error lw t0, TASK_PTRACE($28) # syscall tracing enabled? -#error andi t0, PT_TRACESYS - bnez t0, tracesys_exit - j ret_from_sys_call - -tracesys_exit: - jal syscall_trace - b ret_from_sys_call - -EXPORT(ret_from_irq) -EXPORT(ret_from_exception) - lw t0, PT_STATUS(sp) # returning to kernel mode? + .align 5 +FEXPORT(ret_from_irq) +FEXPORT(ret_from_exception) + ld t0, PT_STATUS(sp) # returning to kernel mode? andi t0, t0, KU_USER - bnez t0, ret_from_sys_call + beqz t0, restore_all + +FEXPORT(resume_userspace) + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) + andi a2, _TIF_WORK_MASK # current->work (ignoring + # syscall_trace + bnez a2, work_pending j restore_all -reschedule: jal schedule +FEXPORT(ret_from_fork) + jal schedule_tail -FEXPORT(ret_from_sys_call) - mfc0 t0, CP0_STATUS # need_resched and signals atomic test - ori t0, t0, 1 - xori t0, t0, 1 +FEXPORT(syscall_exit) + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP -#error ld v0, TASK_NEED_RESCHED($28) -#error lw v1, TASK_SIGPENDING($28) - bnez v0, reschedule - bnez v1, signal_return + LONG_L a2, TI_FLAGS($28) # current->work + bnez a2, syscall_exit_work -restore_all: .set noat +restore_all: + .set noat RESTORE_ALL eret .set at -signal_return: .type signal_return, @function +work_pending: + bltz a2, work_notifysig # current->work.need_resched + # test high 8 bits +work_resched: + jal schedule + + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) # This also converts into + # a union of four chars + andi a2, _TIF_WORK_MASK # is there any work to be done + # other than syscall tracing? + beqz a2, restore_all + andi t0, a2, _TIF_NEED_RESCHED + bnez t0, work_notifysig + +work_notifysig: # deal with pending signals and + # notify-resume requests + move a0, sp + li a1, 0 + jal do_notify_resume # a2 already loaded + j restore_all - mfc0 t0, CP0_STATUS +FEXPORT(syscall_exit_work) + LONG_L t0, TI_FLAGS($28) # current->work.syscall_trace + bgez t0, work_pending + mfc0 t0, CP0_STATUS # sti ori t0, t0, 1 mtc0 t0, CP0_STATUS - - move a0, zero - move a1, sp - jal do_signal - b restore_all + jal do_syscall_trace + b resume_userspace /* * Common spurious interrupt handler. @@ -81,9 +102,10 @@ * Someone tried to fool us by sending an interrupt but we * couldn't find a cause for it. */ - lui t1,%hi(spurious_count) - lw t0,%lo(spurious_count)(t1) - addiu t0,1 - sw t0,%lo(spurious_count)(t1) + lui t1, %hi(irq_err_count) +1: ll t0, %lo(irq_err_count)(t1) + addiu t0, 1 + sc t0, %lo(irq_err_count)(t1) + beqz t0, 1b j ret_from_irq END(spurious_interrupt) diff -Nru a/arch/mips64/kernel/head.S b/arch/mips64/kernel/head.S --- a/arch/mips64/kernel/head.S Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/kernel/head.S Fri Jun 27 14:19:54 2003 @@ -10,7 +10,6 @@ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ -#define __ASSEMBLY__ #include <linux/config.h> #include <linux/init.h> #include <asm/asm.h> @@ -27,7 +26,7 @@ #if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL) /* We get launched at a XKPHYS address but the kernel is linked to run at a KSEG0 address, so jump there. */ - la t0, \@f + PTR_LA t0, \@f jr t0 \@: #endif @@ -35,13 +34,13 @@ #ifdef CONFIG_SGI_IP27 /* - * outputs the local nasid into t1. + * outputs the local nasid into res. IP27 stuff. */ - .macro GET_NASID_ASM - dli t1, LOCAL_HUB_ADDR(NI_STATUS_REV_ID) - ld t1, (t1) - and t1, NSRI_NODEID_MASK - dsrl t1, NSRI_NODEID_SHFT + .macro GET_NASID_ASM res + dli \res, LOCAL_HUB_ADDR(NI_STATUS_REV_ID) + ld \res, (\res) + and \res, NSRI_NODEID_MASK + dsrl \res, NSRI_NODEID_SHFT .endm #endif /* CONFIG_SGI_IP27 */ @@ -97,7 +96,7 @@ xori sp, 0xf #ifdef CONFIG_SGI_IP27 - GET_NASID_ASM + GET_NASID_ASM t1 move t2, t1 # text and data are here MAPPED_KERNEL_SETUP_TLB #endif /* IP27 */ @@ -106,39 +105,39 @@ CLI # disable interrupts - mfc0 t0, CP0_STATUS + PTR_LA $28, init_thread_union # init current pointer + daddiu sp, $28, KERNEL_STACK_SIZE-32 + set_saved_sp sp, t0, t1 + /* - * On IP27, I am seeing the TS bit set when the - * kernel is loaded. Maybe because the kernel is - * in ckseg0 and not xkphys? Clear it anyway ... + * The firmware/bootloader passes argc/argp/envp + * to us as arguments. But clear bss first because + * the romvec and other important info is stored there + * by prom_init(). */ - li t1, ~(ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3) - and t0, t1 - or t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR) # Bogosity: cu0 indicates kernel - mtc0 t0, CP0_STATUS # thread in copy_thread. - - la $28, init_task_union # init current pointer - daddiu t0, $28, KERNEL_STACK_SIZE-32 - sd t0, kernelsp - dsubu sp, t0, 4*SZREG # init stack pointer - move t0, $28 -#ifdef CONFIG_SMP - mtc0 t0, CP0_WATCHLO - dsrl32 t0, t0, 0 - mtc0 t0, CP0_WATCHHI -#endif - /* Note that all firmware passed argument registers still - have their values. */ - jal prom_init # initialize firmware + PTR_LA t0, __bss_start + sd zero, (t0) + PTR_LA t1, __bss_stop - 8 +1: + daddiu t0, 8 + sd zero, (t0) + bne t0, t1, 1b + + dsubu sp, 4*SZREG # init stack pointer - jal start_kernel -1: b 1b # just in case ... + j init_arch END(kernel_entry) +#ifdef CONFIG_SMP +/* + * SMP slave cpus entry point. Board specific code for bootstrap calls this + * function after setting up the stack and gp registers. + */ +NESTED(smp_bootstrap, 16, sp) #ifdef CONFIG_SGI_IP27 -NESTED(bootstrap, 16, sp) - GET_NASID_ASM - li t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + KLDIR_OFF_POINTER + K0BASE + GET_NASID_ASM t1 + li t0, KLDIR_OFFSET + (KLI_KERN_VARS * KLDIR_ENT_SIZE) + \ + KLDIR_OFF_POINTER + K0BASE dsll t1, NASID_SHFT or t0, t0, t1 ld t0, 0(t0) # t0 points to kern_vars struct @@ -146,19 +145,27 @@ lh t2, KV_RW_NASID_OFFSET(t0) MAPPED_KERNEL_SETUP_TLB ARC64_TWIDDLE_PC - CLI - mfc0 t0, CP0_STATUS - li t1, ~(ST0_CU1|ST0_CU2|ST0_CU3) - and t0, t1 - or t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR) # Bogosity: cu0 indicates kernel - mtc0 t0, CP0_STATUS # thread in copy_thread. - jal cboot - END(bootstrap) #endif /* CONFIG_SGI_IP27 */ + CLI + + /* + * For the moment set ST0_KU so the CPU will not spit fire when + * executing 64-bit instructions. The full initialization of the + * CPU's status register is done later in per_cpu_trap_init(). + */ + mfc0 t0, CP0_STATUS + or t0, ST0_KX + mtc0 t0, CP0_STATUS + + jal start_secondary + + END(smp_bootstrap) +#endif /* CONFIG_SMP */ + __FINIT - .comm kernelsp, 8, 8 # current stackpointer + declare_saved_sp #undef PAGE_SIZE #define PAGE_SIZE 0x1000 @@ -171,12 +178,12 @@ .endm .data - .align 12 + .align PAGE_SHIFT page swapper_pg_dir, 1 page invalid_pte_table, 0 page invalid_pmd_table, 1 - page kptbl, KPTBL_PAGE_ORDER + page kptbl, _PGD_ORDER .globl ekptbl page kpmdtbl, 0 ekptbl: diff -Nru a/arch/mips64/kernel/i8259.c b/arch/mips64/kernel/i8259.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/i8259.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,336 @@ +/* + * 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. + * + * Code to handle x86 style IRQs plus some generic interrupt stuff. + * + * Copyright (C) 1992 Linus Torvalds + * Copyright (C) 1994 - 2000 Ralf Baechle + */ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> +#include <linux/sysdev.h> + +#include <asm/i8259.h> +#include <asm/io.h> + +void enable_8259A_irq(unsigned int irq); +void disable_8259A_irq(unsigned int irq); + +/* + * This is the 'legacy' 8259A Programmable Interrupt Controller, + * present in the majority of PC/AT boxes. + * plus some generic x86 specific things if generic specifics makes + * any sense at all. + * this file should become arch/i386/kernel/irq.c when the old irq.c + * moves to arch independent land + */ + +static spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; + +static void end_8259A_irq (unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irq_desc[irq].action) + enable_8259A_irq(irq); +} + +#define shutdown_8259A_irq disable_8259A_irq + +void mask_and_ack_8259A(unsigned int); + +static unsigned int startup_8259A_irq(unsigned int irq) +{ + enable_8259A_irq(irq); + + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type i8259A_irq_type = { + "XT-PIC", + startup_8259A_irq, + shutdown_8259A_irq, + enable_8259A_irq, + disable_8259A_irq, + mask_and_ack_8259A, + end_8259A_irq, + NULL +}; + +/* + * 8259A PIC functions to handle ISA devices: + */ + +/* + * This contains the irq mask for both 8259A irq controllers, + */ +static unsigned int cached_irq_mask = 0xffff; + +#define cached_21 (cached_irq_mask) +#define cached_A1 (cached_irq_mask >> 8) + +void disable_8259A_irq(unsigned int irq) +{ + unsigned int mask = 1 << irq; + unsigned long flags; + + spin_lock_irqsave(&i8259A_lock, flags); + cached_irq_mask |= mask; + if (irq & 8) + outb(cached_A1,0xA1); + else + outb(cached_21,0x21); + spin_unlock_irqrestore(&i8259A_lock, flags); +} + +void enable_8259A_irq(unsigned int irq) +{ + unsigned int mask = ~(1 << irq); + unsigned long flags; + + spin_lock_irqsave(&i8259A_lock, flags); + cached_irq_mask &= mask; + if (irq & 8) + outb(cached_A1,0xA1); + else + outb(cached_21,0x21); + spin_unlock_irqrestore(&i8259A_lock, flags); +} + +int i8259A_irq_pending(unsigned int irq) +{ + unsigned int mask = 1 << irq; + unsigned long flags; + int ret; + + spin_lock_irqsave(&i8259A_lock, flags); + if (irq < 8) + ret = inb(0x20) & mask; + else + ret = inb(0xA0) & (mask >> 8); + spin_unlock_irqrestore(&i8259A_lock, flags); + + return ret; +} + +void make_8259A_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &i8259A_irq_type; + enable_irq(irq); +} + +/* + * This function assumes to be called rarely. Switching between + * 8259A registers is slow. + * This has to be protected by the irq controller spinlock + * before being called. + */ +static inline int i8259A_irq_real(unsigned int irq) +{ + int value; + int irqmask = 1 << irq; + + if (irq < 8) { + outb(0x0B,0x20); /* ISR register */ + value = inb(0x20) & irqmask; + outb(0x0A,0x20); /* back to the IRR register */ + return value; + } + outb(0x0B,0xA0); /* ISR register */ + value = inb(0xA0) & (irqmask >> 8); + outb(0x0A,0xA0); /* back to the IRR register */ + return value; +} + +/* + * Careful! The 8259A is a fragile beast, it pretty + * much _has_ to be done exactly like this (mask it + * first, _then_ send the EOI, and the order of EOI + * to the two 8259s is important! + */ +void mask_and_ack_8259A(unsigned int irq) +{ + unsigned int irqmask = 1 << irq; + unsigned long flags; + + spin_lock_irqsave(&i8259A_lock, flags); + /* + * Lightweight spurious IRQ detection. We do not want to overdo + * spurious IRQ handling - it's usually a sign of hardware problems, so + * we only do the checks we can do without slowing down good hardware + * nnecesserily. + * + * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting + * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A. + * Thus we can check spurious 8259A IRQs without doing the quite slow + * i8259A_irq_real() call for every IRQ. This does not cover 100% of + * spurious interrupts, but should be enough to warn the user that + * there is something bad going on ... + */ + if (cached_irq_mask & irqmask) + goto spurious_8259A_irq; + cached_irq_mask |= irqmask; + +handle_real_irq: + if (irq & 8) { + inb(0xA1); /* DUMMY - (do we need this?) */ + outb(cached_A1,0xA1); + outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ + outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ + } else { + inb(0x21); /* DUMMY - (do we need this?) */ + outb(cached_21,0x21); + outb(0x60+irq,0x20); /* 'Specific EOI' to master */ + } + spin_unlock_irqrestore(&i8259A_lock, flags); + return; + +spurious_8259A_irq: + /* + * this is the slow path - should happen rarely. + */ + if (i8259A_irq_real(irq)) + /* + * oops, the IRQ _is_ in service according to the + * 8259A - not spurious, go handle it. + */ + goto handle_real_irq; + + { + static int spurious_irq_mask = 0; + /* + * At this point we can be sure the IRQ is spurious, + * lets ACK and report it. [once per IRQ] + */ + if (!(spurious_irq_mask & irqmask)) { + printk("spurious 8259A interrupt: IRQ%d.\n", irq); + spurious_irq_mask |= irqmask; + } + atomic_inc(&irq_err_count); + /* + * Theoretically we do not have to handle this IRQ, + * but in Linux this does not cause problems and is + * simpler for us. + */ + goto handle_real_irq; + } +} + +static int i8259A_resume(struct sys_device *dev) +{ + init_8259A(0); + return 0; +} + +static struct sysdev_class i8259_sysdev_class = { + set_kset_name("i8259"), + .resume = i8259A_resume, +}; + +static struct sys_device device_i8259A = { + .id = 0, + .cls = &i8259_sysdev_class, +}; + +static int __init i8259A_init_sysfs(void) +{ + int error = sysdev_class_register(&i8259_sysdev_class); + if (!error) + error = sys_device_register(&device_i8259A); + return error; +} + +device_initcall(i8259A_init_sysfs); + +void __init init_8259A(int auto_eoi) +{ + unsigned long flags; + + spin_lock_irqsave(&i8259A_lock, flags); + + outb(0xff, 0x21); /* mask all of 8259A-1 */ + outb(0xff, 0xA1); /* mask all of 8259A-2 */ + + /* + * outb_p - this has to work on a wide range of PC hardware. + */ + outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ + outb_p(0x00, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */ + outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ + if (auto_eoi) + outb_p(0x03, 0x21); /* master does Auto EOI */ + else + outb_p(0x01, 0x21); /* master expects normal EOI */ + + outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ + outb_p(0x08, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */ + outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ + outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode + is to be investigated) */ + + if (auto_eoi) + /* + * in AEOI mode we just have to mask the interrupt + * when acking. + */ + i8259A_irq_type.ack = disable_8259A_irq; + else + i8259A_irq_type.ack = mask_and_ack_8259A; + + udelay(100); /* wait for 8259A to initialize */ + + outb(cached_21, 0x21); /* restore master IRQ mask */ + outb(cached_A1, 0xA1); /* restore slave IRQ mask */ + + spin_unlock_irqrestore(&i8259A_lock, flags); +} + +asmlinkage void i8259_do_irq(int irq, struct pt_regs regs) +{ + panic("i8259_do_irq: I want to be implemented"); +} + +/* + * IRQ2 is cascade interrupt to second interrupt controller + */ +static struct irqaction irq2 = { + no_action, 0, 0, "cascade", NULL, NULL +}; + +static struct resource pic1_io_resource = { + "pic1", 0x20, 0x3f, IORESOURCE_BUSY +}; + +static struct resource pic2_io_resource = { + "pic2", 0xa0, 0xbf, IORESOURCE_BUSY +}; + +/* + * On systems with i8259-style interrupt controllers we assume for + * driver compatibility reasons interrupts 0 - 15 to be the i8295 + * interrupts even if the hardware uses a different interrupt numbering. + */ +void __init init_i8259_irqs (void) +{ + int i; + + request_resource(&ioport_resource, &pic1_io_resource); + request_resource(&ioport_resource, &pic2_io_resource); + + init_8259A(0); + + for (i = 0; i < 16; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &i8259A_irq_type; + } + + setup_irq(2, &irq2); +} diff -Nru a/arch/mips64/kernel/init_task.c b/arch/mips64/kernel/init_task.c --- a/arch/mips64/kernel/init_task.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips64/kernel/init_task.c Fri Jun 27 14:19:55 2003 @@ -1,17 +1,19 @@ #include <linux/mm.h> #include <linux/sched.h> #include <linux/init_task.h> +#include <linux/fs.h> #include <asm/uaccess.h> #include <asm/pgtable.h> static struct fs_struct init_fs = INIT_FS; static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS; +static struct signal_struct init_signals = INIT_SIGNALS(init_signals); +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); struct mm_struct init_mm = INIT_MM(init_mm); /* - * Initial task structure. + * Initial thread structure. * * We need to make sure that this is 8192-byte aligned due to the * way process stacks are handled. This is done by making sure @@ -20,6 +22,13 @@ * * The things we do for performance.. */ -union task_union init_task_union +union thread_union init_thread_union __attribute__((__section__(".data.init_task"))) = - { INIT_TASK(init_task_union.task) }; + { INIT_THREAD_INFO(init_task) }; + +/* + * Initial task structure. + * + * All other task structs will be allocated on slabs in fork.c + */ +struct task_struct init_task = INIT_TASK(init_task); diff -Nru a/arch/mips64/kernel/ioctl32.c b/arch/mips64/kernel/ioctl32.c --- a/arch/mips64/kernel/ioctl32.c Fri Jun 27 14:19:56 2003 +++ b/arch/mips64/kernel/ioctl32.c Fri Jun 27 14:19:56 2003 @@ -4,33 +4,95 @@ * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * Copyright (C) 2000 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki * * Mostly stolen from the sparc64 ioctl32 implementation. */ #include <linux/config.h> #include <linux/types.h> #include <linux/compat.h> +#include <linux/ioctl32.h> #include <linux/kernel.h> -#include <linux/fs.h> #include <linux/sched.h> +#include <linux/if.h> #include <linux/mm.h> #include <linux/mtio.h> +#include <linux/auto_fs.h> +#include <linux/auto_fs4.h> +#include <linux/devfs_fs.h> +#include <linux/tty.h> #include <linux/init.h> +#include <linux/fs.h> #include <linux/file.h> +#include <linux/fd.h> +#include <linux/ppp_defs.h> +#include <linux/if_ppp.h> +#include <linux/if_pppox.h> +#include <linux/if_tun.h> +#include <linux/cdrom.h> +#include <linux/blkdev.h> +#include <linux/loop.h> +#include <linux/fb.h> #include <linux/vt.h> #include <linux/kd.h> +#include <linux/ext2_fs.h> +#include <linux/videodev.h> #include <linux/netdevice.h> +#include <linux/raw.h> +#include <linux/smb_fs.h> +#include <linux/ncp_fs.h> #include <linux/route.h> #include <linux/hdreg.h> +#include <linux/raid/md.h> #include <linux/blkpg.h> #include <linux/blkdev.h> #include <linux/elevator.h> -#include <linux/auto_fs.h> -#include <linux/ext2_fs.h> -#include <linux/raid/md_u.h> +#include <linux/rtc.h> +#include <linux/pci.h> #include <linux/dm-ioctl.h> -#include <asm/types.h> -#include <asm/uaccess.h> + +#include <scsi/scsi.h> +#undef __KERNEL__ /* This file was born to be ugly ... */ +#include <scsi/scsi_ioctl.h> +#define __KERNEL__ +#include <scsi/sg.h> + +#include <linux/ethtool.h> +#include <linux/mii.h> +#include <linux/if_bonding.h> +#include <linux/watchdog.h> + +#include <asm/ioctls.h> +#include <asm/module.h> +#include <linux/soundcard.h> +#include <linux/lp.h> + +#include <linux/atm.h> +#include <linux/atmarp.h> +#include <linux/atmclip.h> +#include <linux/atmdev.h> +#include <linux/atmioc.h> +#include <linux/atmlec.h> +#include <linux/atmmpc.h> +#include <linux/atmsvc.h> +#include <linux/atm_tcp.h> +#include <linux/sonet.h> +#include <linux/atm_suni.h> +#include <linux/mtd/mtd.h> + +#include <net/bluetooth/bluetooth.h> +#include <net/bluetooth/hci.h> +#include <net/bluetooth/rfcomm.h> + +#include <linux/usb.h> +#include <linux/usbdevice_fs.h> +#include <linux/nbd.h> +#include <linux/random.h> +#include <linux/filter.h> + +#ifdef CONFIG_SIBYTE_TBPROF +#include <asm/sibyte/trace_prof.h> +#endif long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg); @@ -39,7 +101,7 @@ mm_segment_t old_fs = get_fs(); int err; unsigned long val; - + set_fs (KERNEL_DS); err = sys_ioctl(fd, cmd, (unsigned long)&val); set_fs (old_fs); @@ -66,6 +128,166 @@ #define A(__x) ((unsigned long)(__x)) + +#ifdef CONFIG_FB + +struct fb_fix_screeninfo32 { + char id[16]; /* identification string eg "TT Builtin" */ + __u32 smem_start; /* Start of frame buffer mem */ + /* (physical address) */ + __u32 smem_len; /* Length of frame buffer mem */ + __u32 type; /* see FB_TYPE_* */ + __u32 type_aux; /* Interleave for interleaved Planes */ + __u32 visual; /* see FB_VISUAL_* */ + __u16 xpanstep; /* zero if no hardware panning */ + __u16 ypanstep; /* zero if no hardware panning */ + __u16 ywrapstep; /* zero if no hardware ywrap */ + __u32 line_length; /* length of a line in bytes */ + __u32 mmio_start; /* Start of Memory Mapped I/O */ + /* (physical address) */ + __u32 mmio_len; /* Length of Memory Mapped I/O */ + __u32 accel; /* Type of acceleration available */ + __u16 reserved[3]; /* Reserved for future compatibility */ +}; + +static int do_fbioget_fscreeninfo_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + struct fb_fix_screeninfo fix; + struct fb_fix_screeninfo32 *fix32 = (struct fb_fix_screeninfo32 *)arg; + int err; + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&fix); + set_fs(old_fs); + + if (err == 0) { + err = __copy_to_user((char *)fix32->id, (char *)fix.id, + sizeof(fix.id)); + err |= __put_user((__u32)(unsigned long)fix.smem_start, + &fix32->smem_start); + err |= __put_user(fix.smem_len, &fix32->smem_len); + err |= __put_user(fix.type, &fix32->type); + err |= __put_user(fix.type_aux, &fix32->type_aux); + err |= __put_user(fix.visual, &fix32->visual); + err |= __put_user(fix.xpanstep, &fix32->xpanstep); + err |= __put_user(fix.ypanstep, &fix32->ypanstep); + err |= __put_user(fix.ywrapstep, &fix32->ywrapstep); + err |= __put_user(fix.line_length, &fix32->line_length); + err |= __put_user((__u32)(unsigned long)fix.mmio_start, + &fix32->mmio_start); + err |= __put_user(fix.mmio_len, &fix32->mmio_len); + err |= __put_user(fix.accel, &fix32->accel); + err |= __copy_to_user((char *)fix32->reserved, + (char *)fix.reserved, + sizeof(fix.reserved)); + if (err) + err = -EFAULT; + } + + return err; +} + +struct fb_cmap32 { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ + __u32 red; /* Red values */ + __u32 green; + __u32 blue; + __u32 transp; /* transparency, can be NULL */ +}; + +static int do_fbiocmap_ioctl(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ + mm_segment_t old_fs = get_fs(); + u32 red = 0, green = 0, blue = 0, transp = 0; + struct fb_cmap cmap; + struct fb_cmap32 *cmap32 = (struct fb_cmap32 *)arg; + int err; + + memset(&cmap, 0, sizeof(cmap)); + + err = __get_user(cmap.start, &cmap32->start); + err |= __get_user(cmap.len, &cmap32->len); + err |= __get_user(red, &cmap32->red); + err |= __get_user(green, &cmap32->green); + err |= __get_user(blue, &cmap32->blue); + err |= __get_user(transp, &cmap32->transp); + if (err) + return -EFAULT; + + err = -ENOMEM; + cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.red) + goto out; + cmap.green = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.green) + goto out; + cmap.blue = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.blue) + goto out; + if (transp) { + cmap.transp = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL); + if (!cmap.transp) + goto out; + } + + if (cmd == FBIOPUTCMAP) { + err = __copy_from_user(cmap.red, (char *)A(red), + cmap.len * sizeof(__u16)); + err |= __copy_from_user(cmap.green, (char *)A(green), + cmap.len * sizeof(__u16)); + err |= __copy_from_user(cmap.blue, (char *)A(blue), + cmap.len * sizeof(__u16)); + if (cmap.transp) + err |= __copy_from_user(cmap.transp, (char *)A(transp), + cmap.len * sizeof(__u16)); + if (err) { + err = -EFAULT; + goto out; + } + } + + set_fs(KERNEL_DS); + err = sys_ioctl(fd, cmd, (unsigned long)&cmap); + set_fs(old_fs); + if (err) + goto out; + + if (cmd == FBIOGETCMAP) { + err = __copy_to_user((char *)A(red), cmap.red, + cmap.len * sizeof(__u16)); + err |= __copy_to_user((char *)A(green), cmap.blue, + cmap.len * sizeof(__u16)); + err |= __copy_to_user((char *)A(blue), cmap.blue, + cmap.len * sizeof(__u16)); + if (cmap.transp) + err |= __copy_to_user((char *)A(transp), cmap.transp, + cmap.len * sizeof(__u16)); + if (err) { + err = -EFAULT; + goto out; + } + } + +out: + if (cmap.red) + kfree(cmap.red); + if (cmap.green) + kfree(cmap.green); + if (cmap.blue) + kfree(cmap.blue); + if (cmap.transp) + kfree(cmap.transp); + + return err; +} + +#endif /* CONFIG_FB */ + + static int do_siocgstamp(unsigned int fd, unsigned int cmd, unsigned long arg) { struct compat_timeval *up = (struct compat_timeval *)arg; @@ -190,7 +412,7 @@ old_fs = get_fs(); set_fs (KERNEL_DS); - err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); + err = sys_ioctl (fd, SIOCGIFCONF, (unsigned long)&ifc); set_fs (old_fs); if (err) goto out; @@ -217,28 +439,52 @@ return err; } -static inline int dev_ifsioc(unsigned int fd, unsigned int cmd, - unsigned long arg) +int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct ifreq *u_ifreq64; + struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg; + char tmp_buf[IFNAMSIZ]; + void *data64; + u32 data32; + + if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]), + IFNAMSIZ)) + return -EFAULT; + if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data)) + return -EFAULT; + data64 = (void *) A(data32); + + u_ifreq64 = compat_alloc_user_space(sizeof(*u_ifreq64)); + + /* Don't check these user accesses, just let that get trapped + * in the ioctl handler instead. + */ + copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ); + __put_user(data64, &u_ifreq64->ifr_ifru.ifru_data); + + return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64); +} + +static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct ifreq32 *uifr = (struct ifreq32 *)arg; struct ifreq ifr; mm_segment_t old_fs; int err; switch (cmd) { case SIOCSIFMAP: - err = copy_from_user(&ifr, uifr, sizeof(ifr.ifr_name)); - err |= __get_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start)); - err |= __get_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end)); - err |= __get_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr)); - err |= __get_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq)); - err |= __get_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma)); - err |= __get_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port)); + err = copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(ifr.ifr_name)); + err |= __get_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start)); + err |= __get_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end)); + err |= __get_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr)); + err |= __get_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq)); + err |= __get_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma)); + err |= __get_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port)); if (err) return -EFAULT; break; default: - if (copy_from_user(&ifr, uifr, sizeof(struct ifreq32))) + if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32))) return -EFAULT; break; } @@ -259,17 +505,17 @@ case SIOCGIFDSTADDR: case SIOCGIFNETMASK: case SIOCGIFTXQLEN: - if (copy_to_user(uifr, &ifr, sizeof(struct ifreq32))) + if (copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(struct ifreq32))) return -EFAULT; break; case SIOCGIFMAP: - err = copy_to_user(uifr, &ifr, sizeof(ifr.ifr_name)); - err |= __put_user(ifr.ifr_map.mem_start, &(uifr->ifr_ifru.ifru_map.mem_start)); - err |= __put_user(ifr.ifr_map.mem_end, &(uifr->ifr_ifru.ifru_map.mem_end)); - err |= __put_user(ifr.ifr_map.base_addr, &(uifr->ifr_ifru.ifru_map.base_addr)); - err |= __put_user(ifr.ifr_map.irq, &(uifr->ifr_ifru.ifru_map.irq)); - err |= __put_user(ifr.ifr_map.dma, &(uifr->ifr_ifru.ifru_map.dma)); - err |= __put_user(ifr.ifr_map.port, &(uifr->ifr_ifru.ifru_map.port)); + err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name)); + err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start)); + err |= __put_user(ifr.ifr_map.mem_end, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_end)); + err |= __put_user(ifr.ifr_map.base_addr, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.base_addr)); + err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq)); + err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma)); + err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port)); if (err) err = -EFAULT; break; @@ -306,7 +552,7 @@ u32 rtdev; int ret; mm_segment_t old_fs = get_fs(); - + ret = copy_from_user (&r.rt_dst, &(ur->rt_dst), 3 * sizeof(struct sockaddr)); ret |= __get_user (r.rt_flags, &(ur->rt_flags)); ret |= __get_user (r.rt_metric, &(ur->rt_metric)); @@ -404,7 +650,7 @@ struct blkpg_partition p; int err; mm_segment_t old_fs = get_fs(); - + err = get_user(a.op, &arg->op); err |= __get_user(a.flags, &arg->flags); err |= __get_user(a.datalen, &arg->datalen); @@ -423,7 +669,7 @@ set_fs (old_fs); default: return -EINVAL; - } + } return err; } @@ -557,235 +803,356 @@ return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg); } -struct ioctl32_handler { - unsigned int cmd; - int (*function)(unsigned int, unsigned int, unsigned long); -}; - -struct ioctl32_list { - struct ioctl32_handler handler; - struct ioctl32_list *next; -}; - -#define IOCTL32_DEFAULT(cmd) { { cmd, (void *) sys_ioctl }, 0 } -#define IOCTL32_HANDLER(cmd, handler) { { cmd, (void *) handler }, 0 } - -static struct ioctl32_list ioctl32_handler_table[] = { - IOCTL32_DEFAULT(TCGETA), - IOCTL32_DEFAULT(TCSETA), - IOCTL32_DEFAULT(TCSETAW), - IOCTL32_DEFAULT(TCSETAF), - IOCTL32_DEFAULT(TCSBRK), - IOCTL32_DEFAULT(TCXONC), - IOCTL32_DEFAULT(TCFLSH), - IOCTL32_DEFAULT(TCGETS), - IOCTL32_DEFAULT(TCSETS), - IOCTL32_DEFAULT(TCSETSW), - IOCTL32_DEFAULT(TCSETSF), - IOCTL32_DEFAULT(TIOCLINUX), - - IOCTL32_DEFAULT(TIOCGETD), - IOCTL32_DEFAULT(TIOCSETD), - IOCTL32_DEFAULT(TIOCEXCL), - IOCTL32_DEFAULT(TIOCNXCL), - IOCTL32_DEFAULT(TIOCCONS), - IOCTL32_DEFAULT(TIOCGSOFTCAR), - IOCTL32_DEFAULT(TIOCSSOFTCAR), - IOCTL32_DEFAULT(TIOCSWINSZ), - IOCTL32_DEFAULT(TIOCGWINSZ), - IOCTL32_DEFAULT(TIOCMGET), - IOCTL32_DEFAULT(TIOCMBIC), - IOCTL32_DEFAULT(TIOCMBIS), - IOCTL32_DEFAULT(TIOCMSET), - IOCTL32_DEFAULT(TIOCPKT), - IOCTL32_DEFAULT(TIOCNOTTY), - IOCTL32_DEFAULT(TIOCSTI), - IOCTL32_DEFAULT(TIOCOUTQ), - IOCTL32_DEFAULT(TIOCSPGRP), - IOCTL32_DEFAULT(TIOCGPGRP), - IOCTL32_DEFAULT(TIOCSCTTY), - IOCTL32_DEFAULT(TIOCGPTN), - IOCTL32_DEFAULT(TIOCSPTLCK), - IOCTL32_DEFAULT(TIOCGSERIAL), - IOCTL32_DEFAULT(TIOCSSERIAL), - IOCTL32_DEFAULT(TIOCSERGETLSR), - - IOCTL32_DEFAULT(FIOCLEX), - IOCTL32_DEFAULT(FIONCLEX), - IOCTL32_DEFAULT(FIOASYNC), - IOCTL32_DEFAULT(FIONBIO), - IOCTL32_DEFAULT(FIONREAD), - - IOCTL32_DEFAULT(PIO_FONT), - IOCTL32_DEFAULT(GIO_FONT), - IOCTL32_DEFAULT(KDSIGACCEPT), - IOCTL32_DEFAULT(KDGETKEYCODE), - IOCTL32_DEFAULT(KDSETKEYCODE), - IOCTL32_DEFAULT(KIOCSOUND), - IOCTL32_DEFAULT(KDMKTONE), - IOCTL32_DEFAULT(KDGKBTYPE), - IOCTL32_DEFAULT(KDSETMODE), - IOCTL32_DEFAULT(KDGETMODE), - IOCTL32_DEFAULT(KDSKBMODE), - IOCTL32_DEFAULT(KDGKBMODE), - IOCTL32_DEFAULT(KDSKBMETA), - IOCTL32_DEFAULT(KDGKBMETA), - IOCTL32_DEFAULT(KDGKBENT), - IOCTL32_DEFAULT(KDSKBENT), - IOCTL32_DEFAULT(KDGKBSENT), - IOCTL32_DEFAULT(KDSKBSENT), - IOCTL32_DEFAULT(KDGKBDIACR), - IOCTL32_DEFAULT(KDSKBDIACR), - IOCTL32_DEFAULT(KDGKBLED), - IOCTL32_DEFAULT(KDSKBLED), - IOCTL32_DEFAULT(KDGETLED), - IOCTL32_DEFAULT(KDSETLED), - IOCTL32_DEFAULT(GIO_SCRNMAP), - IOCTL32_DEFAULT(PIO_SCRNMAP), - IOCTL32_DEFAULT(GIO_UNISCRNMAP), - IOCTL32_DEFAULT(PIO_UNISCRNMAP), - IOCTL32_DEFAULT(PIO_FONTRESET), - IOCTL32_DEFAULT(PIO_UNIMAPCLR), - - IOCTL32_DEFAULT(VT_SETMODE), - IOCTL32_DEFAULT(VT_GETMODE), - IOCTL32_DEFAULT(VT_GETSTATE), - IOCTL32_DEFAULT(VT_OPENQRY), - IOCTL32_DEFAULT(VT_ACTIVATE), - IOCTL32_DEFAULT(VT_WAITACTIVE), - IOCTL32_DEFAULT(VT_RELDISP), - IOCTL32_DEFAULT(VT_DISALLOCATE), - IOCTL32_DEFAULT(VT_RESIZE), - IOCTL32_DEFAULT(VT_RESIZEX), - IOCTL32_DEFAULT(VT_LOCKSWITCH), - IOCTL32_DEFAULT(VT_UNLOCKSWITCH), +typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); + +#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) +#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL }, +#define IOCTL_TABLE_START \ + struct ioctl_trans ioctl_start[] = { +#define IOCTL_TABLE_END \ + }; struct ioctl_trans ioctl_end[0]; + + +IOCTL_TABLE_START +#include <linux/compat_ioctl.h> +COMPATIBLE_IOCTL(TCGETA) +COMPATIBLE_IOCTL(TCSETA) +COMPATIBLE_IOCTL(TCSETAW) +COMPATIBLE_IOCTL(TCSETAF) +COMPATIBLE_IOCTL(TCSBRK) +COMPATIBLE_IOCTL(TCXONC) +COMPATIBLE_IOCTL(TCFLSH) +COMPATIBLE_IOCTL(TCGETS) +COMPATIBLE_IOCTL(TCSETS) +COMPATIBLE_IOCTL(TCSETSW) +COMPATIBLE_IOCTL(TCSETSF) +COMPATIBLE_IOCTL(TIOCLINUX) + +COMPATIBLE_IOCTL(TIOCGETD) +COMPATIBLE_IOCTL(TIOCSETD) +COMPATIBLE_IOCTL(TIOCEXCL) +COMPATIBLE_IOCTL(TIOCNXCL) +COMPATIBLE_IOCTL(TIOCCONS) +COMPATIBLE_IOCTL(TIOCGSOFTCAR) +COMPATIBLE_IOCTL(TIOCSSOFTCAR) +COMPATIBLE_IOCTL(TIOCSWINSZ) +COMPATIBLE_IOCTL(TIOCGWINSZ) +COMPATIBLE_IOCTL(TIOCMGET) +COMPATIBLE_IOCTL(TIOCMBIC) +COMPATIBLE_IOCTL(TIOCMBIS) +COMPATIBLE_IOCTL(TIOCMSET) +COMPATIBLE_IOCTL(TIOCPKT) +COMPATIBLE_IOCTL(TIOCNOTTY) +COMPATIBLE_IOCTL(TIOCSTI) +COMPATIBLE_IOCTL(TIOCOUTQ) +COMPATIBLE_IOCTL(TIOCSPGRP) +COMPATIBLE_IOCTL(TIOCGPGRP) +COMPATIBLE_IOCTL(TIOCSCTTY) +COMPATIBLE_IOCTL(TIOCGPTN) +COMPATIBLE_IOCTL(TIOCSPTLCK) +COMPATIBLE_IOCTL(TIOCGSERIAL) +COMPATIBLE_IOCTL(TIOCSSERIAL) +COMPATIBLE_IOCTL(TIOCSERGETLSR) + +COMPATIBLE_IOCTL(FIOCLEX) +COMPATIBLE_IOCTL(FIONCLEX) +COMPATIBLE_IOCTL(FIOASYNC) +COMPATIBLE_IOCTL(FIONBIO) +COMPATIBLE_IOCTL(FIONREAD) + +#ifdef CONFIG_FB +/* Big F */ +COMPATIBLE_IOCTL(FBIOGET_VSCREENINFO) +COMPATIBLE_IOCTL(FBIOPUT_VSCREENINFO) +HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl) +HANDLE_IOCTL(FBIOGETCMAP, do_fbiocmap_ioctl) +HANDLE_IOCTL(FBIOPUTCMAP, do_fbiocmap_ioctl) +COMPATIBLE_IOCTL(FBIOPAN_DISPLAY) +#endif /* CONFIG_FB */ + +/* Big K */ +COMPATIBLE_IOCTL(PIO_FONT) +COMPATIBLE_IOCTL(GIO_FONT) +COMPATIBLE_IOCTL(KDSIGACCEPT) +COMPATIBLE_IOCTL(KDGETKEYCODE) +COMPATIBLE_IOCTL(KDSETKEYCODE) +COMPATIBLE_IOCTL(KIOCSOUND) +COMPATIBLE_IOCTL(KDMKTONE) +COMPATIBLE_IOCTL(KDGKBTYPE) +COMPATIBLE_IOCTL(KDSETMODE) +COMPATIBLE_IOCTL(KDGETMODE) +COMPATIBLE_IOCTL(KDSKBMODE) +COMPATIBLE_IOCTL(KDGKBMODE) +COMPATIBLE_IOCTL(KDSKBMETA) +COMPATIBLE_IOCTL(KDGKBMETA) +COMPATIBLE_IOCTL(KDGKBENT) +COMPATIBLE_IOCTL(KDSKBENT) +COMPATIBLE_IOCTL(KDGKBSENT) +COMPATIBLE_IOCTL(KDSKBSENT) +COMPATIBLE_IOCTL(KDGKBDIACR) +COMPATIBLE_IOCTL(KDSKBDIACR) +COMPATIBLE_IOCTL(KDKBDREP) +COMPATIBLE_IOCTL(KDGKBLED) +COMPATIBLE_IOCTL(KDSKBLED) +COMPATIBLE_IOCTL(KDGETLED) +COMPATIBLE_IOCTL(KDSETLED) +COMPATIBLE_IOCTL(GIO_SCRNMAP) +COMPATIBLE_IOCTL(PIO_SCRNMAP) +COMPATIBLE_IOCTL(GIO_UNISCRNMAP) +COMPATIBLE_IOCTL(PIO_UNISCRNMAP) +COMPATIBLE_IOCTL(PIO_FONTRESET) +COMPATIBLE_IOCTL(PIO_UNIMAPCLR) + +/* Big S */ +COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN) +COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK) +COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK) +COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY) +COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_ENABLE) +COMPATIBLE_IOCTL(SCSI_IOCTL_TAGGED_DISABLE) +COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER) +COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND) + +/* Big V */ +COMPATIBLE_IOCTL(VT_SETMODE) +COMPATIBLE_IOCTL(VT_GETMODE) +COMPATIBLE_IOCTL(VT_GETSTATE) +COMPATIBLE_IOCTL(VT_OPENQRY) +COMPATIBLE_IOCTL(VT_ACTIVATE) +COMPATIBLE_IOCTL(VT_WAITACTIVE) +COMPATIBLE_IOCTL(VT_RELDISP) +COMPATIBLE_IOCTL(VT_DISALLOCATE) +COMPATIBLE_IOCTL(VT_RESIZE) +COMPATIBLE_IOCTL(VT_RESIZEX) +COMPATIBLE_IOCTL(VT_LOCKSWITCH) +COMPATIBLE_IOCTL(VT_UNLOCKSWITCH) #ifdef CONFIG_NET - /* Socket level stuff */ - IOCTL32_DEFAULT(FIOSETOWN), - IOCTL32_DEFAULT(SIOCSPGRP), - IOCTL32_DEFAULT(FIOGETOWN), - IOCTL32_DEFAULT(SIOCGPGRP), - IOCTL32_DEFAULT(SIOCATMARK), - IOCTL32_DEFAULT(SIOCSIFLINK), - IOCTL32_DEFAULT(SIOCSIFENCAP), - IOCTL32_DEFAULT(SIOCGIFENCAP), - IOCTL32_DEFAULT(SIOCSIFBR), - IOCTL32_DEFAULT(SIOCGIFBR), - IOCTL32_DEFAULT(SIOCSARP), - IOCTL32_DEFAULT(SIOCGARP), - IOCTL32_DEFAULT(SIOCDARP), - IOCTL32_DEFAULT(SIOCSRARP), - IOCTL32_DEFAULT(SIOCGRARP), - IOCTL32_DEFAULT(SIOCDRARP), - IOCTL32_DEFAULT(SIOCADDDLCI), - IOCTL32_DEFAULT(SIOCDELDLCI), - - IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32), - IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf), - IOCTL32_HANDLER(SIOCGIFFLAGS, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFFLAGS, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFMETRIC, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFMETRIC, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFMTU, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFMTU, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFMEM, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFMEM, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFHWADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFHWADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCADDMULTI, dev_ifsioc), - IOCTL32_HANDLER(SIOCDELMULTI, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFINDEX, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFMAP, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFMAP, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFBRDADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFBRDADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFDSTADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFDSTADDR, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFNETMASK, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFNETMASK, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFPFLAGS, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFPFLAGS, dev_ifsioc), - IOCTL32_HANDLER(SIOCGIFTXQLEN, dev_ifsioc), - IOCTL32_HANDLER(SIOCSIFTXQLEN, dev_ifsioc), - IOCTL32_HANDLER(SIOCADDRT, routing_ioctl), - IOCTL32_HANDLER(SIOCDELRT, routing_ioctl), - /* - * Note SIOCRTMSG is no longer, so this is safe and * the user would - * have seen just an -EINVAL anyways. - */ - IOCTL32_HANDLER(SIOCRTMSG, ret_einval), - IOCTL32_HANDLER(SIOCGSTAMP, do_siocgstamp), +/* Socket level stuff */ +COMPATIBLE_IOCTL(FIOSETOWN) +COMPATIBLE_IOCTL(SIOCSPGRP) +COMPATIBLE_IOCTL(FIOGETOWN) +COMPATIBLE_IOCTL(SIOCGPGRP) +COMPATIBLE_IOCTL(SIOCATMARK) +COMPATIBLE_IOCTL(SIOCSIFLINK) +COMPATIBLE_IOCTL(SIOCSIFENCAP) +COMPATIBLE_IOCTL(SIOCGIFENCAP) +COMPATIBLE_IOCTL(SIOCSIFBR) +COMPATIBLE_IOCTL(SIOCGIFBR) +COMPATIBLE_IOCTL(SIOCSARP) +COMPATIBLE_IOCTL(SIOCGARP) +COMPATIBLE_IOCTL(SIOCDARP) +COMPATIBLE_IOCTL(SIOCSRARP) +COMPATIBLE_IOCTL(SIOCGRARP) +COMPATIBLE_IOCTL(SIOCDRARP) +COMPATIBLE_IOCTL(SIOCADDDLCI) +COMPATIBLE_IOCTL(SIOCDELDLCI) +/* SG stuff */ +COMPATIBLE_IOCTL(SG_SET_TIMEOUT) +COMPATIBLE_IOCTL(SG_GET_TIMEOUT) +COMPATIBLE_IOCTL(SG_EMULATED_HOST) +COMPATIBLE_IOCTL(SG_SET_TRANSFORM) +COMPATIBLE_IOCTL(SG_GET_TRANSFORM) +COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) +COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) +COMPATIBLE_IOCTL(SG_GET_SCSI_ID) +COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA) +COMPATIBLE_IOCTL(SG_GET_LOW_DMA) +COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID) +COMPATIBLE_IOCTL(SG_GET_PACK_ID) +COMPATIBLE_IOCTL(SG_GET_NUM_WAITING) +COMPATIBLE_IOCTL(SG_SET_DEBUG) +COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE) +COMPATIBLE_IOCTL(SG_GET_COMMAND_Q) +COMPATIBLE_IOCTL(SG_SET_COMMAND_Q) +COMPATIBLE_IOCTL(SG_GET_VERSION_NUM) +COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN) +COMPATIBLE_IOCTL(SG_SCSI_RESET) +COMPATIBLE_IOCTL(SG_IO) +COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) +COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN) +COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN) +/* PPP stuff */ +COMPATIBLE_IOCTL(PPPIOCGFLAGS) +COMPATIBLE_IOCTL(PPPIOCSFLAGS) +COMPATIBLE_IOCTL(PPPIOCGASYNCMAP) +COMPATIBLE_IOCTL(PPPIOCSASYNCMAP) +COMPATIBLE_IOCTL(PPPIOCGUNIT) +COMPATIBLE_IOCTL(PPPIOCGRASYNCMAP) +COMPATIBLE_IOCTL(PPPIOCSRASYNCMAP) +COMPATIBLE_IOCTL(PPPIOCGMRU) +COMPATIBLE_IOCTL(PPPIOCSMRU) +COMPATIBLE_IOCTL(PPPIOCSMAXCID) +COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP) +COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP) +COMPATIBLE_IOCTL(PPPIOCXFERUNIT) +COMPATIBLE_IOCTL(PPPIOCGNPMODE) +COMPATIBLE_IOCTL(PPPIOCSNPMODE) +COMPATIBLE_IOCTL(PPPIOCGDEBUG) +COMPATIBLE_IOCTL(PPPIOCSDEBUG) +COMPATIBLE_IOCTL(PPPIOCNEWUNIT) +COMPATIBLE_IOCTL(PPPIOCATTACH) +COMPATIBLE_IOCTL(PPPIOCGCHAN) +/* PPPOX */ +COMPATIBLE_IOCTL(PPPOEIOCSFWD) +COMPATIBLE_IOCTL(PPPOEIOCDFWD) +/* CDROM stuff */ +COMPATIBLE_IOCTL(CDROMPAUSE) +COMPATIBLE_IOCTL(CDROMRESUME) +COMPATIBLE_IOCTL(CDROMPLAYMSF) +COMPATIBLE_IOCTL(CDROMPLAYTRKIND) +COMPATIBLE_IOCTL(CDROMREADTOCHDR) +COMPATIBLE_IOCTL(CDROMREADTOCENTRY) +COMPATIBLE_IOCTL(CDROMSTOP) +COMPATIBLE_IOCTL(CDROMSTART) +COMPATIBLE_IOCTL(CDROMEJECT) +COMPATIBLE_IOCTL(CDROMVOLCTRL) +COMPATIBLE_IOCTL(CDROMSUBCHNL) +COMPATIBLE_IOCTL(CDROMEJECT_SW) +COMPATIBLE_IOCTL(CDROMMULTISESSION) +COMPATIBLE_IOCTL(CDROM_GET_MCN) +COMPATIBLE_IOCTL(CDROMRESET) +COMPATIBLE_IOCTL(CDROMVOLREAD) +COMPATIBLE_IOCTL(CDROMSEEK) +COMPATIBLE_IOCTL(CDROMPLAYBLK) +COMPATIBLE_IOCTL(CDROMCLOSETRAY) +COMPATIBLE_IOCTL(CDROM_SET_OPTIONS) +COMPATIBLE_IOCTL(CDROM_CLEAR_OPTIONS) +COMPATIBLE_IOCTL(CDROM_SELECT_SPEED) +COMPATIBLE_IOCTL(CDROM_SELECT_DISC) +COMPATIBLE_IOCTL(CDROM_MEDIA_CHANGED) +COMPATIBLE_IOCTL(CDROM_DRIVE_STATUS) +COMPATIBLE_IOCTL(CDROM_DISC_STATUS) +COMPATIBLE_IOCTL(CDROM_CHANGER_NSLOTS) +COMPATIBLE_IOCTL(CDROM_LOCKDOOR) +COMPATIBLE_IOCTL(CDROM_DEBUG) +COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY) +/* DVD ioctls */ +COMPATIBLE_IOCTL(DVD_READ_STRUCT) +COMPATIBLE_IOCTL(DVD_WRITE_STRUCT) +COMPATIBLE_IOCTL(DVD_AUTH) +/* Big L */ +COMPATIBLE_IOCTL(LOOP_SET_FD) +COMPATIBLE_IOCTL(LOOP_CLR_FD) + +/* And these ioctls need translation */ +HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) +HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) +HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc) +HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc) +HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc) +HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc) +HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc) +HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) +HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) +HANDLE_IOCTL(SIOCADDRT, routing_ioctl) +HANDLE_IOCTL(SIOCDELRT, routing_ioctl) +/* + * Note SIOCRTMSG is no longer, so this is safe and * the user would + * have seen just an -EINVAL anyways. + */ +HANDLE_IOCTL(SIOCRTMSG, ret_einval) +HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp) #endif /* CONFIG_NET */ - IOCTL32_HANDLER(EXT2_IOC32_GETFLAGS, do_ext2_ioctl), - IOCTL32_HANDLER(EXT2_IOC32_SETFLAGS, do_ext2_ioctl), - IOCTL32_HANDLER(EXT2_IOC32_GETVERSION, do_ext2_ioctl), - IOCTL32_HANDLER(EXT2_IOC32_SETVERSION, do_ext2_ioctl), - - IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */ - IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans), - IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans), - IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans), - IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans), - IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans), - IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans), - IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans), - IOCTL32_DEFAULT(HDIO_GET_IDENTITY), - IOCTL32_DEFAULT(HDIO_DRIVE_CMD), - IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT), - IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR), - IOCTL32_DEFAULT(HDIO_SET_KEEPSETTINGS), - IOCTL32_DEFAULT(HDIO_SET_32BIT), - IOCTL32_DEFAULT(HDIO_SET_NOWERR), - IOCTL32_DEFAULT(HDIO_SET_DMA), - IOCTL32_DEFAULT(HDIO_SET_PIO_MODE), - IOCTL32_DEFAULT(HDIO_SET_NICE), - - IOCTL32_DEFAULT(BLKROSET), /* fs.h ioctls */ - IOCTL32_DEFAULT(BLKROGET), - IOCTL32_DEFAULT(BLKRRPART), - IOCTL32_HANDLER(BLKGETSIZE, w_long), - - IOCTL32_DEFAULT(BLKFLSBUF), - IOCTL32_DEFAULT(BLKSECTSET), - IOCTL32_HANDLER(BLKSECTGET, w_long), - IOCTL32_DEFAULT(BLKSSZGET), - IOCTL32_HANDLER(BLKPG, blkpg_ioctl_trans), - IOCTL32_DEFAULT(BLKBSZGET), - IOCTL32_DEFAULT(BLKBSZSET), +HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) +HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) +HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) +HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl) + +HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo) /* hdreg.h ioctls */ +HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans) +// HDIO_OBSOLETE_IDENTITY +//HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans) +HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans) +COMPATIBLE_IOCTL(HDIO_GET_IDENTITY) +// HDIO_TRISTATE_HWIF /* not implemented */ +// HDIO_DRIVE_TASK /* To do, need specs */ +COMPATIBLE_IOCTL(HDIO_DRIVE_CMD) +COMPATIBLE_IOCTL(HDIO_SET_MULTCOUNT) +COMPATIBLE_IOCTL(HDIO_SET_UNMASKINTR) +//COMPATIBLE_IOCTL(HDIO_SET_KEEPSETTINGS) +COMPATIBLE_IOCTL(HDIO_SET_32BIT) +COMPATIBLE_IOCTL(HDIO_SET_NOWERR) +COMPATIBLE_IOCTL(HDIO_SET_DMA) +COMPATIBLE_IOCTL(HDIO_SET_PIO_MODE) +COMPATIBLE_IOCTL(HDIO_SET_NICE) + +COMPATIBLE_IOCTL(BLKROSET) /* fs.h ioctls */ +COMPATIBLE_IOCTL(BLKROGET) +COMPATIBLE_IOCTL(BLKRRPART) +HANDLE_IOCTL(BLKGETSIZE, w_long) + +COMPATIBLE_IOCTL(BLKFLSBUF) +COMPATIBLE_IOCTL(BLKSECTSET) +HANDLE_IOCTL(BLKSECTGET, w_long) +COMPATIBLE_IOCTL(BLKSSZGET) +HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans) +COMPATIBLE_IOCTL(BLKBSZGET) +COMPATIBLE_IOCTL(BLKBSZSET) #ifdef CONFIG_MD - /* status */ - IOCTL32_DEFAULT(RAID_VERSION), - IOCTL32_DEFAULT(GET_ARRAY_INFO), - IOCTL32_DEFAULT(GET_DISK_INFO), - IOCTL32_DEFAULT(PRINT_RAID_DEBUG), - IOCTL32_DEFAULT(RAID_AUTORUN), - - /* configuration */ - IOCTL32_DEFAULT(CLEAR_ARRAY), - IOCTL32_DEFAULT(ADD_NEW_DISK), - IOCTL32_DEFAULT(HOT_REMOVE_DISK), - IOCTL32_DEFAULT(SET_ARRAY_INFO), - IOCTL32_DEFAULT(SET_DISK_INFO), - IOCTL32_DEFAULT(WRITE_RAID_INFO), - IOCTL32_DEFAULT(UNPROTECT_ARRAY), - IOCTL32_DEFAULT(PROTECT_ARRAY), - IOCTL32_DEFAULT(HOT_ADD_DISK), - IOCTL32_DEFAULT(SET_DISK_FAULTY), - - /* usage */ - IOCTL32_DEFAULT(RUN_ARRAY), - IOCTL32_DEFAULT(START_ARRAY), - IOCTL32_DEFAULT(STOP_ARRAY), - IOCTL32_DEFAULT(STOP_ARRAY_RO), - IOCTL32_DEFAULT(RESTART_ARRAY_RW), +/* status */ +COMPATIBLE_IOCTL(RAID_VERSION) +COMPATIBLE_IOCTL(GET_ARRAY_INFO) +COMPATIBLE_IOCTL(GET_DISK_INFO) +COMPATIBLE_IOCTL(PRINT_RAID_DEBUG) +COMPATIBLE_IOCTL(RAID_AUTORUN) + +/* configuration */ +COMPATIBLE_IOCTL(CLEAR_ARRAY) +COMPATIBLE_IOCTL(ADD_NEW_DISK) +COMPATIBLE_IOCTL(HOT_REMOVE_DISK) +COMPATIBLE_IOCTL(SET_ARRAY_INFO) +COMPATIBLE_IOCTL(SET_DISK_INFO) +COMPATIBLE_IOCTL(WRITE_RAID_INFO) +COMPATIBLE_IOCTL(UNPROTECT_ARRAY) +COMPATIBLE_IOCTL(PROTECT_ARRAY) +COMPATIBLE_IOCTL(HOT_ADD_DISK) +COMPATIBLE_IOCTL(SET_DISK_FAULTY) + +/* usage */ +COMPATIBLE_IOCTL(RUN_ARRAY) +COMPATIBLE_IOCTL(START_ARRAY) +COMPATIBLE_IOCTL(STOP_ARRAY) +COMPATIBLE_IOCTL(STOP_ARRAY_RO) +COMPATIBLE_IOCTL(RESTART_ARRAY_RW) #endif /* CONFIG_MD */ +#ifdef CONFIG_SIBYTE_TBPROF +COMPATIBLE_IOCTL(SBPROF_ZBSTART), +COMPATIBLE_IOCTL(SBPROF_ZBSTOP), +COMPATIBLE_IOCTL(SBPROF_ZBWAITFULL), +#endif /* CONFIG_SIBYTE_TBPROF */ + #if defined(CONFIG_BLK_DEV_DM) || defined(CONFIG_BLK_DEV_DM_MODULE) IOCTL32_DEFAULT(DM_VERSION), IOCTL32_DEFAULT(DM_REMOVE_ALL), @@ -800,25 +1167,44 @@ IOCTL32_DEFAULT(DM_TARGET_WAIT), #endif /* CONFIG_BLK_DEV_DM */ - IOCTL32_DEFAULT(MTIOCTOP), /* mtio.h ioctls */ - IOCTL32_HANDLER(MTIOCGET32, mt_ioctl_trans), - IOCTL32_HANDLER(MTIOCPOS32, mt_ioctl_trans), - IOCTL32_HANDLER(MTIOCGETCONFIG32, mt_ioctl_trans), - IOCTL32_HANDLER(MTIOCSETCONFIG32, mt_ioctl_trans), - // MTIOCRDFTSEG - // MTIOCWRFTSEG - // MTIOCVOLINFO - // MTIOCGETSIZE - // MTIOCFTFORMAT - // MTIOCFTCMD - - IOCTL32_DEFAULT(AUTOFS_IOC_READY), /* auto_fs.h ioctls */ - IOCTL32_DEFAULT(AUTOFS_IOC_FAIL), - IOCTL32_DEFAULT(AUTOFS_IOC_CATATONIC), - IOCTL32_DEFAULT(AUTOFS_IOC_PROTOVER), - IOCTL32_HANDLER(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout), - IOCTL32_DEFAULT(AUTOFS_IOC_EXPIRE) -}; +COMPATIBLE_IOCTL(MTIOCTOP) /* mtio.h ioctls */ +HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans) +HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans) +HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans) +HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans) +// MTIOCRDFTSEG +// MTIOCWRFTSEG +// MTIOCVOLINFO +// MTIOCGETSIZE +// MTIOCFTFORMAT +// MTIOCFTCMD + +COMPATIBLE_IOCTL(AUTOFS_IOC_READY) /* auto_fs.h ioctls */ +COMPATIBLE_IOCTL(AUTOFS_IOC_FAIL) +COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) +COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) +HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) +COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) +COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) + +/* Little p (/dev/rtc, /dev/envctrl, etc.) */ +COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ +COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ +COMPATIBLE_IOCTL(RTC_AIE_ON) +COMPATIBLE_IOCTL(RTC_AIE_OFF) +COMPATIBLE_IOCTL(RTC_UIE_ON) +COMPATIBLE_IOCTL(RTC_UIE_OFF) +COMPATIBLE_IOCTL(RTC_PIE_ON) +COMPATIBLE_IOCTL(RTC_PIE_OFF) +COMPATIBLE_IOCTL(RTC_WIE_ON) +COMPATIBLE_IOCTL(RTC_WIE_OFF) +COMPATIBLE_IOCTL(RTC_ALM_SET) +COMPATIBLE_IOCTL(RTC_ALM_READ) +COMPATIBLE_IOCTL(RTC_RD_TIME) +COMPATIBLE_IOCTL(RTC_SET_TIME) +COMPATIBLE_IOCTL(RTC_WKALM_SET) +COMPATIBLE_IOCTL(RTC_WKALM_RD) +IOCTL_TABLE_END -#define NR_IOCTL32_HANDLERS (sizeof(ioctl32_handler_table) / \ - sizeof(ioctl32_handler_table[0])) +#define NR_IOCTL_TRANS (sizeof(ioctl_translations) / \ + sizeof(ioctl_translations[0])) diff -Nru a/arch/mips64/kernel/irq.c b/arch/mips64/kernel/irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/irq.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,984 @@ +/* + * 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. + * + * Code to handle x86 style IRQs plus some generic interrupt stuff. + * + * Copyright (C) 1992 Linus Torvalds + * Copyright (C) 1994 - 2000 Ralf Baechle + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel_stat.h> +#include <linux/module.h> +#include <linux/proc_fs.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/random.h> +#include <linux/sched.h> +#include <linux/seq_file.h> +#include <linux/kallsyms.h> + +#include <asm/atomic.h> +#include <asm/system.h> +#include <asm/uaccess.h> + +/* + * Controller mappings for all interrupt sources: + */ +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { + [0 ... NR_IRQS-1] = { + .handler = &no_irq_type, + .lock = SPIN_LOCK_UNLOCKED + } +}; + +static void register_irq_proc (unsigned int irq); + +/* + * Special irq handlers. + */ + +irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) +{ return IRQ_NONE; } + +/* + * Generic no controller code + */ + +static void enable_none(unsigned int irq) { } +static unsigned int startup_none(unsigned int irq) { return 0; } +static void disable_none(unsigned int irq) { } +static void ack_none(unsigned int irq) +{ + /* + * 'what should we do if we get a hw irq event on an illegal vector'. + * each architecture has to answer this themselves, it doesn't deserve + * a generic callback i think. + */ + printk("unexpected interrupt %d\n", irq); +} + +/* startup is the same as "enable", shutdown is same as "disable" */ +#define shutdown_none disable_none +#define end_none enable_none + +struct hw_interrupt_type no_irq_type = { + "none", + startup_none, + shutdown_none, + enable_none, + disable_none, + ack_none, + end_none +}; + +atomic_t irq_err_count; + +/* + * Generic, controller-independent functions: + */ + +int show_interrupts(struct seq_file *p, void *v) +{ + int i, j; + struct irqaction * action; + unsigned long flags; + + seq_printf(p, " "); + for (j=0; j<NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "CPU%d ",j); + seq_putc(p, '\n'); + + for (i = 0 ; i < NR_IRQS ; i++) { + spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; + if (!action) + goto skip; + seq_printf(p, "%3d: ",i); +#ifndef CONFIG_SMP + seq_printf(p, "%10u ", kstat_irqs(i)); +#else + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); +#endif + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); + + for (action=action->next; action; action = action->next) + seq_printf(p, ", %s", action->name); + + seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&irq_desc[i].lock, flags); + } + seq_putc(p, '\n'); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + + return 0; +} + +#ifdef CONFIG_SMP +inline void synchronize_irq(unsigned int irq) +{ + while (irq_desc[irq].status & IRQ_INPROGRESS) + cpu_relax(); +} +#endif + +/* + * This should really return information about whether + * we should do bottom half handling etc. Right now we + * end up _always_ checking the bottom half, which is a + * waste of time and is not what some drivers would + * prefer. + */ +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) +{ + int status = 1; /* Force the "do bottom halves" bit */ + int retval = 0; + + if (!(action->flags & SA_INTERRUPT)) + local_irq_enable(); + + do { + status |= action->flags; + retval |= action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + local_irq_disable(); + + return retval; +} + +static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret) +{ + struct irqaction *action; + + if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) { + printk(KERN_ERR "irq event %d: bogus return value %x\n", + irq, action_ret); + } else { + printk(KERN_ERR "irq %d: nobody cared!\n", irq); + } + dump_stack(); + printk(KERN_ERR "handlers:\n"); + action = desc->action; + do { + printk(KERN_ERR "[<%p>]", action->handler); + print_symbol(" (%s)", + (unsigned long)action->handler); + printk("\n"); + action = action->next; + } while (action); +} + +static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret) +{ + static int count = 100; + + if (count) { + count--; + __report_bad_irq(irq, desc, action_ret); + } +} + +static int noirqdebug; + +static int __init noirqdebug_setup(char *str) +{ + noirqdebug = 1; + printk("IRQ lockup detection disabled\n"); + return 1; +} + +__setup("noirqdebug", noirqdebug_setup); + +/* + * If 99,900 of the previous 100,000 interrupts have not been handled then + * assume that the IRQ is stuck in some manner. Drop a diagnostic and try to + * turn the IRQ off. + * + * (The other 100-of-100,000 interrupts may have been a correctly-functioning + * device sharing an IRQ with the failing one) + * + * Called under desc->lock + */ +static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret) +{ + if (action_ret != IRQ_HANDLED) { + desc->irqs_unhandled++; + if (action_ret != IRQ_NONE) + report_bad_irq(irq, desc, action_ret); + } + + desc->irq_count++; + if (desc->irq_count < 100000) + return; + + desc->irq_count = 0; + if (desc->irqs_unhandled > 99900) { + /* + * The interrupt is stuck + */ + __report_bad_irq(irq, desc, action_ret); + /* + * Now kill the IRQ + */ + printk(KERN_EMERG "Disabling IRQ #%d\n", irq); + desc->status |= IRQ_DISABLED; + desc->handler->disable(irq); + } + desc->irqs_unhandled = 0; +} + +/* + * Generic enable/disable code: this just calls + * down into the PIC-specific version for the actual + * hardware disable after having gotten the irq + * controller lock. + */ + +/** + * disable_irq_nosync - disable an irq without waiting + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. Unlike disable_irq(), this function does not ensure existing + * instances of the IRQ handler have completed before returning. + * + * This function may be called from IRQ context. + */ + +void inline disable_irq_nosync(unsigned int irq) +{ + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->depth++) { + desc->status |= IRQ_DISABLED; + desc->handler->disable(irq); + } + spin_unlock_irqrestore(&desc->lock, flags); +} + +/** + * disable_irq - disable an irq and wait for completion + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. That is for two disables you need two enables. This + * function waits for any pending IRQ handlers for this interrupt + * to complete before returning. If you use this function while + * holding a resource the IRQ handler may need you will deadlock. + * + * This function may be called - with care - from IRQ context. + */ + +void disable_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + synchronize_irq(irq); +} + +/** + * enable_irq - enable interrupt handling on an irq + * @irq: Interrupt to enable + * + * Re-enables the processing of interrupts on this IRQ line + * providing no disable_irq calls are now in effect. + * + * This function may be called from IRQ context. + */ + +void enable_irq(unsigned int irq) +{ + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + switch (desc->depth) { + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + desc->status = status; + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + desc->status = status | IRQ_REPLAY; + hw_resend_irq(desc->handler,irq); + } + desc->handler->enable(irq); + /* fall-through */ + } + default: + desc->depth--; + break; + case 0: + printk("enable_irq(%u) unbalanced from %p\n", irq, + __builtin_return_address(0)); + } + spin_unlock_irqrestore(&desc->lock, flags); +} + +/* + * do_IRQ handles all normal device IRQ's (the special + * SMP cross-CPU interrupts have their own specific + * handlers). + */ +asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs) +{ + /* + * We ack quickly, we don't want the irq controller + * thinking we're snobs just because some other CPU has + * disabled global interrupts (we have already done the + * INT_ACK cycles, it's too late to try to pretend to the + * controller that we aren't taking the interrupt). + * + * 0 return value means that this irq is already being + * handled by some other CPU. (or is disabled) + */ + int cpu = smp_processor_id(); + irq_desc_t *desc = irq_desc + irq; + struct irqaction * action; + unsigned int status; + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + spin_lock(&desc->lock); + desc->handler->ack(irq); + /* + REPLAY is when Linux resends an IRQ that was dropped earlier + WAITING is used by probe to mark irqs that are being tested + */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + status |= IRQ_PENDING; /* we _want_ to handle it */ + + /* + * If the IRQ is disabled for whatever reason, we cannot + * use the action we have. + */ + action = NULL; + if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) { + action = desc->action; + status &= ~IRQ_PENDING; /* we commit to handling */ + status |= IRQ_INPROGRESS; /* we are handling it */ + } + desc->status = status; + + /* + * If there is no IRQ handler or it was disabled, exit early. + Since we set PENDING, if another processor is handling + a different instance of this same irq, the other processor + will take care of it. + */ + if (unlikely(!action)) + goto out; + + /* + * Edge triggered interrupts need to remember + * pending events. + * This applies to any hw interrupts that allow a second + * instance of the same irq to arrive while we are in do_IRQ + * or in the handler. But the code here only handles the _second_ + * instance of the irq, not the third or fourth. So it is mostly + * useful for irq hardware that does not mask cleanly in an + * SMP environment. + */ + for (;;) { + irqreturn_t action_ret; + + spin_unlock(&desc->lock); + action_ret = handle_IRQ_event(irq, ®s, action); + spin_lock(&desc->lock); + if (!noirqdebug) + note_interrupt(irq, desc, action_ret); + if (likely(!(desc->status & IRQ_PENDING))) + break; + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; + +out: + /* + * The ->end() handler has to deal with interrupts which got + * disabled while the handler was running. + */ + desc->handler->end(irq); + spin_unlock(&desc->lock); + + irq_exit(); + + return 1; +} + +/** + * request_irq - allocate an interrupt line + * @irq: Interrupt line to allocate + * @handler: Function to be called when the IRQ occurs + * @irqflags: Interrupt type flags + * @devname: An ascii name for the claiming device + * @dev_id: A cookie passed back to the handler function + * + * This call allocates interrupt resources and enables the + * interrupt line and IRQ handling. From the point this + * call is made your handler function may be invoked. Since + * your handler function must clear any interrupt the board + * raises, you must take care both to initialise your hardware + * and to set up the interrupt handler in the right order. + * + * Dev_id must be globally unique. Normally the address of the + * device data structure is used as the cookie. Since the handler + * receives this value it makes sense to use it. + * + * If your interrupt is shared you must pass a non NULL dev_id + * as this is required when freeing the interrupt. + * + * Flags: + * + * SA_SHIRQ Interrupt is shared + * + * SA_INTERRUPT Disable local interrupts while processing + * + * SA_SAMPLE_RANDOM The interrupt can be used for entropy + * + */ + +int request_irq(unsigned int irq, + irqreturn_t (*handler)(int, void *, struct pt_regs *), + unsigned long irqflags, + const char * devname, + void *dev_id) +{ + int retval; + struct irqaction * action; + +#if 1 + /* + * Sanity-check: shared interrupts should REALLY pass in + * a real dev-ID, otherwise we'll have trouble later trying + * to figure out which interrupt is which (messes up the + * interrupt freeing logic etc). + */ + if (irqflags & SA_SHIRQ) { + if (!dev_id) + printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]); + } +#endif + + if (irq >= NR_IRQS) + return -EINVAL; + if (!handler) + return -EINVAL; + + action = (struct irqaction *) + kmalloc(sizeof(struct irqaction), GFP_ATOMIC); + if (!action) + return -ENOMEM; + + action->handler = handler; + action->flags = irqflags; + action->mask = 0; + action->name = devname; + action->next = NULL; + action->dev_id = dev_id; + + retval = setup_irq(irq, action); + if (retval) + kfree(action); + return retval; +} + +/** + * free_irq - free an interrupt + * @irq: Interrupt line to free + * @dev_id: Device identity to free + * + * Remove an interrupt handler. The handler is removed and if the + * interrupt line is no longer in use by any driver it is disabled. + * On a shared IRQ the caller must ensure the interrupt is disabled + * on the card it drives before calling this function. The function + * does not return until any executing interrupts for this IRQ + * have completed. + * + * This function must not be called from interrupt context. + */ + +void free_irq(unsigned int irq, void *dev_id) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + if (irq >= NR_IRQS) + return; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != dev_id) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + desc->handler->shutdown(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + + /* Wait to make sure it's not being used on another CPU */ + synchronize_irq(irq); + kfree(action); + return; + } + printk("Trying to free free IRQ%d\n",irq); + spin_unlock_irqrestore(&desc->lock,flags); + return; + } +} + +/* + * IRQ autodetection code.. + * + * This depends on the fact that any interrupt that + * comes in on to an unassigned handler will get stuck + * with "IRQ_WAITING" cleared and the interrupt + * disabled. + */ + +static DECLARE_MUTEX(probe_sem); + +/** + * probe_irq_on - begin an interrupt autodetect + * + * Commence probing for an interrupt. The interrupts are scanned + * and a mask of potential interrupt lines is returned. + * + */ + +unsigned long probe_irq_on(void) +{ + unsigned int i; + irq_desc_t *desc; + unsigned long val; + unsigned long delay; + + down(&probe_sem); + /* + * something may have generated an irq long ago and we want to + * flush such a longstanding irq before considering it as spurious. + */ + for (i = NR_IRQS-1; i > 0; i--) { + desc = irq_desc + i; + + spin_lock_irq(&desc->lock); + if (!irq_desc[i].action) + irq_desc[i].handler->startup(i); + spin_unlock_irq(&desc->lock); + } + + /* Wait for longstanding interrupts to trigger. */ + for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) + /* about 20ms delay */ barrier(); + + /* + * enable any unassigned irqs + * (we must startup again here because if a longstanding irq + * happened in the previous stage, it may have masked itself) + */ + for (i = NR_IRQS-1; i > 0; i--) { + desc = irq_desc + i; + + spin_lock_irq(&desc->lock); + if (!desc->action) { + desc->status |= IRQ_AUTODETECT | IRQ_WAITING; + if (desc->handler->startup(i)) + desc->status |= IRQ_PENDING; + } + spin_unlock_irq(&desc->lock); + } + + /* + * Wait for spurious interrupts to trigger + */ + for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) + /* about 100ms delay */ barrier(); + + /* + * Now filter out any obviously spurious interrupts + */ + val = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + /* It triggered already - consider it spurious. */ + if (!(status & IRQ_WAITING)) { + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } else + if (i < 32) + val |= 1 << i; + } + spin_unlock_irq(&desc->lock); + } + + return val; +} + +/* + * Return a mask of triggered interrupts (this + * can handle only legacy ISA interrupts). + */ + +/** + * probe_irq_mask - scan a bitmap of interrupt lines + * @val: mask of interrupts to consider + * + * Scan the ISA bus interrupt lines and return a bitmap of + * active interrupts. The interrupt probe logic state is then + * returned to its previous value. + * + * Note: we need to scan all the irq's even though we will + * only return ISA irq numbers - just so that we reset them + * all to a known state. + */ +unsigned int probe_irq_mask(unsigned long val) +{ + int i; + unsigned int mask; + + mask = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + if (i < 16 && !(status & IRQ_WAITING)) + mask |= 1 << i; + + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); + } + up(&probe_sem); + + return mask & val; +} + +/* + * Return the one interrupt that triggered (this can + * handle any interrupt source). + */ + +/** + * probe_irq_off - end an interrupt autodetect + * @val: mask of potential interrupts (unused) + * + * Scans the unused interrupt lines and returns the line which + * appears to have triggered the interrupt. If no interrupt was + * found then zero is returned. If more than one interrupt is + * found then minus the first candidate is returned to indicate + * their is doubt. + * + * The interrupt probe logic state is returned to its previous + * value. + * + * BUGS: When used in a module (which arguably shouldnt happen) + * nothing prevents two IRQ probe callers from overlapping. The + * results of this are non-optimal. + */ + +int probe_irq_off(unsigned long val) +{ + int i, irq_found, nr_irqs; + + nr_irqs = 0; + irq_found = 0; + for (i = 0; i < NR_IRQS; i++) { + irq_desc_t *desc = irq_desc + i; + unsigned int status; + + spin_lock_irq(&desc->lock); + status = desc->status; + + if (status & IRQ_AUTODETECT) { + if (!(status & IRQ_WAITING)) { + if (!nr_irqs) + irq_found = i; + nr_irqs++; + } + desc->status = status & ~IRQ_AUTODETECT; + desc->handler->shutdown(i); + } + spin_unlock_irq(&desc->lock); + } + up(&probe_sem); + + if (nr_irqs > 1) + irq_found = -irq_found; + return irq_found; +} + +/* this was setup_x86_irq but it seems pretty generic */ +int setup_irq(unsigned int irq, struct irqaction * new) +{ + int shared = 0; + unsigned long flags; + struct irqaction *old, **p; + irq_desc_t *desc = irq_desc + irq; + + /* + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. + */ + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); + } + + /* + * The following block of code has to be executed atomically + */ + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->depth = 0; + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); + desc->handler->startup(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + + register_irq_proc(irq); + return 0; +} + +void __init init_generic_irq(void) +{ + int i; + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &no_irq_type; + } +} + +EXPORT_SYMBOL(disable_irq_nosync); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(probe_irq_mask); + +static struct proc_dir_entry * root_irq_dir; +static struct proc_dir_entry * irq_dir [NR_IRQS]; + +#define HEX_DIGITS 8 + +static unsigned int parse_hex_value (const char *buffer, + unsigned long count, unsigned long *ret) +{ + unsigned char hexnum [HEX_DIGITS]; + unsigned long value; + int i; + + if (!count) + return -EINVAL; + if (count > HEX_DIGITS) + count = HEX_DIGITS; + if (copy_from_user(hexnum, buffer, count)) + return -EFAULT; + + /* + * Parse the first 8 characters as a hex string, any non-hex char + * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. + */ + value = 0; + + for (i = 0; i < count; i++) { + unsigned int c = hexnum[i]; + + switch (c) { + case '0' ... '9': c -= '0'; break; + case 'a' ... 'f': c -= 'a'-10; break; + case 'A' ... 'F': c -= 'A'-10; break; + default: + goto out; + } + value = (value << 4) | c; + } +out: + *ret = value; + return 0; +} + +#ifdef CONFIG_SMP + +static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; + +static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +static int irq_affinity_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + if (count < HEX_DIGITS+1) + return -EINVAL; + return sprintf (page, "%08lx\n", irq_affinity[(long)data]); +} + +static int irq_affinity_write_proc (struct file *file, const char *buffer, + unsigned long count, void *data) +{ + int irq = (long) data, full_count = count, err; + unsigned long new_value; + + if (!irq_desc[irq].handler->set_affinity) + return -EIO; + + err = parse_hex_value(buffer, count, &new_value); + + /* + * Do not allow disabling IRQs completely - it's a too easy + * way to make the system unusable accidentally :-) At least + * one online CPU still has to be targeted. + */ + if (!(new_value & cpu_online_map)) + return -EINVAL; + + irq_affinity[irq] = new_value; + irq_desc[irq].handler->set_affinity(irq, new_value); + + return full_count; +} + +#endif + +static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + unsigned long *mask = (unsigned long *) data; + if (count < HEX_DIGITS+1) + return -EINVAL; + return sprintf (page, "%08lx\n", *mask); +} + +static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long *mask = (unsigned long *) data, full_count = count, err; + unsigned long new_value; + + err = parse_hex_value(buffer, count, &new_value); + if (err) + return err; + + *mask = new_value; + return full_count; +} + +#define MAX_NAMELEN 10 + +static void register_irq_proc (unsigned int irq) +{ + char name [MAX_NAMELEN]; + + if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) || + irq_dir[irq]) + return; + + memset(name, 0, MAX_NAMELEN); + sprintf(name, "%d", irq); + + /* create /proc/irq/1234 */ + irq_dir[irq] = proc_mkdir(name, root_irq_dir); + +#ifdef CONFIG_SMP + { + struct proc_dir_entry *entry; + + /* create /proc/irq/1234/smp_affinity */ + entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); + + if (entry) { + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + } + + smp_affinity_entry[irq] = entry; + } +#endif +} + +unsigned long prof_cpu_mask = -1; + +void init_irq_proc (void) +{ + struct proc_dir_entry *entry; + int i; + + /* create /proc/irq */ + root_irq_dir = proc_mkdir("irq", 0); + + /* create /proc/irq/prof_cpu_mask */ + entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); + + if (!entry) + return; + + entry->nlink = 1; + entry->data = (void *)&prof_cpu_mask; + entry->read_proc = prof_cpu_mask_read_proc; + entry->write_proc = prof_cpu_mask_write_proc; + + /* + * Create entries for all existing IRQs. + */ + for (i = 0; i < NR_IRQS; i++) + register_irq_proc(i); +} diff -Nru a/arch/mips64/kernel/irq_cpu.c b/arch/mips64/kernel/irq_cpu.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/irq_cpu.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,116 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Copyright (C) 2001 Ralf Baechle + * + * This file define the irq handler for MIPS CPU interrupts. + * + * 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. + */ + +/* + * Almost all MIPS CPUs define 8 interrupt sources. They are typically + * level triggered (i.e., cannot be cleared from CPU; must be cleared from + * device). The first two are software interrupts which we don't really + * use or support. The last one is usually cpu timer interrupt if a counter + * register is present. + * + * Don't even think about using this on SMP. You have been warned. + * + * This file exports one global function: + * mips_cpu_irq_init(u32 irq_base); + */ +#include <linux/interrupt.h> +#include <linux/types.h> +#include <linux/kernel.h> + +#include <asm/mipsregs.h> +#include <asm/system.h> + +static int mips_cpu_irq_base; + +static inline void unmask_mips_irq(unsigned int irq) +{ + clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); + set_c0_status(0x100 << (irq - mips_cpu_irq_base)); +} + +static inline void mask_mips_irq(unsigned int irq) +{ + clear_c0_status(0x100 << (irq - mips_cpu_irq_base)); +} + +static inline void mips_cpu_irq_enable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + unmask_mips_irq(irq); + local_irq_restore(flags); +} + +static void mips_cpu_irq_disable(unsigned int irq) +{ + unsigned long flags; + + local_irq_save(flags); + mask_mips_irq(irq); + local_irq_restore(flags); +} + +static unsigned int mips_cpu_irq_startup(unsigned int irq) +{ + mips_cpu_irq_enable(irq); + + return 0; +} + +#define mips_cpu_irq_shutdown mips_cpu_irq_disable + +/* + * While we ack the interrupt interrupts are disabled and thus we don't need + * to deal with concurrency issues. Same for mips_cpu_irq_end. + */ +static void mips_cpu_irq_ack(unsigned int irq) +{ + /* Only necessary for soft interrupts */ + clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8)); + + mask_mips_irq(irq); +} + +static void mips_cpu_irq_end(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + unmask_mips_irq(irq); +} + +static hw_irq_controller mips_cpu_irq_controller = { + "CPU_irq", + mips_cpu_irq_startup, + mips_cpu_irq_shutdown, + mips_cpu_irq_enable, + mips_cpu_irq_disable, + mips_cpu_irq_ack, + mips_cpu_irq_end, + NULL /* no affinity stuff for UP */ +}; + + +void mips_cpu_irq_init(u32 irq_base) +{ + u32 i; + + for (i = irq_base; i < irq_base + 8; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &mips_cpu_irq_controller; + } + + mips_cpu_irq_base = irq_base; +} diff -Nru a/arch/mips64/kernel/linux32.c b/arch/mips64/kernel/linux32.c --- a/arch/mips64/kernel/linux32.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips64/kernel/linux32.c Fri Jun 27 14:19:58 2003 @@ -1,10 +1,11 @@ -/* +/* * Conversion between 32-bit and 64-bit native system calls. * * Copyright (C) 2000 Silicon Graphics, Inc. * Written by Ulf Carlsson (ulfc@engr.sgi.com) * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com) */ +#include <linux/config.h> #include <linux/mm.h> #include <linux/errno.h> #include <linux/file.h> @@ -14,6 +15,7 @@ #include <linux/resource.h> #include <linux/highmem.h> #include <linux/time.h> +#include <linux/times.h> #include <linux/poll.h> #include <linux/slab.h> #include <linux/skbuff.h> @@ -21,29 +23,52 @@ #include <linux/shm.h> #include <linux/sem.h> #include <linux/msg.h> +#include <linux/icmpv6.h> #include <linux/sysctl.h> +#include <linux/utime.h> #include <linux/utsname.h> #include <linux/personality.h> #include <linux/timex.h> #include <linux/dnotify.h> +#include <linux/module.h> +#include <linux/binfmts.h> +#include <linux/security.h> #include <linux/compat.h> #include <linux/vfs.h> + #include <net/sock.h> +#include <net/scm.h> +#include <asm/ipc.h> #include <asm/uaccess.h> +#include <asm/mmu_context.h> #include <asm/mman.h> -#include <asm/ipc.h> - +/* Use this to get at 32-bit user passed pointers. */ +/* A() macro should be used for places where you e.g. + have some internal variable u32 and just want to get + rid of a compiler warning. AA() has to be used in + places where you want to convert a function argument + to 32bit pointer or when you e.g. access pt_regs + structure and want to consider 32bit registers only. + */ #define A(__x) ((unsigned long)(__x)) +#define AA(__x) ((unsigned long)((int)__x)) + +#ifdef __MIPSEB__ +#define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL)) +#endif +#ifdef __MIPSEL__ +#define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) +#endif /* * Revalidate the inode. This is required for proper NFS attribute caching. */ -static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf) +int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf) { - struct stat32 tmp; + struct compat_stat tmp; memset(&tmp, 0, sizeof(tmp)); tmp.st_dev = stat->dev; @@ -54,48 +79,45 @@ SET_STAT_GID(tmp, stat->gid); tmp.st_rdev = stat->rdev; tmp.st_size = stat->size; - tmp.st_atime = stat->atime; - tmp.st_mtime = stat->mtime; - tmp.st_ctime = stat->ctime; + tmp.st_atime = stat->atime.tv_sec; + tmp.st_mtime = stat->mtime.tv_sec; + tmp.st_ctime = stat->ctime.tv_sec; +#ifdef STAT_HAVE_NSEC + tmp.st_atime_nsec = stat->atime.tv_nsec; + tmp.st_mtime_nsec = stat->mtime.tv_nsec; + tmp.st_ctime_nsec = stat->ctime.tv_nsec; +#endif tmp.st_blocks = stat->blocks; tmp.st_blksize = stat->blksize; return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf) -{ - struct kstat stat; - int error = vfs_stat(filename, &stat); - - if (!error) - error = cp_new_stat32(&stat, statbuf); - - return error; -} - -asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf) -{ - struct kstat stat; - int error = vfs_lstat(filename, &stat); - - if (!error) - error = cp_new_stat32(&stat, statbuf); - - return error; -} - -asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 * statbuf) -{ - struct kstat stat; - int error = vfs_fstat(fd, &stat); +asmlinkage unsigned long +sys32_mmap2(unsigned long addr, size_t len, unsigned long prot, + unsigned long flags, unsigned long fd, unsigned long pgoff) +{ + struct file * file = NULL; + unsigned long error; + + error = -EINVAL; + if (!(flags & MAP_ANONYMOUS)) { + error = -EBADF; + file = fget(fd); + if (!file) + goto out; + } + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!error) - error = cp_new_stat32(&stat, statbuf); + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + if (file) + fput(file); +out: return error; } -asmlinkage int sys_mmap2(void) {return 0;} asmlinkage long sys_truncate(const char * path, unsigned long length); @@ -117,7 +139,6 @@ return sys_ftruncate(fd, ((long) high << 32) | low); } -#if 0 /* * count32() counts the number of arguments/envelopes */ @@ -127,15 +148,15 @@ if (argv != NULL) { for (;;) { - u32 p; - /* egcs is stupid */ - if (!access_ok(VERIFY_READ, argv, sizeof (u32))) - return -EFAULT; - __get_user(p,argv); + u32 p; int error; + + error = get_user(p,argv); + if (error) + return error; if (!p) break; argv++; - if(++i > max) + if (++i > max) return -E2BIG; } } @@ -148,7 +169,7 @@ * memory to free pages in kernel mem. These are in a format ready * to be put directly into the top of new user memory. */ -int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm) +int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm) { while (argc-- > 0) { u32 str; @@ -156,13 +177,13 @@ unsigned long pos; if (get_user(str, argv+argc) || !str || - !(len = strnlen_user((char *)A(str), bprm->p))) + !(len = strnlen_user((char *)A(str), bprm->p))) return -EFAULT; - if (bprm->p < len) - return -E2BIG; + if (bprm->p < len) + return -E2BIG; bprm->p -= len; - /* XXX: add architecture specific overflow check here. */ + /* XXX: add architecture specific overflow check here. */ pos = bprm->p; while (len > 0) { @@ -199,7 +220,7 @@ kunmap(page); if (err) - return -EFAULT; + return -EFAULT; pos += bytes_to_copy; str += bytes_to_copy; @@ -209,73 +230,95 @@ return 0; } - /* - * sys_execve32() executes a new program. + * sys32_execve() executes a new program. */ -int do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs) +static inline int +do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs) { struct linux_binprm bprm; - struct dentry * dentry; + struct file * file; int retval; int i; - bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); - memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); + file = open_exec(filename); - dentry = open_namei(filename, 0, 0); - retval = PTR_ERR(dentry); - if (IS_ERR(dentry)) + retval = PTR_ERR(file); + if (IS_ERR(file)) return retval; - bprm.dentry = dentry; + bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); + + bprm.file = file; bprm.filename = filename; bprm.sh_bang = 0; bprm.loader = 0; bprm.exec = 0; - if ((bprm.argc = count32(argv, bprm.p / sizeof(u32))) < 0) { - dput(dentry); - return bprm.argc; - } + bprm.security = NULL; + bprm.mm = mm_alloc(); + retval = -ENOMEM; + if (!bprm.mm) + goto out_file; + + retval = init_new_context(current, bprm.mm); + if (retval < 0) + goto out_mm; + + bprm.argc = count32(argv, bprm.p / sizeof(u32)); + if ((retval = bprm.argc) < 0) + goto out_mm; + + bprm.envc = count32(envp, bprm.p / sizeof(u32)); + if ((retval = bprm.envc) < 0) + goto out_mm; - if ((bprm.envc = count32(envp, bprm.p / sizeof(u32))) < 0) { - dput(dentry); - return bprm.envc; - } + if ((retval = security_bprm_alloc(&bprm))) + goto out; retval = prepare_binprm(&bprm); - if (retval < 0) - goto out; - + if (retval < 0) + goto out; + retval = copy_strings_kernel(1, &bprm.filename, &bprm); - if (retval < 0) - goto out; + if (retval < 0) + goto out; bprm.exec = bprm.p; retval = copy_strings32(bprm.envc, envp, &bprm); - if (retval < 0) - goto out; + if (retval < 0) + goto out; retval = copy_strings32(bprm.argc, argv, &bprm); - if (retval < 0) - goto out; + if (retval < 0) + goto out; - retval = search_binary_handler(&bprm,regs); - if (retval >= 0) + retval = search_binary_handler(&bprm, regs); + if (retval >= 0) { /* execve success */ + security_bprm_free(&bprm); return retval; + } out: /* Something went wrong, return the inode and free the argument pages*/ - if (bprm.dentry) - dput(bprm.dentry); - - /* Assumes that free_page() can take a NULL argument. */ - /* I hope this is ok for all architectures */ - for (i = 0 ; i < MAX_ARG_PAGES ; i++) - if (bprm.page[i]) - __free_page(bprm.page[i]); - + for (i = 0 ; i < MAX_ARG_PAGES ; i++) { + struct page * page = bprm.page[i]; + if (page) + __free_page(page); + } + + if (bprm.security) + security_bprm_free(&bprm); + +out_mm: + mmdrop(bprm.mm); + +out_file: + if (bprm.file) { + allow_write_access(bprm.file); + fput(bprm.file); + } return retval; } @@ -299,84 +342,6 @@ out: return error; } -#else -static int -nargs(unsigned int arg, char **ap) -{ - char *ptr; - int n, ret; - - n = 0; - do { - /* egcs is stupid */ - if (!access_ok(VERIFY_READ, arg, sizeof (unsigned int))) - return -EFAULT; - if (IS_ERR(ret = __get_user((long)ptr,(int *)A(arg)))) - return ret; - if (ap) /* no access_ok needed, we allocated */ - if (IS_ERR(ret = __put_user(ptr, ap++))) - return ret; - arg += sizeof(unsigned int); - n++; - } while (ptr); - return(n - 1); -} - -asmlinkage int -sys32_execve(abi64_no_regargs, struct pt_regs regs) -{ - extern asmlinkage int sys_execve(abi64_no_regargs, struct pt_regs regs); - extern asmlinkage long sys_munmap(unsigned long addr, size_t len); - unsigned int argv = (unsigned int)regs.regs[5]; - unsigned int envp = (unsigned int)regs.regs[6]; - char **av, **ae; - int na, ne, r, len; - char * filename; - - na = nargs(argv, NULL); - if (IS_ERR(na)) - return(na); - ne = nargs(envp, NULL); - if (IS_ERR(ne)) - return(ne); - len = (na + ne + 2) * sizeof(*av); - /* - * kmalloc won't work because the `sys_exec' code will attempt - * to do a `get_user' on the arg list and `get_user' will fail - * on a kernel address (simplifies `get_user'). Instead we - * do an mmap to get a user address. Note that since a successful - * `execve' frees all current memory we only have to do an - * `munmap' if the `execve' failes. - */ - down_write(¤t->mm->mmap_sem); - av = (char **) do_mmap_pgoff(0, 0, len, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, 0); - up_write(¤t->mm->mmap_sem); - - if (IS_ERR(av)) - return (long) av; - ae = av + na + 1; - if (IS_ERR(r = __put_user(0, (av + na)))) - goto out; - if (IS_ERR(r = __put_user(0, (ae + ne)))) - goto out; - if (IS_ERR(r = nargs(argv, av))) - goto out; - if (IS_ERR(r = nargs(envp, ae))) - goto out; - filename = getname((char *) (long)regs.regs[4]); - r = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - - r = do_execve(filename, av, ae, ®s); - putname(filename); - if (IS_ERR(r)) -out: - sys_munmap((unsigned long)av, len); - return(r); -} -#endif struct dirent32 { unsigned int d_ino; @@ -446,8 +411,8 @@ int ru_nswap; int ru_inblock; int ru_oublock; - int ru_msgsnd; - int ru_msgrcv; + int ru_msgsnd; + int ru_msgrcv; int ru_nsignals; int ru_nvcsw; int ru_nivcsw; @@ -457,8 +422,11 @@ put_rusage (struct rusage32 *ru, struct rusage *r) { int err; - - err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); + + if (verify_area(VERIFY_WRITE, ru, sizeof *ru)) + return -EFAULT; + + err = __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec); err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec); err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec); err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec); @@ -476,6 +444,7 @@ err |= __put_user (r->ru_nsignals, &ru->ru_nsignals); err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw); err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw); + return err; } @@ -490,8 +459,8 @@ int ret; unsigned int status; mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); + + set_fs(KERNEL_DS); ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r); set_fs(old_fs); if (put_rusage (ru, &r)) return -EFAULT; @@ -507,139 +476,90 @@ return sys32_wait4(pid, stat_addr, options, NULL); } -#define RLIM_INFINITY32 0x7fffffff -#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) - -struct rlimit32 { - int rlim_cur; - int rlim_max; +struct sysinfo32 { + s32 uptime; + u32 loads[3]; + u32 totalram; + u32 freeram; + u32 sharedram; + u32 bufferram; + u32 totalswap; + u32 freeswap; + u16 procs; + u32 totalhigh; + u32 freehigh; + u32 mem_unit; + char _f[8]; }; -extern asmlinkage int sys_old_getrlimit(unsigned int resource, struct rlimit *rlim); +extern asmlinkage int sys_sysinfo(struct sysinfo *info); -asmlinkage int -sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim) +asmlinkage int sys32_sysinfo(struct sysinfo32 *info) { - struct rlimit r; - int ret; + struct sysinfo s; + int ret, err; mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); - ret = sys_old_getrlimit(resource, &r); + ret = sys_sysinfo(&s); set_fs (old_fs); - if (!ret) { - ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur); - ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max); - } - return ret; -} - -extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim); - -asmlinkage int -sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim) -{ - struct rlimit r; - int ret; - mm_segment_t old_fs = get_fs (); - - if (resource >= RLIM_NLIMITS) return -EINVAL; - if (get_user (r.rlim_cur, &rlim->rlim_cur) || - __get_user (r.rlim_max, &rlim->rlim_max)) + err = put_user (s.uptime, &info->uptime); + err |= __put_user (s.loads[0], &info->loads[0]); + err |= __put_user (s.loads[1], &info->loads[1]); + err |= __put_user (s.loads[2], &info->loads[2]); + err |= __put_user (s.totalram, &info->totalram); + err |= __put_user (s.freeram, &info->freeram); + err |= __put_user (s.sharedram, &info->sharedram); + err |= __put_user (s.bufferram, &info->bufferram); + err |= __put_user (s.totalswap, &info->totalswap); + err |= __put_user (s.freeswap, &info->freeswap); + err |= __put_user (s.procs, &info->procs); + err |= __put_user (s.totalhigh, &info->totalhigh); + err |= __put_user (s.freehigh, &info->freehigh); + err |= __put_user (s.mem_unit, &info->mem_unit); + if (err) return -EFAULT; - if (r.rlim_cur == RLIM_INFINITY32) - r.rlim_cur = RLIM_INFINITY; - if (r.rlim_max == RLIM_INFINITY32) - r.rlim_max = RLIM_INFINITY; - set_fs (KERNEL_DS); - ret = sys_setrlimit(resource, &r); - set_fs (old_fs); return ret; } -struct statfs32 { - int f_type; - int f_bsize; - int f_frsize; - int f_blocks; - int f_bfree; - int f_files; - int f_ffree; - int f_bavail; - __kernel_fsid_t32 f_fsid; - int f_namelen; - int f_spare[6]; +#define RLIM_INFINITY32 0x7fffffff +#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) + +struct rlimit32 { + int rlim_cur; + int rlim_max; }; -static inline int -put_statfs (struct statfs32 *ubuf, struct statfs *kbuf) +#ifdef __MIPSEB__ +asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, + int length_hi, int length_lo) +#endif +#ifdef __MIPSEL__ +asmlinkage long sys32_truncate64(const char * path, unsigned long __dummy, + int length_lo, int length_hi) +#endif { - int err; - - err = put_user (kbuf->f_type, &ubuf->f_type); - err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize); - err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks); - err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree); - err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail); - err |= __put_user (kbuf->f_files, &ubuf->f_files); - err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree); - err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen); - err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]); - err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]); - return err; -} + loff_t length; -extern asmlinkage int sys_statfs(const char * path, struct statfs * buf); + length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; -asmlinkage int -sys32_statfs(const char * path, struct statfs32 *buf) -{ - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_statfs((const char *)path, &s); - set_fs (old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; - return ret; + return sys_truncate(path, length); } -extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf); - -asmlinkage int -sys32_fstatfs(unsigned int fd, struct statfs32 *buf) +#ifdef __MIPSEB__ +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int length_hi, int length_lo) +#endif +#ifdef __MIPSEL__ +asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy, + int length_lo, int length_hi) +#endif { - int ret; - struct statfs s; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_fstatfs(fd, &s); - set_fs (old_fs); - if (put_statfs(buf, &s)) - return -EFAULT; - return ret; -} - -extern asmlinkage int -sys_getrusage(int who, struct rusage *ru); + loff_t length; -asmlinkage int -sys32_getrusage(int who, struct rusage32 *ru) -{ - struct rusage r; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_getrusage(who, &r); - set_fs (old_fs); - if (put_rusage (ru, &r)) - return -EFAULT; + length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo; - return ret; + return sys_ftruncate(fd, length); } static inline long @@ -658,31 +578,7 @@ __put_user(i->tv_usec, &o->tv_usec))); } -asmlinkage unsigned long -sys32_alarm(unsigned int seconds) -{ - struct itimerval it_new, it_old; - unsigned int oldalarm; - - it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; - it_new.it_value.tv_sec = seconds; - it_new.it_value.tv_usec = 0; - do_setitimer(ITIMER_REAL, &it_new, &it_old); - oldalarm = it_old.it_value.tv_sec; - /* ehhh.. We can't return 0 if we have an alarm pending.. */ - /* And we'd better return too much than too little anyway */ - if (it_old.it_value.tv_usec) - oldalarm++; - - return oldalarm; -} - -/* Translations due to time_t size differences. Which affects all - sorts of things, like timeval and itimerval. */ - - extern struct timezone sys_tz; -extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); asmlinkage int sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) @@ -700,14 +596,28 @@ return 0; } +static inline long get_ts32(struct timespec *o, struct compat_timeval *i) +{ + long usec; + + if (!access_ok(VERIFY_READ, i, sizeof(*i))) + return -EFAULT; + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + asmlinkage int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) { - struct timeval ktv; + struct timespec kts; struct timezone ktz; if (tv) { - if (get_tv32(&ktv, tv)) + if (get_ts32(&kts, tv)) return -EFAULT; } if (tz) { @@ -715,16 +625,16 @@ return -EFAULT; } - return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL); + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } extern asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int origin); -extern asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, - unsigned int offset_low, loff_t * result, - unsigned int origin) +asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, + unsigned int offset_low, loff_t * result, + unsigned int origin) { return sys_llseek(fd, offset_high, offset_low, result, origin); } @@ -805,7 +715,7 @@ /* VERIFY_WRITE actually means a read, as we write to user space */ fn = file->f_op->read; if (type == VERIFY_READ) - fn = (IO_fn_t) file->f_op->write; + fn = (IO_fn_t) file->f_op->write; ivp = iov; while (count > 0) { void * base; @@ -876,11 +786,12 @@ non-seekable files. */ asmlinkage ssize_t sys32_pread(unsigned int fd, char * buf, - size_t count, u32 unused, loff_t pos) + size_t count, u32 unused, u64 a4, u64 a5) { ssize_t ret; struct file * file; ssize_t (*read)(struct file *, char *, size_t, loff_t *); + loff_t pos; ret = -EBADF; file = fget(fd); @@ -888,6 +799,7 @@ goto bad_file; if (!(file->f_mode & FMODE_READ)) goto out; + pos = merge_64(a4, a5); ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode, file, pos, count); if (ret) @@ -907,11 +819,12 @@ } asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char * buf, - size_t count, u32 unused, loff_t pos) + size_t count, u32 unused, u64 a4, u64 a5) { ssize_t ret; struct file * file; ssize_t (*write)(struct file *, const char *, size_t, loff_t *); + loff_t pos; ret = -EBADF; file = fget(fd); @@ -919,6 +832,7 @@ goto bad_file; if (!(file->f_mode & FMODE_WRITE)) goto out; + pos = merge_64(a4, a5); ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode, file, pos, count); if (ret) @@ -945,7 +859,6 @@ static inline int get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset) { -#ifdef __MIPSEB__ if (ufdset) { unsigned long odd; @@ -972,9 +885,6 @@ memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32)); } return 0; -#else - <<Bomb - little endian support must define this>> -#endif } static inline void @@ -1047,7 +957,7 @@ /* * We need 6 bitmaps (in/out/ex for both incoming and outgoing), * since we used fdset we need to allocate memory in units of - * long-words. + * long-words. */ ret = -ENOMEM; size = FDS_BYTES(n); @@ -1105,15 +1015,15 @@ extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, - struct timespec *interval); + struct timespec *interval); -asmlinkage int -sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct compat_timespec *interval) +asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, + struct compat_timespec *interval) { struct timespec t; int ret; mm_segment_t old_fs = get_fs (); - + set_fs (KERNEL_DS); ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); @@ -1123,113 +1033,6 @@ return ret; } - -struct tms32 { - int tms_utime; - int tms_stime; - int tms_cutime; - int tms_cstime; -}; - -extern asmlinkage long sys_times(struct tms * tbuf); -asmlinkage long sys32_times(struct tms32 *tbuf) -{ - struct tms t; - long ret; - mm_segment_t old_fs = get_fs(); - int err; - - set_fs(KERNEL_DS); - ret = sys_times(tbuf ? &t : NULL); - set_fs(old_fs); - if (tbuf) { - err = put_user (t.tms_utime, &tbuf->tms_utime); - err |= __put_user (t.tms_stime, &tbuf->tms_stime); - err |= __put_user (t.tms_cutime, &tbuf->tms_cutime); - err |= __put_user (t.tms_cstime, &tbuf->tms_cstime); - if (err) - ret = -EFAULT; - } - return ret; -} - -struct flock32 { - short l_type; - short l_whence; - __kernel_off_t32 l_start; - __kernel_off_t32 l_len; - __kernel_pid_t32 l_pid; - short __unused; -}; - -static inline int get_flock(struct flock *kfl, struct flock32 *ufl) -{ - int err; - - err = get_user(kfl->l_type, &ufl->l_type); - err |= __get_user(kfl->l_whence, &ufl->l_whence); - err |= __get_user(kfl->l_start, &ufl->l_start); - err |= __get_user(kfl->l_len, &ufl->l_len); - err |= __get_user(kfl->l_pid, &ufl->l_pid); - return err; -} - -static inline int put_flock(struct flock *kfl, struct flock32 *ufl) -{ - int err; - - err = __put_user(kfl->l_type, &ufl->l_type); - err |= __put_user(kfl->l_whence, &ufl->l_whence); - err |= __put_user(kfl->l_start, &ufl->l_start); - err |= __put_user(kfl->l_len, &ufl->l_len); - err |= __put_user(kfl->l_pid, &ufl->l_pid); - return err; -} - -extern asmlinkage long -sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); - -asmlinkage long -sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case F_GETLK: - case F_SETLK: - case F_SETLKW: - { - struct flock f; - mm_segment_t old_fs; - long ret; - - if (get_flock(&f, (struct flock32 *)arg)) - return -EFAULT; - old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_fcntl(fd, cmd, (unsigned long)&f); - set_fs (old_fs); - if (put_flock(&f, (struct flock32 *)arg)) - return -EFAULT; - return ret; - } - default: - return sys_fcntl(fd, cmd, (unsigned long)arg); - } -} - -asmlinkage long -sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - case F_GETLK64: - return sys_fcntl(fd, F_GETLK, arg); - case F_SETLK64: - return sys_fcntl(fd, F_SETLK, arg); - case F_SETLKW64: - return sys_fcntl(fd, F_SETLKW, arg); - } - - return sys32_fcntl(fd, cmd, arg); -} - struct msgbuf32 { s32 mtype; char mtext[1]; }; struct ipc_perm32 @@ -1243,6 +1046,19 @@ unsigned short seq; }; +struct ipc64_perm32 { + key_t key; + __kernel_uid_t32 uid; + __kernel_gid_t32 gid; + __kernel_uid_t32 cuid; + __kernel_gid_t32 cgid; + __kernel_mode_t32 mode; + unsigned short seq; + unsigned short __pad1; + unsigned int __unused1; + unsigned int __unused2; +}; + struct semid_ds32 { struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ compat_time_t sem_otime; /* last semop time */ @@ -1254,6 +1070,15 @@ unsigned short sem_nsems; /* no. of semaphores in array */ }; +struct semid64_ds32 { + struct ipc64_perm32 sem_perm; + compat_time_t sem_otime; + compat_time_t sem_ctime; + unsigned int sem_nsems; + unsigned int __unused1; + unsigned int __unused2; +}; + struct msqid_ds32 { struct ipc_perm32 msg_perm; @@ -1265,24 +1090,57 @@ u32 wwait; u32 rwait; unsigned short msg_cbytes; - unsigned short msg_qnum; + unsigned short msg_qnum; unsigned short msg_qbytes; __kernel_ipc_pid_t32 msg_lspid; __kernel_ipc_pid_t32 msg_lrpid; }; +struct msqid64_ds32 { + struct ipc64_perm32 msg_perm; + compat_time_t msg_stime; + unsigned int __unused1; + compat_time_t msg_rtime; + unsigned int __unused2; + compat_time_t msg_ctime; + unsigned int __unused3; + unsigned int msg_cbytes; + unsigned int msg_qnum; + unsigned int msg_qbytes; + __kernel_pid_t32 msg_lspid; + __kernel_pid_t32 msg_lrpid; + unsigned int __unused4; + unsigned int __unused5; +}; + struct shmid_ds32 { struct ipc_perm32 shm_perm; int shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - __kernel_ipc_pid_t32 shm_cpid; - __kernel_ipc_pid_t32 shm_lpid; + compat_time_t shm_atime; + compat_time_t shm_dtime; + compat_time_t shm_ctime; + __kernel_ipc_pid_t32 shm_cpid; + __kernel_ipc_pid_t32 shm_lpid; unsigned short shm_nattch; }; -#define IPCOP_MASK(__x) (1UL << (__x)) +struct shmid64_ds32 { + struct ipc64_perm32 shm_perm; + compat_size_t shm_segsz; + compat_time_t shm_atime; + compat_time_t shm_dtime; + compat_time_t shm_ctime; + __kernel_pid_t32 shm_cpid; + __kernel_pid_t32 shm_lpid; + unsigned int shm_nattch; + unsigned int __unused1; + unsigned int __unused2; +}; + +struct ipc_kludge32 { + u32 msgp; + s32 msgtyp; +}; static int do_sys32_semctl(int first, int second, int third, void *uptr) @@ -1291,7 +1149,6 @@ u32 pad; int err, err2; struct semid64_ds s; - struct semid_ds32 *usp; mm_segment_t old_fs; if (!uptr) @@ -1304,7 +1161,6 @@ else fourth.__pad = (void *)A(pad); switch (third & ~IPC_64) { - case IPC_INFO: case IPC_RMID: case IPC_SET: @@ -1321,29 +1177,54 @@ case IPC_STAT: case SEM_STAT: - usp = (struct semid_ds32 *)A(pad); fourth.__pad = &s; old_fs = get_fs (); set_fs (KERNEL_DS); err = sys_semctl (first, second, third, fourth); set_fs (old_fs); - err2 = put_user(s.sem_perm.key, &usp->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, - &usp->sem_perm.cuid); - err2 |= __put_user (s.sem_perm.cgid, - &usp->sem_perm.cgid); - err2 |= __put_user (s.sem_perm.mode, - &usp->sem_perm.mode); - err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq); - err2 |= __put_user (s.sem_otime, &usp->sem_otime); - err2 |= __put_user (s.sem_ctime, &usp->sem_ctime); - err2 |= __put_user (s.sem_nsems, &usp->sem_nsems); + + if (third & IPC_64) { + struct semid64_ds32 *usp64 = (struct semid64_ds32 *) A(pad); + + if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { + err = -EFAULT; + break; + } + err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); + err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); + err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); + err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); + err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); + err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); + err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); + err2 |= __put_user(s.sem_otime, &usp64->sem_otime); + err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); + err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); + } else { + struct semid_ds32 *usp32 = (struct semid_ds32 *) A(pad); + + if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { + err = -EFAULT; + break; + } + err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); + err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); + err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); + err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); + err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); + err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); + err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); + err2 |= __put_user(s.sem_otime, &usp32->sem_otime); + err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); + err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); + } if (err2) err = -EFAULT; break; + default: + err = - EINVAL; + break; } return err; @@ -1352,15 +1233,20 @@ static int do_sys32_msgsnd (int first, int second, int third, void *uptr) { - struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) - + 4, GFP_USER); struct msgbuf32 *up = (struct msgbuf32 *)uptr; + struct msgbuf *p; mm_segment_t old_fs; int err; + if (second < 0) + return -EINVAL; + p = kmalloc (second + sizeof (struct msgbuf) + + 4, GFP_USER); if (!p) return -ENOMEM; err = get_user (p->mtype, &up->mtype); + if (err) + goto out; err |= __copy_from_user (p->mtext, &up->mtext, second); if (err) goto out; @@ -1370,6 +1256,7 @@ set_fs (old_fs); out: kfree (p); + return err; } @@ -1383,18 +1270,21 @@ int err; if (!version) { - struct ipc_kludge *uipck = (struct ipc_kludge *)uptr; - struct ipc_kludge ipck; + struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr; + struct ipc_kludge32 ipck; err = -EINVAL; if (!uptr) goto out; err = -EFAULT; - if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge))) + if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32))) goto out; - uptr = (void *)A(ipck.msgp); + uptr = (void *)AA(ipck.msgp); msgtyp = ipck.msgtyp; } + + if (second < 0) + return -EINVAL; err = -ENOMEM; p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); if (!p) @@ -1419,13 +1309,12 @@ do_sys32_msgctl (int first, int second, void *uptr) { int err = -EINVAL, err2; - struct msqid_ds m; - struct msqid64_ds m64; - struct msqid_ds32 *up = (struct msqid_ds32 *)uptr; + struct msqid64_ds m; + struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr; + struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr; mm_segment_t old_fs; - switch (second) { - + switch (second & ~IPC_64) { case IPC_INFO: case IPC_RMID: case MSG_INFO: @@ -1433,15 +1322,30 @@ break; case IPC_SET: - err = get_user (m.msg_perm.uid, &up->msg_perm.uid); - err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid); - err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode); - err |= __get_user (m.msg_qbytes, &up->msg_qbytes); + if (second & IPC_64) { + if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) { + err = -EFAULT; + break; + } + err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid); + err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid); + err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode); + err |= __get_user(m.msg_qbytes, &up64->msg_qbytes); + } else { + if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) { + err = -EFAULT; + break; + } + err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid); + err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid); + err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode); + err |= __get_user(m.msg_qbytes, &up32->msg_qbytes); + } if (err) break; old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgctl (first, second, &m); + err = sys_msgctl (first, second, (struct msqid_ds *)&m); set_fs (old_fs); break; @@ -1449,27 +1353,54 @@ case MSG_STAT: old_fs = get_fs (); set_fs (KERNEL_DS); - err = sys_msgctl (first, second, (void *) &m64); + err = sys_msgctl (first, second, (struct msqid_ds *)&m); set_fs (old_fs); - err2 = put_user (m64.msg_perm.key, &up->msg_perm.key); - err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid); - err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid); - err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid); - err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid); - err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode); - err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq); - err2 |= __put_user(m64.msg_stime, &up->msg_stime); - err2 |= __put_user(m64.msg_rtime, &up->msg_rtime); - err2 |= __put_user(m64.msg_ctime, &up->msg_ctime); - err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes); - err2 |= __put_user(m64.msg_qnum, &up->msg_qnum); - err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes); - err2 |= __put_user(m64.msg_lspid, &up->msg_lspid); - err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid); - if (err2) - err = -EFAULT; + if (second & IPC_64) { + if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { + err = -EFAULT; + break; + } + err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key); + err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid); + err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid); + err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid); + err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid); + err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode); + err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq); + err2 |= __put_user(m.msg_stime, &up64->msg_stime); + err2 |= __put_user(m.msg_rtime, &up64->msg_rtime); + err2 |= __put_user(m.msg_ctime, &up64->msg_ctime); + err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes); + err2 |= __put_user(m.msg_qnum, &up64->msg_qnum); + err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes); + err2 |= __put_user(m.msg_lspid, &up64->msg_lspid); + err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid); + if (err2) + err = -EFAULT; + } else { + if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { + err = -EFAULT; + break; + } + err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key); + err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid); + err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid); + err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid); + err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid); + err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode); + err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq); + err2 |= __put_user(m.msg_stime, &up32->msg_stime); + err2 |= __put_user(m.msg_rtime, &up32->msg_rtime); + err2 |= __put_user(m.msg_ctime, &up32->msg_ctime); + err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes); + err2 |= __put_user(m.msg_qnum, &up32->msg_qnum); + err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes); + err2 |= __put_user(m.msg_lspid, &up32->msg_lspid); + err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid); + if (err2) + err = -EFAULT; + } break; - } return err; @@ -1499,7 +1430,8 @@ int err = -EFAULT, err2; struct shmid_ds s; struct shmid64_ds s64; - struct shmid_ds32 *up = (struct shmid_ds32 *)uptr; + struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr; + struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr; mm_segment_t old_fs; struct shm_info32 { int used_ids; @@ -1508,18 +1440,24 @@ } *uip = (struct shm_info32 *)uptr; struct shm_info si; - switch (second) { - + switch (second & ~IPC_64) { case IPC_INFO: + second = IPC_INFO; /* So that we don't have to translate it */ case IPC_RMID: case SHM_LOCK: case SHM_UNLOCK: err = sys_shmctl (first, second, (struct shmid_ds *)uptr); break; case IPC_SET: - err = get_user (s.shm_perm.uid, &up->shm_perm.uid); - err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid); - err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode); + if (second & IPC_64) { + err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); + err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); + err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); + } else { + err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); + err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); + err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); + } if (err) break; old_fs = get_fs (); @@ -1536,23 +1474,45 @@ set_fs (old_fs); if (err < 0) break; - err2 = put_user (s64.shm_perm.key, &up->shm_perm.key); - err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid); - err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid); - err2 |= __put_user (s64.shm_perm.cuid, - &up->shm_perm.cuid); - err2 |= __put_user (s64.shm_perm.cgid, - &up->shm_perm.cgid); - err2 |= __put_user (s64.shm_perm.mode, - &up->shm_perm.mode); - err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq); - err2 |= __put_user (s64.shm_atime, &up->shm_atime); - err2 |= __put_user (s64.shm_dtime, &up->shm_dtime); - err2 |= __put_user (s64.shm_ctime, &up->shm_ctime); - err2 |= __put_user (s64.shm_segsz, &up->shm_segsz); - err2 |= __put_user (s64.shm_nattch, &up->shm_nattch); - err2 |= __put_user (s64.shm_cpid, &up->shm_cpid); - err2 |= __put_user (s64.shm_lpid, &up->shm_lpid); + if (second & IPC_64) { + if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { + err = -EFAULT; + break; + } + err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); + err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); + err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); + err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); + err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); + err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); + err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); + err2 |= __put_user(s64.shm_atime, &up64->shm_atime); + err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); + err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); + err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); + err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); + err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); + err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); + } else { + if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { + err = -EFAULT; + break; + } + err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); + err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); + err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); + err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); + err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); + err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); + err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); + err2 |= __put_user(s64.shm_atime, &up32->shm_atime); + err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); + err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); + err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); + err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); + err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); + err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); + } if (err2) err = -EFAULT; break; @@ -1576,7 +1536,11 @@ err = -EFAULT; break; + default: + err = -ENOSYS; + break; } + return err; } @@ -1592,7 +1556,7 @@ case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semop (first, (struct sembuf *)A(ptr), + err = sys_semop (first, (struct sembuf *)AA(ptr), second); break; case SEMGET: @@ -1600,36 +1564,36 @@ break; case SEMCTL: err = do_sys32_semctl (first, second, third, - (void *)A(ptr)); + (void *)AA(ptr)); break; case MSGSND: err = do_sys32_msgsnd (first, second, third, - (void *)A(ptr)); + (void *)AA(ptr)); break; case MSGRCV: err = do_sys32_msgrcv (first, second, fifth, third, - version, (void *)A(ptr)); + version, (void *)AA(ptr)); break; case MSGGET: err = sys_msgget ((key_t) first, second); break; case MSGCTL: - err = do_sys32_msgctl (first, second, (void *)A(ptr)); + err = do_sys32_msgctl (first, second, (void *)AA(ptr)); break; case SHMAT: err = do_sys32_shmat (first, second, third, - version, (void *)A(ptr)); + version, (void *)AA(ptr)); break; - case SHMDT: + case SHMDT: err = sys_shmdt ((char *)A(ptr)); break; case SHMGET: err = sys_shmget (first, second, third); break; case SHMCTL: - err = do_sys32_shmctl (first, second, (void *)A(ptr)); + err = do_sys32_shmctl (first, second, (void *)AA(ptr)); break; default: err = -EINVAL; @@ -1650,81 +1614,103 @@ unsigned int __unused[4]; }; -asmlinkage long sys32_sysctl(struct sysctl_args32 *uargs32) -{ - struct __sysctl_args kargs; - struct sysctl_args32 kargs32; - mm_segment_t old_fs; - int name[CTL_MAXNAME]; - size_t oldlen[1]; - int err, ret; - - ret = -EFAULT; - - memset(&kargs, 0, sizeof (kargs)); - - err = get_user(kargs32.name, &uargs32->name); - err |= __get_user(kargs32.nlen, &uargs32->nlen); - err |= __get_user(kargs32.oldval, &uargs32->oldval); - err |= __get_user(kargs32.oldlenp, &uargs32->oldlenp); - err |= __get_user(kargs32.newval, &uargs32->newval); - err |= __get_user(kargs32.newlen, &uargs32->newlen); - if (err) - goto out; +#ifdef CONFIG_SYSCTL - if (kargs32.nlen == 0 || kargs32.nlen >= CTL_MAXNAME) { - ret = -ENOTDIR; - goto out; - } +asmlinkage long sys32_sysctl(struct sysctl_args32 *args) +{ + struct sysctl_args32 tmp; + int error; + size_t oldlen, *oldlenp = NULL; + unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; - kargs.name = name; - kargs.nlen = kargs32.nlen; - if (copy_from_user(kargs.name, (int *)A(kargs32.name), - kargs32.nlen * sizeof(name) / sizeof(name[0]))) - goto out; + if (copy_from_user(&tmp, args, sizeof(tmp))) + return -EFAULT; - if (kargs32.oldval) { - if (!kargs32.oldlenp || get_user(oldlen[0], - (int *)A(kargs32.oldlenp))) + if (tmp.oldval && tmp.oldlenp) { + /* Duh, this is ugly and might not work if sysctl_args + is in read-only memory, but do_sysctl does indirectly + a lot of uaccess in both directions and we'd have to + basically copy the whole sysctl.c here, and + glibc's __sysctl uses rw memory for the structure + anyway. */ + if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || + put_user(oldlen, (size_t *)addr)) return -EFAULT; - kargs.oldlenp = oldlen; - kargs.oldval = kmalloc(oldlen[0], GFP_KERNEL); - if (!kargs.oldval) { - ret = -ENOMEM; - goto out; - } + oldlenp = (size_t *)addr; } - if (kargs32.newval && kargs32.newlen) { - kargs.newval = kmalloc(kargs32.newlen, GFP_KERNEL); - if (!kargs.newval) { - ret = -ENOMEM; - goto out; + lock_kernel(); + error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), + oldlenp, (void *)A(tmp.newval), tmp.newlen); + unlock_kernel(); + if (oldlenp) { + if (!error) { + if (get_user(oldlen, (size_t *)addr) || + put_user(oldlen, (u32 *)A(tmp.oldlenp))) + error = -EFAULT; } - if (copy_from_user(kargs.newval, (int *)A(kargs32.newval), - kargs32.newlen)) - goto out; + copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); } + return error; +} - old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_sysctl(&kargs); - set_fs (old_fs); +#else /* CONFIG_SYSCTL */ - if (ret) - goto out; +asmlinkage long sys32_sysctl(struct sysctl_args32 *args) +{ + return -ENOSYS; +} + +#endif /* CONFIG_SYSCTL */ + +extern asmlinkage int sys_sched_setaffinity(pid_t pid, unsigned int len, + unsigned long *user_mask_ptr); - if (kargs.oldval) { - if (put_user(oldlen[0], (int *)A(kargs32.oldlenp)) || - copy_to_user((int *)A(kargs32.oldval), kargs.oldval, - oldlen[0])) +asmlinkage int sys32_sched_setaffinity(__kernel_pid_t32 pid, unsigned int len, + u32 *user_mask_ptr) +{ + unsigned long kernel_mask; + mm_segment_t old_fs; + int ret; + + if (get_user(kernel_mask, user_mask_ptr)) + return -EFAULT; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_sched_setaffinity(pid, + /* XXX Nice api... */ + sizeof(kernel_mask), + &kernel_mask); + set_fs(old_fs); + + return ret; +} + +extern asmlinkage int sys_sched_getaffinity(pid_t pid, unsigned int len, + unsigned long *user_mask_ptr); + +asmlinkage int sys32_sched_getaffinity(__kernel_pid_t32 pid, unsigned int len, + u32 *user_mask_ptr) +{ + unsigned long kernel_mask; + mm_segment_t old_fs; + int ret; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_sched_getaffinity(pid, + /* XXX Nice api... */ + sizeof(kernel_mask), + &kernel_mask); + set_fs(old_fs); + + if (ret == 0) { + if (put_user(kernel_mask, user_mask_ptr)) ret = -EFAULT; } -out: - if (kargs.oldval) - kfree(kargs.oldval); - if (kargs.newval) - kfree(kargs.newval); - return ret; + + return ret; } asmlinkage long sys32_newuname(struct new_utsname * name) @@ -1780,7 +1766,7 @@ memset(&txc, 0, sizeof(struct timex)); - if(get_user(txc.modes, &utp->modes) || + if (get_user(txc.modes, &utp->modes) || __get_user(txc.offset, &utp->offset) || __get_user(txc.freq, &utp->freq) || __get_user(txc.maxerror, &utp->maxerror) || @@ -1804,7 +1790,7 @@ ret = do_adjtimex(&txc); - if(put_user(txc.modes, &utp->modes) || + if (put_user(txc.modes, &utp->modes) || __put_user(txc.offset, &utp->offset) || __put_user(txc.freq, &utp->freq) || __put_user(txc.maxerror, &utp->maxerror) || @@ -1829,3 +1815,31 @@ return ret; } +extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count); + +asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count) +{ + mm_segment_t old_fs = get_fs(); + int ret; + off_t of; + + if (offset && get_user(of, offset)) + return -EFAULT; + + set_fs(KERNEL_DS); + ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); + set_fs(old_fs); + + if (offset && put_user(of, offset)) + return -EFAULT; + + return ret; +} + +asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count); + +asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, + size_t count) +{ + return sys_readahead(fd, merge_64(a2, a3), count); +} diff -Nru a/arch/mips64/kernel/mips64_ksyms.c b/arch/mips64/kernel/mips64_ksyms.c --- a/arch/mips64/kernel/mips64_ksyms.c Fri Jun 27 14:19:55 2003 +++ b/arch/mips64/kernel/mips64_ksyms.c Fri Jun 27 14:19:55 2003 @@ -13,9 +13,9 @@ #include <linux/string.h> #include <linux/mm.h> #include <linux/interrupt.h> -#include <asm/irq.h> #include <linux/in6.h> #include <linux/pci.h> +#include <linux/tty.h> #include <asm/bootinfo.h> #include <asm/dma.h> @@ -38,7 +38,10 @@ extern long __strnlen_user_asm(const char *s); EXPORT_SYMBOL(mips_machtype); + +#ifdef CONFIG_EISA EXPORT_SYMBOL(EISA_bus); +#endif /* * String functions @@ -53,12 +56,9 @@ EXPORT_SYMBOL_NOVERS(strncat); EXPORT_SYMBOL_NOVERS(strnlen); EXPORT_SYMBOL_NOVERS(strrchr); -EXPORT_SYMBOL_NOVERS(strsep); EXPORT_SYMBOL_NOVERS(strpbrk); EXPORT_SYMBOL(_clear_page); -EXPORT_SYMBOL(enable_irq); -EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(kernel_thread); /* @@ -74,43 +74,16 @@ EXPORT_SYMBOL_NOVERS(__strnlen_user_asm); -/* - * Functions to control caches. - */ -EXPORT_SYMBOL(_flush_page_to_ram); -EXPORT_SYMBOL(_flush_cache_l1); -#ifndef CONFIG_COHERENT_IO -EXPORT_SYMBOL(_dma_cache_wback_inv); -EXPORT_SYMBOL(_dma_cache_inv); -#endif - EXPORT_SYMBOL(invalid_pte_table); /* - * Base address of ports for Intel style I/O. - */ -#if defined (CONFIG_PCI) || defined (CONFIG_ISA) -EXPORT_SYMBOL(mips_io_port_base); -#endif - -/* * Kernel hacking ... */ #include <asm/branch.h> #include <linux/sched.h> -int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)); -int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)); - -#ifdef CONFIG_MIPS_FPE_MODULE -EXPORT_SYMBOL(__compute_return_epc); -EXPORT_SYMBOL(register_fpe); -EXPORT_SYMBOL(unregister_fpe); -#endif - #ifdef CONFIG_VT EXPORT_SYMBOL(screen_info); #endif EXPORT_SYMBOL(get_wchan); -EXPORT_SYMBOL(_flush_tlb_page); diff -Nru a/arch/mips64/kernel/module.c b/arch/mips64/kernel/module.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/module.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,349 @@ +/* Kernel module help for MIPS. + Copyright (C) 2001 Rusty Russell. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include <linux/moduleloader.h> +#include <linux/elf.h> +#include <linux/vmalloc.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/string.h> +#include <linux/mm.h> + +struct mips_hi16 { + struct mips_hi16 *next; + Elf32_Addr *addr; + Elf32_Addr value; +}; + +static struct mips_hi16 *mips_hi16_list; + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(fmt , ...) +#endif + +static struct vm_struct * modvmlist = NULL; + +void module_unmap(void * addr) +{ + struct vm_struct **p, *tmp; + int i; + + if (!addr) + return; + if ((PAGE_SIZE-1) & (unsigned long) addr) { + printk("Trying to unmap module with bad address (%p)\n", addr); + return; + } + + for (p = &modvmlist ; (tmp = *p) ; p = &tmp->next) { + if (tmp->addr == addr) { + *p = tmp->next; + goto found; + } + } + printk("Trying to unmap nonexistent module vm area (%p)\n", addr); + return; + +found: + unmap_vm_area(tmp); + + for (i = 0; i < tmp->nr_pages; i++) { + if (unlikely(!tmp->pages[i])) + BUG(); + __free_page(tmp->pages[i]); + } + + kfree(tmp->pages); + kfree(tmp); +} + +#define MODULES_LEN (512*1024*1024) /* Random silly large number */ +#define MODULES_END (512*1024*1024) /* Random silly large number */ +#define MODULES_VADDR (512*1024*1024) /* Random silly large number */ + +void *module_map(unsigned long size) +{ + struct vm_struct **p, *tmp, *area; + struct page **pages; + void * addr; + unsigned int nr_pages, array_size, i; + + size = PAGE_ALIGN(size); + if (!size || size > MODULES_LEN) + return NULL; + + addr = (void *) MODULES_VADDR; + for (p = &modvmlist; (tmp = *p) ; p = &tmp->next) { + if (size + (unsigned long) addr < (unsigned long) tmp->addr) + break; + addr = (void *) (tmp->size + (unsigned long) tmp->addr); + } + if ((unsigned long) addr + size >= MODULES_END) + return NULL; + + area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL); + if (!area) + return NULL; + area->size = size + PAGE_SIZE; + area->addr = addr; + area->next = *p; + area->pages = NULL; + area->nr_pages = 0; + area->phys_addr = 0; + *p = area; + + nr_pages = size >> PAGE_SHIFT; + array_size = (nr_pages * sizeof(struct page *)); + + area->nr_pages = nr_pages; + area->pages = pages = kmalloc(array_size, GFP_KERNEL); + if (!area->pages) + goto fail; + + memset(area->pages, 0, array_size); + + for (i = 0; i < area->nr_pages; i++) { + area->pages[i] = alloc_page(GFP_KERNEL); + if (unlikely(!area->pages[i])) + goto fail; + } + + if (map_vm_area(area, PAGE_KERNEL, &pages)) { + unmap_vm_area(area); + goto fail; + } + + return area->addr; + +fail: + if (area->pages) { + for (i = 0; i < area->nr_pages; i++) { + if (area->pages[i]) + __free_page(area->pages[i]); + } + kfree(area->pages); + } + kfree(area); + + return NULL; +} + +void *module_alloc(unsigned long size) +{ + if (size == 0) + return NULL; + return vmalloc(size); +} + + +/* Free memory returned from module_alloc */ +void module_free(struct module *mod, void *module_region) +{ + vfree(module_region); + /* FIXME: If module_region == mod->init_region, trim exception + table entries. */ +} + +/* We don't need anything special. */ +long module_core_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + struct module *module) +{ + return module->core_size; +} + +long module_init_size(const Elf32_Ehdr *hdr, + const Elf32_Shdr *sechdrs, + const char *secstrings, + struct module *module) +{ + return module->init_size; +} + +int module_frob_arch_sections(Elf_Ehdr *hdr, + Elf_Shdr *sechdrs, + char *secstrings, + struct module *mod) +{ + return 0; +} + +int apply_relocate(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + unsigned int i; + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_offset; + Elf32_Sym *sym; + uint32_t *location; + Elf32_Addr v; + + DEBUGP("Applying relocate section %u to %u\n", relsec, + sechdrs[relsec].sh_info); + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { + /* This is where to make the change */ + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_offset + + rel[i].r_offset; + /* This is the symbol it is referring to */ + sym = (Elf32_Sym *)sechdrs[symindex].sh_offset + + ELF32_R_SYM(rel[i].r_info); + if (!sym->st_value) { + printk(KERN_WARNING "%s: Unknown symbol %s\n", + me->name, strtab + sym->st_name); + return -ENOENT; + } + + v = sym->st_value; + + switch (ELF32_R_TYPE(rel[i].r_info)) { + case R_MIPS_NONE: + break; + + case R_MIPS_32: + *location += v; + break; + + case R_MIPS_26: + if (v % 4) + printk(KERN_ERR + "module %s: dangerous relocation\n", + me->name); + return -ENOEXEC; + if ((v & 0xf0000000) != + (((unsigned long)location + 4) & 0xf0000000)) + printk(KERN_ERR + "module %s: relocation overflow\n", + me->name); + return -ENOEXEC; + *location = (*location & ~0x03ffffff) | + ((*location + (v >> 2)) & 0x03ffffff); + break; + + case R_MIPS_HI16: { + struct mips_hi16 *n; + + /* + * We cannot relocate this one now because we don't + * know the value of the carry we need to add. Save + * the information, and let LO16 do the actual + * relocation. + */ + n = (struct mips_hi16 *) kmalloc(sizeof *n, GFP_KERNEL); + n->addr = location; + n->value = v; + n->next = mips_hi16_list; + mips_hi16_list = n; + break; + } + + case R_MIPS_LO16: { + unsigned long insnlo = *location; + Elf32_Addr val, vallo; + + /* Sign extend the addend we extract from the lo insn. */ + vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; + + if (mips_hi16_list != NULL) { + struct mips_hi16 *l; + + l = mips_hi16_list; + while (l != NULL) { + struct mips_hi16 *next; + unsigned long insn; + + /* + * The value for the HI16 had best be + * the same. + */ + printk(KERN_ERR "module %s: dangerous " + "relocation\n", me->name); + return -ENOEXEC; + + /* + * Do the HI16 relocation. Note that + * we actually don't need to know + * anything about the LO16 itself, + * except where to find the low 16 bits + * of the addend needed by the LO16. + */ + insn = *l->addr; + val = ((insn & 0xffff) << 16) + vallo; + val += v; + + /* + * Account for the sign extension that + * will happen in the low bits. + */ + val = ((val >> 16) + ((val & 0x8000) != + 0)) & 0xffff; + + insn = (insn & ~0xffff) | val; + *l->addr = insn; + + next = l->next; + kfree(l); + l = next; + } + + mips_hi16_list = NULL; + } + + /* + * Ok, we're done with the HI16 relocs. Now deal with + * the LO16. + */ + val = v + vallo; + insnlo = (insnlo & ~0xffff) | (val & 0xffff); + *location = insnlo; + break; + } + + default: + printk(KERN_ERR "module %s: Unknown relocation: %u\n", + me->name, ELF32_R_TYPE(rel[i].r_info)); + return -ENOEXEC; + } + } + return 0; +} + +int apply_relocate_add(Elf32_Shdr *sechdrs, + const char *strtab, + unsigned int symindex, + unsigned int relsec, + struct module *me) +{ + printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", + me->name); + return -ENOEXEC; +} + +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + return 0; +} + +void module_arch_cleanup(struct module *mod) +{ +} diff -Nru a/arch/mips64/kernel/offset.c b/arch/mips64/kernel/offset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/offset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,207 @@ +/* + * offset.c: Calculate pt_regs and task_struct offsets. + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * + * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. + */ +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/interrupt.h> + +#include <asm/ptrace.h> +#include <asm/processor.h> + +#define text(t) __asm__("\n@@@" t) +#define _offset(type, member) (&(((type *)NULL)->member)) + +#define offset(string, ptr, member) \ + __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) +#define constant(string, member) \ + __asm__("\n@@@" string "%x0" : : "i" (member)) +#define size(string, size) \ + __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) +#define linefeed text("") + +void output_ptreg_defines(void) +{ + text("/* MIPS pt_regs offsets. */"); + offset("#define PT_R0 ", struct pt_regs, regs[0]); + offset("#define PT_R1 ", struct pt_regs, regs[1]); + offset("#define PT_R2 ", struct pt_regs, regs[2]); + offset("#define PT_R3 ", struct pt_regs, regs[3]); + offset("#define PT_R4 ", struct pt_regs, regs[4]); + offset("#define PT_R5 ", struct pt_regs, regs[5]); + offset("#define PT_R6 ", struct pt_regs, regs[6]); + offset("#define PT_R7 ", struct pt_regs, regs[7]); + offset("#define PT_R8 ", struct pt_regs, regs[8]); + offset("#define PT_R9 ", struct pt_regs, regs[9]); + offset("#define PT_R10 ", struct pt_regs, regs[10]); + offset("#define PT_R11 ", struct pt_regs, regs[11]); + offset("#define PT_R12 ", struct pt_regs, regs[12]); + offset("#define PT_R13 ", struct pt_regs, regs[13]); + offset("#define PT_R14 ", struct pt_regs, regs[14]); + offset("#define PT_R15 ", struct pt_regs, regs[15]); + offset("#define PT_R16 ", struct pt_regs, regs[16]); + offset("#define PT_R17 ", struct pt_regs, regs[17]); + offset("#define PT_R18 ", struct pt_regs, regs[18]); + offset("#define PT_R19 ", struct pt_regs, regs[19]); + offset("#define PT_R20 ", struct pt_regs, regs[20]); + offset("#define PT_R21 ", struct pt_regs, regs[21]); + offset("#define PT_R22 ", struct pt_regs, regs[22]); + offset("#define PT_R23 ", struct pt_regs, regs[23]); + offset("#define PT_R24 ", struct pt_regs, regs[24]); + offset("#define PT_R25 ", struct pt_regs, regs[25]); + offset("#define PT_R26 ", struct pt_regs, regs[26]); + offset("#define PT_R27 ", struct pt_regs, regs[27]); + offset("#define PT_R28 ", struct pt_regs, regs[28]); + offset("#define PT_R29 ", struct pt_regs, regs[29]); + offset("#define PT_R30 ", struct pt_regs, regs[30]); + offset("#define PT_R31 ", struct pt_regs, regs[31]); + offset("#define PT_LO ", struct pt_regs, lo); + offset("#define PT_HI ", struct pt_regs, hi); + offset("#define PT_EPC ", struct pt_regs, cp0_epc); + offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); + offset("#define PT_STATUS ", struct pt_regs, cp0_status); + offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); + size("#define PT_SIZE ", struct pt_regs); + linefeed; +} + +void output_task_defines(void) +{ + text("/* MIPS task_struct offsets. */"); + offset("#define TASK_STATE ", struct task_struct, state); + offset("#define TASK_THREAD_INFO ", struct task_struct, thread_info); + offset("#define TASK_FLAGS ", struct task_struct, flags); + offset("#define TASK_MM ", struct task_struct, mm); + offset("#define TASK_PID ", struct task_struct, pid); + size( "#define TASK_STRUCT_SIZE ", struct task_struct); + linefeed; +} + +void output_thread_info_defines(void) +{ + text("/* MIPS thread_info offsets. */"); + offset("#define TI_TASK ", struct thread_info, task); + offset("#define TI_EXEC_DOMAIN ", struct thread_info, exec_domain); + offset("#define TI_FLAGS ", struct thread_info, flags); + offset("#define TI_CPU ", struct thread_info, cpu); + offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count); + offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); + offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); + linefeed; +} + +void output_thread_defines(void) +{ + text("/* MIPS specific thread_struct offsets. */"); + offset("#define THREAD_REG16 ", struct task_struct, thread.reg16); + offset("#define THREAD_REG17 ", struct task_struct, thread.reg17); + offset("#define THREAD_REG18 ", struct task_struct, thread.reg18); + offset("#define THREAD_REG19 ", struct task_struct, thread.reg19); + offset("#define THREAD_REG20 ", struct task_struct, thread.reg20); + offset("#define THREAD_REG21 ", struct task_struct, thread.reg21); + offset("#define THREAD_REG22 ", struct task_struct, thread.reg22); + offset("#define THREAD_REG23 ", struct task_struct, thread.reg23); + offset("#define THREAD_REG29 ", struct task_struct, thread.reg29); + offset("#define THREAD_REG30 ", struct task_struct, thread.reg30); + offset("#define THREAD_REG31 ", struct task_struct, thread.reg31); + offset("#define THREAD_STATUS ", struct task_struct, \ + thread.cp0_status); + offset("#define THREAD_FPU ", struct task_struct, thread.fpu); + offset("#define THREAD_BVADDR ", struct task_struct, \ + thread.cp0_badvaddr); + offset("#define THREAD_BUADDR ", struct task_struct, \ + thread.cp0_baduaddr); + offset("#define THREAD_ECODE ", struct task_struct, \ + thread.error_code); + offset("#define THREAD_TRAPNO ", struct task_struct, thread.trap_no); + offset("#define THREAD_MFLAGS ", struct task_struct, thread.mflags); + offset("#define THREAD_TRAMP ", struct task_struct, \ + thread.irix_trampoline); + offset("#define THREAD_OLDCTX ", struct task_struct, \ + thread.irix_oldctx); + linefeed; +} + +void output_mm_defines(void) +{ + text("/* Linux mm_struct offsets. */"); + offset("#define MM_USERS ", struct mm_struct, mm_users); + offset("#define MM_PGD ", struct mm_struct, pgd); + offset("#define MM_CONTEXT ", struct mm_struct, context); + linefeed; + constant("#define _PAGE_SIZE ", PAGE_SIZE); + constant("#define _PGD_ORDER ", PGD_ORDER); + constant("#define _PGDIR_SHIFT ", PGDIR_SHIFT); + linefeed; +} + +void output_sc_defines(void) +{ + text("/* Linux sigcontext offsets. */"); + offset("#define SC_REGS ", struct sigcontext, sc_regs); + offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); + offset("#define SC_MDHI ", struct sigcontext, sc_mdhi); + offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); + offset("#define SC_PC ", struct sigcontext, sc_pc); + offset("#define SC_STATUS ", struct sigcontext, sc_status); + offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); + offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); + offset("#define SC_CAUSE ", struct sigcontext, sc_cause); + offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); + linefeed; +} + +void output_signal_defined(void) +{ + text("/* Linux signal numbers. */"); + constant("#define _SIGHUP ", SIGHUP); + constant("#define _SIGINT ", SIGINT); + constant("#define _SIGQUIT ", SIGQUIT); + constant("#define _SIGILL ", SIGILL); + constant("#define _SIGTRAP ", SIGTRAP); + constant("#define _SIGIOT ", SIGIOT); + constant("#define _SIGABRT ", SIGABRT); + constant("#define _SIGEMT ", SIGEMT); + constant("#define _SIGFPE ", SIGFPE); + constant("#define _SIGKILL ", SIGKILL); + constant("#define _SIGBUS ", SIGBUS); + constant("#define _SIGSEGV ", SIGSEGV); + constant("#define _SIGSYS ", SIGSYS); + constant("#define _SIGPIPE ", SIGPIPE); + constant("#define _SIGALRM ", SIGALRM); + constant("#define _SIGTERM ", SIGTERM); + constant("#define _SIGUSR1 ", SIGUSR1); + constant("#define _SIGUSR2 ", SIGUSR2); + constant("#define _SIGCHLD ", SIGCHLD); + constant("#define _SIGPWR ", SIGPWR); + constant("#define _SIGWINCH ", SIGWINCH); + constant("#define _SIGURG ", SIGURG); + constant("#define _SIGIO ", SIGIO); + constant("#define _SIGSTOP ", SIGSTOP); + constant("#define _SIGTSTP ", SIGTSTP); + constant("#define _SIGCONT ", SIGCONT); + constant("#define _SIGTTIN ", SIGTTIN); + constant("#define _SIGTTOU ", SIGTTOU); + constant("#define _SIGVTALRM ", SIGVTALRM); + constant("#define _SIGPROF ", SIGPROF); + constant("#define _SIGXCPU ", SIGXCPU); + constant("#define _SIGXFSZ ", SIGXFSZ); + linefeed; +} + +void output_irq_cpustat_t_defines(void) +{ + text("/* Linux irq_cpustat_t offsets. */"); + offset("#define IC_SOFTIRQ_PENDING ", irq_cpustat_t, __softirq_pending); + offset("#define IC_SYSCALL_COUNT ", irq_cpustat_t, __syscall_count); + offset("#define IC_KSOFTIRQD_TASK ", irq_cpustat_t, __ksoftirqd_task); + size("#define IC_IRQ_CPUSTAT_T ", irq_cpustat_t); + linefeed; +} diff -Nru a/arch/mips64/kernel/pci-dma.c b/arch/mips64/kernel/pci-dma.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/pci-dma.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,62 @@ +/* + * 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) 2000 Ani Joshi <ajoshi@unixbox.com> + * Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org> + * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/pci.h> + +#include <asm/io.h> + +#ifndef UNCAC_BASE /* Hack ... */ +#define UNCAC_BASE 0x9000000000000000UL +#endif + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t * dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + struct pci_bus *bus = NULL; + +#ifdef CONFIG_ISA + if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) + gfp |= GFP_DMA; +#endif + ret = (void *) __get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + if (hwdev) + bus = hwdev->bus; + *dma_handle = bus_to_baddr(bus, __pa(ret)); +#ifdef CONFIG_NONCOHERENT_IO + dma_cache_wback_inv((unsigned long) ret, size); + ret = UNCAC_ADDR(ret); +#endif + } + + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + unsigned long addr = (unsigned long) vaddr; + +#ifdef CONFIG_NONCOHERENT_IO + addr = CAC_ADDR(addr); +#endif + free_pages(addr, get_order(size)); +} + +EXPORT_SYMBOL(pci_alloc_consistent); +EXPORT_SYMBOL(pci_free_consistent); diff -Nru a/arch/mips64/kernel/proc.c b/arch/mips64/kernel/proc.c --- a/arch/mips64/kernel/proc.c Fri Jun 27 14:20:04 2003 +++ b/arch/mips64/kernel/proc.c Fri Jun 27 14:20:04 2003 @@ -1,76 +1,143 @@ /* - * 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. + * linux/arch/mips/kernel/proc.c * - * Copyright (C) 1995, 1996, 1999, 2001 Ralf Baechle - * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 1995, 1996, 2001 Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. */ +#include <linux/config.h> #include <linux/delay.h> #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/smp.h> +#include <linux/seq_file.h> #include <asm/bootinfo.h> +#include <asm/cpu.h> #include <asm/mipsregs.h> #include <asm/processor.h> #include <asm/watch.h> -extern unsigned long unaligned_instructions; unsigned int vced_count, vcei_count; -/* - * BUFFER is PAGE_SIZE bytes long. - * - * Currently /proc/cpuinfo is being abused to print data about the - * number of date/instruction cacheflushes. - */ -int get_cpuinfo(char *buffer) +static const char *cpu_name[] = { + [CPU_UNKNOWN] "unknown", + [CPU_R2000] "R2000", + [CPU_R3000] "R3000", + [CPU_R3000A] "R3000A", + [CPU_R3041] "R3041", + [CPU_R3051] "R3051", + [CPU_R3052] "R3052", + [CPU_R3081] "R3081", + [CPU_R3081E] "R3081E", + [CPU_R4000PC] "R4000PC", + [CPU_R4000SC] "R4000SC", + [CPU_R4000MC] "R4000MC", + [CPU_R4200] "R4200", + [CPU_R4400PC] "R4400PC", + [CPU_R4400SC] "R4400SC", + [CPU_R4400MC] "R4400MC", + [CPU_R4600] "R4600", + [CPU_R6000] "R6000", + [CPU_R6000A] "R6000A", + [CPU_R8000] "R8000", + [CPU_R10000] "R10000", + [CPU_R4300] "R4300", + [CPU_R4650] "R4650", + [CPU_R4700] "R4700", + [CPU_R5000] "R5000", + [CPU_R5000A] "R5000A", + [CPU_R4640] "R4640", + [CPU_NEVADA] "Nevada", + [CPU_RM7000] "RM7000", + [CPU_R5432] "R5432", + [CPU_4KC] "MIPS 4Kc", + [CPU_5KC] "MIPS 5Kc", + [CPU_R4310] "R4310", + [CPU_SB1] "SiByte SB1", + [CPU_TX3912] "TX3912", + [CPU_TX3922] "TX3922", + [CPU_TX3927] "TX3927", + [CPU_AU1000] "Au1000", + [CPU_AU1500] "Au1500", + [CPU_4KEC] "MIPS 4KEc", + [CPU_4KSC] "MIPS 4KSc", + [CPU_VR41XX] "NEC Vr41xx", + [CPU_R5500] "R5500", + [CPU_TX49XX] "TX49xx", + [CPU_20KC] "MIPS 20Kc", + [CPU_VR4111] "NEC VR4111", + [CPU_VR4121] "NEC VR4121", + [CPU_VR4122] "NEC VR4122", + [CPU_VR4131] "NEC VR4131", + [CPU_VR4181] "NEC VR4181", + [CPU_VR4181A] "NEC VR4181A", + [CPU_SR71000] "Sandcraft SR71000" +}; + + +static int show_cpuinfo(struct seq_file *m, void *v) { + unsigned int version = current_cpu_data.processor_id; + unsigned int fp_vers = current_cpu_data.fpu_id; + unsigned long n = (unsigned long) v - 1; char fmt [64]; - size_t len; - len = sprintf(buffer, "cpu\t\t\t: MIPS\n"); -#if 0 - len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n", - cpu_name[mips_cputype <= CPU_LAST ? - mips_cputype : - CPU_UNKNOWN], - (version >> 4) & 0x0f, - version & 0x0f); - len += sprintf(buffer + len, "system type\t\t: %s %s\n", - mach_group_names[mips_machgroup], - mach_group_to_name[mips_machgroup][mips_machtype]); +#ifdef CONFIG_SMP + if (!CPUMASK_TSTB(cpu_online_map, n)) + return 0; #endif - len += sprintf(buffer + len, "BogoMIPS\t\t: %lu.%02lu\n", - (loops_per_jiffy + 2500) / (500000/HZ), - ((loops_per_jiffy + 2500) / (5000/HZ)) % 100); - len += sprintf(buffer + len, "Number of cpus\t\t: %d\n", smp_num_cpus); -#if defined (__MIPSEB__) - len += sprintf(buffer + len, "byteorder\t\t: big endian\n"); -#endif -#if defined (__MIPSEL__) - len += sprintf(buffer + len, "byteorder\t\t: little endian\n"); -#endif - len += sprintf(buffer + len, "unaligned accesses\t: %lu\n", - unaligned_instructions); - len += sprintf(buffer + len, "wait instruction\t: %s\n", - wait_available ? "yes" : "no"); - len += sprintf(buffer + len, "microsecond timers\t: %s\n", - cyclecounter_available ? "yes" : "no"); - len += sprintf(buffer + len, "extra interrupt vector\t: %s\n", - dedicated_iv_available ? "yes" : "no"); - len += sprintf(buffer + len, "hardware watchpoint\t: %s\n", - watch_available ? "yes" : "no"); + + /* + * For the first processor also print the system type + */ + if (n == 0) + seq_printf(m, "system type\t\t: %s\n", get_system_type()); + + seq_printf(m, "processor\t\t: %ld\n", n); + sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", + cpu_has_fpu ? " FPU V%d.%d" : ""); + seq_printf(m, fmt, cpu_name[current_cpu_data.cputype <= CPU_LAST ? + current_cpu_data.cputype : CPU_UNKNOWN], + (version >> 4) & 0x0f, version & 0x0f, + (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); + seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", + loops_per_jiffy / (500000/HZ), + (loops_per_jiffy / (5000/HZ)) % 100); + seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); + seq_printf(m, "microsecond timers\t: %s\n", + cpu_has_counter ? "yes" : "no"); + seq_printf(m, "tlb_entries\t\t: %d\n", current_cpu_data.tlbsize); + seq_printf(m, "extra interrupt vector\t: %s\n", + cpu_has_divec ? "yes" : "no"); + seq_printf(m, "hardware watchpoint\t: %s\n", + cpu_has_watch ? "yes" : "no"); sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", - vce_available ? "%d" : "not available"); - len += sprintf(buffer + len, fmt, 'D', vced_count); - len += sprintf(buffer + len, fmt, 'I', vcei_count); + cpu_has_vce ? "%d" : "not available"); + seq_printf(m, fmt, 'D', vced_count); + seq_printf(m, fmt, 'I', vcei_count); - return len; + return 0; } -void init_irq_proc(void) +static void *c_start(struct seq_file *m, loff_t *pos) { - /* Nothing, for now. */ + unsigned long i = *pos; + + return i < NR_CPUS ? (void *) (i + 1) : NULL; } + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +struct seq_operations cpuinfo_op = { + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; diff -Nru a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c --- a/arch/mips64/kernel/process.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/kernel/process.c Fri Jun 27 14:19:54 2003 @@ -15,9 +15,12 @@ #include <linux/ptrace.h> #include <linux/slab.h> #include <linux/mman.h> +#include <linux/personality.h> #include <linux/sys.h> #include <linux/user.h> #include <linux/a.out.h> +#include <linux/init.h> +#include <linux/completion.h> #include <asm/bootinfo.h> #include <asm/pgtable.h> @@ -28,78 +31,88 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/elf.h> +#include <asm/cpu.h> +#include <asm/fpu.h> +#include <asm/inst.h> -asmlinkage int cpu_idle(void) +/* + * We use this if we don't have any better idle routine.. + * (This to kill: kernel/platform.c. + */ +void default_idle (void) +{ +} + +/* + * The idle thread. There's no useful work to be done, so just try to conserve + * power and have a low exit latency (ie sit in a loop waiting for somebody to + * say that they'd like to reschedule) + */ +ATTRIB_NORET void cpu_idle(void) { /* endless idle loop with no priority at all */ - init_idle(); - current->nice = 20; while (1) { while (!need_resched()) - if (wait_available) - __asm__("wait"); + if (cpu_wait) + (*cpu_wait)(); schedule(); - check_pgt_cache(); } } -struct task_struct *last_task_used_math = NULL; - asmlinkage void ret_from_fork(void); +void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) +{ + unsigned long status; + + /* New thread loses kernel privileges. */ + status = regs->cp0_status & ~(ST0_CU0|ST0_FR|ST0_KSU); + status |= KSU_USER; + status |= (current->thread.mflags & MF_32BIT_REGS) ? 0 : ST0_FR; + regs->cp0_status = status; + current->used_math = 0; + loose_fpu(); + regs->cp0_epc = pc; + regs->regs[29] = sp; + current_thread_info()->addr_limit = USER_DS; +} + void exit_thread(void) { - /* Forget lazy fpu state */ - if (IS_FPU_OWNER()) { - set_cp0_status(ST0_CU1, ST0_CU1); - __asm__ __volatile__("cfc1\t$0,$31"); - CLEAR_FPU_OWNER(); - } } void flush_thread(void) { - /* Forget lazy fpu state */ - if (IS_FPU_OWNER()) { - set_cp0_status(ST0_CU1, ST0_CU1); - __asm__ __volatile__("cfc1\t$0,$31"); - CLEAR_FPU_OWNER(); - } } int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, - unsigned long unused, - struct task_struct * p, struct pt_regs * regs) + unsigned long unused, struct task_struct *p, + struct pt_regs *regs) { - struct pt_regs * childregs; + struct thread_info *ti = p->thread_info; + struct pt_regs *childregs; long childksp; - childksp = (unsigned long)p + KERNEL_STACK_SIZE - 32; + childksp = (unsigned long)ti + KERNEL_STACK_SIZE - 32; - if (IS_FPU_OWNER()) { + if (is_fpu_owner()) { save_fp(p); } + /* set up new TSS. */ childregs = (struct pt_regs *) childksp - 1; *childregs = *regs; childregs->regs[7] = 0; /* Clear error flag */ - if (current->personality == PER_LINUX) { - childregs->regs[2] = 0; /* Child gets zero as return value */ - regs->regs[2] = p->pid; - } else { - /* Under IRIX things are a little different. */ - childregs->regs[2] = 0; - childregs->regs[3] = 1; - regs->regs[2] = p->pid; - regs->regs[3] = 0; - } + childregs->regs[2] = 0; /* Child gets zero as return value */ + regs->regs[2] = p->pid; + if (childregs->cp0_status & ST0_CU0) { - childregs->regs[28] = (unsigned long) p; + childregs->regs[28] = (unsigned long) ti; childregs->regs[29] = childksp; - p->thread.current_ds = KERNEL_DS; + ti->addr_limit = KERNEL_DS; } else { childregs->regs[29] = usp; - p->thread.current_ds = USER_DS; + ti->addr_limit = USER_DS; } p->thread.reg29 = (unsigned long) childregs; p->thread.reg31 = (unsigned long) ret_from_fork; @@ -108,9 +121,9 @@ * New tasks lose permission to use the fpu. This accelerates context * switching for most programs since they don't use the fpu. */ - p->thread.cp0_status = read_32bit_cp0_register(CP0_STATUS) & - ~(ST0_CU3|ST0_CU2|ST0_CU1|ST0_KSU); - childregs->cp0_status &= ~(ST0_CU3|ST0_CU2|ST0_CU1); + p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1|ST0_KSU); + childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); + p->set_child_tid = p->clear_child_tid = NULL; return 0; } @@ -118,32 +131,8 @@ /* Fill in the fpu structure for a core dump.. */ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { - /* We actually store the FPU info in the task->thread - * area. - */ - if(regs->cp0_status & ST0_CU1) { - memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); - return 1; - } - return 0; /* Task didn't use the fpu at all. */ -} - -/* Fill in the user structure for a core dump.. */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; - dump->start_data = current->mm->start_data; - dump->start_stack = regs->regs[29] & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - dump->start_code) - >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk + (PAGE_SIZE - 1) - dump->start_data) - >> PAGE_SHIFT; - dump->u_ssize = (current->mm->start_stack - dump->start_stack + - PAGE_SIZE - 1) >> PAGE_SHIFT; - memcpy(&dump->regs[0], regs, sizeof(struct pt_regs)); - memcpy(&dump->regs[EF_SIZE/4], ¤t->thread.fpu, - sizeof(current->thread.fpu)); + memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } /* @@ -154,29 +143,106 @@ int retval; __asm__ __volatile__( - "move\t$6, $sp\n\t" - "move\t$4, %5\n\t" - "li\t$2, %1\n\t" - "syscall\n\t" - "beq\t$6, $sp, 1f\n\t" - "move\t$4, %3\n\t" - "jalr\t%4\n\t" - "move\t$4, $2\n\t" - "li\t$2, %2\n\t" - "syscall\n" - "1:\tmove\t%0, $2" - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), - "r" (flags | CLONE_VM | CLONE_UNTRACED) - - /* The called subroutine might have destroyed any of the - * at, result, argument or temporary registers ... */ - :"$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", - "$9","$10","$11","$12","$13","$14","$15","$24","$25"); + " move $6, $sp \n" + " move $4, %5 \n" + " li $2, %1 \n" + " syscall \n" + " beq $6, $sp, 1f \n" + " move $4, %3 \n" + " jalr %4 \n" + " move $4, $2 \n" + " li $2, %2 \n" + " syscall \n" + "1: move %0, $2" + : "=r" (retval) + : "i" (__NR_clone), "i" (__NR_exit), "r" (arg), "r" (fn), + "r" (flags | CLONE_VM | CLONE_UNTRACED) + /* + * The called subroutine might have destroyed any of the + * at, result, argument or temporary registers ... + */ + : "$2", "$3", "$4", "$5", "$6", "$7", "$8", + "$9","$10","$11","$12","$13","$14","$15","$24","$25","$31"); return retval; } +struct mips_frame_info { + int frame_offset; + int pc_offset; +}; +static struct mips_frame_info schedule_frame; +static struct mips_frame_info schedule_timeout_frame; +static struct mips_frame_info sleep_on_frame; +static struct mips_frame_info sleep_on_timeout_frame; +static struct mips_frame_info wait_for_completion_frame; +static int mips_frame_info_initialized; +static int __init get_frame_info(struct mips_frame_info *info, void *func) +{ + int i; + union mips_instruction *ip = (union mips_instruction *)func; + info->pc_offset = -1; + info->frame_offset = -1; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; + if (ip->i_format.opcode == sd_op && + ip->i_format.rs == 29) { + /* sd $ra, offset($sp) */ + if (ip->i_format.rt == 31) { + if (info->pc_offset != -1) + break; + info->pc_offset = + ip->i_format.simmediate / sizeof(long); + } + /* sd $s8, offset($sp) */ + if (ip->i_format.rt == 30) { + if (info->frame_offset != -1) + break; + info->frame_offset = + ip->i_format.simmediate / sizeof(long); + } + } + } + if (info->pc_offset == -1 || info->frame_offset == -1) { + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_offset = -1; + return -1; + } + + return 0; +} +void __init frame_info_init(void) +{ + mips_frame_info_initialized = + !get_frame_info(&schedule_frame, schedule) && + !get_frame_info(&schedule_timeout_frame, schedule_timeout) && + !get_frame_info(&sleep_on_frame, sleep_on) && + !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && + !get_frame_info(&wait_for_completion_frame, wait_for_completion); +} + +/* + * Return saved PC of a blocked thread. + */ +unsigned long thread_saved_pc(struct thread_struct *t) +{ + extern void ret_from_fork(void); + + /* New born processes are a special case */ + if (t->reg31 == (unsigned long) ret_from_fork) + return t->reg31; + + if (schedule_frame.pc_offset < 0) + return 0; + return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; +} + /* * These bracket the sleeping functions.. */ @@ -193,6 +259,8 @@ if (!p || p == current || p->state == TASK_RUNNING) return 0; + if (!mips_frame_info_initialized) + return 0; pc = thread_saved_pc(&p->thread); if (pc < first_sched || pc >= last_sched) goto out; @@ -205,30 +273,33 @@ goto schedule_timeout_caller; if (pc >= (unsigned long)interruptible_sleep_on) goto schedule_caller; + if (pc >= (unsigned long)wait_for_completion) + goto schedule_caller; goto schedule_timeout_caller; schedule_caller: - frame = ((unsigned long *)p->thread.reg30)[10]; - pc = ((unsigned long *)frame)[7]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; + if (pc >= (unsigned long) sleep_on) + pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; + else + pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; goto out; schedule_timeout_caller: /* Must be schedule_timeout ... */ - pc = ((unsigned long *)p->thread.reg30)[11]; - frame = ((unsigned long *)p->thread.reg30)[10]; + frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; /* The schedule_timeout frame ... */ - pc = ((unsigned long *)frame)[9]; - frame = ((unsigned long *)frame)[8]; + pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; if (pc >= first_sched && pc < last_sched) { - /* schedule_timeout called by interruptible_sleep_on_timeout */ - pc = ((unsigned long *)frame)[7]; - frame = ((unsigned long *)frame)[6]; + /* schedule_timeout called by [interruptible_]sleep_on_timeout */ + frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; + pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; } out: - if (current->thread.mflags & MF_32BIT) /* Kludge for 32-bit ps */ + if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps */ pc &= 0xffffffff; return pc; diff -Nru a/arch/mips64/kernel/ptrace.c b/arch/mips64/kernel/ptrace.c --- a/arch/mips64/kernel/ptrace.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips64/kernel/ptrace.c Fri Jun 27 14:20:00 2003 @@ -21,12 +21,16 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/user.h> +#include <linux/security.h> +#include <asm/cpu.h> +#include <asm/fpu.h> #include <asm/mipsregs.h> #include <asm/pgtable.h> #include <asm/page.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/bootinfo.h> /* * Called by kernel/ptrace.c when detaching.. @@ -53,6 +57,8 @@ /* are we already being traced? */ if (current->ptrace & PT_PTRACED) goto out; + if ((ret = security_ptrace(current->parent, current))) + goto out; /* set the ptrace bit in the process flags. */ current->ptrace |= PT_PTRACED; ret = 0; @@ -75,18 +81,14 @@ ret = ptrace_attach(child); goto out_tsk; } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out_tsk; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out_tsk; - } - if (child->p_pptr != current) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; + switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned int tmp; int copied; @@ -104,7 +106,7 @@ struct pt_regs *regs; unsigned int tmp; - regs = (struct pt_regs *) ((unsigned long) child + + regs = (struct pt_regs *) ((unsigned long) child->thread_info + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); ret = 0; @@ -114,28 +116,19 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long *fregs = - (void *) child->thread.fpu.hard.fp_regs; - -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - set_cp0_status(ST0_CU1, ST0_CU1); - save_fp(child); - set_cp0_status(ST0_CU1, 0); - last_task_used_math = NULL; - } -#endif + unsigned long long *fregs; + fregs = (unsigned long long *)get_fpu_regs(child); /* * The odd registers are actually the high * order bits of the values stored in the even - * registers. + * registers - unless we're using r2k_switch.S. */ if (addr & 1) tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); else tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); } else { - tmp = -EIO; + tmp = -1; /* FP not yet used */ } break; case PC: @@ -154,14 +147,17 @@ tmp = regs->lo; break; case FPC_CSR: - tmp = child->thread.fpu.hard.control; + if (cpu_has_fpu) + tmp = child->thread.fpu.hard.control; + else + tmp = child->thread.fpu.soft.sr; break; case FPC_EIR: { /* implementation / version register */ unsigned int flags; - local_save_flags(flags); - set_cp0_status(ST0_CU1, ST0_CU1); + flags = read_c0_status(); + __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); - local_irq_restore(flags); + write_c0_status(flags); break; } default: @@ -184,7 +180,7 @@ case PTRACE_POKEUSR: { struct pt_regs *regs; ret = 0; - regs = (struct pt_regs *) ((unsigned long) child + + regs = (struct pt_regs *) ((unsigned long) child->thread_info + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); switch (addr) { @@ -192,19 +188,9 @@ regs->regs[addr] = data; break; case FPR_BASE ... FPR_BASE + 31: { - unsigned long *fregs = - (void *) child->thread.fpu.hard.fp_regs; - if (child->used_math) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - set_cp0_status(ST0_CU1, ST0_CU1); - save_fp(child); - set_cp0_status(ST0_CU1, 0); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } -#endif - } else { + unsigned long long *fregs; + fregs = (unsigned long long *)get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); @@ -217,10 +203,12 @@ */ if (addr & 1) { fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; - fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32; + fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long long) data) << 32; } else { fregs[addr - FPR_BASE] &= ~0xffffffffLL; - fregs[addr - FPR_BASE] |= data; + /* Must cast, lest sign extension fill upper + bits! */ + fregs[addr - FPR_BASE] |= (unsigned int)data; } break; } @@ -234,24 +222,29 @@ regs->lo = data; break; case FPC_CSR: - child->thread.fpu.hard.control = data; + if (cpu_has_fpu) + child->thread.fpu.hard.control = data; + else + child->thread.fpu.soft.sr = data; break; default: /* The rest are not allowed. */ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ ret = -EIO; if ((unsigned int) data > _NSIG) break; - if (request == PTRACE_SYSCALL) - child->ptrace |= PT_TRACESYS; - else - child->ptrace &= ~PT_TRACESYS; + if (request == PTRACE_SYSCALL) { + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + } + else { + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + } child->exit_code = data; wake_up_process(child); ret = 0; @@ -259,8 +252,8 @@ } /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to * exit. */ case PTRACE_KILL: { @@ -281,7 +274,7 @@ } out_tsk: - free_task_struct(child); + put_task_struct(child); out: unlock_kernel(); return ret; @@ -303,6 +296,8 @@ /* are we already being traced? */ if (current->ptrace & PT_PTRACED) goto out; + if ((ret = security_ptrace(current->parent, current))) + goto out; /* set the ptrace bit in the process flags. */ current->ptrace |= PT_PTRACED; ret = 0; @@ -319,25 +314,20 @@ ret = -EPERM; if (pid == 1) /* you may not mess with init */ - goto out; + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out_tsk; } - ret = -ESRCH; - if (!(child->ptrace & PT_PTRACED)) - goto out_tsk; - if (child->state != TASK_STOPPED) { - if (request != PTRACE_KILL) - goto out_tsk; - } - if (child->p_pptr != current) + + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) goto out_tsk; switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp; int copied; @@ -355,7 +345,7 @@ struct pt_regs *regs; unsigned long tmp; - regs = (struct pt_regs *) ((unsigned long) child + + regs = (struct pt_regs *) ((unsigned long) child->thread_info + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); ret = 0; @@ -365,26 +355,8 @@ break; case FPR_BASE ... FPR_BASE + 31: if (child->used_math) { - unsigned long long *fregs - = (unsigned long long *) - &child->thread.fpu.hard.fp_regs[0]; -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - set_cp0_status(ST0_CU1, ST0_CU1); - save_fp(child); - set_cp0_status(ST0_CU1, 0); - last_task_used_math = NULL; - } -#endif - /* - * The odd registers are actually the high - * order bits of the values stored in the even - * registers. - */ - if (addr & 1) - tmp = (unsigned long) (fregs[((addr & ~1) - 32)] >> 32); - else - tmp = (unsigned long) (fregs[(addr - 32)] & 0xffffffff); + unsigned long *fregs = get_fpu_regs(child); + tmp = fregs[addr - FPR_BASE]; } else { tmp = -EIO; } @@ -405,14 +377,17 @@ tmp = regs->lo; break; case FPC_CSR: - tmp = child->thread.fpu.hard.control; + if (cpu_has_fpu) + tmp = child->thread.fpu.hard.control; + else + tmp = child->thread.fpu.soft.sr; break; case FPC_EIR: { /* implementation / version register */ unsigned int flags; - local_save_flags(flags); - set_cp0_status(ST0_CU1, ST0_CU1); + flags = read_c0_status(); + __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); - local_irq_restore(flags); + write_c0_status(flags); break; } default: @@ -435,7 +410,7 @@ case PTRACE_POKEUSR: { struct pt_regs *regs; ret = 0; - regs = (struct pt_regs *) ((unsigned long) child + + regs = (struct pt_regs *) ((unsigned long) child->thread_info + KERNEL_STACK_SIZE - 32 - sizeof(struct pt_regs)); switch (addr) { @@ -443,36 +418,14 @@ regs->regs[addr] = data; break; case FPR_BASE ... FPR_BASE + 31: { - unsigned long *fregs = - (void *) child->thread.fpu.hard.fp_regs; - if (child->used_math) { -#ifndef CONFIG_SMP - if (last_task_used_math == child) { - set_cp0_status(ST0_CU1, ST0_CU1); - save_fp(child); - set_cp0_status(ST0_CU1, 0); - last_task_used_math = NULL; - regs->cp0_status &= ~ST0_CU1; - } -#endif - } else { + unsigned long *fregs = get_fpu_regs(child); + if (!child->used_math) { /* FP not yet used */ memset(&child->thread.fpu.hard, ~0, sizeof(child->thread.fpu.hard)); child->thread.fpu.hard.control = 0; } - /* - * The odd registers are actually the high order bits - * of the values stored in the even registers - unless - * we're using r2k_switch.S. - */ - if (addr & 1) { - fregs[(addr & ~1) - FPR_BASE] &= 0xffffffff; - fregs[(addr & ~1) - FPR_BASE] |= ((unsigned long) data) << 32; - } else { - fregs[addr - FPR_BASE] &= ~0xffffffffLL; - fregs[addr - FPR_BASE] |= data; - } + fregs[addr - FPR_BASE] = data; break; } case PC: @@ -485,24 +438,29 @@ regs->lo = data; break; case FPC_CSR: - child->thread.fpu.hard.control = data; + if (cpu_has_fpu) + child->thread.fpu.hard.control = data; + else + child->thread.fpu.soft.sr = data; break; default: /* The rest are not allowed. */ ret = -EIO; break; } - goto out; + break; } case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ ret = -EIO; if ((unsigned long) data > _NSIG) break; - if (request == PTRACE_SYSCALL) - child->ptrace |= PT_TRACESYS; - else - child->ptrace &= ~PT_TRACESYS; + if (request == PTRACE_SYSCALL) { + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + } + else { + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + } child->exit_code = data; wake_up_process(child); ret = 0; @@ -510,8 +468,8 @@ } /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to * exit. */ case PTRACE_KILL: { @@ -532,25 +490,47 @@ } out_tsk: - free_task_struct(child); + put_task_struct(child); out: unlock_kernel(); return ret; } -asmlinkage void syscall_trace(void) +struct task_work_bf { +#ifdef __MIPSEB__ + signed need_resched :8; + unsigned syscall_trace; /* count of syscall interceptors */ + unsigned sigpending; + unsigned notify_resume; /* request for notification on + userspace execution resumption */ +#endif +#ifdef __MIPSEL__ + unsigned notify_resume : 8; /* request for notification on + userspace execution + resumption */ + unsigned sigpending : 8; + unsigned syscall_trace : 8; /* count of syscall + interceptors */ + signed need_resched : 8; +#endif +}; + +asmlinkage void do_syscall_trace(void) { - if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) - != (PT_PTRACED|PT_TRACESYS)) + if (!test_thread_flag(TIF_SYSCALL_TRACE)) + return; + if (!(current->ptrace & PT_PTRACED)) return; /* The 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0); + preempt_disable(); current->state = TASK_STOPPED; notify_parent(current, SIGCHLD); schedule(); + preempt_enable(); /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the diff -Nru a/arch/mips64/kernel/r4k_fpu.S b/arch/mips64/kernel/r4k_fpu.S --- a/arch/mips64/kernel/r4k_fpu.S Fri Jun 27 14:19:30 2003 +++ b/arch/mips64/kernel/r4k_fpu.S Fri Jun 27 14:19:30 2003 @@ -31,7 +31,7 @@ .set noreorder /* Save floating point context */ -LEAF(save_fp_context) +LEAF(_save_fp_context) mfc0 t1, CP0_STATUS sll t2, t1,5 @@ -79,7 +79,7 @@ jr ra li v0, 0 # success - END(save_fp_context) + END(_save_fp_context) /* * Restore FPU state: @@ -90,7 +90,7 @@ * frame on the current content of c0_status, not on the content of the * stack frame which might have been changed by the user. */ -LEAF(restore_fp_context) +LEAF(_restore_fp_context) mfc0 t1, CP0_STATUS sll t0, t1,5 bgez t0, 1f @@ -139,7 +139,7 @@ ctc1 t0, fcr31 jr ra li v0, 0 # success - END(restore_fp_context) + END(_restore_fp_context) .type fault@function .ent fault diff -Nru a/arch/mips64/kernel/r4k_genex.S b/arch/mips64/kernel/r4k_genex.S --- a/arch/mips64/kernel/r4k_genex.S Fri Jun 27 14:19:58 2003 +++ b/arch/mips64/kernel/r4k_genex.S Fri Jun 27 14:19:58 2003 @@ -5,116 +5,61 @@ * * Copyright (C) 1994 - 1999 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics + * Copyright (C) 2002 Maciej W. Rozycki * * Low level exception handling */ -#define __ASSEMBLY__ #include <linux/init.h> #include <asm/asm.h> #include <asm/regdef.h> #include <asm/fpregdef.h> #include <asm/mipsregs.h> #include <asm/stackframe.h> -#include <asm/r4kcacheops.h> - - .macro __build_clear_none - .endm - - .macro __build_clear_sti - STI - .endm - - .macro __build_clear_cli - CLI - .endm - - .macro __build_clear_fpe - cfc1 a1, fcr31 - li a2, ~(0x3f << 13) - and a2, a1 - ctc1 a2, fcr31 - STI - .endm - - .macro __build_clear_ade - dmfc0 t0, CP0_BADVADDR - sd t0, PT_BVADDR(sp) - KMODE - .endm - - .macro __BUILD_silent exception - .endm - - /* Gas tries to parse the PRINT argument as a string containing - string escapes and emits bogus warnings if it believes to - recognize an unknown escape code. So make the arguments - start with an n and gas will believe \n is ok ... */ - .macro __BUILD_verbose nexception - ld a1, PT_EPC(sp) - PRINT("Got \nexception at %016lx\012") - .endm - - .macro __BUILD_count exception - .set reorder - ld t0,exception_count_\exception - daddiu t0, 1 - sd t0,exception_count_\exception - .set noreorder - .comm exception_count\exception, 8, 8 - .endm - - .macro BUILD_HANDLER exception handler clear verbose - .align 5 - NESTED(handle_\exception, PT_SIZE, sp) - .set noat - SAVE_ALL -#if DEBUG_MIPS64 -jal dodebug2 -ld $4, PT_R4(sp) -ld $5, PT_R5(sp) -ld $6, PT_R6(sp) -ld $7, PT_R7(sp) -ld $2, PT_R2(sp) -#endif - __BUILD_clear_\clear - .set at - __BUILD_\verbose \exception - move a0, sp - jal do_\handler - j ret_from_sys_call - nop - END(handle_\exception) - .endm +#include <asm/exception.h> +#include <asm/cacheops.h> BUILD_HANDLER adel ade ade silent /* #4 */ BUILD_HANDLER ades ade ade silent /* #5 */ - BUILD_HANDLER ibe ibe cli silent /* #6 */ - BUILD_HANDLER dbe dbe cli silent /* #7 */ + BUILD_HANDLER ibe be cli silent /* #6 */ + BUILD_HANDLER dbe be cli silent /* #7 */ BUILD_HANDLER bp bp sti silent /* #9 */ BUILD_HANDLER ri ri sti silent /* #10 */ BUILD_HANDLER cpu cpu sti silent /* #11 */ BUILD_HANDLER ov ov sti silent /* #12 */ BUILD_HANDLER tr tr sti silent /* #13 */ BUILD_HANDLER fpe fpe fpe silent /* #15 */ + BUILD_HANDLER mdmx mdmx sti silent /* #22 */ BUILD_HANDLER watch watch sti verbose /* #23 */ + BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ BUILD_HANDLER reserved reserved sti verbose /* others */ + __INIT +/* A temporary overflow handler used by check_daddi(). */ + + BUILD_HANDLER daddi_ov daddi_ov none silent /* #12 */ + + /* General exception handler for CPUs with virtual coherency exception. * - * Be careful when changing this, it has to be at most 128 bytes to fit - * into space reserved for the exception handler. + * Be careful when changing this, it has to be at most 256 (as a special + * exception) bytes to fit into space reserved for the exception handler. */ - NESTED(except_vec3_r4000, 0, sp) + .set push .set noat +NESTED(except_vec3_r4000, 0, sp) mfc0 k1, CP0_CAUSE - andi k1, k1, 0x7c li k0, 31<<2 + andi k1, k1, 0x7c + .set push + .set noreorder + .set nomacro beq k1, k0, handle_vced li k0, 14<<2 beq k1, k0, handle_vcei dsll k1, k1, 1 + .set pop ld k0, exception_handlers(k1) jr k0 @@ -125,51 +70,110 @@ * store will be re-executed. */ handle_vced: - mfc0 k0, CP0_BADVADDR + dmfc0 k0, CP0_BADVADDR li k1, -4 # Is this ... and k0, k1 # ... really needed? mtc0 zero, CP0_TAGLO cache Index_Store_Tag_D,(k0) cache Hit_Writeback_Inv_SD,(k0) - lui k0, %hi(vced_count) - lw k1, %lo(vced_count)(k0) + dla k0, vced_count + lw k1, (k0) addiu k1, 1 - sw k1, %lo(vced_count)(k0) + sw k1, (k0) eret handle_vcei: - mfc0 k0, CP0_BADVADDR + dmfc0 k0, CP0_BADVADDR cache Hit_Writeback_Inv_SD,(k0) # also cleans pi - lui k0, %hi(vcei_count) - lw k1, %lo(vcei_count)(k0) + dla k0, vcei_count + lw k1, (k0) addiu k1, 1 - sw k1, %lo(vcei_count)(k0) + sw k1, (k0) eret +END(except_vec3_r4000) + .set pop - END(except_vec3_r4000) - .set at - /* General exception vector for all other CPUs. */ - NESTED(except_vec3_generic, 0, sp) +/* General exception vector for all other CPUs. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. + */ + .set push .set noat +NESTED(except_vec3_generic, 0, sp) +#if R5432_CP0_INTERRUPT_WAR + mfc0 k0, CP0_INDEX +#endif mfc0 k1, CP0_CAUSE andi k1, k1, 0x7c dsll k1, k1, 1 ld k0, exception_handlers(k1) jr k0 - nop - END(except_vec3_generic) - .set at +END(except_vec3_generic) + .set pop + /* - * Special interrupt vector for embedded MIPS. This is a dedicated interrupt - * vector which reduces interrupt processing overhead. The jump instruction - * will be inserted here at initialization time. This handler may only be 8 - * bytes in size! + * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. + * This is a dedicated interrupt exception vector which reduces the + * interrupt processing overhead. The jump instruction will be replaced + * at the initialization time. + * + * Be careful when changing this, it has to be at most 128 bytes + * to fit into space reserved for the exception handler. */ NESTED(except_vec4, 0, sp) 1: j 1b /* Dummy, will be replaced */ +END(except_vec4) + + /* + * EJTAG debug exception handler. + * The EJTAG debug exception entry point is 0xbfc00480, which + * normally is in the boot PROM, so the boot PROM must do a + * unconditional jump to this vector. + */ +NESTED(except_vec_ejtag_debug, 0, sp) + j ejtag_debug_handler nop - END(except_vec4) + END(except_vec_ejtag_debug) __FINIT + + /* + * EJTAG debug exception handler. + */ + NESTED(ejtag_debug_handler, PT_SIZE, sp) + .set noat + .set noreorder + mtc0 k0, CP0_DESAVE + mfc0 k0, CP0_DEBUG + + sll k0, k0, 30 # Check for SDBBP. + bgez k0, ejtag_return + + la k0, ejtag_debug_buffer + sw k1, 0(k0) + SAVE_ALL + jal ejtag_exception_handler + move a0, sp + RESTORE_ALL + la k0, ejtag_debug_buffer + lw k1, 0(k0) + +ejtag_return: + mfc0 k0, CP0_DESAVE + .set mips32 + deret + .set mips0 + nop + .set at + END(ejtag_debug_handler) + + /* + * This buffer is reserved for the use of the EJTAG debug + * handler. + */ + .data + EXPORT(ejtag_debug_buffer) + .fill 8 diff -Nru a/arch/mips64/kernel/r4k_switch.S b/arch/mips64/kernel/r4k_switch.S --- a/arch/mips64/kernel/r4k_switch.S Fri Jun 27 14:19:52 2003 +++ b/arch/mips64/kernel/r4k_switch.S Fri Jun 27 14:19:52 2003 @@ -8,11 +8,8 @@ * Copyright (C) 1994, 1995, 1996, by Andreas Busse * Copyright (C) 1999 Silicon Graphics, Inc. */ -#include <linux/config.h> #include <asm/asm.h> -#include <asm/bootinfo.h> #include <asm/cachectl.h> -#include <asm/current.h> #include <asm/fpregdef.h> #include <asm/mipsregs.h> #include <asm/offset.h> @@ -21,15 +18,32 @@ #include <asm/processor.h> #include <asm/regdef.h> #include <asm/stackframe.h> +#include <asm/thread_info.h> #include <asm/asmmacro.h> .set mips3 +/* + * Offset to the current process status flags, the first 32 bytes of the + * stack are not used. + */ +#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) + +/* + * FPU context is saved iff the process has used it's FPU in the current + * time slice as indicated by TIF_USEDFPU. In any case, the CU1 bit for user + * space STATUS register should be 0, so that a process *always* starts its + * userland with FPU disabled after each context switch. + * + * FPU will be enabled as soon as the process accesses FPU again, through + * do_cpu() trap. + */ + /* - * task_struct *resume(task_struct *prev, task_struct *next) + * task_struct *resume(task_struct *prev, task_struct *next, + * struct thread_info *next_ti)) */ - .set noreorder .align 5 LEAF(resume) mfc0 t1, CP0_STATUS @@ -38,86 +52,85 @@ sd ra, THREAD_REG31(a0) /* + * check if we need to save FPU registers + */ + ld t3, TASK_THREAD_INFO(a0) + ld t0, TI_FLAGS(t3) + li t1, TIF_USEDFPU + and t2, t0, t1 + beqz t2, 1f + nor t1, zero, t1 + + and t0, t0, t1 + sd t0, TI_FLAGS(t3) + + /* + * clear saved user stack CU1 bit + */ + ld t0, ST_OFF(t3) + li t1, ~ST0_CU1 + and t0, t0, t1 + sd t0, ST_OFF(t3) + + + sll t2, t0, 5 + bgez t2, 2f + sdc1 $f0, (THREAD_FPU + 0x00)(a0) + fpu_save_16odd a0 +2: + fpu_save_16even a0 t1 # clobbers t1 +1: + + /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. */ - move $28, a1 - cpu_restore_nonscratch $28 -#ifndef CONFIG_SMP - daddiu t0, $28, KERNEL_STACK_SIZE-32 - sd t0, kernelsp -#else - mtc0 a1, CP0_WATCHLO - dsrl32 a1, a1, 0 - mtc0 a1, CP0_WATCHHI -#endif + move $28, a2 + cpu_restore_nonscratch a1 + + daddiu t1, $28, KERNEL_STACK_SIZE-32 + set_saved_sp t1, t0, t2 + mfc0 t1, CP0_STATUS /* Do we really need this? */ li a3, 0xff00 and t1, a3 - ld a2, THREAD_STATUS($28) + ld a2, THREAD_STATUS(a1) nor a3, $0, a3 and a2, a3 or a2, t1 mtc0 a2, CP0_STATUS + move v0, a0 jr ra - move v0, a0 END(resume) /* - * Do lazy fpu context switch. Saves FPU context to the process in a0 - * and loads the new context of the current process. + * Save a thread's fp context. */ - -#define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS) - -LEAF(lazy_fpu_switch) - mfc0 t0, CP0_STATUS # enable cp1 - li t3, 0x20000000 - or t0, t3 - mtc0 t0, CP0_STATUS - - beqz a0, 2f # Save floating point state - nor t3, zero, t3 - - ld t1, ST_OFF(a0) # last thread loses fpu - and t1, t3 - sd t1, ST_OFF(a0) - sll t2, t1, 5 - bgez t2, 1f - sdc1 $f0, (THREAD_FPU + 0x00)(a0) +LEAF(_save_fp) + mfc0 t0, CP0_STATUS + sll t1, t0, 5 + bgez t1, 1f # 16 register mode? fpu_save_16odd a0 1: fpu_save_16even a0 t1 # clobbers t1 -2: - - beqz a1, 3f - - sll t0, t0, 5 # load new fp state - bgez t0, 1f - ldc1 $f0, (THREAD_FPU + 0x00)($28) - fpu_restore_16odd $28 -1: - .set reorder - fpu_restore_16even $28, t0 # clobbers t0 -3: + sdc1 $f0, (THREAD_FPU + 0x00)(a0) jr ra - END(lazy_fpu_switch) + END(_save_fp) /* - * Save a thread's fp context. + * Restore a thread's fp context. */ - .set noreorder -LEAF(save_fp) +LEAF(_restore_fp) mfc0 t0, CP0_STATUS sll t1, t0, 5 bgez t1, 1f # 16 register mode? - nop - fpu_save_16odd a0 -1: - fpu_save_16even a0 t1 # clobbers t1 + + fpu_restore_16odd a0 +1: fpu_restore_16even a0, t0 # clobbers t0 + ldc1 $f0, (THREAD_FPU + 0x00)(a0) + jr ra - sdc1 $f0, (THREAD_FPU + 0x00)(a0) - END(save_fp) + END(_restore_fp) /* * Load the FPU with signalling NANS. This bit pattern we're using has @@ -129,18 +142,19 @@ #define FPU_DEFAULT 0x00000000 -LEAF(init_fpu) +LEAF(_init_fpu) mfc0 t0, CP0_STATUS - li t1, 0x20000000 + li t1, ST0_CU1 or t0, t1 mtc0 t0, CP0_STATUS + FPU_ENABLE_HAZARD sll t0, t0, 5 li t1, FPU_DEFAULT ctc1 t1, fcr31 + li t0, -1 # SNaN bgez t0, 1f # 16 / 32 register mode? - li t0, -1 dmtc1 t0, $f1 dmtc1 t0, $f3 @@ -174,6 +188,6 @@ dmtc1 t0, $f24 dmtc1 t0, $f26 dmtc1 t0, $f28 + dmtc1 t0, $f30 jr ra - dmtc1 t0, $f30 - END(init_fpu) + END(_init_fpu) diff -Nru a/arch/mips64/kernel/r4k_tlb.S b/arch/mips64/kernel/r4k_tlb.S --- a/arch/mips64/kernel/r4k_tlb.S Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,126 +0,0 @@ -/* - * 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) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - */ -#include <linux/config.h> -#include <linux/threads.h> -#include <asm/asm.h> -#include <asm/regdef.h> -#include <asm/mipsregs.h> -#include <asm/pgtable.h> -#include <asm/stackframe.h> - - .data - .comm pgd_current, NR_CPUS * 8, 8 - - /* - * After this macro runs we have a pointer to the pte of the address - * that caused the fault in in PTR. - */ - - .macro LOAD_PTE2, ptr, tmp -#ifdef CONFIG_SMP - dmfc0 \tmp, CP0_CONTEXT - dla \ptr, pgd_current - dsrl \tmp, 23 - daddu \ptr, \tmp -#else - dla \ptr, pgd_current -#endif - dmfc0 \tmp, CP0_BADVADDR - ld \ptr, (\ptr) - bltz \tmp, kaddr - dsrl \tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes - andi \tmp, ((PTRS_PER_PGD - 1)<<3) - daddu \ptr, \tmp # add in pgd offset - dmfc0 \tmp, CP0_BADVADDR - ld \ptr, (\ptr) # get pmd pointer - dsrl \tmp, (PMD_SHIFT-3) # get pmd offset in bytes - andi \tmp, ((PTRS_PER_PMD - 1)<<3) - daddu \ptr, \tmp # add in pmd offset - dmfc0 \tmp, CP0_XCONTEXT - ld \ptr, (\ptr) # get pte pointer - andi \tmp, 0xff0 # get pte offset - daddu \ptr, \tmp - .endm - - /* - * This places the even/odd pte pair in the page table at the pte - * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. - */ - .macro PTE_RELOAD, pte0, pte1 - dsrl \pte0, 6 # convert to entrylo0 - dmtc0 \pte0, CP0_ENTRYLO0 # load it - dsrl \pte1, 6 # convert to entrylo1 - dmtc0 \pte1, CP0_ENTRYLO1 # load it - .endm - - .text - .set noreorder - .set mips3 - - .align 5 -FEXPORT(except_vec0) - .set noat -1: b 1b - nop - - /* TLB refill handler for the R10000. - * Attention: We may only use 32 instructions. - */ - - .align 5 -FEXPORT(except_vec1_r10k) - .set noat - LOAD_PTE2 k1 k0 - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - PTE_RELOAD k0 k1 - nop - tlbwr - eret -kaddr: - dla k0, handle_vmalloc_address # MAPPED kernel needs this - jr k0 - nop - - .align 5 -FEXPORT(handle_vmalloc_address) - .set noat - /* - * First, determine that the address is in/above vmalloc range. - */ - dmfc0 k0, CP0_BADVADDR - dli k1, VMALLOC_START - - /* - * Now find offset into kptbl. - */ - dsubu k0, k0, k1 - dla k1, kptbl - dsrl k0, (PAGE_SHIFT+1) # get vpn2 - dsll k0, 4 # byte offset of pte - daddu k1, k1, k0 - - /* - * Determine that fault address is within vmalloc range. - */ - dla k0, ekptbl - sltu k0, k1, k0 - beqz k0, not_vmalloc - - /* - * Load cp0 registers. - */ - ld k0, 0(k1) # get even pte - ld k1, 8(k1) # get odd pte - -not_vmalloc: - PTE_RELOAD k0 k1 - nop - tlbwr - eret diff -Nru a/arch/mips64/kernel/r4k_tlb_debug.c b/arch/mips64/kernel/r4k_tlb_debug.c --- a/arch/mips64/kernel/r4k_tlb_debug.c Fri Jun 27 14:20:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,71 +0,0 @@ -/* - * 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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - * - * TLB debugging routines. These perform horribly slow but can easily be - * modified for debugging purposes. - */ -#include <linux/linkage.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/ptrace.h> -#include <asm/system.h> - -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, - unsigned long address); - -asmlinkage void tlb_refill_debug(struct pt_regs regs) -{ - show_regs(®s); - panic(__FUNCTION__ " called. This Does Not Happen (TM)."); -} - -asmlinkage void xtlb_refill_debug(struct pt_regs *regs) -{ - unsigned long addr; - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1); - pgd = pgd_offset(current->active_mm, addr); - pmd = pmd_offset(pgd, addr); - pte = pte_offset(pmd, addr); - - set_entrylo0(pte_val(pte[0]) >> 6); - set_entrylo1(pte_val(pte[1]) >> 6); - __asm__ __volatile__("nop;nop;nop"); - - tlb_write_random(); -} - -asmlinkage void xtlb_mod_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} - -asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 0, addr); -} - -asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs) -{ - unsigned long addr; - - addr = regs->cp0_badvaddr; - do_page_fault(regs, 1, addr); -} diff -Nru a/arch/mips64/kernel/r4k_tlb_glue.S b/arch/mips64/kernel/r4k_tlb_glue.S --- a/arch/mips64/kernel/r4k_tlb_glue.S Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,46 +0,0 @@ -/* - * 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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#define __ASSEMBLY__ -#include <linux/init.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - - .macro __BUILD_cli - CLI - .endm - - .macro __BUILD_sti - STI - .endm - - .macro tlb_handler name interruptible writebit - NESTED(__\name, PT_SIZE, sp) - SAVE_ALL -#if DEBUG_MIPS64 -jal dodebug2 -ld $4, PT_R4(sp) -ld $5, PT_R5(sp) -ld $6, PT_R6(sp) -ld $7, PT_R7(sp) -ld $2, PT_R2(sp) -#endif - dmfc0 a2, CP0_BADVADDR - __BUILD_\interruptible - li a1, \writebit - sd a2, PT_BVADDR(sp) - move a0, sp - jal do_page_fault - j ret_from_sys_call - END(__\name) - .endm - - tlb_handler xtlb_mod sti 1 - tlb_handler xtlb_tlbl sti 0 - tlb_handler xtlb_tlbs sti 1 diff -Nru a/arch/mips64/kernel/reset.c b/arch/mips64/kernel/reset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/reset.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,36 @@ +/* + * 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) 2001 by Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/reboot.h> +#include <asm/reboot.h> + +/* + * Urgs ... Too many MIPS machines to handle this in a generic way. + * So handle all using function pointers to machine specific + * functions. + */ +void (*_machine_restart)(char *command); +void (*_machine_halt)(void); +void (*_machine_power_off)(void); + +void machine_restart(char *command) +{ + _machine_restart(command); +} + +void machine_halt(void) +{ + _machine_halt(); +} + +void machine_power_off(void) +{ + _machine_power_off(); +} diff -Nru a/arch/mips64/kernel/scall_64.S b/arch/mips64/kernel/scall_64.S --- a/arch/mips64/kernel/scall_64.S Fri Jun 27 14:19:53 2003 +++ b/arch/mips64/kernel/scall_64.S Fri Jun 27 14:19:53 2003 @@ -3,106 +3,125 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01 by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. */ #include <linux/config.h> #include <asm/asm.h> #include <linux/errno.h> -#include <asm/current.h> #include <asm/mipsregs.h> #include <asm/regdef.h> #include <asm/stackframe.h> +#include <asm/offset.h> #include <asm/unistd.h> +#include <asm/thread_info.h> -/* This duplicates the definition from <linux/sched.h> */ -#define PT_TRACESYS 0x00000002 /* tracing system calls */ - -/* This duplicates the definition from <asm/signal.h> */ -#define SIGILL 4 /* Illegal instruction (ANSI). */ - -#ifndef CONFIG_MIPS32_COMPAT +#ifndef CONFIG_BINFMT_ELF32 +/* Neither O32 nor N32, so define handle_sys here */ #define handle_sys64 handle_sys #endif .align 5 NESTED(handle_sys64, PT_SIZE, sp) -/* When 32-bit compatibility is configured scall_o32.S already did this. */ -#ifndef CONFIG_MIPS32_COMPAT - .set noat - SAVE_SOME - STI - .set at +#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32) + /* + * When 32-bit compatibility is configured scall_o32.S + * already did this. + */ + .set noat + SAVE_SOME + STI + .set at #endif - ld t1, PT_EPC(sp) # skip syscall on return - - subu t0, v0, __NR_Linux # check syscall number - sltiu t0, t0, __NR_Linux_syscalls + 1 - daddiu t1, 4 # skip to next instruction - beqz t0, illegal_syscall - sd t1, PT_EPC(sp) - - dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_Linux * 8))(t0) # syscall routine + ld t1, PT_EPC(sp) # skip syscall on return - sd a3, PT_R26(sp) # save a3 for syscall restarting - - ld t0, TASK_PTRACE($28) # syscall tracing enabled? - andi t0, PT_TRACESYS - bnez t0, trace_a_syscall - - jalr t2 # Do The Real Thing (TM) - - li t0, -EMAXERRNO - 1 # error? - sltu t0, t0, v0 - sd t0, PT_R7(sp) # set error flag - beqz t0, 1f - - negu v0 # error - sd v0, PT_R0(sp) # set flag for syscall restarting -1: sd v0, PT_R2(sp) # result - -ret_from_sys_call: - mfc0 t0, CP0_STATUS - xori t0, t0, 1 - ori t0, t0, 1 - mtc0 t0, CP0_STATUS - -#error ld t2, TASK_NEED_RESCHED($28) - bnez t2, reschedule -#error lw v0, TASK_SIGPENDING($28) - bnez v0, signal_return - -restore_all: - RESTORE_SOME - RESTORE_SP - eret - -/* Put this behind restore_all for the sake of the branch prediction. */ -signal_return: - .type signal_return, @function - - mfc0 t0, CP0_STATUS - ori t0, t0, 1 - mtc0 t0, CP0_STATUS - - move a0, zero - move a1, sp - jal do_signal - b restore_all - -reschedule: - SAVE_STATIC - jal schedule - b ret_from_sys_call + subu t0, v0, __NR_Linux # check syscall number + sltiu t0, t0, __NR_Linux_syscalls + 1 + daddiu t1, 4 # skip to next instruction + beqz t0, illegal_syscall + sd t1, PT_EPC(sp) + + dsll t0, v0, 3 # offset into table + ld t2, (sys_call_table - (__NR_Linux * 8))(t0) + # syscall routine + + sd a3, PT_R26(sp) # save a3 for syscall restarting + + LONG_L t0, TI_FLAGS($28) + bltz t0, syscall_trace_entry # syscall tracing enabled? + + jalr t2 # Do The Real Thing (TM) + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall + # restarting +1: sd v0, PT_R2(sp) # result + +syscall_exit: + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) # current->work + bnez a2, syscall_exit_work + +FEXPORT(restore_all) + RESTORE_SOME + RESTORE_SP + eret + +EXPORT(work_pending) + andi t0, a2, _TIF_NEED_RESCHED + bltz t0, work_notifysig +work_resched: + jal schedule + + mfc0 t0, CP0_STATUS # make sure need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) + andi a2, _TIF_WORK_MASK # is there any work to be done + # other than syscall tracing + beqz a2, restore_all + andi t0, a2, _TIF_NEED_RESCHED + bnez t0, work_resched + +work_notifysig: # deal with pending signals and + # notify-resume requests + SAVE_STATIC + move a0, sp + li a1, 0 + jal do_notify_resume # a2 already loaded + RESTORE_STATIC + j restore_all + +syscall_exit_work: + LONG_L t0, TI_FLAGS($28) # current->work.syscall_trace + bgez t0, work_pending + + mfc0 t0, CP0_STATUS # sti + ori t0, t0, 1 + mtc0 t0, CP0_STATUS + jal do_syscall_trace + j resume_userspace /* ------------------------------------------------------------------------ */ -trace_a_syscall: +syscall_trace_entry: SAVE_STATIC sd t2,PT_R1(sp) - jal syscall_trace + jal do_syscall_trace ld t2,PT_R1(sp) ld a0, PT_R4(sp) # Restore argument registers @@ -120,8 +139,7 @@ sd v0, PT_R0(sp) # set flag for syscall restarting 1: sd v0, PT_R2(sp) # result - jal syscall_trace - j ret_from_sys_call + j syscall_exit illegal_syscall: /* This also isn't a 64-bit syscall, throw an error. */ @@ -129,223 +147,224 @@ sd v0, PT_R2(sp) li t0, 1 # set error flag sd t0, PT_R7(sp) - j ret_from_sys_call + j syscall_exit END(handle_sys64) + .align 3 sys_call_table: - PTR sys_syscall /* 5000 */ - PTR sys_exit - PTR sys_fork - PTR sys_read + PTR sys_read /* 5000 */ PTR sys_write - PTR sys_open /* 5005 */ + PTR sys_open PTR sys_close - PTR sys_waitpid - PTR sys_creat - PTR sys_link - PTR sys_unlink /* 5010 */ - PTR sys_execve - PTR sys_chdir - PTR sys_time - PTR sys_mknod - PTR sys_chmod /* 5015 */ - PTR sys_lchown - PTR sys_ni_syscall - PTR sys_stat + PTR sys_newstat + PTR sys_newfstat /* 5005 */ + PTR sys_newlstat + PTR sys_poll PTR sys_lseek - PTR sys_getpid /* 5020 */ - PTR sys_mount - PTR sys_oldumount - PTR sys_setuid - PTR sys_getuid - PTR sys_stime /* 5025 */ - PTR sys_ni_syscall /* ptrace */ - PTR sys_alarm - PTR sys_fstat + PTR sys_mmap + PTR sys_mprotect /* 5010 */ + PTR sys_munmap + PTR sys_brk + PTR sys_rt_sigaction + PTR sys_rt_sigprocmask + PTR sys_ioctl /* 5015 */ + PTR sys_pread64 + PTR sys_pwrite64 + PTR sys_readv + PTR sys_writev + PTR sys_access /* 5020 */ + PTR sys_pipe + PTR sys_select + PTR sys_sched_yield + PTR sys_mremap + PTR sys_msync /* 5025 */ + PTR sys_mincore + PTR sys_madvise + PTR sys_shmget + PTR sys_shmat + PTR sys_shmctl /* 5030 */ + PTR sys_dup + PTR sys_dup2 PTR sys_pause - PTR sys_utime /* 5030 */ - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_access - PTR sys_nice - PTR sys_ni_syscall /* 5035 */ - PTR sys_sync - PTR sys_kill - PTR sys_rename + PTR sys_nanosleep + PTR sys_getitimer /* 5035 */ + PTR sys_setitimer + PTR sys_alarm + PTR sys_getpid + PTR sys_sendfile + PTR sys_socket /* 5040 */ + PTR sys_connect + PTR sys_accept + PTR sys_sendto + PTR sys_recvfrom + PTR sys_sendmsg /* 5045 */ + PTR sys_recvmsg + PTR sys_shutdown + PTR sys_bind + PTR sys_listen + PTR sys_getsockname /* 5050 */ + PTR sys_getpeername + PTR sys_socketpair + PTR sys_setsockopt + PTR sys_getsockopt + PTR sys_clone /* 5055 */ + PTR sys_fork + PTR sys_execve + PTR sys_exit + PTR sys_wait4 + PTR sys_kill /* 5060 */ + PTR sys_newuname + PTR sys_semget + PTR sys_semop + PTR sys_semctl + PTR sys_shmdt /* 5065 */ + PTR sys_msgget + PTR sys_msgsnd + PTR sys_msgrcv + PTR sys_msgctl + PTR sys_fcntl /* 5070 */ + PTR sys_flock + PTR sys_fsync + PTR sys_fdatasync + PTR sys_truncate + PTR sys_ftruncate /* 5075 */ + PTR sys_getdents + PTR sys_getcwd + PTR sys_chdir + PTR sys_fchdir + PTR sys_rename /* 5080 */ PTR sys_mkdir - PTR sys_rmdir /* 5040 */ - PTR sys_dup - PTR sys_pipe + PTR sys_rmdir + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 5085 */ + PTR sys_symlink + PTR sys_readlink + PTR sys_chmod + PTR sys_fchmod + PTR sys_chown /* 5090 */ + PTR sys_fchown + PTR sys_lchown + PTR sys_umask + PTR sys_gettimeofday + PTR sys_getrlimit /* 5095 */ + PTR sys_getrusage + PTR sys_sysinfo PTR sys_times - PTR sys_ni_syscall - PTR sys_brk /* 5045 */ - PTR sys_setgid + PTR sys_ptrace + PTR sys_getuid /* 5100 */ + PTR sys_syslog PTR sys_getgid - PTR sys_ni_syscall /* was signal 2 */ - PTR sys_geteuid - PTR sys_getegid /* 5050 */ - PTR sys_acct - PTR sys_umount - PTR sys_ni_syscall - PTR sys_ioctl - PTR sys_fcntl /* 5055 */ - PTR sys_ni_syscall + PTR sys_setuid + PTR sys_setgid + PTR sys_geteuid /* 5105 */ + PTR sys_getegid PTR sys_setpgid - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_umask /* 5060 */ - PTR sys_chroot - PTR sys_ustat - PTR sys_dup2 PTR sys_getppid - PTR sys_getpgrp /* 5065 */ - PTR sys_setsid - PTR sys_sigaction - PTR sys_sgetmask - PTR sys_ssetmask - PTR sys_setreuid /* 5070 */ + PTR sys_getpgrp + PTR sys_setsid /* 5110 */ + PTR sys_setreuid PTR sys_setregid - PTR sys_sigsuspend - PTR sys_sigpending - PTR sys_sethostname - PTR sys_setrlimit /* 5075 */ - PTR sys_getrlimit - PTR sys_getrusage - PTR sys_gettimeofday - PTR sys_settimeofday - PTR sys_getgroups /* 5080 */ + PTR sys_getgroups PTR sys_setgroups - PTR sys_ni_syscall /* old_select */ - PTR sys_symlink - PTR sys_lstat - PTR sys_readlink /* 5085 */ - PTR sys_uselib - PTR sys_swapon - PTR sys_reboot - PTR sys_ni_syscall /* old_readdir */ - PTR sys_mmap /* 5090 */ - PTR sys_munmap - PTR sys_truncate - PTR sys_ftruncate - PTR sys_fchmod - PTR sys_fchown /* 5095 */ - PTR sys_getpriority - PTR sys_setpriority - PTR sys_ni_syscall - PTR sys_statfs - PTR sys_fstatfs /* 5100 */ - PTR sys_ni_syscall /* sys_ioperm */ - PTR sys_socketcall - PTR sys_syslog - PTR sys_setitimer - PTR sys_getitimer /* 5105 */ - PTR sys_newstat - PTR sys_newlstat - PTR sys_newfstat - PTR sys_ni_syscall - PTR sys_ni_syscall /* sys_ioperm *//* 5110 */ - PTR sys_vhangup - PTR sys_ni_syscall /* was sys_idle */ - PTR sys_ni_syscall /* sys_vm86 */ - PTR sys_wait4 - PTR sys_swapoff /* 5115 */ - PTR sys_sysinfo - PTR sys_ipc - PTR sys_fsync - PTR sys_sigreturn - PTR sys_clone /* 5120 */ - PTR sys_setdomainname - PTR sys_newuname - PTR sys_ni_syscall /* sys_modify_ldt */ - PTR sys_adjtimex - PTR sys_mprotect /* 5125 */ - PTR sys_sigprocmask - PTR sys_create_module - PTR sys_init_module - PTR sys_delete_module - PTR sys_get_kernel_syms /* 5130 */ - PTR sys_quotactl + PTR sys_setresuid /* 5115 */ + PTR sys_getresuid + PTR sys_setresgid + PTR sys_getresgid PTR sys_getpgid - PTR sys_fchdir - PTR sys_bdflush - PTR sys_sysfs /* 5135 */ - PTR sys_personality - PTR sys_ni_syscall /* for afs_syscall */ - PTR sys_setfsuid + PTR sys_setfsuid /* 5120 */ PTR sys_setfsgid - PTR sys_llseek /* 5140 */ - PTR sys_getdents - PTR sys_select - PTR sys_flock - PTR sys_msync - PTR sys_readv /* 5145 */ - PTR sys_writev - PTR sys_cacheflush - PTR sys_cachectl - PTR sys_sysmips - PTR sys_ni_syscall /* 5150 */ PTR sys_getsid - PTR sys_fdatasync - PTR sys_sysctl - PTR sys_mlock - PTR sys_munlock /* 5155 */ - PTR sys_mlockall - PTR sys_munlockall + PTR sys_capget + PTR sys_capset + PTR sys_rt_sigpending /* 5125 */ + PTR sys_rt_sigtimedwait + PTR sys_rt_sigqueueinfo + PTR sys_rt_sigsuspend + PTR sys_sigaltstack + PTR sys_utime /* 5130 */ + PTR sys_mknod + PTR sys_personality + PTR sys_ustat + PTR sys_statfs + PTR sys_fstatfs /* 5135 */ + PTR sys_sysfs + PTR sys_getpriority + PTR sys_setpriority PTR sys_sched_setparam - PTR sys_sched_getparam - PTR sys_sched_setscheduler /* 5160 */ + PTR sys_sched_getparam /* 5140 */ + PTR sys_sched_setscheduler PTR sys_sched_getscheduler - PTR sys_sched_yield PTR sys_sched_get_priority_max PTR sys_sched_get_priority_min - PTR sys_sched_rr_get_interval /* 5165 */ - PTR sys_nanosleep - PTR sys_mremap - PTR sys_accept - PTR sys_bind - PTR sys_connect /* 5170 */ - PTR sys_getpeername - PTR sys_getsockname - PTR sys_getsockopt - PTR sys_listen - PTR sys_recv /* 5175 */ - PTR sys_recvfrom - PTR sys_recvmsg - PTR sys_send - PTR sys_sendmsg - PTR sys_sendto /* 5180 */ - PTR sys_setsockopt - PTR sys_shutdown - PTR sys_socket - PTR sys_socketpair - PTR sys_setresuid /* 5185 */ - PTR sys_getresuid - PTR sys_query_module - PTR sys_poll - PTR sys_nfsservctl - PTR sys_setresgid /* 5190 */ - PTR sys_getresgid + PTR sys_sched_rr_get_interval /* 5145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 5150 */ + PTR sys_pivot_root + PTR sys_sysctl PTR sys_prctl - PTR sys_rt_sigreturn - PTR sys_rt_sigaction - PTR sys_rt_sigprocmask /* 5195 */ - PTR sys_rt_sigpending - PTR sys_rt_sigtimedwait - PTR sys_rt_sigqueueinfo - PTR sys_rt_sigsuspend - PTR sys_pread64 /* 5200 */ - PTR sys_pwrite64 - PTR sys_chown - PTR sys_getcwd - PTR sys_capget - PTR sys_capset /* 5205 */ - PTR sys_sigaltstack - PTR sys_sendfile - PTR sys_ni_syscall - PTR sys_ni_syscall - PTR sys_pivot_root /* 5210 */ - PTR sys_mincore - PTR sys_madvise - PTR sys_getdents64 + PTR sys_adjtimex + PTR sys_setrlimit /* 5155 */ + PTR sys_chroot + PTR sys_sync + PTR sys_acct + PTR sys_settimeofday + PTR sys_mount /* 5160 */ + PTR sys_umount + PTR sys_swapon + PTR sys_swapoff + PTR sys_reboot + PTR sys_sethostname /* 5165 */ + PTR sys_setdomainname + PTR sys_ni_syscall /* was create_module */ + PTR sys_init_module + PTR sys_delete_module + PTR sys_ni_syscall /* 5170, was get_kernel_syms */ + PTR sys_ni_syscall /* was query_module */ + PTR sys_quotactl + PTR sys_nfsservctl + PTR sys_ni_syscall /* res. for getpmsg */ + PTR sys_ni_syscall /* 5175 for putpmsg */ + PTR sys_ni_syscall /* res. for afs_syscall */ + PTR sys_ni_syscall /* res. for security */ PTR sys_gettid + PTR sys_readahead + PTR sys_setxattr /* 5180 */ + PTR sys_lsetxattr + PTR sys_fsetxattr + PTR sys_getxattr + PTR sys_lgetxattr + PTR sys_fgetxattr /* 5185 */ + PTR sys_listxattr + PTR sys_llistxattr + PTR sys_flistxattr + PTR sys_removexattr + PTR sys_lremovexattr /* 5190 */ + PTR sys_fremovexattr PTR sys_tkill + PTR sys_time + PTR sys_futex + PTR sys_sched_setaffinity /* 5195 */ + PTR sys_sched_getaffinity + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_io_setup /* 5200 */ + PTR sys_io_destroy + PTR sys_io_getevents + PTR sys_io_submit + PTR sys_io_cancel + PTR sys_exit_group /* 5205 */ + PTR sys_lookup_dcookie + PTR sys_epoll_create + PTR sys_epoll_ctl + PTR sys_epoll_wait + PTR sys_remap_file_pages /* 5210 */ + PTR sys_rt_sigreturn + PTR sys_set_tid_address + PTR sys_restart_syscall + PTR sys_semtimedop + PTR sys_fadvise64 /* 5215 */ diff -Nru a/arch/mips64/kernel/scall_n32.S b/arch/mips64/kernel/scall_n32.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/scall_n32.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,334 @@ +/* + * 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) 1995, 96, 97, 98, 99, 2000, 01 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#include <linux/config.h> +#include <asm/asm.h> +#include <linux/errno.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/unistd.h> + +/* This duplicates the definition from <linux/sched.h> */ +#define PT_TRACESYS 0x00000002 /* tracing system calls */ + +/* This duplicates the definition from <asm/signal.h> */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ + +#ifndef CONFIG_MIPS32_O32 +/* No O32, so define handle_sys here */ +#define handle_sysn32 handle_sys +#endif + + .align 5 +NESTED(handle_sysn32, PT_SIZE, sp) +#ifndef CONFIG_MIPS32_O32 + .set noat + SAVE_SOME + STI + .set at +#endif + ld t1, PT_EPC(sp) # skip syscall on return + + subu t0, v0, __NR_N32_Linux # check syscall number + sltiu t0, t0, __NR_N32_Linux_syscalls + 1 + daddiu t1, 4 # skip to next instruction + beqz t0, not_n32_scall + sd t1, PT_EPC(sp) + + dsll t0, v0, 3 # offset into table + ld t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0) + + sd a3, PT_R26(sp) # save a3 for syscall restarting + + LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? + bltz t0, n32_syscall_trace_entry + + jalr t2 # Do The Real Thing (TM) + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall restarting +1: sd v0, PT_R2(sp) # result + +FEXPORT(n32_syscall_exit) + mfc0 t0, CP0_STATUS # make sure need_resched and + xori t0, t0, 1 # signals dont change between + ori t0, t0, 1 # sampling and return + mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP + + LONG_L a2, TI_FLAGS($28) # current->work + bnez a2, n32_syscall_exit_work + +restore_all: + RESTORE_SOME + RESTORE_SP + eret + +n32_syscall_exit_work: + SAVE_STATIC + j syscall_exit_work + +/* ------------------------------------------------------------------------ */ + +n32_syscall_trace_entry: + SAVE_STATIC + sd t2,PT_R1(sp) + jal do_syscall_trace + ld t2,PT_R1(sp) + + ld a0, PT_R4(sp) # Restore argument registers + ld a1, PT_R5(sp) + ld a2, PT_R6(sp) + ld a3, PT_R7(sp) + jalr t2 + + li t0, -EMAXERRNO - 1 # error? + sltu t0, t0, v0 + sd t0, PT_R7(sp) # set error flag + beqz t0, 1f + + negu v0 # error + sd v0, PT_R0(sp) # set flag for syscall restarting +1: sd v0, PT_R2(sp) # result + + j n32_syscall_exit + +not_n32_scall: + /* This is not an n32 compatibility syscall, pass it on to + the n64 syscall handlers. */ + j handle_sys64 + + END(handle_sysn32) + +EXPORT(sysn32_call_table) + PTR sys_read /* 6000 */ + PTR sys_write + PTR sys_open + PTR sys_close + PTR sys_newstat + PTR sys_newfstat /* 6005 */ + PTR sys_newlstat + PTR sys_poll + PTR sys_lseek + PTR sys_mmap + PTR sys_mprotect /* 6010 */ + PTR sys_munmap + PTR sys_brk + PTR sys32_rt_sigaction + PTR sys32_rt_sigprocmask + PTR compat_sys_ioctl /* 6015 */ + PTR sys_pread64 + PTR sys_pwrite64 + PTR sys32_readv + PTR sys32_writev + PTR sys_access /* 6020 */ + PTR sys_pipe + PTR sys32_select + PTR sys_sched_yield + PTR sys_mremap + PTR sys_msync /* 6025 */ + PTR sys_mincore + PTR sys_madvise + PTR sys_shmget + PTR sys_shmat + PTR sys_shmctl /* 6030 */ + PTR sys_dup + PTR sys_dup2 + PTR sys_pause + PTR compat_sys_nanosleep + PTR compat_sys_getitimer /* 6035 */ + PTR compat_sys_setitimer + PTR sys_alarm + PTR sys_getpid + PTR sys32_sendfile + PTR sys_socket /* 6040 */ + PTR sys_connect + PTR sys_accept + PTR sys_sendto + PTR sys_recvfrom + PTR compat_sys_sendmsg /* 6045 */ + PTR compat_sys_recvmsg + PTR sys_shutdown + PTR sys_bind + PTR sys_listen + PTR sys_getsockname /* 6050 */ + PTR sys_getpeername + PTR sys_socketpair + PTR compat_sys_setsockopt + PTR sys_getsockopt + PTR sys_clone /* 6055 */ + PTR sys_fork + PTR sys32_execve + PTR sys_exit + PTR sys32_wait4 + PTR sys_kill /* 6060 */ + PTR sys32_newuname + PTR sys_semget + PTR sys_semop + PTR sys_semctl + PTR sys_shmdt /* 6065 */ + PTR sys_msgget + PTR sys_msgsnd + PTR sys_msgrcv + PTR sys_msgctl + PTR compat_sys_fcntl /* 6070 */ + PTR sys_flock + PTR sys_fsync + PTR sys_fdatasync + PTR sys_truncate + PTR sys_ftruncate /* 6075 */ + PTR sys32_getdents + PTR sys_getcwd + PTR sys_chdir + PTR sys_fchdir + PTR sys_rename /* 6080 */ + PTR sys_mkdir + PTR sys_rmdir + PTR sys_creat + PTR sys_link + PTR sys_unlink /* 6085 */ + PTR sys_symlink + PTR sys_readlink + PTR sys_chmod + PTR sys_fchmod + PTR sys_chown /* 6090 */ + PTR sys_fchown + PTR sys_lchown + PTR sys_umask + PTR sys32_gettimeofday + PTR compat_sys_getrlimit /* 6095 */ + PTR compat_sys_getrusage + PTR sys32_sysinfo + PTR compat_sys_times + PTR sys_ptrace + PTR sys_getuid /* 6100 */ + PTR sys_syslog + PTR sys_getgid + PTR sys_setuid + PTR sys_setgid + PTR sys_geteuid /* 6105 */ + PTR sys_getegid + PTR sys_setpgid + PTR sys_getppid + PTR sys_getpgrp + PTR sys_setsid /* 6110 */ + PTR sys_setreuid + PTR sys_setregid + PTR sys_getgroups + PTR sys_setgroups + PTR sys_setresuid /* 6115 */ + PTR sys_getresuid + PTR sys_setresgid + PTR sys_getresgid + PTR sys_getpgid + PTR sys_setfsuid /* 6120 */ + PTR sys_setfsgid + PTR sys_getsid + PTR sys_capget + PTR sys_capset + PTR sys32_rt_sigpending /* 6125 */ + PTR sys32_rt_sigtimedwait + PTR sys32_rt_sigqueueinfo + PTR sys32_rt_sigsuspend + PTR sys32_sigaltstack + PTR compat_sys_utime /* 6130 */ + PTR sys_mknod + PTR sys32_personality + PTR sys_ustat + PTR compat_sys_statfs + PTR compat_sys_fstatfs /* 6135 */ + PTR sys_sysfs + PTR sys_getpriority + PTR sys_setpriority + PTR sys_sched_setparam + PTR sys_sched_getparam /* 6140 */ + PTR sys_sched_setscheduler + PTR sys_sched_getscheduler + PTR sys_sched_get_priority_max + PTR sys_sched_get_priority_min + PTR sys32_sched_rr_get_interval /* 6145 */ + PTR sys_mlock + PTR sys_munlock + PTR sys_mlockall + PTR sys_munlockall + PTR sys_vhangup /* 6150 */ + PTR sys_pivot_root + PTR sys32_sysctl + PTR sys_prctl + PTR sys32_adjtimex + PTR compat_sys_setrlimit /* 6155 */ + PTR sys_chroot + PTR sys_sync + PTR sys_acct + PTR sys32_settimeofday + PTR sys_mount /* 6160 */ + PTR sys_umount + PTR sys_swapon + PTR sys_swapoff + PTR sys_reboot + PTR sys_sethostname /* 6165 */ + PTR sys_setdomainname + PTR sys_ni_syscall /* was create_module */ + PTR sys_init_module + PTR sys_delete_module + PTR sys_ni_syscall /* 6170, was get_kernel_syms */ + PTR sys_ni_syscall /* was query_module */ + PTR sys_quotactl + PTR sys_nfsservctl + PTR sys_ni_syscall /* res. for getpmsg */ + PTR sys_ni_syscall /* 6175 for putpmsg */ + PTR sys_ni_syscall /* res. for afs_syscall */ + PTR sys_ni_syscall /* res. for security */ + PTR sys_gettid + PTR sys32_readahead + PTR sys_setxattr /* 6180 */ + PTR sys_lsetxattr + PTR sys_fsetxattr + PTR sys_getxattr + PTR sys_lgetxattr + PTR sys_fgetxattr /* 6185 */ + PTR sys_listxattr + PTR sys_llistxattr + PTR sys_flistxattr + PTR sys_removexattr + PTR sys_lremovexattr /* 6190 */ + PTR sys_fremovexattr + PTR sys_tkill + PTR sys_time + PTR compat_sys_futex + PTR sys32_sched_setaffinity /* 6195 */ + PTR sys32_sched_getaffinity + PTR sys_cacheflush + PTR sys_cachectl + PTR sys_sysmips + PTR sys_io_setup /* 6200 */ + PTR sys_io_destroy + PTR sys_io_getevents + PTR sys_io_submit + PTR sys_io_cancel + PTR sys_exit_group /* 6205 */ + PTR sys_lookup_dcookie + PTR sys_epoll_create + PTR sys_epoll_ctl + PTR sys_epoll_wait + PTR sys_remap_file_pages /* 6210 */ + PTR sys_ni_syscall + PTR sys_fcntl + PTR sys_set_tid_address + PTR sys_restart_syscall + PTR sys_semtimedop /* 6215 */ + PTR sys_fadvise64 + PTR sys_statfs64 + PTR sys_fstatfs64 diff -Nru a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S --- a/arch/mips64/kernel/scall_o32.S Fri Jun 27 14:19:59 2003 +++ b/arch/mips64/kernel/scall_o32.S Fri Jun 27 14:19:59 2003 @@ -14,22 +14,12 @@ */ #include <asm/asm.h> #include <linux/errno.h> -#include <asm/current.h> #include <asm/mipsregs.h> #include <asm/regdef.h> #include <asm/stackframe.h> #include <asm/unistd.h> #include <asm/sysmips.h> -/* This duplicates the definition from <linux/sched.h> */ -#error #define PT_TRACESYS 0x00000002 /* tracing system calls */ - -/* This duplicates the definition from <asm/signal.h> */ -#define SIGILL 4 /* Illegal instruction (ANSI). */ - -/* Highest syscall used of any syscall flavour */ -#define MAX_SYSCALL_NO __NR_Linux32 + __NR_Linux32_syscalls - .align 5 NESTED(handle_sys, PT_SIZE, sp) .set noat @@ -38,24 +28,35 @@ .set at ld t1, PT_EPC(sp) # skip syscall on return - subu t0, v0, __NR_Linux32 # check syscall number - sltiu t0, t0, __NR_Linux32_syscalls + 1 + subu t0, v0, __NR_O32_Linux # check syscall number + sltiu t0, t0, __NR_O32_Linux_syscalls + 1 daddiu t1, 4 # skip to next instruction beqz t0, not_o32_scall sd t1, PT_EPC(sp) +#if 0 + SAVE_ALL + move a1, v0 + PRINT("Scall %ld\n") + RESTORE_ALL +#endif + + sll a0, a0, 0 + sll a1, a1, 0 + sll a2, a2, 0 + sll a3, a3, 0 /* XXX Put both in one cacheline, should save a bit. */ dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_Linux32 * 8))(t0) # syscall routine - lbu t3, (sys_narg_table - __NR_Linux32)(v0) # number of arguments + ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0) + lbu t3, (sys_narg_table - __NR_O32_Linux)(v0) subu t0, t3, 5 # 5 or more arguments? sd a3, PT_R26(sp) # save a3 for syscall restarting bgez t0, stackargs stack_done: -#error ld t0, TASK_PTRACE($28) # syscall tracing enabled? -#error andi t0, PT_TRACESYS + LONG_L t0, TI_FLAGS($28) + # syscall tracing enabled? bnez t0, trace_a_syscall jalr t2 # Do The Real Thing (TM) @@ -69,35 +70,23 @@ sd v0, PT_R0(sp) # flag for syscall restarting 1: sd v0, PT_R2(sp) # result -FEXPORT(o32_ret_from_sys_call) - mfc0 t0, CP0_STATUS # need_resched and signals atomic test - ori t0, t0, 1 - xori t0, t0, 1 +FEXPORT(o32_syscall_exit) + mfc0 t0, CP0_STATUS # make need_resched and + ori t0, t0, 1 # signals dont change between + xori t0, t0, 1 # sampling and return mtc0 t0, CP0_STATUS + SSNOP; SSNOP; SSNOP -#error ld t2, TASK_NEED_RESCHED($28) - bnez t2, o32_reschedule -#error lw v0, TASK_SIGPENDING($28) - bnez v0, signal_return + LONG_L a2, TI_FLAGS($28) + bnez a2, o32_syscall_exit_work restore_all: RESTORE_SOME RESTORE_SP - .set mips3 eret - .set mips0 - -signal_return: mfc0 t0, CP0_STATUS # need_resched and signals atomic test - ori t0, t0, 1 - mtc0 t0, CP0_STATUS - move a0, zero - move a1, sp - SAVE_STATIC -#error jal do_signal -o32_reschedule: +o32_syscall_exit_work: SAVE_STATIC - jal schedule - b o32_ret_from_sys_call + j syscall_exit_work /* ------------------------------------------------------------------------ */ @@ -109,7 +98,7 @@ sd a7, PT_R11(sp) sd t2,PT_R1(sp) - jal syscall_trace + jal do_syscall_trace ld t2,PT_R1(sp) ld a0, PT_R4(sp) # Restore argument registers @@ -130,8 +119,7 @@ sd v0, PT_R0(sp) # set flag for syscall restarting 1: sd v0, PT_R2(sp) # result -#error jal syscall_trace - j o32_ret_from_sys_call + j syscall_exit /* ------------------------------------------------------------------------ */ @@ -150,16 +138,20 @@ bltz t0, bad_stack # -> sp is bad ld t0, PT_R29(sp) # get old user stack pointer - la t1, 3f # copy 1 to 2 arguments + PTR_LA t1, 3f # copy 1 to 2 arguments sll t3, t3, 2 subu t1, t3 jr t1 /* Ok, copy the args from the luser stack to the kernel stack */ + .set push + .set noreorder + .set nomacro 1: lw a5, 20(t0) # argument #6 from usp 2: lw a4, 16(t0) # argument #5 from usp +3: .set pop -3: j stack_done # go back + j stack_done # go back .section __ex_table,"a" PTR 1b, bad_stack @@ -170,70 +162,148 @@ * The stackpointer for a call with more than 4 arguments is bad. */ bad_stack: - negu v0 # error - sd v0, PT_R0(sp) - sd v0, PT_R2(sp) - li t0, 1 # set error flag - sd t0, PT_R7(sp) - j ret_from_sys_call + negu v0 # error + sd v0, PT_R0(sp) + sd v0, PT_R2(sp) + li t0, 1 # set error flag + sd t0, PT_R7(sp) + j o32_syscall_exit not_o32_scall: - /* This is not an 32-bit compatibility syscall, pass it on to - the 64-bit syscall handlers. */ - j handle_sys64 + /* + * This is not an o32 compatibility syscall, pass it on + * to the 64-bit syscall handlers. + */ +#ifdef CONFIG_MIPS32_N32 + j handle_sysn32 +#else + j handle_sys64 +#endif illegal_syscall: - /* This also isn't a 64-bit syscall, throw an error. */ - li v0, ENOSYS # error - sd v0, PT_R2(sp) - li t0, 1 # set error flag - sd t0, PT_R7(sp) - j ret_from_sys_call - END(handle_sys) - - LEAF(mips_atomic_set) - ld v1, THREAD_CURDS($28) - daddiu a0, a1, 4 - or a0, a0, a1 - li v0, -EFAULT - and a0, a0, v1 - bltz a0, 9f - - /* Ok, this is the ll/sc case. World is sane :-) */ -1: ll v0, (a1) - move a0, a2 -2: sc a0, (a1) - beqz a0, 1b + /* This also isn't a 64-bit syscall, throw an error. */ + li v0, ENOSYS # error + sd v0, PT_R2(sp) + li t0, 1 # set error flag + sd t0, PT_R7(sp) + j o32_syscall_exit + END(handle_sys) + +LEAF(mips_atomic_set) + andi v0, a1, 3 # must be word aligned + bnez v0, bad_alignment + + ld v1, TI_ADDR_LIMIT($28) # in legal address range? + daddiu a0, a1, 4 + or a0, a0, a1 + and a0, a0, v1 + bnez a0, bad_address + + /* Ok, this is the ll/sc case. World is sane :-) */ +1: ll v0, (a1) + move a0, a2 +2: sc a0, (a1) + beqz a0, 1b + + .section __ex_table,"a" + PTR 1b, bad_stack + PTR 2b, bad_stack + .previous + +1: sd v0, PT_R2(sp) # result + + /* Success, so skip usual error handling garbage. */ + LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? + bltz t0, 1f + b o32_syscall_exit + +1: SAVE_STATIC + jal do_syscall_trace + li a3, 0 # success + j syscall_exit + +bad_address: + li v0, -EFAULT + jr ra + +bad_alignment: + li v0, -EINVAL + jr ra + END(mips_atomic_set) + +LEAF(sys32_sysmips) + beq a0, MIPS_ATOMIC_SET, mips_atomic_set + j sys_sysmips + END(sys32_sysmips) + +LEAF(sys32_syscall) + ld t0, PT_R29(sp) # user sp + + sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 + beqz v0, enosys + + dsll v0, a0, 3 + dla v1, sys32_syscall + ld t2, (sys_call_table - (__NR_O32_Linux * 8))(v0) + lbu t3, (sys_narg_table - __NR_O32_Linux)(a0) + + li v0, -EINVAL + beq t2, v1, out # do not recurse + + beqz t2, enosys # null function pointer? + + andi v0, t0, 0x3 # unaligned stack pointer? + bnez v0, sigsegv + + daddiu v0, t0, 16 # v0 = usp + 16 + daddu t1, v0, 12 # 3 32-bit arguments + ld v1, TI_ADDR_LIMIT($28) + or v0, v0, t1 + and v1, v1, v0 + bnez v1, efault + + move a0, a1 # shift argument registers + move a1, a2 + move a2, a3 + +1: lw a3, 16(t0) +2: lw t3, 20(t0) +3: lw t1, 24(t0) .section __ex_table,"a" - PTR 1b, bad_stack - PTR 2b, bad_stack + PTR 1b, efault + PTR 2b, efault + PTR 3b, efault .previous -1: sd v0, PT_R2(sp) # result + sw t3, 16(sp) # put into new stackframe + sw t1, 20(sp) + + bnez t1, 1f # zero arguments? + daddu a0, sp, 32 # then pass sp in a0 +1: + + sw t3, 16(sp) + sw v1, 20(sp) + jr t2 + /* Unreached */ + +enosys: li v0, -ENOSYS + b out + +sigsegv: + li a0, _SIGSEGV + move a1, $28 + jal force_sig + /* Fall through */ - /* Success, so skip usual error handling garbage. */ -#error ld t0, TASK_PTRACE($28) # syscall tracing enabled? -#error andi t0, PT_TRACESYS - bnez t0, 1f - b o32_ret_from_sys_call - -1: SAVE_STATIC -#error jal syscall_trace - li a3, 0 # success - j ret_from_sys_call - -9: li v0, -EFAULT - jr ra - END(mips_atomic_set) - - LEAF(sys_sysmips) - beq a0, MIPS_ATOMIC_SET, mips_atomic_set - j _sys_sysmips - END(sys_sysmips) +efault: li v0, -EFAULT + +out: jr ra + END(sys32_syscall) .macro syscalltable - sys sys_syscall 0 /* 4000 */ + sys sys32_syscall 0 /* 4000 */ sys sys_exit 1 sys sys_fork 0 sys sys_read 3 @@ -251,7 +321,7 @@ sys sys_chmod 2 /* 4015 */ sys sys_lchown 3 sys sys_ni_syscall 0 - sys sys_stat 2 + sys sys_ni_syscall 0 /* was sys_stat */ sys sys_lseek 3 sys sys_getpid 0 /* 4020 */ sys sys_mount 5 @@ -260,8 +330,8 @@ sys sys_getuid 0 sys sys_stime 1 /* 4025 */ sys sys32_ptrace 4 - sys sys32_alarm 1 - sys sys_fstat 2 + sys sys_alarm 1 + sys sys_ni_syscall 0 /* was sys_fstat */ sys sys_pause 0 sys compat_sys_utime 2 /* 4030 */ sys sys_ni_syscall 0 @@ -276,7 +346,7 @@ sys sys_rmdir 1 /* 4040 */ sys sys_dup 1 sys sys_pipe 0 - sys sys32_times 1 + sys compat_sys_times 1 sys sys_ni_syscall 0 sys sys_brk 1 /* 4045 */ sys sys_setgid 1 @@ -288,7 +358,7 @@ sys sys_umount 2 sys sys_ni_syscall 0 sys compat_sys_ioctl 3 - sys sys32_fcntl 3 /* 4055 */ + sys compat_sys_fcntl 3 /* 4055 */ sys sys_ni_syscall 2 sys sys_setpgid 2 sys sys_ni_syscall, 0 @@ -306,18 +376,18 @@ sys sys_setreuid 2 /* 4070 */ sys sys_setregid 2 sys sys32_sigsuspend 0 - sys sys32_sigpending 1 + sys compat_sys_sigpending 1 sys sys_sethostname 2 - sys sys32_setrlimit 2 /* 4075 */ - sys sys32_getrlimit 2 - sys sys32_getrusage 2 + sys compat_sys_setrlimit 2 /* 4075 */ + sys compat_sys_getrlimit 2 + sys compat_sys_getrusage 2 sys sys32_gettimeofday 2 sys sys32_settimeofday 2 sys sys_getgroups 2 /* 4080 */ sys sys_setgroups 2 - sys sys_ni_syscall 0 /* old_select */ + sys sys_ni_syscall 0 /* old_select */ sys sys_symlink 2 - sys sys_lstat 2 + sys sys_ni_syscall 0 /* was sys_lstat */ sys sys_readlink 3 /* 4085 */ sys sys_uselib 1 sys sys_swapon 2 @@ -332,24 +402,24 @@ sys sys_getpriority 2 sys sys_setpriority 3 sys sys_ni_syscall 0 - sys sys32_statfs 2 - sys sys32_fstatfs 2 /* 4100 */ - sys sys_ni_syscall 0 /* sys_ioperm */ - sys sys_socketcall 2 - sys sys_syslog 3 + sys compat_sys_statfs 2 + sys compat_sys_fstatfs 2 /* 4100 */ + sys sys_ni_syscall 0 /* sys_ioperm */ + sys sys_socketcall 2 + sys sys_syslog 3 sys compat_sys_setitimer 3 - sys compat_sys_getitimer 2 /* 4105 */ - sys sys32_newstat 2 - sys sys32_newlstat 2 - sys sys32_newfstat 2 - sys sys_ni_syscall 0 /* was sys_uname */ - sys sys_ni_syscall 0 /* sys_ioperm *//* 4110 */ - sys sys_vhangup 0 - sys sys_ni_syscall 0 /* was sys_idle */ - sys sys_ni_syscall 0 /* sys_vm86 */ - sys sys32_wait4 4 - sys sys_swapoff 1 /* 4115 */ - sys sys_sysinfo 1 + sys compat_sys_getitimer 2 /* 4105 */ + sys compat_sys_newstat 2 + sys compat_sys_newlstat 2 + sys compat_sys_newfstat 2 + sys sys_ni_syscall 0 /* was sys_uname */ + sys sys_ni_syscall 0 /* sys_ioperm *//* 4110 */ + sys sys_vhangup 0 + sys sys_ni_syscall 0 /* was sys_idle */ + sys sys_ni_syscall 0 /* sys_vm86 */ + sys sys32_wait4 4 + sys sys_swapoff 1 /* 4115 */ + sys sys32_sysinfo 1 sys sys32_ipc 6 sys sys_fsync 1 sys sys32_sigreturn 0 @@ -359,11 +429,11 @@ sys sys_ni_syscall 0 /* sys_modify_ldt */ sys sys32_adjtimex 1 sys sys_mprotect 3 /* 4125 */ - sys sys32_sigprocmask 3 - sys sys_create_module 2 + sys compat_sys_sigprocmask 3 + sys sys_ni_syscall 0 /* was creat_module */ sys sys_init_module 5 sys sys_delete_module 1 - sys sys_get_kernel_syms 1 /* 4130 */ + sys sys_ni_syscall 0 /* 4130, get_kernel_syms */ sys sys_quotactl 0 sys sys_getpgid 1 sys sys_fchdir 1 @@ -378,11 +448,11 @@ sys sys32_select 5 sys sys_flock 2 sys sys_msync 3 - sys compat_sys_readv 3 /* 4145 */ - sys compat_sys_writev 3 + sys sys32_readv 3 /* 4145 */ + sys sys32_writev 3 sys sys_cacheflush 3 sys sys_cachectl 3 - sys sys_sysmips 4 + sys sys32_sysmips 4 sys sys_ni_syscall 0 /* 4150 */ sys sys_getsid 1 sys sys_fdatasync 0 @@ -420,7 +490,7 @@ sys sys_socketpair 4 sys sys_setresuid 3 /* 4185 */ sys sys_getresuid 3 - sys sys_query_module 5 + sys sys_ni_syscall 0 /* was query_module */ sys sys_poll 3 sys sys_nfsservctl 3 sys sys_setresgid 3 /* 4190 */ @@ -440,12 +510,12 @@ sys sys_capget 2 sys sys_capset 2 /* 4205 */ sys sys32_sigaltstack 0 - sys sys_sendfile 3 + sys sys32_sendfile 4 sys sys_ni_syscall 0 sys sys_ni_syscall 0 - sys sys_mmap2 6 /* 4210 */ - sys sys_truncate64 2 - sys sys_ftruncate64 2 + sys sys32_mmap2 6 /* 4210 */ + sys sys32_truncate64 4 + sys sys32_ftruncate64 4 sys sys_newstat 2 sys sys_newlstat 2 sys sys_newfstat 2 /* 4215 */ @@ -453,15 +523,50 @@ sys sys_mincore 3 sys sys_madvise 3 sys sys_getdents64 3 - sys sys32_fcntl64 3 /* 4220 */ - sys sys32_gettid 0 - sys sys32_tkill 2 + sys compat_sys_fcntl64 3 /* 4220 */ + sys sys_ni_syscall 0 + sys sys_gettid 0 + sys sys32_readahead 5 + sys sys_setxattr 5 + sys sys_lsetxattr 5 /* 4225 */ + sys sys_fsetxattr 5 + sys sys_getxattr 4 + sys sys_lgetxattr 4 + sys sys_fgetxattr 4 + sys sys_listxattr 3 /* 4230 */ + sys sys_llistxattr 3 + sys sys_flistxattr 3 + sys sys_removexattr 2 + sys sys_lremovexattr 2 + sys sys_fremovexattr 2 /* 4235 */ + sys sys_tkill 2 + sys sys_sendfile64 5 + sys compat_sys_futex 5 + sys sys32_sched_setaffinity 3 + sys sys32_sched_getaffinity 3 /* 4240 */ + sys sys_io_setup 2 + sys sys_io_destroy 1 + sys sys_io_getevents 5 + sys sys_io_submit 3 + sys sys_io_cancel 3 /* 4245 */ + sys sys_exit_group 1 + sys sys_lookup_dcookie 3 + sys sys_epoll_create 1 + sys sys_epoll_ctl 4 + sys sys_epoll_wait 3 /* 4250 */ + sys sys_remap_file_pages 5 + sys sys_set_tid_address 1 + sys sys_restart_syscall 0 + sys sys_fadvise64 6 + sys sys_statfs64 3 /* 4255 */ + sys sys_fstatfs64 2 .endm .macro sys function, nargs PTR \function .endm + .align 3 sys_call_table: syscalltable diff -Nru a/arch/mips64/kernel/setup.c b/arch/mips64/kernel/setup.c --- a/arch/mips64/kernel/setup.c Fri Jun 27 14:19:52 2003 +++ b/arch/mips64/kernel/setup.c Fri Jun 27 14:19:52 2003 @@ -4,16 +4,20 @@ * for more details. * * Copyright (C) 1995 Linus Torvalds - * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Ralf Baechle + * Copyright (C) 1995 Waldorf Electronics + * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 Ralf Baechle * Copyright (C) 1996 Stoned Elipot * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 2002 Maciej W. Rozycki */ #include <linux/config.h> #include <linux/errno.h> #include <linux/init.h> +#include <linux/ioport.h> #include <linux/sched.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/stddef.h> #include <linux/string.h> #include <linux/unistd.h> @@ -23,42 +27,35 @@ #include <linux/utsname.h> #include <linux/a.out.h> #include <linux/tty.h> +#include <linux/bootmem.h> #ifdef CONFIG_BLK_DEV_RAM #include <linux/blk.h> #endif +#include <linux/major.h> +#include <linux/kdev_t.h> +#include <linux/root_dev.h> -#include <asm/asm.h> +#include <asm/addrspace.h> #include <asm/bootinfo.h> -#include <asm/cachectl.h> #include <asm/cpu.h> +#include <asm/mipsregs.h> #include <asm/stackframe.h> #include <asm/system.h> +#include <asm/sections.h> #include <asm/pgalloc.h> -#ifndef CONFIG_SMP -struct cpuinfo_mips cpu_data[1]; -#endif +struct cpuinfo_mips cpu_data[NR_CPUS]; #ifdef CONFIG_VT struct screen_info screen_info; #endif /* - * Not all of the MIPS CPUs have the "wait" instruction available. This - * is set to true if it is available. The wait instruction stops the - * pipeline and reduces the power consumption of the CPU very much. - */ -char wait_available; - -/* - * Do we have a cyclecounter available? - */ -char cyclecounter_available; - -/* * Set if box has EISA slots. */ +#ifdef CONFIG_EISA int EISA_bus = 0; +#endif #ifdef CONFIG_BLK_DEV_FD extern struct fd_ops no_fd_ops; @@ -70,6 +67,8 @@ struct ide_ops *ide_ops; #endif +extern void * __rd_start, * __rd_end; + extern struct rtc_ops no_rtc_ops; struct rtc_ops *rtc_ops; @@ -81,7 +80,6 @@ * * These are initialized so they are in the .data section */ -unsigned long mips_cputype = CPU_UNKNOWN; unsigned long mips_machtype = MACH_UNKNOWN; unsigned long mips_machgroup = MACH_GROUP_UNKNOWN; @@ -89,70 +87,396 @@ unsigned char aux_device_present; -extern void load_mmu(void); - static char command_line[CL_SIZE] = { 0, }; char saved_command_line[CL_SIZE]; extern char arcs_cmdline[CL_SIZE]; -extern void ip22_setup(void); -extern void ip27_setup(void); +/* + * mips_io_port_base is the begin of the address space to which x86 style + * I/O ports are mapped. + */ +const unsigned long mips_io_port_base = -1; +EXPORT_SYMBOL(mips_io_port_base); + +/* + * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped + * for the processor. + */ +unsigned long isa_slot_offset; +EXPORT_SYMBOL(isa_slot_offset); + +extern void SetUpBootInfo(void); +extern void load_mmu(void); +extern ATTRIB_NORET asmlinkage void start_kernel(void); +extern void prom_init(int, char **, char **, int *); + +static struct resource code_resource = { "Kernel code" }; +static struct resource data_resource = { "Kernel data" }; -static inline void cpu_probe(void) +asmlinkage void __init init_arch(int argc, char **argv, char **envp, + int *prom_vec) { - unsigned int prid = read_32bit_cp0_register(CP0_PRID); + /* Determine which MIPS variant we are running on. */ + cpu_probe(); - switch(prid & 0xff00) { - case PRID_IMP_R4000: - if((prid & 0xff) == PRID_REV_R4400) - mips_cputype = CPU_R4400SC; - else - mips_cputype = CPU_R4000SC; - break; - case PRID_IMP_R4600: - mips_cputype = CPU_R4600; - break; - case PRID_IMP_R4700: - mips_cputype = CPU_R4700; - break; - case PRID_IMP_R5000: - mips_cputype = CPU_R5000; - break; - case PRID_IMP_NEVADA: - mips_cputype = CPU_NEVADA; - break; - case PRID_IMP_R8000: - mips_cputype = CPU_R8000; - break; - case PRID_IMP_R10000: - case PRID_IMP_R12000: - mips_cputype = CPU_R10000; - break; - default: - mips_cputype = CPU_UNKNOWN; + prom_init(argc, argv, envp, prom_vec); + + cpu_report(); + + /* + * Determine the mmu/cache attached to this machine, then flush the + * tlb and caches. On the r4xx0 variants this also sets CP0_WIRED to + * zero. + */ + load_mmu(); + + /* + * On IP27, I am seeing the TS bit set when the kernel is loaded. + * Maybe because the kernel is in ckseg0 and not xkphys? Clear it + * anyway ... + */ + clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3); + set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR); + + start_kernel(); +} + +void __init add_memory_region(phys_t start, phys_t size, + long type) +{ + int x = boot_mem_map.nr_map; + + if (x == BOOT_MEM_MAP_MAX) { + printk("Ooops! Too many entries in the memory map!\n"); + return; } + + boot_mem_map.map[x].addr = start; + boot_mem_map.map[x].size = size; + boot_mem_map.map[x].type = type; + boot_mem_map.nr_map++; } -void __init setup_arch(char **cmdline_p) +static void __init print_memory_map(void) { - cpu_probe(); - load_mmu(); + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + printk(" memory: %016Lx @ %016Lx ", + (unsigned long long) boot_mem_map.map[i].size, + (unsigned long long) boot_mem_map.map[i].addr); + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + printk("(usable)\n"); + break; + case BOOT_MEM_ROM_DATA: + printk("(ROM data)\n"); + break; + case BOOT_MEM_RESERVED: + printk("(reserved)\n"); + break; + default: + printk("type %lu\n", boot_mem_map.map[i].type); + break; + } + } +} + +static inline void parse_cmdline_early(void) +{ + char c = ' ', *to = command_line, *from = saved_command_line; + unsigned long start_at, mem_size; + int len = 0; + int usermem = 0; + + printk("Determined physical RAM map:\n"); + print_memory_map(); + + for (;;) { + /* + * "mem=XXX[kKmM]" defines a memory region from + * 0 to <XXX>, overriding the determined size. + * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from + * <YYY> to <YYY>+<XXX>, overriding the determined size. + */ + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + /* + * If a user specifies memory size, we + * blow away any automatically generated + * size. + */ + if (usermem == 0) { + boot_mem_map.nr_map = 0; + usermem = 1; + } + mem_size = memparse(from + 4, &from); + if (*from == '@') + start_at = memparse(from + 1, &from); + else + start_at = 0; + add_memory_region(start_at, mem_size, BOOT_MEM_RAM); + } + c = *(from++); + if (!c) + break; + if (CL_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; + if (usermem) { + printk("User-defined physical RAM map:\n"); + print_memory_map(); + } +} + + +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + +static inline void bootmem_init(void) +{ +#ifdef CONFIG_BLK_DEV_INITRD + unsigned long tmp; + unsigned long *initrd_header; +#endif + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn; + int i; + +#ifdef CONFIG_BLK_DEV_INITRD + tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; + if (tmp < (unsigned long)&_end) + tmp += PAGE_SIZE; + initrd_header = (unsigned long *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; + } + start_pfn = PFN_UP(CPHYSADDR((&_end)+(initrd_end - initrd_start) + PAGE_SIZE)); +#else + /* + * Partially used pages are not usable - thus + * we are rounding upwards. + */ + start_pfn = PFN_UP(CPHYSADDR(&_end)); +#endif /* CONFIG_BLK_DEV_INITRD */ + +#ifndef CONFIG_SGI_IP27 + /* Find the highest page frame number we have available. */ + max_pfn = 0; + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long start, end; + + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + continue; + + start = PFN_UP(boot_mem_map.map[i].addr); + end = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + + if (start >= end) + continue; + if (end > max_pfn) + max_pfn = end; + } + + /* Initialize the boot-time allocator. */ + bootmap_size = init_bootmem(start_pfn, max_pfn); + + /* + * Register fully available low RAM pages with the bootmem allocator. + */ + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long curr_pfn, last_pfn, size; + + /* + * Reserve usable memory. + */ + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + continue; + + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(boot_mem_map.map[i].addr); + if (curr_pfn >= max_pfn) + continue; + if (curr_pfn < start_pfn) + curr_pfn = start_pfn; + + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + + if (last_pfn > max_pfn) + last_pfn = max_pfn; + + /* + * ... finally, did all the rounding and playing + * around just make the area go away? + */ + if (last_pfn <= curr_pfn) + continue; + + size = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + } + + /* Reserve the bootmap memory. */ + reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); +#endif + +#ifdef CONFIG_BLK_DEV_INITRD + /* Board specific code should have set up initrd_start and initrd_end */ + ROOT_DEV = Root_RAM0; + if (&__rd_start != &__rd_end) { + initrd_start = (unsigned long)&__rd_start; + initrd_end = (unsigned long)&__rd_end; + } + initrd_below_start_ok = 1; + if (initrd_start) { + unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *)initrd_start, + initrd_size); +/* FIXME: is this right? */ +#ifndef CONFIG_SGI_IP27 + if (CPHYSADDR(initrd_end) > PFN_PHYS(max_pfn)) { + printk("initrd extends beyond end of memory " + "(0x%p > 0x%p)\ndisabling initrd\n", + (void *)CPHYSADDR(initrd_end), + (void *)PFN_PHYS(max_pfn)); + initrd_start = 0; + } +#endif /* !CONFIG_SGI_IP27 */ + } +#endif +} + +static inline void resource_init(void) +{ + int i; + + code_resource.start = virt_to_bus(&_text); + code_resource.end = virt_to_bus(&_etext) - 1; + data_resource.start = virt_to_bus(&_etext); + data_resource.end = virt_to_bus(&_edata) - 1; + + /* + * Request address space for all standard RAM. + */ + for (i = 0; i < boot_mem_map.nr_map; i++) { + struct resource *res; + + res = alloc_bootmem(sizeof(struct resource)); + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + case BOOT_MEM_ROM_DATA: + res->name = "System RAM"; + break; + case BOOT_MEM_RESERVED: + default: + res->name = "reserved"; + } + + res->start = boot_mem_map.map[i].addr; + res->end = boot_mem_map.map[i].addr + + boot_mem_map.map[i].size - 1; + + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + request_resource(&iomem_resource, res); + + /* + * We don't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, &code_resource); + request_resource(res, &data_resource); + } +} + +#undef PFN_UP +#undef PFN_DOWN +#undef PFN_PHYS + + +void __init setup_arch(char **cmdline_p) +{ + extern void decstation_setup(void); + extern void ip22_setup(void); + extern void ip27_setup(void); + extern void ip32_setup(void); + extern void swarm_setup(void); + extern void malta_setup(void); + extern void momenco_ocelot_setup(void); + extern void momenco_ocelot_g_setup(void); + extern void momenco_ocelot_c_setup(void); + extern void swarm_setup(void); + void frame_info_init(void); + + frame_info_init(); +#ifdef CONFIG_DECSTATION + decstation_setup(); +#endif #ifdef CONFIG_SGI_IP22 ip22_setup(); #endif #ifdef CONFIG_SGI_IP27 ip27_setup(); #endif - -#ifdef CONFIG_ARC_MEMORY - bootmem_init (); +#ifdef CONFIG_SGI_IP32 + ip32_setup(); +#endif +#ifdef CONFIG_SIBYTE_BOARD + swarm_setup(); +#endif +#ifdef CONFIG_MIPS_MALTA + malta_setup(); +#endif +#ifdef CONFIG_MOMENCO_OCELOT + case MACH_GROUP_MOMENCO: + momenco_ocelot_setup(); + break; +#endif +#ifdef CONFIG_MOMENCO_OCELOT_G + case MACH_GROUP_MOMENCO: + momenco_ocelot_g_setup(); + break; #endif +#ifdef CONFIG_MOMENCO_OCELOT_C + case MACH_GROUP_MOMENCO: + momenco_ocelot_c_setup(); + break; +#endif + strlcpy(command_line, arcs_cmdline, sizeof(command_line)); strlcpy(saved_command_line, command_line, sizeof(saved_command_line)); *cmdline_p = command_line; + parse_cmdline_early(); + + bootmem_init(); + paging_init(); + + resource_init(); } + +int __init fpu_disable(char *s) +{ + cpu_data[0].options &= ~MIPS_CPU_FPU; + + return 1; +} + +__setup("nofpu", fpu_disable); diff -Nru a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c --- a/arch/mips64/kernel/signal.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/kernel/signal.c Fri Jun 27 14:19:54 2003 @@ -10,6 +10,7 @@ #include <linux/config.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/personality.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/kernel.h> @@ -21,118 +22,25 @@ #include <asm/asm.h> #include <asm/bitops.h> -#include <asm/pgalloc.h> +#include <asm/cacheflush.h> #include <asm/stackframe.h> #include <asm/uaccess.h> #include <asm/ucontext.h> #include <asm/system.h> +#include <asm/fpu.h> #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int save_fp_context(struct sigcontext *sc); -extern asmlinkage int restore_fp_context(struct sigcontext *sc); -extern asmlinkage void syscall_trace(void); - -int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -{ - if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) - return -EFAULT; - if (from->si_code < 0) - return __copy_to_user(to, from, sizeof(siginfo_t)); - else { - int err; - - /* If you change siginfo_t structure, please be sure - this code is fixed accordingly. - It should never copy any pad contained in the structure - to avoid security leaks, but must copy the generic - 3 ints plus the relevant union member. */ - err = __put_user(from->si_signo, &to->si_signo); - err |= __put_user(from->si_errno, &to->si_errno); - err |= __put_user((short)from->si_code, &to->si_code); - switch (from->si_code >> 16) { - case __SI_FAULT >> 16: - err |= __put_user((long)from->si_addr, &to->si_addr); - break; - case __SI_CHLD >> 16: - err |= __put_user(from->si_utime, &to->si_utime); - err |= __put_user(from->si_stime, &to->si_stime); - err |= __put_user(from->si_status, &to->si_status); - default: - err |= __put_user(from->si_pid, &to->si_pid); - err |= __put_user(from->si_uid, &to->si_uid); - break; - /* case __SI_RT: This is not generated by the kernel as of now. */ - } - return err; - } -} - -static inline int store_fp_context(struct sigcontext *sc) -{ - unsigned int fcr0; - int err = 0; - - err |= __copy_to_user(&sc->sc_fpregs[0], - ¤t->thread.fpu.hard.fp_regs[0], NUM_FPU_REGS * - sizeof(unsigned long)); - err |= __copy_to_user(&sc->sc_fpc_csr, ¤t->thread.fpu.hard.control, - sizeof(unsigned int)); - __asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0)); - err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int)); - - return err; -} - -static inline int refill_fp_context(struct sigcontext *sc) -{ - int err = 0; - - if (verify_area(VERIFY_READ, sc, sizeof(*sc))) - return -EFAULT; - err |= __copy_from_user(¤t->thread.fpu.hard.fp_regs[0], - &sc->sc_fpregs[0], NUM_FPU_REGS * sizeof(unsigned long)); - err |= __copy_from_user(¤t->thread.fpu.hard.control, &sc->sc_fpc_csr, - sizeof(unsigned int)); - return err; -} +extern asmlinkage void do_syscall_trace(void); /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage inline int -sys_sigsuspend(abi64_no_regargs, struct pt_regs regs) -{ - sigset_t *uset, saveset, newset; - - save_static(®s); - uset = (sigset_t *) regs.regs[4]; - if (copy_from_user(&newset, uset, sizeof(sigset_t))) - return -EFAULT; - sigdelsetmask(&newset, ~_BLOCKABLE); - - spin_lock_irq(¤t->sigmask_lock); - saveset = current->blocked; - current->blocked = newset; - recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); - - regs.regs[2] = EINTR; - regs.regs[7] = 1; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_signal(&saveset, ®s)) - return -EINTR; - } -} - -asmlinkage int -sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { sigset_t *unewset, saveset, newset; size_t sigsetsize; @@ -149,11 +57,11 @@ return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); regs.regs[2] = EINTR; regs.regs[7] = 1; @@ -165,47 +73,7 @@ } } -asmlinkage int -sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) -{ - struct k_sigaction new_ka, old_ka; - int ret; - int err = 0; - - if (act) { - old_sigset_t mask; - - if (!access_ok(VERIFY_READ, act, sizeof(*act))) - return -EFAULT; - err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler); - err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); - err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer); - if (err) - return -EFAULT; - - siginitset(&new_ka.sa.sa_mask, mask); - } - - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); - - if (!ret && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact))) - return -EFAULT; - err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler); - err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig); - err |= __put_user(0, &oact->sa_mask.sig[1]); - err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer); - if (err) - return -EFAULT; - } - - return ret; -} - -asmlinkage int -sys_sigaltstack(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys_sigaltstack(abi64_no_regargs, struct pt_regs regs) { const stack_t *uss = (const stack_t *) regs.regs[4]; stack_t *uoss = (stack_t *) regs.regs[5]; @@ -214,10 +82,8 @@ return do_sigaltstack(uss, uoss, usp); } -asmlinkage int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - int owned_fp; int err = 0; err |= __get_user(regs->cp0_epc, &sc->sc_pc); @@ -240,26 +106,20 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); - if (owned_fp) { - if (IS_FPU_OWNER()) { - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } - current->used_math = 1; - err |= refill_fp_context(sc); + err |= __get_user(current->used_math, &sc->sc_used_math); + + if (current->used_math) { + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + loose_fpu(); } return err; } -struct sigframe { - u32 sf_ass[4]; /* argument save space for o32 */ - u32 sf_code[2]; /* signal trampoline */ - struct sigcontext sf_sc; - sigset_t sf_mask; -}; - struct rt_sigframe { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ @@ -267,42 +127,6 @@ struct ucontext rs_uc; }; -asmlinkage void sys_sigreturn(abi64_no_regargs, struct pt_regs regs) -{ - struct sigframe *frame; - sigset_t blocked; - - frame = (struct sigframe *) regs.regs[29]; - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) - goto badframe; - - sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); - current->blocked = blocked; - recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); - - if (restore_sigcontext(®s, &frame->sf_sc)) - goto badframe; - - /* - * Don't let your children do this ... - */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); - __asm__ __volatile__( - "move\t$29, %0\n\t" - "j\tret_from_sys_call" - :/* no outputs */ - :"r" (®s)); - /* Unreached */ - -badframe: - force_sig(SIGSEGV, current); -} - asmlinkage void sys_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) { struct rt_sigframe *frame; @@ -316,10 +140,10 @@ goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) goto badframe; @@ -335,7 +159,7 @@ */ __asm__ __volatile__( "move\t$29, %0\n\t" - "j\tret_from_sys_call" + "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ @@ -344,12 +168,12 @@ force_sig(SIGSEGV, current); } -static inline int setup_sigcontext(struct pt_regs *regs, - struct sigcontext *sc) +static inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { int err = 0; err |= __put_user(regs->cp0_epc, &sc->sc_pc); + err |= __put_user(regs->cp0_status, &sc->sc_status); #define save_gp_reg(i) do { \ err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ @@ -370,20 +194,22 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - if (current->used_math) { /* fp is active. */ - if (IS_FPU_OWNER()) { - lazy_fpu_switch(current, 0); - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } - err |= __put_user(1, &sc->sc_ownedfp); - err |= store_fp_context(sc); - current->used_math = 0; - } else { - err |= __put_user(0, &sc->sc_ownedfp); + err |= __put_user(current->used_math, &sc->sc_used_math); + + if (!current->used_math) + goto out; + + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. + */ + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); } - err |= __put_user(regs->cp0_status, &sc->sc_status); + err |= save_fp_context(sc); +out: return err; } @@ -391,13 +217,20 @@ * Determine which stack to use.. */ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) + size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->regs[29]; + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + /* This is the X/Open sanctioned signal stack switching. */ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; @@ -405,96 +238,25 @@ return (void *)((sp - frame_size) & ALMASK); } -static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static void inline setup_rt_frame(struct k_sigaction * ka, + struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) { - struct sigframe *frame; + struct rt_sigframe *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } - - err |= setup_sigcontext(regs, &frame->sf_sc); - err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); - if (err) - goto give_sigsegv; - /* - * Arguments to signal handler: - * - * a0 = signal number - * a1 = 0 (should be cause) - * a2 = pointer to struct sigcontext + * Set up the return code ... * - * $25 and c0_epc point to the signal handler, $29 points to the - * struct sigframe. + * li v0, __NR_rt_sigreturn + * syscall */ - regs->regs[ 4] = signr; - regs->regs[ 5] = 0; - regs->regs[ 6] = (unsigned long) &frame->sf_sc; - regs->regs[29] = (unsigned long) frame; - regs->regs[31] = (unsigned long) frame->sf_code; - regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; - -#if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n", - current->comm, current->pid, frame, regs->cp0_epc, frame->code); -#endif - return; - -give_sigsegv: - if (signr == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); -} - -static void inline setup_rt_frame(struct k_sigaction * ka, - struct pt_regs *regs, int signr, - sigset_t *set, siginfo_t *info) -{ - struct rt_sigframe *frame; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) - goto give_sigsegv; - - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); /* Create siginfo. */ err |= copy_siginfo_to_user(&frame->rs_info, info); @@ -532,8 +294,9 @@ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; #if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n", - current->comm, current->pid, frame, regs->cp0_epc, frame->code); + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, regs->regs[31]); #endif return; @@ -544,29 +307,10 @@ } static inline void handle_signal(unsigned long sig, siginfo_t *info, - sigset_t *oldset, struct pt_regs *regs) + sigset_t *oldset, struct pt_regs *regs) { - struct k_sigaction *ka = ¤t->sig->action[sig-1]; - - if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(ka, regs, sig, oldset, info); - else - setup_frame(ka, regs, sig, oldset); - - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; - if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sigmask_lock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); - } -} + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; -static inline void syscall_restart(struct pt_regs *regs, - struct k_sigaction *ka) -{ switch(regs->regs[0]) { case ERESTARTNOHAND: regs->regs[2] = EINTR; @@ -583,10 +327,23 @@ } regs->regs[0] = 0; /* Don't deal with this again. */ + + setup_rt_frame(ka, regs, sig, oldset, info); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } } -extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); + extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); +extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) { @@ -594,7 +351,7 @@ int signr; #ifdef CONFIG_BINFMT_ELF32 - if (current->thread.mflags & MF_32BIT) { + if (current->thread.mflags & MF_32BIT_REGS) { return do_signal32(oldset, regs); } #endif @@ -604,9 +361,6 @@ signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { - if (regs->regs[0]) - syscall_restart(regs, ka); - /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); return 1; } @@ -625,4 +379,30 @@ } } return 0; +} + + +/* + * notification of userspace execution resumption + * - triggered by current->work.notify_resume + */ +asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, + __u32 thread_info_flags) +{ + /* deal with pending signal delivery */ + if (thread_info_flags & _TIF_SIGPENDING) { +#ifdef CONFIG_BINFMT_ELF32 + if (likely((current->thread.mflags & MF_32BIT_REGS))) { + do_signal32(oldset, regs); + return; + } +#endif +#ifdef CONFIG_BINFMT_IRIX + if (unlikely(current->personality != PER_LINUX)) { + do_irix_signal(oldset, regs); + return; + } +#endif + do_signal(oldset, regs); + } } diff -Nru a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c --- a/arch/mips64/kernel/signal32.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips64/kernel/signal32.c Fri Jun 27 14:19:57 2003 @@ -26,25 +26,20 @@ #include <asm/uaccess.h> #include <asm/ucontext.h> #include <asm/system.h> +#include <asm/fpu.h> #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs); -extern asmlinkage int save_fp_context(struct sigcontext *sc); -extern asmlinkage int restore_fp_context(struct sigcontext *sc); -extern asmlinkage void syscall_trace(void); +extern asmlinkage void do_syscall_trace(void); /* 32-bit compatibility types */ -#define _NSIG32_BPW 32 -#define _NSIG32_WORDS (_NSIG / _NSIG32_BPW) - -typedef struct { - unsigned int sig[_NSIG32_WORDS]; -} sigset32_t; +#define _NSIG_BPW32 32 +#define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32) typedef unsigned int __sighandler32_t; typedef void (*vfptr_t)(void); @@ -52,9 +47,7 @@ struct sigaction32 { unsigned int sa_flags; __sighandler32_t sa_handler; - sigset32_t sa_mask; - unsigned int sa_restorer; - int sa_resv[1]; /* reserved */ + compat_sigset_t sa_mask; }; /* IRIX compatible stack_t */ @@ -64,41 +57,10 @@ int ss_flags; } stack32_t; - -static inline int store_fp_context(struct sigcontext *sc) -{ - unsigned int fcr0; - int err = 0; - - err |= __copy_to_user(&sc->sc_fpregs[0], - ¤t->thread.fpu.hard.fp_regs[0], NUM_FPU_REGS * - sizeof(unsigned long)); - err |= __copy_to_user(&sc->sc_fpc_csr, ¤t->thread.fpu.hard.control, - sizeof(unsigned int)); - __asm__ __volatile__("cfc1 %0, $0\n\t" : "=r" (fcr0)); - err |= __copy_to_user(&sc->sc_fpc_eir, &fcr0, sizeof(unsigned int)); - - return err; -} - -static inline int refill_fp_context(struct sigcontext *sc) -{ - int err = 0; - - if (verify_area(VERIFY_READ, sc, sizeof(*sc))) - return -EFAULT; - err |= __copy_from_user(¤t->thread.fpu.hard.fp_regs[0], - &sc->sc_fpregs[0], NUM_FPU_REGS * sizeof(unsigned long)); - err |= __copy_from_user(¤t->thread.fpu.hard.control, &sc->sc_fpc_csr, - sizeof(unsigned int)); - return err; -} - extern void __put_sigset_unknown_nsig(void); extern void __get_sigset_unknown_nsig(void); -static inline int -put_sigset(const sigset_t *kbuf, sigset32_t *ubuf) +static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf) { int err = 0; @@ -119,8 +81,7 @@ return err; } -static inline int -get_sigset(sigset_t *kbuf, const sigset32_t *ubuf) +static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t *ubuf) { int err = 0; unsigned long sig[4]; @@ -147,23 +108,22 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage inline int -sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs) +asmlinkage inline int sys32_sigsuspend(abi64_no_regargs, struct pt_regs regs) { - sigset32_t *uset; + compat_sigset_t *uset; sigset_t newset, saveset; save_static(®s); - uset = (sigset32_t *) regs.regs[4]; + uset = (compat_sigset_t *) regs.regs[4]; if (get_sigset(&newset, uset)) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); regs.regs[2] = EINTR; regs.regs[7] = 1; @@ -175,29 +135,28 @@ } } -asmlinkage int -sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys32_rt_sigsuspend(abi64_no_regargs, struct pt_regs regs) { - sigset32_t *uset; + compat_sigset_t *uset; sigset_t newset, saveset; size_t sigsetsize; save_static(®s); /* XXX Don't preclude handling different sized sigset_t's. */ sigsetsize = regs.regs[5]; - if (sigsetsize != sizeof(sigset32_t)) + if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; - uset = (sigset32_t *) regs.regs[4]; + uset = (compat_sigset_t *) regs.regs[4]; if (get_sigset(&newset, uset)) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); saveset = current->blocked; current->blocked = newset; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); regs.regs[2] = EINTR; regs.regs[7] = 1; @@ -225,8 +184,6 @@ &act->sa_handler); err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); err |= __get_user(mask, &act->sa_mask.sig[0]); - err |= __get_user((u32)(u64)new_ka.sa.sa_restorer, - &act->sa_restorer); if (err) return -EFAULT; @@ -245,8 +202,6 @@ err |= __put_user(0, &oact->sa_mask.sig[1]); err |= __put_user(0, &oact->sa_mask.sig[2]); err |= __put_user(0, &oact->sa_mask.sig[3]); - err |= __put_user((u32)(u64)old_ka.sa.sa_restorer, - &oact->sa_restorer); if (err) return -EFAULT; } @@ -254,8 +209,7 @@ return ret; } -asmlinkage int -sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs) +asmlinkage int sys32_sigaltstack(abi64_no_regargs, struct pt_regs regs) { const stack32_t *uss = (const stack32_t *) regs.regs[4]; stack32_t *uoss = (stack32_t *) regs.regs[5]; @@ -293,10 +247,9 @@ return ret; } -static asmlinkage int -restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +static asmlinkage int restore_sigcontext(struct pt_regs *regs, + struct sigcontext *sc) { - int owned_fp; int err = 0; err |= __get_user(regs->cp0_epc, &sc->sc_pc); @@ -319,14 +272,15 @@ restore_gp_reg(31); #undef restore_gp_reg - err |= __get_user(owned_fp, &sc->sc_ownedfp); - if (owned_fp) { - if (IS_FPU_OWNER()) { - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } - current->used_math = 1; - err |= refill_fp_context(sc); + err |= __get_user(current->used_math, &sc->sc_used_math); + + if (current->used_math) { + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(sc); + } else { + /* signal handler may have used FPU. Give it up. */ + loose_fpu(); } return err; @@ -339,15 +293,56 @@ sigset_t sf_mask; }; -struct rt_sigframe { +struct rt_sigframe32 { u32 rs_ass[4]; /* argument save space for o32 */ u32 rs_code[2]; /* signal trampoline */ - struct siginfo rs_info; + struct siginfo32 rs_info; struct ucontext rs_uc; }; -asmlinkage void -sys32_sigreturn(abi64_no_regargs, struct pt_regs regs) +static int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from) +{ + int err; + + if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32))) + return -EFAULT; + + /* If you change siginfo_t structure, please be sure + this code is fixed accordingly. + It should never copy any pad contained in the structure + to avoid security leaks, but must copy the generic + 3 ints plus the relevant union member. + This routine must convert siginfo from 64bit to 32bit as well + at the same time. */ + err = __put_user(from->si_signo, &to->si_signo); + err |= __put_user(from->si_errno, &to->si_errno); + err |= __put_user((short)from->si_code, &to->si_code); + if (from->si_code < 0) + err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); + else { + switch (from->si_code >> 16) { + case __SI_CHLD >> 16: + err |= __put_user(from->si_utime, &to->si_utime); + err |= __put_user(from->si_stime, &to->si_stime); + err |= __put_user(from->si_status, &to->si_status); + default: + err |= __put_user(from->si_pid, &to->si_pid); + err |= __put_user(from->si_uid, &to->si_uid); + break; + case __SI_FAULT >> 16: + err |= __put_user((long)from->si_addr, &to->si_addr); + break; + case __SI_POLL >> 16: + err |= __put_user(from->si_band, &to->si_band); + err |= __put_user(from->si_fd, &to->si_fd); + break; + /* case __SI_RT: This is not generated by the kernel as of now. */ + } + } + return err; +} + +asmlinkage void sys32_sigreturn(abi64_no_regargs, struct pt_regs regs) { struct sigframe *frame; sigset_t blocked; @@ -359,10 +354,10 @@ goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = blocked; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(®s, &frame->sf_sc)) goto badframe; @@ -370,11 +365,11 @@ /* * Don't let your children do this ... */ - if (current->ptrace & PT_TRACESYS) - syscall_trace(); + if (current_thread_info()->flags & TIF_SYSCALL_TRACE) + do_syscall_trace(); __asm__ __volatile__( "move\t$29, %0\n\t" - "j\tret_from_sys_call" + "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ @@ -383,24 +378,23 @@ force_sig(SIGSEGV, current); } -asmlinkage void -sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) +asmlinkage void sys32_rt_sigreturn(abi64_no_regargs, struct pt_regs regs) { - struct rt_sigframe *frame; + struct rt_sigframe32 *frame; sigset_t set; stack_t st; - frame = (struct rt_sigframe *) regs.regs[29]; + frame = (struct rt_sigframe32 *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sigmask_lock); + spin_lock_irq(¤t->sighand->siglock); current->blocked = set; recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) goto badframe; @@ -416,7 +410,7 @@ */ __asm__ __volatile__( "move\t$29, %0\n\t" - "j\tret_from_sys_call" + "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ @@ -425,12 +419,13 @@ force_sig(SIGSEGV, current); } -static inline int -setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +static inline int setup_sigcontext(struct pt_regs *regs, + struct sigcontext *sc) { int err = 0; err |= __put_user(regs->cp0_epc, &sc->sc_pc); + err |= __put_user(regs->cp0_status, &sc->sc_status); #define save_gp_reg(i) { \ err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ @@ -451,34 +446,43 @@ err |= __put_user(regs->cp0_cause, &sc->sc_cause); err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); - if (current->used_math) { /* fp is active. */ - if (IS_FPU_OWNER()) { - lazy_fpu_switch(current, 0); - CLEAR_FPU_OWNER(); - regs->cp0_status &= ~ST0_CU1; - } - err |= __put_user(1, &sc->sc_ownedfp); - err |= store_fp_context(sc); - current->used_math = 0; - } else { - err |= __put_user(0, &sc->sc_ownedfp); + err |= __put_user(current->used_math, &sc->sc_used_math); + + if (!current->used_math) + goto out; + + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. + */ + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); } - err |= __put_user(regs->cp0_status, &sc->sc_status); + err |= save_fp_context(sc); +out: return err; } /* * Determine which stack to use.. */ -static inline void * -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) +static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, + size_t frame_size) { unsigned long sp; /* Default to using normal stack */ sp = regs->regs[29]; + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + /* This is the X/Open sanctioned signal stack switching. */ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp)) sp = current->sas_ss_sp + current->sas_ss_size; @@ -486,9 +490,8 @@ return (void *)((sp - frame_size) & ALMASK); } -static void inline -setup_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set) +static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set) { struct sigframe *frame; int err = 0; @@ -497,23 +500,15 @@ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto give_sigsegv; - /* Set up to return from userspace. If provided, use a stub already - in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_Linux32_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_Linux32_sigreturn, - frame->sf_code + 0); - err |= __put_user(0x0000000c , - frame->sf_code + 1); - flush_cache_sigtramp((unsigned long) frame->sf_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_O32_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_O32_sigreturn, frame->sf_code + 0); + err |= __put_user(0x0000000c , frame->sf_code + 1); + flush_cache_sigtramp((unsigned long) frame->sf_code); err |= setup_sigcontext(regs, &frame->sf_sc); err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set)); @@ -538,8 +533,9 @@ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; #if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n", - current->comm, current->pid, frame, regs->cp0_epc, frame->code); + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, frame->sf_code); #endif return; @@ -549,11 +545,11 @@ force_sig(SIGSEGV, current); } -static void inline -setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, - int signr, sigset_t *set, siginfo_t *info) +static inline void setup_rt_frame(struct k_sigaction * ka, + struct pt_regs *regs, int signr, + sigset_t *set, siginfo_t *info) { - struct rt_sigframe *frame; + struct rt_sigframe32 *frame; int err = 0; frame = get_sigframe(ka, regs, sizeof(*frame)); @@ -562,24 +558,18 @@ /* Set up to return from userspace. If provided, use a stub already in userspace. */ - if (ka->sa.sa_flags & SA_RESTORER) - regs->regs[31] = (unsigned long) ka->sa.sa_restorer; - else { - /* - * Set up the return code ... - * - * li v0, __NR_Linux32_rt_sigreturn - * syscall - */ - err |= __put_user(0x24020000 + __NR_Linux32_rt_sigreturn, - frame->rs_code + 0); - err |= __put_user(0x0000000c , - frame->rs_code + 1); - flush_cache_sigtramp((unsigned long) frame->rs_code); - } + /* + * Set up the return code ... + * + * li v0, __NR_O32_rt_sigreturn + * syscall + */ + err |= __put_user(0x24020000 + __NR_O32_rt_sigreturn, frame->rs_code + 0); + err |= __put_user(0x0000000c , frame->rs_code + 1); + flush_cache_sigtramp((unsigned long) frame->rs_code); - /* Create siginfo. */ - err |= __copy_to_user(&frame->rs_info, info, sizeof(*info)); + /* Convert (siginfo_t -> siginfo_t32) and copy to user. */ + err |= copy_siginfo_to_user32(&frame->rs_info, info); /* Create the ucontext. */ err |= __put_user(0, &frame->rs_uc.uc_flags); @@ -604,7 +594,7 @@ * a2 = pointer to ucontext * * $25 and c0_epc point to the signal handler, $29 points to - * the struct rt_sigframe. + * the struct rt_sigframe32. */ regs->regs[ 4] = signr; regs->regs[ 5] = (unsigned long) &frame->rs_info; @@ -614,8 +604,9 @@ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; #if DEBUG_SIG - printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n", - current->comm, current->pid, frame, regs->cp0_epc, frame->code); + printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", + current->comm, current->pid, + frame, regs->cp0_epc, frame->rs_code); #endif return; @@ -625,32 +616,12 @@ force_sig(SIGSEGV, current); } -static inline void -handle_signal(unsigned long sig siginfo_t *info, sigset_t *oldset, - struct pt_regs * regs) +static inline void handle_signal(unsigned long sig, siginfo_t *info, + sigset_t *oldset, struct pt_regs * regs) { - struct k_sigaction *ka = ¤t->sig->action[sig-1]; + struct k_sigaction *ka = ¤t->sighand->action[sig-1]; - if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(ka, regs, sig, oldset, info); - else - setup_frame(ka, regs, sig, oldset); - - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; - if (!(ka->sa.sa_flags & SA_NODEFER)) { - spin_lock_irq(¤t->sigmask_lock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sigmask_lock); - } -} - -static inline void -syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) -{ - switch(regs->regs[0]) { + switch (regs->regs[0]) { case ERESTARTNOHAND: regs->regs[2] = EINTR; break; @@ -666,6 +637,21 @@ } regs->regs[0] = 0; /* Don't deal with this again. */ + + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(ka, regs, sig, oldset, info); + else + setup_frame(ka, regs, sig, oldset); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } } asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs) @@ -678,9 +664,6 @@ signr = get_signal_to_deliver(&info, regs, NULL); if (signr > 0) { - if (regs->regs[0]) - syscall_restart(regs, ka); - /* Whee! Actually deliver the signal. */ handle_signal(signr, &info, oldset, regs); return 1; } @@ -701,44 +684,6 @@ return 0; } -extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, - old_sigset_t *oset); - -asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, - old_sigset_t32 *oset) -{ - old_sigset_t s; - int ret; - mm_segment_t old_fs = get_fs(); - - if (set && get_user (s, set)) - return -EFAULT; - set_fs (KERNEL_DS); - ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL); - set_fs (old_fs); - if (!ret && oset && put_user (s, oset)) - return -EFAULT; - return ret; -} - -asmlinkage long sys_sigpending(old_sigset_t *set); - -asmlinkage int sys32_sigpending(old_sigset_t32 *set) -{ - old_sigset_t pending; - int ret; - mm_segment_t old_fs = get_fs(); - - set_fs (KERNEL_DS); - ret = sys_sigpending(&pending); - set_fs (old_fs); - - if (put_user(pending, set)) - return -EFAULT; - - return ret; -} - asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, struct sigaction32 *oact, unsigned int sigsetsize) @@ -758,8 +703,6 @@ err |= __get_user((u32)(u64)new_sa.sa.sa_handler, &act->sa_handler); err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags); - err |= __get_user((u32)(u64)new_sa.sa.sa_restorer, - &act->sa_restorer); err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask); if (err) return -EFAULT; @@ -776,8 +719,6 @@ err |= __put_user((u32)(u64)old_sa.sa.sa_handler, &oact->sa_handler); err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags); - err |= __put_user((u32)(u64)old_sa.sa.sa_restorer, - &oact->sa_restorer); err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask); if (err) return -EFAULT; @@ -789,8 +730,8 @@ asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize); -asmlinkage int sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset, - unsigned int sigsetsize) +asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, + compat_sigset_t *oset, unsigned int sigsetsize) { sigset_t old_set, new_set; int ret; @@ -798,7 +739,7 @@ if (set && get_sigset(&new_set, set)) return -EFAULT; - + set_fs (KERNEL_DS); ret = sys_rt_sigprocmask(how, set ? &new_set : NULL, oset ? &old_set : NULL, sigsetsize); @@ -812,7 +753,8 @@ asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize); -asmlinkage int sys32_rt_sigpending(sigset32_t *uset, unsigned int sigsetsize) +asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset, + unsigned int sigsetsize) { int ret; sigset_t set; @@ -828,5 +770,110 @@ return ret; } -asmlinkage void sys32_rt_sigtimedwait(void) { panic(__FUNCTION__ " called."); } -asmlinkage void sys32_rt_sigqueueinfo(void) { panic(__FUNCTION__ " called."); } +asmlinkage int sys32_rt_sigtimedwait(compat_sigset_t *uthese, + siginfo_t32 *uinfo, struct compat_timespec *uts, + compat_time_t sigsetsize) +{ + int ret, sig; + sigset_t these; + compat_sigset_t these32; + struct timespec ts; + siginfo_t info; + long timeout = 0; + + /* + * As the result of a brainfarting competition a few years ago the + * size of sigset_t for the 32-bit kernel was choosen to be 128 bits + * but nothing so far is actually using that many, 64 are enough. So + * for now we just drop the high bits. + */ + if (copy_from_user (&these32, uthese, sizeof(compat_old_sigset_t))) + return -EFAULT; + + switch (_NSIG_WORDS) { +#ifdef __MIPSEB__ + case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32); + case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32); + case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32); + case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32); +#endif +#ifdef __MIPSEL__ + case 4: these.sig[3] = these32.sig[7] | (((long)these32.sig[6]) << 32); + case 3: these.sig[2] = these32.sig[5] | (((long)these32.sig[4]) << 32); + case 2: these.sig[1] = these32.sig[3] | (((long)these32.sig[2]) << 32); + case 1: these.sig[0] = these32.sig[1] | (((long)these32.sig[0]) << 32); +#endif + } + + /* + * Invert the set of allowed signals to get those we + * want to block. + */ + sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP)); + signotset(&these); + + if (uts) { + if (get_user (ts.tv_sec, &uts->tv_sec) || + get_user (ts.tv_nsec, &uts->tv_nsec)) + return -EINVAL; + if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0 + || ts.tv_sec < 0) + return -EINVAL; + } + + spin_lock_irq(¤t->sighand->siglock); + sig = dequeue_signal(current, &these, &info); + if (!sig) { + /* None ready -- temporarily unblock those we're interested + in so that we'll be awakened when they arrive. */ + sigset_t oldblocked = current->blocked; + sigandsets(¤t->blocked, ¤t->blocked, &these); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + timeout = MAX_SCHEDULE_TIMEOUT; + if (uts) + timeout = (timespec_to_jiffies(&ts) + + (ts.tv_sec || ts.tv_nsec)); + + current->state = TASK_INTERRUPTIBLE; + timeout = schedule_timeout(timeout); + + spin_lock_irq(¤t->sighand->siglock); + sig = dequeue_signal(current, &these, &info); + current->blocked = oldblocked; + recalc_sigpending(); + } + spin_unlock_irq(¤t->sighand->siglock); + + if (sig) { + ret = sig; + if (uinfo) { + if (copy_siginfo_to_user32(uinfo, &info)) + ret = -EFAULT; + } + } else { + ret = -EAGAIN; + if (timeout) + ret = -EINTR; + } + + return ret; +} + +extern asmlinkage int sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo); + +asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo) +{ + siginfo_t info; + int ret; + mm_segment_t old_fs = get_fs(); + + if (copy_from_user (&info, uinfo, 3*sizeof(int)) || + copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE)) + return -EFAULT; + set_fs (KERNEL_DS); + ret = sys_rt_sigqueueinfo(pid, sig, &info); + set_fs (old_fs); + return ret; +} diff -Nru a/arch/mips64/kernel/smp.c b/arch/mips64/kernel/smp.c --- a/arch/mips64/kernel/smp.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips64/kernel/smp.c Fri Jun 27 14:19:59 2003 @@ -1,100 +1,156 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) 2000, 2001 Kanoj Sarcar + * Copyright (C) 2000, 2001 Ralf Baechle + * Copyright (C) 2000, 2001 Silicon Graphics, Inc. + * Copyright (C) 2000, 2001 Broadcom Corporation + */ #include <linux/config.h> +#include <linux/cache.h> +#include <linux/delay.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/spinlock.h> #include <linux/threads.h> +#include <linux/module.h> #include <linux/time.h> #include <linux/timex.h> #include <linux/sched.h> -#include <linux/cache.h> -#include <linux/interrupt.h> #include <asm/atomic.h> +#include <asm/cpu.h> #include <asm/processor.h> #include <asm/system.h> #include <asm/hardirq.h> #include <asm/mmu_context.h> -#include <asm/irq.h> +#include <asm/smp.h> -#ifdef CONFIG_SGI_IP27 +int smp_threads_ready; /* Not used */ -#include <asm/sn/arch.h> -#include <asm/sn/intr.h> -#include <asm/sn/addrs.h> -#include <asm/sn/agent.h> -#include <asm/sn/sn0/ip27.h> +// static atomic_t cpus_booted = ATOMIC_INIT(0); +atomic_t cpus_booted = ATOMIC_INIT(0); -#define DORESCHED 0xab -#define DOCALL 0xbc +cpumask_t phys_cpu_present_map; /* Bitmask of physically CPUs */ +cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ +int __cpu_number_map[NR_CPUS]; +int __cpu_logical_map[NR_CPUS]; -static void sendintr(int destid, unsigned char status) -{ - int irq; +/* These are defined by the board-specific code. */ -#if (CPUS_PER_NODE == 2) - switch (status) { - case DORESCHED: irq = CPU_RESCHED_A_IRQ; break; - case DOCALL: irq = CPU_CALL_A_IRQ; break; - default: panic("sendintr"); - } - irq += cputoslice(destid); +/* + * Cause the function described by call_data to be executed on the passed + * cpu. When the function has finished, increment the finished field of + * call_data. + */ +void core_send_ipi(int cpu, unsigned int action); - /* - * Convert the compact hub number to the NASID to get the correct - * part of the address space. Then set the interrupt bit associated - * with the CPU we want to send the interrupt to. - */ - REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cputocnode(destid)), - FAST_IRQ_TO_LEVEL(irq)); -#else - << Bomb! Must redefine this for more than 2 CPUS. >> -#endif -} +/* + * Clear all undefined state in the cpu, set up sp and gp to the passed + * values, and kick the cpu into smp_bootstrap(); + */ +void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp); -#endif /* CONFIG_SGI_IP27 */ +/* + * After we've done initial boot, this function is called to allow the + * board code to clean up state, if needed + */ +void prom_init_secondary(void); + +void prom_smp_finish(void); -/* The 'big kernel lock' */ -int smp_threads_ready; /* Not used */ -atomic_t smp_commenced = ATOMIC_INIT(0); -struct cpuinfo_mips cpu_data[NR_CPUS]; -int smp_num_cpus = 1; /* Number that came online. */ -int __cpu_number_map[NR_CPUS]; -int __cpu_logical_map[NR_CPUS]; cycles_t cacheflush_time; +unsigned long cache_decay_ticks; -static void smp_tune_scheduling (void) +void smp_tune_scheduling (void) { -} + struct cache_desc *cd = ¤t_cpu_data.scache; + unsigned long cachesize; /* kB */ + unsigned long bandwidth = 350; /* MB/s */ + unsigned long cpu_khz; -void __init smp_boot_cpus(void) -{ - extern void allowboot(void); + /* + * Crude estimate until we actually meassure ... + */ + cpu_khz = loops_per_jiffy * 2 * HZ / 1000; - init_new_context(current, &init_mm); - current->processor = 0; - init_idle(); - smp_tune_scheduling(); - allowboot(); -} + /* + * Rough estimation for SMP scheduling, this is the number of + * cycles it takes for a fully memory-limited process to flush + * the SMP-local cache. + * + * (For a P5 this pretty much means we will choose another idle + * CPU almost always at wakeup time (this is due to the small + * L1 cache), on PIIs it's around 50-100 usecs, depending on + * the cache size) + */ + if (!cpu_khz) { + /* + * This basically disables processor-affinity scheduling on SMP + * without a cycle counter. Currently all SMP capable MIPS + * processors have a cycle counter. + */ + cacheflush_time = 0; + return; + } -void __init smp_commence(void) -{ - wmb(); - atomic_set(&smp_commenced,1); + cachesize = cd->linesz * cd->sets * cd->ways; + cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth; + cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000; + + printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n", + (long)cacheflush_time/(cpu_khz/1000), + ((long)cacheflush_time*100/(cpu_khz/1000)) % 100); + printk("task migration cache decay timeout: %ld msecs.\n", + (cache_decay_ticks + 1) * 1000 / HZ); +} + +void __init smp_callin(void) +{ +#if 0 + calibrate_delay(); + smp_store_cpu_info(cpuid); +#endif } -static void stop_this_cpu(void *dummy) +#ifndef CONFIG_SGI_IP27 +/* + * Hook for doing final board-specific setup after the generic smp setup + * is done + */ +asmlinkage void start_secondary(void) { + unsigned int cpu = smp_processor_id(); + + cpu_probe(); + prom_init_secondary(); + per_cpu_trap_init(); + /* - * Remove this CPU + * XXX parity protection should be folded in here when it's converted + * to an option instead of something based on .cputype */ - for (;;); -} - -void smp_send_stop(void) -{ - smp_call_function(stop_this_cpu, NULL, 1, 0); - smp_num_cpus = 1; + pgd_current[cpu] = init_mm.pgd; + cpu_data[cpu].udelay_val = loops_per_jiffy; + prom_smp_finish(); + printk("Slave cpu booted successfully\n"); + CPUMASK_SETB(cpu_online_map, cpu); + atomic_inc(&cpus_booted); + cpu_idle(); } +#endif /* CONFIG_SGI_IP27 */ /* * this function sends a 'reschedule' IPI to another CPU. @@ -103,14 +159,12 @@ */ void smp_send_reschedule(int cpu) { - sendintr(cpu, DORESCHED); + core_send_ipi(cpu, SMP_RESCHEDULE_YOURSELF); } -/* Not really SMP stuff ... */ -int setup_profiling_timer(unsigned int multiplier) -{ - return 0; -} +static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; + +struct call_data_struct *call_data; /* * Run a function on all other CPUs. @@ -122,23 +176,18 @@ * * Does not return until remote CPUs are nearly ready to execute <func> * or are or have executed. + * + * You must not call this function with disabled interrupts or from a + * hardware interrupt handler or from a bottom half handler. */ -static volatile struct call_data_struct { - void (*func) (void *info); - void *info; - atomic_t started; - atomic_t finished; - int wait; -} *call_data; - -int smp_call_function (void (*func) (void *info), void *info, int retry, +int smp_call_function (void (*func) (void *info), void *info, int retry, int wait) { struct call_data_struct data; - int i, cpus = smp_num_cpus-1; - static spinlock_t lock = SPIN_LOCK_UNLOCKED; + int i, cpus = num_online_cpus() - 1; + int cpu = smp_processor_id(); - if (cpus == 0) + if (!cpus) return 0; data.func = func; @@ -148,12 +197,13 @@ if (wait) atomic_set(&data.finished, 0); - spin_lock_bh(&lock); + spin_lock(&call_lock); call_data = &data; + /* Send a message to all other CPUs and wait for them to respond */ - for (i = 0; i < smp_num_cpus; i++) - if (smp_processor_id() != i) - sendintr(i, DOCALL); + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(cpu) && cpu != smp_processor_id()) + core_send_ipi(i, SMP_CALL_FUNCTION); /* Wait for response */ /* FIXME: lock-up detection, backtrace on lock-up */ @@ -163,34 +213,62 @@ if (wait) while (atomic_read(&data.finished) != cpus) barrier(); - spin_unlock_bh(&lock); + spin_unlock(&call_lock); + return 0; } -extern void smp_call_function_interrupt(int irq, void *d, struct pt_regs *r) +void smp_call_function_interrupt(void) { void (*func) (void *info) = call_data->func; void *info = call_data->info; int wait = call_data->wait; + irq_enter(); /* * Notify initiating CPU that I've grabbed the data and am * about to execute the function. */ + mb(); atomic_inc(&call_data->started); /* * At this point the info structure may be out of scope unless wait==1. */ + irq_enter(); (*func)(info); - if (wait) + irq_exit(); + + if (wait) { + mb(); atomic_inc(&call_data->finished); + } +} + +static void stop_this_cpu(void *dummy) +{ + /* + * Remove this CPU: + */ + clear_bit(smp_processor_id(), &cpu_online_map); + local_irq_enable(); /* May need to service _machine_restart IPI */ + for (;;); /* Wait if available. */ +} + +void smp_send_stop(void) +{ + smp_call_function(stop_this_cpu, NULL, 1, 0); +} + +/* Not really SMP stuff ... */ +int setup_profiling_timer(unsigned int multiplier) +{ + return 0; } - static void flush_tlb_all_ipi(void *info) { - _flush_tlb_all(); + local_flush_tlb_all(); } void flush_tlb_all(void) @@ -200,15 +278,15 @@ static void flush_tlb_mm_ipi(void *mm) { - _flush_tlb_mm((struct mm_struct *)mm); + local_flush_tlb_mm((struct mm_struct *)mm); } /* - * The following tlb flush calls are invoked when old translations are + * The following tlb flush calls are invoked when old translations are * being torn down, or pte attributes are changing. For single threaded * address spaces, a new context is obtained on the current cpu, and tlb * context on other cpus are invalidated to force a new context allocation - * at switch_mm time, should the mm ever be used on other cpus. For + * at switch_mm time, should the mm ever be used on other cpus. For * multithreaded address spaces, intercpu interrupts have to be sent. * Another case where intercpu interrupts are required is when the target * mm might be active on another cpu (eg debuggers doing the flushes on @@ -224,17 +302,16 @@ smp_call_function(flush_tlb_mm_ipi, (void *)mm, 1, 1); } else { int i; - for (i = 0; i < smp_num_cpus; i++) + for (i = 0; i < num_online_cpus(); i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } - _flush_tlb_mm(mm); + local_flush_tlb_mm(mm); preempt_enable(); } struct flush_tlb_data { - struct mm_struct *mm; struct vm_area_struct *vma; unsigned long addr1; unsigned long addr2; @@ -244,13 +321,14 @@ { struct flush_tlb_data *fd = (struct flush_tlb_data *)info; - _flush_tlb_range(fd->vma, fd->addr1, fd->addr2); + local_flush_tlb_range(fd->vma, fd->addr1, fd->addr2); } void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - preempt_disable(); + struct mm_struct *mm = vma->vm_mm; + preempt_disable(); if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { struct flush_tlb_data fd; @@ -260,26 +338,41 @@ smp_call_function(flush_tlb_range_ipi, (void *)&fd, 1, 1); } else { int i; - for (i = 0; i < smp_num_cpus; i++) + for (i = 0; i < num_online_cpus(); i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, mm) = 0; + cpu_context(i, mm) = 0; } - _flush_tlb_range(mm, start, end); - + local_flush_tlb_range(vma, start, end); preempt_enable(); } +static void flush_tlb_kernel_range_ipi(void *info) +{ + struct flush_tlb_data *fd = (struct flush_tlb_data *)info; + + local_flush_tlb_kernel_range(fd->addr1, fd->addr2); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct flush_tlb_data fd; + + fd.addr1 = start; + fd.addr2 = end; + smp_call_function(flush_tlb_kernel_range_ipi, (void *)&fd, 1, 1); + local_flush_tlb_kernel_range(start, end); +} + static void flush_tlb_page_ipi(void *info) { struct flush_tlb_data *fd = (struct flush_tlb_data *)info; - _flush_tlb_page(fd->vma, fd->addr1); + local_flush_tlb_page(fd->vma, fd->addr1); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) { preempt_disable(); - if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { struct flush_tlb_data fd; @@ -288,12 +381,28 @@ smp_call_function(flush_tlb_page_ipi, (void *)&fd, 1, 1); } else { int i; - for (i = 0; i < smp_num_cpus; i++) + for (i = 0; i < num_online_cpus(); i++) if (smp_processor_id() != i) - CPU_CONTEXT(i, vma->vm_mm) = 0; + cpu_context(i, vma->vm_mm) = 0; } - _flush_tlb_page(vma, page); - + local_flush_tlb_page(vma, page); preempt_enable(); } +static void flush_tlb_one_ipi(void *info) +{ + unsigned long vaddr = (unsigned long) info; + + local_flush_tlb_one(vaddr); +} + +void flush_tlb_one(unsigned long vaddr) +{ + smp_call_function(flush_tlb_one_ipi, (void *) vaddr, 1, 1); + local_flush_tlb_one(vaddr); +} + +EXPORT_SYMBOL(flush_tlb_page); +EXPORT_SYMBOL(flush_tlb_one); +EXPORT_SYMBOL(cpu_data); +EXPORT_SYMBOL(synchronize_irq); diff -Nru a/arch/mips64/kernel/softfp.S b/arch/mips64/kernel/softfp.S --- a/arch/mips64/kernel/softfp.S Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,666 +0,0 @@ -/* - * 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) 1998, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics, Inc. - * - * For now it's just a crude hack good enough to run certain fp programs like - * Mozilla. - * XXX: Handle MIPS II/III/IV/V enhancements, exceptions, ... - */ -#include <asm/regdef.h> -#include <asm/asm.h> - -#ifndef __KERNEL__ -#define printk printf -#endif - -#define LOCK_KERNEL -#define UNLOCK_KERNEL - -/* - * This duplicates definitions from <linux/kernel.h>. - */ -#define KERN_EMERG "<0>" /* system is unusable */ -#define KERN_ALERT "<1>" /* action must be taken immediately */ -#define KERN_CRIT "<2>" /* critical conditions */ -#define KERN_ERR "<3>" /* error conditions */ -#define KERN_WARNING "<4>" /* warning conditions */ -#define KERN_NOTICE "<5>" /* normal but significant condition */ -#define KERN_INFO "<6>" /* informational */ -#define KERN_DEBUG "<7>" /* debug-level messages */ - -/* - * This duplicates definitions from <asm/signal.h> - */ -#define SIGILL 4 /* Illegal instruction (ANSI). */ - -/* - * Definitions about the instruction format - */ -#define fd_shift 6 -#define fr_shift 21 -#define fs_shift 11 -#define ft_shift 16 - -/* - * NaNs as use by the MIPS architecture - */ -#define S_QNaN 0x7fbfffff -#define D_QNaN 0x7ff7ffffffffffff -#define W_QNaN 0x7fffffff -#define L_QNaN 0x7fffffffffffffff - -/* - * Checking for NaNs - */ -#define S_is_QNaN(reg,res) \ - sll res, reg, S_F_size - S_F_bits -#define D_is_QNaN(reg1,reg2,res) \ - sll res, reg1, (D_F_size - 32) - (D_F_bits - 32); \ - or res, reg2 - -/* - * Checking for Denorms - */ -#define S_is_Denorm(reg,res) \ - li res, 1 << (S_F_bits - 1); \ - and reg, res - -/* - * Some constants that define the properties of single precission numbers. - */ -#define S_M_prec 24 -#define S_E_max 127 -#define S_E_min -126 -#define S_E_bias 127 -#define S_E_bits 8 -#define S_F_bits 23 -#define S_F_size 32 - -/* Set temp0, if exponent of reg is S_E_max + 1. */ -#define S_is_E_max(reg,temp0,temp1) \ - li temp0, (S_E_max + 1 + S_E_bias) << S_F_bits; \ - and temp1, temp0, reg; \ - seq temp0, temp1 /* temp0 != 0 if NaN */ - -/* Clear temp0, if exponent of reg is S_E_min - 1. */ -#define S_is_E_min(reg,temp0) \ - li temp0, (S_E_min - 1 + S_E_bias) << S_F_bits; \ - and temp0, reg /* temp0 == 0 if denorm or zero */ - -/* Set temp0 if reg is a NaN assuming S_is_E_max is true */ -#define S_get_F(reg,temp0) \ - li temp0, (1 << S_F_bits) - 1; \ - and temp0, reg /* temp0 != 0 if NaN */ - -/* Set res if fraction of reg is != 0. */ -#define S_is_Inf(reg,res) \ - li res, (1 << S_F_bits) - 1; \ - and res, reg /* temp0 == 0 if Inf */ - - -/* - * Some constants that define the properties of double precission numbers. - */ -#define D_M_prec 53 -#define D_E_max 1023 -#define D_E_min -1022 -#define D_E_bias 1023 -#define D_E_bits 8 -#define D_F_bits 52 -#define D_F_size 64 - -/* Set temp0, if exponent of reg1/reg2 is D_E_max. */ -#define D_is_E_max(reg1,reg2,temp0,temp1) \ - li temp0, (D_E_max + 1 + D_E_bias) << (D_F_bits - 32); \ - and temp1, temp0, reg1; \ - seq temp0, temp1 /* temp0 != 0 if NaN */ - -/* Clear temp0, if exponent of reg is D_E_min. */ -#define D_is_E_min(reg1,reg2,res) \ - li res, (D_E_min + 1 + D_E_bias) << (D_F_bits - 32); \ - and res, reg1 /* temp0 == 0 if NaN or zero */ - -/* Set res if reg is a NaN assuming S_is_E_max is true */ -#define D_get_F(reg1,reg2,res) \ - li res, (1 << (D_F_bits - 32)) - 1; \ - and res, reg1 /* temp0 != 0 if NaN */ - -/* Set temp0 if reg1/reg2 is a NaN */ -#define D_is_NAN(reg1,reg2,temp0,temp1) \ - li temp0, (1 << (D_F_bits - 32) - 1; \ - and temp0, reg1; \ - or temp0, reg2; \ - sne temp0, zero, temp0 /* temp0 != 0 if NaN */ - -/* Set res if fraction of reg1/reg2 is != 0. */ -#define D_is_Inf(reg1,reg2,res) \ - li res, (1 << (D_F_bits - 32)) - 1; \ - and res, reg1; \ - or res, reg2 /* temp0 == 0 if Inf */ - -/* Complain about yet unhandled instruction. */ -#define BITCH(insn) \ -insn: LOCK_KERNEL; \ - la a1, 8f; \ - TEXT(#insn); \ - la a0, nosim; \ - jal printk; \ - UNLOCK_KERNEL; \ - j done - - .data -nosim: .asciz KERN_DEBUG "Don't know how to simulate %s instruction\n" - .previous - -/* - * When we come here, we've saved some of the integer registers and - * reenabled interrupts. - */ -LEAF(simfp) - .set noreorder - .cpload $25 - .set reorder - - dsubu sp, 16 - .cprestore 20 - sd ra, 0(sp) - - /* For now we assume that we get the opcode to simulate passed in as - an argument. */ - move ta0, a0 - - /* - * First table lookup using insn[5:0] - */ - la ta1, lowtab - andi ta2, ta0, 0x3f - sll ta2, ta2, 3 - daddu ta1, ta2 - ld ta1, (ta1) - jr ta1 - END(simfp) - -/* - * We only decode the lower 3 of the 5 bit in the fmt field. That way we - * can keep the jump table significantly shorter. - */ -#define FMT_switch(insn,opc,temp0,temp1) \ -insn: srl temp0, opc, 18; \ - andi temp0, 0x1c; \ - la temp1, insn##.tab; \ - daddu temp0, temp1; \ - ld temp0, (temp0); \ - jr temp0; \ - \ - .data; \ -insn##.tab: \ - .dword insn##.s, insn##.d, unimp, unimp; \ - .dword insn##.w, insn##.l, unimp, unimp; \ - .previous - - BITCH(add) - BITCH(sub) - BITCH(mul) - BITCH(div) - BITCH(sqrt) - BITCH(abs) - BITCH(mov) - BITCH(neg) - BITCH(round.l) - BITCH(trunc.l) - BITCH(ceil.l) - BITCH(floor.l) - BITCH(round.w) - BITCH(trunc.w) - BITCH(ceil.w) - BITCH(floor.w) - BITCH(cvt.s) - BITCH(cvt.d) - -/* ------------------------------------------------------------------------ */ - -FMT_switch(cvt.w,ta0,ta1,ta2) - -/* Convert a single fp to a fixed point integer. */ -cvt.w.s: - srl ta1, ta0, fs_shift # Get source register - andi ta1, 31 - jal s_get_fpreg - - S_is_E_max(ta1,ta2,ta3) - beqz ta2, 3f - /* Might be a NaN or Inf. */ - S_get_F(ta1,ta2) - beqz ta2, 2f - - /* It's a NaN. IEEE says undefined. */ - /* Is it a QNaN? Then the result is a QNaN as well. */ - S_is_QNaN(ta1,ta2) - bltz ta2, 1f - - /* XXX Ok, it's a SNaN. Signal invalid exception, if enabled. - For now we don't signal and supply a QNaN for result. */ - -1: li ta2, W_QNaN - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - j done -2: - - S_is_Inf(ta1,ta2) - bnez ta2, 2f - - /* It's +/- Inf. Set register to +/- max. integer. */ - /* XXX Send invalid operation exception instead, if enabled. */ - srl ta1, ta1, 31 # Extract sign bit - li ta2, 0x7fffffff - addu ta2, ta1 - - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - j done -2: -3: - - /* But then it might be a denorm or zero? */ - S_is_E_min(ta1,ta2) - bnez ta2, 2f - - /* Ok, it's a denorm or zero. */ - S_get_F(ta1,ta2) - beqz ta2, 1f - - /* It's a denorm. */ - /* XXX Should be signaling inexact exception, if enabled. */ - /* Fall through. */ -1: - /* Yes, it is a denorm or zero. Supply a zero as result. */ - move ta2, zero - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - j done -2: - - /* XXX Ok, it's a normal number. We don't handle that case yet. - If we have fp hardware this case is unreached. Add this for - full fp simulation. */ - - /* Done, return. */ - ld ra, 0(sp) - daddu sp, 16 - jr ra - -/* Convert a double fp to a fixed point integer. */ -cvt.w.d: - srl ta1, ta0, fs_shift # Get source register - andi ta1, 31 - jal d_get_fpreg - - D_is_E_max(ta1,ta2,ta3,t0) - beqz ta3, 3f - - /* Might be a NaN or Inf. */ - D_get_F(ta1,ta2,ta3) - or ta3, ta2 - beqz ta3, 2f - - /* It's a NaN. IEEE says undefined. */ - /* Is it a QNaN? Then the result is a QNaN as well. */ - D_is_QNaN(ta1,ta2,ta3) - bltz ta3, 1f - - /* XXX Ok, it's a SNaN. Signal invalid exception, if enabled. - For now we don't signal and supply a QNaN for result. */ - -1: li ta2, W_QNaN - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - j done -2: - - D_is_Inf(ta1,ta2,ta3) - bnez ta3, 2f - - /* It's +/- Inf. Set register to +/- max. integer. */ - /* XXX Send invalid operation exception instead, if enabled. */ - srl ta1, ta1, 31 # Extract sign bit - li ta2, 0x7fffffff - addu ta2, ta1 - - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - j done -2: -3: - - /* But then it might be a denorm or zero? */ - D_is_E_min(ta1,ta2,ta3) - bnez ta3, 2f - - /* Ok, it's a denorm or zero. */ - D_get_F(ta1,ta2,ta3) - or ta3, ta2 - beqz ta3, 1f - - /* It's a denorm. */ - /* XXX Should be signaling inexact exception, if enabled. */ - /* Fall through. */ -1: - /* Yes, it is a denorm or zero. Supply a zero as result. */ - move ta2, zero - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - j done -2: - - /* XXX Ok, it's a normal number. We don't handle that case yet. - If we have fp hardware this case is only reached if the value - of the source register exceeds the range which is representable - in a single precission register. For now we kludge by returning - +/- maxint and don't signal overflow. */ - - srl ta1, ta1, 31 # Extract sign bit - li ta2, 0x7fffffff - addu ta2, ta1 - - srl ta1, ta0, fd_shift # Put result register - andi ta1, 31 - jal s_put_fpreg - - /* Done, return. */ - ld ra, 0(sp) - daddu sp, 16 - jr ra - -cvt.w.w = unimp # undefined result -cvt.w.l = unimp # undefined result - -/* MIPS III extension, no need to handle for 32bit OS. */ -cvt.l = unimp - -/* ------------------------------------------------------------------------ */ - - BITCH(c.f) - BITCH(c.un) - BITCH(c.eq) - BITCH(c.ueq) - BITCH(c.olt) - BITCH(c.ult) - BITCH(c.ole) - BITCH(c.ule) - BITCH(c.sf) - BITCH(c.ngle) - BITCH(c.seq) - BITCH(c.ngl) - BITCH(c.lt) - BITCH(c.nge) - BITCH(c.le) - BITCH(c.ngt) - -/* Get the single precission register which's number is in ta1. */ -s_get_fpreg: - .set noat - sll ta1, 3 - la AT, 1f - daddu AT, ta1 - jr AT - .set at - -1: mfc1 ta1, $0 - jr ra - mfc1 ta1, $1 - jr ra - mfc1 ta1, $2 - jr ra - mfc1 ta1, $3 - jr ra - mfc1 ta1, $4 - jr ra - mfc1 ta1, $5 - jr ra - mfc1 ta1, $6 - jr ra - mfc1 ta1, $7 - jr ra - mfc1 ta1, $8 - jr ra - mfc1 ta1, $9 - jr ra - mfc1 ta1, $10 - jr ra - mfc1 ta1, $11 - jr ra - mfc1 ta1, $12 - jr ra - mfc1 ta1, $13 - jr ra - mfc1 ta1, $14 - jr ra - mfc1 ta1, $15 - jr ra - mfc1 ta1, $16 - jr ra - mfc1 ta1, $17 - jr ra - mfc1 ta1, $18 - jr ra - mfc1 ta1, $19 - jr ra - mfc1 ta1, $20 - jr ra - mfc1 ta1, $21 - jr ra - mfc1 ta1, $22 - jr ra - mfc1 ta1, $23 - jr ra - mfc1 ta1, $24 - jr ra - mfc1 ta1, $25 - jr ra - mfc1 ta1, $26 - jr ra - mfc1 ta1, $27 - jr ra - mfc1 ta1, $28 - jr ra - mfc1 ta1, $29 - jr ra - mfc1 ta1, $30 - jr ra - mfc1 ta1, $31 - jr ra - -/* - * Put the value in ta2 into the single precission register which's number - * is in ta1. - */ -s_put_fpreg: - .set noat - sll ta1, 3 - la AT, 1f - daddu AT, ta1 - jr AT - .set at - -1: mtc1 ta2, $0 - jr ra - mtc1 ta2, $1 - jr ra - mtc1 ta2, $2 - jr ra - mtc1 ta2, $3 - jr ra - mtc1 ta2, $4 - jr ra - mtc1 ta2, $5 - jr ra - mtc1 ta2, $6 - jr ra - mtc1 ta2, $7 - jr ra - mtc1 ta2, $8 - jr ra - mtc1 ta2, $9 - jr ra - mtc1 ta2, $10 - jr ra - mtc1 ta2, $11 - jr ra - mtc1 ta2, $12 - jr ra - mtc1 ta2, $13 - jr ra - mtc1 ta2, $14 - jr ra - mtc1 ta2, $15 - jr ra - mtc1 ta2, $16 - jr ra - mtc1 ta2, $17 - jr ra - mtc1 ta2, $18 - jr ra - mtc1 ta2, $19 - jr ra - mtc1 ta2, $20 - jr ra - mtc1 ta2, $21 - jr ra - mtc1 ta2, $22 - jr ra - mtc1 ta2, $23 - jr ra - mtc1 ta2, $24 - jr ra - mtc1 ta2, $25 - jr ra - mtc1 ta2, $26 - jr ra - mtc1 ta2, $27 - jr ra - mtc1 ta2, $28 - jr ra - mtc1 ta2, $29 - jr ra - mtc1 ta2, $30 - jr ra - mtc1 ta2, $31 - jr ra - -/* Get the double precission register which's number is in ta1 into ta1/ta2. */ -d_get_fpreg: - .set noat - sll AT, ta1, 1 - sll ta1, 2 - daddu ta1, AT - la AT, 1f - daddu AT, ta1 - jr AT - .set at - -1: mfc1 ta1, $0 - mfc1 ta2, $1 - jr ra - mfc1 ta1, $2 - mfc1 ta2, $3 - jr ra - mfc1 ta1, $4 - mfc1 ta2, $5 - jr ra - mfc1 ta1, $6 - mfc1 ta2, $7 - jr ra - mfc1 ta1, $8 - mfc1 ta2, $9 - jr ra - mfc1 ta1, $10 - mfc1 ta2, $11 - jr ra - mfc1 ta1, $12 - mfc1 ta2, $13 - jr ra - mfc1 ta1, $14 - mfc1 ta2, $15 - jr ra - mfc1 ta1, $16 - mfc1 ta2, $17 - jr ra - mfc1 ta1, $18 - mfc1 ta2, $19 - jr ra - mfc1 ta1, $20 - mfc1 ta2, $21 - jr ra - mfc1 ta1, $22 - mfc1 ta2, $23 - jr ra - mfc1 ta1, $24 - mfc1 ta2, $25 - jr ra - mfc1 ta1, $26 - mfc1 ta2, $27 - jr ra - mfc1 ta1, $28 - mfc1 ta2, $29 - jr ra - mfc1 ta1, $30 - mfc1 ta2, $31 - jr ra - -/* - * Send an invalid operation exception. - */ -invalid: - ld ra, 0(sp) - daddu sp, 16 - jr ra - -/* - * Done, just skip over the current instruction - */ -done: - ld ra, 0(sp) - daddu sp, 16 - jr ra - -unimp: - /* We've run into an yet unknown instruction. This happens either - on new, yet unsupported CPU types or when the faulting instruction - is being executed for cache but has been overwritten in memory. */ - LOCK_KERNEL - move a1, ta0 - PRINT(KERN_DEBUG "FP support: unknown fp op %08lx, ") - PRINT("please mail to ralf@gnu.org.\n") - UNLOCK_KERNEL - - li a0, SIGILL # Die, sucker ... - move a1, $28 - jal force_sig - - ld ra, 0(sp) - daddu sp, 16 - jr ra - -/* - * Jump table for the lowest 6 bits of a cp1 instruction. - */ - .data -lowtab: .dword add, sub, mul, div, sqrt, abs, mov, neg - .dword round.l,trunc.l,ceil.l,floor.l,round.w,trunc.w,ceil.w,floor.w - .dword unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp - .dword unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp - .dword cvt.s, cvt.d, unimp, unimp, cvt.w, cvt.l, unimp, unimp - .dword unimp, unimp, unimp, unimp, unimp, unimp, unimp, unimp - .dword c.f, c.un, c.eq, c.ueq, c.olt, c.ult, c.ole, c.ule - .dword c.sf, c.ngle,c.seq, c.ngl, c.lt, c.nge, c.le, c.ngt diff -Nru a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c --- a/arch/mips64/kernel/syscall.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips64/kernel/syscall.c Fri Jun 27 14:19:59 2003 @@ -32,8 +32,6 @@ #include <asm/sysmips.h> #include <asm/uaccess.h> -u64 jiffies_64; - extern asmlinkage void syscall_trace(void); asmlinkage int sys_pipe(abi64_no_regargs, struct pt_regs regs) @@ -52,12 +50,71 @@ return res; } +unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ + +#define COLOUR_ALIGN(addr,pgoff) \ + ((((addr) + shm_align_mask) & ~shm_align_mask) + \ + (((pgoff) << PAGE_SHIFT) & shm_align_mask)) + +unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct vm_area_struct * vmm; + int do_color_align; + + if (flags & MAP_FIXED) { + /* + * We do not accept a shared mapping if it would violate + * cache aliasing constraints. + */ + if ((flags & MAP_SHARED) && (addr & shm_align_mask)) + return -EINVAL; + return addr; + } + + if (len > TASK_SIZE) + return -ENOMEM; + do_color_align = 0; + if (filp || (flags & MAP_SHARED)) + do_color_align = 1; + if (addr) { + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + vmm = find_vma(current->mm, addr); + if (TASK_SIZE - len >= addr && + (!vmm || addr + len <= vmm->vm_start)) + return addr; + } + addr = TASK_UNMAPPED_BASE; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(addr); + + for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { + /* At this point: (!vmm || addr < vmm->vm_end). */ + if (TASK_SIZE - len < addr) + return -ENOMEM; + if (!vmm || addr + len <= vmm->vm_start) + return addr; + addr = vmm->vm_end; + if (do_color_align) + addr = COLOUR_ALIGN(addr, pgoff); + } +} + asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, unsigned long prot, unsigned long flags, unsigned long fd, off_t offset) { struct file * file = NULL; - unsigned long error = -EFAULT; + unsigned long error; + + error = -EINVAL; + if (offset & ~PAGE_MASK) + goto out; if (!(flags & MAP_ANONYMOUS)) { error = -EBADF; @@ -72,33 +129,32 @@ up_write(¤t->mm->mmap_sem); if (file) fput(file); -out: +out: return error; } asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs) { - struct task_struct *p; - save_static(®s); - p = do_fork(SIGCHLD, regs.regs[29], ®s, 0); - return IS_ERR(p) ? PTR_ERR(p) : p->pid; + return do_fork(SIGCHLD, regs.regs[29], ®s, 0, NULL, NULL); } asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs) { unsigned long clone_flags; unsigned long newsp; - struct task_struct *p; + int *parent_tidptr, *child_tidptr; save_static(®s); clone_flags = regs.regs[4]; newsp = regs.regs[5]; if (!newsp) newsp = regs.regs[29]; - p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0); - return IS_ERR(p) ? PTR_ERR(p) : p->pid; + parent_tidptr = (int *) regs.regs[6]; + child_tidptr = (int *) regs.regs[7]; + return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, ®s, 0, + parent_tidptr, child_tidptr); } /* @@ -131,12 +187,10 @@ return -ENOSYS; } -asmlinkage int -_sys_sysmips(int cmd, long arg1, int arg2, int arg3) +asmlinkage int sys_sysmips(int cmd, long arg1, int arg2, int arg3) { - int *p; + int tmp, len; char *name; - int tmp, len, errno; switch(cmd) { case SETNAME: { @@ -150,11 +204,12 @@ len = strncpy_from_user(nodename, name, __NEW_UTS_LEN); if (len < 0) return -EFAULT; - nodename[__NEW_UTS_LEN] = '\0'; down_write(&uts_sem); + strncpy(system_utsname.nodename, nodename, len); + nodename[__NEW_UTS_LEN] = '\0'; strlcpy(system_utsname.nodename, nodename, - sizeof(system_utsname.nodename)); + sizeof(system_utsname.nodename)); up_write(&uts_sem); return 0; } @@ -169,7 +224,7 @@ return 0; case FLUSH_CACHE: - _flush_cache_l2(); + __flush_cache_all(); return 0; case MIPS_RDNVRAM: @@ -207,7 +262,7 @@ } case MSGSND: - return sys_msgsnd (first, (struct msgbuf *) ptr, + return sys_msgsnd (first, (struct msgbuf *) ptr, second, third); case MSGRCV: switch (version) { @@ -215,9 +270,9 @@ struct ipc_kludge tmp; if (!ptr) return -EINVAL; - + if (copy_from_user(&tmp, - (struct ipc_kludge *) ptr, + (struct ipc_kludge *) ptr, sizeof (tmp))) return -EFAULT; return sys_msgrcv (first, tmp.msgp, second, @@ -247,7 +302,7 @@ return -EINVAL; return sys_shmat (first, (char *) ptr, second, (ulong *) third); } - case SHMDT: + case SHMDT: return sys_shmdt ((char *)ptr); case SHMGET: return sys_shmget (first, second, third); @@ -255,15 +310,14 @@ return sys_shmctl (first, second, (struct shmid_ds *) ptr); default: - return -EINVAL; + return -ENOSYS; } } /* * No implemented yet ... */ -asmlinkage int -sys_cachectl(char *addr, int nbytes, int op) +asmlinkage int sys_cachectl(char *addr, int nbytes, int op) { return -ENOSYS; } diff -Nru a/arch/mips64/kernel/time.c b/arch/mips64/kernel/time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/kernel/time.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,602 @@ +/* + * Copyright 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * Common time service routines for MIPS machines. See + * Documents/mips/README.txt. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/param.h> +#include <linux/time.h> +#include <linux/smp.h> +#include <linux/kernel_stat.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <linux/module.h> + +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/time.h> +#include <asm/hardirq.h> +#include <asm/div64.h> + +/* This is for machines which generate the exact clock. */ +#define USECS_PER_JIFFY (1000000/HZ) +#define USECS_PER_JIFFY_FRAC ((u32)((1000000ULL << 32) / HZ)) + +#define TICK_SIZE (tick_nsec / 1000) + +u64 jiffies_64; + +/* + * forward reference + */ +extern volatile unsigned long wall_jiffies; + +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; + +/* + * whether we emulate local_timer_interrupts for SMP machines. + */ +int emulate_local_timer_interrupt; + +/* + * By default we provide the null RTC ops + */ +static unsigned long null_rtc_get_time(void) +{ + return mktime(2000, 1, 1, 0, 0, 0); +} + +static int null_rtc_set_time(unsigned long sec) +{ + return 0; +} + +unsigned long (*rtc_get_time)(void) = null_rtc_get_time; +int (*rtc_set_time)(unsigned long) = null_rtc_set_time; + + +/* + * This version of gettimeofday has microsecond resolution and better than + * microsecond precision on fast machines with cycle counter. + */ +void do_gettimeofday(struct timeval *tv) +{ + unsigned long seq; + unsigned long usec, sec; + + do { + seq = read_seqbegin(&xtime_lock); + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + } while (read_seqretry(&xtime_lock, seq)); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +int do_settimeofday(struct timespec *tv) +{ + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! + */ + tv->tv_nsec -= do_gettimeoffset() * NSEC_PER_USEC; + tv->tv_nsec -= (jiffies - wall_jiffies) * TICK_NSEC; + + while (tv->tv_nsec < 0) { + tv->tv_nsec += NSEC_PER_SEC; + tv->tv_sec--; + } + + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = tv->tv_nsec; + time_adjust = 0; /* stop active adjtime() */ + time_status |= STA_UNSYNC; + time_maxerror = NTP_PHASE_LIMIT; + time_esterror = NTP_PHASE_LIMIT; + write_sequnlock_irq(&xtime_lock); + + return 0; +} + + +/* + * Gettimeoffset routines. These routines returns the time duration + * since last timer interrupt in usecs. + * + * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. + * Otherwise use calibrate_gettimeoffset() + * + * If the CPU does not have counter register all, you can either supply + * your own gettimeoffset() routine, or use null_gettimeoffset() routines, + * which gives the same resolution as HZ. + */ + + +/* This is for machines which generate the exact clock. */ +#define USECS_PER_JIFFY (1000000/HZ) + +/* usecs per counter cycle, shifted to left by 32 bits */ +static unsigned int sll32_usecs_per_cycle=0; + +/* how many counter cycles in a jiffy */ +static unsigned long cycles_per_jiffy=0; + +/* Cycle counter value at the previous timer interrupt.. */ +static unsigned int timerhi, timerlo; + +/* expirelo is the count value for next CPU timer interrupt */ +static unsigned int expirelo; + +/* last time when xtime and rtc are sync'ed up */ +static long last_rtc_update; + +/* the function pointer to one of the gettimeoffset funcs*/ +unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; + +unsigned long null_gettimeoffset(void) +{ + return 0; +} + +unsigned long fixed_rate_gettimeoffset(void) +{ + u32 count; + unsigned long res; + + /* Get last timer tick in absolute kernel time */ + count = read_c0_count(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu\t%1,%2\n\t" + "mfhi\t%0" + :"=r" (res) + :"r" (count), + "r" (sll32_usecs_per_cycle)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + + return res; +} + +/* + * Cached "1/(clocks per usec)*2^32" value. + * It has to be recalculated once each jiffy. + */ +static unsigned long cached_quotient; + +/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ +static unsigned long last_jiffies = 0; + + +/* + * This is copied from dec/time.c:do_ioasic_gettimeoffset() by Mercij. + */ +unsigned long calibrate_div32_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + unsigned long quotient; + + tmp = jiffies; + + quotient = cached_quotient; + + if (last_jiffies != tmp) { + last_jiffies = tmp; + if (last_jiffies != 0) { + unsigned long r0; + do_div64_32(r0, timerhi, timerlo, tmp); + do_div64_32(quotient, USECS_PER_JIFFY, + USECS_PER_JIFFY_FRAC, r0); + cached_quotient = quotient; + } + } + + /* Get last timer tick in absolute kernel time */ + count = read_c0_count(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu %2,%3" + : "=l" (tmp), "=h" (res) + : "r" (count), "r" (quotient)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY - 1; + + return res; +} + +unsigned long calibrate_div64_gettimeoffset(void) +{ + u32 count; + unsigned long res, tmp; + unsigned long quotient; + + tmp = jiffies; + + quotient = cached_quotient; + + if (tmp && last_jiffies != tmp) { + last_jiffies = tmp; + __asm__(".set\tnoreorder\n\t" + ".set\tnoat\n\t" + ".set\tmips3\n\t" + "lwu\t%0,%2\n\t" + "dsll32\t$1,%1,0\n\t" + "or\t$1,$1,%0\n\t" + "ddivu\t$0,$1,%3\n\t" + "mflo\t$1\n\t" + "dsll32\t%0,%4,0\n\t" + "nop\n\t" + "ddivu\t$0,%0,$1\n\t" + "mflo\t%0\n\t" + ".set\tmips0\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=&r" (quotient) + :"r" (timerhi), + "m" (timerlo), + "r" (tmp), + "r" (USECS_PER_JIFFY)); + cached_quotient = quotient; + } + + /* Get last timer tick in absolute kernel time */ + count = read_c0_count(); + + /* .. relative to previous jiffy (32 bits is enough) */ + count -= timerlo; + + __asm__("multu\t%1,%2\n\t" + "mfhi\t%0" + :"=r" (res) + :"r" (count), + "r" (quotient)); + + /* + * Due to possible jiffies inconsistencies, we need to check + * the result so that we'll get a timer that is monotonic. + */ + if (res >= USECS_PER_JIFFY) + res = USECS_PER_JIFFY-1; + + return res; +} + + +/* + * local_timer_interrupt() does profiling and process accounting + * on a per-CPU basis. + * + * In UP mode, it is invoked from the (global) timer_interrupt. + * + * In SMP mode, it might invoked by per-CPU timer interrupt, or + * a broadcasted inter-processor interrupt which itself is triggered + * by the global timer interrupt. + */ +void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + if (!user_mode(regs)) { + if (prof_buffer && current->pid) { + extern int _stext; + unsigned long pc = regs->cp0_epc; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Dont ignore out-of-bounds pc values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len-1) + pc = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[pc]); + } + } + +#ifdef CONFIG_SMP + /* in UP mode, update_process_times() is invoked by do_timer() */ + update_process_times(user_mode(regs)); +#endif +} + +/* + * high-level timer interrupt service routines. This function + * is set as irqaction->handler and is invoked through do_IRQ. + */ +irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + if (cpu_has_counter) { + unsigned int count; + + /* ack timer interrupt, and try to set next interrupt */ + expirelo += cycles_per_jiffy; + write_c0_compare(expirelo); + count = read_c0_count(); + + /* check to see if we have missed any timer interrupts */ + if ((count - expirelo) < 0x7fffffff) { + /* missed_timer_count ++; */ + expirelo = count + cycles_per_jiffy; + write_c0_compare(expirelo); + } + + /* Update timerhi/timerlo for intra-jiffy calibration. */ + timerhi += count < timerlo; /* Wrap around */ + timerlo = count; + } + + /* + * call the generic timer interrupt handling + */ + do_timer(regs); + + /* + * If we have an externally synchronized Linux clock, then update + * CMOS clock accordingly every ~11 minutes. rtc_set_time() has to be + * called as close as possible to 500 ms before the new second starts. + */ + write_seqlock(&xtime_lock); + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && + (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { + if (rtc_set_time(xtime.tv_sec) == 0) { + last_rtc_update = xtime.tv_sec; + } else { + last_rtc_update = xtime.tv_sec - 600; + /* do it again in 60 s */ + } + } + write_sequnlock(&xtime_lock); + + /* + * If jiffies has overflowed in this timer_interrupt we must + * update the timer[hi]/[lo] to make fast gettimeoffset funcs + * quotient calc still valid. -arca + */ + if (!jiffies) { + timerhi = timerlo = 0; + } + +#if !defined(CONFIG_SMP) + /* + * In UP mode, we call local_timer_interrupt() to do profiling + * and process accouting. + * + * In SMP mode, local_timer_interrupt() is invoked by appropriate + * low-level local timer interrupt handler. + */ + local_timer_interrupt(0, NULL, regs); + +#else /* CONFIG_SMP */ + + if (emulate_local_timer_interrupt) { + /* + * this is the place where we send out inter-process + * interrupts and let each CPU do its own profiling + * and process accouting. + * + * Obviously we need to call local_timer_interrupt() for + * the current CPU too. + */ + panic("Not implemented yet!!!"); + } +#endif /* CONFIG_SMP */ + + return IRQ_HANDLED; +} + +asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + + /* we keep interrupt disabled all the time */ + timer_interrupt(irq, NULL, regs); + + irq_exit(); + + if (softirq_pending(cpu)) + do_softirq(); +} + +asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + + irq_enter(); + kstat_cpu(cpu).irqs[irq]++; + + /* we keep interrupt disabled all the time */ + local_timer_interrupt(irq, NULL, regs); + + irq_exit(); + + if (softirq_pending(cpu)) + do_softirq(); +} + +/* + * time_init() - it does the following things. + * + * 1) board_time_init() - + * a) (optional) set up RTC routines, + * b) (optional) calibrate and set the mips_counter_frequency + * (only needed if you intended to use fixed_rate_gettimeoffset + * or use cpu counter as timer interrupt source) + * 2) setup xtime based on rtc_get_time(). + * 3) choose a appropriate gettimeoffset routine. + * 4) calculate a couple of cached variables for later usage + * 5) board_timer_setup() - + * a) (optional) over-write any choices made above by time_init(). + * b) machine specific code should setup the timer irqaction. + * c) enable the timer interrupt + */ + +void (*board_time_init)(void) = NULL; +void (*board_timer_setup)(struct irqaction *irq) = NULL; + +unsigned int mips_counter_frequency = 0; + +static struct irqaction timer_irqaction = { + timer_interrupt, + SA_INTERRUPT, + 0, + "timer", + NULL, + NULL +}; + +void __init time_init(void) +{ + if (board_time_init) + board_time_init(); + + xtime.tv_sec = rtc_get_time(); + xtime.tv_nsec = 0; + + /* choose appropriate gettimeoffset routine */ + if (!cpu_has_counter) { + /* no cpu counter - sorry */ + do_gettimeoffset = null_gettimeoffset; + } else if (mips_counter_frequency != 0) { + /* we have cpu counter and know counter frequency! */ + do_gettimeoffset = fixed_rate_gettimeoffset; + } else if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || + (current_cpu_data.isa_level == MIPS_CPU_ISA_II) ) { + /* we need to calibrate the counter but we don't have + * 64-bit division. */ + do_gettimeoffset = calibrate_div32_gettimeoffset; + } else { + /* we need to calibrate the counter but we *do* have + * 64-bit division. */ + do_gettimeoffset = calibrate_div64_gettimeoffset; + } + + /* caclulate cache parameters */ + if (mips_counter_frequency) { + cycles_per_jiffy = mips_counter_frequency / HZ; + + /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ + /* any better way to do this? */ + sll32_usecs_per_cycle = mips_counter_frequency / 100000; + sll32_usecs_per_cycle = 0xffffffff / sll32_usecs_per_cycle; + sll32_usecs_per_cycle *= 10; + + /* + * For those using cpu counter as timer, this sets up the + * first interrupt + */ + write_c0_compare(cycles_per_jiffy); + write_c0_count(0); + expirelo = cycles_per_jiffy; + } + + /* + * Call board specific timer interrupt setup. + * + * this pointer must be setup in machine setup routine. + * + * Even if the machine choose to use low-level timer interrupt, + * it still needs to setup the timer_irqaction. + * In that case, it might be better to set timer_irqaction.handler + * to be NULL function so that we are sure the high-level code + * is not invoked accidentally. + */ + board_timer_setup(&timer_irqaction); +} + +#define FEBRUARY 2 +#define STARTOFTIME 1970 +#define SECDAY 86400L +#define SECYR (SECDAY * 365) +#define leapyear(year) ((year) % 4 == 0) +#define days_in_year(a) (leapyear(a) ? 366 : 365) +#define days_in_month(a) (month_days[(a) - 1]) + +static int month_days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +void to_tm(unsigned long tim, struct rtc_time * tm) +{ + long hms, day, gday; + int i; + + gday = day = tim / SECDAY; + hms = tim % SECDAY; + + /* Hours, minutes, seconds are easy */ + tm->tm_hour = hms / 3600; + tm->tm_min = (hms % 3600) / 60; + tm->tm_sec = (hms % 3600) % 60; + + /* Number of years in days */ + for (i = STARTOFTIME; day >= days_in_year(i); i++) + day -= days_in_year(i); + tm->tm_year = i; + + /* Number of months in days left */ + if (leapyear(tm->tm_year)) + days_in_month(FEBRUARY) = 29; + for (i = 1; day >= days_in_month(i); i++) + day -= days_in_month(i); + days_in_month(FEBRUARY) = 28; + tm->tm_mon = i-1; /* tm_mon starts from 0 to 11 */ + + /* Days are what is left over (+1) from all that. */ + tm->tm_mday = day + 1; + + /* + * Determine the day of week + */ + tm->tm_wday = (gday + 4) % 7; /* 1970/1/1 was Thursday */ +} + +EXPORT_SYMBOL(rtc_lock); diff -Nru a/arch/mips64/kernel/traps.c b/arch/mips64/kernel/traps.c --- a/arch/mips64/kernel/traps.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips64/kernel/traps.c Fri Jun 27 14:19:58 2003 @@ -3,29 +3,39 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 - 1999 by Ralf Baechle + * Copyright (C) 1994 - 1999, 2000, 01 Ralf Baechle * Copyright (C) 1995, 1996 Paul M. Antoine * Copyright (C) 1998 Ulf Carlsson * Copyright (C) 1999 Silicon Graphics, Inc. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000, 01 MIPS Technologies, Inc. + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ #include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/spinlock.h> +#include <linux/kallsyms.h> +#include <asm/bootinfo.h> #include <asm/branch.h> -#include <asm/cachectl.h> +#include <asm/cpu.h> +#include <asm/fpu.h> +#include <asm/module.h> #include <asm/pgtable.h> -#include <asm/io.h> -#include <asm/bootinfo.h> #include <asm/ptrace.h> -#include <asm/watch.h> +#include <asm/sections.h> #include <asm/system.h> +#include <asm/tlbdebug.h> +#include <asm/traps.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> +#include <asm/watch.h> +#include <asm/types.h> extern asmlinkage void __xtlb_mod(void); extern asmlinkage void __xtlb_tlbl(void); @@ -41,15 +51,16 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); +extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); -static char *cpu_names[] = CPU_NAMES; +extern int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp, + struct mips_fpu_soft_struct *ctx); -char watch_available = 0; -char dedicated_iv_available = 0; -char vce_available = 0; -char mips4_available = 0; +void (*board_be_init)(void); +int (*board_be_handler)(struct pt_regs *regs, int is_fixup); /* * These constant is for searching for possible module text segments. @@ -61,84 +72,70 @@ * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... */ -void show_stack(unsigned long *sp) +void show_stack(struct task_struct *task, unsigned long *sp) { + const int field = 2 * sizeof(unsigned long); + long stackdata; int i; - unsigned long *stack; - - stack = sp; - i = 0; - printk("Stack:"); - while ((unsigned long) stack & (PAGE_SIZE - 1)) { - unsigned long stackdata; + sp = sp ? sp : (unsigned long *) &sp; - if (__get_user(stackdata, stack++)) { - printk(" (Bad stack address)"); + printk("Stack: "); + i = 1; + while ((unsigned long) sp & (PAGE_SIZE - 1)) { + if (i && ((i % (64 / sizeof(unsigned long))) == 0)) + printk("\n "); + if (i > 40) { + printk(" ..."); break; } - printk(" %016lx", stackdata); - - if (++i > 40) { - printk(" ..."); + if (__get_user(stackdata, sp++)) { + printk(" (Bad stack address)"); break; } - if (i % 4 == 0) - printk("\n "); + printk(" %0*lx", field, stackdata); + i++; } + printk("\n"); } -void show_trace(unsigned long *sp) +void show_trace(struct task_struct *task, unsigned long *stack) { - int i; - unsigned long *stack; - unsigned long kernel_start, kernel_end; - unsigned long module_start, module_end; - extern char _stext, _etext; - - stack = sp; - i = 0; - - kernel_start = (unsigned long) &_stext; - kernel_end = (unsigned long) &_etext; - module_start = VMALLOC_START; - module_end = module_start + MODULE_RANGE; - - printk("\nCall Trace:"); + const int field = 2 * sizeof(unsigned long); + unsigned long addr; - while ((unsigned long) stack & (PAGE_SIZE -1)) { - unsigned long addr; + if (!stack) + stack = (unsigned long*)&stack; - if (__get_user(addr, stack++)) { - printk(" (Bad stack address)\n"); - break; + printk("Call Trace:"); +#ifdef CONFIG_KALLSYMS + printk("\n"); +#endif + while (((long) stack & (THREAD_SIZE-1)) != 0) { + addr = *stack++; + if (kernel_text_address(addr)) { + printk(" [<%0*lx>] ", field, addr); + print_symbol("%s\n", addr); } + } + printk("\n"); +} - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ +void show_trace_task(struct task_struct *tsk) +{ + show_trace(tsk, (long *)tsk->thread.reg29); +} - if ((addr >= kernel_start && addr < kernel_end) || - (addr >= module_start && addr < module_end)) { +/* + * The architecture-independent dump_stack generator + */ +void dump_stack(void) +{ + unsigned long stack; - /* Since our kernel is still at KSEG0, - * truncate the address so that ksymoops - * understands it. - */ - printk(" [<%08x>]", (unsigned int) addr); - if (++i > 40) { - printk(" ..."); - break; - } - } - } + show_trace(current, &stack); } void show_code(unsigned int *pc) @@ -153,120 +150,369 @@ printk(" (Bad address in epc)\n"); break; } - printk("%c%08x%c",(i?' ':'<'),insn,(i?' ':'>')); + printk("%c%08x%c", (i?' ':'<'), insn, (i?' ':'>')); + } +} + +void show_regs(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); + int i; + + printk("Cpu %d\n", smp_processor_id()); + + /* + * Saved main processor registers + */ + for (i = 0; i < 32; i++) { + if ((i % 4) == 0) + printk("$%2d :", i); + if (i == 0) + printk(" %0*lx", field, 0UL); + else if (i == 26 || i == 27) + printk(" %*s", field, ""); + else + printk(" %0*lx", field, regs->regs[i]); + + i++; + if ((i % 4) == 0) + printk("\n"); } + + printk("Hi : %0*lx\n", field, regs->hi); + printk("Lo : %0*lx\n", field, regs->lo); + + /* + * Saved cp0 registers + */ + printk("epc : %0*lx %s\n", field, regs->cp0_epc, print_tainted()); + printk("Status: %0*lx\n", field, regs->cp0_status); + printk("Cause : %0*lx\n", field, regs->cp0_cause); + + if (regs->cp0_status & ST0_KX) + printk("KX "); + if (regs->cp0_status & ST0_SX) + printk("SX "); + if (regs->cp0_status & ST0_UX) + printk("UX "); + switch (regs->cp0_status & ST0_KSU) { + case KSU_USER: + printk("USER "); + break; + case KSU_SUPERVISOR: + printk("SUPERVISOR "); + break; + case KSU_KERNEL: + printk("KERNEL "); + break; + default: + printk("BAD_MODE "); + break; + } + if (regs->cp0_status & ST0_ERL) + printk("ERL "); + if (regs->cp0_status & ST0_EXL) + printk("EXL "); + if (regs->cp0_status & ST0_IE) + printk("IE "); } -spinlock_t die_lock; +void show_registers(struct pt_regs *regs) +{ + const int field = 2 * sizeof(unsigned long); -void die(const char * str, struct pt_regs * regs, unsigned long err) + show_regs(regs); + printk("Process %s (pid: %d, stackpage=%0*lx)\n", + current->comm, current->pid, field, (unsigned long) current); + show_stack(current, (long *) regs->regs[29]); + show_trace(current, (long *) regs->regs[29]); + show_code((unsigned int *) regs->cp0_epc); + printk("\n"); +} + +static spinlock_t die_lock = SPIN_LOCK_UNLOCKED; + +void __die(const char * str, struct pt_regs * regs, const char * file, + const char * func, unsigned long line) { static int die_counter; - if (user_mode(regs)) /* Just return if in user mode. */ - return; console_verbose(); spin_lock_irq(&die_lock); - printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); - show_regs(regs); - printk("Process %s (pid: %d, stackpage=%08lx)\n", - current->comm, current->pid, (unsigned long) current); - show_stack((unsigned long *) regs->regs[29]); - show_trace((unsigned long *) regs->regs[29]); - show_code((unsigned int *) regs->cp0_epc); - printk("\n"); + printk("%s", str); + if (file && func) + printk(" in %s:%s, line %ld", file, func, line); + printk("[#%d]:\n", ++die_counter); + show_registers(regs); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); } -void die_if_kernel(const char * str, struct pt_regs * regs, unsigned long err) +void __die_if_kernel(const char * str, struct pt_regs * regs, + const char * file, const char * func, unsigned long line) { if (!user_mode(regs)) - die(str, regs, err); + __die(str, regs, file, func, line); +} + +extern const struct exception_table_entry __start___dbe_table[]; +extern const struct exception_table_entry __stop___dbe_table[]; + +void __declare_dbe_table(void) +{ + __asm__ __volatile__( + ".section\t__dbe_table,\"a\"\n\t" + ".previous" + ); } -void do_ov(struct pt_regs *regs) +asmlinkage void do_be(struct pt_regs *regs) { - if (compute_return_epc(regs)) + const int field = 2 * sizeof(unsigned long); + const struct exception_table_entry *fixup = NULL; + int data = regs->cp0_cause & 4; + int action = MIPS_BE_FATAL; + + /* XXX For now. Fixme, this searches the wrong table ... */ + if (data && !user_mode(regs)) + fixup = search_exception_tables(regs->cp0_epc); + + if (fixup) + action = MIPS_BE_FIXUP; + + if (board_be_handler) + action = board_be_handler(regs, fixup != 0); + + switch (action) { + case MIPS_BE_DISCARD: return; - force_sig(SIGFPE, current); + case MIPS_BE_FIXUP: + if (fixup) { + regs->cp0_epc = fixup->nextinsn; + return; + } + break; + default: + break; + } + + /* + * Assume it would be too dangerous to continue ... + */ + printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n", + data ? "Data" : "Instruction", + field, regs->cp0_epc, field, regs->regs[31]); + die_if_kernel("Oops", regs); + force_sig(SIGBUS, current); } -#ifdef CONFIG_MIPS_FPE_MODULE -static void (*fpe_handler)(struct pt_regs *regs, unsigned int fcr31); +static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) +{ + unsigned int *epc; + + epc = (unsigned int *) regs->cp0_epc + + ((regs->cp0_cause & CAUSEF_BD) != 0); + if (!get_user(*opcode, epc)) + return 0; + + force_sig(SIGSEGV, current); + return 1; +} + +/* + * ll/sc emulation + */ + +#define OPCODE 0xfc000000 +#define BASE 0x03e00000 +#define RT 0x001f0000 +#define OFFSET 0x0000ffff +#define LL 0xc0000000 +#define SC 0xe0000000 /* - * Register_fpe/unregister_fpe are for debugging purposes only. To make - * this hack work a bit better there is no error checking. + * The ll_bit is cleared by r*_switch.S */ -int register_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)) + +unsigned long ll_bit; + +static struct task_struct *ll_task = NULL; + +static inline void simulate_ll(struct pt_regs *regs, unsigned int opcode) { - fpe_handler = handler; - return 0; + unsigned long value, *vaddr; + long offset; + int signal = 0; + + /* + * analyse the ll instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (get_user(value, vaddr)) { + signal = SIGSEGV; + goto sig; + } + + if (ll_task == NULL || ll_task == current) { + ll_bit = 1; + } else { + ll_bit = 0; + } + ll_task = current; + + regs->regs[(opcode & RT) >> 16] = value; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); } -int unregister_fpe(void (*handler)(struct pt_regs *regs, unsigned int fcr31)) +static inline void simulate_sc(struct pt_regs *regs, unsigned int opcode) { - fpe_handler = NULL; - return 0; + unsigned long *vaddr, reg; + long offset; + int signal = 0; + + /* + * analyse the sc instruction that just caused a ri exception + * and put the referenced address to addr. + */ + + /* sign extend offset */ + offset = opcode & OFFSET; + offset <<= 16; + offset >>= 16; + + vaddr = (unsigned long *)((long)(regs->regs[(opcode & BASE) >> 21]) + offset); + reg = (opcode & RT) >> 16; + + if ((unsigned long)vaddr & 3) { + signal = SIGBUS; + goto sig; + } + if (ll_bit == 0 || ll_task != current) { + regs->regs[reg] = 0; + compute_return_epc(regs); + return; + } + + if (put_user(regs->regs[reg], vaddr)) { + signal = SIGSEGV; + goto sig; + } + + regs->regs[reg] = 1; + + compute_return_epc(regs); + return; + +sig: + force_sig(signal, current); } -#endif /* - * XXX Delayed fp exceptions when doing a lazy ctx switch XXX + * ll uses the opcode of lwc0 and sc uses the opcode of swc0. That is both + * opcodes are supposed to result in coprocessor unusable exceptions if + * executed on ll/sc-less processors. That's the theory. In practice a + * few processors such as NEC's VR4100 throw reserved instruction exceptions + * instead, so we're doing the emulation thing in both exception handlers. */ -void do_fpe(struct pt_regs *regs, unsigned long fcr31) +static inline int simulate_llsc(struct pt_regs *regs) { - unsigned long pc; - unsigned int insn; - extern void simfp(unsigned int); - -#ifdef CONFIG_MIPS_FPE_MODULE - if (fpe_handler != NULL) { - fpe_handler(regs, fcr31); - return; - } -#endif - if (fcr31 & 0x20000) { - /* Retry instruction with flush to zero ... */ - if (!(fcr31 & (1<<24))) { - printk("Setting flush to zero for %s.\n", - current->comm); - fcr31 &= ~0x20000; - fcr31 |= (1<<24); - __asm__ __volatile__( - "ctc1\t%0,$31" - : /* No outputs */ - : "r" (fcr31)); - return; - } - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); - if (get_user(insn, (unsigned int *)pc)) { - /* XXX Can this happen? */ - force_sig(SIGSEGV, current); - } + unsigned int opcode; - printk(KERN_DEBUG "Unimplemented exception for insn %08x at 0x%08lx in %s.\n", - insn, regs->cp0_epc, current->comm); - simfp(insn); + if (unlikely(get_insn_opcode(regs, &opcode))) + return -EFAULT; + + if ((opcode & OPCODE) == LL) { + simulate_ll(regs, opcode); + return 0; + } + if ((opcode & OPCODE) == SC) { + simulate_sc(regs, opcode); + return 0; } - if (compute_return_epc(regs)) + return -EFAULT; /* Strange things going on ... */ +} + +asmlinkage void do_ov(struct pt_regs *regs) +{ + siginfo_t info; + + info.si_code = FPE_INTOVF; + info.si_signo = SIGFPE; + info.si_errno = 0; + info.si_addr = (void *)regs->cp0_epc; + force_sig_info(SIGFPE, &info, current); +} + +/* + * XXX Delayed fp exceptions when doing a lazy ctx switch XXX + */ +asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) +{ + if (fcr31 & FPU_CSR_UNI_X) { + int sig; + + /* + * Unimplemented operation exception. If we've got the full + * software emulator on-board, let's use it... + * + * Force FPU to dump state into task/thread context. We're + * moving a lot of data here for what is probably a single + * instruction, but the alternative is to pre-decode the FP + * register operands before invoking the emulator, which seems + * a bit extreme for what should be an infrequent event. + */ + save_fp(current); + + /* Run the emulator */ + sig = fpu_emulator_cop1Handler (0, regs, + ¤t->thread.fpu.soft); + + /* + * We can't allow the emulated instruction to leave any of + * the cause bit set in $fcr31. + */ + current->thread.fpu.soft.sr &= ~FPU_CSR_ALL_X; + + /* Restore the hardware register state */ + restore_fp(current); + + /* If something went wrong, signal */ + if (sig) + force_sig(sig, current); + return; - //force_sig(SIGFPE, current); - printk(KERN_DEBUG "Should send SIGFPE to %s\n", current->comm); + } + + force_sig(SIGFPE, current); } -void do_bp(struct pt_regs *regs) +asmlinkage void do_bp(struct pt_regs *regs) { unsigned int opcode, bcode; - unsigned int *epc; siginfo_t info; - epc = (unsigned int *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (get_user(opcode, epc)) - goto sigsegv; + die_if_kernel("Break instruction in kernel code", regs); + + if (get_insn_opcode(regs, &opcode)) + return; /* * There is the ancient bug in the MIPS assemblers that the break @@ -290,160 +536,243 @@ info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; - info.si_addr = (void *)compute_return_epc(regs); + info.si_addr = (void *)regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; default: force_sig(SIGTRAP, current); } - - force_sig(SIGTRAP, current); - return; - -sigsegv: - force_sig(SIGSEGV, current); } -void do_tr(struct pt_regs *regs) +asmlinkage void do_tr(struct pt_regs *regs) { - unsigned int opcode, bcode; - unsigned int *epc; + unsigned int opcode, tcode = 0; siginfo_t info; - epc = (unsigned int *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (get_user(opcode, epc)) - goto sigsegv; + die_if_kernel("Trap instruction in kernel code", regs); - bcode = ((opcode >> 6) & ((1 << 20) - 1)); + if (get_insn_opcode(regs, &opcode)) + return; + + /* Immediate versions don't provide a code. */ + if (!(opcode & OPCODE)) + tcode = ((opcode >> 6) & ((1 << 20) - 1)); /* - * (A short test says that IRIX 5.3 sends SIGTRAP for all break - * insns, even for break codes that indicate arithmetic failures. - * Wiered ...) + * (A short test says that IRIX 5.3 sends SIGTRAP for all trap + * insns, even for trap codes that indicate arithmetic failures. + * Weird ...) * But should we continue the brokenness??? --macro */ - switch (bcode) { + switch (tcode) { case 6: case 7: - if (bcode == 7) + if (tcode == 7) info.si_code = FPE_INTDIV; else info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; - info.si_addr = (void *)compute_return_epc(regs); + info.si_addr = (void *)regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; default: force_sig(SIGTRAP, current); } - return; - -sigsegv: - force_sig(SIGSEGV, current); } -void do_ri(struct pt_regs *regs) +asmlinkage void do_ri(struct pt_regs *regs) { - printk("Cpu%d[%s:%d] Illegal instruction at %08lx ra=%08lx\n", - smp_processor_id(), current->comm, current->pid, regs->cp0_epc, - regs->regs[31]); - if (compute_return_epc(regs)) - return; + die_if_kernel("Reserved instruction in kernel code", regs); + + if (!cpu_has_llsc) + if (!simulate_llsc(regs)) + return; + force_sig(SIGILL, current); } -void do_cpu(struct pt_regs *regs) +asmlinkage void do_cpu(struct pt_regs *regs) { - u32 cpid; + unsigned int cpid; + + die_if_kernel("do_cpu invoked from kernel context!", regs); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; - if (cpid != 1) - goto bad_cid; - regs->cp0_status |= ST0_CU1; -#ifndef CONFIG_SMP - if (last_task_used_math == current) + switch (cpid) { + case 0: + if (cpu_has_llsc) + break; + + if (!simulate_llsc(regs)) + return; + break; + + case 1: + own_fpu(); + if (current->used_math) { /* Using the FPU again. */ + restore_fp(current); + } else { /* First time FPU user. */ + init_fpu(); + current->used_math = 1; + } + + if (!cpu_has_fpu) { + int sig = fpu_emulator_cop1Handler(0, regs, + ¤t->thread.fpu.soft); + if (sig) + force_sig(sig, current); + } + return; - if (current->used_math) { /* Using the FPU again. */ - lazy_fpu_switch(last_task_used_math, current); - } else { /* First time FPU user. */ - lazy_fpu_switch(last_task_used_math, 0); - init_fpu(); - current->used_math = 1; - } - last_task_used_math = current; -#else - if (current->used_math) { - lazy_fpu_switch(0, current); - } else { - init_fpu(); - current->used_math = 1; + case 2: + case 3: + break; } - current->flags |= PF_USEDFPU; -#endif - return; -bad_cid: force_sig(SIGILL, current); } -void do_watch(struct pt_regs *regs) +asmlinkage void do_mdmx(struct pt_regs *regs) +{ + force_sig(SIGILL, current); +} + +asmlinkage void do_watch(struct pt_regs *regs) { /* * We use the watch exception where available to detect stack * overflows. */ + dump_tlb_all(); show_regs(regs); panic("Caught WATCH exception - probably caused by stack overflow."); } -void do_reserved(struct pt_regs *regs) +asmlinkage void do_mcheck(struct pt_regs *regs) +{ + show_regs(regs); + dump_tlb_all(); + /* + * Some chips may have other causes of machine check (e.g. SB1 + * graduation timer) + */ + panic("Caught Machine Check exception - %scaused by multiple " + "matching entries in the TLB.", + (regs->cp0_status & ST0_TS) ? "" : "not "); +} + +asmlinkage void do_reserved(struct pt_regs *regs) { /* * Game over - no way to handle this if it ever occurs. Most probably * caused by a new unknown cpu type or after another deadly * hard/software error. */ + show_regs(regs); panic("Caught reserved exception %ld - should not happen.", - (regs->cp0_cause & 0x1f) >> 2); + (regs->cp0_cause & 0x7f) >> 2); } -static inline void watch_init(unsigned long cputype) +/* + * Some MIPS CPUs can enable/disable for cache parity detection, but do + * it different ways. + */ +static inline void parity_protection_init(void) { - switch(cputype) { - case CPU_R10000: - case CPU_R4000MC: - case CPU_R4400MC: - case CPU_R4000SC: - case CPU_R4400SC: - case CPU_R4000PC: - case CPU_R4400PC: - case CPU_R4200: - case CPU_R4300: - set_except_vector(23, handle_watch); - watch_available = 1; + switch (current_cpu_data.cputype) { + case CPU_5KC: + /* Set the PE bit (bit 31) in the c0_ecc register. */ + printk(KERN_INFO "Enable the cache parity protection for " + "MIPS 5KC CPUs.\n"); + write_c0_ecc(read_c0_ecc() | 0x80000000); + break; + default: break; } } +asmlinkage void cache_parity_error(void) +{ + const int field = 2 * sizeof(unsigned long); + unsigned int reg_val; + + /* For the moment, report the problem and hang. */ + printk("Cache error exception:\n"); + printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); + reg_val = read_c0_cacheerr(); + printk("c0_cacheerr == %08x\n", reg_val); + + printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", + reg_val & (1<<30) ? "secondary" : "primary", + reg_val & (1<<31) ? "data" : "insn"); + printk("Error bits: %s%s%s%s%s%s%s\n", + reg_val & (1<<29) ? "ED " : "", + reg_val & (1<<28) ? "ET " : "", + reg_val & (1<<26) ? "EE " : "", + reg_val & (1<<25) ? "EB " : "", + reg_val & (1<<24) ? "EI " : "", + reg_val & (1<<23) ? "E1 " : "", + reg_val & (1<<22) ? "E0 " : ""); + printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); + +#if defined(CONFIG_CPU_MIPS32) || defined (CONFIG_CPU_MIPS64) + if (reg_val & (1<<22)) + printk("DErrAddr0: 0x%08x\n", read_c0_derraddr0()); + + if (reg_val & (1<<23)) + printk("DErrAddr1: 0x%08x\n", read_c0_derraddr1()); +#endif + + panic("Can't handle the cache error!"); +} + /* - * Some MIPS CPUs have a dedicated interrupt vector which reduces the - * interrupt processing overhead. Use it where available. - * FIXME: more CPUs than just the Nevada have this feature. + * SDBBP EJTAG debug exception handler. + * We skip the instruction and return to the next instruction. */ -static inline void setup_dedicated_int(void) +void ejtag_exception_handler(struct pt_regs *regs) { - extern void except_vec4(void); + const int field = 2 * sizeof(unsigned long); + unsigned long depc, old_epc; + unsigned int debug; + + printk("SDBBP EJTAG debug exception - not handled yet, just ignored!\n"); + depc = read_c0_depc(); + debug = read_c0_debug(); + printk("c0_depc = %0*lx, DEBUG = %08x\n", field, depc, debug); + if (debug & 0x80000000) { + /* + * In branch delay slot. + * We cheat a little bit here and use EPC to calculate the + * debug return address (DEPC). EPC is restored after the + * calculation. + */ + old_epc = regs->cp0_epc; + regs->cp0_epc = depc; + __compute_return_epc(regs); + depc = regs->cp0_epc; + regs->cp0_epc = old_epc; + } else + depc += 4; + write_c0_depc(depc); + +#if 0 + printk("\n\n----- Enable EJTAG single stepping ----\n\n"); + write_c0_debug(debug | 0x100); +#endif +} - switch(mips_cputype) { - case CPU_NEVADA: - memcpy((void *)(KSEG0 + 0x200), except_vec4, 8); - set_cp0_cause(CAUSEF_IV, CAUSEF_IV); - dedicated_iv_available = 1; - } +/* + * NMI exception handler. + */ +void nmi_exception_handler(struct pt_regs *regs) +{ + printk("NMI taken!!!!\n"); + die("NMI", regs); + while(1) ; } unsigned long exception_handlers[32]; @@ -453,139 +782,160 @@ * to interrupt handlers in the address range from * KSEG0 <= x < KSEG0 + 256mb on the Nevada. Oh well ... */ -void set_except_vector(int n, void *addr) +void *set_except_vector(int n, void *addr) { unsigned long handler = (unsigned long) addr; + unsigned long old_handler = exception_handlers[n]; + exception_handlers[n] = handler; - if (n == 0 && dedicated_iv_available) { + if (n == 0 && cpu_has_divec) { *(volatile u32 *)(KSEG0+0x200) = 0x08000000 | (0x03ffffff & (handler >> 2)); flush_icache_range(KSEG0+0x200, KSEG0 + 0x204); } + return (void *)old_handler; } -static inline void mips4_setup(void) -{ - switch (mips_cputype) { - case CPU_R5000: - case CPU_R5000A: - case CPU_NEVADA: - case CPU_R8000: - case CPU_R10000: - mips4_available = 1; - set_cp0_status(ST0_XX, ST0_XX); - } -} +asmlinkage int (*save_fp_context)(struct sigcontext *sc); +asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + +extern asmlinkage int _save_fp_context(struct sigcontext *sc); +extern asmlinkage int _restore_fp_context(struct sigcontext *sc); -static inline void go_64(void) +extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); +extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); + +void __init per_cpu_trap_init(void) { - unsigned int bits; + unsigned int cpu = smp_processor_id(); + + /* Some firmware leaves the BEV flag set, clear it. */ + clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); + set_c0_status(ST0_CU0|ST0_FR|ST0_KX|ST0_SX|ST0_UX); + + /* + * Some MIPS CPUs have a dedicated interrupt vector which reduces the + * interrupt processing overhead. Use it where available. + */ + if (cpu_has_divec) + set_c0_cause(CAUSEF_IV); - bits = ST0_KX|ST0_SX|ST0_UX; - set_cp0_status(bits, bits); - printk("Entering 64-bit mode.\n"); + cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; + write_c0_context(((long)(&pgd_current[cpu])) << 23); + write_c0_wired(0); } void __init trap_init(void) { - extern char except_vec0; - extern char except_vec1_r10k; - extern char except_vec2_generic; + extern char except_vec0_generic; extern char except_vec3_generic, except_vec3_r4000; - extern void bus_error_init(void); + extern char except_vec_ejtag_debug; + extern char except_vec4; unsigned long i; - /* Some firmware leaves the BEV flag set, clear it. */ - set_cp0_status(ST0_BEV, 0); + per_cpu_trap_init(); - /* Copy the generic exception handler code to its final destination. */ - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + /* Copy the generic exception handlers to their final destination. */ + memcpy((void *) KSEG0 , &except_vec0_generic, 0x80); memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); /* * Setup default vectors */ - for(i = 0; i <= 31; i++) + for (i = 0; i <= 31; i++) set_except_vector(i, handle_reserved); /* + * Copy the EJTAG debug exception vector handler code to it's final + * destination. + */ + if (cpu_has_ejtag) + memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80); + + /* * Only some CPUs have the watch exceptions or a dedicated * interrupt vector. */ - watch_init(mips_cputype); - setup_dedicated_int(); - mips4_setup(); - go_64(); /* In memoriam C128 ;-) */ + if (cpu_has_watch) + set_except_vector(23, handle_watch); /* - * Handling the following exceptions depends mostly of the cpu type + * Some MIPS CPUs have a dedicated interrupt vector which reduces the + * interrupt processing overhead. Use it where available. */ - switch(mips_cputype) { - case CPU_R10000: - /* - * The R10000 is in most aspects similar to the R4400. It - * should get some special optimizations. - */ - write_32bit_cp0_register(CP0_FRAMEMASK, 0); - set_cp0_status(ST0_XX, ST0_XX); - goto r4k; - - case CPU_R4000MC: - case CPU_R4400MC: - case CPU_R4000SC: - case CPU_R4400SC: - vce_available = 1; - /* Fall through ... */ - case CPU_R4000PC: - case CPU_R4400PC: - case CPU_R4200: - case CPU_R4300: - case CPU_R4600: - case CPU_R5000: - case CPU_NEVADA: -r4k: - /* Debug TLB refill handler. */ - memcpy((void *)KSEG0, &except_vec0, 0x80); - memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80); - - /* Cache error vector */ - memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); - - if (vce_available) { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, - 0x180); - } else { - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, - 0x100); - } + if (cpu_has_divec) + memcpy((void *)(KSEG0 + 0x200), &except_vec4, 0x8); + + /* + * Some CPUs can enable/disable for cache parity detection, but does + * it different ways. + */ + parity_protection_init(); + + /* + * The Data Bus Errors / Instruction Bus Errors are signaled + * by external hardware. Therefore these two exceptions + * may have board specific handlers. + */ + if (board_be_init) + board_be_init(); - set_except_vector(1, __xtlb_mod); - set_except_vector(2, __xtlb_tlbl); - set_except_vector(3, __xtlb_tlbs); - set_except_vector(4, handle_adel); - set_except_vector(5, handle_ades); - - /* DBE / IBE exception handler are system specific. */ - bus_error_init(); - - set_except_vector(8, handle_sys); - set_except_vector(9, handle_bp); - set_except_vector(10, handle_ri); - set_except_vector(11, handle_cpu); - set_except_vector(12, handle_ov); - set_except_vector(13, handle_tr); + set_except_vector(1, __xtlb_mod); + set_except_vector(2, __xtlb_tlbl); + set_except_vector(3, __xtlb_tlbs); + set_except_vector(4, handle_adel); + set_except_vector(5, handle_ades); + + set_except_vector(6, handle_ibe); + set_except_vector(7, handle_dbe); + + set_except_vector(8, handle_sys); + set_except_vector(9, handle_bp); + set_except_vector(10, handle_ri); + set_except_vector(11, handle_cpu); + set_except_vector(12, handle_ov); + set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); + + if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); - break; - case CPU_R8000: - panic("unsupported CPU type %s.\n", cpu_names[mips_cputype]); - break; + if (cpu_has_mcheck) + set_except_vector(24, handle_mcheck); - case CPU_UNKNOWN: - default: - panic("Unknown CPU type"); + if (cpu_has_vce) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_r4000, 0x100); + else if (cpu_has_4kex) + memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80); + else + memcpy((void *)(KSEG0 + 0x080), &except_vec3_generic, 0x80); + + if (current_cpu_data.cputype == CPU_R6000 || + current_cpu_data.cputype == CPU_R6000A) { + /* + * The R6000 is the only R-series CPU that features a machine + * check exception (similar to the R4000 cache error) and + * unaligned ldc1/sdc1 exception. The handlers have not been + * written yet. Well, anyway there is no R6000 machine on the + * current list of targets for Linux/MIPS. + * (Duh, crap, there is someone with a tripple R6k machine) + */ + //set_except_vector(14, handle_mc); + //set_except_vector(15, handle_ndc); + } + + if (cpu_has_fpu) { + save_fp_context = _save_fp_context; + restore_fp_context = _restore_fp_context; + } else { + save_fp_context = fpu_emulator_save_context; + restore_fp_context = fpu_emulator_restore_context; } - flush_icache_range(KSEG0, KSEG0 + 0x200); + + flush_icache_range(KSEG0, KSEG0 + 0x400); + + if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + set_c0_status(ST0_XX); atomic_inc(&init_mm.mm_count); /* XXX UP? */ current->active_mm = &init_mm; diff -Nru a/arch/mips64/kernel/unaligned.c b/arch/mips64/kernel/unaligned.c --- a/arch/mips64/kernel/unaligned.c Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/kernel/unaligned.c Fri Jun 27 14:19:54 2003 @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1998, 1999 by Ralf Baechle + * Copyright (C) 1996, 1998, 1999, 2002 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * * This file contains exception handler for address error exception with the @@ -41,7 +41,7 @@ * * #include <stdio.h> * #include <asm/sysmips.h> - * + * * struct foo { * unsigned char bar[8]; * }; @@ -74,6 +74,7 @@ */ #include <linux/config.h> #include <linux/mm.h> +#include <linux/module.h> #include <linux/signal.h> #include <linux/smp.h> #include <linux/smp_lock.h> @@ -88,23 +89,22 @@ #define STR(x) __STR(x) #define __STR(x) #x -/* - * User code may only access USEG; kernel code may access the - * entire address space. - */ -#define check_axs(pc,a,s) \ - if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0) \ - goto sigbus; +#ifdef CONFIG_PROC_FS +unsigned long unaligned_instructions; +#endif -static inline void -emulate_load_store_insn(struct pt_regs *regs, - unsigned long addr, - unsigned long pc) +static inline int emulate_load_store_insn(struct pt_regs *regs, + void *addr, unsigned long pc, + unsigned long **regptr, unsigned long *newvalue) { union mips_instruction insn; - unsigned long value, fixup; + unsigned long value; + const struct exception_table_entry *fixup; + unsigned int res; regs->regs[0] = 0; + *regptr=NULL; + /* * This load never faults. */ @@ -144,186 +144,295 @@ * The remaining opcodes are the ones that are really of interest. */ case lh_op: - check_axs(pc, addr, 2); - __asm__( - ".set\tnoat\n" + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ (".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlb\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlb\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlb\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlb\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault) - :"$1"); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lw_op: - check_axs(pc, addr, 4); - __asm__( + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lhu_op: - check_axs(pc, addr, 2); - __asm__( + if (verify_area(VERIFY_READ, addr, 2)) + goto sigbus; + + __asm__ __volatile__ ( ".set\tnoat\n" #ifdef __BIG_ENDIAN - "1:\tlbu\t%0,0(%1)\n" - "2:\tlbu\t$1,1(%1)\n\t" + "1:\tlbu\t%0, 0(%2)\n" + "2:\tlbu\t$1, 1(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlbu\t%0,1(%1)\n" - "2:\tlbu\t$1,0(%1)\n\t" + "1:\tlbu\t%0, 1(%2)\n" + "2:\tlbu\t$1, 0(%2)\n\t" #endif - "sll\t%0,0x8\n\t" - "or\t%0,$1\n\t" - ".set\tat\n\t" + "sll\t%0, 0x8\n\t" + "or\t%0, $1\n\t" + "li\t%1, 0\n" + "3:\t.set\tat\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault) - :"$1"); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; case lwu_op: - check_axs(pc, addr, 4); - __asm__( +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 4)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tlwl\t%0,(%1)\n" - "2:\tlwr\t%0,3(%1)\n\t" + "1:\tlwl\t%0, (%2)\n" + "2:\tlwr\t%0, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tlwl\t%0,3(%1)\n" - "2:\tlwr\t%0,(%1)\n\t" + "1:\tlwl\t%0, 3(%2)\n" + "2:\tlwr\t%0, (%2)\n\t" #endif + "dsll\t%0, %0, 32\n\t" + "dsrl\t%0, %0, 32\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - value &= 0xffffffff; - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case ld_op: - check_axs(pc, addr, 8); - __asm__( - ".set\tmips3\n" +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_READ, addr, 8)) + goto sigbus; + + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tldl\t%0,(%1)\n" - "2:\tldr\t%0,7(%1)\n\t" + "1:\tldl\t%0, (%2)\n" + "2:\tldr\t%0, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tldl\t%0,7(%1)\n" - "2:\tldr\t%0,(%1)\n\t" + "1:\tldl\t%0, 7(%2)\n" + "2:\tldr\t%0, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%1, 0\n" + "3:\t.section\t.fixup,\"ax\"\n\t" + "4:\tli\t%1, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - :"=&r" (value) - :"r" (addr), "i" (&&fault)); - regs->regs[insn.i_format.rt] = value; - return; + : "=&r" (value), "=r" (res) + : "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + *newvalue = value; + *regptr = ®s->regs[insn.i_format.rt]; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case sh_op: - check_axs(pc, addr, 2); + if (verify_area(VERIFY_WRITE, addr, 2)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,1(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,0(%1)\n\t" + "1:\tsb\t%1, 1(%2)\n\t" + "srl\t$1, %1, 0x8\n" + "2:\tsb\t$1, 0(%2)\n\t" ".set\tat\n\t" #endif #ifdef __LITTLE_ENDIAN ".set\tnoat\n" - "1:\tsb\t%0,0(%1)\n\t" - "srl\t$1,%0,0x8\n" - "2:\tsb\t$1,1(%1)\n\t" + "1:\tsb\t%1, 0(%2)\n\t" + "srl\t$1,%1, 0x8\n" + "2:\tsb\t$1, 1(%2)\n\t" ".set\tat\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault) - :"$1"); - return; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sw_op: - check_axs(pc, addr, 4); + if (verify_area(VERIFY_WRITE, addr, 4)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tswl\t%0,(%1)\n" - "2:\tswr\t%0,3(%1)\n\t" + "1:\tswl\t%1,(%2)\n" + "2:\tswr\t%1, 3(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tswl\t%0,3(%1)\n" - "2:\tswr\t%0,(%1)\n\t" + "1:\tswl\t%1, 3(%2)\n" + "2:\tswr\t%1, (%2)\n\t" #endif + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; case sd_op: - check_axs(pc, addr, 8); +#ifdef CONFIG_MIPS64 + /* + * A 32-bit kernel might be running on a 64-bit processor. But + * if we're on a 32-bit processor and an i-cache incoherency + * or race makes us see a 64-bit instruction here the sdl/sdr + * would blow up, so for now we don't handle unaligned 64-bit + * instructions on 32-bit kernels. + */ + if (verify_area(VERIFY_WRITE, addr, 8)) + goto sigbus; + value = regs->regs[insn.i_format.rt]; - __asm__( - ".set\tmips3\n" + __asm__ __volatile__ ( #ifdef __BIG_ENDIAN - "1:\tsdl\t%0,(%1)\n" - "2:\tsdr\t%0,7(%1)\n\t" + "1:\tsdl\t%1,(%2)\n" + "2:\tsdr\t%1, 7(%2)\n\t" #endif #ifdef __LITTLE_ENDIAN - "1:\tsdl\t%0,7(%1)\n" - "2:\tsdr\t%0,(%1)\n\t" + "1:\tsdl\t%1, 7(%2)\n" + "2:\tsdr\t%1, (%2)\n\t" #endif - ".set\tmips0\n\t" + "li\t%0, 0\n" + "3:\n\t" + ".section\t.fixup,\"ax\"\n\t" + "4:\tli\t%0, %3\n\t" + "j\t3b\n\t" + ".previous\n\t" ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,%2\n\t" - STR(PTR)"\t2b,%2\n\t" + STR(PTR)"\t1b, 4b\n\t" + STR(PTR)"\t2b, 4b\n\t" ".previous" - : /* no outputs */ - :"r" (value), "r" (addr), "i" (&&fault)); - return; + : "=r" (res) + : "r" (value), "r" (addr), "i" (-EFAULT)); + if (res) + goto fault; + break; +#endif /* CONFIG_MIPS64 */ + + /* Cannot handle 64-bit instructions in 32-bit kernel */ + goto sigill; case lwc1_op: case ldc1_op: @@ -352,63 +461,97 @@ */ goto sigill; } - return; + +#ifdef CONFIG_PROC_FS + unaligned_instructions++; +#endif + + return 0; fault: /* Did we have an exception handler installed? */ - fixup = search_exception_table(regs->cp0_epc); + fixup = search_exception_tables(exception_epc(regs)); if (fixup) { - long new_epc; - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); + unsigned long new_epc = fixup->nextinsn; printk(KERN_DEBUG "%s: Forwarding exception at [<%lx>] (%lx)\n", current->comm, regs->cp0_epc, new_epc); regs->cp0_epc = new_epc; - return; + return 1; } die_if_kernel ("Unhandled kernel unaligned access", regs); send_sig(SIGSEGV, current, 1); - return; + + return 0; + sigbus: - die_if_kernel ("Unhandled kernel unaligned access", regs); + die_if_kernel("Unhandled kernel unaligned access", regs); send_sig(SIGBUS, current, 1); - return; + + return 0; + sigill: - die_if_kernel ("Unhandled kernel unaligned access or invalid instruction", regs); + die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs); send_sig(SIGILL, current, 1); - return; -} -#ifdef CONFIG_PROC_FS -unsigned long unaligned_instructions; -#endif + return 0; +} asmlinkage void do_ade(struct pt_regs *regs) { + unsigned long *regptr, newval; + extern int do_dsemulret(struct pt_regs *); + mm_segment_t seg; unsigned long pc; /* + * Address errors may be deliberately induced by the FPU emulator to + * retake control of the CPU after executing the instruction in the + * delay slot of an emulated branch. + */ + /* Terminate if exception was recognized as a delay slot return */ + if (do_dsemulret(regs)) + return; + + /* Otherwise handle as normal */ + + /* * Did we catch a fault trying to load an instruction? - * This also catches attempts to activate MIPS16 code on - * CPUs which don't support it. + * Or are we running in MIPS16 mode? */ - if (regs->cp0_badvaddr == regs->cp0_epc) + if ((regs->cp0_badvaddr == regs->cp0_epc) || (regs->cp0_epc & 0x1)) goto sigbus; - pc = regs->cp0_epc + ((regs->cp0_cause & CAUSEF_BD) ? 4 : 0); - if (compute_return_epc(regs)) - return; + pc = exception_epc(regs); if ((current->thread.mflags & MF_FIXADE) == 0) goto sigbus; - emulate_load_store_insn(regs, regs->cp0_badvaddr, pc); -#ifdef CONFIG_PROC_FS - unaligned_instructions++; -#endif + /* + * Do branch emulation only if we didn't forward the exception. + * This is all so but ugly ... + */ + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); + if (!emulate_load_store_insn(regs, (void *)regs->cp0_badvaddr, pc, + ®ptr, &newval)) { + compute_return_epc(regs); + /* + * Now that branch is evaluated, update the dest + * register if necessary + */ + if (regptr) + *regptr = newval; + } + set_fs(seg); return; sigbus: - die_if_kernel ("Kernel unaligned instruction access", regs); + die_if_kernel("Kernel unaligned instruction access", regs); force_sig(SIGBUS, current); + + /* + * XXX On return from the signal handler we should advance the epc + */ } diff -Nru a/arch/mips64/ld.script.elf64 b/arch/mips64/ld.script.elf64 --- a/arch/mips64/ld.script.elf64 Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,143 +0,0 @@ -OUTPUT_ARCH(mips) -ENTRY(kernel_entry) -jiffies = jiffies_64; -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - /* . = 0xc000000000000000; */ - - /* This is the value for an Origin kernel, taken from an IRIX kernel. */ - /* . = 0xc00000000001c000; */ - - /* Set the vaddr for the text segment to a value - >= 0xa800 0000 0001 9000 if no symmon is going to configured - >= 0xa800 0000 0030 0000 otherwise */ - - /* . = 0xa800000000300000; */ - /* . = 0xa800000000300000; */ - . = 0xffffffff80300000; - .text : { - *(.text) - *(.rodata) - *(.rodata.*) - *(.rodata1) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - } = 0 - .kstrtab : { *(.kstrtab) } - __vermagic : { *(__vermagic) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___dbe_table = .; /* Exception table for data bus errors */ - __dbe_table : { *(__dbe_table) } - __stop___dbe_table = .; - - _etext = .; - - . = ALIGN(16384); - .data.init_task : { *(.data.init_task) } - - /* Startup code */ - . = ALIGN(4096); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(16); - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) - } - __initcall_end = .; - . = ALIGN(4096); /* Align double page for init_task_union */ - __init_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - .fini : { *(.fini) } =0 - .reginfo : { *(.reginfo) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. It would - be more correct to do this: - . = .; - The current expression does not correctly handle the case of a - text segment ending precisely at the end of a page; it causes the - data segment to skip a page. The above expression does not have - this problem, but it will currently (2/95) cause BFD to allocate - a single segment, combining both text and data, for this case. - This will prevent the text segment from being shared among - multiple executions of the program; I think that is more - important than losing a page of the virtual address space (note - that no actual memory is lost; the page which is skipped can not - be referenced). */ - . = .; - .data : - { - _fdata = . ; - *(.data) - CONSTRUCTORS - } - .data1 : { *(.data1) } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - .got : { *(.got.plt) *(.got) } - .dynamic : { *(.dynamic) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } - _edata = .; - - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) - _end = . ; - } - - /* Sections to be discarded */ - /DISCARD/ : - { - *(.text.exit) - *(.data.exit) - *(.exitcall.exit) - } - - /* These are needed for ELF backends which have not yet been - converted to the new style linker. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - /* DWARF debug sections. - Symbols in the .debug DWARF section are relative to the beginning of the - section so we begin .debug at 0. It's not clear yet what needs to happen - for the others. */ - .debug 0 : { *(.debug) } - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_sfnames 0 : { *(.debug_sfnames) } - .line 0 : { *(.line) } - /* These must appear regardless of . */ - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } -} diff -Nru a/arch/mips64/lib/Makefile b/arch/mips64/lib/Makefile --- a/arch/mips64/lib/Makefile Fri Jun 27 14:20:01 2003 +++ b/arch/mips64/lib/Makefile Fri Jun 27 14:20:01 2003 @@ -2,9 +2,17 @@ # Makefile for MIPS-specific library files.. # -EXTRA_AFLAGS := $(CFLAGS) +lib-y += csum_partial.o csum_partial_copy.o memcpy.o \ + memset.o promlib.o rtc-std.o rtc-no.o strlen_user.o \ + strncpy_user.o strnlen_user.o watch.o + +ifeq ($(CONFIG_CPU_R3000)$(CONFIG_CPU_TX39XX),y) + lib-y += r3k_dump_tlb.o +else + lib-y += dump_tlb.o +endif -lib-y += csum_partial.o csum_partial_copy.o dump_tlb.o floppy-std.o \ - floppy-no.o ide-std.o ide-no.o kbd-std.o kbd-no.o rtc-std.o \ - rtc-no.o memset.o memcpy.o strlen_user.o strncpy_user.o \ - strnlen_user.o watch.o +lib-$(CONFIG_BLK_DEV_FD) += floppy-no.o floppy-std.o +lib-$(subst m,y,$(CONFIG_IDE)) += ide-std.o ide-no.o # needed for ide module + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips64/lib/csum_partial_copy.c b/arch/mips64/lib/csum_partial_copy.c --- a/arch/mips64/lib/csum_partial_copy.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips64/lib/csum_partial_copy.c Fri Jun 27 14:20:00 2003 @@ -16,8 +16,8 @@ /* * copy while checksumming, otherwise like csum_partial */ -unsigned int csum_partial_copy_nocheck(const char *src, char *dst, - int len, unsigned int sum) +unsigned int csum_partial_copy_nocheck(const char *src, char *dst, + int len, unsigned int sum) { /* * It's 2:30 am and I don't feel like doing it real ... @@ -44,6 +44,6 @@ memset(dst + len - missing, 0, missing); *err_ptr = -EFAULT; } - + return csum_partial(dst, len, sum); } diff -Nru a/arch/mips64/lib/dump_tlb.c b/arch/mips64/lib/dump_tlb.c --- a/arch/mips64/lib/dump_tlb.c Fri Jun 27 14:20:00 2003 +++ b/arch/mips64/lib/dump_tlb.c Fri Jun 27 14:20:00 2003 @@ -11,34 +11,47 @@ #include <asm/bootinfo.h> #include <asm/cachectl.h> +#include <asm/cpu.h> #include <asm/mipsregs.h> #include <asm/page.h> #include <asm/pgtable.h> -#define mips_tlb_entries 64 +static inline const char *msk2str(unsigned int mask) +{ + switch (mask) { + case PM_4K: return "4kb"; + case PM_16K: return "16kb"; + case PM_64K: return "64kb"; + case PM_256K: return "256kb"; + case PM_1M: return "1Mb"; + case PM_4M: return "4Mb"; + case PM_16M: return "16Mb"; + case PM_64M: return "64Mb"; + case PM_256M: return "256Mb"; + } +} -void -dump_tlb(int first, int last) +void dump_tlb(int first, int last) { unsigned long s_entryhi, entryhi, entrylo0, entrylo1, asid; unsigned int s_index, pagemask, c0, c1, i; - s_entryhi = get_entryhi(); - s_index = get_index(); + s_entryhi = read_c0_entryhi(); + s_index = read_c0_index(); asid = s_entryhi & 0xff; for (i = first; i <= last; i++) { - write_32bit_cp0_register(CP0_INDEX, i); + write_c0_index(i); __asm__ __volatile__( ".set\tnoreorder\n\t" "nop;nop;nop;nop\n\t" "tlbr\n\t" "nop;nop;nop;nop\n\t" ".set\treorder"); - pagemask = read_32bit_cp0_register(CP0_PAGEMASK); - entryhi = get_entryhi(); - entrylo0 = get_entrylo0(); - entrylo1 = get_entrylo1(); + pagemask = read_c0_pagemask(); + entryhi = read_c0_entryhi(); + entrylo0 = read_c0_entrylo0(); + entrylo1 = read_c0_entrylo1(); /* Unused entries have a virtual address of CKSEG0. */ if ((entryhi & ~0x1ffffUL) != CKSEG0 @@ -46,47 +59,44 @@ /* * Only print entries in use */ - printk("Index: %2d pgmask=%08x ", i, pagemask); + printk("Index: %2d pgmask=%s ", i, msk2str(pagemask)); c0 = (entrylo0 >> 3) & 7; c1 = (entrylo1 >> 3) & 7; - printk("va=%08lx asid=%02lx" - " [pa=%06lx c=%d d=%d v=%d g=%ld]" - " [pa=%06lx c=%d d=%d v=%d g=%ld]\n", + printk("va=%011lx asid=%02lx\n", (entryhi & ~0x1fffUL), - entryhi & 0xff, - entrylo0 & PAGE_MASK, c0, + entryhi & 0xff); + printk("\t[pa=%011lx c=%d d=%d v=%d g=%ld] ", + (entrylo0 << 6) & PAGE_MASK, c0, (entrylo0 & 4) ? 1 : 0, (entrylo0 & 2) ? 1 : 0, - (entrylo0 & 1), - entrylo1 & PAGE_MASK, c1, + (entrylo0 & 1)); + printk("[pa=%011lx c=%d d=%d v=%d g=%ld]\n", + (entrylo1 << 6) & PAGE_MASK, c1, (entrylo1 & 4) ? 1 : 0, (entrylo1 & 2) ? 1 : 0, (entrylo1 & 1)); - } } printk("\n"); - set_entryhi(s_entryhi); - set_index(s_index); + write_c0_entryhi(s_entryhi); + write_c0_index(s_index); } -void -dump_tlb_all(void) +void dump_tlb_all(void) { - dump_tlb(0, mips_tlb_entries - 1); + dump_tlb(0, current_cpu_data.tlbsize - 1); } -void -dump_tlb_wired(void) +void dump_tlb_wired(void) { int wired; - wired = read_32bit_cp0_register(CP0_WIRED); + wired = read_c0_wired(); printk("Wired: %d", wired); - dump_tlb(0, read_32bit_cp0_register(CP0_WIRED)); + dump_tlb(0, read_c0_wired()); } #define BARRIER \ @@ -95,21 +105,20 @@ "nop;nop;nop;nop;nop;nop;nop\n\t" \ ".set\treorder"); -void -dump_tlb_addr(unsigned long addr) +void dump_tlb_addr(unsigned long addr) { unsigned int flags, oldpid; int index; local_irq_save(flags); - oldpid = get_entryhi() & 0xff; + oldpid = read_c0_entryhi() & 0xff; BARRIER; - set_entryhi((addr & PAGE_MASK) | oldpid); + write_c0_entryhi((addr & PAGE_MASK) | oldpid); BARRIER; tlb_probe(); BARRIER; - index = get_index(); - set_entryhi(oldpid); + index = read_c0_index(); + write_c0_entryhi(oldpid); local_irq_restore(flags); if (index < 0) { @@ -121,14 +130,12 @@ dump_tlb(index, index); } -void -dump_tlb_nonwired(void) +void dump_tlb_nonwired(void) { - dump_tlb(read_32bit_cp0_register(CP0_WIRED), mips_tlb_entries - 1); + dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1); } -void -dump_list_process(struct task_struct *t, void *address) +void dump_list_process(struct task_struct *t, void *address) { pgd_t *page_dir, *pgd; pmd_t *pmd; @@ -154,7 +161,7 @@ printk("pte == %08lx, ", (unsigned long) pte); page = *pte; - printk("page == %08lx\n", (unsigned long) pte_val(page)); + printk("page == %08lx\n", pte_val(page)); val = pte_val(page); if (val & _PAGE_PRESENT) printk("present "); @@ -194,8 +201,7 @@ { int i; - for(i=0;i<8;i++) - { + for(i = 0; i < 8; i++) { printk("*%08lx == %08lx, ", (unsigned long)p, (unsigned long)*p); p++; diff -Nru a/arch/mips64/lib/floppy-std.c b/arch/mips64/lib/floppy-std.c --- a/arch/mips64/lib/floppy-std.c Fri Jun 27 14:19:58 2003 +++ b/arch/mips64/lib/floppy-std.c Fri Jun 27 14:19:58 2003 @@ -15,11 +15,11 @@ #include <linux/linkage.h> #include <linux/types.h> #include <linux/mm.h> + #include <asm/bootinfo.h> #include <asm/cachectl.h> #include <asm/dma.h> #include <asm/floppy.h> -#include <asm/keyboard.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/pgtable.h> @@ -100,23 +100,9 @@ return 0x3f0; } -/* Pure 2^n version of get_order */ -static int __get_order(unsigned long size) -{ - int order; - - size = (size-1) >> (PAGE_SHIFT-1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; -} - static unsigned long std_fd_dma_mem_alloc(unsigned long size) { - int order = __get_order(size); + int order = get_order(size); unsigned long mem; mem = __get_dma_pages(GFP_KERNEL,order); @@ -125,8 +111,8 @@ } static void std_fd_dma_mem_free(unsigned long addr, unsigned long size) -{ - free_pages(addr, __get_order(size)); +{ + free_pages(addr, get_order(size)); } static unsigned long std_fd_drive_type(unsigned long n) diff -Nru a/arch/mips64/lib/ide-no.c b/arch/mips64/lib/ide-no.c --- a/arch/mips64/lib/ide-no.c Fri Jun 27 14:19:30 2003 +++ b/arch/mips64/lib/ide-no.c Fri Jun 27 14:19:30 2003 @@ -12,7 +12,6 @@ #include <linux/kernel.h> #include <linux/ide.h> #include <asm/hdreg.h> -#include <asm/ptrace.h> static int no_ide_default_irq(ide_ioreg_t base) { diff -Nru a/arch/mips64/lib/ide-std.c b/arch/mips64/lib/ide-std.c --- a/arch/mips64/lib/ide-std.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips64/lib/ide-std.c Fri Jun 27 14:19:57 2003 @@ -11,7 +11,6 @@ #include <linux/ide.h> #include <linux/ioport.h> #include <linux/hdreg.h> -#include <asm/ptrace.h> #include <asm/hdreg.h> static int std_ide_default_irq(ide_ioreg_t base) @@ -30,16 +29,11 @@ static ide_ioreg_t std_ide_default_io_base(int index) { - switch (index) { - case 0: return 0x1f0; - case 1: return 0x170; - case 2: return 0x1e8; - case 3: return 0x168; - case 4: return 0x1e0; - case 5: return 0x160; - default: - return 0; - } + static unsigned long ata_io_base[MAX_HWIFS] = { + 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 + }; + + return ata_io_base[index]; } static void std_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, diff -Nru a/arch/mips64/lib/kbd-no.c b/arch/mips64/lib/kbd-no.c --- a/arch/mips64/lib/kbd-no.c Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,62 +0,0 @@ -/* - * 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. - * - * Stub keyboard and psaux routines to keep Linux from crashing on machines - * without a keyboard. - * - * Copyright (C) 1998 by Ralf Baechle - */ -#include <linux/sched.h> -#include <asm/keyboard.h> - -static void no_kbd_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int no_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static int no_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return -ENODEV; -} - -static void no_aux_free_irq(void) -{ -} - -static unsigned char no_kbd_read_input(void) -{ - return 0; -} - -static void no_kbd_write_output(unsigned char val) -{ -} - -static void no_kbd_write_command(unsigned char val) -{ -} - -static unsigned char no_kbd_read_status(void) -{ - return 0; -} - -struct kbd_ops no_kbd_ops = { - no_kbd_request_region, - no_kbd_request_irq, - - no_aux_request_irq, - no_aux_free_irq, - - no_kbd_read_input, - no_kbd_write_output, - no_kbd_write_command, - no_kbd_read_status -}; diff -Nru a/arch/mips64/lib/kbd-std.c b/arch/mips64/lib/kbd-std.c --- a/arch/mips64/lib/kbd-std.c Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,80 +0,0 @@ -/* - * 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. - * - * Routines for standard PC style keyboards accessible via I/O ports. - * - * Copyright (C) 1998, 1999 by Ralf Baechle - */ -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/pc_keyb.h> -#include <asm/keyboard.h> -#include <asm/io.h> - -#define KEYBOARD_IRQ 1 -#define AUX_IRQ 12 - -static void std_kbd_request_region(void) -{ - request_region(0x60, 16, "keyboard"); -} - -static int std_kbd_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return request_irq(KEYBOARD_IRQ, handler, 0, "keyboard", NULL); -} - -static int std_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - return request_irq(AUX_IRQ, handler, 0, "PS/2 Mouse", NULL); -} - -static void std_aux_free_irq(void) -{ - free_irq(AUX_IRQ, NULL); -} - -static unsigned char std_kbd_read_input(void) -{ - return inb(KBD_DATA_REG); -} - -static void std_kbd_write_output(unsigned char val) -{ - int status; - - do { - status = inb(KBD_CNTL_REG); - } while (status & KBD_STAT_IBF); - outb(val, KBD_DATA_REG); -} - -static void std_kbd_write_command(unsigned char val) -{ - int status; - - do { - status = inb(KBD_CNTL_REG); - } while (status & KBD_STAT_IBF); - outb(val, KBD_CNTL_REG); -} - -static unsigned char std_kbd_read_status(void) -{ - return inb(KBD_STATUS_REG); -} - -struct kbd_ops std_kbd_ops = { - std_kbd_request_region, - std_kbd_request_irq, - - std_aux_request_irq, - std_aux_free_irq, - - std_kbd_read_input, - std_kbd_write_output, - std_kbd_write_command, - std_kbd_read_status -}; diff -Nru a/arch/mips64/lib/memcpy.S b/arch/mips64/lib/memcpy.S --- a/arch/mips64/lib/memcpy.S Fri Jun 27 14:19:53 2003 +++ b/arch/mips64/lib/memcpy.S Fri Jun 27 14:19:53 2003 @@ -5,766 +5,502 @@ * * Unified implementation of memcpy, memmove and the __copy_user backend. * - * Copyright (C) 1998, 1999, 2000, 2001 Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc. + * Copyright (C) 2002 Broadcom, Inc. + * memcpy/copy_user author: Mark Vandevoorde * - * For __rmemcpy and memmove an exception is always a kernel bug, therefore - * they're not protected. In order to keep the exception fixup routine - * simple all memory accesses in __copy_user to src rsp. dst are stricly - * incremental. The fixup routine depends on $at not being changed. + * Mnemonic names for arguments to memcpy/__copy_user */ +#include <linux/config.h> #include <asm/asm.h> #include <asm/offset.h> #include <asm/regdef.h> +#define dst a0 +#define src a1 +#define len a2 + /* - * The fixup routine for copy_to_user depends on copying strictly in - * increasing order. Gas expands the ulw/usw macros in the wrong order for - * little endian machines, so we cannot depend on them. + * Spec + * + * memcpy copies len bytes from src to dst and sets v0 to dst. + * It assumes that + * - src and dst don't overlap + * - src is readable + * - dst is writable + * memcpy uses the standard calling convention + * + * __copy_user copies up to len bytes from src to dst and sets a2 (len) to + * the number of uncopied bytes due to an exception caused by a read or write. + * __copy_user assumes that src and dst don't overlap, and that the call is + * implementing one of the following: + * copy_to_user + * - src is readable (no exceptions when reading src) + * copy_from_user + * - dst is writable (no exceptions when writing dst) + * __copy_user uses a non-standard calling convention; see + * include/asm-mips/uaccess.h + * + * When an exception happens on a load, the handler must + # ensure that all of the destination buffer is overwritten to prevent + * leaking information to user mode programs. */ -#ifdef __MIPSEB__ -#define uswL swl -#define uswU swr -#define ulwL lwl -#define ulwU lwr -#define usdL sdl -#define usdU sdr -#define uldL ldl -#define uldU ldr -#endif -#ifdef __MIPSEL__ -#define uswL swr -#define uswU swl -#define ulwL lwr -#define ulwU lwl -#define usdL sdr -#define usdU sdl -#define uldL ldr -#define uldU ldl -#endif -#define EX(insn,reg,addr,handler) \ -9: insn reg, addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - .previous +/* + * Implementation + */ -#define UEX(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 3 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ - .previous +/* + * The exception handler for loads requires that: + * 1- AT contain the address of the byte just past the end of the source + * of the copy, + * 2- src_entry <= src < AT, and + * 3- (dst - src) == (dst_entry - src_entry), + * The _entry suffix denotes values when __copy_user was called. + * + * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user + * (2) is met by incrementing src by the number of bytes copied + * (3) is met by not doing loads between a pair of increments of dst and src + * + * The exception handlers for stores adjust len (if necessary) and return. + * These handlers do not need to overwrite any data. + * + * For __rmemcpy and memmove an exception is always a kernel bug, therefore + * they're not protected. + */ -#define UEXD(insn,reg,addr,handler) \ -9: insn ## L reg, addr; \ -10: insn ## U reg, 7 + addr; \ - .section __ex_table,"a"; \ - PTR 9b, handler; \ - PTR 10b, handler; \ +#define EXC(inst_reg,addr,handler) \ +9: inst_reg, addr; \ + .section __ex_table,"a"; \ + PTR 9b, handler; \ .previous -/* ascending order, destination aligned */ -#define MOVE_BIGGERCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(ld, t0, (offset + 0x00)(src), l_fixup); \ - EX(ld, t1, (offset + 0x08)(src), l_fixup); \ - EX(ld, t2, (offset + 0x10)(src), l_fixup); \ - EX(ld, t3, (offset + 0x18)(src), l_fixup); \ - EX(sd, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sd, t1, (offset + 0x08)(dst), s_fixup); \ - EX(sd, t2, (offset + 0x10)(dst), s_fixup); \ - EX(sd, t3, (offset + 0x18)(dst), s_fixup); \ - EX(ld, t0, (offset + 0x20)(src), l_fixup); \ - EX(ld, t1, (offset + 0x28)(src), l_fixup); \ - EX(ld, t2, (offset + 0x30)(src), l_fixup); \ - EX(ld, t3, (offset + 0x38)(src), l_fixup); \ - EX(sd, t0, (offset + 0x20)(dst), s_fixup); \ - EX(sd, t1, (offset + 0x28)(dst), s_fixup); \ - EX(sd, t2, (offset + 0x30)(dst), s_fixup); \ - EX(sd, t3, (offset + 0x38)(dst), s_fixup) - -/* ascending order, destination aligned */ -#define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x00)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x04)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x08)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - EX(sw, t0, (offset + 0x10)(dst), s_fixup); \ - EX(sw, t1, (offset + 0x14)(dst), s_fixup); \ - EX(sw, t2, (offset + 0x18)(dst), s_fixup); \ - EX(sw, t3, (offset + 0x1c)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGGERCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(ld, t0, (offset + 0x00)(src), l_fixup); \ - EX(ld, t1, (offset + 0x08)(src), l_fixup); \ - EX(ld, t2, (offset + 0x10)(src), l_fixup); \ - EX(ld, t3, (offset + 0x18)(src), l_fixup); \ - UEXD(usd, t0, (offset + 0x00)(dst), s_fixup); \ - UEXD(usd, t1, (offset + 0x08)(dst), s_fixup); \ - UEXD(usd, t2, (offset + 0x10)(dst), s_fixup); \ - UEXD(usd, t3, (offset + 0x18)(dst), s_fixup); \ - EX(ld, t0, (offset + 0x20)(src), l_fixup); \ - EX(ld, t1, (offset + 0x28)(src), l_fixup); \ - EX(ld, t2, (offset + 0x30)(src), l_fixup); \ - EX(ld, t3, (offset + 0x38)(src), l_fixup); \ - UEXD(usd, t0, (offset + 0x20)(dst), s_fixup); \ - UEXD(usd, t1, (offset + 0x28)(dst), s_fixup); \ - UEXD(usd, t2, (offset + 0x30)(dst), s_fixup); \ - UEXD(usd, t3, (offset + 0x38)(dst), s_fixup) - -/* ascending order, destination unaligned */ -#define UMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - EX(lw, t0, (offset + 0x00)(src), l_fixup); \ - EX(lw, t1, (offset + 0x04)(src), l_fixup); \ - EX(lw, t2, (offset + 0x08)(src), l_fixup); \ - EX(lw, t3, (offset + 0x0c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x00)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x04)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x08)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x0c)(dst), s_fixup); \ - EX(lw, t0, (offset + 0x10)(src), l_fixup); \ - EX(lw, t1, (offset + 0x14)(src), l_fixup); \ - EX(lw, t2, (offset + 0x18)(src), l_fixup); \ - EX(lw, t3, (offset + 0x1c)(src), l_fixup); \ - UEX(usw, t0, (offset + 0x10)(dst), s_fixup); \ - UEX(usw, t1, (offset + 0x14)(dst), s_fixup); \ - UEX(usw, t2, (offset + 0x18)(dst), s_fixup); \ - UEX(usw, t3, (offset + 0x1c)(dst), s_fixup) +/* + * Only on the 64-bit kernel we can made use of 64-bit registers. + */ +#ifdef CONFIG_MIPS64 +#define USE_DOUBLE +#endif + +#ifdef USE_DOUBLE + +#define LOAD ld +#define LOADL ldl +#define LOADR ldr +#define STOREL sdl +#define STORER sdr +#define STORE sd +#define ADD daddu +#define SUB dsubu +#define SRL dsrl +#define SRA dsra +#define SLL dsll +#define SLLV dsllv +#define SRLV dsrlv +#define NBYTES 8 +#define LOG_NBYTES 3 + +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 + +#else + +#define LOAD lw +#define LOADL lwl +#define LOADR lwr +#define STOREL swl +#define STORER swr +#define STORE sw +#define ADD addu +#define SUB subu +#define SRL srl +#define SLL sll +#define SRA sra +#define SLLV sllv +#define SRLV srlv +#define NBYTES 4 +#define LOG_NBYTES 2 + +#endif /* USE_DOUBLE */ + +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define LDFIRST LOADR +#define LDREST LOADL +#define STFIRST STORER +#define STREST STOREL +#define SHIFT_DISCARD SLLV +#else +#define LDFIRST LOADL +#define LDREST LOADR +#define STFIRST STOREL +#define STREST STORER +#define SHIFT_DISCARD SRLV +#endif + +#define FIRST(unit) ((unit)*NBYTES) +#define REST(unit) (FIRST(unit)+NBYTES-1) +#define UNIT(unit) FIRST(unit) + +#define ADDRMASK (NBYTES-1) .text .set noreorder .set noat +/* + * A combined memcpy/__copy_user + * __copy_user sets len to 0 for success; else to an upper bound of + * the number of uncopied bytes. + * memcpy sets v0 to dst. + */ .align 5 LEAF(memcpy) /* a0=dst a1=src a2=len */ - move v0, a0 /* return value */ + move v0, dst /* return value */ __memcpy: FEXPORT(__copy_user) - xor ta0, a0, a1 - andi ta0, ta0, 0x7 - move t3, a0 - beqz ta0, can_align - sltiu t8, a2, 0x8 - - b memcpy_u_src # bad alignment - move ta2, a2 - -can_align: - bnez t8, small_memcpy # < 8 bytes to copy - move ta2, a2 - - beqz a2, out - andi t8, a1, 0x1 - -hword_align: - beqz t8, word_align - andi t8, a1, 0x2 - - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - daddu a0, a0, 0x1 - andi t8, a1, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a2, 56 - - EX(lh, ta0, (a1), l_fixup) - dsubu a2, a2, 0x2 - EX(sh, ta0, (a0), s_fixup) - sltiu t8, a2, 56 - daddu a0, a0, 0x2 - daddu a1, a1, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, qword_align - andi t8, a1, 0x8 - - EX(lw, ta0, 0x00(a1), l_fixup) - dsubu a2, a2, 0x4 - EX(sw, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x4 - daddu a0, a0, 0x4 - andi t8, a1, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, a1, 0x10 - - EX(lw, ta0, 0x00(a1), l_fixup) - EX(lw, ta1, 0x04(a1), l_fixup) - dsubu a2, a2, 0x8 - EX(sw, ta0, 0x00(a0), s_fixup) - EX(sw, ta1, 0x04(a0), s_fixup) - daddu a1, a1, 0x8 - andi t8, a1, 0x10 - daddu a0, a0, 0x8 - -oword_align: - beqz t8, begin_movement - srl t8, a2, 0x7 - - EX(lw, ta3, 0x00(a1), l_fixup) - EX(lw, t0, 0x04(a1), l_fixup) - EX(lw, ta0, 0x08(a1), l_fixup) - EX(lw, ta1, 0x0c(a1), l_fixup) - EX(sw, ta3, 0x00(a0), s_fixup) - EX(sw, t0, 0x04(a0), s_fixup) - EX(sw, ta0, 0x08(a0), s_fixup) - EX(sw, ta1, 0x0c(a0), s_fixup) - dsubu a2, a2, 0x10 - daddu a1, a1, 0x10 - srl t8, a2, 0x7 - daddu a0, a0, 0x10 - -begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -move_128bytes: - PREF (0, 2*128(a0)) - PREF (1, 2*128(a1)) - MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - MOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - daddu a1, a1, 0x80 - bnez t8, move_128bytes - daddu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -move_64bytes: - MOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - daddu a1, a1, 0x40 - daddu a0, a0, 0x40 - + /* + * Note: dst & src may be unaligned, len may be 0 + * Temps + */ +#define rem t8 + + /* + * The "issue break"s below are very approximate. + * Issue delays for dcache fills will perturb the schedule, as will + * load queue full replay traps, etc. + * + * If len < NBYTES use byte operations. + */ + PREF( 0, 0(src) ) + PREF( 1, 0(dst) ) + sltu t2, len, NBYTES + and t1, dst, ADDRMASK + PREF( 0, 1*32(src) ) + PREF( 1, 1*32(dst) ) + bnez t2, copy_bytes_checklen + and t0, src, ADDRMASK + PREF( 0, 2*32(src) ) + PREF( 1, 2*32(dst) ) + bnez t1, dst_unaligned + nop + bnez t0, src_unaligned_dst_aligned + /* + * use delay slot for fall-through + * src and dst are aligned; need to compute rem + */ +both_aligned: + SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter + beqz t0, cleanup_both_aligned # len < 8*NBYTES + and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES) + PREF( 0, 3*32(src) ) + PREF( 1, 3*32(dst) ) + .align 4 1: - beqz ta2, do_end_words - andi t8, a2, 0x1c - -move_32bytes: - MOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - daddu a1, a1, 0x20 - daddu a0, a0, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - srl t8, t8, 0x2 - -end_words: - EX(lw, ta0, (a1), l_fixup) - dsubu t8, t8, 0x1 - EX(sw, ta0, (a0), s_fixup) - daddu a1, a1, 0x4 - bnez t8, end_words - daddu a0, a0, 0x4 - -maybe_end_cruft: - andi ta2, a2, 0x3 - -small_memcpy: - beqz ta2, out - move a2, ta2 - -end_bytes: - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - bnez a2, end_bytes - daddu a0, a0, 0x1 - -out: jr ra - move a2, zero - -/* ------------------------------------------------------------------------- */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 8*NBYTES +EXC( LOAD t4, UNIT(4)(src), l_exc_copy) +EXC( LOAD t7, UNIT(5)(src), l_exc_copy) +EXC( STORE t0, UNIT(0)(dst), s_exc_p8u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p7u) +EXC( LOAD t0, UNIT(6)(src), l_exc_copy) +EXC( LOAD t1, UNIT(7)(src), l_exc_copy) + ADD src, src, 8*NBYTES + ADD dst, dst, 8*NBYTES +EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u) +EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u) +EXC( STORE t4, UNIT(-4)(dst), s_exc_p4u) +EXC( STORE t7, UNIT(-3)(dst), s_exc_p3u) +EXC( STORE t0, UNIT(-2)(dst), s_exc_p2u) +EXC( STORE t1, UNIT(-1)(dst), s_exc_p1u) + PREF( 0, 8*32(src) ) + PREF( 1, 8*32(dst) ) + bne len, rem, 1b + nop -/* Bad, bad. At least try to align the source */ + /* + * len == rem == the number of bytes left to copy < 8*NBYTES + */ +cleanup_both_aligned: + beqz len, done + sltu t0, len, 4*NBYTES + bnez t0, less_than_4units + and rem, len, (NBYTES-1) # rem = len % NBYTES + /* + * len >= 4*NBYTES + */ +EXC( LOAD t0, UNIT(0)(src), l_exc) +EXC( LOAD t1, UNIT(1)(src), l_exc_copy) +EXC( LOAD t2, UNIT(2)(src), l_exc_copy) +EXC( LOAD t3, UNIT(3)(src), l_exc_copy) + SUB len, len, 4*NBYTES + ADD src, src, 4*NBYTES +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + beqz len, done + ADD dst, dst, 4*NBYTES +less_than_4units: + /* + * rem = len % NBYTES + */ + beq rem, len, copy_bytes + nop +1: +EXC( LOAD t0, 0(src), l_exc) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne rem, len, 1b + ADD dst, dst, NBYTES + + /* + * src and dst are aligned, need to copy rem bytes (rem < NBYTES) + * A loop would do only a byte at a time with possible branch + * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE + * because can't assume read-access to dst. Instead, use + * STREST dst, which doesn't require read access to dst. + * + * This code should perform better than a simple loop on modern, + * wide-issue mips processors because the code has fewer branches and + * more instruction-level parallelism. + */ +#define bits t2 + beqz len, done + ADD t1, dst, len # t1 is just past last byte of dst + li bits, 8*NBYTES + SLL rem, len, 3 # rem = number of bits to keep +EXC( LOAD t0, 0(src), l_exc) + SUB bits, bits, rem # bits = number of bits to discard + SHIFT_DISCARD t0, t0, bits +EXC( STREST t0, -1(t1), s_exc) + jr ra + move len, zero +dst_unaligned: + /* + * dst is unaligned + * t0 = src & ADDRMASK + * t1 = dst & ADDRMASK; T1 > 0 + * len >= NBYTES + * + * Copy enough bytes to align dst + * Set match = (src and dst have same alignment) + */ +#define match rem +EXC( LDFIRST t3, FIRST(0)(src), l_exc) + ADD t2, zero, NBYTES +EXC( LDREST t3, REST(0)(src), l_exc_copy) + SUB t2, t2, t1 # t2 = number of bytes copied + xor match, t0, t1 +EXC( STFIRST t3, FIRST(0)(dst), s_exc) + beq len, t2, done + SUB len, len, t2 + ADD dst, dst, t2 + beqz match, both_aligned + ADD src, src, t2 + +src_unaligned_dst_aligned: + SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter + PREF( 0, 3*32(src) ) + beqz t0, cleanup_src_unaligned + and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES + PREF( 1, 3*32(dst) ) +1: +/* + * Avoid consecutive LD*'s to the same register since some mips + * implementations can't issue them in the same cycle. + * It's OK to load FIRST(N+1) before REST(N) because the two addresses + * are to the same unit (unless src is aligned, but it's not). + */ +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy) + SUB len, len, 4*NBYTES +EXC( LDREST t0, REST(0)(src), l_exc_copy) +EXC( LDREST t1, REST(1)(src), l_exc_copy) +EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy) +EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy) +EXC( LDREST t2, REST(2)(src), l_exc_copy) +EXC( LDREST t3, REST(3)(src), l_exc_copy) + PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed) + ADD src, src, 4*NBYTES +#ifdef CONFIG_CPU_SB1 + nop # improves slotting +#endif +EXC( STORE t0, UNIT(0)(dst), s_exc_p4u) +EXC( STORE t1, UNIT(1)(dst), s_exc_p3u) +EXC( STORE t2, UNIT(2)(dst), s_exc_p2u) +EXC( STORE t3, UNIT(3)(dst), s_exc_p1u) + PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed) + bne len, rem, 1b + ADD dst, dst, 4*NBYTES + +cleanup_src_unaligned: + beqz len, done + and rem, len, NBYTES-1 # rem = len % NBYTES + beq rem, len, copy_bytes + nop +1: +EXC( LDFIRST t0, FIRST(0)(src), l_exc) +EXC( LDREST t0, REST(0)(src), l_exc_copy) + ADD src, src, NBYTES + SUB len, len, NBYTES +EXC( STORE t0, 0(dst), s_exc_p1u) + bne len, rem, 1b + ADD dst, dst, NBYTES -memcpy_u_src: - bnez t8, small_memcpy # < 8 bytes? - move ta2, a2 - - daddiu ta0, a1, 7 # ta0: how much to align - ori ta0, 7 - xori ta0, 7 - dsubu ta0, a1 - - UEXD(uld, ta1, 0(a1), l_fixup) # dword alignment - UEXD(usd, ta1, 0(a0), s_fixup) - - daddu a1, ta0 # src - daddu a0, ta0 # dst - dsubu a2, ta0 # len - - sltiu t8, a2, 56 - bnez t8, u_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -u_qword_align: - beqz t8, u_oword_align - andi t8, a1, 0x10 - - EX(ld, ta0, 0x00(a1), l_fixup) - dsubu a2, a2, 0x8 - UEXD(usd, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x8 - andi t8, a1, 0x10 - daddu a0, a0, 0x8 - -u_oword_align: - beqz t8, u_begin_movement - srl t8, a2, 0x7 - - EX(lw, ta3, 0x08(a1), l_fixup) - EX(lw, t0, 0x0c(a1), l_fixup) - EX(lw, ta0, 0x00(a1), l_fixup) - EX(lw, ta1, 0x04(a1), l_fixup) - UEX(usw, ta3, 0x08(a0), s_fixup) - UEX(usw, t0, 0x0c(a0), s_fixup) - UEX(usw, ta0, 0x00(a0), s_fixup) - UEX(usw, ta1, 0x04(a0), s_fixup) - dsubu a2, a2, 0x10 - daddu a1, a1, 0x10 - srl t8, a2, 0x7 - daddu a0, a0, 0x10 - -u_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -u_move_128bytes: - UMOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - UMOVE_BIGGERCHUNK(a1, a0, 0x40, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - daddu a1, a1, 0x80 - bnez t8, u_move_128bytes - daddu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -u_move_64bytes: - UMOVE_BIGGERCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - daddu a1, a1, 0x40 - daddu a0, a0, 0x40 +copy_bytes_checklen: + beqz len, done + nop +copy_bytes: + /* 0 < len < NBYTES */ +#define COPY_BYTE(N) \ +EXC( lb t0, N(src), l_exc); \ + SUB len, len, 1; \ + beqz len, done; \ +EXC( sb t0, N(dst), s_exc_p1) + + COPY_BYTE(0) + COPY_BYTE(1) +#ifdef USE_DOUBLE + COPY_BYTE(2) + COPY_BYTE(3) + COPY_BYTE(4) + COPY_BYTE(5) +#endif +EXC( lb t0, NBYTES-2(src), l_exc) + SUB len, len, 1 + jr ra +EXC( sb t0, NBYTES-2(dst), s_exc_p1) +done: + jr ra + nop + END(memcpy) +l_exc_copy: + /* + * Copy bytes from src until faulting load address (or until a + * lb faults) + * + * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28) + * may be more than a byte beyond the last address. + * Hence, the lb below may get an exception. + * + * Assumes src < THREAD_BUADDR($28) + */ + LOAD t0, TI_TASK($28) + LOAD t0, THREAD_BUADDR(t0) 1: - beqz ta2, u_do_end_words - andi t8, a2, 0x1c +EXC( lb t1, 0(src), l_exc) + ADD src, src, 1 + sb t1, 0(dst) # can't fault -- we're copy_from_user + bne src, t0, 1b + ADD dst, dst, 1 +l_exc: + LOAD t0, THREAD_BUADDR($28) # t0 is just past last good address + LOAD t0, THREAD_BUADDR(t0) + nop + SUB len, AT, t0 # len number of uncopied bytes + /* + * Here's where we rely on src and dst being incremented in tandem, + * See (3) above. + * dst += (fault addr - src) to put dst at first byte to clear + */ + ADD dst, t0 # compute start address in a1 + SUB dst, src + /* + * Clear len bytes starting at dst. Can't call __bzero because it + * might modify len. An inefficient loop for these rare times... + */ + beqz len, done + SUB src, len, 1 +1: sb zero, 0(dst) + ADD dst, dst, 1 + bnez src, 1b + SUB src, src, 1 + jr ra + nop -u_move_32bytes: - UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - daddu a1, a1, 0x20 - daddu a0, a0, 0x20 - -u_do_end_words: - beqz t8, u_maybe_end_cruft - srl t8, t8, 0x2 - -u_end_words: - EX(lw, ta0, 0x00(a1), l_fixup) - dsubu t8, t8, 0x1 - UEX(usw, ta0, 0x00(a0), s_fixup) - daddu a1, a1, 0x4 - bnez t8, u_end_words - daddu a0, a0, 0x4 - -u_maybe_end_cruft: - andi ta2, a2, 0x3 - -u_cannot_optimize: - beqz ta2, out - move a2, ta2 - -u_end_bytes: - EX(lb, ta0, (a1), l_fixup) - dsubu a2, a2, 0x1 - EX(sb, ta0, (a0), s_fixup) - daddu a1, a1, 0x1 - bnez a2, u_end_bytes - daddu a0, a0, 0x1 - jr ra - move a2, zero - END(memcpy) +#define SEXC(n) \ +s_exc_p ## n ## u: \ + jr ra; \ + ADD len, len, n*NBYTES + +SEXC(8) +SEXC(7) +SEXC(6) +SEXC(5) +SEXC(4) +SEXC(3) +SEXC(2) +SEXC(1) -/* descending order, destination aligned */ -#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - sw t0, (offset + 0x10)(dst); \ - sw t1, (offset + 0x14)(dst); \ - sw t2, (offset + 0x18)(dst); \ - sw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - sw t0, (offset + 0x00)(dst); \ - sw t1, (offset + 0x04)(dst); \ - sw t2, (offset + 0x08)(dst); \ - sw t3, (offset + 0x0c)(dst) - -/* descending order, destination ununaligned */ -#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - usw t0, (offset + 0x10)(dst); \ - usw t1, (offset + 0x14)(dst); \ - usw t2, (offset + 0x18)(dst); \ - usw t3, (offset + 0x1c)(dst); \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - usw t0, (offset + 0x00)(dst); \ - usw t1, (offset + 0x04)(dst); \ - usw t2, (offset + 0x08)(dst); \ - usw t3, (offset + 0x0c)(dst) +s_exc_p1: + jr ra + ADD len, len, 1 +s_exc: + jr ra + nop .align 5 LEAF(memmove) - daddu t0, a0, a2 + ADD t0, a0, a2 + ADD t1, a1, a2 sltu t0, a1, t0 # dst + len <= src -> memcpy - daddu t1, a1, a2 sltu t1, a0, t1 # dst >= src + len -> memcpy and t0, t1 beqz t0, __memcpy - move v0, a0 /* return value */ beqz a2, r_out END(memmove) + /* fall through to __rmemcpy */ LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ - sltu t0, a1, a0 + sltu t0, a1, a0 beqz t0, r_end_bytes_up # src >= dst nop - daddu a0, a2 # dst = dst + len - daddu a1, a2 # src = src + len - -#if 0 /* Horror fix */ - xor ta0, a0, a1 - andi ta0, ta0, 0x3 - move t3, a0 - beqz ta0, r_can_align - sltiu t8, a2, 0x8 - - b r_memcpy_u_src # bad alignment - move ta2, a2 - -r_can_align: - bnez t8, r_small_memcpy # < 8 bytes to copy - move ta2, a2 - - beqz a2, r_out - andi t8, a1, 0x1 - -r_hword_align: - beqz t8, r_word_align - andi t8, a1, 0x2 - - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 - dsubu a0, a0, 0x1 - andi t8, a1, 0x2 - -r_word_align: - beqz t8, r_dword_align - sltiu t8, a2, 56 - - lh ta0, -2(a1) - dsubu a2, a2, 0x2 - sh ta0, -2(a0) - sltiu t8, a2, 56 - dsubu a0, a0, 0x2 - dsubu a1, a1, 0x2 - -r_dword_align: - bnez t8, r_do_end_words - move t8, a2 - - andi t8, a1, 0x4 - beqz t8, r_qword_align - andi t8, a1, 0x8 - - lw ta0, -4(a1) - dsubu a2, a2, 0x4 - sw ta0, -4(a0) - dsubu a1, a1, 0x4 - dsubu a0, a0, 0x4 - andi t8, a1, 0x8 - -r_qword_align: - beqz t8, r_oword_align - andi t8, a1, 0x10 - - dsubu a1, a1, 0x8 - lw ta0, 0x04(a1) - lw ta1, 0x00(a1) - dsubu a0, a0, 0x8 - sw ta0, 0x04(a0) - sw ta1, 0x00(a0) - dsubu a2, a2, 0x8 - - andi t8, a1, 0x10 - -r_oword_align: - beqz t8, r_begin_movement - srl t8, a2, 0x7 - - dsubu a1, a1, 0x10 - lw ta3, 0x08(a1) # assumes subblock ordering - lw t0, 0x0c(a1) - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x10 - sw ta3, 0x08(a0) - sw t0, 0x0c(a0) - sw ta0, 0x00(a0) - sw ta1, 0x04(a0) - dsubu a2, a2, 0x10 - srl t8, a2, 0x7 - -r_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -r_move_128bytes: - RMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - dsubu a1, a1, 0x80 - bnez t8, r_move_128bytes - dsubu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -r_move_64bytes: - dsubu a1, a1, 0x40 - dsubu a0, a0, 0x40 - RMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) - RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - -1: - beqz ta2, r_do_end_words - andi t8, a2, 0x1c - -r_move_32bytes: - dsubu a1, a1, 0x20 - dsubu a0, a0, 0x20 - RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - -r_do_end_words: - beqz t8, r_maybe_end_cruft - srl t8, t8, 0x2 - -r_end_words: - lw ta0, -4(a1) - dsubu t8, t8, 0x1 - sw ta0, -4(a0) - dsubu a1, a1, 0x4 - bnez t8, r_end_words - dsubu a0, a0, 0x4 - -r_maybe_end_cruft: - andi ta2, a2, 0x3 - -r_small_memcpy: - beqz ta2, r_out - move a2, ta2 -#endif /* Horror fix */ + ADD a0, a2 # dst = dst + len + ADD a1, a2 # src = src + len r_end_bytes: - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 + lb t0, -1(a1) + SUB a2, a2, 0x1 + sb t0, -1(a0) + SUB a1, a1, 0x1 bnez a2, r_end_bytes - dsubu a0, a0, 0x1 + SUB a0, a0, 0x1 r_out: - jr ra - move a2, zero + jr ra + move a2, zero r_end_bytes_up: lb t0, (a1) - dsubu a2, a2, 0x1 + SUB a2, a2, 0x1 sb t0, (a0) - daddu a1, a1, 0x1 + ADD a1, a1, 0x1 bnez a2, r_end_bytes_up - daddu a0, a0, 0x1 + ADD a0, a0, 0x1 jr ra move a2, zero - -#if 0 /* Horror fix */ -/* ------------------------------------------------------------------------- */ - -/* Bad, bad. At least try to align the source */ - -r_memcpy_u_src: - bnez t8, r_small_memcpy # < 8 bytes? - move ta2, a2 - - andi ta0, a1, 7 # ta0: how much to align - - ulw ta1, -8(a1) # dword alignment - ulw ta2, -4(a1) - usw ta1, -8(a0) - usw ta2, -4(a0) - - dsubu a1, ta0 # src - dsubu a0, ta0 # dst - dsubu a2, ta0 # len - - sltiu t8, a2, 56 - bnez t8, ru_do_end_words - andi t8, a2, 0x3c - - andi t8, a1, 8 # now qword aligned? - -ru_qword_align: - beqz t8, ru_oword_align - andi t8, a1, 0x10 - - dsubu a1, a1, 0x8 - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x8 - usw ta0, 0x00(a0) - usw ta1, 0x04(a0) - dsubu a2, a2, 0x8 - - andi t8, a1, 0x10 - -ru_oword_align: - beqz t8, ru_begin_movement - srl t8, a2, 0x7 - - dsubu a1, a1, 0x10 - lw ta3, 0x08(a1) # assumes subblock ordering - lw t0, 0x0c(a1) - lw ta0, 0x00(a1) - lw ta1, 0x04(a1) - dsubu a0, a0, 0x10 - usw ta3, 0x08(a0) - usw t0, 0x0c(a0) - usw ta0, 0x00(a0) - usw ta1, 0x04(a0) - dsubu a2, a2, 0x10 - - srl t8, a2, 0x7 - -ru_begin_movement: - beqz t8, 0f - andi ta2, a2, 0x40 - -ru_move_128bytes: - RUMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - dsubu a1, a1, 0x80 - bnez t8, ru_move_128bytes - dsubu a0, a0, 0x80 - -0: - beqz ta2, 1f - andi ta2, a2, 0x20 - -ru_move_64bytes: - dsubu a1, a1, 0x40 - dsubu a0, a0, 0x40 - RUMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) - RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - -1: - beqz ta2, ru_do_end_words - andi t8, a2, 0x1c - -ru_move_32bytes: - dsubu a1, a1, 0x20 - dsubu a0, a0, 0x20 - RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) - andi t8, a2, 0x1c - -ru_do_end_words: - beqz t8, ru_maybe_end_cruft - srl t8, t8, 0x2 - -ru_end_words: - lw ta0, -4(a1) - usw ta0, -4(a0) - dsubu t8, t8, 0x1 - dsubu a1, a1, 0x4 - bnez t8, ru_end_words - dsubu a0, a0, 0x4 - -ru_maybe_end_cruft: - andi ta2, a2, 0x3 - -ru_cannot_optimize: - beqz ta2, r_out - move a2, ta2 - -ru_end_bytes: - lb ta0, -1(a1) - dsubu a2, a2, 0x1 - sb ta0, -1(a0) - dsubu a1, a1, 0x1 - bnez a2, ru_end_bytes - dsubu a0, a0, 0x1 - - jr ra - move a2, zero -#endif /* Horror fix */ END(__rmemcpy) - -l_fixup: # clear the rest of the buffer - ld ta0, THREAD_BUADDR($28) - nop - dsubu a2, AT, ta0 # a2 bytes to go - daddu a0, ta0 # compute start address in a1 - dsubu a0, a1 - j __bzero - move a1, zero - -s_fixup: - jr ra - nop diff -Nru a/arch/mips64/lib/memset.S b/arch/mips64/lib/memset.S --- a/arch/mips64/lib/memset.S Fri Jun 27 14:19:59 2003 +++ b/arch/mips64/lib/memset.S Fri Jun 27 14:19:59 2003 @@ -52,7 +52,6 @@ 1: FEXPORT(__bzero) - .type __bzero, @function sltiu t0, a2, 8 /* very small region? */ bnez t0, small_memset andi t0, a0, 7 /* aligned? */ @@ -82,7 +81,7 @@ .set noreorder memset_partial: - la t1, 2f /* where to start */ + PTR_LA t1, 2f /* where to start */ .set noat dsrl AT, t0, 1 dsubu t1, AT @@ -90,8 +89,12 @@ jr t1 daddu a0, t0 /* dest ptr */ + .set push + .set noreorder + .set nomacro F_FILL64(a0, -64, a1, partial_fixup) /* ... but first do dwds ... */ -2: andi a2, 7 /* 0 <= n <= 7 to go */ +2: .set pop + andi a2, 7 /* 0 <= n <= 7 to go */ beqz a2, 1f daddu a0, a2 /* What's left */ @@ -121,14 +124,16 @@ nop fwd_fixup: - ld t0, THREAD_BUADDR($28) + ld t2, TI_TASK($28) + ld t0, THREAD_BUADDR(t2) andi a2, 0x3f daddu a2, t1 jr ra dsubu a2, t0 partial_fixup: - ld t0, THREAD_BUADDR($28) + ld t2, TI_TASK($28) + ld t0, THREAD_BUADDR(t2) andi a2, 7 daddu a2, t1 jr ra diff -Nru a/arch/mips64/lib/promlib.c b/arch/mips64/lib/promlib.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/lib/promlib.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,24 @@ +#include <stdarg.h> +#include <linux/kernel.h> + +extern void prom_putchar(char); + +void prom_printf(char *fmt, ...) +{ + va_list args; + char ppbuf[1024]; + char *bptr; + + va_start(args, fmt); + vsprintf(ppbuf, fmt, args); + + bptr = ppbuf; + + while (*bptr != 0) { + if (*bptr == '\n') + prom_putchar('\r'); + + prom_putchar(*bptr++); + } + va_end(args); +} diff -Nru a/arch/mips64/lib/strlen_user.S b/arch/mips64/lib/strlen_user.S --- a/arch/mips64/lib/strlen_user.S Fri Jun 27 14:19:55 2003 +++ b/arch/mips64/lib/strlen_user.S Fri Jun 27 14:19:55 2003 @@ -23,9 +23,9 @@ * Return 0 for error */ LEAF(__strlen_user_asm) - ld v0, THREAD_CURDS($28) # pointer ok? + ld v0, TI_ADDR_LIMIT($28) # pointer ok? and v0, a0 - bltz v0, fault + bnez v0, fault FEXPORT(__strlen_user_nocheck_asm) move v0, a0 @@ -35,10 +35,6 @@ dsubu v0, a0 jr ra END(__strlen_user_asm) - - .section __ex_table,"a" - PTR 1b, fault - .previous fault: move v0, zero jr ra diff -Nru a/arch/mips64/lib/strncpy_user.S b/arch/mips64/lib/strncpy_user.S --- a/arch/mips64/lib/strncpy_user.S Fri Jun 27 14:19:54 2003 +++ b/arch/mips64/lib/strncpy_user.S Fri Jun 27 14:19:54 2003 @@ -28,9 +28,9 @@ */ LEAF(__strncpy_from_user_asm) - ld v0, THREAD_CURDS($28) # pointer ok? + ld v0, TI_ADDR_LIMIT($28) # pointer ok? and v0, a1 - bltz v0, fault + bnez v0, fault FEXPORT(__strncpy_from_user_nocheck_asm) move v0, zero diff -Nru a/arch/mips64/lib/strnlen_user.S b/arch/mips64/lib/strnlen_user.S --- a/arch/mips64/lib/strnlen_user.S Fri Jun 27 14:19:55 2003 +++ b/arch/mips64/lib/strnlen_user.S Fri Jun 27 14:19:55 2003 @@ -23,11 +23,11 @@ * Return 0 for error, len on string but at max a1 otherwise */ LEAF(__strnlen_user_asm) - ld v0, THREAD_CURDS($28) # pointer ok? - and v0, ta0 - bltz v0, fault + ld v0, TI_ADDR_LIMIT($28) # pointer ok? + and v0, a0 + bnez v0, fault -EXPORT(__strnlen_user_nocheck_asm) +FEXPORT(__strnlen_user_nocheck_asm) move v0, a0 daddu a1, a0 # stop pointer 1: beq v0, a1, 1f # limit reached? @@ -37,10 +37,6 @@ 1: dsubu v0, a0 jr ra END(__strnlen_user_asm) - - .section __ex_table,"a" - PTR 1b, fault - .previous fault: move v0, zero jr ra diff -Nru a/arch/mips64/math-emu/Makefile b/arch/mips64/math-emu/Makefile --- a/arch/mips64/math-emu/Makefile Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,11 +0,0 @@ -# -# Makefile for the Linux/MIPS kernel FPU emulation. -# - -obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ - ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \ - dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \ - dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \ - sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \ - sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ - dp_sqrt.o sp_sqrt.o kernel_linkage.o diff -Nru a/arch/mips64/math-emu/cp1emu.c b/arch/mips64/math-emu/cp1emu.c --- a/arch/mips64/math-emu/cp1emu.c Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1811 +0,0 @@ -/* - * MIPS floating point support - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * cp1emu.c: a MIPS coprocessor 1 (fpu) instruction emulator - * - * A complete emulator for MIPS coprocessor 1 instructions. This is - * required for #float(switch) or #float(trap), where it catches all - * COP1 instructions via the "CoProcessor Unusable" exception. - * - * More surprisingly it is also required for #float(ieee), to help out - * the hardware fpu at the boundaries of the IEEE-754 representation - * (denormalised values, infinities, underflow, etc). It is made - * quite nasty because emulation of some non-COP1 instructions is - * required, e.g. in branch delay slots. - * - * Notes: - * 1) the IEEE754 library (-le) performs the actual arithmetic; - * 2) if you know that you won't have an fpu, then you'll get much - * better performance by compiling with -msoft-float! - * - * Nov 7, 2000 - * Massive changes to integrate with Linux kernel. - * - * Replace use of kernel data area with use of user stack - * for execution of instructions in branch delay slots. - * - * Replace use of static kernel variables with thread_struct elements. - * - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/config.h> -#include <linux/mm.h> -#include <linux/signal.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/asm.h> -#include <asm/branch.h> -#include <asm/bootinfo.h> -#include <asm/byteorder.h> -#include <asm/cpu.h> -#include <asm/inst.h> -#include <asm/uaccess.h> -#include <asm/processor.h> -#include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/pgtable.h> - -#include <asm/fpu_emulator.h> - -#include "ieee754.h" - -/* Strap kernel emulator for full MIPS IV emulation */ - -#ifdef __mips -#undef __mips -#endif -#define __mips 4 - -typedef void *vaddr_t; - -/* Function which emulates the instruction in a branch delay slot. */ - -static int mips_dsemul(struct pt_regs *, mips_instruction, vaddr_t); - -/* Function which emulates a floating point instruction. */ - -static int fpu_emu(struct pt_regs *, struct mips_fpu_soft_struct *, - mips_instruction); - -#if __mips >= 4 && __mips != 32 -static int fpux_emu(struct pt_regs *, - struct mips_fpu_soft_struct *, mips_instruction); -#endif - -/* Further private data for which no space exists in mips_fpu_soft_struct */ - -struct mips_fpu_emulator_private fpuemuprivate; - -/* Control registers */ - -#define FPCREG_RID 0 /* $0 = revision id */ -#define FPCREG_CSR 31 /* $31 = csr */ - -/* Convert Mips rounding mode (0..3) to IEEE library modes. */ -static const unsigned char ieee_rm[4] = { - IEEE754_RN, IEEE754_RZ, IEEE754_RU, IEEE754_RD -}; - -#if __mips >= 4 -/* convert condition code register number to csr bit */ -static const unsigned int fpucondbit[8] = { - FPU_CSR_COND0, - FPU_CSR_COND1, - FPU_CSR_COND2, - FPU_CSR_COND3, - FPU_CSR_COND4, - FPU_CSR_COND5, - FPU_CSR_COND6, - FPU_CSR_COND7 -}; -#endif - - - -/* - * Redundant with logic already in kernel/branch.c, - * embedded in compute_return_epc. At some point, - * a single subroutine should be used across both - * modules. - */ -static int isBranchInstr(mips_instruction * i) -{ - switch (MIPSInst_OPCODE(*i)) { - case spec_op: - switch (MIPSInst_FUNC(*i)) { - case jalr_op: - case jr_op: - return 1; - } - break; - - case bcond_op: - switch (MIPSInst_RT(*i)) { - case bltz_op: - case bgez_op: - case bltzl_op: - case bgezl_op: - case bltzal_op: - case bgezal_op: - case bltzall_op: - case bgezall_op: - return 1; - } - break; - - case j_op: - case jal_op: - case jalx_op: - case beq_op: - case bne_op: - case blez_op: - case bgtz_op: - case beql_op: - case bnel_op: - case blezl_op: - case bgtzl_op: - return 1; - - case cop0_op: - case cop1_op: - case cop2_op: - case cop1x_op: - if (MIPSInst_RS(*i) == bc_op) - return 1; - break; - } - - return 0; -} - -#define REG_TO_VA (vaddr_t) -#define VA_TO_REG (unsigned long) - -static unsigned long -mips_get_word(struct pt_regs *xcp, void *va, int *perr) -{ - unsigned long temp; - - if (!user_mode(xcp)) { - *perr = 0; - return (*(unsigned long *) va); - } else { - /* Use kernel get_user() macro */ - *perr = (int) get_user(temp, (unsigned long *) va); - return temp; - } -} - -static unsigned long long -mips_get_dword(struct pt_regs *xcp, void *va, int *perr) -{ - unsigned long long temp; - - if (!user_mode(xcp)) { - *perr = 0; - return (*(unsigned long long *) va); - } else { - /* Use kernel get_user() macro */ - *perr = (int) get_user(temp, (unsigned long long *) va); - return temp; - } -} - -static int mips_put_word(struct pt_regs *xcp, void *va, unsigned long val) -{ - if (!user_mode(xcp)) { - *(unsigned long *) va = val; - return 0; - } else { - /* Use kernel get_user() macro */ - return (int) put_user(val, (unsigned long *) va); - } -} - -static int mips_put_dword(struct pt_regs *xcp, void *va, long long val) -{ - if (!user_mode(xcp)) { - *(unsigned long long *) va = val; - return 0; - } else { - /* Use kernel get_user() macro */ - return (int) put_user(val, (unsigned long long *) va); - } -} - - -/* - * In the Linux kernel, we support selection of FPR format on the - * basis of the Status.FR bit. This does imply that, if a full 32 - * FPRs are desired, there needs to be a flip-flop that can be written - * to one at that bit position. In any case, normal MIPS ABI uses - * only the even FPRs (Status.FR = 0). - */ - -#define CP0_STATUS_FR_SUPPORT - -/* - * Emulate the single floating point instruction pointed at by EPC. - * Two instructions if the instruction is in a branch delay slot. - */ - -static int -cop1Emulate(int xcptno, struct pt_regs *xcp, - struct mips_fpu_soft_struct *ctx) -{ - mips_instruction ir; - vaddr_t emulpc; - vaddr_t contpc; - unsigned int cond; - int err = 0; - - - ir = mips_get_word(xcp, REG_TO_VA xcp->cp0_epc, &err); - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - - /* XXX NEC Vr54xx bug workaround */ - if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) - xcp->cp0_cause &= ~CAUSEF_BD; - - if (xcp->cp0_cause & CAUSEF_BD) { - /* - * The instruction to be emulated is in a branch delay slot - * which means that we have to emulate the branch instruction - * BEFORE we do the cop1 instruction. - * - * This branch could be a COP1 branch, but in that case we - * would have had a trap for that instruction, and would not - * come through this route. - * - * Linux MIPS branch emulator operates on context, updating the - * cp0_epc. - */ - emulpc = REG_TO_VA(xcp->cp0_epc + 4); /* Snapshot emulation target */ - - if (__compute_return_epc(xcp)) { -#ifdef CP1DBG - printk("failed to emulate branch at %p\n", - REG_TO_VA(xcp->cp0_epc)); -#endif - return SIGILL;; - } - ir = mips_get_word(xcp, emulpc, &err); - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - contpc = REG_TO_VA xcp->cp0_epc; - } else { - emulpc = REG_TO_VA xcp->cp0_epc; - contpc = REG_TO_VA xcp->cp0_epc + 4; - } - - emul: - fpuemuprivate.stats.emulated++; - switch (MIPSInst_OPCODE(ir)) { -#ifdef CP0_STATUS_FR_SUPPORT - /* R4000+ 64-bit fpu registers */ -#ifndef SINGLE_ONLY_FPU - case ldc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - int ft = MIPSInst_RT(ir); - if (!(xcp->cp0_status & ST0_FR)) - ft &= ~1; - ctx->regs[ft] = mips_get_dword(xcp, va, &err); - fpuemuprivate.stats.loads++; - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - } - break; - - case sdc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - int ft = MIPSInst_RT(ir); - if (!(xcp->cp0_status & ST0_FR)) - ft &= ~1; - fpuemuprivate.stats.stores++; - if (mips_put_dword(xcp, va, ctx->regs[ft])) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - } - break; -#endif - - case lwc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - fpureg_t val; - int ft = MIPSInst_RT(ir); - fpuemuprivate.stats.loads++; - val = mips_get_word(xcp, va, &err); - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - if (xcp->cp0_status & ST0_FR) { - /* load whole register */ - ctx->regs[ft] = val; - } else if (ft & 1) { - /* load to m.s. 32 bits */ -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - ctx->regs[(ft & ~1)] &= 0xffffffff; - ctx->regs[(ft & ~1)] |= val << 32; -#endif - } else { - /* load to l.s. 32 bits */ - ctx->regs[ft] &= ~0xffffffffLL; - ctx->regs[ft] |= val; - } - } - break; - - case swc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - unsigned int val; - int ft = MIPSInst_RT(ir); - fpuemuprivate.stats.stores++; - if (xcp->cp0_status & ST0_FR) { - /* store whole register */ - val = ctx->regs[ft]; - } else if (ft & 1) { -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - /* store from m.s. 32 bits */ - val = ctx->regs[(ft & ~1)] >> 32; -#endif - } else { - /* store from l.s. 32 bits */ - val = ctx->regs[ft]; - } - if (mips_put_word(xcp, va, val)) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - } - break; -#else /* old 32-bit fpu registers */ - case lwc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - ctx->regs[MIPSInst_RT(ir)] = - mips_get_word(xcp, va, &err); - fpuemuprivate.stats.loads++; - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - } - break; - - case swc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - fpuemuprivate.stats.stores++; - if (mips_put_word - (xcp, va, ctx->regs[MIPSInst_RT(ir)])) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - } - break; - case ldc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - unsigned int rt = MIPSInst_RT(ir) & ~1; - int errs = 0; - fpuemuprivate.stats.loads++; -#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__) - ctx->regs[rt + 1] = - mips_get_word(xcp, va + 0, &err); - errs += err; - ctx->regs[rt + 0] = - mips_get_word(xcp, va + 4, &err); - errs += err; -#else - ctx->regs[rt + 0] = - mips_get_word(xcp, va + 0, &err); - errs += err; - ctx->regs[rt + 1] = - mips_get_word(xcp, va + 4, &err); - errs += err; -#endif - if (err) - return SIGBUS; - } - break; - - case sdc1_op: - { - void *va = REG_TO_VA(xcp->regs[MIPSInst_RS(ir)]) - + MIPSInst_SIMM(ir); - unsigned int rt = MIPSInst_RT(ir) & ~1; - fpuemuprivate.stats.stores++; -#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__) - if (mips_put_word(xcp, va + 0, ctx->regs[rt + 1])) - return SIGBUS; - if (mips_put_word(xcp, va + 4, ctx->regs[rt + 0])) - return SIGBUS; -#else - if (mips_put_word(xcp, va + 0, ctx->regs[rt + 0])) - return SIGBUS; - if (mips_put_word(xcp, va + 4, ctx->regs[rt + 1])) - return SIGBUS; -#endif - } - break; -#endif - - case cop1_op: - switch (MIPSInst_RS(ir)) { - -#ifdef CP0_STATUS_FR_SUPPORT -#if __mips64 && !defined(SINGLE_ONLY_FPU) - case dmfc_op: - /* copregister fs -> gpr[rt] */ - if (MIPSInst_RT(ir) != 0) { - int fs = MIPSInst_RD(ir); - if (!(xcp->cp0_status & ST0_FR)) - fs &= ~1; - xcp->regs[MIPSInst_RT(ir)] = ctx->regs[fs]; - } - break; - - case dmtc_op: - /* copregister fs <- rt */ - { - fpureg_t value; - int fs = MIPSInst_RD(ir); - if (!(xcp->cp0_status & ST0_FR)) - fs &= ~1; - value = - (MIPSInst_RT(ir) == - 0) ? 0 : xcp->regs[MIPSInst_RT(ir)]; - ctx->regs[fs] = value; - } - break; -#endif - - case mfc_op: - /* copregister rd -> gpr[rt] */ - if (MIPSInst_RT(ir) != 0) { - /* default value from l.s. 32 bits */ - int value = ctx->regs[MIPSInst_RD(ir)]; - if (MIPSInst_RD(ir) & 1) { -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - if (!(xcp->cp0_status & ST0_FR)) { - /* move from m.s. 32 bits */ - value = - ctx-> - regs[MIPSInst_RD(ir) & - ~1] >> 32; - } -#endif - } - xcp->regs[MIPSInst_RT(ir)] = value; - } - break; - - case mtc_op: - /* copregister rd <- rt */ - { - fpureg_t value; - if (MIPSInst_RT(ir) == 0) - value = 0; - else - value = - (unsigned int) xcp-> - regs[MIPSInst_RT(ir)]; - if (MIPSInst_RD(ir) & 1) { -#ifdef SINGLE_ONLY_FPU - /* illegal register in single-float mode */ - return SIGILL; -#else - if (!(xcp->cp0_status & ST0_FR)) { - /* move to m.s. 32 bits */ - ctx-> - regs[ - (MIPSInst_RD(ir) & - ~1)] &= - 0xffffffff; - ctx-> - regs[ - (MIPSInst_RD(ir) & - ~1)] |= - value << 32; - break; - } -#endif - } - /* move to l.s. 32 bits */ - ctx->regs[MIPSInst_RD(ir)] &= - ~0xffffffffLL; - ctx->regs[MIPSInst_RD(ir)] |= value; - } - break; -#else - - case mfc_op: - /* copregister rd -> gpr[rt] */ - if (MIPSInst_RT(ir) != 0) { - unsigned value = - ctx->regs[MIPSInst_RD(ir)]; - xcp->regs[MIPSInst_RT(ir)] = value; - } - break; - - case mtc_op: - /* copregister rd <- rt */ - { - unsigned value; - value = - (MIPSInst_RT(ir) == - 0) ? 0 : xcp->regs[MIPSInst_RT(ir)]; - ctx->regs[MIPSInst_RD(ir)] = value; - } - break; -#endif - - case cfc_op: - /* cop control register rd -> gpr[rt] */ - { - unsigned value; - - if (MIPSInst_RD(ir) == FPCREG_CSR) { - value = ctx->sr; -#ifdef CSRTRACE - printk - ("%p gpr[%d]<-csr=%08x\n", - REG_TO_VA(xcp->cp0_epc), - MIPSInst_RT(ir), value); -#endif - } else if (MIPSInst_RD(ir) == FPCREG_RID) - value = 0; - else - value = 0; - if (MIPSInst_RT(ir)) - xcp->regs[MIPSInst_RT(ir)] = value; - } - break; - - case ctc_op: - /* copregister rd <- rt */ - { - unsigned value; - - if (MIPSInst_RT(ir) == 0) - value = 0; - else - value = xcp->regs[MIPSInst_RT(ir)]; - - /* we only have one writable control reg - */ - if (MIPSInst_RD(ir) == FPCREG_CSR) { -#ifdef CSRTRACE - printk - ("%p gpr[%d]->csr=%08x\n", - REG_TO_VA(xcp->cp0_epc), - MIPSInst_RT(ir), value); -#endif - ctx->sr = value; - /* copy new rounding mode to ieee library state! */ - ieee754_csr.rm = - ieee_rm[value & 0x3]; - } - } - break; - - case bc_op: - if (xcp->cp0_cause & CAUSEF_BD) { - return SIGILL; - } - { - int likely = 0; - -#if __mips >= 4 - cond = - ctx-> - sr & fpucondbit[MIPSInst_RT(ir) >> 2]; -#else - cond = ctx->sr & FPU_CSR_COND; -#endif - switch (MIPSInst_RT(ir) & 3) { - case bcfl_op: - likely = 1; - case bcf_op: - cond = !cond; - break; - case bctl_op: - likely = 1; - case bct_op: - break; - default: - /* thats an illegal instruction */ - return SIGILL; - } - - xcp->cp0_cause |= CAUSEF_BD; - if (cond) { - /* branch taken: emulate dslot instruction */ - xcp->cp0_epc += 4; - contpc = - REG_TO_VA xcp->cp0_epc + - (MIPSInst_SIMM(ir) << 2); - - ir = - mips_get_word(xcp, - REG_TO_VA(xcp-> - cp0_epc), - &err); - if (err) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - - switch (MIPSInst_OPCODE(ir)) { - case lwc1_op: - case swc1_op: -#if (__mips >= 2 || __mips64) && !defined(SINGLE_ONLY_FPU) - case ldc1_op: - case sdc1_op: -#endif - case cop1_op: -#if __mips >= 4 && __mips != 32 - case cop1x_op: -#endif - /* its one of ours */ - goto emul; -#if __mips >= 4 - case spec_op: - if (MIPSInst_FUNC(ir) == - movc_op) goto emul; - break; -#endif - } - - /* single step the non-cp1 instruction in the dslot */ - return mips_dsemul(xcp, ir, contpc); - } else { - /* branch not taken */ - if (likely) - /* branch likely nullifies dslot if not taken */ - xcp->cp0_epc += 4; - /* else continue & execute dslot as normal insn */ - } - } - break; - - default: - if (!(MIPSInst_RS(ir) & 0x10)) { - return SIGILL; - } - /* a real fpu computation instruction */ - { - int sig; - if ((sig = fpu_emu(xcp, ctx, ir))) - return sig; - } - } - break; - -#if __mips >= 4 && __mips != 32 - case cop1x_op: - { - int sig; - if ((sig = fpux_emu(xcp, ctx, ir))) - return sig; - } - break; -#endif - -#if __mips >= 4 - case spec_op: - if (MIPSInst_FUNC(ir) != movc_op) - return SIGILL; - cond = fpucondbit[MIPSInst_RT(ir) >> 2]; - if (((ctx->sr & cond) != 0) != - ((MIPSInst_RT(ir) & 1) != 0)) return 0; - xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)]; - break; -#endif - - default: - return SIGILL; - } - - /* we did it !! */ - xcp->cp0_epc = VA_TO_REG(contpc); - xcp->cp0_cause &= ~CAUSEF_BD; - return 0; -} - -/* - * Emulate the arbritrary instruction ir at xcp->cp0_epc. Required when - * we have to emulate the instruction in a COP1 branch delay slot. Do - * not change cp0_epc due to the instruction - * - * According to the spec: - * 1) it shouldnt be a branch :-) - * 2) it can be a COP instruction :-( - * 3) if we are tring to run a protected memory space we must take - * special care on memory access instructions :-( - */ - -/* - * "Trampoline" return routine to catch exception following - * execution of delay-slot instruction execution. - */ - -int do_dsemulret(struct pt_regs *xcp) -{ -#ifdef DSEMUL_TRACE - printk("desemulret\n"); -#endif - /* Set EPC to return to post-branch instruction */ - xcp->cp0_epc = current->thread.dsemul_epc; - /* - * Clear the state that got us here. - */ - current->thread.dsemul_aerpc = (unsigned long) 0; - - return 0; -} - - -#define AdELOAD 0x8c000001 /* lw $0,1($0) */ - -static int -mips_dsemul(struct pt_regs *xcp, mips_instruction ir, vaddr_t cpc) -{ - mips_instruction *dsemul_insns; - mips_instruction forcetrap; - extern asmlinkage void handle_dsemulret(void); - - if (ir == 0) { /* a nop is easy */ - xcp->cp0_epc = VA_TO_REG(cpc); - return 0; - } -#ifdef DSEMUL_TRACE - printk("desemul %p %p\n", REG_TO_VA(xcp->cp0_epc), cpc); -#endif - - /* - * The strategy is to push the instruction onto the user stack - * and put a trap after it which we can catch and jump to - * the required address any alternative apart from full - * instruction emulation!!. - */ - dsemul_insns = (mips_instruction *) (xcp->regs[29] & ~3); - dsemul_insns -= 3; /* Two instructions, plus one for luck ;-) */ - /* Verify that the stack pointer is not competely insane */ - if (verify_area - (VERIFY_WRITE, dsemul_insns, sizeof(mips_instruction) * 2)) - return SIGBUS; - - if (mips_put_word(xcp, &dsemul_insns[0], ir)) { - fpuemuprivate.stats.errors++; - return (SIGBUS); - } - - /* - * Algorithmics used a system call instruction, and - * borrowed that vector. MIPS/Linux version is a bit - * more heavyweight in the interests of portability and - * multiprocessor support. We flag the thread for special - * handling in the unaligned access handler and force an - * address error excpetion. - */ - - /* If one is *really* paranoid, one tests for a bad stack pointer */ - if ((xcp->regs[29] & 0x3) == 0x3) - forcetrap = AdELOAD - 1; - else - forcetrap = AdELOAD; - - if (mips_put_word(xcp, &dsemul_insns[1], forcetrap)) { - fpuemuprivate.stats.errors++; - return (SIGBUS); - } - - /* Set thread state to catch and handle the exception */ - current->thread.dsemul_epc = (unsigned long) cpc; - current->thread.dsemul_aerpc = (unsigned long) &dsemul_insns[1]; - xcp->cp0_epc = VA_TO_REG & dsemul_insns[0]; - flush_cache_sigtramp((unsigned long) dsemul_insns); - - return SIGILL; /* force out of emulation loop */ -} - -/* - * Conversion table from MIPS compare ops 48-63 - * cond = ieee754dp_cmp(x,y,IEEE754_UN); - */ -static const unsigned char cmptab[8] = { - 0, /* cmp_0 (sig) cmp_sf */ - IEEE754_CUN, /* cmp_un (sig) cmp_ngle */ - IEEE754_CEQ, /* cmp_eq (sig) cmp_seq */ - IEEE754_CEQ | IEEE754_CUN, /* cmp_ueq (sig) cmp_ngl */ - IEEE754_CLT, /* cmp_olt (sig) cmp_lt */ - IEEE754_CLT | IEEE754_CUN, /* cmp_ult (sig) cmp_nge */ - IEEE754_CLT | IEEE754_CEQ, /* cmp_ole (sig) cmp_le */ - IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */ -}; - -#define SIFROMREG(si,x) ((si) = ctx->regs[x]) -#define SITOREG(si,x) (ctx->regs[x] = (int)(si)) - -#if __mips64 && !defined(SINGLE_ONLY_FPU) -#define DIFROMREG(di,x) ((di) = ctx->regs[x]) -#define DITOREG(di,x) (ctx->regs[x] = (di)) -#endif - -#define SPFROMREG(sp,x) ((sp).bits = ctx->regs[x]) -#define SPTOREG(sp,x) (ctx->regs[x] = (sp).bits) - -#ifdef CP0_STATUS_FR_SUPPORT -#define DPFROMREG(dp,x) ((dp).bits = \ - ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]) -#define DPTOREG(dp,x) (ctx->regs[(xcp->cp0_status & ST0_FR) ? x : (x & ~1)]\ - = (dp).bits) -#else -/* Beware: MIPS COP1 doubles are always little_word endian in registers */ -#define DPFROMREG(dp,x) \ - ((dp).bits = ((unsigned long long)ctx->regs[(x)+1] << 32) | ctx->regs[x]) -#define DPTOREG(dp,x) \ - (ctx->regs[x] = (dp).bits, ctx->regs[(x)+1] = (dp).bits >> 32) -#endif - -#if __mips >= 4 && __mips != 32 - -/* - * Additional MIPS4 instructions - */ - -static ieee754dp fpemu_dp_recip(ieee754dp d) -{ - return ieee754dp_div(ieee754dp_one(0), d); -} - -static ieee754dp fpemu_dp_rsqrt(ieee754dp d) -{ - return ieee754dp_div(ieee754dp_one(0), ieee754dp_sqrt(d)); -} - -static ieee754sp fpemu_sp_recip(ieee754sp s) -{ - return ieee754sp_div(ieee754sp_one(0), s); -} - -static ieee754sp fpemu_sp_rsqrt(ieee754sp s) -{ - return ieee754sp_div(ieee754sp_one(0), ieee754sp_sqrt(s)); -} - - -static ieee754dp fpemu_dp_madd(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_add(ieee754dp_mul(s, t), r); -} - -static ieee754dp fpemu_dp_msub(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_sub(ieee754dp_mul(s, t), r); -} - -static ieee754dp fpemu_dp_nmadd(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_neg(ieee754dp_add(ieee754dp_mul(s, t), r)); -} - -static ieee754dp fpemu_dp_nmsub(ieee754dp r, ieee754dp s, ieee754dp t) -{ - return ieee754dp_neg(ieee754dp_sub(ieee754dp_mul(s, t), r)); -} - - -static ieee754sp fpemu_sp_madd(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_add(ieee754sp_mul(s, t), r); -} - -static ieee754sp fpemu_sp_msub(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_sub(ieee754sp_mul(s, t), r); -} - -static ieee754sp fpemu_sp_nmadd(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_neg(ieee754sp_add(ieee754sp_mul(s, t), r)); -} - -static ieee754sp fpemu_sp_nmsub(ieee754sp r, ieee754sp s, ieee754sp t) -{ - return ieee754sp_neg(ieee754sp_sub(ieee754sp_mul(s, t), r)); -} - -static int -fpux_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx, - mips_instruction ir) -{ - unsigned rcsr = 0; /* resulting csr */ - - fpuemuprivate.stats.cp1xops++; - - switch (MIPSInst_FMA_FFMT(ir)) { - case s_fmt: /* 0 */ - { - ieee754sp(*handler) (ieee754sp, ieee754sp, - ieee754sp); - ieee754sp fd, fr, fs, ft; - - switch (MIPSInst_FUNC(ir)) { - case lwxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - fpureg_t val; - int err = 0; - val = mips_get_word(xcp, va, &err); - if (err) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - if (xcp->cp0_status & ST0_FR) { - /* load whole register */ - ctx-> - regs[MIPSInst_FD(ir)] = - val; - } else if (MIPSInst_FD(ir) & 1) { - /* load to m.s. 32 bits */ -#if defined(SINGLE_ONLY_FPU) - /* illegal register in single-float mode */ - return SIGILL; -#else - ctx-> - regs[ - (MIPSInst_FD(ir) & - ~1)] &= - 0xffffffff; - ctx-> - regs[ - (MIPSInst_FD(ir) & - ~1)] |= - val << 32; -#endif - } else { - /* load to l.s. 32 bits */ - ctx-> - regs[MIPSInst_FD(ir)] - &= ~0xffffffffLL; - ctx-> - regs[MIPSInst_FD(ir)] - |= val; - } - } - break; - - case swxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - unsigned int val; - if (xcp->cp0_status & ST0_FR) { - /* store whole register */ - val = - ctx-> - regs[MIPSInst_FS(ir)]; - } else if (MIPSInst_FS(ir) & 1) { -#if defined(SINGLE_ONLY_FPU) - /* illegal register in single-float mode */ - return SIGILL; -#else - /* store from m.s. 32 bits */ - val = - ctx-> - regs[ - (MIPSInst_FS(ir) & - ~1)] >> 32; -#endif - } else { - /* store from l.s. 32 bits */ - val = - ctx-> - regs[MIPSInst_FS(ir)]; - } - if (mips_put_word(xcp, va, val)) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - } - break; - - case madd_s_op: - handler = fpemu_sp_madd; - goto scoptop; - case msub_s_op: - handler = fpemu_sp_msub; - goto scoptop; - case nmadd_s_op: - handler = fpemu_sp_nmadd; - goto scoptop; - case nmsub_s_op: - handler = fpemu_sp_nmsub; - goto scoptop; - - scoptop: - SPFROMREG(fr, MIPSInst_FR(ir)); - SPFROMREG(fs, MIPSInst_FS(ir)); - SPFROMREG(ft, MIPSInst_FT(ir)); - fd = (*handler) (fr, fs, ft); - SPTOREG(fd, MIPSInst_FD(ir)); - - copcsr: - if (ieee754_cxtest(IEEE754_INEXACT)) - rcsr |= - FPU_CSR_INE_X | FPU_CSR_INE_S; - if (ieee754_cxtest(IEEE754_UNDERFLOW)) - rcsr |= - FPU_CSR_UDF_X | FPU_CSR_UDF_S; - if (ieee754_cxtest(IEEE754_OVERFLOW)) - rcsr |= - FPU_CSR_OVF_X | FPU_CSR_OVF_S; - if (ieee754_cxtest - (IEEE754_INVALID_OPERATION)) rcsr |= - FPU_CSR_INV_X | FPU_CSR_INV_S; - - ctx->sr = - (ctx->sr & ~FPU_CSR_ALL_X) | rcsr; - if ((ctx->sr >> 5) & ctx-> - sr & FPU_CSR_ALL_E) { - /*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */ - return SIGFPE; - } - - break; - - default: - return SIGILL; - } - } - break; - -#if !defined(SINGLE_ONLY_FPU) - case d_fmt: /* 1 */ - { - ieee754dp(*handler) (ieee754dp, ieee754dp, - ieee754dp); - ieee754dp fd, fr, fs, ft; - - switch (MIPSInst_FUNC(ir)) { - case ldxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - int err = 0; - ctx->regs[MIPSInst_FD(ir)] = - mips_get_dword(xcp, va, &err); - if (err) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - } - break; - - case sdxc1_op: - { - void *va = - REG_TO_VA(xcp-> - regs[MIPSInst_FR(ir)] - + - xcp-> - regs[MIPSInst_FT - (ir)]); - if (mips_put_dword - (xcp, va, - ctx->regs[MIPSInst_FS(ir)])) { - fpuemuprivate.stats. - errors++; - return SIGBUS; - } - } - break; - - case madd_d_op: - handler = fpemu_dp_madd; - goto dcoptop; - case msub_d_op: - handler = fpemu_dp_msub; - goto dcoptop; - case nmadd_d_op: - handler = fpemu_dp_nmadd; - goto dcoptop; - case nmsub_d_op: - handler = fpemu_dp_nmsub; - goto dcoptop; - - dcoptop: - DPFROMREG(fr, MIPSInst_FR(ir)); - DPFROMREG(fs, MIPSInst_FS(ir)); - DPFROMREG(ft, MIPSInst_FT(ir)); - fd = (*handler) (fr, fs, ft); - DPTOREG(fd, MIPSInst_FD(ir)); - goto copcsr; - - default: - return SIGILL; - } - } - break; -#endif - - case 0x7: /* 7 */ - { - if (MIPSInst_FUNC(ir) != pfetch_op) { - return SIGILL; - } - /* ignore prefx operation */ - } - break; - - default: - return SIGILL; - } - - return 0; -} -#endif - - - -/* - * Emulate a single COP1 arithmetic instruction. - */ -static int -fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx, - mips_instruction ir) -{ - int rfmt; /* resulting format */ - unsigned rcsr = 0; /* resulting csr */ - unsigned cond; - union { - ieee754dp d; - ieee754sp s; - int w; -#if __mips64 - long long l; -#endif - } rv; /* resulting value */ - - fpuemuprivate.stats.cp1ops++; - switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) { - - case s_fmt:{ /* 0 */ - ieee754sp(*handler) (); - - switch (MIPSInst_FUNC(ir)) { - /* binary ops */ - case fadd_op: - handler = ieee754sp_add; - goto scopbop; - case fsub_op: - handler = ieee754sp_sub; - goto scopbop; - case fmul_op: - handler = ieee754sp_mul; - goto scopbop; - case fdiv_op: - handler = ieee754sp_div; - goto scopbop; - - /* unary ops */ -#if __mips >= 2 || __mips64 - case fsqrt_op: - handler = ieee754sp_sqrt; - goto scopuop; -#endif -#if __mips >= 4 && __mips != 32 - case frsqrt_op: - handler = fpemu_sp_rsqrt; - goto scopuop; - case frecip_op: - handler = fpemu_sp_recip; - goto scopuop; -#endif -#if __mips >= 4 - case fmovc_op: - cond = fpucondbit[MIPSInst_FT(ir) >> 2]; - if (((ctx->sr & cond) != 0) != - ((MIPSInst_FT(ir) & 1) != 0)) - return 0; - SPFROMREG(rv.s, MIPSInst_FS(ir)); - break; - case fmovz_op: - if (xcp->regs[MIPSInst_FT(ir)] != 0) - return 0; - SPFROMREG(rv.s, MIPSInst_FS(ir)); - break; - case fmovn_op: - if (xcp->regs[MIPSInst_FT(ir)] == 0) - return 0; - SPFROMREG(rv.s, MIPSInst_FS(ir)); - break; -#endif - case fabs_op: - handler = ieee754sp_abs; - goto scopuop; - case fneg_op: - handler = ieee754sp_neg; - goto scopuop; - case fmov_op: - /* an easy one */ - SPFROMREG(rv.s, MIPSInst_FS(ir)); - break; - /* binary op on handler */ -scopbop: - { - ieee754sp fs, ft; - - SPFROMREG(fs, MIPSInst_FS(ir)); - SPFROMREG(ft, MIPSInst_FT(ir)); - - rv.s = (*handler) (fs, ft); - goto copcsr; - } -scopuop: - { - ieee754sp fs; - - SPFROMREG(fs, MIPSInst_FS(ir)); - rv.s = (*handler) (fs); - goto copcsr; - } -copcsr: - if (ieee754_cxtest(IEEE754_INEXACT)) - rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S; - if (ieee754_cxtest(IEEE754_UNDERFLOW)) - rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S; - if (ieee754_cxtest(IEEE754_OVERFLOW)) - rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S; - if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) - rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S; - if (ieee754_cxtest - (IEEE754_INVALID_OPERATION)) rcsr |= - FPU_CSR_INV_X | FPU_CSR_INV_S; - break; - - /* unary conv ops */ - case fcvts_op: - return SIGILL; /* not defined */ - case fcvtd_op: -#if defined(SINGLE_ONLY_FPU) - return SIGILL; /* not defined */ -#else - { - ieee754sp fs; - - SPFROMREG(fs, MIPSInst_FS(ir)); - rv.d = ieee754dp_fsp(fs); - rfmt = d_fmt; - goto copcsr; - } -#endif - case fcvtw_op: - { - ieee754sp fs; - - SPFROMREG(fs, MIPSInst_FS(ir)); - rv.w = ieee754sp_tint(fs); - rfmt = w_fmt; - goto copcsr; - } - -#if __mips >= 2 || __mips64 - case fround_op: - case ftrunc_op: - case fceil_op: - case ffloor_op: - { - unsigned int oldrm = ieee754_csr.rm; - ieee754sp fs; - - SPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; - rv.w = ieee754sp_tint(fs); - ieee754_csr.rm = oldrm; - rfmt = w_fmt; - goto copcsr; - } -#endif /* __mips >= 2 */ - -#if __mips64 && !defined(SINGLE_ONLY_FPU) - case fcvtl_op: - { - ieee754sp fs; - - SPFROMREG(fs, MIPSInst_FS(ir)); - rv.l = ieee754sp_tlong(fs); - rfmt = l_fmt; - goto copcsr; - } - - case froundl_op: - case ftruncl_op: - case fceill_op: - case ffloorl_op: - { - unsigned int oldrm = ieee754_csr.rm; - ieee754sp fs; - - SPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; - rv.l = ieee754sp_tlong(fs); - ieee754_csr.rm = oldrm; - rfmt = l_fmt; - goto copcsr; - } -#endif /* __mips64 && !fpu(single) */ - - default: - if (MIPSInst_FUNC(ir) >= fcmp_op) { - unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; - ieee754sp fs, ft; - - SPFROMREG(fs, MIPSInst_FS(ir)); - SPFROMREG(ft, MIPSInst_FT(ir)); - rv.w = ieee754sp_cmp(fs, ft, cmptab[cmpop & 0x7]); - rfmt = -1; - if ((cmpop & 0x8) && ieee754_cxtest(IEEE754_INVALID_OPERATION)) - rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; - } else { - return SIGILL; - } - break; - } - break; - } - -#if !defined(SINGLE_ONLY_FPU) - case d_fmt: { - ieee754dp(*handler) (); - - switch (MIPSInst_FUNC(ir)) { - /* binary ops */ - case fadd_op: - handler = ieee754dp_add; - goto dcopbop; - case fsub_op: - handler = ieee754dp_sub; - goto dcopbop; - case fmul_op: - handler = ieee754dp_mul; - goto dcopbop; - case fdiv_op: - handler = ieee754dp_div; - goto dcopbop; - - /* unary ops */ -#if __mips >= 2 || __mips64 - case fsqrt_op: - handler = ieee754dp_sqrt; - goto dcopuop; -#endif -#if __mips >= 4 && __mips != 32 - case frsqrt_op: - handler = fpemu_dp_rsqrt; - goto dcopuop; - case frecip_op: - handler = fpemu_dp_recip; - goto dcopuop; -#endif -#if __mips >= 4 - case fmovc_op: - cond = fpucondbit[MIPSInst_FT(ir) >> 2]; - if (((ctx->sr & cond) != 0) != ((MIPSInst_FT(ir) & 1) != 0)) - return 0; - DPFROMREG(rv.d, MIPSInst_FS(ir)); - break; - case fmovz_op: - if (xcp->regs[MIPSInst_FT(ir)] != 0) - return 0; - DPFROMREG(rv.d, MIPSInst_FS(ir)); - break; - case fmovn_op: - if (xcp->regs[MIPSInst_FT(ir)] == 0) - return 0; - DPFROMREG(rv.d, MIPSInst_FS(ir)); - break; -#endif - case fabs_op: - handler = ieee754dp_abs; - goto dcopuop; - case fneg_op: - handler = ieee754dp_neg; - goto dcopuop; - case fmov_op: - /* an easy one */ - DPFROMREG(rv.d, MIPSInst_FS(ir)); - break; - - /* binary op on handler */ -dcopbop: - { - ieee754dp fs, ft; - - DPFROMREG(fs, MIPSInst_FS(ir)); - DPFROMREG(ft, MIPSInst_FT(ir)); - - rv.d = (*handler) (fs, ft); - goto copcsr; - } -dcopuop: - { - ieee754dp fs; - - DPFROMREG(fs, MIPSInst_FS(ir)); - rv.d = (*handler) (fs); - goto copcsr; - } - - /* unary conv ops */ - case fcvts_op: - { - ieee754dp fs; - - DPFROMREG(fs, MIPSInst_FS(ir)); - rv.s = ieee754sp_fdp(fs); - rfmt = s_fmt; - goto copcsr; - } - case fcvtd_op: - return SIGILL; /* not defined */ - case fcvtw_op: - { - ieee754dp fs; - - DPFROMREG(fs, MIPSInst_FS(ir)); - rv.w = ieee754dp_tint(fs); /* wrong */ - rfmt = w_fmt; - goto copcsr; - } - -#if __mips >= 2 || __mips64 - case fround_op: - case ftrunc_op: - case fceil_op: - case ffloor_op: - { - unsigned int oldrm = ieee754_csr.rm; - ieee754dp fs; - - DPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; - rv.w = ieee754dp_tint(fs); - ieee754_csr.rm = oldrm; - rfmt = w_fmt; - goto copcsr; - } -#endif - -#if __mips64 && !defined(SINGLE_ONLY_FPU) - case fcvtl_op: - { - ieee754dp fs; - - DPFROMREG(fs, MIPSInst_FS(ir)); - rv.l = ieee754dp_tlong(fs); - rfmt = l_fmt; - goto copcsr; - } - - case froundl_op: - case ftruncl_op: - case fceill_op: - case ffloorl_op: - { - unsigned int oldrm = ieee754_csr.rm; - ieee754dp fs; - - DPFROMREG(fs, MIPSInst_FS(ir)); - ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3]; - rv.l = ieee754dp_tlong(fs); - ieee754_csr.rm = oldrm; - rfmt = l_fmt; - goto copcsr; - } -#endif /* __mips >= 3 && !fpu(single) */ - - default: - if (MIPSInst_FUNC(ir) >= fcmp_op) { - unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op; - ieee754dp fs, ft; - - DPFROMREG(fs, MIPSInst_FS(ir)); - DPFROMREG(ft, MIPSInst_FT(ir)); - rv.w = ieee754dp_cmp(fs, ft, cmptab[cmpop & 0x7]); - rfmt = -1; - if ((cmpop & 0x8) && ieee754_cxtest (IEEE754_INVALID_OPERATION)) - rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S; - } else { - return SIGILL; - } - break; - } - break; - } -#endif /* !defined(SINGLE_ONLY_FPU) */ - - case w_fmt: { - switch (MIPSInst_FUNC(ir)) { - case fcvts_op: - /* convert word to single precision real */ - rv.s = ieee754sp_fint(ctx-> regs[MIPSInst_FS(ir)]); - rfmt = s_fmt; - goto copcsr; -#if !defined(SINGLE_ONLY_FPU) - case fcvtd_op: - /* convert word to double precision real */ - rv.d = ieee754dp_fint(ctx-> regs[MIPSInst_FS(ir)]); - rfmt = d_fmt; - goto copcsr; -#endif - default: - return SIGILL; - } - break; - } - -#if __mips64 && !defined(SINGLE_ONLY_FPU) - case l_fmt: { - switch (MIPSInst_FUNC(ir)) { - case fcvts_op: - /* convert long to single precision real */ - rv.s = ieee754sp_flong(ctx-> regs[MIPSInst_FS(ir)]); - rfmt = s_fmt; - goto copcsr; - case fcvtd_op: - /* convert long to double precision real */ - rv.d = ieee754dp_flong(ctx-> regs[MIPSInst_FS(ir)]); - rfmt = d_fmt; - goto copcsr; - default: - return SIGILL; - } - break; - } -#endif - - default: - return SIGILL; - } - - /* - * Update the fpu CSR register for this operation. - * If an exception is required, generate a tidy SIGFPE exception, - * without updating the result register. - * Note: cause exception bits do not accumulate, they are rewritten - * for each op; only the flag/sticky bits accumulate. - */ - ctx->sr = (ctx->sr & ~FPU_CSR_ALL_X) | rcsr; - if ((ctx->sr >> 5) & ctx->sr & FPU_CSR_ALL_E) { - /*printk ("SIGFPE: fpu csr = %08x\n",ctx->sr); */ - return SIGFPE; - } - - /* - * Now we can safely write the result back to the register file. - */ - switch (rfmt) { - case -1: { -#if __mips >= 4 - cond = fpucondbit[MIPSInst_FD(ir) >> 2]; -#else - cond = FPU_CSR_COND; -#endif - if (rv.w) - ctx->sr |= cond; - else - ctx->sr &= ~cond; - break; - } -#if !defined(SINGLE_ONLY_FPU) - case d_fmt: - DPTOREG(rv.d, MIPSInst_FD(ir)); - break; -#endif - case s_fmt: - SPTOREG(rv.s, MIPSInst_FD(ir)); - break; - case w_fmt: - SITOREG(rv.w, MIPSInst_FD(ir)); - break; -#if __mips64 && !defined(SINGLE_ONLY_FPU) - case l_fmt: - DITOREG(rv.l, MIPSInst_FD(ir)); - break; -#endif - default: - return SIGILL; - } - - return 0; -} - - -/* - * Emulate the floating point instruction at EPC, and continue - * to run until we hit a non-fp instruction, or a backward - * branch. This cuts down dramatically on the per instruction - * exception overhead. - */ -int fpu_emulator_cop1Handler(int xcptno, struct pt_regs *xcp) -{ - struct mips_fpu_soft_struct *ctx = ¤t->thread.fpu.soft; - unsigned long oldepc, prevepc; - unsigned int insn; - int sig = 0; - int err = 0; - - oldepc = xcp->cp0_epc; - do { - cond_resched(); - - prevepc = xcp->cp0_epc; - insn = mips_get_word(xcp, REG_TO_VA(xcp->cp0_epc), &err); - if (err) { - fpuemuprivate.stats.errors++; - return SIGBUS; - } - if (insn != 0) - sig = cop1Emulate(xcptno, xcp, ctx); - else - xcp->cp0_epc += 4; /* skip nops */ - - if (mips_cpu.options & MIPS_CPU_FPU) - break; - } while (xcp->cp0_epc > prevepc && sig == 0); - - /* SIGILL indicates a non-fpu instruction */ - if (sig == SIGILL && xcp->cp0_epc != oldepc) - /* but if epc has advanced, then ignore it */ - sig = 0; - - return sig; -} - - -#ifdef NOTDEF -/* - * Patch up the hardware fpu state when an f.p. exception occurs. - */ -static int cop1Patcher(int xcptno, struct pt_regs *xcp) -{ - struct mips_fpu_soft_struct *ctx = ¤t->thread.fpu.soft; - unsigned sr; - int sig; - - /* reenable Cp1, else fpe_save() will get nested exception */ - sr = mips_bissr(ST0_CU1); - - /* get fpu registers and status, then clear pending exceptions */ - fpe_save(ctx); - fpe_setsr(ctx->sr &= ~FPU_CSR_ALL_X); - - /* get current rounding mode for IEEE library, and emulate insn */ - ieee754_csr.rm = ieee_rm[ctx->sr & 0x3]; - sig = cop1Emulate(xcptno, xcp, ctx); - - /* don't return with f.p. exceptions pending */ - ctx->sr &= ~FPU_CSR_ALL_X; - fpe_restore(ctx); - - mips_setsr(sr); - return sig; -} - -void _cop1_init(int emulate) -{ - extern int _nofpu; - - if (emulate) { - /* - * Install cop1 emulator to handle "coprocessor unusable" exception - */ - xcption(XCPTCPU, cop1Handler); - fpuemuactive = 1; /* tell dbg.c that we are in charge */ - _nofpu = 0; /* tell setjmp() it "has" an fpu */ - } else { - /* - * Install cop1 emulator for floating point exceptions only, - * i.e. denormalised results, underflow, overflow etc, which - * must be emulated in s/w. - */ -#ifdef 1 - /* r4000 or above use dedicate exception */ - xcption(XCPTFPE, cop1Patcher); -#else - /* r3000 et al use interrupt */ - extern int _sbd_getfpuintr(void); - int intno = _sbd_getfpuintr(); - intrupt(intno, cop1Patcher, 0); - mips_bissr(SR_IM0 << intno); -#endif - -#if (#cpu(r4640) || #cpu(r4650)) && !defined(SINGLE_ONLY_FPU) - /* For R4640/R4650 compiled *without* the -msingle-float flag, - then we share responsibility: the h/w handles the single - precision operations, and the trap emulator handles the - double precision. We set fpuemuactive so that dbg.c first - fetches the s/w state before saving the h/w state. */ - fpuemuactive = 1; - { - int i; - /* initialise the unused d.p high order words to be NaN */ - for (i = 0; i < 32; i++) - current->thread.fpu.soft.regs[i] = - 0x7ff80bad00000000LL; - } -#endif /* (r4640 || r4650) && !fpu(single) */ - } -} -#endif - diff -Nru a/arch/mips64/math-emu/dp_add.c b/arch/mips64/math-emu/dp_add.c --- a/arch/mips64/math-emu/dp_add.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,186 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) -{ - COMPXDP; - COMPYDP; - - EXPLODEXDP; - EXPLODEYDP; - - CLEARCX; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "add", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "add", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "add", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Inifity handling - */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (xs == ys) - return x; - SETCX(IEEE754_INVALID_OPERATION); - return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - return y; - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - return x; - - /* Zero handling - */ - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - else - return ieee754dp_zero(ieee754_csr.rm == - IEEE754_RD); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return y; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - DPDNORMX; - - /* FALL THROUGH */ - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - DPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - DPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - assert(xm & DP_HIDDEN_BIT); - assert(ym & DP_HIDDEN_BIT); - - /* provide guard,round and stick bit space */ - xm <<= 3; - ym <<= 3; - - if (xe > ye) { - /* have to shift y fraction right to align - */ - int s = xe - ye; - ym = XDPSRS(ym, s); - ye += s; - } else if (ye > xe) { - /* have to shift x fraction right to align - */ - int s = ye - xe; - xm = XDPSRS(xm, s); - xe += s; - } - assert(xe == ye); - assert(xe <= DP_EMAX); - - if (xs == ys) { - /* generate 28 bit result of adding two 27 bit numbers - * leaving result in xm,xs,xe - */ - xm = xm + ym; - xe = xe; - xs = xs; - - if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */ - xm = XDPSRS1(xm); - xe++; - } - } else { - if (xm >= ym) { - xm = xm - ym; - xe = xe; - xs = xs; - } else { - xm = ym - xm; - xe = xe; - xs = ys; - } - if (xm == 0) - return ieee754dp_zero(ieee754_csr.rm == - IEEE754_RD); - - /* normalize to rounding precision */ - while ((xm >> (DP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - - } - DPNORMRET2(xs, xe, xm, "add", x, y); -} diff -Nru a/arch/mips64/math-emu/dp_cmp.c b/arch/mips64/math-emu/dp_cmp.c --- a/arch/mips64/math-emu/dp_cmp.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp) -{ - CLEARCX; - - if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) { - if (cmp & IEEE754_CUN) - return 1; - if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (SETCX(IEEE754_INVALID_OPERATION)) - return ieee754si_xcpt(0, "fcmpf", x); - } - return 0; - } else { - long long int vx = x.bits; - long long int vy = y.bits; - - if (vx < 0) - vx = -vx ^ DP_SIGN_BIT; - if (vy < 0) - vy = -vy ^ DP_SIGN_BIT; - - if (vx < vy) - return (cmp & IEEE754_CLT) != 0; - else if (vx == vy) - return (cmp & IEEE754_CEQ) != 0; - else - return (cmp & IEEE754_CGT) != 0; - } -} diff -Nru a/arch/mips64/math-emu/dp_div.c b/arch/mips64/math-emu/dp_div.c --- a/arch/mips64/math-emu/dp_div.c Fri Jun 27 14:19:30 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,160 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) -{ - COMPXDP; - COMPYDP; - - CLEARCX; - - EXPLODEXDP; - EXPLODEYDP; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "div", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "div", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "div", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Infinity handling - */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - SETCX(IEEE754_INVALID_OPERATION); - return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - return ieee754dp_zero(xs ^ ys); - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - return ieee754dp_inf(xs ^ ys); - - /* Zero handling - */ - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - SETCX(IEEE754_INVALID_OPERATION); - return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - SETCX(IEEE754_ZERO_DIVIDE); - return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return ieee754dp_zero(xs == ys ? 0 : 1); - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - DPDNORMX; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - DPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - DPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - assert(xm & DP_HIDDEN_BIT); - assert(ym & DP_HIDDEN_BIT); - - /* provide rounding space */ - xm <<= 3; - ym <<= 3; - - { - /* now the dirty work */ - - unsigned long long rm = 0; - int re = xe - ye; - unsigned long long bm; - - for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) { - if (xm >= ym) { - xm -= ym; - rm |= bm; - if (xm == 0) - break; - } - xm <<= 1; - } - rm <<= 1; - if (xm) - rm |= 1; /* have remainder, set sticky */ - - assert(rm); - - /* normalise rm to rounding precision ? - */ - while ((rm >> (DP_MBITS + 3)) == 0) { - rm <<= 1; - re--; - } - - DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y); - } -} diff -Nru a/arch/mips64/math-emu/dp_fint.c b/arch/mips64/math-emu/dp_fint.c --- a/arch/mips64/math-emu/dp_fint.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,78 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_fint(int x) -{ - COMPXDP; - - CLEARCX; - - if (x == 0) - return ieee754dp_zero(0); - if (x == 1 || x == -1) - return ieee754dp_one(x < 0); - if (x == 10 || x == -10) - return ieee754dp_ten(x < 0); - - xs = (x < 0); - if (xs) { - if (x == (1 << 31)) - xm = ((unsigned) 1 << 31); /* max neg can't be safely negated */ - else - xm = -x; - } else { - xm = x; - } - -#if 1 - /* normalize - result can never be inexact or overflow */ - xe = DP_MBITS; - while ((xm >> DP_MBITS) == 0) { - xm <<= 1; - xe--; - } - return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -#else - /* normalize */ - xe = DP_MBITS + 3; - while ((xm >> (DP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - DPNORMRET1(xs, xe, xm, "fint", x); -#endif -} - -ieee754dp ieee754dp_funs(unsigned int u) -{ - if ((int) u < 0) - return ieee754dp_add(ieee754dp_1e31(), - ieee754dp_fint(u & ~(1 << 31))); - return ieee754dp_fint(u); -} diff -Nru a/arch/mips64/math-emu/dp_flong.c b/arch/mips64/math-emu/dp_flong.c --- a/arch/mips64/math-emu/dp_flong.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,76 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_flong(long long x) -{ - COMPXDP; - - CLEARCX; - - if (x == 0) - return ieee754dp_zero(0); - if (x == 1 || x == -1) - return ieee754dp_one(x < 0); - if (x == 10 || x == -10) - return ieee754dp_ten(x < 0); - - xs = (x < 0); - if (xs) { - if (x == (1ULL << 63)) - xm = (1ULL << 63); /* max neg can't be safely negated */ - else - xm = -x; - } else { - xm = x; - } - - /* normalize */ - xe = DP_MBITS + 3; - if (xm >> (DP_MBITS + 1 + 3)) { - /* shunt out overflow bits */ - while (xm >> (DP_MBITS + 1 + 3)) { - XDPSRSX1(); - } - } else { - /* normalize in grs extended double precision */ - while ((xm >> (DP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - } - DPNORMRET1(xs, xe, xm, "dp_flong", x); -} - -ieee754dp ieee754dp_fulong(unsigned long long u) -{ - if ((long long) u < 0) - return ieee754dp_add(ieee754dp_1e63(), - ieee754dp_flong(u & ~(1ULL << 63))); - return ieee754dp_flong(u); -} diff -Nru a/arch/mips64/math-emu/dp_frexp.c b/arch/mips64/math-emu/dp_frexp.c --- a/arch/mips64/math-emu/dp_frexp.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,53 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -/* close to ieeep754dp_logb -*/ -ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr) -{ - COMPXDP; - CLEARCX; - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_INF: - case IEEE754_CLASS_ZERO: - *eptr = 0; - return x; - case IEEE754_CLASS_DNORM: - DPDNORMX; - break; - case IEEE754_CLASS_NORM: - break; - } - *eptr = xe + 1; - return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -} diff -Nru a/arch/mips64/math-emu/dp_fsp.c b/arch/mips64/math-emu/dp_fsp.c --- a/arch/mips64/math-emu/dp_fsp.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,70 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_fsp(ieee754sp x) -{ - COMPXSP; - - CLEARCX; - - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: - return ieee754dp_nanxcpt(builddp(xs, - DP_EMAX + 1 + DP_EBIAS, - ((unsigned long long) xm - << (DP_MBITS - - SP_MBITS))), "fsp", - x); - case IEEE754_CLASS_INF: - return ieee754dp_inf(xs); - case IEEE754_CLASS_ZERO: - return ieee754dp_zero(xs); - case IEEE754_CLASS_DNORM: - /* normalize */ - while ((xm >> SP_MBITS) == 0) { - xm <<= 1; - xe--; - } - break; - case IEEE754_CLASS_NORM: - break; - } - - /* CANT possibly overflow,underflow, or need rounding - */ - - /* drop the hidden bit */ - xm &= ~SP_HIDDEN_BIT; - - return builddp(xs, xe + DP_EBIAS, - (unsigned long long) xm << (DP_MBITS - SP_MBITS)); -} diff -Nru a/arch/mips64/math-emu/dp_logb.c b/arch/mips64/math-emu/dp_logb.c --- a/arch/mips64/math-emu/dp_logb.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,54 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_logb(ieee754dp x) -{ - COMPXDP; - - CLEARCX; - - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - return ieee754dp_nanxcpt(x, "logb", x); - case IEEE754_CLASS_QNAN: - return x; - case IEEE754_CLASS_INF: - return ieee754dp_inf(0); - case IEEE754_CLASS_ZERO: - return ieee754dp_inf(1); - case IEEE754_CLASS_DNORM: - DPDNORMX; - break; - case IEEE754_CLASS_NORM: - break; - } - return ieee754dp_fint(xe); -} diff -Nru a/arch/mips64/math-emu/dp_modf.c b/arch/mips64/math-emu/dp_modf.c --- a/arch/mips64/math-emu/dp_modf.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,80 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -/* modf function is always exact for a finite number -*/ -ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip) -{ - COMPXDP; - - CLEARCX; - - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_INF: - case IEEE754_CLASS_ZERO: - *ip = x; - return x; - case IEEE754_CLASS_DNORM: - /* far to small */ - *ip = ieee754dp_zero(xs); - return x; - case IEEE754_CLASS_NORM: - break; - } - if (xe < 0) { - *ip = ieee754dp_zero(xs); - return x; - } - if (xe >= DP_MBITS) { - *ip = x; - return ieee754dp_zero(xs); - } - /* generate ipart mantissa by clearing bottom bits - */ - *ip = builddp(xs, xe + DP_EBIAS, - ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) & - ~DP_HIDDEN_BIT); - - /* generate fpart mantissa by clearing top bits - * and normalizing (must be able to normalize) - */ - xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe)); - if (xm == 0) - return ieee754dp_zero(xs); - - while ((xm >> DP_MBITS) == 0) { - xm <<= 1; - xe--; - } - return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -} diff -Nru a/arch/mips64/math-emu/dp_mul.c b/arch/mips64/math-emu/dp_mul.c --- a/arch/mips64/math-emu/dp_mul.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,180 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) -{ - COMPXDP; - COMPYDP; - - CLEARCX; - - EXPLODEXDP; - EXPLODEYDP; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "mul", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Infinity handling */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - SETCX(IEEE754_INVALID_OPERATION); - return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - return ieee754dp_inf(xs ^ ys); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return ieee754dp_zero(xs ^ ys); - - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - DPDNORMX; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - DPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - DPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - /* rm = xm * ym, re = xe+ye basicly */ - assert(xm & DP_HIDDEN_BIT); - assert(ym & DP_HIDDEN_BIT); - { - int re = xe + ye; - int rs = xs ^ ys; - unsigned long long rm; - - /* shunt to top of word */ - xm <<= 64 - (DP_MBITS + 1); - ym <<= 64 - (DP_MBITS + 1); - - /* multiply 32bits xm,ym to give high 32bits rm with stickness - */ - - /* 32 * 32 => 64 */ -#define DPXMULT(x,y) ((unsigned long long)(x) * (unsigned long long)y) - - { - unsigned lxm = xm; - unsigned hxm = xm >> 32; - unsigned lym = ym; - unsigned hym = ym >> 32; - unsigned long long lrm; - unsigned long long hrm; - - lrm = DPXMULT(lxm, lym); - hrm = DPXMULT(hxm, hym); - - { - unsigned long long t = DPXMULT(lxm, hym); - { - unsigned long long at = - lrm + (t << 32); - hrm += at < lrm; - lrm = at; - } - hrm = hrm + (t >> 32); - } - - { - unsigned long long t = DPXMULT(hxm, lym); - { - unsigned long long at = - lrm + (t << 32); - hrm += at < lrm; - lrm = at; - } - hrm = hrm + (t >> 32); - } - rm = hrm | (lrm != 0); - } - - /* - * sticky shift down to normal rounding precision - */ - if ((signed long long) rm < 0) { - rm = - (rm >> (64 - (DP_MBITS + 1 + 3))) | - ((rm << (DP_MBITS + 1 + 3)) != 0); - re++; - } else { - rm = - (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) | - ((rm << (DP_MBITS + 1 + 3 + 1)) != 0); - } - assert(rm & (DP_HIDDEN_BIT << 3)); - DPNORMRET2(rs, re, rm, "mul", x, y); - } -} diff -Nru a/arch/mips64/math-emu/dp_scalb.c b/arch/mips64/math-emu/dp_scalb.c --- a/arch/mips64/math-emu/dp_scalb.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_scalb(ieee754dp x, int n) -{ - COMPXDP; - - CLEARCX; - - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - return ieee754dp_nanxcpt(x, "scalb", x, n); - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_INF: - case IEEE754_CLASS_ZERO: - return x; - case IEEE754_CLASS_DNORM: - DPDNORMX; - break; - case IEEE754_CLASS_NORM: - break; - } - DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n); -} - - -ieee754dp ieee754dp_ldexp(ieee754dp x, int n) -{ - return ieee754dp_scalb(x, n); -} diff -Nru a/arch/mips64/math-emu/dp_simple.c b/arch/mips64/math-emu/dp_simple.c --- a/arch/mips64/math-emu/dp_simple.c Fri Jun 27 14:20:03 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,66 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -int ieee754dp_finite(ieee754dp x) -{ - return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS; -} - -ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y) -{ - CLEARCX; - DPSIGN(x) = DPSIGN(y); - return x; -} - - -ieee754dp ieee754dp_neg(ieee754dp x) -{ - CLEARCX; - - if (ieee754dp_isnan(x)) /* but not infinity */ - return ieee754dp_nanxcpt(x, "neg", x); - - /* quick fix up */ - DPSIGN(x) ^= 1; - return x; -} - - -ieee754dp ieee754dp_abs(ieee754dp x) -{ - CLEARCX; - - if (ieee754dp_isnan(x)) /* but not infinity */ - return ieee754dp_nanxcpt(x, "abs", x); - - /* quick fix up */ - DPSIGN(x) = 0; - return x; -} diff -Nru a/arch/mips64/math-emu/dp_sqrt.c b/arch/mips64/math-emu/dp_sqrt.c --- a/arch/mips64/math-emu/dp_sqrt.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,167 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision square root - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -static const struct ieee754dp_konst knan = { -#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__) - 0, 0, DP_EBIAS + DP_EMAX + 1, 0 -#else - 0, DP_EBIAS + DP_EMAX + 1, 0, 0 -#endif -}; - -#define nan ((ieee754dp)knan) - -static const unsigned table[] = { - 0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, - 29598, 36145, 43202, 50740, 58733, 67158, 75992, - 85215, 83599, 71378, 60428, 50647, 41945, 34246, - 27478, 21581, 16499, 12183, 8588, 5674, 3403, - 1742, 661, 130 -}; - -ieee754dp ieee754dp_sqrt(ieee754dp x) -{ - struct ieee754_csr oldcsr; - ieee754dp y, z, t; - unsigned scalx, yh; - COMPXDP; - - EXPLODEXDP; - - /* x == INF or NAN? */ - switch (xc) { - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: - /* sqrt(Nan) = Nan */ - return ieee754dp_nanxcpt(x, "sqrt"); - case IEEE754_CLASS_ZERO: - /* sqrt(0) = 0 */ - return x; - case IEEE754_CLASS_INF: - if (xs) - /* sqrt(-Inf) = Nan */ - return ieee754dp_nanxcpt(nan, "sqrt"); - /* sqrt(+Inf) = Inf */ - return x; - case IEEE754_CLASS_DNORM: - DPDNORMX; - /* fall through */ - case IEEE754_CLASS_NORM: - if (xs) - /* sqrt(-x) = Nan */ - return ieee754dp_nanxcpt(nan, "sqrt"); - break; - } - - /* save old csr; switch off INX enable & flag; set RN rounding */ - oldcsr = ieee754_csr; - ieee754_csr.mx &= ~IEEE754_INEXACT; - ieee754_csr.sx &= ~IEEE754_INEXACT; - ieee754_csr.rm = IEEE754_RN; - - /* adjust exponent to prevent overflow */ - scalx = 0; - if (xe > 512) { /* x > 2**-512? */ - xe -= 512; /* x = x / 2**512 */ - scalx += 256; - } else if (xe < -512) { /* x < 2**-512? */ - xe += 512; /* x = x * 2**512 */ - scalx -= 256; - } - - y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); - - /* magic initial approximation to almost 8 sig. bits */ - yh = y.bits >> 32; - yh = (yh >> 1) + 0x1ff80000; - yh = yh - table[(yh >> 15) & 31]; - y.bits = ((unsigned long long) yh << 32) | (y.bits & 0xffffffff); - - /* Heron's rule once with correction to improve to ~18 sig. bits */ - /* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */ - t = ieee754dp_div(x, y); - y = ieee754dp_add(y, t); - y.bits -= 0x0010000600000000LL; - y.bits &= 0xffffffff00000000LL; - - /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */ - /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */ - z = t = ieee754dp_mul(y, y); - t.parts.bexp += 0x001; - t = ieee754dp_add(t, z); - z = ieee754dp_mul(ieee754dp_sub(x, z), y); - - /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */ - t = ieee754dp_div(z, ieee754dp_add(t, x)); - t.parts.bexp += 0x001; - y = ieee754dp_add(y, t); - - /* twiddle last bit to force y correctly rounded */ - - /* set RZ, clear INEX flag */ - ieee754_csr.rm = IEEE754_RZ; - ieee754_csr.sx &= ~IEEE754_INEXACT; - - /* t=x/y; ...chopped quotient, possibly inexact */ - t = ieee754dp_div(x, y); - - if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) { - - if (!(ieee754_csr.sx & IEEE754_INEXACT)) - /* t = t-ulp */ - t.bits -= 1; - - /* add inexact to result status */ - oldcsr.cx |= IEEE754_INEXACT; - oldcsr.sx |= IEEE754_INEXACT; - - switch (oldcsr.rm) { - case IEEE754_RP: - y.bits += 1; - /* drop through */ - case IEEE754_RN: - t.bits += 1; - break; - } - - /* y=y+t; ...chopped sum */ - y = ieee754dp_add(y, t); - - /* adjust scalx for correctly rounded sqrt(x) */ - scalx -= 1; - } - - /* py[n0]=py[n0]+scalx; ...scale back y */ - y.parts.bexp += scalx; - - /* restore rounding mode, possibly set inexact */ - ieee754_csr = oldcsr; - - return y; -} diff -Nru a/arch/mips64/math-emu/dp_sub.c b/arch/mips64/math-emu/dp_sub.c --- a/arch/mips64/math-emu/dp_sub.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,194 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) -{ - COMPXDP; - COMPYDP; - - CLEARCX; - - EXPLODEXDP; - EXPLODEYDP; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(ieee754dp_bestnan(x, y), "sub", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754dp_nanxcpt(y, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754dp_nanxcpt(x, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754dp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Inifity handling - */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (xs != ys) - return x; - SETCX(IEEE754_INVALID_OPERATION); - return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - return ieee754dp_inf(ys ^ 1); - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - return x; - - /* Zero handling - */ - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs != ys) - return x; - else - return ieee754dp_zero(ieee754_csr.rm == - IEEE754_RD); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - /* quick fix up */ - DPSIGN(y) ^= 1; - return y; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - DPDNORMX; - /* FAAL THOROUGH */ - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - /* normalize ym,ye */ - DPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - /* normalize xm,xe */ - DPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - /* flip sign of y and handle as add */ - ys ^= 1; - - assert(xm & DP_HIDDEN_BIT); - assert(ym & DP_HIDDEN_BIT); - - - /* provide guard,round and stick bit dpace */ - xm <<= 3; - ym <<= 3; - - if (xe > ye) { - /* have to shift y fraction right to align - */ - int s = xe - ye; - ym = XDPSRS(ym, s); - ye += s; - } else if (ye > xe) { - /* have to shift x fraction right to align - */ - int s = ye - xe; - xm = XDPSRS(xm, s); - xe += s; - } - assert(xe == ye); - assert(xe <= DP_EMAX); - - if (xs == ys) { - /* generate 28 bit result of adding two 27 bit numbers - */ - xm = xm + ym; - xe = xe; - xs = xs; - - if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */ - xm = XDPSRS1(xm); /* shift preserving sticky */ - xe++; - } - } else { - if (xm >= ym) { - xm = xm - ym; - xe = xe; - xs = xs; - } else { - xm = ym - xm; - xe = xe; - xs = ys; - } - if (xm == 0) { - if (ieee754_csr.rm == IEEE754_RD) - return ieee754dp_zero(1); /* round negative inf. => sign = -1 */ - else - return ieee754dp_zero(0); /* other round modes => sign = 1 */ - } - - /* normalize to rounding precision - */ - while ((xm >> (DP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - } - DPNORMRET2(xs, xe, xm, "sub", x, y); -} diff -Nru a/arch/mips64/math-emu/dp_tint.c b/arch/mips64/math-emu/dp_tint.c --- a/arch/mips64/math-emu/dp_tint.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,88 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include <linux/kernel.h> -#include "ieee754dp.h" - -int ieee754dp_tint(ieee754dp x) -{ - COMPXDP; - - CLEARCX; - - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754si_xcpt(ieee754si_indef(), "fixdp", x); - case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fixdp", x); - case IEEE754_CLASS_ZERO: - return 0; - case IEEE754_CLASS_DNORM: /* much to small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fixdp", x); - case IEEE754_CLASS_NORM: - break; - } - if (xe >= 31) { - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fix", x); - } - if (xe < 0) { - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fix", x); - } - /* oh gawd */ - if (xe > DP_MBITS) { - xm <<= xe - DP_MBITS; - } else if (xe < DP_MBITS) { - /* XXX no rounding - */ - xm >>= DP_MBITS - xe; - } - if (xs) - return -xm; - else - return xm; -} - - -unsigned int ieee754dp_tuns(ieee754dp x) -{ - ieee754dp hb = ieee754dp_1e31(); - - /* what if x < 0 ?? */ - if (ieee754dp_lt(x, hb)) - return (unsigned) ieee754dp_tint(x); - - return (unsigned) ieee754dp_tint(ieee754dp_sub(x, hb)) | - ((unsigned) 1 << 31); -} diff -Nru a/arch/mips64/math-emu/dp_tlong.c b/arch/mips64/math-emu/dp_tlong.c --- a/arch/mips64/math-emu/dp_tlong.c Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,141 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -long long ieee754dp_tlong(ieee754dp x) -{ - COMPXDP; - - CLEARCX; - - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); - case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); - return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); - case IEEE754_CLASS_ZERO: - return 0; - case IEEE754_CLASS_DNORM: /* much too small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "dp_tlong", x); - case IEEE754_CLASS_NORM: - break; - } - if (xe >= 63) { - SETCX(IEEE754_OVERFLOW); - return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); - } - if (xe < 0) { - if (ieee754_csr.rm == IEEE754_RU) { - if (xs) { /* Negative */ - return 0x0000000000000000LL; - } else { /* Positive */ - return 0x0000000000000001LL; - } - } else if (ieee754_csr.rm == IEEE754_RD) { - if (xs) { /* Negative , return -1 */ - return 0xffffffffffffffffLL; - } else { /* Positive */ - return 0x0000000000000000LL; - } - } else { - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "dp_tlong", x); - } - } - /* oh gawd */ - if (xe > DP_MBITS) { - xm <<= xe - DP_MBITS; - } else if (xe < DP_MBITS) { - unsigned long long residue; - unsigned long long mask = 0; - int i; - int round; - int sticky; - int odd; - - /* compute mask */ - for (i = 0; i < DP_MBITS - xe; i++) { - mask = mask << 1; - mask = mask | 0x1; - } - residue = (xm & mask) << (64 - (DP_MBITS - xe)); - round = - ((0x8000000000000000LL & residue) != - 0x0000000000000000LL); - sticky = - ((0x7fffffffffffffffLL & residue) != - 0x0000000000000000LL); - - xm >>= DP_MBITS - xe; - - odd = ((xm & 0x1) != 0x0000000000000000LL); - - /* Do the rounding */ - if (!round && sticky) { - if ((ieee754_csr.rm == IEEE754_RU && !xs) - || (ieee754_csr.rm == IEEE754_RD && xs)) { - xm++; - } - } else if (round && !sticky) { - if ((ieee754_csr.rm == IEEE754_RU && !xs) - || (ieee754_csr.rm == IEEE754_RD && xs) - || (ieee754_csr.rm == IEEE754_RN && odd)) { - xm++; - } - } else if (round && sticky) { - if ((ieee754_csr.rm == IEEE754_RU && !xs) - || (ieee754_csr.rm == IEEE754_RD && xs) - || (ieee754_csr.rm == IEEE754_RN)) { - xm++; - } - } - } - if (xs) - return -xm; - else - return xm; -} - - -unsigned long long ieee754dp_tulong(ieee754dp x) -{ - ieee754dp hb = ieee754dp_1e63(); - - /* what if x < 0 ?? */ - if (ieee754dp_lt(x, hb)) - return (unsigned long long) ieee754dp_tlong(x); - - return (unsigned long long) ieee754dp_tlong(ieee754dp_sub(x, hb)) | - (1ULL << 63); -} diff -Nru a/arch/mips64/math-emu/ieee754.c b/arch/mips64/math-emu/ieee754.c --- a/arch/mips64/math-emu/ieee754.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,138 +0,0 @@ -/* ieee754 floating point arithmetic - * single and double precision - * - * BUGS - * not much dp done - * doesn't generate IEEE754_INEXACT - * - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754int.h" - -#define DP_EBIAS 1023 -#define DP_EMIN (-1022) -#define DP_EMAX 1023 - -#define SP_EBIAS 127 -#define SP_EMIN (-126) -#define SP_EMAX 127 - -/* indexed by class */ -const char *const ieee754_cname[] = { - "Normal", - "Zero", - "Denormal", - "Infinity", - "QNaN", - "SNaN", -}; - -/* the control status register -*/ -struct ieee754_csr ieee754_csr; - -/* special constants -*/ - - -#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__) -#define SPSTR(s,b,m) {m,b,s} -#define DPSTR(s,b,mh,ml) {ml,mh,b,s} -#endif - -#ifdef __MIPSEB__ -#define SPSTR(s,b,m) {s,b,m} -#define DPSTR(s,b,mh,ml) {s,b,mh,ml} -#endif - -const struct ieee754dp_konst __ieee754dp_spcvals[] = { - DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* + zero */ - DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* - zero */ - DPSTR(0, DP_EBIAS, 0, 0), /* + 1.0 */ - DPSTR(1, DP_EBIAS, 0, 0), /* - 1.0 */ - DPSTR(0, 3 + DP_EBIAS, 0x40000, 0), /* + 10.0 */ - DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */ - DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */ - DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */ - DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x40000, 0), /* + indef quiet Nan */ - DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */ - DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */ - DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */ - DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0), /* - min normal */ - DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* + min denormal */ - DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* - min denormal */ - DPSTR(0, 31 + DP_EBIAS, 0, 0), /* + 1.0e31 */ - DPSTR(0, 63 + DP_EBIAS, 0, 0), /* + 1.0e63 */ -}; - -const struct ieee754sp_konst __ieee754sp_spcvals[] = { - SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0), /* + zero */ - SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0), /* - zero */ - SPSTR(0, SP_EBIAS, 0), /* + 1.0 */ - SPSTR(1, SP_EBIAS, 0), /* - 1.0 */ - SPSTR(0, 3 + SP_EBIAS, 0x200000), /* + 10.0 */ - SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */ - SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */ - SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */ - SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x200000), /* + indef quiet Nan */ - SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */ - SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */ - SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */ - SPSTR(1, SP_EMIN + SP_EBIAS, 0), /* - min normal */ - SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1), /* + min denormal */ - SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1), /* - min denormal */ - SPSTR(0, 31 + SP_EBIAS, 0), /* + 1.0e31 */ - SPSTR(0, 63 + SP_EBIAS, 0), /* + 1.0e63 */ -}; - - -int ieee754si_xcpt(int r, const char *op, ...) -{ - struct ieee754xctx ax; - - if (!TSTX()) - return r; - ax.op = op; - ax.rt = IEEE754_RT_SI; - ax.rv.si = r; - va_start(ax.ap, op); - ieee754_xcpt(&ax); - return ax.rv.si; -} - -long long ieee754di_xcpt(long long r, const char *op, ...) -{ - struct ieee754xctx ax; - - if (!TSTX()) - return r; - ax.op = op; - ax.rt = IEEE754_RT_DI; - ax.rv.di = r; - va_start(ax.ap, op); - ieee754_xcpt(&ax); - return ax.rv.di; -} diff -Nru a/arch/mips64/math-emu/ieee754.h b/arch/mips64/math-emu/ieee754.h --- a/arch/mips64/math-emu/ieee754.h Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,490 +0,0 @@ -/* single and double precision fp ops - * missing extended precision. -*/ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - -/************************************************************************** - * Nov 7, 2000 - * Modification to allow integration with Linux kernel - * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - *************************************************************************/ - -#ifdef __KERNEL__ -/* Going from Algorithmics to Linux native environment, add this */ -#include <linux/types.h> - -/* - * Not very pretty, but the Linux kernel's normal va_list definition - * does not allow it to be used as a structure element, as it is here. - */ -#ifndef _STDARG_H -#include <stdarg.h> -#endif - -#else - -/* Note that __KERNEL__ is taken to mean Linux kernel */ - -#if #system(OpenBSD) -#include <machine/types.h> -#endif -#include <machine/endian.h> - -#endif /* __KERNEL__ */ - -#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__) -struct ieee754dp_konst { - unsigned mantlo:32; - unsigned manthi:20; - unsigned bexp:11; - unsigned sign:1; -}; -struct ieee754sp_konst { - unsigned mant:23; - unsigned bexp:8; - unsigned sign:1; -}; - -typedef union _ieee754dp { - struct ieee754dp_konst oparts; - struct { - unsigned long long mant:52; - unsigned int bexp:11; - unsigned int sign:1; - } parts; - unsigned long long bits; - double d; -} ieee754dp; - -typedef union _ieee754sp { - struct ieee754sp_konst parts; - float f; - unsigned long bits; -} ieee754sp; -#endif - -#if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__) -struct ieee754dp_konst { - unsigned sign:1; - unsigned bexp:11; - unsigned manthi:20; - unsigned mantlo:32; -}; -typedef union _ieee754dp { - struct ieee754dp_konst oparts; - struct { - unsigned int sign:1; - unsigned int bexp:11; - unsigned long long mant:52; - } parts; - double d; - unsigned long long bits; -} ieee754dp; - -struct ieee754sp_konst { - unsigned sign:1; - unsigned bexp:8; - unsigned mant:23; -}; - -typedef union _ieee754sp { - struct ieee754sp_konst parts; - float f; - unsigned long bits; -} ieee754sp; -#endif - -/* - * single precision (often aka float) -*/ -int ieee754sp_finite(ieee754sp x); -int ieee754sp_class(ieee754sp x); - -ieee754sp ieee754sp_abs(ieee754sp x); -ieee754sp ieee754sp_neg(ieee754sp x); -ieee754sp ieee754sp_scalb(ieee754sp x, int); -ieee754sp ieee754sp_logb(ieee754sp x); - -/* x with sign of y */ -ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y); - -ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y); -ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y); -ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y); -ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y); - -ieee754sp ieee754sp_fint(int x); -ieee754sp ieee754sp_funs(unsigned x); -ieee754sp ieee754sp_flong(long long x); -ieee754sp ieee754sp_fulong(unsigned long long x); -ieee754sp ieee754sp_fdp(ieee754dp x); - -int ieee754sp_tint(ieee754sp x); -unsigned int ieee754sp_tuns(ieee754sp x); -long long ieee754sp_tlong(ieee754sp x); -unsigned long long ieee754sp_tulong(ieee754sp x); - -int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop); -/* - * basic sp math - */ -ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip); -ieee754sp ieee754sp_frexp(ieee754sp x, int *exp); -ieee754sp ieee754sp_ldexp(ieee754sp x, int exp); - -ieee754sp ieee754sp_ceil(ieee754sp x); -ieee754sp ieee754sp_floor(ieee754sp x); -ieee754sp ieee754sp_trunc(ieee754sp x); - -ieee754sp ieee754sp_sqrt(ieee754sp x); - -/* - * double precision (often aka double) -*/ -int ieee754dp_finite(ieee754dp x); -int ieee754dp_class(ieee754dp x); - -/* x with sign of y */ -ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y); - -ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y); -ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y); -ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y); -ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y); - -ieee754dp ieee754dp_abs(ieee754dp x); -ieee754dp ieee754dp_neg(ieee754dp x); -ieee754dp ieee754dp_scalb(ieee754dp x, int); - -/* return exponent as integer in floating point format - */ -ieee754dp ieee754dp_logb(ieee754dp x); - -ieee754dp ieee754dp_fint(int x); -ieee754dp ieee754dp_funs(unsigned x); -ieee754dp ieee754dp_flong(long long x); -ieee754dp ieee754dp_fulong(unsigned long long x); -ieee754dp ieee754dp_fsp(ieee754sp x); - -ieee754dp ieee754dp_ceil(ieee754dp x); -ieee754dp ieee754dp_floor(ieee754dp x); -ieee754dp ieee754dp_trunc(ieee754dp x); - -int ieee754dp_tint(ieee754dp x); -unsigned int ieee754dp_tuns(ieee754dp x); -long long ieee754dp_tlong(ieee754dp x); -unsigned long long ieee754dp_tulong(ieee754dp x); - -int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop); -/* - * basic sp math - */ -ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip); -ieee754dp ieee754dp_frexp(ieee754dp x, int *exp); -ieee754dp ieee754dp_ldexp(ieee754dp x, int exp); - -ieee754dp ieee754dp_ceil(ieee754dp x); -ieee754dp ieee754dp_floor(ieee754dp x); -ieee754dp ieee754dp_trunc(ieee754dp x); - -ieee754dp ieee754dp_sqrt(ieee754dp x); - - - -/* 5 types of floating point number -*/ -#define IEEE754_CLASS_NORM 0x00 -#define IEEE754_CLASS_ZERO 0x01 -#define IEEE754_CLASS_DNORM 0x02 -#define IEEE754_CLASS_INF 0x03 -#define IEEE754_CLASS_SNAN 0x04 -#define IEEE754_CLASS_QNAN 0x05 -extern const char *const ieee754_cname[]; - -/* exception numbers */ -#define IEEE754_INEXACT 0x01 -#define IEEE754_UNDERFLOW 0x02 -#define IEEE754_OVERFLOW 0x04 -#define IEEE754_ZERO_DIVIDE 0x08 -#define IEEE754_INVALID_OPERATION 0x10 - -/* cmp operators -*/ -#define IEEE754_CLT 0x01 -#define IEEE754_CEQ 0x02 -#define IEEE754_CGT 0x04 -#define IEEE754_CUN 0x08 - -/* rounding mode -*/ -#define IEEE754_RN 0 /* round to nearest */ -#define IEEE754_RZ 1 /* round toward zero */ -#define IEEE754_RD 2 /* round toward -Infinity */ -#define IEEE754_RU 3 /* round toward +Infinity */ - -/* other naming */ -#define IEEE754_RM IEEE754_RD -#define IEEE754_RP IEEE754_RU - -/* "normal" comparisons -*/ -static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y) -{ - return ieee754sp_cmp(x, y, IEEE754_CEQ); -} - -static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y) -{ - return ieee754sp_cmp(x, y, - IEEE754_CLT | IEEE754_CGT | IEEE754_CUN); -} - -static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y) -{ - return ieee754sp_cmp(x, y, IEEE754_CLT); -} - -static __inline int ieee754sp_le(ieee754sp x, ieee754sp y) -{ - return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ); -} - -static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y) -{ - return ieee754sp_cmp(x, y, IEEE754_CGT); -} - - -static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y) -{ - return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ); -} - -static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y) -{ - return ieee754dp_cmp(x, y, IEEE754_CEQ); -} - -static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y) -{ - return ieee754dp_cmp(x, y, - IEEE754_CLT | IEEE754_CGT | IEEE754_CUN); -} - -static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y) -{ - return ieee754dp_cmp(x, y, IEEE754_CLT); -} - -static __inline int ieee754dp_le(ieee754dp x, ieee754dp y) -{ - return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ); -} - -static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y) -{ - return ieee754dp_cmp(x, y, IEEE754_CGT); -} - -static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y) -{ - return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ); -} - - -/* like strtod -*/ -ieee754dp ieee754dp_fstr(const char *s, char **endp); -char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af); - - -/* the control status register -*/ -struct ieee754_csr { - unsigned pad:13; - unsigned noq:1; /* set 1 for no quiet NaN's */ - unsigned nod:1; /* set 1 for no denormalised numbers */ - unsigned cx:5; /* exceptions this operation */ - unsigned mx:5; /* exception enable mask */ - unsigned sx:5; /* exceptions total */ - unsigned rm:2; /* current rounding mode */ -}; -extern struct ieee754_csr ieee754_csr; - -static __inline unsigned ieee754_getrm(void) -{ - return (ieee754_csr.rm); -} -static __inline unsigned ieee754_setrm(unsigned rm) -{ - return (ieee754_csr.rm = rm); -} - -/* - * get current exceptions - */ -static __inline unsigned ieee754_getcx(void) -{ - return (ieee754_csr.cx); -} - -/* test for current exception condition - */ -static __inline int ieee754_cxtest(unsigned n) -{ - return (ieee754_csr.cx & n); -} - -/* - * get sticky exceptions - */ -static __inline unsigned ieee754_getsx(void) -{ - return (ieee754_csr.sx); -} - -/* clear sticky conditions -*/ -static __inline unsigned ieee754_clrsx(void) -{ - return (ieee754_csr.sx = 0); -} - -/* test for sticky exception condition - */ -static __inline int ieee754_sxtest(unsigned n) -{ - return (ieee754_csr.sx & n); -} - -/* debugging */ -ieee754sp ieee754sp_dump(char *s, ieee754sp x); -ieee754dp ieee754dp_dump(char *s, ieee754dp x); - -#define IEEE754_SPCVAL_PZERO 0 -#define IEEE754_SPCVAL_NZERO 1 -#define IEEE754_SPCVAL_PONE 2 -#define IEEE754_SPCVAL_NONE 3 -#define IEEE754_SPCVAL_PTEN 4 -#define IEEE754_SPCVAL_NTEN 5 -#define IEEE754_SPCVAL_PINFINITY 6 -#define IEEE754_SPCVAL_NINFINITY 7 -#define IEEE754_SPCVAL_INDEF 8 -#define IEEE754_SPCVAL_PMAX 9 /* +max norm */ -#define IEEE754_SPCVAL_NMAX 10 /* -max norm */ -#define IEEE754_SPCVAL_PMIN 11 /* +min norm */ -#define IEEE754_SPCVAL_NMIN 12 /* +min norm */ -#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */ -#define IEEE754_SPCVAL_NMIND 14 /* +min denorm */ -#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */ -#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */ - -extern const struct ieee754dp_konst __ieee754dp_spcvals[]; -extern const struct ieee754sp_konst __ieee754sp_spcvals[]; -#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals) -#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals) - -/* return infinity with given sign -*/ -#define ieee754dp_inf(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) -#define ieee754dp_zero(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) -#define ieee754dp_one(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) -#define ieee754dp_ten(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) -#define ieee754dp_indef() \ - (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF]) -#define ieee754dp_max(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) -#define ieee754dp_min(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) -#define ieee754dp_mind(sn) \ - (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) -#define ieee754dp_1e31() \ - (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31]) -#define ieee754dp_1e63() \ - (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63]) - -#define ieee754sp_inf(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) -#define ieee754sp_zero(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) -#define ieee754sp_one(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) -#define ieee754sp_ten(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) -#define ieee754sp_indef() \ - (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF]) -#define ieee754sp_max(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) -#define ieee754sp_min(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) -#define ieee754sp_mind(sn) \ - (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) -#define ieee754sp_1e31() \ - (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31]) -#define ieee754sp_1e63() \ - (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63]) - -/* indefinite integer value -*/ -#define ieee754si_indef() INT_MIN -#ifdef LONG_LONG_MIN -#define ieee754di_indef() LONG_LONG_MIN -#else -#define ieee754di_indef() (-9223372036854775807LL-1) -#endif - -/* IEEE exception context, passed to handler */ -struct ieee754xctx { - const char *op; /* operation name */ - int rt; /* result type */ - union { - ieee754sp sp; /* single precision */ - ieee754dp dp; /* double precision */ -#ifdef IEEE854_XP - ieee754xp xp; /* extended precision */ -#endif - int si; /* standard signed integer (32bits) */ - long long di; /* extended signed integer (64bits) */ - } rv; /* default result format implied by op */ - va_list ap; -}; - -/* result types for xctx.rt */ -#define IEEE754_RT_SP 0 -#define IEEE754_RT_DP 1 -#define IEEE754_RT_XP 2 -#define IEEE754_RT_SI 3 -#define IEEE754_RT_DI 4 - -extern void ieee754_xcpt(struct ieee754xctx *xcp); - -/* compat */ -#define ieee754dp_fix(x) ieee754dp_tint(x) -#define ieee754sp_fix(x) ieee754sp_tint(x) diff -Nru a/arch/mips64/math-emu/ieee754d.c b/arch/mips64/math-emu/ieee754d.c --- a/arch/mips64/math-emu/ieee754d.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,142 +0,0 @@ -/* some debug functions -*/ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - -/************************************************************************** - * Nov 7, 2000 - * Modified to build and operate in Linux kernel environment. - * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - *************************************************************************/ - -#include "ieee754.h" - -#define DP_EBIAS 1023 -#define DP_EMIN (-1022) -#define DP_EMAX 1023 -#define DP_FBITS 52 - -#define SP_EBIAS 127 -#define SP_EMIN (-126) -#define SP_EMAX 127 -#define SP_FBITS 23 - -#define DP_MBIT(x) ((unsigned long long)1 << (x)) -#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS) -#define DP_SIGN_BIT DP_MBIT(63) - - -#define SP_MBIT(x) ((unsigned long)1 << (x)) -#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS) -#define SP_SIGN_BIT SP_MBIT(31) - - -#define SPSIGN(sp) (sp.parts.sign) -#define SPBEXP(sp) (sp.parts.bexp) -#define SPMANT(sp) (sp.parts.mant) - -#define DPSIGN(dp) (dp.parts.sign) -#define DPBEXP(dp) (dp.parts.bexp) -#define DPMANT(dp) (dp.parts.mant) - -ieee754dp ieee754dp_dump(char *m, ieee754dp x) -{ - int i; - - printk("%s", m); - printk("<%08x,%08x>\n", (unsigned) (x.bits >> 32), - (unsigned) x.bits); - printk("\t="); - switch (ieee754dp_class(x)) { - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: - printk("Nan %c", DPSIGN(x) ? '-' : '+'); - for (i = DP_FBITS - 1; i >= 0; i--) - printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); - break; - case IEEE754_CLASS_INF: - printk("%cInfinity", DPSIGN(x) ? '-' : '+'); - break; - case IEEE754_CLASS_ZERO: - printk("%cZero", DPSIGN(x) ? '-' : '+'); - break; - case IEEE754_CLASS_DNORM: - printk("%c0.", DPSIGN(x) ? '-' : '+'); - for (i = DP_FBITS - 1; i >= 0; i--) - printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); - printk("e%d", DPBEXP(x) - DP_EBIAS); - break; - case IEEE754_CLASS_NORM: - printk("%c1.", DPSIGN(x) ? '-' : '+'); - for (i = DP_FBITS - 1; i >= 0; i--) - printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); - printk("e%d", DPBEXP(x) - DP_EBIAS); - break; - default: - printk("Illegal/Unknown IEEE754 value class"); - } - printk("\n"); - return x; -} - -ieee754sp ieee754sp_dump(char *m, ieee754sp x) -{ - int i; - - printk("%s=", m); - printk("<%08x>\n", (unsigned) x.bits); - printk("\t="); - switch (ieee754sp_class(x)) { - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: - printk("Nan %c", SPSIGN(x) ? '-' : '+'); - for (i = SP_FBITS - 1; i >= 0; i--) - printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); - break; - case IEEE754_CLASS_INF: - printk("%cInfinity", SPSIGN(x) ? '-' : '+'); - break; - case IEEE754_CLASS_ZERO: - printk("%cZero", SPSIGN(x) ? '-' : '+'); - break; - case IEEE754_CLASS_DNORM: - printk("%c0.", SPSIGN(x) ? '-' : '+'); - for (i = SP_FBITS - 1; i >= 0; i--) - printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); - printk("e%d", SPBEXP(x) - SP_EBIAS); - break; - case IEEE754_CLASS_NORM: - printk("%c1.", SPSIGN(x) ? '-' : '+'); - for (i = SP_FBITS - 1; i >= 0; i--) - printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); - printk("e%d", SPBEXP(x) - SP_EBIAS); - break; - default: - printk("Illegal/Unknown IEEE754 value class"); - } - printk("\n"); - return x; -} - diff -Nru a/arch/mips64/math-emu/ieee754dp.c b/arch/mips64/math-emu/ieee754dp.c --- a/arch/mips64/math-emu/ieee754dp.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,197 +0,0 @@ -/* IEEE754 floating point arithmetic - * double precision: common utilities - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754dp.h" - -int ieee754dp_class(ieee754dp x) -{ - COMPXDP; - EXPLODEXDP; - return xc; -} - -int ieee754dp_isnan(ieee754dp x) -{ - return ieee754dp_class(x) >= IEEE754_CLASS_SNAN; -} - -int ieee754dp_issnan(ieee754dp x) -{ - assert(ieee754dp_isnan(x)); - if (ieee754_csr.noq) - return 1; - return !(DPMANT(x) & DP_MBIT(DP_MBITS - 1)); -} - - -ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...) -{ - struct ieee754xctx ax; - if (!TSTX()) - return r; - - ax.op = op; - ax.rt = IEEE754_RT_DP; - ax.rv.dp = r; - va_start(ax.ap, op); - ieee754_xcpt(&ax); - return ax.rv.dp; -} - -ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...) -{ - struct ieee754xctx ax; - - assert(ieee754dp_isnan(r)); - - if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ - return r; - - if (!SETCX(IEEE754_INVALID_OPERATION)) { - /* not enabled convert to a quiet NaN */ - if (ieee754_csr.noq) - return r; - DPMANT(r) |= DP_MBIT(DP_MBITS - 1); - return r; - } - - ax.op = op; - ax.rt = 0; - ax.rv.dp = r; - va_start(ax.ap, op); - ieee754_xcpt(&ax); - return ax.rv.dp; -} - -ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y) -{ - assert(ieee754dp_isnan(x)); - assert(ieee754dp_isnan(y)); - - if (DPMANT(x) > DPMANT(y)) - return x; - else - return y; -} - - -/* generate a normal/denormal number with over,under handling - * sn is sign - * xe is an unbiased exponent - * xm is 3bit extended precision value. - */ -ieee754dp ieee754dp_format(int sn, int xe, unsigned long long xm) -{ - assert(xm); /* we don't gen exact zeros (probably should) */ - - assert((xm >> (DP_MBITS + 1 + 3)) == 0); /* no execess */ - assert(xm & (DP_HIDDEN_BIT << 3)); - - if (xe < DP_EMIN) { - /* strip lower bits */ - int es = DP_EMIN - xe; - - if (ieee754_csr.nod) { - SETCX(IEEE754_UNDERFLOW); - return ieee754dp_zero(sn); - } - - /* sticky right shift es bits - */ - xm = XDPSRS(xm, es); - xe += es; - - assert((xm & (DP_HIDDEN_BIT << 3)) == 0); - assert(xe == DP_EMIN); - } - if (xm & (DP_MBIT(3) - 1)) { - SETCX(IEEE754_INEXACT); - /* inexact must round of 3 bits - */ - switch (ieee754_csr.rm) { - case IEEE754_RZ: - break; - case IEEE754_RN: - xm += 0x3 + ((xm >> 3) & 1); - /* xm += (xm&0x8)?0x4:0x3 */ - break; - case IEEE754_RU: /* toward +Infinity */ - if (!sn) /* ?? */ - xm += 0x8; - break; - case IEEE754_RD: /* toward -Infinity */ - if (sn) /* ?? */ - xm += 0x8; - break; - } - /* adjust exponent for rounding add overflowing - */ - if (xm >> (DP_MBITS + 3 + 1)) { /* add causes mantissa overflow */ - xm >>= 1; - xe++; - } - } - /* strip grs bits */ - xm >>= 3; - - assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ - assert(xe >= DP_EMIN); - - if (xe > DP_EMAX) { - SETCX(IEEE754_OVERFLOW); - /* -O can be table indexed by (rm,sn) */ - switch (ieee754_csr.rm) { - case IEEE754_RN: - return ieee754dp_inf(sn); - case IEEE754_RZ: - return ieee754dp_max(sn); - case IEEE754_RU: /* toward +Infinity */ - if (sn == 0) - return ieee754dp_inf(0); - else - return ieee754dp_max(1); - case IEEE754_RD: /* toward -Infinity */ - if (sn == 0) - return ieee754dp_max(0); - else - return ieee754dp_inf(1); - } - } - /* gen norm/denorm/zero */ - - if ((xm & DP_HIDDEN_BIT) == 0) { - /* we underflow (tiny/zero) */ - assert(xe == DP_EMIN); - SETCX(IEEE754_UNDERFLOW); - return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm); - } else { - assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ - assert(xm & DP_HIDDEN_BIT); - - return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); - } -} diff -Nru a/arch/mips64/math-emu/ieee754dp.h b/arch/mips64/math-emu/ieee754dp.h --- a/arch/mips64/math-emu/ieee754dp.h Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,83 +0,0 @@ -/* - * IEEE754 floating point - * double precision internal header file - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754int.h" - -#define assert(expr) ((void)0) - -/* 3bit extended double precision sticky right shift */ -#define XDPSRS(v,rs) \ - ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0)) - -#define XDPSRSX1() \ - (xe++, (xm = (xm >> 1) | (xm & 1))) - -#define XDPSRS1(v) \ - (((v) >> 1) | ((v) & 1)) - -/* convert denormal to normalized with extended exponent */ -#define DPDNORMx(m,e) \ - while( (m >> DP_MBITS) == 0) { m <<= 1; e--; } -#define DPDNORMX DPDNORMx(xm,xe) -#define DPDNORMY DPDNORMx(ym,ye) - -static __inline ieee754dp builddp(int s, int bx, unsigned long long m) -{ - ieee754dp r; - - assert((s) == 0 || (s) == 1); - assert((bx) >= DP_EMIN - 1 + DP_EBIAS - && (bx) <= DP_EMAX + 1 + DP_EBIAS); - assert(((m) >> DP_MBITS) == 0); - - r.parts.sign = s; - r.parts.bexp = bx; - r.parts.mant = m; - return r; -} - -extern int ieee754dp_isnan(ieee754dp); -extern int ieee754dp_issnan(ieee754dp); -extern int ieee754si_xcpt(int, const char *, ...); -extern long long ieee754di_xcpt(long long, const char *, ...); -extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...); -extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...); -extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp); -extern ieee754dp ieee754dp_format(int, int, unsigned long long); - - -#define DPNORMRET2(s,e,m,name,a0,a1) \ -{ \ - ieee754dp V = ieee754dp_format(s,e,m); \ - if(TSTX()) \ - return ieee754dp_xcpt(V,name,a0,a1); \ - else \ - return V; \ -} - -#define DPNORMRET1(s,e,m,name,a0) DPNORMRET2(s,e,m,name,a0,a0) diff -Nru a/arch/mips64/math-emu/ieee754int.h b/arch/mips64/math-emu/ieee754int.h --- a/arch/mips64/math-emu/ieee754int.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,135 +0,0 @@ -/* - * IEEE754 floating point - * common internal header file - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754.h" - -#define DP_EBIAS 1023 -#define DP_EMIN (-1022) -#define DP_EMAX 1023 -#define DP_MBITS 52 - -#define SP_EBIAS 127 -#define SP_EMIN (-126) -#define SP_EMAX 127 -#define SP_MBITS 23 - -#define DP_MBIT(x) ((unsigned long long)1 << (x)) -#define DP_HIDDEN_BIT DP_MBIT(DP_MBITS) -#define DP_SIGN_BIT DP_MBIT(63) - -#define SP_MBIT(x) ((unsigned long)1 << (x)) -#define SP_HIDDEN_BIT SP_MBIT(SP_MBITS) -#define SP_SIGN_BIT SP_MBIT(31) - - -#define SPSIGN(sp) (sp.parts.sign) -#define SPBEXP(sp) (sp.parts.bexp) -#define SPMANT(sp) (sp.parts.mant) - -#define DPSIGN(dp) (dp.parts.sign) -#define DPBEXP(dp) (dp.parts.bexp) -#define DPMANT(dp) (dp.parts.mant) - -#define CLPAIR(x,y) ((x)*6+(y)) - -#define CLEARCX \ - (ieee754_csr.cx = 0) - -#define SETCX(x) \ - (ieee754_csr.cx |= (x),ieee754_csr.sx |= (x),ieee754_csr.mx & (x)) - -#define TSTX() \ - (ieee754_csr.cx & ieee754_csr.mx) - - -#define COMPXSP \ - unsigned xm; int xe; int xs; int xc - -#define COMPYSP \ - unsigned ym; int ye; int ys; int yc - -#define EXPLODESP(v,vc,vs,ve,vm) \ -{\ - vs = SPSIGN(v);\ - ve = SPBEXP(v);\ - vm = SPMANT(v);\ - if(ve == SP_EMAX+1+SP_EBIAS){\ - if(vm == 0)\ - vc = IEEE754_CLASS_INF;\ - else if(vm & SP_MBIT(SP_MBITS-1)) \ - vc = IEEE754_CLASS_QNAN;\ - else \ - vc = IEEE754_CLASS_SNAN;\ - } else if(ve == SP_EMIN-1+SP_EBIAS) {\ - if(vm) {\ - ve = SP_EMIN;\ - vc = IEEE754_CLASS_DNORM;\ - } else\ - vc = IEEE754_CLASS_ZERO;\ - } else {\ - ve -= SP_EBIAS;\ - vm |= SP_HIDDEN_BIT;\ - vc = IEEE754_CLASS_NORM;\ - }\ -} -#define EXPLODEXSP EXPLODESP(x,xc,xs,xe,xm) -#define EXPLODEYSP EXPLODESP(y,yc,ys,ye,ym) - - -#define COMPXDP \ -unsigned long long xm; int xe; int xs; int xc - -#define COMPYDP \ -unsigned long long ym; int ye; int ys; int yc - -#define EXPLODEDP(v,vc,vs,ve,vm) \ -{\ - vm = DPMANT(v);\ - vs = DPSIGN(v);\ - ve = DPBEXP(v);\ - if(ve == DP_EMAX+1+DP_EBIAS){\ - if(vm == 0)\ - vc = IEEE754_CLASS_INF;\ - else if(vm & DP_MBIT(DP_MBITS-1)) \ - vc = IEEE754_CLASS_QNAN;\ - else \ - vc = IEEE754_CLASS_SNAN;\ - } else if(ve == DP_EMIN-1+DP_EBIAS) {\ - if(vm) {\ - ve = DP_EMIN;\ - vc = IEEE754_CLASS_DNORM;\ - } else\ - vc = IEEE754_CLASS_ZERO;\ - } else {\ - ve -= DP_EBIAS;\ - vm |= DP_HIDDEN_BIT;\ - vc = IEEE754_CLASS_NORM;\ - }\ -} -#define EXPLODEXDP EXPLODEDP(x,xc,xs,xe,xm) -#define EXPLODEYDP EXPLODEDP(y,yc,ys,ye,ym) diff -Nru a/arch/mips64/math-emu/ieee754m.c b/arch/mips64/math-emu/ieee754m.c --- a/arch/mips64/math-emu/ieee754m.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,56 +0,0 @@ -/* - * floor, trunc, ceil - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754.h" - -ieee754dp ieee754dp_floor(ieee754dp x) -{ - ieee754dp i; - - if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0))) - return ieee754dp_sub(i, ieee754dp_one(0)); - else - return i; -} - -ieee754dp ieee754dp_ceil(ieee754dp x) -{ - ieee754dp i; - - if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0))) - return ieee754dp_add(i, ieee754dp_one(0)); - else - return i; -} - -ieee754dp ieee754dp_trunc(ieee754dp x) -{ - ieee754dp i; - - (void) ieee754dp_modf(x, &i); - return i; -} diff -Nru a/arch/mips64/math-emu/ieee754sp.c b/arch/mips64/math-emu/ieee754sp.c --- a/arch/mips64/math-emu/ieee754sp.c Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,197 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -int ieee754sp_class(ieee754sp x) -{ - COMPXSP; - EXPLODEXSP; - return xc; -} - -int ieee754sp_isnan(ieee754sp x) -{ - return ieee754sp_class(x) >= IEEE754_CLASS_SNAN; -} - -int ieee754sp_issnan(ieee754sp x) -{ - assert(ieee754sp_isnan(x)); - if (ieee754_csr.noq) - return 1; - return !(SPMANT(x) & SP_MBIT(SP_MBITS - 1)); -} - - -ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...) -{ - struct ieee754xctx ax; - - if (!TSTX()) - return r; - - ax.op = op; - ax.rt = IEEE754_RT_SP; - ax.rv.sp = r; - va_start(ax.ap, op); - ieee754_xcpt(&ax); - return ax.rv.sp; -} - -ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...) -{ - struct ieee754xctx ax; - - assert(ieee754sp_isnan(r)); - - if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ - return r; - - if (!SETCX(IEEE754_INVALID_OPERATION)) { - /* not enabled convert to a quiet NaN */ - if (ieee754_csr.noq) - return r; - SPMANT(r) |= SP_MBIT(SP_MBITS - 1); - return r; - } - - ax.op = op; - ax.rt = 0; - ax.rv.sp = r; - va_start(ax.ap, op); - ieee754_xcpt(&ax); - return ax.rv.sp; -} - -ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y) -{ - assert(ieee754sp_isnan(x)); - assert(ieee754sp_isnan(y)); - - if (SPMANT(x) > SPMANT(y)) - return x; - else - return y; -} - - -/* generate a normal/denormal number with over,under handling - * sn is sign - * xe is an unbiased exponent - * xm is 3bit extended precision value. - */ -ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) -{ - assert(xm); /* we don't gen exact zeros (probably should) */ - - assert((xm >> (SP_MBITS + 1 + 3)) == 0); /* no execess */ - assert(xm & (SP_HIDDEN_BIT << 3)); - - if (xe < SP_EMIN) { - /* strip lower bits */ - int es = SP_EMIN - xe; - - if (ieee754_csr.nod) { - SETCX(IEEE754_UNDERFLOW); - return ieee754sp_zero(sn); - } - - /* sticky right shift es bits - */ - SPXSRSXn(es); - - assert((xm & (SP_HIDDEN_BIT << 3)) == 0); - assert(xe == SP_EMIN); - } - if (xm & (SP_MBIT(3) - 1)) { - SETCX(IEEE754_INEXACT); - /* inexact must round of 3 bits - */ - switch (ieee754_csr.rm) { - case IEEE754_RZ: - break; - case IEEE754_RN: - xm += 0x3 + ((xm >> 3) & 1); - /* xm += (xm&0x8)?0x4:0x3 */ - break; - case IEEE754_RU: /* toward +Infinity */ - if (!sn) /* ?? */ - xm += 0x8; - break; - case IEEE754_RD: /* toward -Infinity */ - if (sn) /* ?? */ - xm += 0x8; - break; - } - /* adjust exponent for rounding add overflowing - */ - if (xm >> (SP_MBITS + 1 + 3)) { /* add causes mantissa overflow */ - xm >>= 1; - xe++; - } - } - /* strip grs bits */ - xm >>= 3; - - assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ - assert(xe >= SP_EMIN); - - if (xe > SP_EMAX) { - SETCX(IEEE754_OVERFLOW); - /* -O can be table indexed by (rm,sn) */ - switch (ieee754_csr.rm) { - case IEEE754_RN: - return ieee754sp_inf(sn); - case IEEE754_RZ: - return ieee754sp_max(sn); - case IEEE754_RU: /* toward +Infinity */ - if (sn == 0) - return ieee754sp_inf(0); - else - return ieee754sp_max(1); - case IEEE754_RD: /* toward -Infinity */ - if (sn == 0) - return ieee754sp_max(0); - else - return ieee754sp_inf(1); - } - } - /* gen norm/denorm/zero */ - - if ((xm & SP_HIDDEN_BIT) == 0) { - /* we underflow (tiny/zero) */ - assert(xe == SP_EMIN); - SETCX(IEEE754_UNDERFLOW); - return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm); - } else { - assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ - assert(xm & SP_HIDDEN_BIT); - - return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); - } -} diff -Nru a/arch/mips64/math-emu/ieee754sp.h b/arch/mips64/math-emu/ieee754sp.h --- a/arch/mips64/math-emu/ieee754sp.h Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,89 +0,0 @@ -/* - * IEEE754 floating point - * double precision internal header file - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754int.h" - -#define assert(expr) ((void)0) - -/* 3bit extended single precision sticky right shift */ -#define SPXSRSXn(rs) \ - (xe += rs, \ - xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0)) - -#define SPXSRSX1() \ - (xe++, (xm = (xm >> 1) | (xm & 1))) - -#define SPXSRSYn(rs) \ - (ye+=rs, \ - ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0)) - -#define SPXSRSY1() \ - (ye++, (ym = (ym >> 1) | (ym & 1))) - -/* convert denormal to normalized with extended exponent */ -#define SPDNORMx(m,e) \ - while( (m >> SP_MBITS) == 0) { m <<= 1; e--; } -#define SPDNORMX SPDNORMx(xm,xe) -#define SPDNORMY SPDNORMx(ym,ye) - -static __inline ieee754sp buildsp(int s, int bx, unsigned m) -{ - ieee754sp r; - - assert((s) == 0 || (s) == 1); - assert((bx) >= SP_EMIN - 1 + SP_EBIAS - && (bx) <= SP_EMAX + 1 + SP_EBIAS); - assert(((m) >> SP_MBITS) == 0); - - r.parts.sign = s; - r.parts.bexp = bx; - r.parts.mant = m; - - return r; -} - -extern int ieee754sp_isnan(ieee754sp); -extern int ieee754sp_issnan(ieee754sp); -extern int ieee754si_xcpt(int, const char *, ...); -extern long long ieee754di_xcpt(long long, const char *, ...); -extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...); -extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...); -extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp); -extern ieee754sp ieee754sp_format(int, int, unsigned); - - -#define SPNORMRET2(s,e,m,name,a0,a1) \ -{ \ - ieee754sp V = ieee754sp_format(s,e,m); \ - if(TSTX()) \ - return ieee754sp_xcpt(V,name,a0,a1); \ - else \ - return V; \ -} - -#define SPNORMRET1(s,e,m,name,a0) SPNORMRET2(s,e,m,name,a0,a0) diff -Nru a/arch/mips64/math-emu/ieee754xcpt.c b/arch/mips64/math-emu/ieee754xcpt.c --- a/arch/mips64/math-emu/ieee754xcpt.c Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,48 +0,0 @@ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - -/************************************************************************** - * Nov 7, 2000 - * Added preprocessor hacks to map to Linux kernel diagnostics. - * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - *************************************************************************/ - -#include "ieee754.h" - -/* - * Very naff exception handler (you can plug in your own and - * override this). - */ - -static const char *const rtnames[] = { - "sp", "dp", "xp", "si", "di" -}; - -void ieee754_xcpt(struct ieee754xctx *xcp) -{ - printk("floating point exception in \"%s\", type=%s\n", - xcp->op, rtnames[xcp->rt]); -} - diff -Nru a/arch/mips64/math-emu/kernel_linkage.c b/arch/mips64/math-emu/kernel_linkage.c --- a/arch/mips64/math-emu/kernel_linkage.c Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,95 +0,0 @@ -/************************************************************************** - * - * arch/mips/math_emu/kernel_linkage.c - * - * Kevin D. Kissell, kevink@mips and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - *************************************************************************/ -/* - * Routines corresponding to Linux kernel FP context - * manipulation primitives for the Algorithmics MIPS - * FPU Emulator - */ - -#include <linux/sched.h> -#include <asm/processor.h> -#include <asm/signal.h> -#include <asm/uaccess.h> - -#include <asm/fpu_emulator.h> - -extern struct mips_fpu_emulator_private fpuemuprivate; - -#define SIGNALLING_NAN 0x7ff800007ff80000LL - -void fpu_emulator_init_fpu(void) -{ - static int first = 1; - int i; - - if (first) { - first = 0; - printk("Algorithmics/MIPS FPU Emulator v1.4\n"); - } - - current->thread.fpu.soft.sr = 0; - for (i = 0; i < 32; i++) { - current->thread.fpu.soft.regs[i] = SIGNALLING_NAN; - } -} - - -/* - * Emulator context save/restore to/from a signal context - * presumed to be on the user stack, and therefore accessed - * with appropriate macros from uaccess.h - */ - -int fpu_emulator_save_context(struct sigcontext *sc) -{ - int i; - int err = 0; - - for (i = 0; i < 32; i++) { - err |= - __put_user(current->thread.fpu.soft.regs[i], - &sc->sc_fpregs[i]); - } - err |= __put_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - err |= __put_user(fpuemuprivate.eir, &sc->sc_fpc_eir); - - return err; -} - -int fpu_emulator_restore_context(struct sigcontext *sc) -{ - int i; - int err = 0; - - for (i = 0; i < 32; i++) { - err |= - __get_user(current->thread.fpu.soft.regs[i], - &sc->sc_fpregs[i]); - } - err |= __get_user(current->thread.fpu.soft.sr, &sc->sc_fpc_csr); - err |= __get_user(fpuemuprivate.eir, &sc->sc_fpc_eir); - - return err; -} - diff -Nru a/arch/mips64/math-emu/sp_add.c b/arch/mips64/math-emu/sp_add.c --- a/arch/mips64/math-emu/sp_add.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,180 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) -{ - COMPXSP; - COMPYSP; - - EXPLODEXSP; - EXPLODEYSP; - - CLEARCX; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "add", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "add", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "add", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Inifity handling - */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (xs == ys) - return x; - SETCX(IEEE754_INVALID_OPERATION); - return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - return y; - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - return x; - - /* Zero handling - */ - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs == ys) - return x; - else - return ieee754sp_zero(ieee754_csr.rm == - IEEE754_RD); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return y; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - SPDNORMX; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - SPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - SPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - assert(xm & SP_HIDDEN_BIT); - assert(ym & SP_HIDDEN_BIT); - - /* provide guard,round and stick bit space */ - xm <<= 3; - ym <<= 3; - - if (xe > ye) { - /* have to shift y fraction right to align - */ - int s = xe - ye; - SPXSRSYn(s); - } else if (ye > xe) { - /* have to shift x fraction right to align - */ - int s = ye - xe; - SPXSRSXn(s); - } - assert(xe == ye); - assert(xe <= SP_EMAX); - - if (xs == ys) { - /* generate 28 bit result of adding two 27 bit numbers - * leaving result in xm,xs,xe - */ - xm = xm + ym; - xe = xe; - xs = xs; - - if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */ - SPXSRSX1(); - } - } else { - if (xm >= ym) { - xm = xm - ym; - xe = xe; - xs = xs; - } else { - xm = ym - xm; - xe = xe; - xs = ys; - } - if (xm == 0) - return ieee754sp_zero(ieee754_csr.rm == - IEEE754_RD); - - /* normalize in extended single precision */ - while ((xm >> (SP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - - } - SPNORMRET2(xs, xe, xm, "add", x, y); -} diff -Nru a/arch/mips64/math-emu/sp_cmp.c b/arch/mips64/math-emu/sp_cmp.c --- a/arch/mips64/math-emu/sp_cmp.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp) -{ - CLEARCX; - - if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) { - if (cmp & IEEE754_CUN) - return 1; - if (cmp & (IEEE754_CLT | IEEE754_CGT)) { - if (SETCX(IEEE754_INVALID_OPERATION)) - return ieee754si_xcpt(0, "fcmpf", x); - } - return 0; - } else { - int vx = x.bits; - int vy = y.bits; - - if (vx < 0) - vx = -vx ^ SP_SIGN_BIT; - if (vy < 0) - vy = -vy ^ SP_SIGN_BIT; - - if (vx < vy) - return (cmp & IEEE754_CLT) != 0; - else if (vx == vy) - return (cmp & IEEE754_CEQ) != 0; - else - return (cmp & IEEE754_CGT) != 0; - } -} diff -Nru a/arch/mips64/math-emu/sp_div.c b/arch/mips64/math-emu/sp_div.c --- a/arch/mips64/math-emu/sp_div.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,160 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) -{ - COMPXSP; - COMPYSP; - - CLEARCX; - - EXPLODEXSP; - EXPLODEYSP; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "div", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "div", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "div", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Infinity handling - */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - SETCX(IEEE754_INVALID_OPERATION); - return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - return ieee754sp_zero(xs ^ ys); - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - return ieee754sp_inf(xs ^ ys); - - /* Zero handling - */ - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - SETCX(IEEE754_INVALID_OPERATION); - return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - SETCX(IEEE754_ZERO_DIVIDE); - return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - return ieee754sp_zero(xs == ys ? 0 : 1); - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - SPDNORMX; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - SPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - SPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - assert(xm & SP_HIDDEN_BIT); - assert(ym & SP_HIDDEN_BIT); - - /* provide rounding space */ - xm <<= 3; - ym <<= 3; - - { - /* now the dirty work */ - - unsigned rm = 0; - int re = xe - ye; - unsigned bm; - - for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) { - if (xm >= ym) { - xm -= ym; - rm |= bm; - if (xm == 0) - break; - } - xm <<= 1; - } - rm <<= 1; - if (xm) - rm |= 1; /* have remainder, set sticky */ - - assert(rm); - - /* normalise rm to rounding precision ? - */ - while ((rm >> (SP_MBITS + 3)) == 0) { - rm <<= 1; - re--; - } - - SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y); - } -} diff -Nru a/arch/mips64/math-emu/sp_fdp.c b/arch/mips64/math-emu/sp_fdp.c --- a/arch/mips64/math-emu/sp_fdp.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,69 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_fdp(ieee754dp x) -{ - COMPXDP; - - CLEARCX; - - EXPLODEXDP; - - switch (xc) { - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: - return ieee754sp_nanxcpt(buildsp(xs, - SP_EMAX + 1 + SP_EBIAS, - (unsigned long) - (xm >> - (DP_MBITS - SP_MBITS))), - "fdp", x); - case IEEE754_CLASS_INF: - return ieee754sp_inf(xs); - case IEEE754_CLASS_ZERO: - return ieee754sp_zero(xs); - case IEEE754_CLASS_DNORM: - /* can't possibly be sp representable */ - SETCX(IEEE754_UNDERFLOW); - return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x); - case IEEE754_CLASS_NORM: - break; - } - - { - unsigned long rm; - - /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift - */ - rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) | - ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0); - - SPNORMRET1(xs, xe, rm, "fdp", x); - } -} diff -Nru a/arch/mips64/math-emu/sp_fint.c b/arch/mips64/math-emu/sp_fint.c --- a/arch/mips64/math-emu/sp_fint.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,78 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_fint(int x) -{ - COMPXSP; - - CLEARCX; - - if (x == 0) - return ieee754sp_zero(0); - if (x == 1 || x == -1) - return ieee754sp_one(x < 0); - if (x == 10 || x == -10) - return ieee754sp_ten(x < 0); - - xs = (x < 0); - if (xs) { - if (x == (1 << 31)) - xm = ((unsigned) 1 << 31); /* max neg can't be safely negated */ - else - xm = -x; - } else { - xm = x; - } - xe = SP_MBITS + 3; - - if (xm >> (SP_MBITS + 1 + 3)) { - /* shunt out overflow bits - */ - while (xm >> (SP_MBITS + 1 + 3)) { - SPXSRSX1(); - } - } else { - /* normalize in grs extended single precision - */ - while ((xm >> (SP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - } - SPNORMRET1(xs, xe, xm, "fint", x); -} - - -ieee754sp ieee754sp_funs(unsigned int u) -{ - if ((int) u < 0) - return ieee754sp_add(ieee754sp_1e31(), - ieee754sp_fint(u & ~(1 << 31))); - return ieee754sp_fint(u); -} diff -Nru a/arch/mips64/math-emu/sp_flong.c b/arch/mips64/math-emu/sp_flong.c --- a/arch/mips64/math-emu/sp_flong.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,77 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_flong(long long x) -{ - COMPXDP; /* <--- need 64-bit mantissa temp */ - - CLEARCX; - - if (x == 0) - return ieee754sp_zero(0); - if (x == 1 || x == -1) - return ieee754sp_one(x < 0); - if (x == 10 || x == -10) - return ieee754sp_ten(x < 0); - - xs = (x < 0); - if (xs) { - if (x == (1ULL << 63)) - xm = (1ULL << 63); /* max neg can't be safely negated */ - else - xm = -x; - } else { - xm = x; - } - xe = SP_MBITS + 3; - - if (xm >> (SP_MBITS + 1 + 3)) { - /* shunt out overflow bits - */ - while (xm >> (SP_MBITS + 1 + 3)) { - SPXSRSX1(); - } - } else { - /* normalize in grs extended single precision */ - while ((xm >> (SP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - } - SPNORMRET1(xs, xe, xm, "sp_flong", x); -} - - -ieee754sp ieee754sp_fulong(unsigned long long u) -{ - if ((long long) u < 0) - return ieee754sp_add(ieee754sp_1e63(), - ieee754sp_flong(u & ~(1ULL << 63))); - return ieee754sp_flong(u); -} diff -Nru a/arch/mips64/math-emu/sp_frexp.c b/arch/mips64/math-emu/sp_frexp.c --- a/arch/mips64/math-emu/sp_frexp.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,53 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -/* close to ieeep754sp_logb -*/ -ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr) -{ - COMPXSP; - CLEARCX; - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_INF: - case IEEE754_CLASS_ZERO: - *eptr = 0; - return x; - case IEEE754_CLASS_DNORM: - SPDNORMX; - break; - case IEEE754_CLASS_NORM: - break; - } - *eptr = xe + 1; - return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT); -} diff -Nru a/arch/mips64/math-emu/sp_logb.c b/arch/mips64/math-emu/sp_logb.c --- a/arch/mips64/math-emu/sp_logb.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,54 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_logb(ieee754sp x) -{ - COMPXSP; - - CLEARCX; - - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - return ieee754sp_nanxcpt(x, "logb", x); - case IEEE754_CLASS_QNAN: - return x; - case IEEE754_CLASS_INF: - return ieee754sp_inf(0); - case IEEE754_CLASS_ZERO: - return ieee754sp_inf(1); - case IEEE754_CLASS_DNORM: - SPDNORMX; - break; - case IEEE754_CLASS_NORM: - break; - } - return ieee754sp_fint(xe); -} diff -Nru a/arch/mips64/math-emu/sp_modf.c b/arch/mips64/math-emu/sp_modf.c --- a/arch/mips64/math-emu/sp_modf.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,80 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -/* modf function is always exact for a finite number -*/ -ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip) -{ - COMPXSP; - - CLEARCX; - - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_INF: - case IEEE754_CLASS_ZERO: - *ip = x; - return x; - case IEEE754_CLASS_DNORM: - /* far to small */ - *ip = ieee754sp_zero(xs); - return x; - case IEEE754_CLASS_NORM: - break; - } - if (xe < 0) { - *ip = ieee754sp_zero(xs); - return x; - } - if (xe >= SP_MBITS) { - *ip = x; - return ieee754sp_zero(xs); - } - /* generate ipart mantissa by clearing bottom bits - */ - *ip = buildsp(xs, xe + SP_EBIAS, - ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) & - ~SP_HIDDEN_BIT); - - /* generate fpart mantissa by clearing top bits - * and normalizing (must be able to normalize) - */ - xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe)); - if (xm == 0) - return ieee754sp_zero(xs); - - while ((xm >> SP_MBITS) == 0) { - xm <<= 1; - xe--; - } - return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); -} diff -Nru a/arch/mips64/math-emu/sp_mul.c b/arch/mips64/math-emu/sp_mul.c --- a/arch/mips64/math-emu/sp_mul.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,174 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) -{ - COMPXSP; - COMPYSP; - - CLEARCX; - - EXPLODEXSP; - EXPLODEYSP; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "mul", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "mul", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Infinity handling */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - SETCX(IEEE754_INVALID_OPERATION); - return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - return ieee754sp_inf(xs ^ ys); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return ieee754sp_zero(xs ^ ys); - - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - SPDNORMX; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - SPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - SPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - /* rm = xm * ym, re = xe+ye basicly */ - assert(xm & SP_HIDDEN_BIT); - assert(ym & SP_HIDDEN_BIT); - - { - int re = xe + ye; - int rs = xs ^ ys; - unsigned rm; - - /* shunt to top of word */ - xm <<= 32 - (SP_MBITS + 1); - ym <<= 32 - (SP_MBITS + 1); - - /* multiply 32bits xm,ym to give high 32bits rm with stickness - */ - { - unsigned short lxm = xm & 0xffff; - unsigned short hxm = xm >> 16; - unsigned short lym = ym & 0xffff; - unsigned short hym = ym >> 16; - unsigned lrm; - unsigned hrm; - - lrm = lxm * lym; /* 16 * 16 => 32 */ - hrm = hxm * hym; /* 16 * 16 => 32 */ - - { - unsigned t = lxm * hym; /* 16 * 16 => 32 */ - { - unsigned at = lrm + (t << 16); - hrm += at < lrm; - lrm = at; - } - hrm = hrm + (t >> 16); - } - - { - unsigned t = hxm * lym; /* 16 * 16 => 32 */ - { - unsigned at = lrm + (t << 16); - hrm += at < lrm; - lrm = at; - } - hrm = hrm + (t >> 16); - } - rm = hrm | (lrm != 0); - } - - /* - * sticky shift down to normal rounding precision - */ - if ((int) rm < 0) { - rm = (rm >> (32 - (SP_MBITS + 1 + 3))) | - ((rm << (SP_MBITS + 1 + 3)) != 0); - re++; - } else { - rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) | - ((rm << (SP_MBITS + 1 + 3 + 1)) != 0); - } - assert(rm & (SP_HIDDEN_BIT << 3)); - - SPNORMRET2(rs, re, rm, "mul", x, y); - } -} diff -Nru a/arch/mips64/math-emu/sp_scalb.c b/arch/mips64/math-emu/sp_scalb.c --- a/arch/mips64/math-emu/sp_scalb.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_scalb(ieee754sp x, int n) -{ - COMPXSP; - - CLEARCX; - - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - return ieee754sp_nanxcpt(x, "scalb", x, n); - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_INF: - case IEEE754_CLASS_ZERO: - return x; - case IEEE754_CLASS_DNORM: - SPDNORMX; - break; - case IEEE754_CLASS_NORM: - break; - } - SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n); -} - - -ieee754sp ieee754sp_ldexp(ieee754sp x, int n) -{ - return ieee754sp_scalb(x, n); -} diff -Nru a/arch/mips64/math-emu/sp_simple.c b/arch/mips64/math-emu/sp_simple.c --- a/arch/mips64/math-emu/sp_simple.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,66 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -int ieee754sp_finite(ieee754sp x) -{ - return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; -} - -ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y) -{ - CLEARCX; - SPSIGN(x) = SPSIGN(y); - return x; -} - - -ieee754sp ieee754sp_neg(ieee754sp x) -{ - CLEARCX; - - if (ieee754sp_isnan(x)) /* but not infinity */ - return ieee754sp_nanxcpt(x, "neg", x); - - /* quick fix up */ - SPSIGN(x) ^= 1; - return x; -} - - -ieee754sp ieee754sp_abs(ieee754sp x) -{ - CLEARCX; - - if (ieee754sp_isnan(x)) /* but not infinity */ - return ieee754sp_nanxcpt(x, "abs", x); - - /* quick fix up */ - SPSIGN(x) = 0; - return x; -} diff -Nru a/arch/mips64/math-emu/sp_sqrt.c b/arch/mips64/math-emu/sp_sqrt.c --- a/arch/mips64/math-emu/sp_sqrt.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,115 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision square root - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -static const struct ieee754sp_konst knan = { - 0, SP_EBIAS + SP_EMAX + 1, 0 -}; - -#define nan ((ieee754sp)knan) - -ieee754sp ieee754sp_sqrt(ieee754sp x) -{ - int sign = (int) 0x80000000; - int ix, s, q, m, t, i; - unsigned int r; - COMPXDP; - - /* take care of Inf and NaN */ - - EXPLODEXDP; - - /* x == INF or NAN? */ - switch (xc) { - case IEEE754_CLASS_QNAN: - case IEEE754_CLASS_SNAN: - /* sqrt(Nan) = Nan */ - return ieee754sp_nanxcpt(x, "sqrt"); - case IEEE754_CLASS_ZERO: - /* sqrt(0) = 0 */ - return x; - case IEEE754_CLASS_INF: - if (xs) - /* sqrt(-Inf) = Nan */ - return ieee754sp_nanxcpt(nan, "sqrt"); - /* sqrt(+Inf) = Inf */ - return x; - case IEEE754_CLASS_DNORM: - case IEEE754_CLASS_NORM: - if (xs) - /* sqrt(-x) = Nan */ - return ieee754sp_nanxcpt(nan, "sqrt"); - break; - } - - ix = x.bits; - - /* normalize x */ - m = (ix >> 23); - if (m == 0) { /* subnormal x */ - for (i = 0; (ix & 0x00800000) == 0; i++) - ix <<= 1; - m -= i - 1; - } - m -= 127; /* unbias exponent */ - ix = (ix & 0x007fffff) | 0x00800000; - if (m & 1) /* odd m, double x to make it even */ - ix += ix; - m >>= 1; /* m = [m/2] */ - - /* generate sqrt(x) bit by bit */ - ix += ix; - q = s = 0; /* q = sqrt(x) */ - r = 0x01000000; /* r = moving bit from right to left */ - - while (r != 0) { - t = s + r; - if (t <= ix) { - s = t + r; - ix -= t; - q += r; - } - ix += ix; - r >>= 1; - } - - if (ix != 0) { - switch (ieee754_csr.rm) { - case IEEE754_RP: - q += 2; - break; - case IEEE754_RN: - q += (q & 1); - break; - } - } - ix = (q >> 1) + 0x3f000000; - ix += (m << 23); - x.bits = ix; - return x; -} diff -Nru a/arch/mips64/math-emu/sp_sub.c b/arch/mips64/math-emu/sp_sub.c --- a/arch/mips64/math-emu/sp_sub.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,187 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) -{ - COMPXSP; - COMPYSP; - - CLEARCX; - - EXPLODEXSP; - EXPLODEYSP; - - switch (CLPAIR(xc, yc)) { - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(ieee754sp_bestnan(x, y), "sub", x, - y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): - return ieee754sp_nanxcpt(y, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): - return ieee754sp_nanxcpt(x, "sub", x, y); - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): - return ieee754sp_bestnan(x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): - return y; - - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): - return x; - - - /* Inifity handling - */ - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - if (xs != ys) - return x; - SETCX(IEEE754_INVALID_OPERATION); - return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y); - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): - return ieee754sp_inf(ys ^ 1); - - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): - return x; - - /* Zero handling - */ - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): - if (xs != ys) - return x; - else - return ieee754sp_zero(ieee754_csr.rm == - IEEE754_RD); - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): - return x; - - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): - /* quick fix up */ - DPSIGN(y) ^= 1; - return y; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): - SPDNORMX; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): - SPDNORMY; - break; - - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): - SPDNORMX; - break; - - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): - break; - } - /* flip sign of y and handle as add */ - ys ^= 1; - - assert(xm & SP_HIDDEN_BIT); - assert(ym & SP_HIDDEN_BIT); - - - /* provide guard,round and stick bit space */ - xm <<= 3; - ym <<= 3; - - if (xe > ye) { - /* have to shift y fraction right to align - */ - int s = xe - ye; - SPXSRSYn(s); - } else if (ye > xe) { - /* have to shift x fraction right to align - */ - int s = ye - xe; - SPXSRSXn(s); - } - assert(xe == ye); - assert(xe <= SP_EMAX); - - if (xs == ys) { - /* generate 28 bit result of adding two 27 bit numbers - */ - xm = xm + ym; - xe = xe; - xs = xs; - - if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */ - SPXSRSX1(); /* shift preserving sticky */ - } - } else { - if (xm >= ym) { - xm = xm - ym; - xe = xe; - xs = xs; - } else { - xm = ym - xm; - xe = xe; - xs = ys; - } - if (xm == 0) - if (ieee754_csr.rm == IEEE754_RD) - return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ - else - return ieee754sp_zero(0); /* other round modes => sign = 1 */ - - /* normalize to rounding precision - */ - while ((xm >> (SP_MBITS + 3)) == 0) { - xm <<= 1; - xe--; - } - } - SPNORMRET2(xs, xe, xm, "sub", x, y); -} diff -Nru a/arch/mips64/math-emu/sp_tint.c b/arch/mips64/math-emu/sp_tint.c --- a/arch/mips64/math-emu/sp_tint.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,88 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include <linux/kernel.h> -#include "ieee754sp.h" - -int ieee754sp_tint(ieee754sp x) -{ - COMPXSP; - - CLEARCX; - - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754si_xcpt(ieee754si_indef(), "fixsp", x); - case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fixsp", x); - case IEEE754_CLASS_ZERO: - return 0; - case IEEE754_CLASS_DNORM: /* much to small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fixsp", x); - case IEEE754_CLASS_NORM: - break; - } - if (xe >= 31) { - SETCX(IEEE754_OVERFLOW); - return ieee754si_xcpt(ieee754si_indef(), "fix", x); - } - if (xe < 0) { - SETCX(IEEE754_UNDERFLOW); - return ieee754si_xcpt(0, "fix", x); - } - /* oh gawd */ - if (xe > SP_MBITS) { - xm <<= xe - SP_MBITS; - } else if (xe < SP_MBITS) { - /* XXX no rounding - */ - xm >>= SP_MBITS - xe; - } - if (xs) - return -xm; - else - return xm; -} - - -unsigned int ieee754sp_tuns(ieee754sp x) -{ - ieee754sp hb = ieee754sp_1e31(); - - /* what if x < 0 ?? */ - if (ieee754sp_lt(x, hb)) - return (unsigned) ieee754sp_tint(x); - - return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) | - ((unsigned) 1 << 31); -} diff -Nru a/arch/mips64/math-emu/sp_tlong.c b/arch/mips64/math-emu/sp_tlong.c --- a/arch/mips64/math-emu/sp_tlong.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,87 +0,0 @@ -/* IEEE754 floating point arithmetic - * single precision - */ -/* - * MIPS floating point support - * Copyright (C) 1994-2000 Algorithmics Ltd. All rights reserved. - * http://www.algor.co.uk - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - */ - - -#include "ieee754sp.h" - -long long ieee754sp_tlong(ieee754sp x) -{ - COMPXDP; /* <-- need 64-bit mantissa tmp */ - - CLEARCX; - - EXPLODEXSP; - - switch (xc) { - case IEEE754_CLASS_SNAN: - case IEEE754_CLASS_QNAN: - SETCX(IEEE754_INVALID_OPERATION); - return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); - case IEEE754_CLASS_INF: - SETCX(IEEE754_OVERFLOW); - return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); - case IEEE754_CLASS_ZERO: - return 0; - case IEEE754_CLASS_DNORM: /* much to small */ - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "sp_tlong", x); - case IEEE754_CLASS_NORM: - break; - } - if (xe >= 63) { - SETCX(IEEE754_OVERFLOW); - return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); - } - if (xe < 0) { - SETCX(IEEE754_UNDERFLOW); - return ieee754di_xcpt(0, "sp_tlong", x); - } - /* oh gawd */ - if (xe > SP_MBITS) { - xm <<= xe - SP_MBITS; - } else if (xe < SP_MBITS) { - /* XXX no rounding - */ - xm >>= SP_MBITS - xe; - } - if (xs) - return -xm; - else - return xm; -} - - -unsigned long long ieee754sp_tulong(ieee754sp x) -{ - ieee754sp hb = ieee754sp_1e63(); - - /* what if x < 0 ?? */ - if (ieee754sp_lt(x, hb)) - return (unsigned long long) ieee754sp_tlong(x); - - return (unsigned long long) ieee754sp_tlong(ieee754sp_sub(x, hb)) | - (1ULL << 63); -} diff -Nru a/arch/mips64/mips-boards/atlas/Makefile b/arch/mips64/mips-boards/atlas/Makefile --- a/arch/mips64/mips-boards/atlas/Makefile Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,26 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -# -# ######################################################################## -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -# ####################################################################### -# -# Makefile for the MIPS Atlas specific kernel interface routines -# under Linux. -# - -obj-y := atlas_int.o atlas_rtc.o atlas_setup.o diff -Nru a/arch/mips64/mips-boards/atlas/atlas_int.c b/arch/mips64/mips-boards/atlas/atlas_int.c --- a/arch/mips64/mips-boards/atlas/atlas_int.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,255 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Routines for generic manipulation of the interrupts found on the MIPS - * Atlas board. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <linux/seq_file.h> - -#include <asm/irq.h> -#include <asm/mips-boards/atlas.h> -#include <asm/mips-boards/atlasint.h> -#ifdef CONFIG_REMOTE_DEBUG -#include <asm/gdb-stub.h> -#endif - -struct atlas_ictrl_regs *atlas_hw0_icregs - = (struct atlas_ictrl_regs *)ATLAS_ICTRL_REGS_BASE; - -extern asmlinkage void mipsIRQ(void); -extern void do_IRQ(int irq, struct pt_regs *regs); - -unsigned long spurious_count = 0; -irq_desc_t irq_desc[NR_IRQS]; - -#if 0 -#define DEBUG_INT(x...) printk(x) -#else -#define DEBUG_INT(x...) -#endif - -void disable_atlas_irq(unsigned int irq_nr) -{ - atlas_hw0_icregs->intrsten = (1 << irq_nr); -} - -void enable_atlas_irq(unsigned int irq_nr) -{ - atlas_hw0_icregs->intseten = (1 << irq_nr); -} - -static unsigned int startup_atlas_irq(unsigned int irq) -{ - enable_atlas_irq(irq); - return 0; /* never anything pending */ -} - -#define shutdown_atlas_irq disable_atlas_irq - -#define mask_and_ack_atlas_irq disable_atlas_irq - -static void end_atlas_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_atlas_irq(irq); -} - -static struct hw_interrupt_type atlas_irq_type = { - "Atlas", - startup_atlas_irq, - shutdown_atlas_irq, - enable_atlas_irq, - disable_atlas_irq, - mask_and_ack_atlas_irq, - end_atlas_irq, - NULL -}; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - int num = 0; - struct irqaction *action; - unsigned long flags; - - for (i = 0; i < ATLASINT_END; i++, num++) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto unlock; - seq_printf(p, "%2d: %8d %c %s", - num, kstat_cpu(0).irqs[num], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_puts(p, " [hw0]\n"); -unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } - return 0; -} - -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, - const char * devname, - void *dev_id) -{ - struct irqaction *action; - - DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname); - - if (irq >= ATLASINT_END) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if(!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->dev_id = dev_id; - action->next = 0; - irq_desc[irq].action = action; - enable_atlas_irq(irq); - - return 0; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *action; - - if (irq >= ATLASINT_END) { - printk("Trying to free IRQ%d\n",irq); - return; - } - - action = irq_desc[irq].action; - irq_desc[irq].action = NULL; - disable_atlas_irq(irq); - kfree(action); -} - -static inline int ls1bit32(unsigned int x) -{ - int b = 31, s; - - s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s; - s = 8; if (x << 8 == 0) s = 0; b -= s; x <<= s; - s = 4; if (x << 4 == 0) s = 0; b -= s; x <<= s; - s = 2; if (x << 2 == 0) s = 0; b -= s; x <<= s; - s = 1; if (x << 1 == 0) s = 0; b -= s; - - return b; -} - -void atlas_hw0_irqdispatch(struct pt_regs *regs) -{ - struct irqaction *action; - unsigned long int_status; - int irq, cpu = smp_processor_id(); - - int_status = atlas_hw0_icregs->intstatus; - - /* if int_status == 0, then the interrupt has already been cleared */ - if (int_status == 0) - return; - - irq = ls1bit32(int_status); - action = irq_desc[irq].action; - - DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); - - /* if action == NULL, then we don't have a handler for the irq */ - if ( action == NULL ) { - printk("No handler for hw0 irq: %i\n", irq); - spurious_count++; - return; - } - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - action->handler(irq, action->dev_id, regs); - irq_exit(cpu, irq); - - return; -} - -unsigned long probe_irq_on (void) -{ - return 0; -} - - -int probe_irq_off (unsigned long irqs) -{ - return 0; -} - -#ifdef CONFIG_REMOTE_DEBUG -extern void breakpoint(void); -extern int remote_debug; -#endif - -void __init init_IRQ(void) -{ - int i; - - /* - * Mask out all interrupt by writing "1" to all bit position in - * the interrupt reset reg. - */ - atlas_hw0_icregs->intrsten = 0xffffffff; - - /* Now safe to set the exception vector. */ - set_except_vector(0, mipsIRQ); - - for (i = 0; i <= ATLASINT_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].handler = &atlas_irq_type; - spin_lock_init(&irq_desc[i].lock); - } - -#ifdef CONFIG_REMOTE_DEBUG - if (remote_debug) { - set_debug_traps(); - breakpoint(); - } -#endif -} diff -Nru a/arch/mips64/mips-boards/atlas/atlas_rtc.c b/arch/mips64/mips-boards/atlas/atlas_rtc.c --- a/arch/mips64/mips-boards/atlas/atlas_rtc.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * RTC routines for Atlas style attached Dallas chip. - * - */ -#include <asm/mc146818rtc.h> -#include <asm/mips-boards/atlas.h> - - -static unsigned char atlas_rtc_read_data(unsigned long addr) -{ - volatile unsigned int *rtc_adr_reg = (void *)ATLAS_RTC_ADR_REG; - volatile unsigned int *rtc_dat_reg = (void *)ATLAS_RTC_DAT_REG; - - *rtc_adr_reg = addr; - - return *rtc_dat_reg; -} - -static void atlas_rtc_write_data(unsigned char data, unsigned long addr) -{ - volatile unsigned int *rtc_adr_reg = (void *)ATLAS_RTC_ADR_REG; - volatile unsigned int *rtc_dat_reg = (void *)ATLAS_RTC_DAT_REG; - - *rtc_adr_reg = addr; - *rtc_dat_reg = data; -} - -static int atlas_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops atlas_rtc_ops = { - &atlas_rtc_read_data, - &atlas_rtc_write_data, - &atlas_rtc_bcd_mode -}; - diff -Nru a/arch/mips64/mips-boards/atlas/atlas_setup.c b/arch/mips64/mips-boards/atlas/atlas_setup.c --- a/arch/mips64/mips-boards/atlas/atlas_setup.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,123 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Atlas specific setup, including init of the feature struct. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/ioport.h> - -#include <asm/cpu.h> -#include <asm/bootinfo.h> -#include <asm/irq.h> -#include <asm/mips-boards/generic.h> -#include <asm/mips-boards/prom.h> -#include <asm/mips-boards/gt64120.h> -#include <asm/mips-boards/atlasint.h> - -#include <asm/mmu_context.h> - -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -extern void saa9730_kgdb_hook(void); -extern void breakpoint(void); -int remote_debug = 0; -#endif - -extern struct rtc_ops atlas_rtc_ops; - -extern void mips_reboot_setup(void); - -void __init atlas_setup(void) -{ -#ifdef CONFIG_REMOTE_DEBUG - int rs_putDebugChar(char); - char rs_getDebugChar(void); - int saa9730_putDebugChar(char); - char saa9730_getDebugChar(void); - extern int (*putDebugChar)(char); - extern char (*getDebugChar)(void); -#endif - char *argptr; - - current_cpu_data.asid_cache = ASID_FIRST_VERSION; - TLBMISS_HANDLER_SETUP(); - - ioport_resource.end = 0x7fffffff; - -#ifdef CONFIG_SERIAL_CONSOLE - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) { - int i = 0; - char *s = prom_getenv("modetty0"); - while(s[i] >= '0' && s[i] <= '9') - i++; - strcpy(serial_console, "ttyS0,"); - strncpy(serial_console + 6, s, i); - prom_printf("Config serial console: %s\n", serial_console); - console_setup(serial_console, NULL); - } -#endif - -#ifdef CONFIG_REMOTE_DEBUG - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { - int line; - argptr += strlen("kgdb=ttyS"); - if (*argptr != '0' && *argptr != '1') - printk("KGDB: Uknown serial line /dev/ttyS%c, " - "falling back to /dev/ttyS1\n", *argptr); - line = *argptr == '0' ? 0 : 1; - printk("KGDB: Using serial line /dev/ttyS%d for session\n", - line ? 1 : 0); - - if(line == 0) { - rs_kgdb_hook(line); - putDebugChar = rs_putDebugChar; - getDebugChar = rs_getDebugChar; - } else { - saa9730_kgdb_hook(); - putDebugChar = saa9730_putDebugChar; - getDebugChar = saa9730_getDebugChar; - } - - prom_printf("KGDB: Using serial line /dev/ttyS%d for session, " - "please connect your debugger\n", line ? 1 : 0); - - remote_debug = 1; - /* Breakpoints and stuff are in atlas_irq_setup() */ - } -#endif - argptr = prom_getcmdline(); - - if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; - - rtc_ops = &atlas_rtc_ops; -} diff -Nru a/arch/mips64/mips-boards/generic/Makefile b/arch/mips64/mips-boards/generic/Makefile --- a/arch/mips64/mips-boards/generic/Makefile Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,29 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -# -# ######################################################################## -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -# ####################################################################### -# -# Makefile for the MIPS boards generic routines under Linux. -# - -obj-y := mipsIRQ.o pci.o reset.o display.o init.o \ - memory.o printf.o cmdline.o time.o -obj-$(CONFIG_REMOTE_DEBUG) += gdb_hook.o - -EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips64/mips-boards/generic/cmdline.c b/arch/mips64/mips-boards/generic/cmdline.c --- a/arch/mips64/mips-boards/generic/cmdline.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,71 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Kernel command line creation using the prom monitor (YAMON) argc/argv. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/string.h> - -#include <asm/bootinfo.h> - -/*#define DEBUG_CMDLINE*/ - -extern int prom_argc; -extern int *_prom_argv; - -/* - * A 32-bit PROM pass arguments and environment as 32-bit pointer. - * This macro take care of sign extension. - */ -#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)])) - -char arcs_cmdline[CL_SIZE]; - -char * __init prom_getcmdline(void) -{ - return &(arcs_cmdline[0]); -} - - -void __init prom_init_cmdline(void) -{ - char *cp; - int actr; - - actr = 1; /* Always ignore argv[0] */ - - cp = &(arcs_cmdline[0]); - while(actr < prom_argc) { - strcpy(cp, prom_argv(actr)); - cp += strlen(prom_argv(actr)); - *cp++ = ' '; - actr++; - } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ - --cp; - *cp = '\0'; - -#ifdef DEBUG_CMDLINE - prom_printf("prom_init_cmdline: %s\n", &(arcs_cmdline[0])); -#endif -} diff -Nru a/arch/mips64/mips-boards/generic/display.c b/arch/mips64/mips-boards/generic/display.c --- a/arch/mips64/mips-boards/generic/display.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,47 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Display routines for display messages in MIPS boards ascii display. - * - */ - -#include <asm/mips-boards/generic.h> - - -void mips_display_message(const char *str) -{ - volatile unsigned int *display = (void *)ASCII_DISPLAY_POS_BASE; - int i; - - for (i = 0; i <= 14; i=i+2) { - if (*str) - display[i] = *str++; - else - display[i] = ' '; - } -} - -void mips_display_word(unsigned int num) -{ - volatile unsigned int *display = (void *)ASCII_DISPLAY_WORD_BASE; - - *display = num; -} diff -Nru a/arch/mips64/mips-boards/generic/gdb_hook.c b/arch/mips64/mips-boards/generic/gdb_hook.c --- a/arch/mips64/mips-boards/generic/gdb_hook.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,202 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * This is the interface to the remote debugger stub. - * - */ - -#include <linux/serialP.h> -#include <linux/serial_reg.h> - -#include <asm/serial.h> -#include <asm/io.h> - -static struct serial_state rs_table[RS_TABLE_SIZE] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -static struct async_struct kdb_port_info = {0}; - - -static __inline__ unsigned int serial_in(struct async_struct *info, int offset) -{ - return inb(info->port + offset); -} - -static __inline__ void serial_out(struct async_struct *info, int offset, - int value) -{ - outb(value, info->port+offset); -} - -void rs_kgdb_hook(int tty_no) { - int t; - struct serial_state *ser = &rs_table[tty_no]; - - kdb_port_info.state = ser; - kdb_port_info.magic = SERIAL_MAGIC; - kdb_port_info.port = ser->port; - kdb_port_info.flags = ser->flags; - - /* - * Clear all interrupts - */ - serial_in(&kdb_port_info, UART_LSR); - serial_in(&kdb_port_info, UART_RX); - serial_in(&kdb_port_info, UART_IIR); - serial_in(&kdb_port_info, UART_MSR); - - /* - * Now, initialize the UART - */ - serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */ - if (kdb_port_info.flags & ASYNC_FOURPORT) { - kdb_port_info.MCR = UART_MCR_DTR | UART_MCR_RTS; - t = UART_MCR_DTR | UART_MCR_OUT1; - } else { - kdb_port_info.MCR - = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2; - t = UART_MCR_DTR | UART_MCR_RTS; - } - - kdb_port_info.MCR = t; /* no interrupts, please */ - serial_out(&kdb_port_info, UART_MCR, kdb_port_info.MCR); - - /* - * and set the speed of the serial port - * (currently hardwired to 9600 8N1 - */ - - /* baud rate is fixed to 9600 (is this sufficient?)*/ - t = kdb_port_info.state->baud_base / 9600; - /* set DLAB */ - serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8 | UART_LCR_DLAB); - serial_out(&kdb_port_info, UART_DLL, t & 0xff);/* LS of divisor */ - serial_out(&kdb_port_info, UART_DLM, t >> 8); /* MS of divisor */ - /* reset DLAB */ - serial_out(&kdb_port_info, UART_LCR, UART_LCR_WLEN8); -} - -int rs_putDebugChar(char c) -{ - - if (!kdb_port_info.state) { /* need to init device first */ - return 0; - } - - while ((serial_in(&kdb_port_info, UART_LSR) & UART_LSR_THRE) == 0) - ; - - serial_out(&kdb_port_info, UART_TX, c); - - return 1; -} - -char rs_getDebugChar(void) -{ - if (!kdb_port_info.state) { /* need to init device first */ - return 0; - } - - while (!(serial_in(&kdb_port_info, UART_LSR) & 1)) - ; - - return(serial_in(&kdb_port_info, UART_RX)); -} - - -#ifdef CONFIG_MIPS_ATLAS - -#include <asm/mips-boards/atlas.h> -#include <asm/mips-boards/saa9730_uart.h> - -#define INB(a) inb((unsigned long)a) -#define OUTB(x,a) outb(x,(unsigned long)a) - -/* - * This is the interface to the remote debugger stub - * if the Philips part is used for the debug port, - * called from the platform setup code. - * - * PCI init will not have been done yet, we make a - * universal assumption about the way the bootloader (YAMON) - * have located and set up the chip. - */ -static t_uart_saa9730_regmap *kgdb_uart = (void *)(ATLAS_SAA9730_REG + SAA9730_UART_REGS_ADDR); - -static int saa9730_kgdb_active = 0; - -void saa9730_kgdb_hook(void) -{ - volatile unsigned char t; - - /* - * Clear all interrupts - */ - t = INB(&kgdb_uart->Lsr); - t += INB(&kgdb_uart->Msr); - t += INB(&kgdb_uart->Thr_Rbr); - t += INB(&kgdb_uart->Iir_Fcr); - - /* - * Now, initialize the UART - */ - /* 8 data bits, one stop bit, no parity */ - OUTB(SAA9730_LCR_DATA8, &kgdb_uart->Lcr); - - /* baud rate is fixed to 9600 (is this sufficient?)*/ - OUTB(0, &kgdb_uart->BaudDivMsb); /* HACK - Assumes standard crystal */ - OUTB(23, &kgdb_uart->BaudDivLsb); /* HACK - known for MIPS Atlas */ - - /* Set RTS/DTR active */ - OUTB(SAA9730_MCR_DTR | SAA9730_MCR_RTS, &kgdb_uart->Mcr); - saa9730_kgdb_active = 1; -} - -int saa9730_putDebugChar(char c) -{ - - if (!saa9730_kgdb_active) { /* need to init device first */ - return 0; - } - - while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_THRE)) - ; - OUTB(c, &kgdb_uart->Thr_Rbr); - - return 1; -} - -char saa9730_getDebugChar(void) -{ - char c; - - if (!saa9730_kgdb_active) { /* need to init device first */ - return 0; - } - while (!(INB(&kgdb_uart->Lsr) & SAA9730_LSR_DR)) - ; - - c = INB(&kgdb_uart->Thr_Rbr); - return(c); -} - -#endif diff -Nru a/arch/mips64/mips-boards/generic/init.c b/arch/mips64/mips-boards/generic/init.c --- a/arch/mips64/mips-boards/generic/init.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,152 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * PROM library initialisation code. - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/kernel.h> - -#include <asm/io.h> -#include <asm/mips-boards/prom.h> -#include <asm/mips-boards/generic.h> -#include <asm/mips-boards/gt64120.h> -#include <asm/mips-boards/malta.h> - -/* Environment variable */ -typedef struct -{ - char *name; - char *val; -}t_env_var; - -int prom_argc; -int *_prom_argv, *_prom_envp; - -/* - * A 32-bit PROM pass arguments and environment as 32-bit pointer. - * This macro take care of sign extension. - */ -#define prom_envp(index) ((char *)(((int *)(int)_prom_envp)[(index)])) - -int init_debug = 0; - -char *prom_getenv(char *envname) -{ - /* - * Return a pointer to the given environment variable. - * We're using 64-bit pointers, but all pointers in the PROM - * structures are only 32-bit, so we need some workarounds. - */ - int i, index=0; - - i = strlen(envname); - - while(prom_envp(index)) { - if(strncmp(envname, prom_envp(index), i) == 0) { - return(prom_envp(index+1)); - } - index += 2; - } - - return(NULL); -} - -static inline unsigned char str2hexnum(unsigned char c) -{ - if(c >= '0' && c <= '9') - return c - '0'; - if(c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0; /* foo */ -} - -static inline void str2eaddr(unsigned char *ea, unsigned char *str) -{ - int i; - - for(i = 0; i < 6; i++) { - unsigned char num; - - if((*str == '.') || (*str == ':')) - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; - } -} - -int get_ethernet_addr(char *ethernet_addr) -{ - char *ethaddr_str; - - ethaddr_str = prom_getenv("ethaddr"); - if (!ethaddr_str) { - printk("ethaddr not set in boot prom\n"); - return -1; - } - str2eaddr(ethernet_addr, ethaddr_str); - - if (init_debug > 1) - { - int i; - printk("get_ethernet_addr: "); - for (i=0; i<5; i++) - printk("%02x:", (unsigned char)*(ethernet_addr+i)); - printk("%02x\n", *(ethernet_addr+i)); - } - - return 0; -} - -int __init prom_init(int argc, char **argv, char **envp) -{ - prom_argc = argc; - _prom_argv = (int *)argv; - _prom_envp = (int *)envp; - - mips_display_message("LINUX"); - - /* - * Setup the North bridge to do Master byte-lane swapping when - * running in bigendian. - */ -#if defined(__MIPSEL__) - GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT | - GT_PCI0_CMD_SBYTESWAP_BIT); -#else - GT_WRITE(GT_PCI0_CMD_OFS, 0); -#endif - -#if defined(CONFIG_MIPS_MALTA) - mips_io_port_base = MALTA_PORT_BASE; -#else - mips_io_port_base = KSEG1; -#endif - - setup_prom_printf(0); - prom_printf("\nLINUX started...\n"); - prom_init_cmdline(); - prom_meminit(); - - return 0; -} diff -Nru a/arch/mips64/mips-boards/generic/memory.c b/arch/mips64/mips-boards/generic/memory.c --- a/arch/mips64/mips-boards/generic/memory.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,263 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * PROM library functions for acquiring/using memory descriptors given to - * us from the YAMON. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/mm.h> -#include <linux/bootmem.h> - -#include <asm/bootinfo.h> -#include <asm/page.h> - -#include <asm/mips-boards/prom.h> - -/*#define DEBUG*/ - -enum yamon_memtypes { - yamon_dontuse, - yamon_prom, - yamon_free, -}; -struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; - -#define MEMTYPE_DONTUSE 0 -#define MEMTYPE_PROM 1 -#define MEMTYPE_FREE 2 - -#ifdef DEBUG -static char *mtypes[3] = { - "Dont use memory", - "YAMON PROM memory", - "Free memmory", -}; -#endif - -/* References to section boundaries */ -extern char _end; - -#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) - -struct prom_pmemblock * __init prom_getmdesc(void) -{ - char *memsize_str; - unsigned int memsize; - - memsize_str = prom_getenv("memsize"); - if (!memsize_str) { - prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); - memsize = 0x02000000; - } else { -#ifdef DEBUG - prom_printf("prom_memsize = %s\n", memsize_str); -#endif - memsize = simple_strtol(memsize_str, NULL, 0); - } - - memset(mdesc, 0, sizeof(mdesc)); - - mdesc[0].type = yamon_dontuse; - mdesc[0].base = 0x00000000; - mdesc[0].size = 0x00001000; - - mdesc[1].type = yamon_prom; - mdesc[1].base = 0x00001000; - mdesc[1].size = 0x000ef000; - -#if (CONFIG_MIPS_MALTA) - /* - * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the - * south bridge and PCI access always forwarded to the ISA Bus and - * BIOSCS# is always generated. - * This mean that this area can't be used as DMA memory for PCI - * devices. - */ - mdesc[2].type = yamon_dontuse; - mdesc[2].base = 0x000f0000; - mdesc[2].size = 0x00010000; -#else - mdesc[2].type = yamon_prom; - mdesc[2].base = 0x000f0000; - mdesc[2].size = 0x00010000; -#endif - - mdesc[3].type = yamon_dontuse; - mdesc[3].base = 0x00100000; - mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base; - - mdesc[4].type = yamon_free; - mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); - mdesc[4].size = memsize - mdesc[4].base; - - return &mdesc[0]; -} - -int __init page_is_ram(unsigned long pagenr) -{ - if ((pagenr << PAGE_SHIFT) < mdesc[4].base + mdesc[4].size) - return 1; - - return 0; -} - -static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS]; - -static int __init prom_memtype_classify (unsigned int type) -{ - switch (type) { - case yamon_free: - return MEMTYPE_FREE; - case yamon_prom: - return MEMTYPE_PROM; - default: - return MEMTYPE_DONTUSE; - } -} - -static inline unsigned long find_max_low_pfn(void) -{ - struct prom_pmemblock *p, *highest; - unsigned long pfn; - - p = pblocks; - highest = 0; - while (p->size != 0) { - if (!highest || p->base > highest->base) - highest = p; - p++; - } - - pfn = (highest->base + highest->size) >> PAGE_SHIFT; -#ifdef DEBUG - prom_printf("find_max_low_pfn: 0x%lx pfns.\n", pfn); -#endif - return pfn; -} - -static inline struct prom_pmemblock *find_largest_memblock(void) -{ - struct prom_pmemblock *p, *largest; - - p = pblocks; - largest = 0; - while (p->size != 0) { - if (!largest || p->size > largest->size) - largest = p; - p++; - } - - return largest; -} - -void __init prom_meminit(void) -{ - struct prom_pmemblock *largest, *p; - unsigned long bootmap_size; - int totram; - int i = 0; - -#ifdef DEBUG - prom_printf("YAMON MEMORY DESCRIPTOR dump:\n"); - p = prom_getmdesc(); - while (p->size) { - prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", - i, p, p->base, p->size, mtypes[p->type]); - p++; - i++; - } -#endif - totram = 0; - i = 0; - p = prom_getmdesc(); - - while (p->size) { - pblocks[i].type = prom_memtype_classify (p->type); - pblocks[i].base = p->base; - pblocks[i].size = p->size; - switch (pblocks[i].type) { - case MEMTYPE_FREE: - totram += pblocks[i].size; -#ifdef DEBUG - prom_printf("free_chunk[%d]: base=%08lx size=%d\n", - i, pblocks[i].base, pblocks[i].size); -#endif - i++; - break; - case MEMTYPE_PROM: -#ifdef DEBUG - prom_printf("prom_chunk[%d]: base=%08lx size=%d\n", - i, pblocks[i].base, pblocks[i].size); -#endif - i++; - break; - default: - break; - } - p++; - } - pblocks[i].base = 0xdeadbeef; - pblocks[i].size = 0; /* indicates last elem. of array */ - - max_low_pfn = find_max_low_pfn(); - largest = find_largest_memblock(); - bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn); - - for (i = 0; pblocks[i].size; i++) - if (pblocks[i].type == MEMTYPE_FREE) - free_bootmem(pblocks[i].base, pblocks[i].size); - - /* This test is simpleminded. It will fail if the bootmem bitmap - falls into multiple adjacent PROM memory areas. */ - if (bootmap_size > largest->size) { - prom_printf("CRITIAL: overwriting PROM data.\n"); - BUG(); - } - - /* Reserve the memory bootmap itself */ - reserve_bootmem(largest->base, bootmap_size); - printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n", - totram, (totram/1024), (totram/1024/1024)); -} - -void prom_free_prom_memory (void) -{ - struct prom_pmemblock *p; - unsigned long freed = 0; - unsigned long addr; - - for (p = pblocks; p->size != 0; p++) { - if (p->type != MEMTYPE_PROM) - continue; - - addr = p->base; - while (addr < p->base + p->size) { - ClearPageReserved(virt_to_page(__va(addr))); - set_page_count(virt_to_page(__va(addr)), 1); - free_page(__va(addr)); - addr += PAGE_SIZE; - freed += PAGE_SIZE; - } - } - printk("Freeing prom memory: %ldkb freed\n", freed >> 10); -} diff -Nru a/arch/mips64/mips-boards/generic/mipsIRQ.S b/arch/mips64/mips-boards/generic/mipsIRQ.S --- a/arch/mips64/mips-boards/generic/mipsIRQ.S Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,122 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Interrupt exception dispatch code. - * - */ -#include <linux/config.h> - -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -/* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the MIPS board look basically (barring software - * IRQs which we don't use at all and all external interrupt sources are - * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Combined hardware interrupt (hw0) - * 3 Hardware (ignored) - * 4 Hardware (ignored) - * 5 Hardware (ignored) - * 6 Hardware (ignored) - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Lowest ---- Combined hardware interrupt - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(mipsIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - - mfc0 s0, CP0_CAUSE # get irq mask - - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP7 - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt - - /* Wheee, a timer interrupt. */ - move a0, sp - jal mips_timer_interrupt - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, combined hardware level zero interrupt. */ -#if defined(CONFIG_MIPS_ATLAS) - jal atlas_hw0_irqdispatch -#elif defined(CONFIG_MIPS_MALTA) - jal malta_hw0_irqdispatch -#else -#error "MIPS board not supported\n" -#endif - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - /* - * Here by mistake? This is possible, what can happen is that by the - * time we take the exception the IRQ pin goes low, so just leave if - * this is the case. - */ - move a1,s0 - PRINT("Got interrupt: c0_cause = %08x\n") - mfc0 a1, CP0_EPC - PRINT("c0_epc = %08x\n") - - j ret_from_irq - nop - END(mipsIRQ) diff -Nru a/arch/mips64/mips-boards/generic/pci.c b/arch/mips64/mips-boards/generic/pci.c --- a/arch/mips64/mips-boards/generic/pci.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,326 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * MIPS boards specific PCI support. - * - */ -#include <linux/config.h> - -#ifdef CONFIG_PCI - -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/kernel.h> -#include <linux/init.h> - -#include <asm/mips-boards/generic.h> -#include <asm/mips-boards/gt64120.h> -#ifdef CONFIG_MIPS_MALTA -#include <asm/mips-boards/malta.h> -#endif - -#define PCI_ACCESS_READ 0 -#define PCI_ACCESS_WRITE 1 - -static int -mips_pcibios_config_access(unsigned char access_type, struct pci_dev *dev, - unsigned char where, u32 *data) -{ - unsigned char bus = dev->bus->number; - unsigned char dev_fn = dev->devfn; - u32 intr; - - if ((bus == 0) && (dev_fn >= PCI_DEVFN(31,0))) - return -1; /* Because of a bug in the galileo (for slot 31). */ - - /* Clear cause register bits */ - GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT)); - - /* Setup address */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | - (dev_fn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | - ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | - GT_PCI0_CFGADDR_CONFIGEN_BIT); - - if (access_type == PCI_ACCESS_WRITE) { - if (bus == 0 && dev_fn == 0) { - /* - * Galileo is acting differently than other devices. - */ - GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_WRITE(GT_PCI0_CFGDATA_OFS, *data); - } - } else { - if (bus == 0 && dev_fn == 0) { - /* - * Galileo is acting differently than other devices. - */ - GT_READ(GT_PCI0_CFGDATA_OFS, *data); - } else { - GT_PCI_READ(GT_PCI0_CFGDATA_OFS, *data); - } - } - - /* Check for master or target abort */ - GT_READ(GT_INTRCAUSE_OFS, intr); - - if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) - { - /* Error occurred */ - - /* Clear bits */ - GT_WRITE( GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | - GT_INTRCAUSE_TARABORT0_BIT) ); - - return -1; - } - - return 0; -} - - -/* - * We can't address 8 and 16 bit words directly. Instead we have to - * read/write a 32bit word and mask/modify the data we actually want. - */ -static int -mips_pcibios_read_config_byte (struct pci_dev *dev, int where, u8 *val) -{ - u32 data = 0; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = (data >> ((where & 3) << 3)) & 0xff; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_read_config_word (struct pci_dev *dev, int where, u16 *val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = (data >> ((where & 3) << 3)) & 0xffff; - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_read_config_dword (struct pci_dev *dev, int where, u32 *val) -{ - u32 data = 0; - - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - *val = data; - - return PCIBIOS_SUCCESSFUL; -} - - -static int -mips_pcibios_write_config_byte (struct pci_dev *dev, int where, u8 val) -{ - u32 data = 0; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_write_config_word (struct pci_dev *dev, int where, u16 val) -{ - u32 data = 0; - - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_READ, dev, where, &data)) - return -1; - - data = (data & ~(0xffff << ((where & 3) << 3))) | - (val << ((where & 3) << 3)); - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &data)) - return -1; - - - return PCIBIOS_SUCCESSFUL; -} - -static int -mips_pcibios_write_config_dword(struct pci_dev *dev, int where, u32 val) -{ - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - - if (mips_pcibios_config_access(PCI_ACCESS_WRITE, dev, where, &val)) - return -1; - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops mips_pci_ops = { - mips_pcibios_read_config_byte, - mips_pcibios_read_config_word, - mips_pcibios_read_config_dword, - mips_pcibios_write_config_byte, - mips_pcibios_write_config_word, - mips_pcibios_write_config_dword -}; - -void __init pcibios_init(void) -{ -#ifdef CONFIG_MIPS_MALTA - struct pci_dev *pdev = NULL; - unsigned char reg_val; -#endif - - printk("PCI: Probing PCI hardware on host bus 0.\n"); - pci_scan_bus(0, &mips_pci_ops, NULL); - - /* - * Due to a bug in the Galileo system controller, we need to setup - * the PCI BAR for the Galileo internal registers. - * This should be done in the bios/bootprom and will be fixed in - * a later revision of YAMON (the MIPS boards boot prom). - */ - GT_WRITE(GT_PCI0_CFGADDR_OFS, - (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */ - (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 device */ - (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0 */ - ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4 */ - GT_PCI0_CFGADDR_CONFIGEN_BIT ); - - /* Perform the write */ - GT_WRITE( GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE)); - -#ifdef CONFIG_MIPS_MALTA - while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { - if ((pdev->vendor == PCI_VENDOR_ID_INTEL) - && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB) - && (PCI_SLOT(pdev->devfn) == 0x0a)) { - /* - * IDE Decode enable. - */ - pci_read_config_byte(pdev, 0x41, ®_val); - pci_write_config_byte(pdev, 0x41, reg_val | 0x80); - pci_read_config_byte(pdev, 0x43, ®_val); - pci_write_config_byte(pdev, 0x43, reg_val | 0x80); - } - - if ((pdev->vendor == PCI_VENDOR_ID_INTEL) - && (pdev->device == PCI_DEVICE_ID_INTEL_82371AB_0) - && (PCI_SLOT(pdev->devfn) == 0x0a)) { - /* - * Set top of main memory accessible by ISA or DMA - * devices to 16 Mb. - */ - pci_read_config_byte(pdev, 0x69, ®_val); - pci_write_config_byte(pdev, 0x69, reg_val | 0xf0); - } - } - - /* - * Activate Floppy Controller in the SMSC FDC37M817 Super I/O - * Controller. - * This should be done in the bios/bootprom and will be fixed in - * a later revision of YAMON (the MIPS boards boot prom). - */ - /* Entering config state. */ - SMSC_WRITE(SMSC_CONFIG_ENTER, SMSC_CONFIG_REG); - - /* Activate floppy controller. */ - SMSC_WRITE(SMSC_CONFIG_DEVNUM, SMSC_CONFIG_REG); - SMSC_WRITE(SMSC_CONFIG_DEVNUM_FLOPPY, SMSC_DATA_REG); - SMSC_WRITE(SMSC_CONFIG_ACTIVATE, SMSC_CONFIG_REG); - SMSC_WRITE(SMSC_CONFIG_ACTIVATE_ENABLE, SMSC_DATA_REG); - - /* Exit config state. */ - SMSC_WRITE(SMSC_CONFIG_EXIT, SMSC_CONFIG_REG); -#endif -} - -int __init -pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void __init -pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - -struct pci_fixup pcibios_fixups[] = { - { 0 } -}; - -#warning pcibios_update_resource() is now a generic implementation - please check - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 1; -} - -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void __init pcibios_fixup_bus(struct pci_bus *b) -{ - pci_read_bridge_bases(b); -} - -#endif /* CONFIG_PCI */ diff -Nru a/arch/mips64/mips-boards/generic/printf.c b/arch/mips64/mips-boards/generic/printf.c --- a/arch/mips64/mips-boards/generic/printf.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,140 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Putting things on the screen/serial line using YAMONs facilities. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/serialP.h> -#include <linux/serial_reg.h> -#include <asm/system.h> -#include <asm/io.h> -#include <asm/serial.h> - - -#ifdef CONFIG_MIPS_ATLAS -/* - * Atlas registers are memory mapped on 64-bit aligned boundaries and - * only word access are allowed. - * When reading the UART 8 bit registers only the LSB are valid. - */ -unsigned int atlas_serial_in(struct async_struct *info, int offset) -{ - return (*(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) & 0xff); -} - -void atlas_serial_out(struct async_struct *info, int offset, int value) -{ - *(volatile unsigned int *)(info->port + mips_io_port_base + offset*8) = value; -} - -#define serial_in atlas_serial_in -#define serial_out atlas_serial_out - -#else - -static unsigned int serial_in(struct async_struct *info, int offset) -{ - return inb(info->port + offset); -} - -static void serial_out(struct async_struct *info, int offset, - int value) -{ - outb(value, info->port + offset); -} -#endif - -static struct serial_state rs_table[] = { - SERIAL_PORT_DFNS /* Defined in serial.h */ -}; - -/* - * Hooks to fake "prom" console I/O before devices - * are fully initialized. - */ -static struct async_struct prom_port_info = {0}; - -void __init setup_prom_printf(int tty_no) { - struct serial_state *ser = &rs_table[tty_no]; - - prom_port_info.state = ser; - prom_port_info.magic = SERIAL_MAGIC; - prom_port_info.port = ser->port; - prom_port_info.flags = ser->flags; - - /* No setup of UART - assume YAMON left in sane state */ -} - -int putPromChar(char c) -{ - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while ((serial_in(&prom_port_info, UART_LSR) & UART_LSR_THRE) == 0) - ; - - serial_out(&prom_port_info, UART_TX, c); - - return 1; -} - -char getPromChar(void) -{ - if (!prom_port_info.state) { /* need to init device first */ - return 0; - } - - while (!(serial_in(&prom_port_info, UART_LSR) & 1)) - ; - - return(serial_in(&prom_port_info, UART_RX)); -} - -static char buf[1024]; - -void __init prom_printf(char *fmt, ...) -{ - va_list args; - int l; - char *p, *buf_end; - long flags; - - int putPromChar(char); - - /* Low level, brute force, not SMP safe... */ - save_and_cli(flags); - va_start(args, fmt); - l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ - va_end(args); - - buf_end = buf + l; - - for (p = buf; p < buf_end; p++) { - /* Crude cr/nl handling is better than none */ - if(*p == '\n')putPromChar('\r'); - putPromChar(*p); - } - restore_flags(flags); -} diff -Nru a/arch/mips64/mips-boards/generic/reset.c b/arch/mips64/mips-boards/generic/reset.c --- a/arch/mips64/mips-boards/generic/reset.c Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,61 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Reset the MIPS boards. - * - */ -#include <linux/config.h> - -#include <asm/mips-boards/generic.h> -#if defined(CONFIG_MIPS_ATLAS) -#include <asm/mips-boards/atlas.h> -#endif - -void machine_restart(char *command) __attribute__((noreturn)); -void machine_halt(void) __attribute__((noreturn)); -#if defined(CONFIG_MIPS_ATLAS) -void machine_power_off(void) __attribute__((noreturn)); -#endif - -void machine_restart(char *command) -{ - volatile unsigned int *softres_reg = (void *)SOFTRES_REG; - - *softres_reg = GORESET; -} - -void machine_halt(void) -{ - volatile unsigned int *softres_reg = (void *)SOFTRES_REG; - - *softres_reg = GORESET; -} - -void machine_power_off(void) -{ -#if defined(CONFIG_MIPS_ATLAS) - volatile unsigned int *psustby_reg = (void *)ATLAS_PSUSTBY_REG; - - *psustby_reg = ATLAS_GOSTBY; -#else - machine_halt(); -#endif -} diff -Nru a/arch/mips64/mips-boards/generic/time.c b/arch/mips64/mips-boards/generic/time.c --- a/arch/mips64/mips-boards/generic/time.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,409 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Setting up the clock on the MIPS boards. - * - */ - -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/sched.h> -#include <linux/time.h> -#include <linux/spinlock.h> - -#include <asm/mipsregs.h> -#include <asm/ptrace.h> - -#include <linux/mc146818rtc.h> -#include <linux/timex.h> - -#include <asm/mips-boards/generic.h> -#include <asm/mips-boards/prom.h> - -extern volatile unsigned long wall_jiffies; -static long last_rtc_update = 0; -unsigned long missed_heart_beats = 0; - -static unsigned long r4k_offset; /* Amount to increment compare reg each time */ -static unsigned long r4k_cur; /* What counter should be at next timer irq */ - -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) - -#if defined(CONFIG_MIPS_ATLAS) -static char display_string[] = " LINUX ON ATLAS "; -#endif -#if defined(CONFIG_MIPS_MALTA) -static char display_string[] = " LINUX ON MALTA "; -#endif -static unsigned int display_count = 0; -#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) - -static unsigned int timer_tick_count=0; - - -static inline void ack_r4ktimer(unsigned long newval) -{ - write_32bit_cp0_register(CP0_COMPARE, newval); -} - - -/* - * In order to set the CMOS clock precisely, set_rtc_mmss has to be - * called 500 ms after the second nowtime has started, because when - * nowtime is written into the registers of the CMOS clock, it will - * jump to the next second precisely 500 ms later. Check the Motorola - * MC146818A or Dallas DS12887 data sheet for details. - * - * BUG: This routine does not handle hour overflow properly; it just - * sets the minutes. Usually you won't notice until after reboot! - */ -static int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - -/* - * There are a lot of conceptually broken versions of the MIPS timer interrupt - * handler floating around. This one is rather different, but the algorithm - * is provably more robust. - */ -void mips_timer_interrupt(struct pt_regs *regs) -{ - unsigned long flags; - unsigned long seq; - int irq = 7; - - if (r4k_offset == 0) - goto null; - - do { - kstat_cpu(0).irqs[irq]++; - do_timer(regs); - - /* Historical comment/code: - * RTC time of day s updated approx. every 11 - * minutes. Because of how the numbers work out - * we need to make absolutely sure we do this update - * within 500ms before the * next second starts, - * thus the following code. - */ - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - if ((time_status & STA_UNSYNC) == 0 - && xtime.tv_sec > last_rtc_update + 660 - && xtime.tv_usec >= 500000 - (tick >> 1) - && xtime.tv_usec <= 500000 + (tick >> 1)) - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - - if ((timer_tick_count++ % HZ) == 0) { - mips_display_message(&display_string[display_count++]); - if (display_count == MAX_DISPLAY_COUNT) - display_count = 0; - } - - r4k_cur += r4k_offset; - ack_r4ktimer(r4k_cur); - - } while (((unsigned int)read_32bit_cp0_register(CP0_COUNT) - - (unsigned int)r4k_cur) < 0x7fffffff); - - return; - -null: - ack_r4ktimer(0); -} - -/* - * Figure out the r4k offset, the amount to increment the compare - * register for each time tick. - * Use the RTC to calculate offset. - */ -static unsigned long __init cal_r4koff(void) -{ - unsigned long count; - unsigned int flags; - - local_irq_save(flags); - - /* Start counter exactly on falling edge of update flag */ - while (CMOS_READ(RTC_REG_A) & RTC_UIP); - while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - - /* Start r4k counter. */ - write_32bit_cp0_register(CP0_COUNT, 0); - - /* Read counter exactly on falling edge of update flag */ - while (CMOS_READ(RTC_REG_A) & RTC_UIP); - while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - - count = read_32bit_cp0_register(CP0_COUNT); - - /* restore interrupts */ - local_irq_restore(flags); - - return (count / HZ); -} - -static unsigned long __init get_mips_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - unsigned char save_control; - - save_control = CMOS_READ(RTC_CONTROL); - - /* Freeze it. */ - CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL); - - /* Read regs. */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - - if (!(save_control & RTC_24H)) - { - if ((hour & 0xf) == 0xc) - hour &= 0x80; - if (hour & 0x80) - hour = (hour & 0xf) + 12; - } - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - - /* Unfreeze clock. */ - CMOS_WRITE(save_control, RTC_CONTROL); - - if ((year += 1900) < 1970) - year += 100; - - return mktime(year, mon, day, hour, min, sec); -} - -void __init time_init(void) -{ - unsigned int est_freq, flags; - - /* Set Data mode - binary. */ - CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL); - - printk("calculating r4koff... "); - r4k_offset = cal_r4koff(); - printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - - est_freq = 2*r4k_offset*HZ; - est_freq += 5000; /* round */ - est_freq -= est_freq%10000; - printk("CPU frequency %d.%02d MHz\n", est_freq/1000000, - (est_freq%1000000)*100/1000000); - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ST0_IM, ALLINTS); - - /* Read time from the RTC chipset. */ - write_seqlock_irqsave (&xtime_lock, flags); - xtime.tv_sec = get_mips_time(); - xtime.tv_usec = 0; - write_sequnlock_irqrestore(&xtime_lock, flags); -} - -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff) - -/* Cycle counter value at the previous timer interrupt.. */ - -static unsigned int timerhi = 0, timerlo = 0; - -/* - * FIXME: Does playing with the RP bit in c0_status interfere with this code? - */ -static unsigned long do_fast_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies=0; - unsigned long quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient=0; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n\t" - ".set\tmips3\n\t" - "lwu\t%0,%2\n\t" - "dsll32\t$1,%1,0\n\t" - "or\t$1,$1,%0\n\t" - "ddivu\t$0,$1,%3\n\t" - "mflo\t$1\n\t" - "dsll32\t%0,%4,0\n\t" - "nop\n\t" - "ddivu\t$0,%0,$1\n\t" - "mflo\t%0\n\t" - ".set\tmips0\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=&r" (quotient) - :"r" (timerhi), - "m" (timerlo), - "r" (tmp), - "r" (USECS_PER_JIFFY) - :"$1"); - cached_quotient = quotient; - } - - /* Get last timer tick in absolute kernel time */ - count = read_32bit_cp0_register(CP0_COUNT); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - :"=r" (res) - :"r" (count), - "r" (quotient)); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - *tv = xtime; - tv->tv_usec += do_fast_gettimeoffset(); - - /* - * xtime is atomically updated in timer_bh. - * jiffies - wall_jiffies - * is nonzero if the timer bottom half hasnt executed yet. - */ - if (jiffies - wall_jiffies) - tv->tv_usec += USECS_PER_JIFFY; - - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } -} - -void do_settimeofday(struct timeval *tv) -{ - write_seqlock_irq (&xtime_lock); - - /* This is revolting. We need to set the xtime.tv_usec correctly. - * However, the value in this location is is value at the last tick. - * Discover what correction gettimeofday would have done, and then - * undo it! - */ - tv->tv_usec -= do_fast_gettimeoffset(); - - if (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; - - write_sequnlock_irq (&xtime_lock); -} diff -Nru a/arch/mips64/mips-boards/malta/Makefile b/arch/mips64/mips-boards/malta/Makefile --- a/arch/mips64/mips-boards/malta/Makefile Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,26 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -# -# ######################################################################## -# -# This program is free software; you can distribute it and/or modify it -# under the terms of the GNU General Public License (Version 2) as -# published by the Free Software Foundation. -# -# This program is distributed in the hope it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -# -# ####################################################################### -# -# Makefile for the MIPS Malta specific kernel interface routines -# under Linux. -# - -obj-y := malta_int.o malta_rtc.o malta_setup.o diff -Nru a/arch/mips64/mips-boards/malta/malta_int.c b/arch/mips64/mips-boards/malta/malta_int.c --- a/arch/mips64/mips-boards/malta/malta_int.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,391 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Routines for generic manipulation of the interrupts found on the MIPS - * Malta board. - * The interrupt controller is located in the South Bridge a PIIX4 device - * with two internal 82C95 interrupt controllers. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <linux/random.h> -#include <linux/seq_file.h> - -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/mips-boards/malta.h> -#include <asm/mips-boards/maltaint.h> -#include <asm/mips-boards/piix4.h> -#include <asm/mips-boards/gt64120.h> -#include <asm/mips-boards/generic.h> - -extern asmlinkage void mipsIRQ(void); - -unsigned int local_bh_count[NR_CPUS]; -unsigned int local_irq_count[NR_CPUS]; -unsigned long spurious_count = 0; - -static struct irqaction *hw0_irq_action[MALTAINT_END] = { - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL -}; - -static struct irqaction r4ktimer_action = { - NULL, 0, 0, "R4000 timer/counter", NULL, NULL, -}; - -static struct irqaction *irq_action[8] = { - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, &r4ktimer_action -}; - -#if 0 -#define DEBUG_INT(x...) printk(x) -#else -#define DEBUG_INT(x...) -#endif - -/* - * This contains the interrupt mask for both 82C59 interrupt controllers. - */ -static unsigned int cached_int_mask = 0xffff; - - -void disable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - if(irq_nr >= MALTAINT_END) { - printk("whee, invalid irq_nr %d\n", irq_nr); - panic("IRQ, you lose..."); - } - - save_and_cli(flags); - cached_int_mask |= (1 << irq_nr); - if (irq_nr & 8) { - outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1); - } else { - outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1); - } - restore_flags(flags); -} - - -void enable_irq(unsigned int irq_nr) -{ - unsigned long flags; - - if(irq_nr >= MALTAINT_END) { - printk("whee, invalid irq_nr %d\n", irq_nr); - panic("IRQ, you lose..."); - } - - save_and_cli(flags); - cached_int_mask &= ~(1 << irq_nr); - if (irq_nr & 8) { - outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1); - - /* Enable irq 2 (cascade interrupt). */ - cached_int_mask &= ~(1 << 2); - outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1); - } else { - outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1); - } - restore_flags(flags); -} - - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - int num = 0; - struct irqaction *action; - unsigned long flags; - - for (i = 0; i < 8; i++, num++) { - local_irq_save(flags); - action = irq_action[i]; - if (!action) - goto skip_1; - seq_printf(p, "%2d: %8d %c %s", - num, kstat_cpu(0).irqs[num], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_puts(p, " [on-chip]\n"); -skip_1: - local_irq_restore(flags); - } - for (i = 0; i < MALTAINT_END; i++, num++) { - local_irq_save(flags); - action = hw0_irq_action[i]; - if (!action) - goto skip_2; - seq_printf(p, "%2d: %8d %c %s", - num, kstat_cpu(0).irqs[num], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_puts(p, " [hw0]\n"); -skip_2: - local_irq_restore(flags); - } - return 0; -} - -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, - const char * devname, - void *dev_id) -{ - struct irqaction *action; - int retval; - - DEBUG_INT("request_irq: irq=%d, devname = %s\n", irq, devname); - - if (irq >= MALTAINT_END) - return -EINVAL; - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if(!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->dev_id = dev_id; - action->next = 0; - - retval = setup_irq(irq, action); - if (retval) - kfree(action); - - return retval; -} - - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction *action, **p; - - if (irq >= MALTAINT_END) { - printk("Trying to free IRQ%d\n",irq); - return; - } - - for (p = &hw0_irq_action[irq]; (action = *p) != NULL; - p = &action->next) - { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - *p = action->next; - kfree(action); - if (!hw0_irq_action[irq]) - disable_irq(irq); - return; - } - printk("Trying to free IRQ%d\n",irq); -} - -void __init init_IRQ(void) -{ - irq_setup(); -} - -static int setup_irq(unsigned int irq, struct irqaction * new) -{ - int shared = 0; - struct irqaction *old, **p; - - p = &hw0_irq_action[irq]; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) - return -EBUSY; - - /* Can't share interrupts unless both are same type */ - if ((old->flags ^ new->flags) & SA_INTERRUPT) - return -EBUSY; - - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - *p = new; - if (!shared) - enable_irq(irq); - - return 0; -} - -static inline int get_int(int *irq) -{ - /* - * Determine highest priority pending interrupt by performing - * a PCI Interrupt Acknowledge cycle. - */ - GT_READ(GT_PCI0_IACK_OFS, *irq); - *irq &= 0xFF; - - /* - * IRQ7 is used to detect spurious interrupts. - * The interrupt acknowledge cycle returns IRQ7, if no - * interrupts is requested. - * We can differentiate between this situation and a - * "Normal" IRQ7 by reading the ISR. - */ - if (*irq == 7) - { - outb(PIIX4_OCW3_SEL | PIIX4_OCW3_ISR, PIIX4_ICTLR1_OCW3); - if (!(inb(PIIX4_ICTLR1_OCW3) & (1 << 7))) - return -1; /* Spurious interrupt. */ - } - - return 0; -} - -static inline void ack_int(int irq) -{ - if (irq & 8) { - /* Specific EOI to cascade */ - outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI | PIIX4_OCW2_ILS_2, - PIIX4_ICTLR1_OCW2); - - /* Non specific EOI to cascade */ - outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR2_OCW2); - } else { - /* Non specific EOI to cascade */ - outb(PIIX4_OCW2_SEL | PIIX4_OCW2_NSEOI, PIIX4_ICTLR1_OCW2); - } -} - -void malta_hw0_irqdispatch(struct pt_regs *regs) -{ - struct irqaction *action; - int irq=0, cpu = smp_processor_id(); - - DEBUG_INT("malta_hw0_irqdispatch\n"); - - if (get_int(&irq)) - return; /* interrupt has already been cleared */ - - disable_irq(irq); - ack_int(irq); - - DEBUG_INT("malta_hw0_irqdispatch: irq=%d\n", irq); - action = hw0_irq_action[irq]; - - /* - * if action == NULL, then we don't have a handler - * for the irq - */ - if ( action == NULL ) - return; - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq + 8]++; - do { - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - - enable_irq(irq); - irq_exit(cpu, irq); -} - - -unsigned long probe_irq_on (void) -{ - unsigned int i, irqs = 0; - unsigned long delay; - - /* first, enable any unassigned irqs */ - for (i = MALTAINT_END-1; i > 0; i--) { - if (!hw0_irq_action[i]) { - enable_irq(i); - irqs |= (1 << i); - } - } - - /* wait for spurious interrupts to mask themselves out again */ - for (delay = jiffies + HZ/10; time_before(jiffies, delay); ) - /* about 100ms delay */; - - /* now filter out any obviously spurious interrupts */ - return irqs & ~cached_int_mask; -} - - -int probe_irq_off (unsigned long irqs) -{ - unsigned int i; - - irqs &= cached_int_mask; - if (!irqs) - return 0; - i = ffz(~irqs); - if (irqs != (irqs & (1 << i))) - i = -i; - - return i; -} - - -void __init maltaint_init(void) -{ - /* - * Mask out all interrupt by writing "1" to all bit position in - * the IMR register. - */ - outb(cached_int_mask & 0xff, PIIX4_ICTLR1_OCW1); - outb((cached_int_mask >> 8) & 0xff, PIIX4_ICTLR2_OCW1); - - /* Now safe to set the exception vector. */ - set_except_vector(0, mipsIRQ); -} diff -Nru a/arch/mips64/mips-boards/malta/malta_rtc.c b/arch/mips64/mips-boards/malta/malta_rtc.c --- a/arch/mips64/mips-boards/malta/malta_rtc.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,50 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * RTC routines for Malta style attached PIIX4 device, which contains a - * Motorola MC146818A-compatible Real Time Clock. - * - */ -#include <asm/mc146818rtc.h> -#include <asm/mips-boards/malta.h> - -static unsigned char malta_rtc_read_data(unsigned long addr) -{ - outb(addr, MALTA_RTC_ADR_REG); - return inb(MALTA_RTC_DAT_REG); -} - -static void malta_rtc_write_data(unsigned char data, unsigned long addr) -{ - outb(addr, MALTA_RTC_ADR_REG); - outb(data, MALTA_RTC_DAT_REG); -} - -static int malta_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops malta_rtc_ops = { - &malta_rtc_read_data, - &malta_rtc_write_data, - &malta_rtc_bcd_mode -}; diff -Nru a/arch/mips64/mips-boards/malta/malta_setup.c b/arch/mips64/mips-boards/malta/malta_setup.c --- a/arch/mips64/mips-boards/malta/malta_setup.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,170 +0,0 @@ -/* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Malta specific setup, including init of the feature struct. - * - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#ifdef CONFIG_BLK_DEV_IDE -#include <linux/ide.h> -#endif - -#include <asm/cpu.h> -#include <asm/bootinfo.h> -#include <asm/irq.h> -#include <asm/mips-boards/generic.h> -#include <asm/mips-boards/prom.h> -#include <asm/mips-boards/gt64120.h> -#include <asm/mips-boards/malta.h> -#include <asm/mips-boards/maltaint.h> -#ifdef CONFIG_BLK_DEV_FD -#include <asm/floppy.h> -#endif -#include <asm/dma.h> -#include <asm/mmu_context.h> - -#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_PROM_CONSOLE) -extern void console_setup(char *, int *); -char serial_console[20]; -#endif - -#ifdef CONFIG_REMOTE_DEBUG -extern void set_debug_traps(void); -extern void rs_kgdb_hook(int); -extern void breakpoint(void); -static int remote_debug = 0; -#endif - -#ifdef CONFIG_BLK_DEV_IDE -extern struct ide_ops std_ide_ops; -#endif -#ifdef CONFIG_BLK_DEV_FD -extern struct fd_ops std_fd_ops; -#endif -extern struct rtc_ops malta_rtc_ops; - -extern void mips_reboot_setup(void); - -struct resource standard_io_resources[] = { - { "dma1", 0x00, 0x1f, IORESOURCE_BUSY }, - { "pic1", 0x20, 0x3f, IORESOURCE_BUSY }, - { "timer", 0x40, 0x5f, IORESOURCE_BUSY }, - { "dma page reg", 0x80, 0x8f, IORESOURCE_BUSY }, - { "pic2", 0xa0, 0xbf, IORESOURCE_BUSY }, - { "dma2", 0xc0, 0xdf, IORESOURCE_BUSY }, -}; - -#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) - -static void __init malta_irq_setup(void) -{ - maltaint_init(); - -#ifdef CONFIG_REMOTE_DEBUG - if (remote_debug) { - set_debug_traps(); - breakpoint(); - } -#endif -} - - -void __init malta_setup(void) -{ -#ifdef CONFIG_REMOTE_DEBUG - int rs_putDebugChar(char); - char rs_getDebugChar(void); - extern int (*putDebugChar)(char); - extern char (*getDebugChar)(void); -#endif - char *argptr; - int i; - - current_cpu_data.asid_cache = ASID_FIRST_VERSION; - TLBMISS_HANDLER_SETUP(); - - irq_setup = malta_irq_setup; - - /* Request I/O space for devices used on the Malta board. */ - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, standard_io_resources+i); - - /* - * Enable DMA channel 4 (cascade channel) in the PIIX4 south bridge. - */ - enable_dma(4); - -#ifdef CONFIG_SERIAL_CONSOLE - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) - { - int i=0; - char *s = prom_getenv("modetty0"); - while(s[i] >= '0' && s[i] <= '9') - i++; - strcpy(serial_console, "ttyS0,"); - strncpy(serial_console + 6, s, i); - prom_printf("Config serial console: %s\n", serial_console); - console_setup(serial_console, NULL); - } -#endif - -#ifdef CONFIG_REMOTE_DEBUG - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "kgdb=ttyS")) != NULL) { - int line; - argptr += strlen("kgdb=ttyS"); - if (*argptr != '0' && *argptr != '1') - printk("KGDB: Uknown serial line /dev/ttyS%c, " - "falling back to /dev/ttyS1\n", *argptr); - line = *argptr == '0' ? 0 : 1; - printk("KGDB: Using serial line /dev/ttyS%d for session\n", - line ? 1 : 0); - - rs_kgdb_hook(line); - putDebugChar = rs_putDebugChar; - getDebugChar = rs_getDebugChar; - - prom_printf("KGDB: Using serial line /dev/ttyS%d for session, " - "please connect your debugger\n", line ? 1 : 0); - - remote_debug = 1; - /* Breakpoints and stuff are in malta_irq_setup() */ - } -#endif - - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "nofpu")) != NULL) - mips_cpu.options &= ~MIPS_CPU_FPU; - - rtc_ops = &malta_rtc_ops; -#ifdef CONFIG_BLK_DEV_IDE - ide_ops = &std_ide_ops; -#endif -#ifdef CONFIG_BLK_DEV_FD - fd_ops = &std_fd_ops; -#endif -} diff -Nru a/arch/mips64/mm/Makefile b/arch/mips64/mm/Makefile --- a/arch/mips64/mm/Makefile Fri Jun 27 14:19:30 2003 +++ b/arch/mips64/mm/Makefile Fri Jun 27 14:19:30 2003 @@ -2,11 +2,31 @@ # Makefile for the Linux/MIPS-specific parts of the memory manager. # -obj-y := extable.o init.o fault.o loadmmu.o +obj-y := cache.o extable.o init.o fault.o loadmmu.o \ + pgtable.o tlbex-r4k.o -obj-$(CONFIG_CPU_R4300) += r4xx0.o -obj-$(CONFIG_CPU_R4X00) += r4xx0.o -obj-$(CONFIG_CPU_R5000) += r4xx0.o -obj-$(CONFIG_CPU_NEVADA) += r4xx0.o -obj-$(CONFIG_CPU_R10000) += andes.o -obj-$(CONFIG_SGI_IP22) += umap.o +obj-$(CONFIG_CPU_R4300) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R4X00) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R5000) += c-r4k.o pg-r4k.o tlb-r4k.o sc-r5k.o \ + tlb-glue-r4k.o +obj-$(CONFIG_CPU_NEVADA) += c-r4k.o pg-r4k.o tlb-r4k.o sc-r5k.o \ + tlb-glue-r4k.o +obj-$(CONFIG_CPU_R5432) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_RM7000) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_R10000) += c-r4k.o pg-r4k.o tlb-andes.o tlb-glue-r4k.o +obj-$(CONFIG_CPU_SB1) += c-sb1.o pg-sb1.o tlb-sb1.o tlb-glue-sb1.o \ + cex-sb1.o cerr-sb1.o +obj-$(CONFIG_CPU_MIPS64) += c-r4k.o pg-r4k.o tlb-r4k.o tlb-glue-r4k.o + +# +# Debug TLB exception handler, currently unused +# +#obj-y += tlb-dbg-r4k.o + +obj-$(CONFIG_CPU_RM7000) += sc-rm7k.o +obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o +obj-$(CONFIG_SGI_IP22) += sc-ip22.o + +AFLAGS_tlb-glue-r4k.o := -P + +EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips64/mm/andes.c b/arch/mips64/mm/andes.c --- a/arch/mips64/mm/andes.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,391 +0,0 @@ -/* - * 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) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silicon Graphics, Inc. - * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/r10kcache.h> -#include <asm/system.h> -#include <asm/sgialib.h> -#include <asm/mmu_context.h> - -static int scache_lsz64; - -/* - * This version has been tuned on an Origin. For other machines the arguments - * of the pref instructin may have to be tuned differently. - */ -static void andes_clear_page(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tpref 7,512(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), "I" (PAGE_SIZE) - :"$1", "memory"); -} - -/* R10000 has no Create_Dirty type cacheops. */ -static void andes_copy_page(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tpref\t0,2*128(%1)\n\t" - "pref\t1,2*128(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), - "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), "I" (PAGE_SIZE)); -} - -/* Cache operations. These are only used with the virtual memory system, - not for non-coherent I/O so it's ok to ignore the secondary caches. */ -static void -andes_flush_cache_l1(void) -{ - blast_dcache32(); blast_icache64(); -} - -/* - * This is only used during initialization time. vmalloc() also calls - * this, but that will be changed pretty soon. - */ -static void -andes_flush_cache_l2(void) -{ - switch (sc_lsize()) { - case 64: - blast_scache64(); - break; - case 128: - blast_scache128(); - break; - default: - printk("Unknown L2 line size\n"); - while(1); - } -} - -void -andes_flush_icache_page(unsigned long page) -{ - if (scache_lsz64) - blast_scache64_page(page); - else - blast_scache128_page(page); -} - -static void -andes_flush_cache_sigtramp(unsigned long addr) -{ - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -#define NTLB_ENTRIES 64 -#define NTLB_ENTRIES_HALF 32 - -static inline void -andes_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - unsigned long entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = get_entryhi() & 0xff; - set_entryhi(CKSEG0); - set_entrylo0(0); - set_entrylo1(0); - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < NTLB_ENTRIES) { - set_index(entry); - tlb_write_indexed(); - entry++; - } - set_entryhi(old_ctx); - local_irq_restore(flags); -} - -static void andes_flush_tlb_mm(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - local_irq_save(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - local_irq_restore(flags); - } -} - -static void -andes_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - continue; - tlb_write_indexed(); - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & - 0xff); - } - local_irq_restore(flags); - } -} - -static void -andes_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - tlb_probe(); - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - tlb_write_indexed(); - - finish: - set_entryhi(oldpid); - local_irq_restore(flags); - } -} - -/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual - address that already exists will overwrite the old entry and not result - in TLB malfunction or TLB shutdown. */ -static void andes_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - local_irq_save(flags); - pid = get_entryhi() & 0xff; - - if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) || - (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d " - "tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & 0xff), pid); - } - - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - set_entryhi(pid); - local_irq_restore(flags); -} - -static void andes_show_regs(struct pt_regs *regs) -{ - printk("Cpu %d\n", smp_processor_id()); - /* Saved main processor registers. */ - printk("$0 : %016lx %016lx %016lx %016lx\n", - 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); - printk("$4 : %016lx %016lx %016lx %016lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - printk("$8 : %016lx %016lx %016lx %016lx\n", - regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); - printk("$12 : %016lx %016lx %016lx %016lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); - printk("$16 : %016lx %016lx %016lx %016lx\n", - regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); - printk("$20 : %016lx %016lx %016lx %016lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); - printk("$24 : %016lx %016lx\n", - regs->regs[24], regs->regs[25]); - printk("$28 : %016lx %016lx %016lx %016lx\n", - regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); - printk("Hi : %016lx\n", regs->hi); - printk("Lo : %016lx\n", regs->lo); - - /* Saved cp0 registers. */ - printk("epc : %016lx %s\nbadvaddr: %016lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_badvaddr); - printk("Status : %08x\nCause : %08x\n", - (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); -} - -void __init ld_mmu_andes(void) -{ - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - - printk("Primary instruction cache %dkb, linesize %d bytes\n", - icache_size >> 10, ic_lsize); - printk("Primary data cache %dkb, linesize %d bytes\n", - dcache_size >> 10, dc_lsize); - printk("Secondary cache sized at %ldK, linesize %ld\n", - scache_size() >> 10, sc_lsize()); - - _clear_page = andes_clear_page; - _copy_page = andes_copy_page; - - _flush_cache_l1 = andes_flush_cache_l1; - _flush_cache_l2 = andes_flush_cache_l2; - _flush_cache_sigtramp = andes_flush_cache_sigtramp; - - _flush_tlb_all = andes_flush_tlb_all; - _flush_tlb_mm = andes_flush_tlb_mm; - _flush_tlb_range = andes_flush_tlb_range; - _flush_tlb_page = andes_flush_tlb_page; - - switch (sc_lsize()) { - case 64: - scache_lsz64 = 1; - break; - case 128: - scache_lsz64 = 0; - break; - default: - printk("Unknown L2 line size\n"); - while(1); - } - - update_mmu_cache = andes_update_mmu_cache; - - _show_regs = andes_show_regs; - - flush_cache_l1(); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - - /* From this point on the ARC firmware is dead. */ - _flush_tlb_all(); - - /* Did I tell you that ARC SUCKS? */ -} diff -Nru a/arch/mips64/mm/c-r4k.c b/arch/mips64/mm/c-r4k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/c-r4k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1161 @@ +/* + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/bitops.h> + +#include <asm/bcache.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/mmu_context.h> +#include <asm/war.h> + +/* Primary cache parameters. */ +static unsigned long icache_size, dcache_size, scache_size; +unsigned long icache_way_size, dcache_way_size, scache_way_size; +static unsigned long scache_size; + +#include <asm/cacheops.h> +#include <asm/r4kcache.h> + +extern void andes_clear_page(void * page); +extern void r4k_clear_page32_d16(void * page); +extern void r4k_clear_page32_d32(void * page); +extern void r4k_clear_page_d16(void * page); +extern void r4k_clear_page_d32(void * page); +extern void r4k_clear_page_r4600_v1(void * page); +extern void r4k_clear_page_r4600_v2(void * page); +extern void r4k_clear_page_s16(void * page); +extern void r4k_clear_page_s32(void * page); +extern void r4k_clear_page_s64(void * page); +extern void r4k_clear_page_s128(void * page); +extern void andes_copy_page(void * to, void * from); +extern void r4k_copy_page_d16(void * to, void * from); +extern void r4k_copy_page_d32(void * to, void * from); +extern void r4k_copy_page_r4600_v1(void * to, void * from); +extern void r4k_copy_page_r4600_v2(void * to, void * from); +extern void r4k_copy_page_s16(void * to, void * from); +extern void r4k_copy_page_s32(void * to, void * from); +extern void r4k_copy_page_s64(void * to, void * from); +extern void r4k_copy_page_s128(void * to, void * from); + +/* + * Dummy cache handling routines for machines without boardcaches + */ +static void no_sc_noop(void) {} + +static struct bcache_ops no_sc_ops = { + .bc_enable = (void *)no_sc_noop, + .bc_disable = (void *)no_sc_noop, + .bc_wback_inv = (void *)no_sc_noop, + .bc_inv = (void *)no_sc_noop +}; + +struct bcache_ops *bcops = &no_sc_ops; + +#define R4600_HIT_CACHEOP_WAR_IMPL \ +do { \ + if (R4600_V2_HIT_CACHEOP_WAR && \ + (read_c0_prid() & 0xfff0) == 0x2020) { /* R4600 V2.0 */\ + *(volatile unsigned long *)KSEG1; \ + } \ + if (R4600_V1_HIT_CACHEOP_WAR) \ + __asm__ __volatile__("nop;nop;nop;nop"); \ +} while (0) + +static void r4k_blast_dcache_page(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page(addr); + return; + +dc_32: + R4600_HIT_CACHEOP_WAR_IMPL; + blast_dcache32_page(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache_page_indexed(unsigned long addr) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16_page_indexed(addr); + return; + +dc_32: + blast_dcache32_page_indexed(addr); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_dcache(void) +{ + static void *l = &&init; + unsigned long dc_lsize; + + goto *l; + +dc_16: + blast_dcache16(); + return; + +dc_32: + blast_dcache32(); + return; + +init: + dc_lsize = current_cpu_data.dcache.linesz; + + if (dc_lsize == 16) + l = &&dc_16; + else if (dc_lsize == 32) + l = &&dc_32; + goto *l; +} + +static void r4k_blast_icache_page(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page(addr); + return; + +ic_32: + blast_icache32_page(addr); + return; + +ic_64: + blast_icache64_page(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache_page_indexed(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16_page_indexed(addr); + return; + +ic_32: + blast_icache32_page_indexed(addr); + return; + +ic_64: + blast_icache64_page_indexed(addr); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_icache(void) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + static void *l = &&init; + + goto *l; + +ic_16: + blast_icache16(); + return; + +ic_32: + blast_icache32(); + return; + +ic_64: + blast_icache64(); + return; + +init: + if (ic_lsize == 16) + l = &&ic_16; + else if (ic_lsize == 32) + l = &&ic_32; + else if (ic_lsize == 64) + l = &&ic_64; + goto *l; +} + +static void r4k_blast_scache_page(unsigned long addr) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16_page(addr); + return; + +sc_32: + blast_scache32_page(addr); + return; + +sc_64: + blast_scache64_page(addr); + return; + +sc_128: + blast_scache128_page(addr); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_blast_scache(void) +{ + unsigned long sc_lsize = current_cpu_data.scache.linesz; + static void *l = &&init; + + goto *l; + +sc_16: + blast_scache16(); + return; + +sc_32: + blast_scache32(); + return; + +sc_64: + blast_scache64(); + return; + +sc_128: + blast_scache128(); + return; + +init: + if (sc_lsize == 16) + l = &&sc_16; + else if (sc_lsize == 32) + l = &&sc_32; + else if (sc_lsize == 64) + l = &&sc_64; + else if (sc_lsize == 128) + l = &&sc_128; + goto *l; +} + +static void r4k_flush_cache_all(void) +{ + if (!cpu_has_dc_aliases) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); +} + +static void r4k___flush_cache_all(void) +{ + r4k_blast_dcache(); + r4k_blast_icache(); + + switch (current_cpu_data.cputype) { + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400SC: + case CPU_R4400MC: + case CPU_R10000: + case CPU_R12000: + r4k_blast_scache(); + } +} + +static void r4k_flush_cache_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) { + r4k_blast_dcache(); + if (vma->vm_flags & VM_EXEC) + r4k_blast_icache(); + } +} + +static void r4k_flush_cache_mm(struct mm_struct *mm) +{ + if (!cpu_has_dc_aliases) + return; + + if (!cpu_context(smp_processor_id(), mm)) + return; + + r4k_blast_dcache(); + r4k_blast_icache(); + + /* + * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we + * only flush the primary caches but R10000 and R12000 behave sane ... + */ + if (current_cpu_data.cputype == CPU_R4000SC || + current_cpu_data.cputype == CPU_R4000MC || + current_cpu_data.cputype == CPU_R4400SC || + current_cpu_data.cputype == CPU_R4400MC) + r4k_blast_scache(); +} + +static void r4k_flush_cache_page(struct vm_area_struct *vma, + unsigned long page) +{ + int exec = vma->vm_flags & VM_EXEC; + struct mm_struct *mm = vma->vm_mm; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + page &= PAGE_MASK; + pgdp = pgd_offset(mm, page); + pmdp = pmd_offset(pgdp, page); + ptep = pte_offset(pmdp, page); + + /* + * If the page isn't marked valid, the page cannot possibly be + * in the cache. + */ + if (!(pte_val(*ptep) & _PAGE_PRESENT)) + return; + + /* + * Doing flushes for another ASID than the current one is + * too difficult since stupid R4k caches do a TLB translation + * for every cache flush operation. So we do indexed flushes + * in that case, which doesn't overly flush the cache too much. + */ + if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) { + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page(page); + if (exec) + r4k_blast_icache_page(page); + + return; + } + + /* + * Do indexed flush, too much work to get the (possible) TLB refills + * to work correctly. + */ + page = (KSEG0 + (page & (dcache_size - 1))); + if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) + r4k_blast_dcache_page_indexed(page); + if (exec) { + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache_page_indexed(page); + } +} + +static void r4k_flush_data_cache_page(unsigned long addr) +{ + r4k_blast_dcache_page(addr); +} + +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + unsigned long addr, aend; + + if (!cpu_has_ic_fills_f_dc) { + if (end - start > dcache_size) + r4k_blast_dcache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + + while (1) { + /* Hit_Writeback_Inv_D */ + protected_writeback_dcache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } + } + + if (end - start > icache_size) + r4k_blast_icache(); + else { + addr = start & ~(dc_lsize - 1); + aend = (end - 1) & ~(dc_lsize - 1); + while (1) { + /* Hit_Invalidate_I */ + protected_flush_icache_line(addr); + if (addr == aend) + break; + addr += dc_lsize; + } + } +} + +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_subset_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_scache_page(addr); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); +} + +#ifdef CONFIG_NONCOHERENT_IO + +static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + /* + * Either no secondary cache or the available caches don't have the + * subset property so we have to flush the primary caches + * explicitly + */ + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_wback_inv(addr, size); +} + +static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (cpu_has_subset_pcaches) { + unsigned long sc_lsize = current_cpu_data.scache.linesz; + + if (size >= scache_size) { + r4k_blast_scache(); + return; + } + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + return; + } + + if (size >= dcache_size) { + r4k_blast_dcache(); + } else { + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + a = addr & ~(dc_lsize - 1); + end = (addr + size - 1) & ~(dc_lsize - 1); + while (1) { + flush_dcache_line(a); /* Hit_Writeback_Inv_D */ + if (a == end) + break; + a += dc_lsize; + } + } + + bc_inv(addr, size); +} +#endif /* CONFIG_NONCOHERENT_IO */ + +/* + * While we're protected against bad userland addresses we don't care + * very much about what happens in that case. Usually a segmentation + * fault will dump the process later on anyway ... + */ +static void r4k_flush_cache_sigtramp(unsigned long addr) +{ + unsigned long ic_lsize = current_cpu_data.icache.linesz; + unsigned long dc_lsize = current_cpu_data.dcache.linesz; + + R4600_HIT_CACHEOP_WAR_IMPL; + protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); +} + +static void r4k_flush_icache_all(void) +{ + if (cpu_has_vtag_icache) + r4k_blast_icache(); +} + +static inline void rm7k_erratum31(void) +{ + const unsigned long ic_lsize = 32; + unsigned long addr; + + /* RM7000 erratum #31. The icache is screwed at startup. */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = KSEG0; addr <= KSEG0 + 4096; addr += ic_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + "cache\t%2, 0(%0)\n\t" + "cache\t%2, 0x1000(%0)\n\t" + "cache\t%2, 0x2000(%0)\n\t" + "cache\t%2, 0x3000(%0)\n\t" + "cache\t%1, 0(%0)\n\t" + "cache\t%1, 0x1000(%0)\n\t" + "cache\t%1, 0x2000(%0)\n\t" + "cache\t%1, 0x3000(%0)\n\t" + ".set\tmips0\n\t" + ".set\treorder\n\t" + : + : "r" (addr), "i" (Index_Store_Tag_I), "i" (Fill)); + } +} + +static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way", + "5-way", "6-way", "7-way", "8-way" +}; + +static void __init probe_pcache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + unsigned int prid = read_c0_prid(); + unsigned long config1; + unsigned int lsize; + + switch (current_cpu_data.cputype) { + case CPU_R4600: /* QED style two way caches? */ + case CPU_R4700: + case CPU_R5000: + case CPU_NEVADA: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit= ffs(dcache_size/2) - 1; + break; + + case CPU_R5432: + case CPU_R5500: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_TX49XX: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + break; + + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_R10000: + case CPU_R12000: + icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29)); + c->icache.linesz = 64; + c->icache.ways = 2; + c->icache.waybit = 0; + + dcache_size = 1 << (12 + ((config & R10K_CONF_DC) >> 26)); + c->dcache.linesz = 32; + c->dcache.ways = 2; + c->dcache.waybit = 0; + break; + + case CPU_VR4131: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 2; + c->icache.waybit = ffs(icache_size/2) - 1; + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 2; + c->dcache.waybit = ffs(dcache_size/2) - 1; + break; + + case CPU_VR41XX: + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 1; + c->icache.waybit = 0; /* doesn't matter */ + + dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + break; + + case CPU_RM7000: + rm7k_erratum31(); + + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; + break; + + default: + if (!(config & MIPS_CONF_M)) + panic("Don't know how to probe P-caches on this cpu."); + + /* + * So we seem to be a MIPS32 or MIPS64 CPU + * So let's probe the I-cache ... + */ + config1 = read_c0_config1(); + + if ((lsize = ((config1 >> 19) & 7))) + c->icache.linesz = 2 << lsize; + else + c->icache.linesz = lsize; + c->icache.sets = 64 << ((config1 >> 22) & 7); + c->icache.ways = 1 + ((config1 >> 16) & 7); + + icache_size = c->icache.sets * + c->icache.ways * + c->icache.linesz; + c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; + + /* + * Now probe the MIPS32 / MIPS64 data cache. + */ + c->dcache.flags = 0; + + if ((lsize = ((config1 >> 10) & 7))) + c->dcache.linesz = 2 << lsize; + else + c->dcache.linesz= lsize; + c->dcache.sets = 64 << ((config1 >> 13) & 7); + c->dcache.ways = 1 + ((config1 >> 7) & 7); + + dcache_size = c->dcache.sets * + c->dcache.ways * + c->dcache.linesz; + c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; + break; + } + + /* + * Processor configuration sanity check for the R4000SC erratum + * #5. With page sizes larger than 32kB there is no possibility + * to get a VCE exception anymore so we don't care about this + * misconfiguration. The case is rather theoretical anyway; + * presumably no vendor is shipping his hardware in the "bad" + * configuration. + */ + if ((prid & 0xff00) == PRID_IMP_R4000 && (prid & 0xff) < 0x40 && + !(config & CONF_SC) && c->icache.linesz != 16 && + PAGE_SIZE <= 0x8000) + panic("Improper R4000SC processor configuration detected"); + + /* compute a couple of other cache variables */ + icache_way_size = icache_size / c->icache.ways; + dcache_way_size = dcache_size / c->dcache.ways; + + c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways); + c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways); + + /* + * R10000 and R12000 P-caches are odd in a positive way. They're 32kB + * 2-way virtually indexed so normally would suffer from aliases. So + * normally they'd suffer from aliases but magic in the hardware deals + * with that for us so we don't need to take care ourselves. + */ + if (current_cpu_data.cputype != CPU_R10000 && + current_cpu_data.cputype != CPU_R12000) + if (dcache_way_size > PAGE_SIZE) + c->dcache.flags |= MIPS_CACHE_ALIASES; + + if (config & 0x8) /* VI bit */ + c->icache.flags |= MIPS_CACHE_VTAG; + + switch (c->cputype) { + case CPU_20KC: + /* + * Some older 20Kc chips doesn't have the 'VI' bit in + * the config register. + */ + c->icache.flags |= MIPS_CACHE_VTAG; + break; + + case CPU_AU1500: + c->icache.flags |= MIPS_CACHE_IC_F_DC; + break; + } + + printk("Primary instruction cache %ldkB, %s, %s, linesize %d bytes.\n", + icache_size >> 10, + cpu_has_vtag_icache ? "virtually tagged" : "physically tagged", + way_string[c->icache.ways], c->icache.linesz); + + printk("Primary data cache %ldkB %s, linesize %d bytes.\n", + dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz); +} + +/* + * If you even _breathe_ on this function, look at the gcc output and make sure + * it does not pop things on and off the stack for the cache sizing loop that + * executes in KSEG1 space or else you will crash and burn badly. You have + * been warned. + */ +static int __init probe_scache(void) +{ + extern unsigned long stext; + unsigned long flags, addr, begin, end, pow2; + unsigned int config = read_c0_config(); + struct cpuinfo_mips *c = ¤t_cpu_data; + int tmp; + + if (config & CONF_SC) + return 0; + + begin = (unsigned long) &stext; + begin &= ~((4 * 1024 * 1024) - 1); + end = begin + (4 * 1024 * 1024); + + /* + * This is such a bitch, you'd think they would make it easy to do + * this. Away you daemons of stupidity! + */ + local_irq_save(flags); + + /* Fill each size-multiple cache line with a valid tag. */ + pow2 = (64 * 1024); + for (addr = begin; addr < end; addr = (begin + pow2)) { + unsigned long *p = (unsigned long *) addr; + __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ + pow2 <<= 1; + } + + /* Load first line with zero (therefore invalid) tag. */ + write_c0_taglo(0); + write_c0_taghi(0); + __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ + cache_op(Index_Store_Tag_I, begin); + cache_op(Index_Store_Tag_D, begin); + cache_op(Index_Store_Tag_SD, begin); + + /* Now search for the wrap around point. */ + pow2 = (128 * 1024); + tmp = 0; + for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { + cache_op(Index_Load_Tag_SD, addr); + __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ + if (!read_c0_taglo()) + break; + pow2 <<= 1; + } + local_irq_restore(flags); + addr -= begin; + + c = ¤t_cpu_data; + scache_size = addr; + c->scache.linesz = 16 << ((config & R4K_CONF_SB) >> 22); + c->scache.ways = 1; + c->dcache.waybit = 0; /* does not matter */ + + return 1; +} + +static void __init setup_noscache_funcs(void) +{ + unsigned int prid; + + switch (current_cpu_data.dcache.linesz) { + case 16: + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d16; + else + _clear_page = r4k_clear_page32_d16; + _copy_page = r4k_copy_page_d16; + + break; + case 32: + prid = read_c0_prid() & 0xfff0; + if (prid == 0x2010) { /* R4600 V1.7 */ + _clear_page = r4k_clear_page_r4600_v1; + _copy_page = r4k_copy_page_r4600_v1; + } else if (prid == 0x2020) { /* R4600 V2.0 */ + _clear_page = r4k_clear_page_r4600_v2; + _copy_page = r4k_copy_page_r4600_v2; + } else { + if (cpu_has_64bits) + _clear_page = r4k_clear_page_d32; + else + _clear_page = r4k_clear_page32_d32; + _copy_page = r4k_copy_page_d32; + } + break; + } +} + +static void __init setup_scache_funcs(void) +{ + if (current_cpu_data.dcache.linesz > current_cpu_data.scache.linesz) + panic("Invalid primary cache configuration detected"); + + if (current_cpu_data.cputype == CPU_R10000 || + current_cpu_data.cputype == CPU_R12000) { + _clear_page = andes_clear_page; + _copy_page = andes_copy_page; + return; + } + + switch (current_cpu_data.scache.linesz) { + case 16: + _clear_page = r4k_clear_page_s16; + _copy_page = r4k_copy_page_s16; + break; + case 32: + _clear_page = r4k_clear_page_s32; + _copy_page = r4k_copy_page_s32; + break; + case 64: + _clear_page = r4k_clear_page_s64; + _copy_page = r4k_copy_page_s64; + break; + case 128: + _clear_page = r4k_clear_page_s128; + _copy_page = r4k_copy_page_s128; + break; + } +} + +typedef int (*probe_func_t)(unsigned long); +extern int r5k_sc_init(void); +extern int rm7k_sc_init(void); + +static void __init setup_scache(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned int config = read_c0_config(); + probe_func_t probe_scache_kseg1; + int sc_present = 0; + + /* + * Do the probing thing on R4000SC and R4400SC processors. Other + * processors don't have a S-cache that would be relevant to the + * Linux memory managment. + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); + sc_present = probe_scache_kseg1(config); + break; + + case CPU_R10000: + case CPU_R12000: + scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16); + c->scache.linesz = 64 << ((config >> 13) & 1); + c->scache.ways = 2; + c->scache.waybit= 0; + sc_present = 1; + break; + + case CPU_R5000: + case CPU_NEVADA: + setup_noscache_funcs(); +#ifdef CONFIG_R5000_CPU_SCACHE + r5k_sc_init(); +#endif + return; + + case CPU_RM7000: + setup_noscache_funcs(); +#ifdef CONFIG_RM7000_CPU_SCACHE + rm7k_sc_init(); +#endif + return; + + default: + sc_present = 0; + } + + if (!sc_present) { + setup_noscache_funcs(); + return; + } + + if ((current_cpu_data.isa_level == MIPS_CPU_ISA_M32 || + current_cpu_data.isa_level == MIPS_CPU_ISA_M64) && + !(current_cpu_data.scache.flags & MIPS_CACHE_NOT_PRESENT)) + panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); + + printk("Unified secondary cache %ldkB %s, linesize %d bytes.\n", + scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + current_cpu_data.options |= MIPS_CPU_SUBSET_CACHES; + setup_scache_funcs(); +} + +static inline void coherency_setup(void) +{ + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + + /* + * c0_status.cu=0 specifies that updates by the sc instruction use + * the coherency mode specified by the TLB; 1 means cachable + * coherent update on write will be used. Not all processors have + * this bit and; some wire it to zero, others like Toshiba had the + * silly idea of putting something else there ... + */ + switch (current_cpu_data.cputype) { + case CPU_R4000PC: + case CPU_R4000SC: + case CPU_R4000MC: + case CPU_R4400PC: + case CPU_R4400SC: + case CPU_R4400MC: + clear_c0_config(CONF_CU); + break; + } + +} + +void __init ld_mmu_r4xx0(void) +{ + extern char except_vec2_generic; + + /* Default cache error handler for R4000 and R5000 family */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_generic, 0x80); + + probe_pcache(); + setup_scache(); + coherency_setup(); + + if (current_cpu_data.dcache.sets * + current_cpu_data.dcache.ways > PAGE_SIZE) + current_cpu_data.dcache.flags |= MIPS_CACHE_ALIASES; + + /* + * Some MIPS32 and MIPS64 processors have physically indexed caches. + * This code supports virtually indexed processors and will be + * unnecessarily unefficient on physically indexed processors. + */ + shm_align_mask = max_t(unsigned long, + current_cpu_data.dcache.sets * current_cpu_data.dcache.linesz - 1, + PAGE_SIZE - 1); + + flush_cache_all = r4k_flush_cache_all; + __flush_cache_all = r4k___flush_cache_all; + flush_cache_mm = r4k_flush_cache_mm; + flush_cache_page = r4k_flush_cache_page; + flush_icache_page = r4k_flush_icache_page; + flush_cache_range = r4k_flush_cache_range; + + flush_cache_sigtramp = r4k_flush_cache_sigtramp; + flush_icache_all = r4k_flush_icache_all; + flush_data_cache_page = r4k_flush_data_cache_page; + flush_icache_range = r4k_flush_icache_range; + +#ifdef CONFIG_NONCOHERENT_IO + _dma_cache_wback_inv = r4k_dma_cache_wback_inv; + _dma_cache_wback = r4k_dma_cache_wback_inv; + _dma_cache_inv = r4k_dma_cache_inv; +#endif + + __flush_cache_all(); +} diff -Nru a/arch/mips64/mm/c-sb1.c b/arch/mips64/mm/c-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/c-sb1.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,594 @@ +/* + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/init.h> +#include <asm/mmu_context.h> +#include <asm/bootinfo.h> +#include <asm/cacheops.h> +#include <asm/cpu.h> +#include <asm/uaccess.h> + +extern void sb1_clear_page(void * page); +extern void sb1_copy_page(void * to, void * from); + +/* These are probed at ld_mmu time */ +static unsigned long icache_size; +static unsigned long dcache_size; + +static unsigned long icache_line_size; +static unsigned long dcache_line_size; + +static unsigned int icache_index_mask; +static unsigned int dcache_index_mask; + +static unsigned long icache_assoc; +static unsigned long dcache_assoc; + +static unsigned int icache_sets; +static unsigned int dcache_sets; + +static unsigned int icache_range_cutoff; +static unsigned int dcache_range_cutoff; + +/* + * The dcache is fully coherent to the system, with one + * big caveat: the instruction stream. In other words, + * if we miss in the icache, and have dirty data in the + * L1 dcache, then we'll go out to memory (or the L2) and + * get the not-as-recent data. + * + * So the only time we have to flush the dcache is when + * we're flushing the icache. Since the L2 is fully + * coherent to everything, including I/O, we never have + * to flush it + */ + +/* + * Writeback and invalidate the entire dcache + */ +static inline void __sb1_writeback_inv_dcache_all(void) +{ + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " daddiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " daddu $1, $1, %0 \n" /* Next address */ + ".set pop \n" + : + : "r" (dcache_line_size), "r" (dcache_sets), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. The addresses are + * virtual, and since we're using index ops and bit 12 is part of both + * the virtual frame and physical index, we have to clear both sets + * (bit 12 set and cleared). + */ +static inline void __sb1_writeback_inv_dcache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " xori $1, $1, 1<<12 \n" + " cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + +/* + * Writeback and invalidate a range of the dcache. With physical + * addresseses, we don't have to worry about possible bit 12 aliasing. + * XXXKW is it worth turning on KX and using hit ops with xkphys? + */ +static inline void __sb1_writeback_inv_dcache_phys_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-WB-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-WB-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " sync \n" + " .set pop \n" + : + : "r" (start & ~(dcache_line_size - 1)), + "r" ((end + dcache_line_size - 1) & ~(dcache_line_size - 1)), + "r" (dcache_line_size), + "r" (dcache_index_mask), + "i" (Index_Writeback_Inv_D)); +} + + +/* + * Invalidate the entire icache + */ +static inline void __sb1_flush_icache_all(void) +{ + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " move $1, $0 \n" /* Start at index 0 */ + "1: cache %2, 0($1) \n" /* Invalidate this index */ + " cache %2, (1<<13)($1)\n" /* Invalidate this index */ + " cache %2, (2<<13)($1)\n" /* Invalidate this index */ + " cache %2, (3<<13)($1)\n" /* Invalidate this index */ + " daddiu %1, %1, -1 \n" /* Decrement loop count */ + " bnez %1, 1b \n" /* loop test */ + " daddu $1, $1, %0 \n" /* Next address */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (icache_line_size), "r" (icache_sets), + "i" (Index_Invalidate_I)); +} + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_cache_page(struct vm_area_struct *vma, + unsigned long addr) +{ + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + + /* + * Bumping the ASID is probably cheaper than the flush ... + */ + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); +} + +#ifdef CONFIG_SMP +struct flush_cache_page_args { + struct vm_area_struct *vma; + unsigned long addr; +}; + +static void sb1_flush_cache_page_ipi(void *info) +{ + struct flush_cache_page_args *args = info; + + local_sb1_flush_cache_page(args->vma, args->addr); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr) +{ + struct flush_cache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.addr = addr; + on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); +} +#else +void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr); +asm("sb1_flush_cache_page = local_sb1_flush_cache_page"); +#endif + +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " and $1, %0, %3 \n" /* mask non-index bits */ + "1: cache %4, (0<<13)($1) \n" /* Index-inval this address */ + " cache %4, (1<<13)($1) \n" /* Index-inval this address */ + " cache %4, (2<<13)($1) \n" /* Index-inval this address */ + " cache %4, (3<<13)($1) \n" /* Index-inval this address */ + " daddu %0, %0, %2 \n" /* next line */ + " bne %0, %1, 1b \n" /* loop test */ + " and $1, %0, %3 \n" /* mask non-index bits */ + " bnezl $0, 2f \n" /* Force mispredict */ + " nop \n" + "2: sync \n" + ".set pop \n" + : + : "r" (start & ~(icache_line_size - 1)), + "r" ((end + icache_line_size - 1) & ~(icache_line_size - 1)), + "r" (icache_line_size), + "r" (icache_index_mask), + "i" (Index_Invalidate_I)); +} + + +/* + * Invalidate all caches on this CPU + */ +static void local_sb1___flush_cache_all(void) +{ + __sb1_writeback_inv_dcache_all(); + __sb1_flush_icache_all(); +} + +#ifdef CONFIG_SMP +extern void sb1___flush_cache_all_ipi(void *ignored); +asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all"); + +static void sb1___flush_cache_all(void) +{ + on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); +} +#else +extern void sb1___flush_cache_all(void); +asm("sb1___flush_cache_all = local_sb1___flush_cache_all"); +#endif + +/* + * When flushing a range in the icache, we have to first writeback + * the dcache for the same range, so new ifetches will see any + * data that was dirty in the dcache. + * + * The start/end arguments are Kseg addresses (possibly mapped Kseg). + */ + +static void local_sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + /* Just wb-inv the whole dcache if the range is big enough */ + if ((end - start) > dcache_range_cutoff) + __sb1_writeback_inv_dcache_all(); + else + __sb1_writeback_inv_dcache_range(start, end); + + /* Just flush the whole icache if the range is big enough */ + if ((end - start) > icache_range_cutoff) + __sb1_flush_icache_all(); + else + __sb1_flush_icache_range(start, end); +} + +#ifdef CONFIG_SMP +struct flush_icache_range_args { + unsigned long start; + unsigned long end; +}; + +static void sb1_flush_icache_range_ipi(void *info) +{ + struct flush_icache_range_args *args = info; + + local_sb1_flush_icache_range(args->start, args->end); +} + +void sb1_flush_icache_range(unsigned long start, unsigned long end) +{ + struct flush_icache_range_args args; + + args.start = start; + args.end = end; + on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); +} +#else +void sb1_flush_icache_range(unsigned long start, unsigned long end); +asm("sb1_flush_icache_range = local_sb1_flush_icache_range"); +#endif + +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); + /* + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) + */ + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } +} + +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) +{ + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); +} +#else +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page); +asm("sb1_flush_icache_page = local_sb1_flush_icache_page"); +#endif + +/* + * A signal trampoline must fit into a single cacheline. + */ +static void local_sb1_flush_cache_sigtramp(unsigned long addr) +{ + __asm__ __volatile__ ( + " .set push \n" + " .set noreorder \n" + " .set noat \n" + " .set mips4 \n" + " cache %2, (0<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (1<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (2<<13)(%0) \n" /* Index-inval this address */ + " cache %2, (3<<13)(%0) \n" /* Index-inval this address */ + " xori $1, %0, 1<<12 \n" /* Flip index bit 12 */ + " cache %2, (0<<13)($1) \n" /* Index-inval this address */ + " cache %2, (1<<13)($1) \n" /* Index-inval this address */ + " cache %2, (2<<13)($1) \n" /* Index-inval this address */ + " cache %2, (3<<13)($1) \n" /* Index-inval this address */ + " cache %3, (0<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (1<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (2<<13)(%1) \n" /* Index-inval this address */ + " cache %3, (3<<13)(%1) \n" /* Index-inval this address */ + " bnezl $0, 1f \n" /* Force mispredict */ + " nop \n" + "1: \n" + " .set pop \n" + : + : "r" (addr & dcache_index_mask), "r" (addr & icache_index_mask), + "i" (Index_Writeback_Inv_D), "i" (Index_Invalidate_I)); +} + +#ifdef CONFIG_SMP +static void sb1_flush_cache_sigtramp_ipi(void *info) +{ + unsigned long iaddr = (unsigned long) info; + local_sb1_flush_cache_sigtramp(iaddr); +} + +static void sb1_flush_cache_sigtramp(unsigned long addr) +{ + on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); +} +#else +void sb1_flush_cache_sigtramp(unsigned long addr); +asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp"); +#endif + + +/* + * Anything that just flushes dcache state can be ignored, as we're always + * coherent in dcache space. This is just a dummy function that all the + * nop'ed routines point to + */ +static void sb1_nop(void) +{ +} + +/* + * Cache set values (from the mips64 spec) + * 0 - 64 + * 1 - 128 + * 2 - 256 + * 3 - 512 + * 4 - 1024 + * 5 - 2048 + * 6 - 4096 + * 7 - Reserved + */ + +static unsigned int decode_cache_sets(unsigned int config_field) +{ + if (config_field == 7) { + /* JDCXXX - Find a graceful way to abort. */ + return 0; + } + return (1<<(config_field + 6)); +} + +/* + * Cache line size values (from the mips64 spec) + * 0 - No cache present. + * 1 - 4 bytes + * 2 - 8 bytes + * 3 - 16 bytes + * 4 - 32 bytes + * 5 - 64 bytes + * 6 - 128 bytes + * 7 - Reserved + */ + +static unsigned int decode_cache_line_size(unsigned int config_field) +{ + if (config_field == 0) { + return 0; + } else if (config_field == 7) { + /* JDCXXX - Find a graceful way to abort. */ + return 0; + } + return (1<<(config_field + 1)); +} + +/* + * Relevant bits of the config1 register format (from the MIPS32/MIPS64 specs) + * + * 24:22 Icache sets per way + * 21:19 Icache line size + * 18:16 Icache Associativity + * 15:13 Dcache sets per way + * 12:10 Dcache line size + * 9:7 Dcache Associativity + */ + +static __init void probe_cache_sizes(void) +{ + u32 config1; + + config1 = read_c0_config1(); + icache_line_size = decode_cache_line_size((config1 >> 19) & 0x7); + dcache_line_size = decode_cache_line_size((config1 >> 10) & 0x7); + icache_sets = decode_cache_sets((config1 >> 22) & 0x7); + dcache_sets = decode_cache_sets((config1 >> 13) & 0x7); + icache_assoc = ((config1 >> 16) & 0x7) + 1; + dcache_assoc = ((config1 >> 7) & 0x7) + 1; + icache_size = icache_line_size * icache_sets * icache_assoc; + dcache_size = dcache_line_size * dcache_sets * dcache_assoc; + /* Need to remove non-index bits for index ops */ + icache_index_mask = (icache_sets - 1) * icache_line_size; + dcache_index_mask = (dcache_sets - 1) * dcache_line_size; + /* + * These are for choosing range (index ops) versus all. + * icache flushes all ways for each set, so drop icache_assoc. + * dcache flushes all ways and each setting of bit 12 for each + * index, so drop dcache_assoc and halve the dcache_sets. + */ + icache_range_cutoff = icache_sets * icache_line_size; + dcache_range_cutoff = (dcache_sets / 2) * icache_line_size; +} + +/* + * This is called from loadmmu.c. We have to set up all the + * memory management function pointers, as well as initialize + * the caches and tlbs + */ +void ld_mmu_sb1(void) +{ + extern char except_vec2_sb1; + unsigned long temp; + + /* Special cache error handler for SB1 */ + memcpy((void *)(KSEG0 + 0x100), &except_vec2_sb1, 0x80); + memcpy((void *)(KSEG1 + 0x100), &except_vec2_sb1, 0x80); + + probe_cache_sizes(); + + _clear_page = sb1_clear_page; + _copy_page = sb1_copy_page; + + /* + * None of these are needed for the SB1 - the Dcache is + * physically indexed and tagged, so no virtual aliasing can + * occur + */ + flush_cache_range = (void *) sb1_nop; + flush_cache_page = sb1_flush_cache_page; + flush_cache_mm = (void (*)(struct mm_struct *))sb1_nop; + flush_cache_all = sb1_nop; + + /* These routines are for Icache coherence with the Dcache */ + flush_icache_range = sb1_flush_icache_range; + flush_icache_page = sb1_flush_icache_page; + flush_icache_all = __sb1_flush_icache_all; /* local only */ + + flush_cache_sigtramp = sb1_flush_cache_sigtramp; + flush_data_cache_page = (void *) sb1_nop; + + /* Full flush */ + __flush_cache_all = sb1___flush_cache_all; + + change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); + /* + * This is the only way to force the update of K0 to complete + * before subsequent instruction fetch. + */ + __asm__ __volatile__ ( + " .set push \n" + " .set mips4 \n" + " dla %0, 1f \n" + " dmtc0 %0, $14 \n" + " eret \n" + "1: .set pop \n" + : "=r" (temp)); + flush_cache_all(); +} diff -Nru a/arch/mips64/mm/cache.c b/arch/mips64/mm/cache.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/cache.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,60 @@ +/* + * 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 - 2003 by Ralf Baechle + */ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/cacheflush.h> + +asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) +{ + /* This should flush more selectivly ... */ + __flush_cache_all(); + + return 0; +} + +void flush_dcache_page(struct page *page) +{ + unsigned long addr; + + if (page->mapping && + list_empty(&page->mapping->i_mmap) && + list_empty(&page->mapping->i_mmap_shared)) { + SetPageDcacheDirty(page); + + return; + } + + /* + * We could delay the flush for the !page->mapping case too. But that + * case is for exec env/arg pages and those are %99 certainly going to + * get faulted into the tlb (and thus flushed) anyways. + */ + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); +} + +void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + struct page *page; + unsigned long pfn, addr; + + pfn = pte_pfn(pte); + if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page->mapping) && + Page_dcache_dirty(page)) { + if (pages_do_alias((unsigned long)page_address(page), + address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); + flush_data_cache_page(addr); + } + + ClearPageDcacheDirty(page); + } +} diff -Nru a/arch/mips64/mm/cerr-sb1.c b/arch/mips64/mm/cerr-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/cerr-sb1.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,542 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <linux/sched.h> +#include <asm/mipsregs.h> +#include <asm/sibyte/sb1250.h> + +#ifndef CONFIG_SIBYTE_BUS_WATCHER +#include <asm/io.h> +#include <asm/sibyte/sb1250_regs.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/64bit.h> +#endif + +/* SB1 definitions */ + +/* XXX should come from config1 XXX */ +#define SB1_CACHE_INDEX_MASK 0x1fe0 + +#define CP0_ERRCTL_RECOVERABLE (1 << 31) +#define CP0_ERRCTL_DCACHE (1 << 30) +#define CP0_ERRCTL_ICACHE (1 << 29) +#define CP0_ERRCTL_MULTIBUS (1 << 23) +#define CP0_ERRCTL_MC_TLB (1 << 15) +#define CP0_ERRCTL_MC_TIMEOUT (1 << 14) + +#define CP0_CERRI_TAG_PARITY (1 << 29) +#define CP0_CERRI_DATA_PARITY (1 << 28) +#define CP0_CERRI_EXTERNAL (1 << 26) + +#define CP0_CERRI_IDX_VALID(c) (!((c) & CP0_CERRI_EXTERNAL)) +#define CP0_CERRI_DATA (CP0_CERRI_DATA_PARITY) + +#define CP0_CERRD_MULTIPLE (1 << 31) +#define CP0_CERRD_TAG_STATE (1 << 30) +#define CP0_CERRD_TAG_ADDRESS (1 << 29) +#define CP0_CERRD_DATA_SBE (1 << 28) +#define CP0_CERRD_DATA_DBE (1 << 27) +#define CP0_CERRD_EXTERNAL (1 << 26) +#define CP0_CERRD_LOAD (1 << 25) +#define CP0_CERRD_STORE (1 << 24) +#define CP0_CERRD_FILLWB (1 << 23) +#define CP0_CERRD_COHERENCY (1 << 22) +#define CP0_CERRD_DUPTAG (1 << 21) + +#define CP0_CERRD_DPA_VALID(c) (!((c) & CP0_CERRD_EXTERNAL)) +#define CP0_CERRD_IDX_VALID(c) \ + (((c) & (CP0_CERRD_LOAD | CP0_CERRD_STORE)) ? (!((c) & CP0_CERRD_EXTERNAL)) : 0) +#define CP0_CERRD_CAUSES \ + (CP0_CERRD_LOAD | CP0_CERRD_STORE | CP0_CERRD_FILLWB | CP0_CERRD_COHERENCY | CP0_CERRD_DUPTAG) +#define CP0_CERRD_TYPES \ + (CP0_CERRD_TAG_STATE | CP0_CERRD_TAG_ADDRESS | CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE | CP0_CERRD_EXTERNAL) +#define CP0_CERRD_DATA (CP0_CERRD_DATA_SBE | CP0_CERRD_DATA_DBE) + +static uint32_t extract_ic(unsigned short addr, int data); +static uint32_t extract_dc(unsigned short addr, int data); + +static inline void breakout_errctl(unsigned int val) +{ + if (val & CP0_ERRCTL_RECOVERABLE) + prom_printf(" recoverable"); + if (val & CP0_ERRCTL_DCACHE) + prom_printf(" dcache"); + if (val & CP0_ERRCTL_ICACHE) + prom_printf(" icache"); + if (val & CP0_ERRCTL_MULTIBUS) + prom_printf(" multiple-buserr"); + prom_printf("\n"); +} + +static inline void breakout_cerri(unsigned int val) +{ + if (val & CP0_CERRI_TAG_PARITY) + prom_printf(" tag-parity"); + if (val & CP0_CERRI_DATA_PARITY) + prom_printf(" data-parity"); + if (val & CP0_CERRI_EXTERNAL) + prom_printf(" external"); + prom_printf("\n"); +} + +static inline void breakout_cerrd(unsigned int val) +{ + switch (val & CP0_CERRD_CAUSES) { + case CP0_CERRD_LOAD: + prom_printf(" load,"); + break; + case CP0_CERRD_STORE: + prom_printf(" store,"); + break; + case CP0_CERRD_FILLWB: + prom_printf(" fill/wb,"); + break; + case CP0_CERRD_COHERENCY: + prom_printf(" coherency,"); + break; + case CP0_CERRD_DUPTAG: + prom_printf(" duptags,"); + break; + default: + prom_printf(" NO CAUSE,"); + break; + } + if (!(val & CP0_CERRD_TYPES)) + prom_printf(" NO TYPE"); + else { + if (val & CP0_CERRD_MULTIPLE) + prom_printf(" multi-err"); + if (val & CP0_CERRD_TAG_STATE) + prom_printf(" tag-state"); + if (val & CP0_CERRD_TAG_ADDRESS) + prom_printf(" tag-address"); + if (val & CP0_CERRD_DATA_SBE) + prom_printf(" data-SBE"); + if (val & CP0_CERRD_DATA_DBE) + prom_printf(" data-DBE"); + if (val & CP0_CERRD_EXTERNAL) + prom_printf(" external"); + } + prom_printf("\n"); +} + +#ifndef CONFIG_SIBYTE_BUS_WATCHER + +static void check_bus_watcher(void) +{ + uint32_t status, l2_err, memio_err; + + /* Destructive read, clears register and interrupt */ + status = csr_in32(IO_SPACE_BASE | A_SCD_BUS_ERR_STATUS); + /* Bit 31 is always on, but there's no #define for that */ + if (status & ~(1UL << 31)) { + l2_err = csr_in32(IO_SPACE_BASE | A_BUS_L2_ERRORS); + memio_err = csr_in32(IO_SPACE_BASE | A_BUS_MEM_IO_ERRORS); + prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + prom_printf("\nLast recorded signature:\n"); + prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), + (int)(G_SCD_BERR_TID(status) >> 6), + (int)G_SCD_BERR_RID(status), + (int)G_SCD_BERR_DCODE(status)); + } else { + prom_printf("Bus watcher indicates no error\n"); + } +} +#else +extern void check_bus_watcher(void); +#endif + +asmlinkage void sb1_cache_error(void) +{ + uint64_t cerr_dpa; + uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + + prom_printf("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); + + __asm__ __volatile__ ( + " .set push\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " mfc0 %0, $26\n\t" + " mfc0 %1, $27\n\t" + " mfc0 %2, $27, 1\n\t" + " dmfc0 $1, $27, 3\n\t" + " dsrl32 %3, $1, 0 \n\t" + " sll %4, $1, 0 \n\t" + " mfc0 %5, $30\n\t" + " .set pop" + : "=r" (errctl), "=r" (cerr_i), "=r" (cerr_d), + "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); + + cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; + prom_printf(" c0_errorepc == %08x\n", eepc); + prom_printf(" c0_errctl == %08x", errctl); + breakout_errctl(errctl); + if (errctl & CP0_ERRCTL_ICACHE) { + prom_printf(" c0_cerr_i == %08x", cerr_i); + breakout_cerri(cerr_i); + if (CP0_CERRI_IDX_VALID(cerr_i)) { + if ((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_i idx doesn't match eepc\n"); + else { + res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, + (cerr_i & CP0_CERRI_DATA) != 0); + if (!(res & cerr_i)) + prom_printf("...didn't see indicated icache problem\n"); + } + } + } + if (errctl & CP0_ERRCTL_DCACHE) { + prom_printf(" c0_cerr_d == %08x", cerr_d); + breakout_cerrd(cerr_d); + if (CP0_CERRD_DPA_VALID(cerr_d)) { + prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa); + if (!CP0_CERRD_IDX_VALID(cerr_d)) { + res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated dcache problem\n"); + } else { + if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) + prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + else { + res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, + (cerr_d & CP0_CERRD_DATA) != 0); + if (!(res & cerr_d)) + prom_printf("...didn't see indicated problem\n"); + } + } + } + } + + check_bus_watcher(); + + while (1); + /* + * This tends to make things get really ugly; let's just stall instead. + * panic("Can't handle the cache error!"); + */ +} + + +/* Parity lookup table. */ +static const uint8_t parity[256] = { + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */ +static const uint64_t mask_72_64[8] = { + 0x0738C808099264FFL, + 0x38C808099264FF07L, + 0xC808099264FF0738L, + 0x08099264FF0738C8L, + 0x099264FF0738C808L, + 0x9264FF0738C80809L, + 0x64FF0738C8080992L, + 0xFF0738C808099264L +}; + +/* Calculate the parity on a range of bits */ +static char range_parity(uint64_t dword, int max, int min) +{ + char parity = 0; + int i; + dword >>= min; + for (i=max-min; i>=0; i--) { + if (dword & 0x1) + parity = !parity; + dword >>= 1; + } + return parity; +} + +/* Calculate the 4-bit even byte-parity for an instruction */ +static unsigned char inst_parity(uint32_t word) +{ + int i, j; + char parity = 0; + for (j=0; j<4; j++) { + char byte_parity = 0; + for (i=0; i<8; i++) { + if (word & 0x80000000) + byte_parity = !byte_parity; + word <<= 1; + } + parity <<= 1; + parity |= byte_parity; + } + return parity; +} + +static uint32_t extract_ic(unsigned short addr, int data) +{ + unsigned short way; + int valid; + uint64_t taglo, va, tlo_tmp; + uint32_t taghi, taglolo, taglohi; + uint8_t lru; + int res = 0; + + prom_printf("Icache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + /* Index-load-tag-I */ + __asm__ __volatile__ ( + " .set push \n\t" + " .set noreorder \n\t" + " .set mips64 \n\t" + " .set noat \n\t" + " cache 4, 0(%3) \n\t" + " mfc0 %0, $29 \n\t" + " dmfc0 $1, $28 \n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 5) & 0x3), /* bank */ + ((addr >> 7) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + va = (taglo & 0xC0000FFFFFFFE000) | addr; + if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3)) + va |= 0x3FFFF00000000000; + valid = ((taghi >> 29) & 1); + if (valid) { + tlo_tmp = taglo & 0xfff3ff; + if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { + prom_printf(" ** bad parity in VTag0/G/ASID\n"); + res |= CP0_CERRI_TAG_PARITY; + } + if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { + prom_printf(" ** bad parity in R/VTag1\n"); + res |= CP0_CERRI_TAG_PARITY; + } + } + if (valid ^ ((taghi >> 27) & 1)) { + prom_printf(" ** bad parity for valid bit\n"); + res |= CP0_CERRI_TAG_PARITY; + } + prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + way, va, valid, taghi, taglo); + + if (data) { + uint32_t datahi, insta, instb; + uint8_t predecode; + int offset; + + /* (hit all banks and ways) */ + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-I */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 6, 0(%3) \n\t" + " mfc0 %0, $29, 1\n\t" + " dmfc0 $1, $28, 1\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop \n" + : "=r" (datahi), "=r" (insta), "=r" (instb) + : "r" ((way << 13) | addr | (offset << 3))); + predecode = (datahi >> 8) & 0xff; + if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { + prom_printf(" ** bad parity in predecode\n"); + res |= CP0_CERRI_DATA_PARITY; + } + /* XXXKW should/could check predecode bits themselves */ + if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { + prom_printf(" ** bad parity in instruction a\n"); + res |= CP0_CERRI_DATA_PARITY; + } + if ((datahi & 0xf) ^ inst_parity(instb)) { + prom_printf(" ** bad parity in instruction b\n"); + res |= CP0_CERRI_DATA_PARITY; + } + prom_printf(" %05X-%08X%08X", datahi, insta, instb); + } + prom_printf("\n"); + } + } + return res; +} + +/* Compute the ECC for a data doubleword */ +static uint8_t dc_ecc(uint64_t dword) +{ + uint64_t t; + uint32_t w; + uint8_t p; + int i; + + p = 0; + for (i = 7; i >= 0; i--) + { + p <<= 1; + t = dword & mask_72_64[i]; + w = (uint32_t)(t >> 32); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + w = (uint32_t)(t & 0xFFFFFFFF); + p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF] + ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]); + } + return p; +} + +struct dc_state { + unsigned char val; + char *name; +}; + +static struct dc_state dc_states[] = { + { 0x00, "INVALID" }, + { 0x0f, "COH-SHD" }, + { 0x13, "NCO-E-C" }, + { 0x19, "NCO-E-D" }, + { 0x16, "COH-E-C" }, + { 0x1c, "COH-E-D" }, + { 0xff, "*ERROR*" } +}; + +#define DC_TAG_VALID(state) \ + (((state) == 0xf) || ((state) == 0x13) || ((state) == 0x19) || ((state == 0x16)) || ((state) == 0x1c)) + +static char *dc_state_str(unsigned char state) +{ + struct dc_state *dsc = dc_states; + while (dsc->val != 0xff) { + if (dsc->val == state) + break; + dsc++; + } + return dsc->name; +} + +static uint32_t extract_dc(unsigned short addr, int data) +{ + int valid, way; + unsigned char state; + uint64_t taglo, pa; + uint32_t taghi, taglolo, taglohi; + uint8_t ecc, lru; + int res = 0; + + prom_printf("Dcache index 0x%04x ", addr); + for (way = 0; way < 4; way++) { + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 5, 0(%3)\n\t" /* Index-load-tag-D */ + " mfc0 %0, $29, 2\n\t" + " dmfc0 $1, $28, 2\n\t" + " dsrl32 %1, $1, 0\n\t" + " sll %2, $1, 0\n\t" + " .set pop" + : "=r" (taghi), "=r" (taglohi), "=r" (taglolo) + : "r" ((way << 13) | addr)); + + taglo = ((unsigned long long)taglohi << 32) | taglolo; + pa = (taglo & 0xFFFFFFE000) | addr; + if (way == 0) { + lru = (taghi >> 14) & 0xff; + prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ + ((addr >> 6) & 0x3f), /* index */ + (lru & 0x3), + ((lru >> 2) & 0x3), + ((lru >> 4) & 0x3), + ((lru >> 6) & 0x3)); + } + state = (taghi >> 25) & 0x1f; + valid = DC_TAG_VALID(state); + prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + way, pa, dc_state_str(state), state, taghi, taglo); + if (valid) { + if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { + prom_printf(" ** bad parity in PTag1\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { + prom_printf(" ** bad parity in PTag0\n"); + res |= CP0_CERRD_TAG_ADDRESS; + } + } else { + res |= CP0_CERRD_TAG_STATE; + } + + if (data) { + uint64_t datalo; + uint32_t datalohi, datalolo, datahi; + int offset; + + for (offset = 0; offset < 4; offset++) { + /* Index-load-data-D */ + __asm__ __volatile__ ( + " .set push\n\t" + " .set noreorder\n\t" + " .set mips64\n\t" + " .set noat\n\t" + " cache 7, 0(%3)\n\t" /* Index-load-data-D */ + " mfc0 %0, $29, 3\n\t" + " dmfc0 $1, $28, 3\n\t" + " dsrl32 %1, $1, 0 \n\t" + " sll %2, $1, 0 \n\t" + " .set pop" + : "=r" (datahi), "=r" (datalohi), "=r" (datalolo) + : "r" ((way << 13) | addr | (offset << 3))); + datalo = ((unsigned long long)datalohi << 32) | datalolo; + ecc = dc_ecc(datalo); + if (ecc != datahi) { + int bits = 0; + prom_printf(" ** bad ECC (%02x %02x) ->", + datahi, ecc); + ecc ^= datahi; + while (ecc) { + if (ecc & 1) bits++; + ecc >>= 1; + } + res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; + } + prom_printf(" %02X-%016llX", datahi, datalo); + } + prom_printf("\n"); + } + } + return res; +} diff -Nru a/arch/mips64/mm/cex-sb1.S b/arch/mips64/mm/cex-sb1.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/cex-sb1.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2001,2002,2003 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <linux/init.h> + +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> +#include <asm/sibyte/board.h> + + .text + .set noat + .set mips4 + + __INIT + + /* Cache Error handler for SB1 */ + LEAF(except_vec2_sb1) + mfc0 k1, $26 + # check if error was recoverable + bltz k1, leave_cerr +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS + # look for signature of spurious CErr + lui k0, 0x4000 + bne k0, k1, 1f + .word 0x401Bd801 # mfc0 k1, $27, 1 + lui k0, 0xffe0 + and k1, k0, k1 + lui k0, 0x0200 + beq k0, k1, leave_cerr +1: +#endif + j handle_vec2_sb1 + +leave_cerr: + # clear/unlock the registers + mtc0 zero, $26 + mtc0 zero, $27 + .word 0x4080d801 # mtc0 zero, $27, 1 + .word 0x4080d803 # mtc0 zero, $27, 3 + eret + END(except_vec2_sb1) + + __FINIT + + LEAF(handle_vec2_sb1) + mfc0 k0,CP0_CONFIG + li k1,~CONF_CM_CMASK + and k0,k0,k1 + ori k0,k0,CONF_CM_UNCACHED + mtc0 k0,CP0_CONFIG + + SSNOP + SSNOP + SSNOP + SSNOP + bnezl $0, 1f +1: + mfc0 k0, CP0_STATUS + sll k0, k0, 3 # check CU0 (kernel?) + bltz k0, 2f + get_saved_sp + move sp, k1 # want Kseg SP (so uncached) +2: + j sb1_cache_error + + END(handle_vec2_sb1) diff -Nru a/arch/mips64/mm/extable.c b/arch/mips64/mm/extable.c --- a/arch/mips64/mm/extable.c Fri Jun 27 14:19:53 2003 +++ b/arch/mips64/mm/extable.c Fri Jun 27 14:19:53 2003 @@ -1,65 +1,30 @@ /* - * 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, 1995, 1996, 1999 by Ralf Baechle - * Copyright (C) 1999 by Silicon Graphics + * linux/arch/i386/mm/extable.c */ + #include <linux/config.h> #include <linux/module.h> #include <linux/spinlock.h> #include <asm/uaccess.h> -extern const struct exception_table_entry __start___ex_table[]; -extern const struct exception_table_entry __stop___ex_table[]; - -static inline unsigned long -search_one_table(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) +/* Simple binary search */ +const struct exception_table_entry * +search_extable(const struct exception_table_entry *first, + const struct exception_table_entry *last, + unsigned long value) { - while (first <= last) { + while (first <= last) { const struct exception_table_entry *mid; long diff; mid = (last - first) / 2 + first; diff = mid->insn - value; - if (diff == 0) - return mid->nextinsn; - else if (diff < 0) - first = mid+1; - else - last = mid-1; - } - return 0; -} - -extern spinlock_t modlist_lock; - -unsigned long search_exception_table(unsigned long addr) -{ - unsigned long ret = 0; - unsigned long flags; - -#ifndef CONFIG_MODULES - /* There is only the kernel to search. */ - ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr); - return ret; -#else - /* The kernel is the last "module" -- no need to treat it special. */ - struct module *mp; - - spin_lock_irqsave(&modlist_lock, flags); - for (mp = module_list; mp != NULL; mp = mp->next) { - if (mp->ex_table_start == NULL) - continue; - ret = search_one_table(mp->ex_table_start, - mp->ex_table_end - 1, addr); - if (ret) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - return ret; -#endif + if (diff == 0) + return mid; + else if (diff < 0) + first = mid+1; + else + last = mid-1; + } + return NULL; } diff -Nru a/arch/mips64/mm/fault.c b/arch/mips64/mm/fault.c --- a/arch/mips64/mm/fault.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips64/mm/fault.c Fri Jun 27 14:19:57 2003 @@ -20,7 +20,10 @@ #include <linux/smp.h> #include <linux/smp_lock.h> #include <linux/version.h> +#include <linux/vt_kern.h> /* For unblank_screen() */ +#include <linux/module.h> +#include <asm/branch.h> #include <asm/hardirq.h> #include <asm/pgalloc.h> #include <asm/mmu_context.h> @@ -30,60 +33,34 @@ #define development_version (LINUX_VERSION_CODE & 0x100) -extern void die(char *, struct pt_regs *, unsigned long write); - /* * Macro for exception fixup code to access integer registers. */ #define dpf_reg(r) (regs->regs[r]) -asmlinkage void -dodebug(abi64_no_regargs, struct pt_regs regs) -{ - printk("Got syscall %ld, cpu %d proc %s:%d epc 0x%lx\n", regs.regs[2], - smp_processor_id(), current->comm, current->pid, regs.cp0_epc); -} - -asmlinkage void -dodebug2(abi64_no_regargs, struct pt_regs regs) -{ - unsigned long retaddr; - - __asm__ __volatile__( - ".set noreorder\n\t" - "add %0,$0,$31\n\t" - ".set reorder" - : "=r" (retaddr)); - printk("Got exception 0x%lx at 0x%lx\n", retaddr, regs.cp0_epc); -} - -extern spinlock_t timerlist_lock; - /* - * Unlock any spinlocks which will prevent us from getting the - * message out (timerlist_lock is acquired through the - * console unblank code) + * Unlock any spinlocks which will prevent us from getting the out */ void bust_spinlocks(int yes) { - spin_lock_init(&timerlist_lock); + int loglevel_save = console_loglevel; + if (yes) { oops_in_progress = 1; - } else { - int loglevel_save = console_loglevel; + return; + } #ifdef CONFIG_VT - unblank_screen(); + unblank_screen(); #endif - oops_in_progress = 0; - /* - * OK, the message is on the console. Now we call printk() - * without oops_in_progress set so that printk will give klogd - * a poke. Hold onto your hats... - */ - console_loglevel = 15; /* NMI oopser may have shut the console up */ - printk(" "); - console_loglevel = loglevel_save; - } + oops_in_progress = 0; + /* + * OK, the message is on the console. Now we call printk() + * without oops_in_progress set so that printk will give klogd + * a poke. Hold onto your hats... + */ + console_loglevel = 15; /* NMI oopser may have shut the console up */ + printk(" "); + console_loglevel = loglevel_save; } /* @@ -91,15 +68,20 @@ * and the problem, and then passes it off to one of the appropriate * routines. */ -asmlinkage void -do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address) +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, + unsigned long address) { struct vm_area_struct * vma; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; - unsigned long fixup; + const struct exception_table_entry *fixup; siginfo_t info; +#if 0 + printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), + current->comm, current->pid, address, write, regs->cp0_epc); +#endif + /* * We fault-in kernel-space virtual memory on-demand. The * 'reference' page table is init_mm.pgd. @@ -109,7 +91,7 @@ * only copy the information from the master page table, * nothing more. */ - if (address >= TASK_SIZE) + if (address >= VMALLOC_START) goto vmalloc_fault; info.si_code = SEGV_MAPERR; @@ -117,12 +99,9 @@ * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || mm == &init_mm) + if (in_atomic() || !mm) goto no_context; -#if DEBUG_MIPS64 - printk("Cpu%d[%s:%d:%08lx:%ld:%08lx]\n", smp_processor_id(), current->comm, - current->pid, address, write, regs->cp0_epc); -#endif + down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -148,22 +127,25 @@ goto bad_area; } +survive: /* * If for any reason at all we couldn't handle the fault, * make sure we exit gracefully rather than endlessly redo * the fault. */ switch (handle_mm_fault(mm, vma, address, write)) { - case 1: + case VM_FAULT_MINOR: tsk->min_flt++; break; - case 2: + case VM_FAULT_MAJOR: tsk->maj_flt++; break; - case 0: + case VM_FAULT_SIGBUS: goto do_sigbus; - default: + case VM_FAULT_OOM: goto out_of_memory; + default: + BUG(); } up_read(&mm->mmap_sem); @@ -176,7 +158,7 @@ bad_area: up_read(&mm->mmap_sem); -bad_area_nosemaphore: + /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { tsk->thread.cp0_badvaddr = address; tsk->thread.error_code = write; @@ -199,12 +181,11 @@ no_context: /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_table(regs->cp0_epc); + fixup = search_exception_tables(exception_epc(regs)); if (fixup) { - long new_epc; + unsigned long new_epc = fixup->nextinsn; tsk->thread.cp0_baduaddr = address; - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); if (development_version) printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", tsk->comm, regs->cp0_epc, new_epc); @@ -220,12 +201,9 @@ bust_spinlocks(1); printk(KERN_ALERT "Cpu %d Unable to handle kernel paging request at " - "address %08lx, epc == %08x, ra == %08x\n", - smp_processor_id(), address, (unsigned int) regs->cp0_epc, - (unsigned int) regs->regs[31]); - die("Oops", regs, write); - do_exit(SIGKILL); - bust_spinlocks(0); + "address %016lx, epc == %016lx, ra == %016lx\n", + smp_processor_id(), address, regs->cp0_epc, regs->regs[31]); + die("Oops", regs); /* * We ran out of memory, or some other thing happened to us that made @@ -233,6 +211,11 @@ */ out_of_memory: up_read(&mm->mmap_sem); + if (tsk->pid == 1) { + yield(); + down_read(&mm->mmap_sem); + goto survive; + } printk("VM: killing process %s\n", tsk->comm); if (user_mode(regs)) do_exit(SIGKILL); diff -Nru a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c --- a/arch/mips64/mm/init.c Fri Jun 27 14:19:59 2003 +++ b/arch/mips64/mm/init.c Fri Jun 27 14:19:59 2003 @@ -27,13 +27,12 @@ #include <asm/cachectl.h> #include <asm/dma.h> #include <asm/system.h> +#include <asm/sections.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> -#ifdef CONFIG_SGI_IP22 -#include <asm/sgialib.h> -#endif #include <asm/mmu_context.h> #include <asm/tlb.h> +#include <asm/cpu.h> DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -57,20 +56,6 @@ } } -pgd_t *get_pgd_slow(void) -{ - pgd_t *ret, *init; - - ret = (pgd_t *) __get_free_pages(GFP_KERNEL, 1); - if (ret) { - init = pgd_offset(&init_mm, 0); - pgd_init((unsigned long)ret); - memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - return ret; -} - void pmd_init(unsigned long addr, unsigned long pagetable) { unsigned long *p, *end; @@ -91,31 +76,6 @@ } } -int do_check_pgt_cache(int low, int high) -{ - int freed = 0; - - if (pgtable_cache_size > high) { - do { - if (pgd_quicklist) - free_pgd_slow(get_pgd_fast()), freed++; - if (pmd_quicklist) - free_pmd_slow(get_pmd_fast()), freed++; - if (pte_quicklist) - free_pte_slow(get_pte_fast()), freed++; - } while (pgtable_cache_size > low); - } - return freed; -} - - -asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) -{ - /* XXX Just get it working for now... */ - flush_cache_l1(); - return 0; -} - /* * We have up to 8 empty zeroed pages so we can map one of the right colour * when needed. This is necessary only on R4000 / R4400 SC and MC versions @@ -130,16 +90,10 @@ unsigned long order, size; struct page *page; - switch (mips_cputype) { - case CPU_R4000SC: - case CPU_R4000MC: - case CPU_R4400SC: - case CPU_R4400MC: + if (cpu_has_vce) order = 3; - break; - default: + else order = 0; - } empty_zero_page = __get_free_pages(GFP_KERNEL, order); if (!empty_zero_page) @@ -159,185 +113,6 @@ return 1UL << order; } -void __init add_memory_region(unsigned long start, unsigned long size, - long type) -{ - int x = boot_mem_map.nr_map; - - if (x == BOOT_MEM_MAP_MAX) { - printk("Ooops! Too many entries in the memory map!\n"); - return; - } - - boot_mem_map.map[x].addr = start; - boot_mem_map.map[x].size = size; - boot_mem_map.map[x].type = type; - boot_mem_map.nr_map++; -} - -static void __init print_memory_map(void) -{ - int i; - - for (i = 0; i < boot_mem_map.nr_map; i++) { - printk(" memory: %08lx @ %08lx ", - boot_mem_map.map[i].size, boot_mem_map.map[i].addr); - switch (boot_mem_map.map[i].type) { - case BOOT_MEM_RAM: - printk("(usable)\n"); - break; - case BOOT_MEM_ROM_DATA: - printk("(ROM data)\n"); - break; - case BOOT_MEM_RESERVED: - printk("(reserved)\n"); - break; - default: - printk("type %lu\n", boot_mem_map.map[i].type); - break; - } - } -} - -void bootmem_init(void) { -#ifdef CONFIG_BLK_DEV_INITRD - unsigned long tmp; - unsigned long *initrd_header; -#endif - unsigned long bootmap_size; - unsigned long start_pfn, max_pfn; - int i; - extern int _end; - -#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) - - /* - * Partially used pages are not usable - thus - * we are rounding upwards. - */ - start_pfn = PFN_UP(__pa(&_end)); - - /* Find the highest page frame number we have available. */ - max_pfn = 0; - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start, end; - - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) - continue; - - start = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); - - if (start >= end) - continue; - if (end > max_pfn) - max_pfn = end; - } - - /* Initialize the boot-time allocator. */ - bootmap_size = init_bootmem(start_pfn, max_pfn); - - /* - * Register fully available low RAM pages with the bootmem allocator. - */ - for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long curr_pfn, last_pfn, size; - - /* - * Reserve usable memory. - */ - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) - continue; - - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(boot_mem_map.map[i].addr); - if (curr_pfn >= max_pfn) - continue; - if (curr_pfn < start_pfn) - curr_pfn = start_pfn; - - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); - - if (last_pfn > max_pfn) - last_pfn = max_pfn; - - /* - * ... finally, did all the rounding and playing - * around just make the area go away? - */ - if (last_pfn <= curr_pfn) - continue; - - size = last_pfn - curr_pfn; - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); - } - - /* Reserve the bootmap memory. */ - reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); - -#ifdef CONFIG_BLK_DEV_INITRD -#error "Initrd is broken, please fit it." - tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; - if (tmp < (unsigned long)&_end) - tmp += PAGE_SIZE; - initrd_header = (unsigned long *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; - initrd_below_start_ok = 1; - if (initrd_end > memory_end) { - printk("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx)\ndisabling initrd\n", - initrd_end,memory_end); - initrd_start = 0; - } else - *memory_start_p = initrd_end; - } -#endif - -#undef PFN_UP -#undef PFN_DOWN -#undef PFN_PHYS - -} - -void show_mem(void) -{ - int i, free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0; - - printk("Mem-info:\n"); - show_free_areas(); - printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map+i)) - reserved++; - else if (PageSwapCache(mem_map+i)) - cached++; - else if (!page_count(mem_map + i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk("%d pages of RAM\n", total); - printk("%d reserved pages\n", reserved); - printk("%d pages shared\n", shared); - printk("%d pages swap cached\n",cached); - printk("%ld pages in page table cache\n", pgtable_cache_size); - printk("%d free pages\n", free); -} - #ifndef CONFIG_DISCONTIGMEM /* References to section boundaries */ @@ -361,7 +136,7 @@ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; -#if defined(CONFIG_PCI) || defined(CONFIG_ISA) +#ifdef CONFIG_ISA if (low < max_dma) zones_size[ZONE_DMA] = low; else { @@ -373,15 +148,38 @@ #endif free_area_init(zones_size); - - memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER); + + memset((void *)kptbl, 0, PAGE_SIZE << PGD_ORDER); memset((void *)kpmdtbl, 0, PAGE_SIZE); - pgd_set(swapper_pg_dir, kpmdtbl); - for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE) + set_pgd(swapper_pg_dir, __pgd(kpmdtbl)); + for (i = 0; i < (1 << PGD_ORDER); pmd++,i++,pte+=PTRS_PER_PTE) pmd_val(*pmd) = (unsigned long)pte; } -extern int page_is_ram(unsigned long pagenr); +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) + +static inline int page_is_ram(unsigned long pagenr) +{ + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long addr, end; + + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + /* not usable memory */ + continue; + + addr = PFN_UP(boot_mem_map.map[i].addr); + end = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + + if (pagenr >= addr && pagenr < end) + return 1; + } + + return 0; +} void __init mem_init(void) { @@ -402,12 +200,12 @@ reservedpages++; } - codesize = (unsigned long) &_etext - (unsigned long) &_stext; - datasize = (unsigned long) &_edata - (unsigned long) &_fdata; + codesize = (unsigned long) &_etext - (unsigned long) &_text; + datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " - "%ldk data, %ldk init)\n", + printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " + "%ldk reserved, %ldk data, %ldk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), ram << (PAGE_SHIFT-10), codesize >> 10, @@ -420,26 +218,30 @@ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + /* Switch from KSEG0 to XKPHYS addresses */ + start = (unsigned long)phys_to_virt(CPHYSADDR(start)); + end = (unsigned long)phys_to_virt(CPHYSADDR(end)); + if (start < end) + printk(KERN_INFO "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 -extern char __init_begin, __init_end; -extern void prom_free_prom_memory(void); +extern void prom_free_prom_memory(void) __init; -void -free_initmem(void) +void free_initmem(void) { unsigned long addr, page; prom_free_prom_memory(); - + addr = (unsigned long)(&__init_begin); while (addr < (unsigned long)&__init_end) { page = PAGE_OFFSET | CPHYSADDR(addr); @@ -449,6 +251,6 @@ totalram_pages++; addr += PAGE_SIZE; } - printk("Freeing unused kernel memory: %ldk freed\n", + printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", (&__init_end - &__init_begin) >> 10); } diff -Nru a/arch/mips64/mm/loadmmu.c b/arch/mips64/mm/loadmmu.c --- a/arch/mips64/mm/loadmmu.c Fri Jun 27 14:19:57 2003 +++ b/arch/mips64/mm/loadmmu.c Fri Jun 27 14:19:57 2003 @@ -4,101 +4,117 @@ * for more details. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ #include <linux/config.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/mm.h> +#include <linux/module.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> #include <asm/page.h> #include <asm/pgtable.h> #include <asm/system.h> -#include <asm/bootinfo.h> -#include <asm/sgialib.h> /* memory functions */ void (*_clear_page)(void * page); void (*_copy_page)(void * to, void * from); /* Cache operations. */ -void (*_flush_cache_mm)(struct mm_struct *mm); -void (*_flush_cache_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -void (*_flush_page_to_ram)(struct page * page); +void (*flush_cache_all)(void); +void (*__flush_cache_all)(void); +void (*flush_cache_mm)(struct mm_struct *mm); +void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, + unsigned long end); +void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page); +void (*flush_icache_range)(unsigned long start, unsigned long end); +void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); /* MIPS specific cache operations */ -void (*_flush_cache_sigtramp)(unsigned long addr); -void (*_flush_cache_l2)(void); -void (*_flush_cache_l1)(void); +void (*flush_cache_sigtramp)(unsigned long addr); +void (*flush_data_cache_page)(unsigned long addr); +void (*flush_icache_all)(void); +#ifdef CONFIG_NONCOHERENT_IO /* DMA cache operations. */ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); void (*_dma_cache_wback)(unsigned long start, unsigned long size); void (*_dma_cache_inv)(unsigned long start, unsigned long size); -/* TLB operations. */ -void (*_flush_tlb_all)(void); -void (*_flush_tlb_mm)(struct mm_struct *mm); -void (*_flush_tlb_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page); - -/* Miscellaneous. */ -void (*update_mmu_cache)(struct vm_area_struct * vma, - unsigned long address, pte_t pte); +EXPORT_SYMBOL(_dma_cache_wback_inv); +EXPORT_SYMBOL(_dma_cache_wback); +EXPORT_SYMBOL(_dma_cache_inv); -void (*_show_regs)(struct pt_regs *); +#endif /* CONFIG_NONCOHERENT_IO */ +extern void ld_mmu_r23000(void); extern void ld_mmu_r4xx0(void); +extern void ld_mmu_tx39(void); +extern void ld_mmu_r6000(void); +extern void ld_mmu_tfp(void); extern void ld_mmu_andes(void); +extern void ld_mmu_sb1(void); +extern void sb1_tlb_init(void); +extern void r3k_tlb_init(void); +extern void r4k_tlb_init(void); +extern void sb1_tlb_init(void); void __init load_mmu(void) { - switch(mips_cputype) { -#if defined (CONFIG_CPU_R4300) \ - || defined (CONFIG_CPU_R4X00) \ - || defined (CONFIG_CPU_R5000) \ - || defined (CONFIG_CPU_NEVADA) - case CPU_R4000PC: - case CPU_R4000SC: - case CPU_R4000MC: - case CPU_R4200: - case CPU_R4300: - case CPU_R4400PC: - case CPU_R4400SC: - case CPU_R4400MC: - case CPU_R4600: - case CPU_R4640: - case CPU_R4650: - case CPU_R4700: - case CPU_R5000: - case CPU_R5000A: - case CPU_NEVADA: - printk("Loading R4000 MMU routines.\n"); + if (cpu_has_4ktlb) { +#if defined(CONFIG_CPU_R4X00) || defined(CONFIG_CPU_VR41XX) || \ + defined(CONFIG_CPU_R4300) || defined(CONFIG_CPU_R5000) || \ + defined(CONFIG_CPU_NEVADA) || defined(CONFIG_CPU_R5432) || \ + defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) || defined(CONFIG_CPU_TX49XX) || \ + defined(CONFIG_CPU_RM7000) ld_mmu_r4xx0(); + r4k_tlb_init(); +#endif + } else switch (current_cpu_data.cputype) { +#ifdef CONFIG_CPU_R3000 + case CPU_R2000: + case CPU_R3000: + case CPU_R3000A: + case CPU_R3081E: + ld_mmu_r23000(); + r3k_tlb_init(); break; #endif - -#if defined (CONFIG_CPU_R10000) +#ifdef CONFIG_CPU_TX39XX + case CPU_TX3912: + case CPU_TX3922: + case CPU_TX3927: + ld_mmu_tx39(); + r3k_tlb_init(); + break; +#endif +#ifdef CONFIG_CPU_R10000 case CPU_R10000: - printk("Loading R10000 MMU routines.\n"); - ld_mmu_andes(); + case CPU_R12000: + ld_mmu_r4xx0(); + andes_tlb_init(); + break; +#endif +#ifdef CONFIG_CPU_SB1 + case CPU_SB1: + ld_mmu_sb1(); + sb1_tlb_init(); break; #endif + case CPU_R8000: + panic("R8000 is unsupported"); + break; + default: - /* XXX We need an generic routine in the MIPS port - * XXX to jabber stuff onto the screen on all machines - * XXX before the console is setup. The ARCS prom - * XXX routines look good for this, but only the SGI - * XXX code has a full library for that at this time. - */ - panic("Yeee, unsupported mmu/cache architecture or " - "wrong compiletime kernel configuration."); + panic("Yeee, unsupported mmu/cache architecture."); } } diff -Nru a/arch/mips64/mm/pg-r4k.c b/arch/mips64/mm/pg-r4k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/pg-r4k.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,708 @@ +/* + * 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) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 98, 99, 2000, 01, 02, 03 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/cacheops.h> +#include <asm/io.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/bootinfo.h> +#include <asm/mmu_context.h> +#include <asm/cpu.h> + +/* + * Zero an entire page. Basically a simple unrolled loop should do the + * job but we want more performance by saving memory bus bandwidth. We + * have five flavours of the routine available for: + * + * - 16byte cachelines and no second level cache + * - 32byte cachelines second level cache + * - a version which handles the buggy R4600 v1.x + * - a version which handles the buggy R4600 v2.0 + * - Finally a last version without fancy cache games for the SC and MC + * versions of R4000 and R4400. + */ + +void r4k_clear_page_d16(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + +void r4k_clear_page_d32(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + + +/* + * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the + * IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + */ +void r4k_clear_page_r4600_v1(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); +} + +/* + * And this one is for the R4600 V2.0 + */ +void r4k_clear_page_r4600_v2(void * page) +{ + unsigned int flags; + + local_irq_save(flags); + *(volatile unsigned int *)KSEG1; + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) + : "memory"); + local_irq_restore(flags); +} + +/* + * The next 4 versions are optimized for all possible scache configurations + * of the SC / MC versions of R4000 and R4400 ... + * + * Todo: For even better performance we should have a routine optimized for + * every legal combination of dcache / scache linesize. When I (Ralf) tried + * this the kernel crashed shortly after mounting the root filesystem. CPU + * bug? Weirdo cache instruction semantics? + */ +void r4k_clear_page_s16(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "cache\t%3,16(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "cache\t%3,-16(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s32(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "cache\t%3,-32(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s64(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +void r4k_clear_page_s128(void * page) +{ + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tcache\t%3,(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "sd\t$0,32(%0)\n\t" + "sd\t$0,40(%0)\n\t" + "sd\t$0,48(%0)\n\t" + "sd\t$0,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "sd\t$0,-64(%0)\n\t" + "sd\t$0,-56(%0)\n\t" + "sd\t$0,-48(%0)\n\t" + "sd\t$0,-40(%0)\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) + : "memory"); +} + +/* + * This version has been tuned on an Origin. For other machines the arguments + * of the pref instructin may have to be tuned differently. + */ +void andes_clear_page(void * page) +{ + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tmips4\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%2\n" + "1:\tpref 7,512(%0)\n\t" + "sd\t$0,(%0)\n\t" + "sd\t$0,8(%0)\n\t" + "sd\t$0,16(%0)\n\t" + "sd\t$0,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "sd\t$0,-32(%0)\n\t" + "sd\t$0,-24(%0)\n\t" + "sd\t$0,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + "sd\t$0,-8(%0)\n\t" + ".set\tpop" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE) + : "memory"); +} + + +/* + * This is still inefficient. We only can do better if we know the + * virtual address where the copy will be accessed. + */ + +void r4k_copy_page_d16(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "cache\t%7,16(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "cache\t%7,-16(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +void r4k_copy_page_d32(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +/* + * Again a special version for the R4600 V1.x + */ +void r4k_copy_page_r4600_v1(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); +} + +void r4k_copy_page_r4600_v2(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + unsigned int flags; + + local_irq_save(flags); + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tnop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_D)); + local_irq_restore(flags); +} + +/* + * These are for R4000SC / R4400MC + */ +void r4k_copy_page_s16(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "cache\t%7,16(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "cache\t%7,-16(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s32(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "cache\t%7,32(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s64(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%6\n" + "1:\tcache\t%7,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "ld\t%2,16(%1)\n\t" + "ld\t%3,24(%1)\n\t" + "sd\t%2,16(%0)\n\t" + "sd\t%3,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "ld\t%2,-16(%1)\n\t" + "ld\t%3,-8(%1)\n\t" + "sd\t%2,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%3,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) + :"0" (to), "1" (from), "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +void r4k_copy_page_s128(void * to, void * from) +{ + unsigned long dummy1, dummy2; + unsigned long reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tcache\t%9,(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "ld\t%4,16(%1)\n\t" + "ld\t%5,24(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "sd\t%4,16(%0)\n\t" + "sd\t%5,24(%0)\n\t" + "ld\t%2,32(%1)\n\t" + "ld\t%3,40(%1)\n\t" + "ld\t%4,48(%1)\n\t" + "ld\t%5,56(%1)\n\t" + "sd\t%2,32(%0)\n\t" + "sd\t%3,40(%0)\n\t" + "sd\t%4,48(%0)\n\t" + "sd\t%5,56(%0)\n\t" + "daddiu\t%0,128\n\t" + "daddiu\t%1,128\n\t" + "ld\t%2,-64(%1)\n\t" + "ld\t%3,-56(%1)\n\t" + "ld\t%4,-48(%1)\n\t" + "ld\t%5,-40(%1)\n\t" + "sd\t%2,-64(%0)\n\t" + "sd\t%3,-56(%0)\n\t" + "sd\t%4,-48(%0)\n\t" + "sd\t%5,-40(%0)\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "ld\t%4,-16(%1)\n\t" + "ld\t%5,-8(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "sd\t%4,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%5,-8(%0)\n\t" + ".set\tat\n\t" + ".set\treorder" + :"=r" (dummy1), "=r" (dummy2), + "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), + "I" (PAGE_SIZE), + "i" (Create_Dirty_Excl_SD)); +} + +/* + * This version has been tuned on an Origin. For other machines the arguments + * of the pref instructin may have to be tuned differently. + */ +void andes_copy_page(void * to, void * from) +{ + unsigned long dummy1, dummy2, reg1, reg2, reg3, reg4; + + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tmips4\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "daddiu\t$1,%0,%8\n" + "1:\tpref\t0,2*128(%1)\n\t" + "pref\t1,2*128(%0)\n\t" + "ld\t%2,(%1)\n\t" + "ld\t%3,8(%1)\n\t" + "ld\t%4,16(%1)\n\t" + "ld\t%5,24(%1)\n\t" + "sd\t%2,(%0)\n\t" + "sd\t%3,8(%0)\n\t" + "sd\t%4,16(%0)\n\t" + "sd\t%5,24(%0)\n\t" + "daddiu\t%0,64\n\t" + "daddiu\t%1,64\n\t" + "ld\t%2,-32(%1)\n\t" + "ld\t%3,-24(%1)\n\t" + "ld\t%4,-16(%1)\n\t" + "ld\t%5,-8(%1)\n\t" + "sd\t%2,-32(%0)\n\t" + "sd\t%3,-24(%0)\n\t" + "sd\t%4,-16(%0)\n\t" + "bne\t$1,%0,1b\n\t" + " sd\t%5,-8(%0)\n\t" + ".set\tpop\n\t" + :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2), + "=&r" (reg3), "=&r" (reg4) + :"0" (to), "1" (from), "I" (PAGE_SIZE)); +} diff -Nru a/arch/mips64/mm/pg-sb1.c b/arch/mips64/mm/pg-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/pg-sb1.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,131 @@ +/* + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2000 Sibyte + * + * Written by Justin Carlson (carlson@sibyte.com) + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <asm/page.h> + +#ifdef CONFIG_SB1_PASS_1_WORKAROUNDS +#define SB1_PREF_LOAD_STREAMED_HINT "0" +#define SB1_PREF_STORE_STREAMED_HINT "1" +#else +#define SB1_PREF_LOAD_STREAMED_HINT "4" +#define SB1_PREF_STORE_STREAMED_HINT "5" +#endif + +/* These are the functions hooked by the memory management function pointers */ +void sb1_clear_page(void *page) +{ + /* + * JDCXXX - This should be bottlenecked by the write buffer, but these + * things tend to be mildly unpredictable...should check this on the + * performance model + * + * We prefetch 4 lines ahead. We're also "cheating" slightly here... + * since we know we're on an SB1, we force the assembler to take + * 64-bit operands to speed things up + */ + __asm__ __volatile__( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " daddiu $1, %0, %2 \n" /* Calculate the end of the page to clear */ +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 4 lines */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%0) \n" +#endif + "1: sd $0, 0(%0) \n" /* Throw out a cacheline of 0's */ + " sd $0, 8(%0) \n" + " sd $0, 16(%0) \n" + " sd $0, 24(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_STORE_STREAMED_HINT ",128(%0) \n" /* Prefetch 4 lines ahead */ +#endif + " bne $1, %0, 1b \n" + " daddiu %0, %0, 32\n" /* Next cacheline (This instruction better be short piped!) */ + ".set pop \n" + : "=r" (page) + : "0" (page), "I" (PAGE_SIZE-32) + : "memory"); + +} + +void sb1_copy_page(void *to, void *from) +{ + /* + * This should be optimized in assembly...can't use ld/sd, though, + * because the top 32 bits could be nuked if we took an interrupt + * during the routine. And this is not a good place to be cli()'ing + * + * The pref's used here are using "streaming" hints, which cause the + * copied data to be kicked out of the cache sooner. A page copy often + * ends up copying a lot more data than is commonly used, so this seems + * to make sense in terms of reducing cache pollution, but I've no real + * performance data to back this up + */ + + __asm__ __volatile__( + ".set push \n" + ".set noreorder \n" + ".set noat \n" + ".set mips4 \n" + " daddiu $1, %0, %4 \n" /* Calculate the end of the page to copy */ +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 0(%0) \n" /* Prefetch the first 3 lines */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", 0(%1) \n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 32(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 32(%1) \n" + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 64(%0) \n" + " pref " SB1_PREF_STORE_STREAMED_HINT ", 64(%1) \n" +#endif + "1: lw $2, 0(%0) \n" /* Block copy a cacheline */ + " lw $3, 4(%0) \n" + " lw $4, 8(%0) \n" + " lw $5, 12(%0) \n" + " lw $6, 16(%0) \n" + " lw $7, 20(%0) \n" + " lw $8, 24(%0) \n" + " lw $9, 28(%0) \n" +#ifdef CONFIG_CPU_HAS_PREFETCH + " pref " SB1_PREF_LOAD_STREAMED_HINT ", 96(%0) \n" /* Prefetch ahead */ + " pref " SB1_PREF_STORE_STREAMED_HINT ", 96(%1) \n" +#endif + " sw $2, 0(%1) \n" + " sw $3, 4(%1) \n" + " sw $4, 8(%1) \n" + " sw $5, 12(%1) \n" + " sw $6, 16(%1) \n" + " sw $7, 20(%1) \n" + " sw $8, 24(%1) \n" + " sw $9, 28(%1) \n" + " daddiu %1, %1, 32 \n" /* Next cacheline */ + " nop \n" /* Force next add to short pipe */ + " nop \n" /* Force next add to short pipe */ + " bne $1, %0, 1b \n" + " daddiu %0, %0, 32 \n" /* Next cacheline */ + ".set pop \n" + : "=r" (to), "=r" (from) + : "0" (from), "1" (to), "I" (PAGE_SIZE-32) + : "$2","$3","$4","$5","$6","$7","$8","$9","memory"); +} diff -Nru a/arch/mips64/mm/pgtable.c b/arch/mips64/mm/pgtable.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/pgtable.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,33 @@ +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/swap.h> + +void show_mem(void) +{ + int pfn, total = 0, reserved = 0; + int shared = 0, cached = 0; + int highmem = 0; + struct page *page; + + printk("Mem-info:\n"); + show_free_areas(); + printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); + pfn = max_mapnr; + while (pfn-- > 0) { + page = pfn_to_page(pfn); + total++; + if (PageHighMem(page)) + highmem++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (page_count(page)) + shared += page_count(page) - 1; + } + printk("%d pages of RAM\n", total); + printk("%d pages of HIGHMEM\n",highmem); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); +} diff -Nru a/arch/mips64/mm/r4xx0.c b/arch/mips64/mm/r4xx0.c --- a/arch/mips64/mm/r4xx0.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2414 +0,0 @@ -/* - * 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. - * - * r4xx0.c: R4000 processor variant specific MMU/Cache routines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999, 2000, 2001 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/bcache.h> -#include <asm/io.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/bootinfo.h> -#include <asm/sgialib.h> -#include <asm/mmu_context.h> - -/* CP0 hazard avoidance. */ -#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ - "nop; nop; nop; nop; nop; nop;\n\t" \ - ".set reorder\n\t") - -/* Primary cache parameters. */ -static int icache_size, dcache_size; /* Size in bytes */ -static int ic_lsize, dc_lsize; /* LineSize in bytes */ - -/* Secondary cache (if present) parameters. */ -static unsigned int scache_size, sc_lsize; /* Again, in bytes */ - -#include <asm/r4kcacheops.h> -#include <asm/r4kcache.h> - -#undef DEBUG_CACHE - -/* - * Dummy cache handling routines for machines without boardcaches - */ -static void no_sc_noop(void) {} - -static struct bcache_ops no_sc_ops = { - (void *)no_sc_noop, (void *)no_sc_noop, - (void *)no_sc_noop, (void *)no_sc_noop -}; - -struct bcache_ops *bcops = &no_sc_ops; - -/* - * On processors with QED R4600 style two set assosicative cache - * this is the bit which selects the way in the cache for the - * indexed cachops. - */ -#define icache_waybit (icache_size >> 1) -#define dcache_waybit (dcache_size >> 1) - -/* - * Zero an entire page. Basically a simple unrolled loop should do the - * job but we want more performance by saving memory bus bandwidth. We - * have five flavours of the routine available for: - * - * - 16byte cachelines and no second level cache - * - 32byte cachelines second level cache - * - a version which handles the buggy R4600 v1.x - * - a version which handles the buggy R4600 v2.0 - * - Finally a last version without fancy cache games for the SC and MC - * versions of R4000 and R4400. - */ - -static void r4k_clear_page_d16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - :"$1", "memory"); -} - -static void r4k_clear_page_d32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - :"$1", "memory"); -} - - -/* - * This flavour of r4k_clear_page is for the R4600 V1.x. Cite from the - * IDT R4600 V1.7 errata: - * - * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, - * Hit_Invalidate_D and Create_Dirty_Excl_D should only be - * executed if there is no other dcache activity. If the dcache is - * accessed for another instruction immeidately preceding when these - * cache instructions are executing, it is possible that the dcache - * tag match outputs used by these cache instructions will be - * incorrect. These cache instructions should be preceded by at least - * four instructions that are not any kind of load or store - * instruction. - * - * This is not allowed: lw - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - * - * This is allowed: lw - * nop - * nop - * nop - * nop - * cache Hit_Writeback_Invalidate_D - */ -static void r4k_clear_page_r4600_v1(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D) - :"$1", "memory"); -} - -/* - * And this one is for the R4600 V2.0 - */ -static void r4k_clear_page_r4600_v2(void * page) -{ - unsigned int flags; - - local_irq_save(flags); - *(volatile unsigned int *)KSEG1; - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_D) - :"$1", "memory"); - local_irq_restore(flags); -} - -/* - * The next 4 versions are optimized for all possible scache configurations - * of the SC / MC versions of R4000 and R4400 ... - * - * Todo: For even better performance we should have a routine optimized for - * every legal combination of dcache / scache linesize. When I (Ralf) tried - * this the kernel crashed shortly after mounting the root filesystem. CPU - * bug? Weirdo cache instruction semantics? - */ -static void r4k_clear_page_s16(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "cache\t%3,16(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "cache\t%3,-16(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - -static void r4k_clear_page_s32(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "cache\t%3,-32(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), "I" (PAGE_SIZE), "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - -static void r4k_clear_page_s64(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD) - :"$1","memory"); -} - -static void r4k_clear_page_s128(void * page) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%2\n" - "1:\tcache\t%3,(%0)\n\t" - "sd\t$0,(%0)\n\t" - "sd\t$0,8(%0)\n\t" - "sd\t$0,16(%0)\n\t" - "sd\t$0,24(%0)\n\t" - "sd\t$0,32(%0)\n\t" - "sd\t$0,40(%0)\n\t" - "sd\t$0,48(%0)\n\t" - "sd\t$0,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "sd\t$0,-64(%0)\n\t" - "sd\t$0,-56(%0)\n\t" - "sd\t$0,-48(%0)\n\t" - "sd\t$0,-40(%0)\n\t" - "sd\t$0,-32(%0)\n\t" - "sd\t$0,-24(%0)\n\t" - "sd\t$0,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - "sd\t$0,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (page) - :"0" (page), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD) - :"$1", "memory"); -} - - -/* - * This is still inefficient. We only can do better if we know the - * virtual address where the copy will be accessed. - */ - -static void r4k_copy_page_d16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_d32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -/* - * Again a special version for the R4600 V1.x - */ -static void r4k_copy_page_r4600_v1(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); -} - -static void r4k_copy_page_r4600_v2(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - unsigned int flags; - - local_irq_save(flags); - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tnop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_D)); - local_irq_restore(flags); -} - -/* - * These are for R4000SC / R4400MC - */ -static void r4k_copy_page_s16(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "cache\t%7,16(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "cache\t%7,-16(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s32(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "cache\t%7,32(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s64(void * to, void * from) -{ - unsigned long dummy1, dummy2, reg1, reg2; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%6\n" - "1:\tcache\t%7,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "ld\t%2,16(%1)\n\t" - "ld\t%3,24(%1)\n\t" - "sd\t%2,16(%0)\n\t" - "sd\t%3,24(%0)\n\t" - "daddiu\t%0,64\n\t" - "daddiu\t%1,64\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "ld\t%2,-16(%1)\n\t" - "ld\t%3,-8(%1)\n\t" - "sd\t%2,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%3,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), "=&r" (reg1), "=&r" (reg2) - :"0" (to), "1" (from), "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - -static void r4k_copy_page_s128(void * to, void * from) -{ - unsigned long dummy1, dummy2; - unsigned long reg1, reg2, reg3, reg4; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "daddiu\t$1,%0,%8\n" - "1:\tcache\t%9,(%0)\n\t" - "ld\t%2,(%1)\n\t" - "ld\t%3,8(%1)\n\t" - "ld\t%4,16(%1)\n\t" - "ld\t%5,24(%1)\n\t" - "sd\t%2,(%0)\n\t" - "sd\t%3,8(%0)\n\t" - "sd\t%4,16(%0)\n\t" - "sd\t%5,24(%0)\n\t" - "ld\t%2,32(%1)\n\t" - "ld\t%3,40(%1)\n\t" - "ld\t%4,48(%1)\n\t" - "ld\t%5,56(%1)\n\t" - "sd\t%2,32(%0)\n\t" - "sd\t%3,40(%0)\n\t" - "sd\t%4,48(%0)\n\t" - "sd\t%5,56(%0)\n\t" - "daddiu\t%0,128\n\t" - "daddiu\t%1,128\n\t" - "ld\t%2,-64(%1)\n\t" - "ld\t%3,-56(%1)\n\t" - "ld\t%4,-48(%1)\n\t" - "ld\t%5,-40(%1)\n\t" - "sd\t%2,-64(%0)\n\t" - "sd\t%3,-56(%0)\n\t" - "sd\t%4,-48(%0)\n\t" - "sd\t%5,-40(%0)\n\t" - "ld\t%2,-32(%1)\n\t" - "ld\t%3,-24(%1)\n\t" - "ld\t%4,-16(%1)\n\t" - "ld\t%5,-8(%1)\n\t" - "sd\t%2,-32(%0)\n\t" - "sd\t%3,-24(%0)\n\t" - "sd\t%4,-16(%0)\n\t" - "bne\t$1,%0,1b\n\t" - " sd\t%5,-8(%0)\n\t" - ".set\tat\n\t" - ".set\treorder" - :"=r" (dummy1), "=r" (dummy2), - "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4) - :"0" (to), "1" (from), - "I" (PAGE_SIZE), - "i" (Create_Dirty_Excl_SD)); -} - - -/* - * If you think for one second that this stuff coming up is a lot - * of bulky code eating too many kernel cache lines. Think _again_. - * - * Consider: - * 1) Taken branches have a 3 cycle penalty on R4k - * 2) The branch itself is a real dead cycle on even R4600/R5000. - * 3) Only one of the following variants of each type is even used by - * the kernel based upon the cache parameters we detect at boot time. - * - * QED. - */ - -static inline void r4k_flush_cache_all_s16d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache16(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s32d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache32(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s64d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache64(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s128d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); blast_scache128(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s32d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); blast_scache32(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s64d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); blast_scache64(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_s128d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); blast_scache128(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_d16i16(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16(); blast_icache16(); - local_irq_restore(flags); -} - -static inline void r4k_flush_cache_all_d32i32(void) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32(); blast_icache32(); - local_irq_restore(flags); -} - -static void r4k_flush_cache_range_s16d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s16d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache16_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s32d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s32d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s64d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s64d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s128d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s128d16i16(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s32d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s32d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache32_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s64d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s64d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache64_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_s128d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) - return; - - start &= PAGE_MASK; -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - if (vma) { - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - r4k_flush_cache_all_s128d32i32(); - } else { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - - local_irq_save(flags); - while(start < end) { - pgd = pgd_offset(mm, start); - pmd = pmd_offset(pgd, start); - pte = pte_offset(pmd, start); - - if(pte_val(*pte) & _PAGE_VALID) - blast_scache128_page(start); - start += PAGE_SIZE; - } - local_irq_restore(flags); - } - } -} - -static void r4k_flush_cache_range_d16i16(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - local_irq_save(flags); - blast_dcache16(); blast_icache16(); - local_irq_restore(flags); - } -} - -static void r4k_flush_cache_range_d32i32(struct vm_area_struct *vma, - unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_CACHE - printk("crange[%d,%08lx,%08lx]", (int)mm->context, start, end); -#endif - local_irq_save(flags); - blast_dcache32(); blast_icache32(); - local_irq_restore(flags); - } -} - -/* - * On architectures like the Sparc, we could get rid of lines in - * the cache created only by a certain context, but on the MIPS - * (and actually certain Sparc's) we cannot. - */ -static void r4k_flush_cache_mm_s16d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s16d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d16i16(); - } -} - -static void r4k_flush_cache_mm_s64d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d16i16(); - } -} - -static void r4k_flush_cache_mm_s128d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d16i16(); - } -} - -static void r4k_flush_cache_mm_s32d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s32d32i32(); - } -} - -static void r4k_flush_cache_mm_s64d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s64d32i32(); - } -} - -static void r4k_flush_cache_mm_s128d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_s128d32i32(); - } -} - -static void r4k_flush_cache_mm_d16i16(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d16i16(); - } -} - -static void r4k_flush_cache_mm_d32i32(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { -#ifdef DEBUG_CACHE - printk("cmm[%d]", (int)mm->context); -#endif - r4k_flush_cache_all_d32i32(); - } -} - -static void r4k_flush_cache_page_s16d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache16_page_indexed(page); - } else - blast_scache16_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s32d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s64d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s128d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache16_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s32d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache32_page_indexed(page); - } else - blast_scache32_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s64d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache64_page_indexed(page); - } else - blast_scache64_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_s128d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) != - CPU_CONTEXT(smp_processor_id(), current->mm)) { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (scache_size - 1))); - blast_dcache32_page_indexed(page); - blast_scache128_page_indexed(page); - } else - blast_scache128_page(page); -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_d16i16(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_VALID)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if(mm == current->mm) { - blast_dcache16_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache16_page_indexed(page); - } -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_d32i32(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* - * Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - } -out: - local_irq_restore(flags); -} - -static void r4k_flush_cache_page_d32i32_r4600(struct vm_area_struct *vma, - unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (CPU_CONTEXT(smp_processor_id(), mm) == 0) - return; - -#ifdef DEBUG_CACHE - printk("cpage[%d,%08lx]", (int)mm->context, page); -#endif - local_irq_save(flags); - page &= PAGE_MASK; - pgdp = pgd_offset(mm, page); - pmdp = pmd_offset(pgdp, page); - ptep = pte_offset(pmdp, page); - - /* - * If the page isn't marked valid, the page cannot possibly be - * in the cache. - */ - if(!(pte_val(*ptep) & _PAGE_PRESENT)) - goto out; - - /* - * Doing flushes for another ASID than the current one is - * too difficult since stupid R4k caches do a TLB translation - * for every cache flush operation. So we do indexed flushes - * in that case, which doesn't overly flush the cache too much. - */ - if((mm == current->mm) && (pte_val(*ptep) & _PAGE_VALID)) { - blast_dcache32_page(page); - } else { - /* Do indexed flush, too much work to get the (possible) - * tlb refills to work correctly. - */ - page = (KSEG0 + (page & (dcache_size - 1))); - blast_dcache32_page_indexed(page); - blast_dcache32_page_indexed(page ^ dcache_waybit); - } -out: - local_irq_restore(flags); -} - -static void r4k_flush_page_to_ram_s16(struct page *page) -{ - blast_scache16_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s32(struct page *page) -{ - blast_scache32_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s64(struct page *page) -{ - blast_scache64_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_s128(struct page *page) -{ - blast_scache128_page((unsigned long)page_address(page)); -} - -static void r4k_flush_page_to_ram_d16(struct page *page) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache16_page((unsigned long)page_address(page)); - local_irq_restore(flags); -} - -static void r4k_flush_page_to_ram_d32(struct page *page) -{ - unsigned long flags; - - local_irq_save(flags); - blast_dcache32_page((unsigned long)page_address(page)); - local_irq_restore(flags); -} - -/* - * Writeback and invalidate the primary cache dcache before DMA. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -static void r4k_dma_cache_wback_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - flush_cache_l1(); - } else { - /* Workaround for R4600 bug. See comment above. */ - local_irq_save(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - local_irq_restore(flags); - } - bc_wback_inv(addr, size); -} - -static void r4k_dma_cache_wback_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= (unsigned long)scache_size) { - flush_cache_l1(); - return; - } - - a = addr & ~((unsigned long)sc_lsize - 1); - end = (addr + size) & ~((unsigned long)sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void r4k_dma_cache_inv_pc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - unsigned int flags; - - if (size >= (unsigned long)dcache_size) { - flush_cache_l1(); - } else { - /* Workaround for R4600 bug. See comment above. */ - local_irq_save(flags); - *(volatile unsigned long *)KSEG1; - - a = addr & ~((unsigned long)dc_lsize - 1); - end = (addr + size) & ~((unsigned long)dc_lsize - 1); - while (1) { - flush_dcache_line(a); /* Hit_Writeback_Inv_D */ - if (a == end) break; - a += dc_lsize; - } - local_irq_restore(flags); - } - - bc_inv(addr, size); -} - -static void r4k_dma_cache_inv_sc(unsigned long addr, unsigned long size) -{ - unsigned long end, a; - - if (size >= (unsigned long)scache_size) { - flush_cache_l1(); - return; - } - - a = addr & ~((unsigned long)sc_lsize - 1); - end = (addr + size) & ~((unsigned long)sc_lsize - 1); - while (1) { - flush_scache_line(a); /* Hit_Writeback_Inv_SD */ - if (a == end) break; - a += sc_lsize; - } -} - -static void r4k_dma_cache_wback(unsigned long addr, unsigned long size) -{ - panic("r4k_dma_cache called - should not happen.\n"); -} - -/* - * While we're protected against bad userland addresses we don't care - * very much about what happens in that case. Usually a segmentation - * fault will dump the process later on anyway ... - */ -static void r4k_flush_cache_sigtramp(unsigned long addr) -{ - __asm__ __volatile__("nop;nop;nop;nop"); /* R4600 V1.7 */ - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); -} - -static void r4600v20k_flush_cache_sigtramp(unsigned long addr) -{ - unsigned int flags; - - local_irq_save(flags); - - /* Clear internal cache refill buffer */ - *(volatile unsigned int *)KSEG1; - - protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - protected_flush_icache_line(addr & ~(ic_lsize - 1)); - - local_irq_restore(flags); -} - -#undef DEBUG_TLB - -#define NTLB_ENTRIES 48 /* Fixed on all R4XX0 variants... */ - -#define NTLB_ENTRIES_HALF 24 /* Fixed on all R4XX0 variants... */ - -static inline void r4k_flush_tlb_all(void) -{ - unsigned long flags; - unsigned long old_ctx; - int entry; - -#ifdef DEBUG_TLB - printk("[tlball]"); -#endif - - local_irq_save(flags); - /* Save old context and create impossible VPN2 value */ - old_ctx = (get_entryhi() & 0xff); - set_entryhi(KSEG0); - set_entrylo0(0); - set_entrylo1(0); - BARRIER; - - entry = get_wired(); - - /* Blast 'em all away. */ - while(entry < NTLB_ENTRIES) { - set_index(entry); - BARRIER; - tlb_write_indexed(); - BARRIER; - entry++; - } - BARRIER; - set_entryhi(old_ctx); - local_irq_restore(flags); -} - -static void r4k_flush_tlb_mm(struct mm_struct *mm) -{ - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - -#ifdef DEBUG_TLB - printk("[tlbmm<%d>]", mm->context); -#endif - local_irq_save(flags); - get_new_cpu_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - local_irq_restore(flags); - } -} - -static void r4k_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (CPU_CONTEXT(smp_processor_id(), mm) != 0) { - unsigned long flags; - int size; - -#ifdef DEBUG_TLB - printk("[tlbrange<%02x,%08lx,%08lx>]", (mm->context & 0xff), - start, end); -#endif - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - size = (size + 1) >> 1; - if(size <= NTLB_ENTRIES_HALF) { - int oldpid = (get_entryhi() & 0xff); - int newpid = (CPU_CONTEXT(smp_processor_id(), mm) & 0xff); - - start &= (PAGE_MASK << 1); - end += ((PAGE_SIZE << 1) - 1); - end &= (PAGE_MASK << 1); - while(start < end) { - int idx; - - set_entryhi(start | newpid); - start += (PAGE_SIZE << 1); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - BARRIER; - if(idx < 0) - continue; - tlb_write_indexed(); - BARRIER; - } - set_entryhi(oldpid); - } else { - get_new_cpu_mmu_context(mm, smp_processor_id()); - if(mm == current->mm) - set_entryhi(CPU_CONTEXT(smp_processor_id(), - mm) & 0xff); - } - local_irq_restore(flags); - } -} - -static void r4k_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) != 0) { - unsigned long flags; - int oldpid, newpid, idx; - -#ifdef DEBUG_TLB - printk("[tlbpage<%d,%08lx>]", vma->vm_mm->context, page); -#endif - newpid = (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff); - page &= (PAGE_MASK << 1); - local_irq_save(flags); - oldpid = (get_entryhi() & 0xff); - set_entryhi(page | newpid); - BARRIER; - tlb_probe(); - BARRIER; - idx = get_index(); - set_entrylo0(0); - set_entrylo1(0); - set_entryhi(KSEG0); - if(idx < 0) - goto finish; - BARRIER; - tlb_write_indexed(); - - finish: - BARRIER; - set_entryhi(oldpid); - local_irq_restore(flags); - } -} - -static void r4k_flush_cache_l2(void) -{ -} - -/* We will need multiple versions of update_mmu_cache(), one that just - * updates the TLB with the new pte(s), and another which also checks - * for the R4k "end of page" hardware bug and does the needy. - */ -static void r4k_update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx, pid; - - /* - * Handle debugger faulting in for debugee. - */ - if (current->active_mm != vma->vm_mm) - return; - - local_irq_save(flags); - pid = (get_entryhi() & 0xff); - -#ifdef DEBUG_TLB - if((pid != (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) & 0xff)) || - (CPU_CONTEXT(smp_processor_id(), vma->vm_mm) == 0)) { - printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d - tlbpid=%d\n", (int) (CPU_CONTEXT(smp_processor_id(), - vma->vm_mm) & 0xff), pid); - } -#endif - - address &= (PAGE_MASK << 1); - set_entryhi(address | (pid)); - pgdp = pgd_offset(vma->vm_mm, address); - BARRIER; - tlb_probe(); - BARRIER; - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - BARRIER; - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - set_entryhi(address | (pid)); - BARRIER; - if(idx < 0) { - tlb_write_random(); - } else { - tlb_write_indexed(); - } - BARRIER; - set_entryhi(pid); - BARRIER; - local_irq_restore(flags); -} - -#if 0 -static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ - unsigned long flags; - pgd_t *pgdp; - pmd_t *pmdp; - pte_t *ptep; - int idx; - - local_irq_save(flags); - address &= (PAGE_MASK << 1); - set_entryhi(address | (get_entryhi() & 0xff)); - pgdp = pgd_offset(vma->vm_mm, address); - tlb_probe(); - pmdp = pmd_offset(pgdp, address); - idx = get_index(); - ptep = pte_offset(pmdp, address); - set_entrylo0(pte_val(*ptep++) >> 6); - set_entrylo1(pte_val(*ptep) >> 6); - BARRIER; - if(idx < 0) - tlb_write_random(); - else - tlb_write_indexed(); - BARRIER; - local_irq_restore(flags); -} -#endif - -static void r4k_show_regs(struct pt_regs *regs) -{ - /* Saved main processor registers. */ - printk("$0 : %016lx %016lx %016lx %016lx\n", - 0UL, regs->regs[1], regs->regs[2], regs->regs[3]); - printk("$4 : %016lx %016lx %016lx %016lx\n", - regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - printk("$8 : %016lx %016lx %016lx %016lx\n", - regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]); - printk("$12 : %016lx %016lx %016lx %016lx\n", - regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]); - printk("$16 : %016lx %016lx %016lx %016lx\n", - regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]); - printk("$20 : %016lx %016lx %016lx %016lx\n", - regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]); - printk("$24 : %016lx %016lx\n", - regs->regs[24], regs->regs[25]); - printk("$28 : %016lx %016lx %016lx %016lx\n", - regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]); - printk("Hi : %016lx\n", regs->hi); - printk("Lo : %016lx\n", regs->lo); - - /* Saved cp0 registers. */ - printk("epc : %016lx %s\nbadvaddr: %016lx\n", - regs->cp0_epc, print_tainted(), regs->cp0_badvaddr); - printk("Status : %08x\nCause : %08x\n", - (unsigned int) regs->cp0_status, (unsigned int) regs->cp0_cause); -} - -/* Detect and size the various r4k caches. */ -static void __init probe_icache(unsigned long config) -{ - icache_size = 1 << (12 + ((config >> 9) & 7)); - ic_lsize = 16 << ((config >> 5) & 1); - - printk("Primary instruction cache %dkb, linesize %d bytes)\n", - icache_size >> 10, ic_lsize); -} - -static void __init probe_dcache(unsigned long config) -{ - dcache_size = 1 << (12 + ((config >> 6) & 7)); - dc_lsize = 16 << ((config >> 4) & 1); - - printk("Primary data cache %dkb, linesize %d bytes)\n", - dcache_size >> 10, dc_lsize); -} - - -/* If you even _breathe_ on this function, look at the gcc output - * and make sure it does not pop things on and off the stack for - * the cache sizing loop that executes in KSEG1 space or else - * you will crash and burn badly. You have been warned. - */ -static int __init probe_scache(unsigned long config) -{ - extern unsigned long stext; - unsigned long flags, addr, begin, end, pow2; - int tmp; - - tmp = ((config >> 17) & 1); - if(tmp) - return 0; - tmp = ((config >> 22) & 3); - switch(tmp) { - case 0: - sc_lsize = 16; - break; - case 1: - sc_lsize = 32; - break; - case 2: - sc_lsize = 64; - break; - case 3: - sc_lsize = 128; - break; - } - - begin = (unsigned long) &stext; - begin &= ~((4 * 1024 * 1024) - 1); - end = begin + (4 * 1024 * 1024); - - /* This is such a bitch, you'd think they would make it - * easy to do this. Away you daemons of stupidity! - */ - local_irq_save(flags); - - /* Fill each size-multiple cache line with a valid tag. */ - pow2 = (64 * 1024); - for(addr = begin; addr < end; addr = (begin + pow2)) { - unsigned long *p = (unsigned long *) addr; - __asm__ __volatile__("nop" : : "r" (*p)); /* whee... */ - pow2 <<= 1; - } - - /* Load first line with zero (therefore invalid) tag. */ - set_taglo(0); - set_taghi(0); - __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */ - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 8, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 9, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 11, (%0)\n\t" - ".set reorder\n\t" : : "r" (begin)); - - /* Now search for the wrap around point. */ - pow2 = (128 * 1024); - tmp = 0; - for(addr = (begin + (128 * 1024)); addr < (end); addr = (begin + pow2)) { - __asm__ __volatile__("\n\t.set noreorder\n\t" - "cache 7, (%0)\n\t" - ".set reorder\n\t" : : "r" (addr)); - __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ - if(!get_taglo()) - break; - pow2 <<= 1; - } - local_irq_restore(flags); - addr -= begin; - printk("Secondary cache sized at %dK linesize %d\n", - (int) (addr >> 10), sc_lsize); - scache_size = addr; - return 1; -} - -static void __init setup_noscache_funcs(void) -{ - unsigned int prid; - - switch(dc_lsize) { - case 16: - _clear_page = r4k_clear_page_d16; - _copy_page = r4k_copy_page_d16; - _flush_cache_l1 = r4k_flush_cache_all_d16i16; - _flush_cache_mm = r4k_flush_cache_mm_d16i16; - _flush_cache_range = r4k_flush_cache_range_d16i16; - _flush_cache_page = r4k_flush_cache_page_d16i16; - break; - case 32: - prid = read_32bit_cp0_register(CP0_PRID) & 0xfff0; - if (prid == 0x2010) { /* R4600 V1.7 */ - _clear_page = r4k_clear_page_r4600_v1; - _copy_page = r4k_copy_page_r4600_v1; - } else if (prid == 0x2020) { /* R4600 V2.0 */ - _clear_page = r4k_clear_page_r4600_v2; - _copy_page = r4k_copy_page_r4600_v2; - } else { - _clear_page = r4k_clear_page_d32; - _copy_page = r4k_copy_page_d32; - } - _flush_cache_l1 = r4k_flush_cache_all_d32i32; - _flush_cache_mm = r4k_flush_cache_mm_d32i32; - _flush_cache_range = r4k_flush_cache_range_d32i32; - _flush_cache_page = r4k_flush_cache_page_d32i32; - break; - } - - switch(ic_lsize) { - case 16: - _flush_page_to_ram = r4k_flush_page_to_ram_d16; - break; - case 32: - _flush_page_to_ram = r4k_flush_page_to_ram_d32; - break; - } - - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_pc; - _dma_cache_wback = r4k_dma_cache_wback; - _dma_cache_inv = r4k_dma_cache_inv_pc; -} - -static void __init setup_scache_funcs(void) -{ - switch(sc_lsize) { - case 16: - switch(dc_lsize) { - case 16: - _flush_cache_l1 = r4k_flush_cache_all_s16d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s16d16i16; - _flush_cache_range = r4k_flush_cache_range_s16d16i16; - _flush_cache_page = r4k_flush_cache_page_s16d16i16; - break; - case 32: - panic("Invalid cache configuration detected"); - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s16; - _clear_page = r4k_clear_page_s16; - _copy_page = r4k_copy_page_s16; - break; - case 32: - switch(dc_lsize) { - case 16: - _flush_cache_l1 = r4k_flush_cache_all_s32d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s32d16i16; - _flush_cache_range = r4k_flush_cache_range_s32d16i16; - _flush_cache_page = r4k_flush_cache_page_s32d16i16; - break; - case 32: - _flush_cache_l1 = r4k_flush_cache_all_s32d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s32d32i32; - _flush_cache_range = r4k_flush_cache_range_s32d32i32; - _flush_cache_page = r4k_flush_cache_page_s32d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s32; - _clear_page = r4k_clear_page_s32; - _copy_page = r4k_copy_page_s32; - break; - case 64: - switch(dc_lsize) { - case 16: - _flush_cache_l1 = r4k_flush_cache_all_s64d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s64d16i16; - _flush_cache_range = r4k_flush_cache_range_s64d16i16; - _flush_cache_page = r4k_flush_cache_page_s64d16i16; - break; - case 32: - _flush_cache_l1 = r4k_flush_cache_all_s64d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s64d32i32; - _flush_cache_range = r4k_flush_cache_range_s64d32i32; - _flush_cache_page = r4k_flush_cache_page_s64d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s64; - _clear_page = r4k_clear_page_s64; - _copy_page = r4k_copy_page_s64; - break; - case 128: - switch(dc_lsize) { - case 16: - _flush_cache_l1 = r4k_flush_cache_all_s128d16i16; - _flush_cache_mm = r4k_flush_cache_mm_s128d16i16; - _flush_cache_range = r4k_flush_cache_range_s128d16i16; - _flush_cache_page = r4k_flush_cache_page_s128d16i16; - break; - case 32: - _flush_cache_l1 = r4k_flush_cache_all_s128d32i32; - _flush_cache_mm = r4k_flush_cache_mm_s128d32i32; - _flush_cache_range = r4k_flush_cache_range_s128d32i32; - _flush_cache_page = r4k_flush_cache_page_s128d32i32; - break; - }; - _flush_page_to_ram = r4k_flush_page_to_ram_s128; - _clear_page = r4k_clear_page_s128; - _copy_page = r4k_copy_page_s128; - break; - } - _dma_cache_wback_inv = r4k_dma_cache_wback_inv_sc; - _dma_cache_wback = r4k_dma_cache_wback; - _dma_cache_inv = r4k_dma_cache_inv_sc; -} - -typedef int (*probe_func_t)(unsigned long); - -static inline void __init setup_scache(unsigned int config) -{ - probe_func_t probe_scache_kseg1; - int sc_present = 0; - - /* Maybe the cpu knows about a l2 cache? */ - probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache)); - sc_present = probe_scache_kseg1(config); - - if (sc_present) { - setup_scache_funcs(); - return; - } - - setup_noscache_funcs(); -} - -void __init ld_mmu_r4xx0(void) -{ - unsigned long config = read_32bit_cp0_register(CP0_CONFIG); - - printk("CPU revision is: %08x\n", read_32bit_cp0_register(CP0_PRID)); - -#ifdef CONFIG_MIPS_UNCACHED - set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); -#else - set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); -#endif /* UNCACHED */ - - probe_icache(config); - probe_dcache(config); - setup_scache(config); - - switch(mips_cputype) { - case CPU_R4600: /* QED style two way caches? */ - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - _flush_cache_page = r4k_flush_cache_page_d32i32_r4600; - } - - _flush_cache_sigtramp = r4k_flush_cache_sigtramp; - if ((read_32bit_cp0_register(CP0_PRID) & 0xfff0) == 0x2020) { - _flush_cache_sigtramp = r4600v20k_flush_cache_sigtramp; - } - - _flush_tlb_all = r4k_flush_tlb_all; - _flush_tlb_mm = r4k_flush_tlb_mm; - _flush_tlb_range = r4k_flush_tlb_range; - _flush_tlb_page = r4k_flush_tlb_page; - _flush_cache_l2 = r4k_flush_cache_l2; - - update_mmu_cache = r4k_update_mmu_cache; - - _show_regs = r4k_show_regs; - - flush_cache_l1(); - - /* - * You should never change this register: - * - On R4600 1.7 the tlbp never hits for pages smaller than - * the value in the c0_pagemask register. - * - The entire mm handling assumes the c0_pagemask register to - * be set for 4kb pages. - */ - write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); - _flush_tlb_all(); -} diff -Nru a/arch/mips64/mm/sc-ip22.c b/arch/mips64/mm/sc-ip22.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/sc-ip22.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,177 @@ +/* + * sc-ip22.c: Indy cache management functions. + * + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/bcache.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/bootinfo.h> +#include <asm/sgi/ip22.h> +#include <asm/sgi/mc.h> + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#undef DEBUG_CACHE + +#define SC_SIZE 0x00080000 +#define SC_LINE 32 +#define CI_MASK (SC_SIZE - SC_LINE) +#define SC_INDEX(n) ((n) & CI_MASK) + +static inline void indy_sc_wipe(unsigned long first, unsigned long last) +{ + unsigned long tmp; + + __asm__ __volatile__( + ".set\tpush\t\t\t# indy_sc_wipe\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n\t" + "mfc0\t%2, $12\n\t" + "li\t$1, 0x80\t\t\t# Go 64 bit\n\t" + "mtc0\t$1, $12\n\t" + + "dli\t$1, 0x9000000080000000\n\t" + "or\t%0, $1\t\t\t# first line to flush\n\t" + "or\t%1, $1\t\t\t# last line to flush\n\t" + ".set\tat\n\t" + + "1:\tsw\t$0, 0(%0)\n\t" + "bne\t%0, %1, 1b\n\t" + " daddu\t%0, 32\n\t" + + "mtc0\t%2, $12\t\t\t# Back to 32 bit\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (first), "=r" (last), "=&r" (tmp) + : "0" (first), "1" (last)); +} + +static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) +{ + unsigned long first_line, last_line; + unsigned int flags; + +#ifdef DEBUG_CACHE + printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); +#endif + + if (!size) + return; + + /* Which lines to flush? */ + first_line = SC_INDEX(addr); + last_line = SC_INDEX(addr + size - 1); + + local_irq_save(flags); + if (first_line <= last_line) { + indy_sc_wipe(first_line, last_line); + goto out; + } + + indy_sc_wipe(first_line, SC_SIZE - SC_LINE); + indy_sc_wipe(0, last_line); +out: + local_irq_restore(flags); +} + +static void indy_sc_enable(void) +{ + unsigned long addr, tmp1, tmp2; + + /* This is really cool... */ +#ifdef DEBUG_CACHE + printk("Enabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop;\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "sb\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop;\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop;\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (addr)); +} + +static void indy_sc_disable(void) +{ + unsigned long tmp1, tmp2, tmp3; + +#ifdef DEBUG_CACHE + printk("Disabling R4600 SCACHE\n"); +#endif + __asm__ __volatile__( + ".set\tpush\n\t" + ".set\tnoreorder\n\t" + ".set\tmips3\n\t" + "li\t%0, 0x1\n\t" + "dsll\t%0, 31\n\t" + "lui\t%1, 0x9000\n\t" + "dsll32\t%1, 0\n\t" + "or\t%0, %1, %0\n\t" + "mfc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + "li\t%1, 0x80\n\t" + "mtc0\t%1, $12\n\t" + "nop; nop; nop; nop\n\t" + "sh\t$0, 0(%0)\n\t" + "mtc0\t$0, $12\n\t" + "nop; nop; nop; nop\n\t" + "mtc0\t%2, $12\n\t" + "nop; nop; nop; nop\n\t" + ".set\tpop" + : "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)); +} + +static inline int __init indy_sc_probe(void) +{ + unsigned int size = ip22_eeprom_read(&sgimc->eeprom, 17); + if (size == 0) + return 0; + + size <<= PAGE_SHIFT; + printk(KERN_INFO "R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", + size >> 10); + scache_size = size; + + return 1; +} + +/* XXX Check with wje if the Indy caches can differenciate between + writeback + invalidate and just invalidate. */ +struct bcache_ops indy_sc_ops = { + .bc_enable = indy_sc_enable, + .bc_disable = indy_sc_disable, + .bc_wback_inv = indy_sc_wback_invalidate, + .bc_inv = indy_sc_wback_invalidate +}; + +void __init indy_sc_init(void) +{ + if (indy_sc_probe()) { + indy_sc_enable(); + bcops = &indy_sc_ops; + } +} diff -Nru a/arch/mips64/mm/sc-r5k.c b/arch/mips64/mm/sc-r5k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/sc-r5k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,115 @@ +/* + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org), + * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/mipsregs.h> +#include <asm/bcache.h> +#include <asm/cacheops.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/mmu_context.h> + +/* Secondary cache size in bytes, if present. */ +static unsigned long scache_size; + +#define SC_LINE 32 +#define SC_PAGE (128*SC_LINE) + +#define cache_op(base,op) \ +__asm__ __volatile__(" \ + .set noreorder; \ + .set mips3; \ + cache %1, (%0); \ + .set mips0; \ + .set reorder" \ + : \ + : "r" (base), \ + "i" (op)); + +static inline void blast_r5000_scache(void) +{ + unsigned long start = KSEG0; + unsigned long end = KSEG0 + scache_size; + + while(start < end) { + cache_op(start, R5K_Page_Invalidate_S); + start += SC_PAGE; + } +} + +static void r5k_dma_cache_inv_sc(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + + if (size >= scache_size) { + blast_r5000_scache(); + return; + } + + /* On the R5000 secondary cache we cannot + * invalidate less than a page at a time. + * The secondary cache is physically indexed, write-through. + */ + a = addr & ~(SC_PAGE - 1); + end = (addr + size - 1) & ~(SC_PAGE - 1); + while (a <= end) { + cache_op(a, R5K_Page_Invalidate_S); + a += SC_PAGE; + } +} + +static void r5k_sc_enable(void) +{ + unsigned long flags; + + local_irq_save(flags); + change_c0_config(R5K_CONF_SE, R5K_CONF_SE); + blast_r5000_scache(); + local_irq_restore(flags); +} + +static void r5k_sc_disable(void) +{ + unsigned long flags; + + local_irq_save(flags); + blast_r5000_scache(); + change_c0_config(R5K_CONF_SE, 0); + local_irq_restore(flags); +} + +static inline int __init r5k_sc_probe(void) +{ + unsigned long config = read_c0_config(); + + if (config & CONF_SC) + return(0); + + scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); + + printk("R5000 SCACHE size %ldkB, linesize 32 bytes.\n", + scache_size >> 10); + + return 1; +} + +static struct bcache_ops r5k_sc_ops = { + .bc_enable = r5k_sc_enable, + .bc_disable = r5k_sc_disable, + .bc_wback_inv = r5k_dma_cache_inv_sc, + .bc_inv = r5k_dma_cache_inv_sc +}; + +void __init r5k_sc_init(void) +{ + if (r5k_sc_probe()) { + r5k_sc_enable(); + bcops = &r5k_sc_ops; + } +} diff -Nru a/arch/mips64/mm/sc-rm7k.c b/arch/mips64/mm/sc-rm7k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/sc-rm7k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,191 @@ +/* + * sc-rm7k.c: RM7000 cache management functions. + * + * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org), + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/mm.h> + +#include <asm/addrspace.h> +#include <asm/bcache.h> +#include <asm/cacheops.h> +#include <asm/mipsregs.h> +#include <asm/processor.h> + +/* Primary cache parameters. */ +#define sc_lsize 32 +#define tc_pagesize (32*128) + +/* Secondary cache parameters. */ +#define scache_size (256*1024) /* Fixed to 256KiB on RM7000 */ + +extern unsigned long icache_way_size, dcache_way_size; + +#include <asm/r4kcache.h> + +int rm7k_tcache_enabled; + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * (XXX These need to be fixed ...) + */ +static void rm7k_sc_wback_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + flush_scache_line(a); /* Hit_Writeback_Inv_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +static void rm7k_sc_inv(unsigned long addr, unsigned long size) +{ + unsigned long end, a; + +#ifdef DEBUG_CACHE + printk("rm7k_sc_inv[%08lx,%08lx]", addr, size); +#endif + + a = addr & ~(sc_lsize - 1); + end = (addr + size - 1) & ~(sc_lsize - 1); + while (1) { + invalidate_scache_line(a); /* Hit_Invalidate_SD */ + if (a == end) + break; + a += sc_lsize; + } + + if (!rm7k_tcache_enabled) + return; + + a = addr & ~(tc_pagesize - 1); + end = (addr + size - 1) & ~(tc_pagesize - 1); + while(1) { + invalidate_tcache_page(a); /* Page_Invalidate_T */ + if (a == end) + break; + a += tc_pagesize; + } +} + +/* + * This function is executed in the uncached segment KSEG1. + * It must not touch the stack, because the stack pointer still points + * into KSEG0. + * + * Three options: + * - Write it in assembly and guarantee that we don't use the stack. + * - Disable caching for KSEG0 before calling it. + * - Pray that GCC doesn't randomly start using the stack. + * + * This being Linux, we obviously take the least sane of those options - + * following DaveM's lead in c-r4k.c + * + * It seems we get our kicks from relying on unguaranteed behaviour in GCC + */ +static __init void rm7k_sc_enable(void) +{ + int i; + + set_c0_config(1<<3); /* CONF_SE */ + + write_c0_taglo(0); + write_c0_taghi(0); + + for (i=0; i<scache_size; i+=sc_lsize) { + __asm__ __volatile__ ( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (KSEG0ADDR(i)), + "i" (Index_Store_Tag_SD)); + } +} + +static void rm7k_sc_disable(void) +{ + set_c0_config(1<<3); /* CONF_SE */ +} + +static inline int __init rm7k_sc_probe(void) +{ + void (*func)(void) = KSEG1ADDR(&rm7k_sc_enable); + unsigned int config = read_c0_config(); + + if ((config >> 31) & 1) + return 0; + + printk(KERN_INFO "Secondary cache size %ldK, linesize 32 bytes.\n", + (scache_size >> 10), sc_lsize); + + if ((config >> 3) & 1) + return; + + printk(KERN_INFO "Enabling secondary cache..."); + func(); + printk(" done\n"); + + /* + * While we're at it let's deal with the tertiary cache. + */ + if ((config >> 17) & 1) + return 1; + + /* + * We can't enable the L3 cache yet. There may be board-specific + * magic necessary to turn it on, and blindly asking the CPU to + * start using it would may give cache errors. + * + * Also, board-specific knowledge may allow us to use the + * CACHE Flash_Invalidate_T instruction if the tag RAM supports + * it, and may specify the size of the L3 cache so we don't have + * to probe it. + */ + printk(KERN_INFO "Tertiary cache present, %s enabled\n", + config&(1<<12) ? "already" : "not (yet)"); + + if ((config >> 12) & 1) + rm7k_tcache_enabled = 1; + + return 1; +} + +struct bcache_ops rm7k_sc_ops = { + .bc_enable = rm7k_sc_enable, + .bc_disable = rm7k_sc_disable, + .bc_wback_inv = rm7k_sc_wback_inv, + .bc_inv = rm7k_sc_inv +}; + +void __init rm7k_sc_init(void) +{ + if (rm7k_sc_probe()) { + rm7k_sc_enable(); + bcops = &rm7k_sc_ops; + } +} diff -Nru a/arch/mips64/mm/tlb-andes.c b/arch/mips64/mm/tlb-andes.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlb-andes.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,257 @@ +/* + * 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) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 2000 Kanoj Sarcar (kanoj@sgi.com) + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/system.h> +#include <asm/mmu_context.h> + +extern void except_vec1_r10k(void); + +#define NTLB_ENTRIES 64 +#define NTLB_ENTRIES_HALF 32 + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + unsigned long entry; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(CKSEG0); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + + entry = read_c0_wired(); + + /* Blast 'em all away. */ + while (entry < NTLB_ENTRIES) { + write_c0_index(entry); + tlb_write_indexed(); + entry++; + } + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm,cpu); + } +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { + unsigned long flags; + int size; + + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= NTLB_ENTRIES_HALF) { + int oldpid = (read_c0_entryhi() & ASID_MASK); + int newpid = (cpu_context(smp_processor_id(), mm) + & ASID_MASK); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while(start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0); + if(idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + local_irq_restore(flags); + } +} + +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + local_irq_save(flags); + if (size <= NTLB_ENTRIES_HALF) { + int pid = read_c0_entryhi(); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + + while (start < end) { + int idx; + + write_c0_entryhi(start); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(pid); + } else { + local_flush_tlb_all(); + } + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + if (cpu_context(smp_processor_id(), vma->vm_mm) != 0) { + unsigned long flags; + int oldpid, newpid, idx; + + newpid = (cpu_context(smp_processor_id(), vma->vm_mm) & + ASID_MASK); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = (read_c0_entryhi() & ASID_MASK); + write_c0_entryhi(page | newpid); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0); + if (idx < 0) + goto finish; + tlb_write_indexed(); + + finish: + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +} + +/* + * This one is only used for pages with the global bit set so we don't care + * much about the ASID. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + local_irq_save(flags); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + + local_irq_restore(flags); +} + +/* XXX Simplify this. On the R10000 writing a TLB entry for an virtual + address that already exists will overwrite the old entry and not result + in TLB malfunction or TLB shutdown. */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + + if ((pid != (cpu_context(smp_processor_id(), vma->vm_mm) & ASID_MASK)) + || (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) { + printk(KERN_WARNING + "%s: Wheee, bogus tlbpid mmpid=%d tlbpid=%d\n", + __FUNCTION__, (int) (cpu_context(smp_processor_id(), + vma->vm_mm) & ASID_MASK), pid); + } + + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (pid)); + pgdp = pgd_offset(vma->vm_mm, address); + tlb_probe(); + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset_map(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | (pid)); + if (idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + write_c0_entryhi(pid); + local_irq_restore(flags); +} + +void __init andes_tlb_init(void) +{ + /* + * You should never change this register: + * - On R4600 1.7 the tlbp never hits for pages smaller than + * the value in the c0_pagemask register. + * - The entire mm handling assumes the c0_pagemask register to + * be set for 4kb pages. + */ + write_c0_pagemask(PM_4K); + write_c0_wired(0); + write_c0_framemask(0); + + /* From this point on the ARC firmware is dead. */ + local_flush_tlb_all(); + + /* Did I tell you that ARC SUCKS? */ + + memcpy((void *)KSEG1 + 0x080, except_vec1_r10k, 0x80); +} diff -Nru a/arch/mips64/mm/tlb-dbg-r4k.c b/arch/mips64/mm/tlb-dbg-r4k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlb-dbg-r4k.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,71 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + * + * TLB debugging routines. These perform horribly slow but can easily be + * modified for debugging purposes. + */ +#include <linux/linkage.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/ptrace.h> +#include <asm/system.h> + +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, + unsigned long address); + +asmlinkage void tlb_refill_debug(struct pt_regs regs) +{ + show_regs(®s); + panic(__FUNCTION__ " called. This Does Not Happen (TM)."); +} + +asmlinkage void xtlb_refill_debug(struct pt_regs *regs) +{ + unsigned long addr; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + addr = regs->cp0_badvaddr & ~((PAGE_SIZE << 1) - 1); + pgd = pgd_offset(current->active_mm, addr); + pmd = pmd_offset(pgd, addr); + pte = pte_offset(pmd, addr); + + write_c0_entrylo0(pte_val(pte[0]) >> 6); + write_c0_entrylo1(pte_val(pte[1]) >> 6); + __asm__ __volatile__("nop;nop;nop"); + + tlb_write_random(); +} + +asmlinkage void xtlb_mod_debug(struct pt_regs *regs) +{ + unsigned long addr; + + addr = regs->cp0_badvaddr; + do_page_fault(regs, 1, addr); +} + +asmlinkage void xtlb_tlbl_debug(struct pt_regs *regs) +{ + unsigned long addr; + + addr = regs->cp0_badvaddr; + do_page_fault(regs, 0, addr); +} + +asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs) +{ + unsigned long addr; + + addr = regs->cp0_badvaddr; + do_page_fault(regs, 1, addr); +} diff -Nru a/arch/mips64/mm/tlb-glue-r4k.S b/arch/mips64/mm/tlb-glue-r4k.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlb-glue-r4k.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,41 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include <linux/init.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 + tlb_handler xtlb_tlbl kmode 0 + tlb_handler xtlb_tlbs kmode 1 diff -Nru a/arch/mips64/mm/tlb-glue-sb1.S b/arch/mips64/mm/tlb-glue-sb1.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlb-glue-sb1.S Fri Jun 27 14:20:07 2003 @@ -0,0 +1,66 @@ +/* + * 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) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include <linux/init.h> +#include <asm/mipsregs.h> +#include <asm/page.h> +#include <asm/regdef.h> +#include <asm/stackframe.h> +#include <asm/war.h> + + .macro __BUILD_cli + CLI + .endm + + .macro __BUILD_sti + STI + .endm + + .macro __BUILD_kmode + KMODE + .endm + + .macro tlb_handler name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault + j ret_from_exception + END(__\name) + .endm + + .macro tlb_handler_m3 name interruptible writebit + NESTED(__\name, PT_SIZE, sp) + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT + 1 + bnez k0, 1f + SAVE_ALL + dmfc0 a2, CP0_BADVADDR + __BUILD_\interruptible + li a1, \writebit + sd a2, PT_BVADDR(sp) + move a0, sp + jal do_page_fault +1: + j ret_from_exception + END(__\name) + .endm + + tlb_handler xtlb_mod kmode 1 +#if BCM1250_M3_WAR + tlb_handler_m3 xtlb_tlbl kmode 0 +#else + tlb_handler xtlb_tlbl kmode 0 +#endif + tlb_handler xtlb_tlbs kmode 1 diff -Nru a/arch/mips64/mm/tlb-r4k.c b/arch/mips64/mm/tlb-r4k.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlb-r4k.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,415 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * MIPS64 CPU variant specific MMU routines. + * These routine are not optimized in any way, they are done in a generic way + * so they can be used on all MIPS64 compliant CPUs, and also done in an + * attempt not to break anything for the R4xx0 style CPUs. + */ +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/mm.h> + +#include <asm/cpu.h> +#include <asm/bootinfo.h> +#include <asm/mmu_context.h> +#include <asm/pgtable.h> +#include <asm/system.h> + +#undef DEBUG_TLB +#undef DEBUG_TLBUPDATE + +extern void except_vec1_r4k(void); + +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + +#ifdef DEBUG_TLB + printk("[tlball]"); +#endif + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(XKPHYS); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + BARRIER; + + entry = read_c0_wired(); + + /* Blast 'em all away. */ + while(entry < current_cpu_data.tlbsize) { + /* Make sure all entries differ. */ + write_c0_entryhi(XKPHYS+entry*0x2000); + write_c0_index(entry); + BARRIER; + tlb_write_indexed(); + BARRIER; + entry++; + } + BARRIER; + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { +#ifdef DEBUG_TLB + printk("[tlbmm<%d>]", cpu_context(cpu, mm)); +#endif + drop_mmu_context(mm,cpu); + } +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + int cpu = smp_processor_id(); + + if (cpu_context(cpu, mm) != 0) { + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbrange<%02x,%08lx,%08lx>]", cpu_context(cpu, mm) & ASID_MASK, + start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if(size <= current_cpu_data.tlbsize/2) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while (start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if(idx < 0) + continue; + /* Make sure all entries differ. */ + write_c0_entryhi(XKPHYS+idx*0x2000); + BARRIER; + tlb_write_indexed(); + BARRIER; + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + local_irq_restore(flags); + } +} + +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + +#ifdef DEBUG_TLB + printk("[tlbkernelrange<%08lx,%08lx>]", start, end); +#endif + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= current_cpu_data.tlbsize/2) { + int pid = read_c0_entryhi(); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + + while (start < end) { + int idx; + + write_c0_entryhi(start); + start += (PAGE_SIZE << 1); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx < 0) + continue; + /* Make sure all entries differ. */ + write_c0_entryhi(XKPHYS+idx*0x2000); + BARRIER; + tlb_write_indexed(); + BARRIER; + } + write_c0_entryhi(pid); + } else { + local_flush_tlb_all(); + } + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) { + unsigned long flags; + unsigned long oldpid, newpid, idx; + +#ifdef DEBUG_TLB + printk("[tlbpage<%d,%08lx>]", cpu_asid(cpu, vma->vm_mm), page); +#endif + newpid = cpu_asid(cpu, vma->vm_mm); + page &= (PAGE_MASK << 1); + local_irq_save(flags); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if(idx < 0) + goto finish; + /* Make sure all entries differ. */ + write_c0_entryhi(XKPHYS+idx*0x2000); + BARRIER; + tlb_write_indexed(); + finish: + BARRIER; + write_c0_entryhi(oldpid); + local_irq_restore(flags); + } +} + +/* + * This one is only used for pages with the global bit set so we don't care + * much about the ASID. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + local_irq_save(flags); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi(page); + BARRIER; + tlb_probe(); + BARRIER; + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + BARRIER; + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(oldpid); + + local_irq_restore(flags); +} + +/* + * Updates the TLB with the new pte(s). + */ +void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + pid = read_c0_entryhi() & ASID_MASK; + +#ifdef DEBUG_TLB + if ((pid != cpu_asid(smp_processor_id(), vma->vm_mm))) || + (cpu_context(smp_processor_id(), vma->vm_mm) == 0)) { + printk("update_mmu_cache: Wheee, bogus tlbpid mmpid=%d " + "tlbpid=%d\n", (int) cpu_asid(smp_processor_id(), + vma->vm_mm), pid); + } +#endif + + local_irq_save(flags); + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (pid)); + pgdp = pgd_offset(vma->vm_mm, address); + BARRIER; + tlb_probe(); + BARRIER; + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset_map(pmdp, address); + BARRIER; + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + write_c0_entryhi(address | (pid)); + BARRIER; + if(idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + BARRIER; + write_c0_entryhi(pid); + BARRIER; + local_irq_restore(flags); +} + +void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + write_c0_wired(wired + 1); + write_c0_index(wired); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); + local_flush_tlb_all(); + local_irq_restore(flags); +} + +/* + * Used for loading TLB entries before trap_init() has started, when we + * don't actually want to add a wired entry which remains throughout the + * lifetime of the system + */ + +static int temp_tlb_entry __initdata; + +__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, + unsigned long entryhi, unsigned long pagemask) +{ + int ret = 0; + unsigned long flags; + unsigned long wired; + unsigned long old_pagemask; + unsigned long old_ctx; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + old_pagemask = read_c0_pagemask(); + wired = read_c0_wired(); + if (--temp_tlb_entry < wired) { + printk(KERN_WARNING "No TLB space left for add_temporary_entry\n"); + ret = -ENOSPC; + goto out; + } + + write_c0_index(temp_tlb_entry); + BARRIER; + write_c0_pagemask(pagemask); + write_c0_entryhi(entryhi); + write_c0_entrylo0(entrylo0); + write_c0_entrylo1(entrylo1); + BARRIER; + tlb_write_indexed(); + BARRIER; + + write_c0_entryhi(old_ctx); + BARRIER; + write_c0_pagemask(old_pagemask); +out: + local_irq_restore(flags); + return ret; +} + +static void __init probe_tlb(unsigned long config) +{ + unsigned long config1; + + if (!(config & (1 << 31))) { + /* + * Not a MIPS64 complainant CPU. + * Config 1 register not supported, we assume R4k style. + */ + current_cpu_data.tlbsize = 48; + } else { + config1 = read_c0_config1(); + if (!((config >> 7) & 3)) + panic("No MMU present"); + else + current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; + } + + printk("Number of TLB entries %d.\n", current_cpu_data.tlbsize); +} + +void __init r4k_tlb_init(void) +{ + unsigned long config = read_c0_config(); + + probe_tlb(config); + write_c0_pagemask(PM_4K); + write_c0_wired(0); + temp_tlb_entry = current_cpu_data.tlbsize - 1; + local_flush_tlb_all(); + + memcpy((void *)(KSEG0 + 0x80), except_vec1_r4k, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); +} diff -Nru a/arch/mips64/mm/tlb-sb1.c b/arch/mips64/mm/tlb-sb1.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlb-sb1.c Fri Jun 27 14:20:07 2003 @@ -0,0 +1,342 @@ +/* + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#include <linux/config.h> +#include <asm/mmu_context.h> +#include <asm/bootinfo.h> +#include <asm/cpu.h> + +extern void except_vec1_sb1(void); + +/* Dump the current entry* and pagemask registers */ +static inline void dump_cur_tlb_regs(void) +{ + unsigned int entryhihi, entryhilo, entrylo0hi, entrylo0lo, entrylo1hi; + unsigned int entrylo1lo, pagemask; + + __asm__ __volatile__ ( + ".set push \n" + ".set noreorder \n" + "#.set mips64 \n" + ".set mips4 \n" + ".set noat \n" + " tlbr \n" + " dmfc0 $1, $10 \n" + " dsrl32 %0, $1, 0 \n" + " sll %1, $1, 0 \n" + " dmfc0 $1, $2 \n" + " dsrl32 %2, $1, 0 \n" + " sll %3, $1, 0 \n" + " dmfc0 $1, $3 \n" + " dsrl32 %4, $1, 0 \n" + " sll %5, $1, 0 \n" + " mfc0 %6, $5 \n" + ".set pop \n" + : "=r" (entryhihi), + "=r" (entryhilo), + "=r" (entrylo0hi), + "=r" (entrylo0lo), + "=r" (entrylo1hi), + "=r" (entrylo1lo), + "=r" (pagemask)); + printk("%08X%08X %08X%08X %08X%08X %08X", + entryhihi, entryhilo, + entrylo0hi, entrylo0lo, + entrylo1hi, entrylo1lo, + pagemask); +} + +void sb1_dump_tlb(void) +{ + unsigned long old_ctx; + unsigned long flags; + int entry; + local_irq_save(flags); + old_ctx = read_c0_entryhi(); + printk("Current TLB registers state:\n" + " EntryHi EntryLo0 EntryLo1 PageMask Index\n" + "--------------------------------------------------------------------\n"); + dump_cur_tlb_regs(); + printk(" %08X\n", read_c0_index()); + printk("\n\nFull TLB Dump:\n" + "Idx EntryHi EntryLo0 EntryLo1 PageMask\n" + "--------------------------------------------------------------\n"); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_index(entry); + printk("\n%02i ", entry); + dump_cur_tlb_regs(); + } + printk("\n"); + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + +void local_flush_tlb_all(void) +{ + unsigned long flags; + unsigned long old_ctx; + int entry; + + local_irq_save(flags); + /* Save old context and create impossible VPN2 value */ + old_ctx = read_c0_entryhi() & ASID_MASK; + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + write_c0_entryhi(KSEG0 + (PAGE_SIZE << 1) * entry); + write_c0_index(entry); + tlb_write_indexed(); + } + write_c0_entryhi(old_ctx); + local_irq_restore(flags); +} + + +/* + * Use a bogus region of memory (starting at 0) to sanitize the TLB's. + * Use increments of the maximum page size (16MB), and check for duplicate + * entries before doing a given write. Then, when we're safe from collisions + * with the firmware, go back and give all the entries invalid addresses with + * the normal flush routine. + */ +void sb1_sanitize_tlb(void) +{ + int entry; + long addr = 0; + + long inc = 1<<24; /* 16MB */ + /* Save old context and create impossible VPN2 value */ + write_c0_entrylo0(0); + write_c0_entrylo1(0); + for (entry = 0; entry < current_cpu_data.tlbsize; entry++) { + do { + addr += inc; + write_c0_entryhi(addr); + tlb_probe(); + } while ((int)(read_c0_index()) >= 0); + write_c0_index(entry); + tlb_write_indexed(); + } + /* Now that we know we're safe from collisions, we can safely flush + the TLB with the "normal" routine. */ + local_flush_tlb_all(); +} + +void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long flags; + int cpu; + + local_irq_save(flags); + cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + int size; + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + if (size <= (current_cpu_data.tlbsize/2)) { + int oldpid = read_c0_entryhi() & ASID_MASK; + int newpid = cpu_asid(cpu, mm); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + while (start < end) { + int idx; + + write_c0_entryhi(start | newpid); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + } else { + drop_mmu_context(mm, cpu); + } + } + local_irq_restore(flags); +} + +void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + size = (size + 1) >> 1; + + local_irq_save(flags); + if (size <= (current_cpu_data.tlbsize/2)) { + int pid = read_c0_entryhi(); + + start &= (PAGE_MASK << 1); + end += ((PAGE_SIZE << 1) - 1); + end &= (PAGE_MASK << 1); + + while (start < end) { + int idx; + + write_c0_entryhi(start); + start += (PAGE_SIZE << 1); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + write_c0_entryhi(KSEG0 + (idx << (PAGE_SHIFT+1))); + if (idx < 0) + continue; + tlb_write_indexed(); + } + write_c0_entryhi(pid); + } else { + local_flush_tlb_all(); + } + local_irq_restore(flags); +} + +void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + unsigned long flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + if (cpu_context(cpu, vma->vm_mm) != 0) { + int oldpid, newpid, idx; + newpid = cpu_asid(cpu, vma->vm_mm); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & ASID_MASK; + write_c0_entryhi(page | newpid); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if(idx < 0) + goto finish; + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + tlb_write_indexed(); + finish: + write_c0_entryhi(oldpid); + } + local_irq_restore(flags); +} + +/* + * This one is only used for pages with the global bit set so we don't care + * much about the ASID. + */ +void local_flush_tlb_one(unsigned long page) +{ + unsigned long flags; + int oldpid, idx; + + local_irq_save(flags); + page &= (PAGE_MASK << 1); + oldpid = read_c0_entryhi() & 0xff; + write_c0_entryhi(page); + tlb_probe(); + idx = read_c0_index(); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + if (idx >= 0) { + /* Make sure all entries differ. */ + write_c0_entryhi(KSEG0+(idx<<(PAGE_SHIFT+1))); + tlb_write_indexed(); + } + write_c0_entryhi(oldpid); + + local_irq_restore(flags); +} + +/* All entries common to a mm share an asid. To effectively flush + these entries, we just bump the asid. */ +void local_flush_tlb_mm(struct mm_struct *mm) +{ + int cpu = smp_processor_id(); + if (cpu_context(cpu, mm) != 0) { + drop_mmu_context(mm, cpu); + } +} + +/* Stolen from mips32 routines */ + +void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte) +{ + unsigned long flags; + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + int idx, pid; + + /* + * Handle debugger faulting in for debugee. + */ + if (current->active_mm != vma->vm_mm) + return; + + local_irq_save(flags); + + pid = read_c0_entryhi() & ASID_MASK; + address &= (PAGE_MASK << 1); + write_c0_entryhi(address | (pid)); + pgdp = pgd_offset(vma->vm_mm, address); + tlb_probe(); + pmdp = pmd_offset(pgdp, address); + idx = read_c0_index(); + ptep = pte_offset_map(pmdp, address); + write_c0_entrylo0(pte_val(*ptep++) >> 6); + write_c0_entrylo1(pte_val(*ptep) >> 6); + if (idx < 0) { + tlb_write_random(); + } else { + tlb_write_indexed(); + } + local_irq_restore(flags); +} + +/* + * This is called from loadmmu.c. We have to set up all the + * memory management function pointers, as well as initialize + * the caches and tlbs + */ +void sb1_tlb_init(void) +{ + u32 config1; + + write_c0_pagemask(PM_4K); + config1 = read_c0_config1(); + current_cpu_data.tlbsize = ((config1 >> 25) & 0x3f) + 1; + + /* + * We don't know what state the firmware left the TLB's in, so this is + * the ultra-conservative way to flush the TLB's and avoid machine + * check exceptions due to duplicate TLB entries + */ + sb1_sanitize_tlb(); + + memcpy((void *)KSEG0 + 0x080, except_vec1_sb1, 0x80); + flush_icache_range(KSEG0, KSEG0 + 0x80); +} diff -Nru a/arch/mips64/mm/tlbex-r4k.S b/arch/mips64/mm/tlbex-r4k.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/mips64/mm/tlbex-r4k.S Fri Jun 27 14:20:06 2003 @@ -0,0 +1,208 @@ +/* + * 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) 2000 Silicon Graphics, Inc. + * Written by Ulf Carlsson (ulfc@engr.sgi.com) + * Copyright (C) 2002 Maciej W. Rozycki + */ +#include <linux/config.h> +#include <linux/init.h> +#include <linux/threads.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/pgtable.h> +#include <asm/stackframe.h> +#include <asm/war.h> + + .data + .comm pgd_current, NR_CPUS * 8, 8 + + /* + * After this macro runs we have a pointer to the pte of the address + * that caused the fault in PTR. + */ + .macro LOAD_PTE2, ptr, tmp, kaddr +#ifdef CONFIG_SMP + dmfc0 \ptr, CP0_CONTEXT + dmfc0 \tmp, CP0_BADVADDR + dsra \ptr, 23 # get pgd_current[cpu] +#else + dmfc0 \tmp, CP0_BADVADDR + dla \ptr, pgd_current +#endif + bltz \tmp, \kaddr + ld \ptr, (\ptr) + dsrl \tmp, (PGDIR_SHIFT-3) # get pgd offset in bytes + andi \tmp, ((PTRS_PER_PGD - 1)<<3) + daddu \ptr, \tmp # add in pgd offset + dmfc0 \tmp, CP0_BADVADDR + ld \ptr, (\ptr) # get pmd pointer + dsrl \tmp, (PMD_SHIFT-3) # get pmd offset in bytes + andi \tmp, ((PTRS_PER_PMD - 1)<<3) + daddu \ptr, \tmp # add in pmd offset + dmfc0 \tmp, CP0_XCONTEXT + ld \ptr, (\ptr) # get pte pointer + andi \tmp, 0xff0 # get pte offset + daddu \ptr, \tmp + .endm + + + /* + * Ditto for the kernel table. + */ + .macro LOAD_KPTE2, ptr, tmp, not_vmalloc + /* + * First, determine that the address is in/above vmalloc range. + */ + dmfc0 \tmp, CP0_BADVADDR + dli \ptr, VMALLOC_START + + /* + * Now find offset into kptbl. + */ + dsubu \tmp, \tmp, \ptr + dla \ptr, kptbl + dsrl \tmp, (PAGE_SHIFT+1) # get vpn2 + dsll \tmp, 4 # byte offset of pte + daddu \ptr, \ptr, \tmp + + /* + * Determine that fault address is within vmalloc range. + */ + dla \tmp, ekptbl + slt \tmp, \ptr, \tmp + beqz \tmp, \not_vmalloc # not vmalloc + nop + .endm + + + /* + * This places the even/odd pte pair in the page table at the pte + * entry pointed to by PTE into ENTRYLO0 and ENTRYLO1. + */ + .macro PTE_RELOAD, pte0, pte1 + dsrl \pte0, 6 # convert to entrylo0 + dmtc0 \pte0, CP0_ENTRYLO0 # load it + dsrl \pte1, 6 # convert to entrylo1 + dmtc0 \pte1, CP0_ENTRYLO1 # load it + .endm + + + .text + .set noreorder + .set mips3 + + __INIT + + .align 5 +LEAF(except_vec0_generic) + .set noat + PANIC("Unused vector called") +1: b 1b + nop +END(except_vec0_generic) + + + /* + * TLB refill handlers for the R4000 and SB1. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r4k) + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop +END(except_vec1_r4k) + +LEAF(except_vec1_sb1) +#if BCM1250_M3_WAR + dmfc0 k0, CP0_BADVADDR + dmfc0 k1, CP0_ENTRYHI + xor k0, k1 + dsrl k0, k0, PAGE_SHIFT+1 + bnez k0, 1f +#endif + .set noat + dla k0, handle_vec1_r4k + jr k0 + nop + +1: eret + nop +END(except_vec1_sb1) + + __FINIT + + .align 5 +LEAF(handle_vec1_r4k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + b 1f + tlbwr +1: nop + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + b 1f + tlbwr +1: nop + eret +END(handle_vec1_r4k) + + + __INIT + + /* + * TLB refill handler for the R10000. + * Attention: We may only use 32 instructions / 128 bytes. + */ + .align 5 +LEAF(except_vec1_r10k) + .set noat + dla k0, handle_vec1_r10k + jr k0 + nop +END(except_vec1_r10k) + + __FINIT + + .align 5 +LEAF(handle_vec1_r10k) + .set noat + LOAD_PTE2 k1 k0 9f + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret + +9: # handle the vmalloc range + LOAD_KPTE2 k1 k0 invalid_vmalloc_address + ld k0, 0(k1) # get even pte + ld k1, 8(k1) # get odd pte + PTE_RELOAD k0 k1 + nop + tlbwr + eret +END(handle_vec1_r10k) + + + .align 5 +LEAF(invalid_vmalloc_address) + .set noat + PANIC("Invalid kernel address") +1: b 1b + nop +END(invalid_vmalloc_address) diff -Nru a/arch/mips64/mm/umap.c b/arch/mips64/mm/umap.c --- a/arch/mips64/mm/umap.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,221 +0,0 @@ -/* - * 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 Linus Torvalds - * Copyright (C) 1997 Miguel de Icaza - * Copyright (C) 2001 Ralf Baechle - */ -#include <linux/stat.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> -#include <linux/shm.h> -#include <linux/errno.h> -#include <linux/mman.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/vmalloc.h> -#include <linux/swap.h> - -#include <asm/system.h> -#include <asm/pgalloc.h> -#include <asm/page.h> - -static inline void remove_mapping_pte_range (pmd_t *pmd, unsigned long address, - unsigned long size) -{ - pte_t *pte; - unsigned long end; - - if (pmd_none (*pmd)) - return; - if (pmd_bad (*pmd)){ - printk ("remove_graphics_pte_range: bad pmd (%08lx)\n", - pmd_val (*pmd)); - pmd_clear (pmd); - return; - } - pte = pte_offset (pmd, address); - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t entry = *pte; - if (pte_present (entry)) - set_pte (pte, pte_modify (entry, PAGE_NONE)); - address += PAGE_SIZE; - pte++; - } while (address < end); - -} - -static inline void remove_mapping_pmd_range (pgd_t *pgd, unsigned long address, - unsigned long size) -{ - pmd_t *pmd; - unsigned long end; - - if (pgd_none (*pgd)) - return; - - if (pgd_bad (*pgd)){ - printk ("remove_graphics_pmd_range: bad pgd (%08lx)\n", - pgd_val (*pgd)); - pgd_clear (pgd); - return; - } - pmd = pmd_offset (pgd, address); - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - do { - remove_mapping_pte_range (pmd, address, end - address); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - -} - -/* - * This routine is called from the page fault handler to remove a - * range of active mappings at this point - */ -void remove_mapping (struct vm_area_struct *vma, struct task_struct *task, unsigned long start, - unsigned long end) -{ - unsigned long beg = start; - pgd_t *dir; - - down_write (&task->mm->mmap_sem); - dir = pgd_offset (task->mm, start); - flush_cache_range (vma, beg, end); - while (start < end){ - remove_mapping_pmd_range (dir, start, end - start); - start = (start + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range (vma, beg, end); - up_write (&task->mm->mmap_sem); -} - -EXPORT_SYMBOL(remove_mapping); - -void *vmalloc_uncached (unsigned long size) -{ - return __vmalloc (size, GFP_KERNEL | __GFP_HIGHMEM, - PAGE_KERNEL_UNCACHED); -} - -static inline void free_pte(pte_t page) -{ - if (pte_present(page)) { - unsigned long pfn = pte_pfn(page); - struct page *ptpage; - if (!pfn_valid(pfn)) - return; - ptpage = pfn_to_page(pfn); - if (PageReserved(ptpage)) - return; - __free_page(ptpage); - if (current->mm->rss <= 0) - return; - current->mm->rss--; - return; - } - swap_free(pte_to_swp_entry(page)); -} - -static inline void forget_pte(pte_t page) -{ - if (!pte_none(page)) { - printk("forget_pte: old mapping existed!\n"); - free_pte(page); - } -} - -/* - * maps a range of vmalloc()ed memory into the requested pages. the old - * mappings are removed. - */ -static inline void vmap_pte_range (pte_t *pte, unsigned long address, - unsigned long size, unsigned long vaddr) -{ - unsigned long end; - pgd_t *vdir; - pmd_t *vpmd; - pte_t *vpte; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - do { - pte_t oldpage = *pte; - struct page * page; - pte_clear(pte); - - vdir = pgd_offset_k (vaddr); - vpmd = pmd_offset (vdir, vaddr); - vpte = pte_offset (vpmd, vaddr); - page = pte_page (*vpte); - - set_pte(pte, mk_pte(page, PAGE_USERIO)); - forget_pte(oldpage); - address += PAGE_SIZE; - vaddr += PAGE_SIZE; - pte++; - } while (address < end); -} - -static inline int vmap_pmd_range (pmd_t *pmd, unsigned long address, - unsigned long size, unsigned long vaddr) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - vaddr -= address; - do { - pte_t * pte = pte_alloc(current->mm, pmd, address); - if (!pte) - return -ENOMEM; - vmap_pte_range(pte, address, end - address, address + vaddr); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address < end); - return 0; -} - -int vmap_page_range (struct vm_area_struct *vma, unsigned long from, unsigned long size, - unsigned long vaddr) -{ - int error = 0; - pgd_t * dir; - unsigned long beg = from; - unsigned long end = from + size; - - vaddr -= from; - dir = pgd_offset(current->mm, from); - flush_cache_range(vma, beg, end); - while (from < end) { - pmd_t *pmd = pmd_alloc(current->mm, dir, from); - error = -ENOMEM; - if (!pmd) - break; - error = vmap_pmd_range(pmd, from, end - from, vaddr + from); - if (error) - break; - from = (from + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } - flush_tlb_range(vma, beg, end); - return error; -} diff -Nru a/arch/mips64/sgi-ip22/Makefile b/arch/mips64/sgi-ip22/Makefile --- a/arch/mips64/sgi-ip22/Makefile Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -# -# Makefile for the SGI specific kernel interface routines -# under Linux. -# - -EXTRA_AFLAGS := $(CFLAGS) - -lib-y += ip22-berr.o ip22-mc.o ip22-sc.o ip22-hpc.o ip22-int.o ip22-rtc.o \ - ip22-setup.o system.o ip22-timer.o ip22-irq.o ip22-reset.o time.o diff -Nru a/arch/mips64/sgi-ip22/ip22-berr.c b/arch/mips64/sgi-ip22/ip22-berr.c --- a/arch/mips64/sgi-ip22/ip22-berr.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,125 +0,0 @@ -/* - * 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, 1995, 1996, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <asm/module.h> -#include <asm/uaccess.h> -#include <asm/paccess.h> -#include <asm/addrspace.h> -#include <asm/ptrace.h> - -extern asmlinkage void handle_ibe(void); -extern asmlinkage void handle_dbe(void); - -extern const struct exception_table_entry __start___dbe_table[]; -extern const struct exception_table_entry __stop___dbe_table[]; - -static inline unsigned long -search_one_table(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - while (first <= last) { - const struct exception_table_entry *mid; - long diff; - - mid = (last - first) / 2 + first; - diff = mid->insn - value; - if (diff == 0) - return mid->nextinsn; - else if (diff < 0) - first = mid+1; - else - last = mid-1; - } - return 0; -} - -extern spinlock_t modlist_lock; - -static inline unsigned long -search_dbe_table(unsigned long addr) -{ - unsigned long ret = 0; - -#ifndef CONFIG_MODULES - /* There is only the kernel to search. */ - ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr); - return ret; -#else - unsigned long flags; - - /* The kernel is the last "module" -- no need to treat it special. */ - struct module *mp; - struct archdata *ap; - - spin_lock_irqsave(&modlist_lock, flags); - for (mp = module_list; mp != NULL; mp = mp->next) { - if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, - dbe_table_end)) - continue; - ap = (struct archdata *)(mod->archdata_start); - - if (ap->dbe_table_start == NULL || - !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING))) - continue; - ret = search_one_table(ap->dbe_table_start, - ap->dbe_table_end - 1, addr); - if (ret) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - return ret; -#endif -} - -void do_ibe(struct pt_regs *regs) -{ - printk("Got ibe at 0x%lx\n", regs->cp0_epc); - show_regs(regs); - dump_tlb_addr(regs->cp0_epc); - force_sig(SIGBUS, current); - while(1); -} - -void do_dbe(struct pt_regs *regs) -{ - unsigned long fixup; - - fixup = search_dbe_table(regs->cp0_epc); - if (fixup) { - long new_epc; - - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); - regs->cp0_epc = new_epc; - return; - } - - printk("Got dbe at 0x%lx\n", regs->cp0_epc); - show_regs(regs); - dump_tlb_all(); - while(1); - force_sig(SIGBUS, current); -} - -void __init -bus_error_init(void) -{ - int dummy; - - set_except_vector(6, handle_ibe); - set_except_vector(7, handle_dbe); - - /* At this time nothing uses the DBE protection mechanism on the - Indy, so this here is needed to make the kernel link. */ - get_dbe(dummy, (int *)KSEG0); -} diff -Nru a/arch/mips64/sgi-ip22/ip22-hpc.c b/arch/mips64/sgi-ip22/ip22-hpc.c --- a/arch/mips64/sgi-ip22/ip22-hpc.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,104 +0,0 @@ -/* - * ip22-hpc.c: Routines for generic manipulation of the HPC controllers. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1998, 1999, 2001 Ralf Baechle - */ -#include <linux/init.h> -#include <linux/types.h> - -#include <asm/addrspace.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> -#include <asm/bootinfo.h> - -#undef DEBUG_SGIHPC - -struct hpc3_regs *hpc3c0, *hpc3c1; -struct hpc3_miscregs *hpc3mregs; - -/* We need software copies of these because they are write only. */ -unsigned int sgi_hpc_write1, sgi_hpc_write2; - -/* Machine specific identifier knobs. */ -int sgi_has_ioc2 = 0; -int sgi_guiness = 0; -int sgi_boardid; - -void __init sgihpc_init(void) -{ - unsigned long sid, crev, brev; - - hpc3c0 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP0_PBASE); - hpc3c1 = (struct hpc3_regs *) (KSEG1 + HPC3_CHIP1_PBASE); - hpc3mregs = (struct hpc3_miscregs *) (KSEG1 + HPC3_MREGS_PBASE); - sid = hpc3mregs->sysid; - - sid &= 0xff; - crev = (sid & 0xe0) >> 5; - brev = (sid & 0x1e) >> 1; - -#ifdef DEBUG_SGIHPC - prom_printf("sgihpc_init: crev<%2x> brev<%2x>\n", crev, brev); - prom_printf("sgihpc_init: "); -#endif - - /* This test works now thanks to William J. Earl */ - if ((sid & 1) == 0 ) { -#ifdef DEBUG_SGIHPC - prom_printf("GUINESS "); -#endif - sgi_guiness = 1; - mips_machtype = MACH_SGI_INDY; - } else { -#ifdef DEBUG_SGIHPC - prom_printf("FULLHOUSE "); -#endif - mips_machtype = MACH_SGI_INDIGO2; - sgi_guiness = 0; - } - sgi_boardid = brev; - -#ifdef DEBUG_SGIHPC - prom_printf("sgi_boardid<%d> ", sgi_boardid); -#endif - - if(crev == 1) { - if((sid & 1) || (brev >= 2)) { -#ifdef DEBUG_SGIHPC - prom_printf("IOC2 "); -#endif - sgi_has_ioc2 = 1; - } else { -#ifdef DEBUG_SGIHPC - prom_printf("IOC1 revision 1 "); -#endif - } - } else { -#ifdef DEBUG_SGIHPC - prom_printf("IOC1 revision 0 "); -#endif - } -#ifdef DEBUG_SGIHPC - prom_printf("\n"); -#endif - - sgi_hpc_write1 = (HPC3_WRITE1_PRESET | - HPC3_WRITE1_KMRESET | - HPC3_WRITE1_ERESET | - HPC3_WRITE1_LC0OFF); - - sgi_hpc_write2 = (HPC3_WRITE2_EASEL | - HPC3_WRITE2_NTHRESH | - HPC3_WRITE2_TPSPEED | - HPC3_WRITE2_EPSEL | - HPC3_WRITE2_U0AMODE | - HPC3_WRITE2_U1AMODE); - - if(!sgi_guiness) - sgi_hpc_write1 |= HPC3_WRITE1_GRESET; - hpc3mregs->write1 = sgi_hpc_write1; - hpc3mregs->write2 = sgi_hpc_write2; - - hpc3c0->pbus_piocfgs[0][6] |= HPC3_PIOPCFG_HW; -} diff -Nru a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c --- a/arch/mips64/sgi-ip22/ip22-int.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,616 +0,0 @@ -/* - * indy_int.c: Routines for generic manipulation of the INT[23] ASIC - * found on INDY workstations.. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/seq_file.h> - -#include <linux/errno.h> -#include <linux/kernel_stat.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/smp.h> -#include <linux/smp_lock.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/mipsregs.h> -#include <asm/system.h> - -#include <asm/ptrace.h> -#include <asm/processor.h> -#include <asm/sgi/sgi.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> - -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -struct sgi_int2_regs *sgi_i2regs; -struct sgi_int3_regs *sgi_i3regs; -struct sgi_ioc_ints *ioc_icontrol; -struct sgi_ioc_timers *ioc_timers; -volatile unsigned char *ioc_tclear; - -static char lc0msk_to_irqnr[256]; -static char lc1msk_to_irqnr[256]; -static char lc2msk_to_irqnr[256]; -static char lc3msk_to_irqnr[256]; - -extern asmlinkage void indyIRQ(void); - -#ifdef CONFIG_REMOTE_DEBUG -extern void rs_kgdb_hook(int); -#endif - -unsigned long spurious_count = 0; - -/* Local IRQ's are layed out logically like this: - * - * 0 --> 7 == local 0 interrupts - * 8 --> 15 == local 1 interrupts - * 16 --> 23 == vectored level 2 interrupts - * 24 --> 31 == vectored level 3 interrupts (not used) - */ -void disable_local_irq(unsigned int irq_nr) -{ - unsigned long flags; - - save_and_cli(flags); - switch(irq_nr) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - ioc_icontrol->imask0 &= ~(1 << irq_nr); - break; - - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: - ioc_icontrol->imask1 &= ~(1 << (irq_nr - 8)); - break; - - case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: - ioc_icontrol->cmeimask0 &= ~(1 << (irq_nr - 16)); - break; - - default: - /* This way we'll see if anyone would ever want vectored - * level 3 interrupts. Highly unlikely. - */ - printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr); - panic("INVALID IRQ level!"); - }; - restore_flags(flags); -} - -void enable_local_irq(unsigned int irq_nr) -{ - unsigned long flags; - save_and_cli(flags); - switch(irq_nr) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - ioc_icontrol->imask0 |= (1 << irq_nr); - break; - - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: - ioc_icontrol->imask1 |= (1 << (irq_nr - 8)); - break; - - case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: - enable_local_irq(7); - ioc_icontrol->cmeimask0 |= (1 << (irq_nr - 16)); - break; - - default: - printk("Yeeee, got passed irq_nr %d at disable_irq\n", irq_nr); - panic("INVALID IRQ level!"); - }; - restore_flags(flags); -} - -void disable_gio_irq(unsigned int irq_nr) -{ - /* XXX TODO XXX */ -} - -void enable_gio_irq(unsigned int irq_nr) -{ - /* XXX TODO XXX */ -} - -void disable_hpcdma_irq(unsigned int irq_nr) -{ - /* XXX TODO XXX */ -} - -void enable_hpcdma_irq(unsigned int irq_nr) -{ - /* XXX TODO XXX */ -} - -void disable_irq(unsigned int irq_nr) -{ - unsigned int n = irq_nr; - if(n >= SGINT_END) { - printk("whee, invalid irq_nr %d\n", irq_nr); - panic("IRQ, you lose..."); - } - if(n >= SGINT_LOCAL0 && n < SGINT_GIO) { - disable_local_irq(n - SGINT_LOCAL0); - } else if(n >= SGINT_GIO && n < SGINT_HPCDMA) { - disable_gio_irq(n - SGINT_GIO); - } else if(n >= SGINT_HPCDMA && n < SGINT_END) { - disable_hpcdma_irq(n - SGINT_HPCDMA); - } else { - panic("how did I get here?"); - } -} - -void enable_irq(unsigned int irq_nr) -{ - unsigned int n = irq_nr; - if(n >= SGINT_END) { - printk("whee, invalid irq_nr %d\n", irq_nr); - panic("IRQ, you lose..."); - } - if(n >= SGINT_LOCAL0 && n < SGINT_GIO) { - enable_local_irq(n - SGINT_LOCAL0); - } else if(n >= SGINT_GIO && n < SGINT_HPCDMA) { - enable_gio_irq(n - SGINT_GIO); - } else if(n >= SGINT_HPCDMA && n < SGINT_END) { - enable_hpcdma_irq(n - SGINT_HPCDMA); - } else { - panic("how did I get here?"); - } -} - -#if 0 -/* - * Currently unused. - */ -static void local_unex(int irq, void *data, struct pt_regs *regs) -{ - printk("Whee: unexpected local IRQ at %08lx\n", - (unsigned long) regs->cp0_epc); - printk("DUMP: stat0<%x> stat1<%x> vmeistat<%x>\n", - ioc_icontrol->istat0, ioc_icontrol->istat1, - ioc_icontrol->vmeistat); -} -#endif - -static struct irqaction *local_irq_action[24] = { - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL -}; - -int setup_indy_irq(int irq, struct irqaction * new) -{ - printk("setup_indy_irq: Yeee, don't know how to setup irq<%d> for %s %p\n", - irq, new->name, new->handler); - return 0; -} - -static struct irqaction r4ktimer_action = { - NULL, 0, 0, "R4000 timer/counter", NULL, NULL, -}; - -static struct irqaction indy_berr_action = { - NULL, 0, 0, "IP22 Bus Error", NULL, NULL, -}; - -static struct irqaction *irq_action[16] = { - NULL, NULL, NULL, NULL, - NULL, NULL, &indy_berr_action, &r4ktimer_action, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL -}; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - int num = 0; - struct irqaction * action; - unsigned long flags; - - for (i = 0 ; i < 16 ; i++, num++) { - local_irq_save(flags); - action = irq_action[i]; - if (!action) - goto skip_1; - seq_printf(p, "%2d: %8d %c %s", - num, kstat_cpu(0).irqs[num], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_puts(p, " [on-chip]\n"); -skip_1: - local_irq_restore(flags); - } - for (i = 0 ; i < 24 ; i++, num++) { - local_irq_save(flags); - action = local_irq_action[i]; - if (!action) - goto skip_2; - seq_printf(p, "%2d: %8d %c %s", - num, kstat_cpu(0).irqs[num], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) ? " +" : "", - action->name); - } - seq_puts(p, " [local]\n"); -skip_2: - local_irq_restore(flags); - } - return 0; -} - -/* - * do_IRQ handles IRQ's that have been installed without the - * SA_INTERRUPT flag: it uses the full signal-handling return - * and runs with other interrupts enabled. All relatively slow - * IRQ's should use this format: notably the keyboard/timer - * routines. - */ -asmlinkage void do_IRQ(int irq, struct pt_regs * regs) -{ - struct irqaction *action; - int do_random, cpu; - - cpu = smp_processor_id(); - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - - panic(KERN_DEBUG "Got irq %d, press a key.", irq); - - /* - * mask and ack quickly, we don't want the irq controller - * thinking we're snobs just because some other CPU has - * disabled global interrupts (we have already done the - * INT_ACK cycles, it's too late to try to pretend to the - * controller that we aren't taking the interrupt). - * - * Commented out because we've already done this in the - * machinespecific part of the handler. It's reasonable to - * do this here in a highlevel language though because that way - * we could get rid of a good part of duplicated code ... - */ - /* mask_and_ack_irq(irq); */ - - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); - action = *(irq + irq_action); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - local_irq_disable(); - } - irq_exit(cpu, irq); - - /* unmasking and bottom half handling is done magically for us. */ -} - -int request_local_irq(unsigned int lirq, void (*func)(int, void *, struct pt_regs *), - unsigned long iflags, const char *dname, void *devid) -{ - struct irqaction *action; - - lirq -= SGINT_LOCAL0; - if(lirq >= 24 || !func) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if(!action) - return -ENOMEM; - - action->handler = func; - action->flags = iflags; - action->mask = 0; - action->name = dname; - action->dev_id = devid; - action->next = 0; - local_irq_action[lirq] = action; - enable_irq(lirq + SGINT_LOCAL0); - return 0; -} - -void free_local_irq(unsigned int lirq, void *dev_id) -{ - struct irqaction *action; - - lirq -= SGINT_LOCAL0; - if(lirq >= 24) { - printk("Aieee: trying to free bogus local irq %d\n", - lirq + SGINT_LOCAL0); - return; - } - action = local_irq_action[lirq]; - local_irq_action[lirq] = NULL; - disable_irq(lirq + SGINT_LOCAL0); - kfree(action); -} - -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, - const char * devname, - void *dev_id) -{ - int retval; - struct irqaction * action; - - if (irq >= SGINT_END) - return -EINVAL; - if (!handler) - return -EINVAL; - - if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) - return request_local_irq(irq, handler, irqflags, devname, dev_id); - - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - retval = setup_indy_irq(irq, action); - - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction * action, **p; - unsigned long flags; - - if (irq >= SGINT_END) { - printk("Trying to free IRQ%d\n",irq); - return; - } - if((irq >= SGINT_LOCAL0) && (irq < SGINT_GIO)) { - free_local_irq(irq, dev_id); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - restore_flags(flags); - kfree(action); - return; - } - printk("Trying to free free IRQ%d\n",irq); -} - -void indy_local0_irqdispatch(struct pt_regs *regs) -{ - struct irqaction *action; - unsigned char mask = ioc_icontrol->istat0; - unsigned char mask2 = 0; - int irq, cpu = smp_processor_id();; - - mask &= ioc_icontrol->imask0; - if(mask & ISTAT0_LIO2) { - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask0; - irq = lc2msk_to_irqnr[mask2]; - action = local_irq_action[irq]; - } else { - irq = lc0msk_to_irqnr[mask]; - action = local_irq_action[irq]; - } - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq + 16]++; - action->handler(irq, action->dev_id, regs); - irq_exit(cpu, irq); -} - -void indy_local1_irqdispatch(struct pt_regs *regs) -{ - struct irqaction *action; - unsigned char mask = ioc_icontrol->istat1; - unsigned char mask2 = 0; - int irq, cpu = smp_processor_id();; - - mask &= ioc_icontrol->imask1; - if(mask & ISTAT1_LIO3) { - printk("WHee: Got an LIO3 irq, winging it...\n"); - mask2 = ioc_icontrol->vmeistat; - mask2 &= ioc_icontrol->cmeimask1; - irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat]; - action = local_irq_action[irq]; - } else { - irq = lc1msk_to_irqnr[mask]; - action = local_irq_action[irq]; - } - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq + 24]++; - action->handler(irq, action->dev_id, regs); - irq_exit(cpu, irq); -} - -void indy_buserror_irq(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - int irq = 6; - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - printk("Got a bus error IRQ, shouldn't happen yet\n"); - show_regs(regs); - printk("Spinning...\n"); - while(1); - irq_exit(cpu, irq); -} - -/* Misc. crap just to keep the kernel linking... */ -unsigned long probe_irq_on (void) -{ - return 0; -} - -int probe_irq_off (unsigned long irqs) -{ - return 0; -} - -static inline void sgint_init(void) -{ - int i; -#ifdef CONFIG_REMOTE_DEBUG - char *ctype; -#endif - - sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE); - sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE); - - /* Init local mask --> irq tables. */ - for(i = 0; i < 256; i++) { - if(i & 0x80) { - lc0msk_to_irqnr[i] = 7; - lc1msk_to_irqnr[i] = 15; - lc2msk_to_irqnr[i] = 23; - lc3msk_to_irqnr[i] = 31; - } else if(i & 0x40) { - lc0msk_to_irqnr[i] = 6; - lc1msk_to_irqnr[i] = 14; - lc2msk_to_irqnr[i] = 22; - lc3msk_to_irqnr[i] = 30; - } else if(i & 0x20) { - lc0msk_to_irqnr[i] = 5; - lc1msk_to_irqnr[i] = 13; - lc2msk_to_irqnr[i] = 21; - lc3msk_to_irqnr[i] = 29; - } else if(i & 0x10) { - lc0msk_to_irqnr[i] = 4; - lc1msk_to_irqnr[i] = 12; - lc2msk_to_irqnr[i] = 20; - lc3msk_to_irqnr[i] = 28; - } else if(i & 0x08) { - lc0msk_to_irqnr[i] = 3; - lc1msk_to_irqnr[i] = 11; - lc2msk_to_irqnr[i] = 19; - lc3msk_to_irqnr[i] = 27; - } else if(i & 0x04) { - lc0msk_to_irqnr[i] = 2; - lc1msk_to_irqnr[i] = 10; - lc2msk_to_irqnr[i] = 18; - lc3msk_to_irqnr[i] = 26; - } else if(i & 0x02) { - lc0msk_to_irqnr[i] = 1; - lc1msk_to_irqnr[i] = 9; - lc2msk_to_irqnr[i] = 17; - lc3msk_to_irqnr[i] = 25; - } else if(i & 0x01) { - lc0msk_to_irqnr[i] = 0; - lc1msk_to_irqnr[i] = 8; - lc2msk_to_irqnr[i] = 16; - lc3msk_to_irqnr[i] = 24; - } else { - lc0msk_to_irqnr[i] = 0; - lc1msk_to_irqnr[i] = 0; - lc2msk_to_irqnr[i] = 0; - lc3msk_to_irqnr[i] = 0; - } - } - - /* Indy uses an INT3, Indigo2 uses an INT2 */ - if (sgi_guiness) { - ioc_icontrol = &sgi_i3regs->ints; - ioc_timers = &sgi_i3regs->timers; - ioc_tclear = &sgi_i3regs->tclear; - } else { - ioc_icontrol = &sgi_i2regs->ints; - ioc_timers = &sgi_i2regs->timers; - ioc_tclear = &sgi_i2regs->tclear; - } - - /* Mask out all interrupts. */ - ioc_icontrol->imask0 = 0; - ioc_icontrol->imask1 = 0; - ioc_icontrol->cmeimask0 = 0; - ioc_icontrol->cmeimask1 = 0; - - /* Now safe to set the exception vector. */ - set_except_vector(0, indyIRQ); - -#ifdef CONFIG_REMOTE_DEBUG - ctype = prom_getcmdline(); - for(i = 0; i < strlen(ctype); i++) { - if(ctype[i]=='k' && ctype[i+1]=='g' && - ctype[i+2]=='d' && ctype[i+3]=='b' && - ctype[i+4]=='=' && ctype[i+5]=='t' && - ctype[i+6]=='t' && ctype[i+7]=='y' && - ctype[i+8]=='d' && - (ctype[i+9] == '1' || ctype[i+9] == '2')) { - printk("KGDB: Using serial line /dev/ttyd%d for " - "session\n", (ctype[i+9] - '0')); - if(ctype[i+9]=='1') - rs_kgdb_hook(1); - else if(ctype[i+9]=='2') - rs_kgdb_hook(0); - else { - printk("KGDB: whoops bogon tty line " - "requested, disabling session\n"); - } - - } - } -#endif -} - -void __init init_IRQ(void) -{ - sgint_init(); -} diff -Nru a/arch/mips64/sgi-ip22/ip22-irq.S b/arch/mips64/sgi-ip22/ip22-irq.S --- a/arch/mips64/sgi-ip22/ip22-irq.S Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,128 +0,0 @@ -/* - * 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. - * - * indyIRQ.S: Interrupt exception dispatch code for FullHouse and - * Guiness. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - -/* A lot of complication here is taken away because: - * - * 1) We handle one interrupt and return, sitting in a loop and moving across - * all the pending IRQ bits in the cause register is _NOT_ the answer, the - * common case is one pending IRQ so optimize in that direction. - * - * 2) We need not check against bits in the status register IRQ mask, that - * would make this routine slow as hell. - * - * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in - * between like BSD spl() brain-damage. - * - * Furthermore, the IRQs on the INDY look basically (barring software IRQs - * which we don't use at all) like: - * - * MIPS IRQ Source - * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Local IRQ level zero - * 3 Local IRQ level one - * 4 8254 Timer zero - * 5 8254 Timer one - * 6 Bus Error - * 7 R4k timer (what we use) - * - * We handle the IRQ according to _our_ priority which is: - * - * Highest ---- R4k Timer - * Local IRQ zero - * Local IRQ one - * Bus Error - * 8254 Timer zero - * Lowest ---- 8254 Timer one - * - * then we just return, if multiple IRQs are pending then we will just take - * another exception, big deal. - */ - - .text - .set noreorder - .set noat - .align 5 - NESTED(indyIRQ, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - mfc0 s0, CP0_CAUSE # get irq mask - - /* First we check for r4k counter/timer IRQ. */ - andi a0, s0, CAUSEF_IP7 - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero - - /* Wheee, a timer interrupt. */ - move a0, sp - jal indy_timer_interrupt - nop # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP3 # delay slot, check local level one - - /* Wheee, local level zero interrupt. */ - jal indy_local0_irqdispatch - move a0, sp # delay slot - - j ret_from_irq - nop # delay slot - -1: - beq a0, zero, 1f - andi a0, s0, CAUSEF_IP6 # delay slot, check bus error - - /* Wheee, local level one interrupt. */ - move a0, sp - jal indy_local1_irqdispatch - nop - - j ret_from_irq - nop - -1: - beq a0, zero, 1f - nop - - /* Wheee, an asynchronous bus error... */ - move a0, sp - jal indy_buserror_irq - nop - - j ret_from_irq - nop - -1: - /* Here by mistake? This is possible, what can happen - * is that by the time we take the exception the IRQ - * pin goes low, so just leave if this is the case. - */ - andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) - beq a0, zero, 1f - - /* Must be one of the 8254 timers... */ - move a0, sp - jal indy_8254timer_irq - nop -1: - j ret_from_irq - nop - END(indyIRQ) diff -Nru a/arch/mips64/sgi-ip22/ip22-mc.c b/arch/mips64/sgi-ip22/ip22-mc.c --- a/arch/mips64/sgi-ip22/ip22-mc.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,158 +0,0 @@ -/* - * 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) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) - */ -#include <linux/init.h> -#include <linux/kernel.h> - -#include <asm/addrspace.h> -#include <asm/ptrace.h> -#include <asm/sgi/sgimc.h> -#include <asm/sgi/sgihpc.h> - -/* #define DEBUG_SGIMC */ - -struct sgimc_misc_ctrl *mcmisc_regs; -u32 *rpsscounter; -struct sgimc_dma_ctrl *dmactrlregs; - -static inline char *mconfig_string(unsigned long val) -{ - switch(val & SGIMC_MCONFIG_RMASK) { - case SGIMC_MCONFIG_FOURMB: - return "4MB"; - - case SGIMC_MCONFIG_EIGHTMB: - return "8MB"; - - case SGIMC_MCONFIG_SXTEENMB: - return "16MB"; - - case SGIMC_MCONFIG_TTWOMB: - return "32MB"; - - case SGIMC_MCONFIG_SFOURMB: - return "64MB"; - - case SGIMC_MCONFIG_OTEIGHTMB: - return "128MB"; - - default: - return "wheee, unknown"; - }; -} - -void __init sgimc_init(void) -{ - unsigned long tmpreg; - - mcmisc_regs = (struct sgimc_misc_ctrl *)(KSEG1+0x1fa00000); - rpsscounter = (u32 *) (KSEG1 + 0x1fa01004); - dmactrlregs = (struct sgimc_dma_ctrl *) (KSEG1+0x1fa02000); - - printk("MC: SGI memory controller Revision %d\n", - (int) mcmisc_regs->systemid & SGIMC_SYSID_MASKREV); - -#if 0 /* XXX Until I figure out what this bit really indicates XXX */ - /* XXX Is this systemid bit reliable? */ - if(mcmisc_regs->systemid & SGIMC_SYSID_EPRESENT) { - EISA_bus = 1; - printk("with EISA\n"); - } else { - EISA_bus = 0; - printk("no EISA\n"); - } -#endif - -#ifdef DEBUG_SGIMC - prom_printf("sgimc_init: memconfig0<%s> mconfig1<%s>\n", - mconfig_string(mcmisc_regs->mconfig0), - mconfig_string(mcmisc_regs->mconfig1)); - - prom_printf("mcdump: cpuctrl0<%08lx> cpuctrl1<%08lx>\n", - mcmisc_regs->cpuctrl0, mcmisc_regs->cpuctrl1); - prom_printf("mcdump: divider<%08lx>, gioparm<%04x>\n", - mcmisc_regs->divider, mcmisc_regs->gioparm); -#endif - - /* Place the MC into a known state. This must be done before - * interrupts are first enabled etc. - */ - - /* Step 1: The CPU/GIO error status registers will not latch - * up a new error status until the register has been - * cleared by the cpu. These status registers are - * cleared by writing any value to them. - */ - mcmisc_regs->cstat = mcmisc_regs->gstat = 0; - - /* Step 2: Enable all parity checking in cpu control register - * zero. - */ - tmpreg = mcmisc_regs->cpuctrl0; - tmpreg |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM | - SGIMC_CCTRL0_R4KNOCHKPARR); - mcmisc_regs->cpuctrl0 = tmpreg; - - /* Step 3: Setup the MC write buffer depth, this is controlled - * in cpu control register 1 in the lower 4 bits. - */ - tmpreg = mcmisc_regs->cpuctrl1; - tmpreg &= ~0xf; - tmpreg |= 0xd; - mcmisc_regs->cpuctrl1 = tmpreg; - - /* Step 4: Initialize the RPSS divider register to run as fast - * as it can correctly operate. The register is laid - * out as follows: - * - * ---------------------------------------- - * | RESERVED | INCREMENT | DIVIDER | - * ---------------------------------------- - * 31 16 15 8 7 0 - * - * DIVIDER determines how often a 'tick' happens, - * INCREMENT determines by how the RPSS increment - * registers value increases at each 'tick'. Thus, - * for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101 - */ - mcmisc_regs->divider = 0x101; - - /* Step 5: Initialize GIO64 arbitrator configuration register. - * - * NOTE: If you dork with startup code the HPC init code in - * sgihpc_init() must run before us because of how we - * need to know Guiness vs. FullHouse and the board - * revision on this machine. You have been warned. - */ - - /* First the basic invariants across all gio64 implementations. */ - tmpreg = SGIMC_GIOPARM_HPC64; /* All 1st HPC's interface at 64bits. */ - tmpreg |= SGIMC_GIOPARM_ONEBUS; /* Only one physical GIO bus exists. */ - - if(sgi_guiness) { - /* Guiness specific settings. */ - tmpreg |= SGIMC_GIOPARM_EISA64; /* MC talks to EISA at 64bits */ - tmpreg |= SGIMC_GIOPARM_MASTEREISA; /* EISA bus can act as master */ - } else { - /* Fullhouse specific settings. */ - if(sgi_boardid < 2) { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC at 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp0 pipelines */ - tmpreg |= SGIMC_GIOPARM_MASTEREXP1;/* exp1 masters */ - tmpreg |= SGIMC_GIOPARM_RTIMEEXP0; /* exp0 is realtime */ - } else { - tmpreg |= SGIMC_GIOPARM_HPC264; /* 2nd HPC 64bits */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP0; /* exp[01] pipelined */ - tmpreg |= SGIMC_GIOPARM_PLINEEXP1; - tmpreg |= SGIMC_GIOPARM_MASTEREISA;/* EISA masters */ - /* someone forgot this poor little guy... */ - tmpreg |= SGIMC_GIOPARM_GFX64; /* GFX at 64 bits */ - } - } - mcmisc_regs->gioparm = tmpreg; /* poof */ -} diff -Nru a/arch/mips64/sgi-ip22/ip22-reset.c b/arch/mips64/sgi-ip22/ip22-reset.c --- a/arch/mips64/sgi-ip22/ip22-reset.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,238 +0,0 @@ -/* - * 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. - * - * Reset an IP22. - * - * Copyright (C) 1997, 1998, 1999, 2001 by Ralf Baechle - */ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/notifier.h> -#include <linux/timer.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/sgialib.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> - -/* - * Just powerdown if init hasn't done after POWERDOWN_TIMEOUT seconds. - * I'm not shure if this feature is a good idea, for now it's here just to - * make the power button make behave just like under IRIX. - */ -#define POWERDOWN_TIMEOUT 120 - -/* - * Blink frequency during reboot grace period and when paniced. - */ -#define POWERDOWN_FREQ (HZ / 4) -#define PANIC_FREQ (HZ / 8) - -static unsigned char sgi_volume; - -static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; -static int shuting_down, has_paniced; - -void machine_restart(char *command) __attribute__((noreturn)); -void machine_halt(void) __attribute__((noreturn)); -void machine_power_off(void) __attribute__((noreturn)); - -/* XXX How to pass the reboot command to the firmware??? */ -void machine_restart(char *command) -{ - if (shuting_down) - machine_power_off(); - ArcReboot(); -} - -void machine_halt(void) -{ - if (shuting_down) - machine_power_off(); - ArcEnterInteractiveMode(); -} - -void machine_power_off(void) -{ - struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; - - cli(); - - clock->cmd |= 0x08; /* Disable watchdog */ - clock->whsec = 0; - clock->wsec = 0; - - while(1) { - hpc3mregs->panel=0xfe; - /* Good bye cruel world ... */ - - /* If we're still running, we probably got sent an alarm - interrupt. Read the flag to clear it. */ - clock->halarm; - } -} - -static void power_timeout(unsigned long data) -{ - machine_power_off(); -} - -static void blink_timeout(unsigned long data) -{ - /* XXX Fix this for Fullhouse */ - sgi_hpc_write1 ^= (HPC3_WRITE1_LC0OFF|HPC3_WRITE1_LC1OFF); - hpc3mregs->write1 = sgi_hpc_write1; - - mod_timer(&blink_timer, jiffies+data); -} - -static void debounce(unsigned long data) -{ - del_timer(&debounce_timer); - if (ioc_icontrol->istat1 & 2) { /* Interrupt still being sent. */ - debounce_timer.expires = jiffies + 5; /* 0.05s */ - add_timer(&debounce_timer); - - hpc3mregs->panel = 0xf3; - - return; - } - - if (has_paniced) - ArcReboot(); - - enable_irq(9); -} - -static inline void power_button(void) -{ - if (has_paniced) - return; - - if (shuting_down || kill_proc(1, SIGINT, 1)) { - /* No init process or button pressed twice. */ - machine_power_off(); - } - - shuting_down = 1; - blink_timer.data = POWERDOWN_FREQ; - blink_timeout(POWERDOWN_FREQ); - - init_timer(&power_timer); - power_timer.function = power_timeout; - power_timer.expires = jiffies + POWERDOWN_TIMEOUT * HZ; - add_timer(&power_timer); -} - -void inline ip22_volume_set(unsigned char volume) -{ - sgi_volume = volume; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; -} - -void inline ip22_volume_get(unsigned char *volume) -{ - *volume = sgi_volume; -} - -static inline void volume_up_button(unsigned long data) -{ - del_timer(&volume_timer); - - if (sgi_volume < 0xff) - sgi_volume++; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; - - if (ioc_icontrol->istat1 & 2) { - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } - -} - -static inline void volume_down_button(unsigned long data) -{ - del_timer(&volume_timer); - - if (sgi_volume > 0) - sgi_volume--; - - hpc3c0->pbus_extregs[2][0] = sgi_volume; - hpc3c0->pbus_extregs[2][1] = sgi_volume; - - if (ioc_icontrol->istat1 & 2) { - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } -} - -static void panel_int(int irq, void *dev_id, struct pt_regs *regs) -{ - unsigned int buttons; - - buttons = hpc3mregs->panel; - hpc3mregs->panel = 3; /* power_interrupt | power_supply_on */ - - if (ioc_icontrol->istat1 & 2) { /* Wait until interrupt goes away */ - disable_irq(9); - init_timer(&debounce_timer); - debounce_timer.function = debounce; - debounce_timer.expires = jiffies + 5; - add_timer(&debounce_timer); - } - - if (!(buttons & 2)) /* Power button was pressed */ - power_button(); - if (!(buttons & 0x40)) { /* Volume up button was pressed */ - init_timer(&volume_timer); - volume_timer.function = volume_up_button; - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } - if (!(buttons & 0x10)) { /* Volume down button was pressed */ - init_timer(&volume_timer); - volume_timer.function = volume_down_button; - volume_timer.expires = jiffies + 1; - add_timer(&volume_timer); - } -} - -static int panic_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - if (has_paniced) - return NOTIFY_DONE; - has_paniced = 1; - - blink_timer.data = PANIC_FREQ; - blink_timeout(PANIC_FREQ); - - return NOTIFY_DONE; -} - -static struct notifier_block panic_block = { - panic_event, - NULL, - 0 -}; - -void ip22_reboot_setup(void) -{ - static int setup_done; - - if (setup_done) - return; - setup_done = 1; - - request_irq(9, panel_int, 0, "Front Panel", NULL); - init_timer(&blink_timer); - blink_timer.function = blink_timeout; - notifier_chain_register(&panic_notifier_list, &panic_block); -} diff -Nru a/arch/mips64/sgi-ip22/ip22-rtc.c b/arch/mips64/sgi-ip22/ip22-rtc.c --- a/arch/mips64/sgi-ip22/ip22-rtc.c Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/* - * 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. - * - * RTC routines for Indy style attached Dallas chip. - * - * Copyright (C) 1998, 2001 by Ralf Baechle - */ -#include <linux/mc146818rtc.h> -#include <asm/sgi/sgihpc.h> - -static unsigned char indy_rtc_read_data(unsigned long addr) -{ - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - return rtcregs[addr]; -} - -static void indy_rtc_write_data(unsigned char data, unsigned long addr) -{ - volatile unsigned int *rtcregs = (void *)INDY_CLOCK_REGS; - - rtcregs[addr] = data; -} - -static int indy_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops indy_rtc_ops = { - &indy_rtc_read_data, - &indy_rtc_write_data, - &indy_rtc_bcd_mode -}; diff -Nru a/arch/mips64/sgi-ip22/ip22-sc.c b/arch/mips64/sgi-ip22/ip22-sc.c --- a/arch/mips64/sgi-ip22/ip22-sc.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,164 +0,0 @@ -/* - * indy_sc.c: Indy cache management functions. - * - * Copyright (C) 1997 Ralf Baechle (ralf@gnu.org), - * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com). - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/mm.h> - -#include <asm/bcache.h> -#include <asm/sgi/sgimc.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/system.h> -#include <asm/bootinfo.h> -#include <asm/mmu_context.h> - -/* Secondary cache size in bytes, if present. */ -static unsigned long scache_size; - -#undef DEBUG_CACHE - -#define SC_SIZE 0x00080000 -#define SC_LINE 32 -#define CI_MASK (SC_SIZE - SC_LINE) -#define SC_INDEX(n) ((n) & CI_MASK) - -static inline void indy_sc_wipe(unsigned long first, unsigned long last) -{ - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "or\t%0, %4\t\t\t# first line to flush\n\t" - "or\t%1, %4\t\t\t# last line to flush\n" - "1:\tsw $0, 0(%0)\n\t" - "bne\t%0, %1, 1b\n\t" - "daddu\t%0, 32\n\t" - ".set reorder" - : "=r" (first), "=r" (last) - : "0" (first), "1" (last), "r" (0x9000000080000000) - : "$1"); -} - -static void indy_sc_wback_invalidate(unsigned long addr, unsigned long size) -{ - unsigned long first_line, last_line; - unsigned int flags; - -#ifdef DEBUG_CACHE - printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size); -#endif - - if (!size) - return; - - /* Which lines to flush? */ - first_line = SC_INDEX(addr); - last_line = SC_INDEX(addr + size - 1); - - local_irq_save(flags); - if (first_line <= last_line) { - indy_sc_wipe(first_line, last_line); - goto out; - } - - indy_sc_wipe(first_line, SC_SIZE - SC_LINE); - indy_sc_wipe(0, last_line); -out: - local_irq_restore(flags); -} - -static void inline indy_sc_enable(void) -{ -#ifdef DEBUG_CACHE - printk("Enabling R4600 SCACHE\n"); -#endif - *(volatile unsigned char *) 0x9000000080000000 = 0; -} - -static void indy_sc_disable(void) -{ -#ifdef DEBUG_CACHE - printk("Disabling R4600 SCACHE\n"); -#endif - *(volatile unsigned short *) 0x9000000080000000 = 0; -} - -static inline __init int indy_sc_probe(void) -{ - volatile u32 *cpu_control; - unsigned short cmd = 0xc220; - unsigned long data = 0; - int i, n; - -#ifdef __MIPSEB__ - cpu_control = (volatile u32 *) KSEG1ADDR(0x1fa00034); -#else - cpu_control = (volatile u32 *) KSEG1ADDR(0x1fa00030); -#endif -#define DEASSERT(bit) (*(cpu_control) &= (~(bit))) -#define ASSERT(bit) (*(cpu_control) |= (bit)) -#define DELAY for(n = 0; n < 100000; n++) __asm__ __volatile__("") - DEASSERT(SGIMC_EEPROM_PRE); - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_PRE); - DELAY; - ASSERT(SGIMC_EEPROM_CSEL); ASSERT(SGIMC_EEPROM_SECLOCK); - for(i = 0; i < 11; i++) { - if(cmd & (1<<15)) - ASSERT(SGIMC_EEPROM_SDATAO); - else - DEASSERT(SGIMC_EEPROM_SDATAO); - DEASSERT(SGIMC_EEPROM_SECLOCK); - ASSERT(SGIMC_EEPROM_SECLOCK); - cmd <<= 1; - } - DEASSERT(SGIMC_EEPROM_SDATAO); - for(i = 0; i < (sizeof(unsigned short) * 8); i++) { - unsigned int tmp; - - DEASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - ASSERT(SGIMC_EEPROM_SECLOCK); - DELAY; - data <<= 1; - tmp = *cpu_control; - if(tmp & SGIMC_EEPROM_SDATAI) - data |= 1; - } - DEASSERT(SGIMC_EEPROM_SECLOCK); - DEASSERT(SGIMC_EEPROM_CSEL); - ASSERT(SGIMC_EEPROM_PRE); - ASSERT(SGIMC_EEPROM_SECLOCK); - - data <<= PAGE_SHIFT; - if (data == 0) - return 0; - - scache_size = data; - - printk("R4600/R5000 SCACHE size %ldK, linesize 32 bytes.\n", - scache_size >> 10); - - return 1; -} - -/* XXX Check with wje if the Indy caches can differenciate between - writeback + invalidate and just invalidate. */ -static struct bcache_ops indy_sc_ops = { - indy_sc_enable, - indy_sc_disable, - indy_sc_wback_invalidate, - indy_sc_wback_invalidate -}; - -void __init indy_sc_init(void) -{ - if (indy_sc_probe()) { - indy_sc_enable(); - bcops = &indy_sc_ops; - } -} diff -Nru a/arch/mips64/sgi-ip22/ip22-setup.c b/arch/mips64/sgi-ip22/ip22-setup.c --- a/arch/mips64/sgi-ip22/ip22-setup.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,189 +0,0 @@ -/* - * 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. - * - * SGI IP22 specific setup. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 1998, 1999 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999 Silcon Graphics, Inc. - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kbd_ll.h> -#include <linux/kernel.h> -#include <linux/kdev_t.h> -#include <linux/types.h> -#include <linux/console.h> -#include <linux/sched.h> -#include <linux/mc146818rtc.h> -#include <linux/pc_keyb.h> -#include <linux/tty.h> - -#include <asm/addrspace.h> -#include <asm/mmu_context.h> -#include <asm/bcache.h> -#include <asm/keyboard.h> -#include <asm/irq.h> -#include <asm/sgialib.h> -#include <asm/sgi/sgi.h> -#include <asm/sgi/sgimc.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> - -extern struct rtc_ops indy_rtc_ops; -extern void ip22_reboot_setup(void); -extern void ip22_volume_set(unsigned char); - -#define sgi_kh ((struct hpc_keyb *) (KSEG1 + 0x1fbd9800 + 64)) - -#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ - -static void ip22_request_region(void) -{ - /* No I/O ports are being used on the Indy. */ -} - -static int ip22_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - /* Dirty hack, this get's called as a callback from the keyboard - driver. We piggyback the initialization of the front panel - button handling on it even though they're technically not - related with the keyboard driver in any way. Doing it from - indy_setup wouldn't work since kmalloc isn't initialized yet. */ - ip22_reboot_setup(); - - return request_irq(SGI_KEYBOARD_IRQ, handler, 0, "keyboard", NULL); -} - -static int ip22_aux_request_irq(void (*handler)(int, void *, struct pt_regs *)) -{ - /* Nothing to do, interrupt is shared with the keyboard hw */ - return 0; -} - -static void ip22_aux_free_irq(void) -{ - /* Nothing to do, interrupt is shared with the keyboard hw */ -} - -static unsigned char ip22_read_input(void) -{ - return sgi_kh->data; -} - -static void ip22_write_output(unsigned char val) -{ - int status; - - do { - status = sgi_kh->command; - } while (status & KBD_STAT_IBF); - sgi_kh->data = val; -} - -static void ip22_write_command(unsigned char val) -{ - int status; - - do { - status = sgi_kh->command; - } while (status & KBD_STAT_IBF); - sgi_kh->command = val; -} - -static unsigned char ip22_read_status(void) -{ - return sgi_kh->command; -} - -struct kbd_ops sgi_kbd_ops = { - ip22_request_region, - ip22_request_irq, - - ip22_aux_request_irq, - ip22_aux_free_irq, - - ip22_read_input, - ip22_write_output, - ip22_write_command, - ip22_read_status -}; - -int __init page_is_ram(unsigned long pagenr) -{ - if ((pagenr<<PAGE_SHIFT) < 0x2000UL) - return 1; - if ((pagenr<<PAGE_SHIFT) > 0x08002000) - return 1; - return 0; -} - -void __init ip22_setup(void) -{ -#ifdef CONFIG_SERIAL_CONSOLE - char *ctype; -#endif - TLBMISS_HANDLER_SETUP(); - - /* Init the INDY HPC I/O controller. Need to call this before - * fucking with the memory controller because it needs to know the - * boardID and whether this is a Guiness or a FullHouse machine. - */ - sgihpc_init(); - - /* Init INDY memory controller. */ - sgimc_init(); - - /* Now enable boardcaches, if any. */ - indy_sc_init(); - -#ifdef CONFIG_SERIAL_CONSOLE - /* ARCS console environment variable is set to "g?" for - * graphics console, it is set to "d" for the first serial - * line and "d2" for the second serial line. - */ - ctype = ArcGetEnvironmentVariable("console"); - if(*ctype == 'd') { - if(*(ctype+1)=='2') - console_setup ("ttyS1"); - else - console_setup ("ttyS0"); - } -#endif -#ifdef CONFIG_ARC_CONSOLE - console_setup("ttyS0"); -#endif - - ip22_volume_set(simple_strtoul(ArcGetEnvironmentVariable("volume"), - NULL, 10)); - -#ifdef CONFIG_VT -#ifdef CONFIG_SGI_NEWPORT_CONSOLE - conswitchp = &newport_con; - - screen_info = (struct screen_info) { - 0, 0, /* orig-x, orig-y */ - 0, /* unused */ - 0, /* orig_video_page */ - 0, /* orig_video_mode */ - 160, /* orig_video_cols */ - 0, 0, 0, /* unused, ega_bx, unused */ - 64, /* orig_video_lines */ - 0, /* orig_video_isVGA */ - 16 /* orig_video_points */ - }; -#else - conswitchp = &dummy_con; -#endif -#endif - rtc_ops = &indy_rtc_ops; - kbd_ops = &sgi_kbd_ops; -#ifdef CONFIG_PSMOUSE - aux_device_present = 0xaa; -#endif -#ifdef CONFIG_VIDEO_VINO - init_vino(); -#endif -} diff -Nru a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c --- a/arch/mips64/sgi-ip22/ip22-timer.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,262 +0,0 @@ -/* - * indy_timer.c: Setting up the clock on the INDY 8254 controller. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copytight (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) - */ -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/time.h> -#include <linux/interrupt.h> -#include <linux/timex.h> -#include <linux/kernel_stat.h> - -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/ptrace.h> -#include <asm/system.h> -#include <asm/sgi/sgi.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> -#include <asm/sgialib.h> - - -/* Because of a bug in the i8254 timer we need to use the onchip r4k - * counter as our system wide timer interrupt running at 100HZ. - */ -static unsigned long r4k_offset; /* Amount to increment compare reg each time */ -static unsigned long r4k_cur; /* What counter should be at next timer irq */ - -static inline void ack_r4ktimer(unsigned long newval) -{ - write_32bit_cp0_register(CP0_COMPARE, newval); -} - -static int set_rtc_mmss(unsigned long nowtime) -{ - struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; - int retval = 0; - int real_seconds, real_minutes, clock_minutes; - -#define FROB_FROM_CLOCK(x) (((x) & 0xf) | ((((x) & 0xf0) >> 4) * 10)); -#define FROB_TO_CLOCK(x) ((((((x) & 0xff) / 10)<<4) | (((x) & 0xff) % 10)) & 0xff) - - clock->cmd &= ~(0x80); - clock_minutes = clock->min; - clock->cmd |= (0x80); - - clock_minutes = FROB_FROM_CLOCK(clock_minutes); - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - - if(((abs(real_minutes - clock_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - - real_minutes %= 60; - if(abs(real_minutes - clock_minutes) < 30) { - /* Force clock oscillator to be on. */ - clock->month &= ~(0x80); - - /* Write real_seconds and real_minutes into the Dallas. */ - clock->cmd &= ~(0x80); - clock->sec = real_seconds; - clock->min = real_minutes; - clock->cmd |= (0x80); - } else - return -1; - -#undef FROB_FROM_CLOCK -#undef FROB_TO_CLOCK - - return retval; -} - -static long last_rtc_update; -unsigned long missed_heart_beats; - -void indy_timer_interrupt(struct pt_regs *regs) -{ - unsigned long count; - int irq = 7; - - write_seqlock(&xtime_lock); - /* Ack timer and compute new compare. */ - count = read_32bit_cp0_register(CP0_COUNT); - /* This has races. */ - if ((count - r4k_cur) >= r4k_offset) { - /* If this happens to often we'll need to compensate. */ - missed_heart_beats++; - r4k_cur = count + r4k_offset; - } - else - r4k_cur += r4k_offset; - ack_r4ktimer(r4k_cur); - kstat_cpu(0).irqs[irq]++; - do_timer(regs); - - /* We update the Dallas time of day approx. every 11 minutes, - * because of how the numbers work out we need to make - * absolutely sure we do this update within 500ms before the - * next second starts, thus the following code. - */ - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec >= 500000 - (tick >> 1) && - xtime.tv_usec <= 500000 + (tick >> 1)) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* do it again in 60s */ - last_rtc_update = xtime.tv_sec - 600; - } - write_sequnlock(&xtime_lock); -} - -static unsigned long dosample(volatile unsigned char *tcwp, - volatile unsigned char *tc2p) -{ - unsigned long ct0, ct1; - unsigned char msb, lsb; - - /* Start the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MRGEN); - *tc2p = (SGINT_TCSAMP_COUNTER & 0xff); - *tc2p = (SGINT_TCSAMP_COUNTER >> 8); - - /* Get initial counter invariant */ - ct0 = read_32bit_cp0_register(CP0_COUNT); - - /* Latch and spin until top byte of counter2 is zero */ - do { - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT); - lsb = *tc2p; - msb = *tc2p; - ct1 = read_32bit_cp0_register(CP0_COUNT); - } while(msb); - - /* Stop the counter. */ - *tcwp = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | SGINT_TCWORD_MSWST); - - /* Return the difference, this is how far the r4k counter increments - * for every one HZ. - */ - return ct1 - ct0; -} - -static unsigned long __init get_indy_time(void) -{ - struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS; - unsigned int year, mon, day, hour, min, sec; - - /* Freeze it. */ - clock->cmd &= ~(0x80); - - /* Read regs. */ - sec = clock->sec; - min = clock->min; - hour = (clock->hr & 0x3f); - day = (clock->date & 0x3f); - mon = (clock->month & 0x1f); - year = clock->year; - - /* Unfreeze clock. */ - clock->cmd |= 0x80; - - /* Frob the bits. */ -#define FROB1(x) (((x) & 0xf) + ((((x) & 0xf0) >> 4) * 10)); -#define FROB2(x) (((x) & 0xf) + (((((x) & 0xf0) >> 4) & 0x3) * 10)); - - /* XXX Should really check that secs register is the same - * XXX as when we first read it and if not go back and - * XXX read the regs above again. - */ - sec = FROB1(sec); min = FROB1(min); day = FROB1(day); - mon = FROB1(mon); year = FROB1(year); - hour = FROB2(hour); - -#undef FROB1 -#undef FROB2 - - /* Wheee... */ - if(year < 45) - year += 30; - if ((year += 1940) < 1970) - year += 100; - - return mktime(year, mon, day, hour, min, sec); -} - -#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) - -void __init indy_timer_init(void) -{ - struct sgi_ioc_timers *p; - volatile unsigned char *tcwp, *tc2p; - - /* Figure out the r4k offset, the algorithm is very simple and works - * in _all_ cases as long as the 8254 counter register itself works ok - * (as an interrupt driving timer it does not because of bug, this is - * why we are using the onchip r4k counter/compare register to serve - * this purpose, but for r4k_offset calculation it will work ok for us). - * There are other very complicated ways of performing this calculation - * but this one works just fine so I am not going to futz around. ;-) - */ - p = ioc_timers; - tcwp = &p->tcword; - tc2p = &p->tcnt2; - - printk("calculating r4koff... "); - dosample(tcwp, tc2p); /* First sample. */ - dosample(tcwp, tc2p); /* Eat one. */ - r4k_offset = dosample(tcwp, tc2p); /* Second sample. */ - - printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset); - - r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset); - write_32bit_cp0_register(CP0_COMPARE, r4k_cur); - set_cp0_status(ST0_IM, ALLINTS); - sti(); - - write_seqlock_irq(&xtime_lock); - xtime.tv_sec = get_indy_time(); /* Read time from RTC. */ - xtime.tv_usec = 0; - write_sequnlock_irq(&xtime_lock); -} - -void indy_8254timer_irq(void) -{ - int cpu = smp_processor_id(); - int irq = 4; - - irq_enter(cpu, irq); - kstat_cpu(0).irqs[irq]++; - panic("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n"); - irq_exit(cpu, irq); -} - -void do_gettimeofday(struct timeval *tv) -{ - unsigned long seq; - - do { - seq = read_seqbegin(&xtime_lock); - *tv = xtime; - } while (read_seqretry(&xtime_lock, seq)); -} - -void do_settimeofday(struct timeval *tv) -{ - write_seqlock_irq(&xtime_lock); - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; - write_sequnlock_irq(&xtime_lock); -} diff -Nru a/arch/mips64/sgi-ip22/system.c b/arch/mips64/sgi-ip22/system.c --- a/arch/mips64/sgi-ip22/system.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,123 +0,0 @@ -/* - * 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. - * - * system.c: Probe the system type using ARCS prom interface library. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/string.h> - -#include <asm/sgi/sgi.h> -#include <asm/sgialib.h> -#include <asm/bootinfo.h> - -struct smatch { - char *name; - int type; -}; - -static struct smatch sgi_cputable[] = { - { "MIPS-R2000", CPU_R2000 }, - { "MIPS-R3000", CPU_R3000 }, - { "MIPS-R3000A", CPU_R3000A }, - { "MIPS-R4000", CPU_R4000SC }, - { "MIPS-R4400", CPU_R4400SC }, - { "MIPS-R4600", CPU_R4600 }, - { "MIPS-R8000", CPU_R8000 }, - { "MIPS-R5000", CPU_R5000 }, - { "MIPS-R5000A", CPU_R5000A } -}; - -#define NUM_CPUS 9 /* for now */ - -static int __init string_to_cpu(char *s) -{ - int i; - - for(i = 0; i < NUM_CPUS; i++) { - if(!strcmp(s, sgi_cputable[i].name)) - return sgi_cputable[i].type; - } - panic("\nYeee, could not determine MIPS cpu type <%s>", s); - return 0; -} - -/* - * We' call this early before loadmmu(). If we do the other way around - * the firmware will crash and burn. - */ -void __init sgi_sysinit(void) -{ - pcomponent *p, *toplev, *cpup = 0; - int cputype = -1; - - - /* The root component tells us what machine architecture we - * have here. - */ - p = ArcGetChild(PROM_NULL_COMPONENT); - - /* Now scan for cpu(s). */ - toplev = p = ArcGetChild(p); - while(p) { - int ncpus = 0; - - if(p->type == Cpu) { - if (++ncpus > 1) - panic("\nYeee, SGI MP not ready yet"); - printk("CPU: %s ", p->iname); - cpup = p; - cputype = string_to_cpu(cpup->iname); - } - p = ArcGetPeer(p); - } - if (cputype == -1) { - panic("\nYeee, could not find cpu ARCS component"); - } - p = ArcGetChild(cpup); - while(p) { - switch(p->class) { - case processor: - switch(p->type) { - case Fpu: - printk("FPU<%s> ", p->iname); - break; - - default: - break; - }; - break; - - case cache: - switch(p->type) { - case picache: - printk("ICACHE "); - break; - - case pdcache: - printk("DCACHE "); - break; - - case sccache: - printk("SCACHE "); - break; - - default: - break; - - }; - break; - - default: - break; - }; - p = ArcGetPeer(p); - } - printk("\n"); -} diff -Nru a/arch/mips64/sgi-ip22/time.c b/arch/mips64/sgi-ip22/time.c --- a/arch/mips64/sgi-ip22/time.c Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,19 +0,0 @@ -/* - * 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. - * - * time.c: Generic SGI time_init() code, this will dispatch to the - * appropriate per-architecture time/counter init code. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#include <linux/init.h> - -extern void indy_timer_init(void); - -void __init time_init(void) -{ - /* XXX assume INDY for now XXX */ - indy_timer_init(); -} diff -Nru a/arch/mips64/sgi-ip27/Makefile b/arch/mips64/sgi-ip27/Makefile --- a/arch/mips64/sgi-ip27/Makefile Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -# -# Makefile for the IP27 specific kernel interface routines under Linux. -# - -EXTRA_AFLAGS := $(CFLAGS) - -obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ - ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \ - ip27-pci-dma.o ip27-reset.o ip27-setup.o ip27-timer.o diff -Nru a/arch/mips64/sgi-ip27/TODO b/arch/mips64/sgi-ip27/TODO --- a/arch/mips64/sgi-ip27/TODO Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,23 +0,0 @@ -1. Need to figure out why PCI writes to the IOC3 hang, and if it is okay -not to write to the IOC3 ever. -2. Need to figure out RRB allocation in bridge_startup(). -3. Need to figure out why address swaizzling is needed in inw/outw for -Qlogic scsi controllers. -4. Need to integrate ip27-klconfig.c:find_lboard and -ip27-init.c:find_lbaord_real. DONE -5. Is it okay to set calias space on all nodes as 0, instead of 8k as -in irix? -6. Investigate why things do not work without the setup_test() call -being invoked on all nodes in ip27-memory.c. -7. Too many CLIs in the locore handlers : -For the low level handlers set up by set_except_vector(), -__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror, -investigate whether the code should do CLI, STI or KMODE. -8. Too many do_page_faults invoked - investigate. -9. start_thread must turn off UX64 ... and define tlb_refill_debug. -10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable -does not agree with pgd_bad/pmd_bad. -11. All intrs (ip27_do_irq handlers) are targetted at cpu A on the node. -This might need to change later. Only the timer intr is set up to be -received on both Cpu A and B. (ip27_do_irq()/bridge_startup()) -13. Cache flushing (specially the SMP version) has to be investigated. diff -Nru a/arch/mips64/sgi-ip27/ip27-berr.c b/arch/mips64/sgi-ip27/ip27-berr.c --- a/arch/mips64/sgi-ip27/ip27-berr.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,172 +0,0 @@ -/* - * 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, 1995, 1996, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include <asm/module.h> -#include <asm/sn/addrs.h> -#include <asm/sn/arch.h> -#include <asm/sn/sn0/hub.h> -#include <asm/uaccess.h> - -extern void dump_tlb_addr(unsigned long addr); -extern void dump_tlb_all(void); - -extern asmlinkage void handle_ibe(void); -extern asmlinkage void handle_dbe(void); - -extern const struct exception_table_entry __start___dbe_table[]; -extern const struct exception_table_entry __stop___dbe_table[]; - -static inline unsigned long -search_one_table(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - while (first <= last) { - const struct exception_table_entry *mid; - long diff; - - mid = (last - first) / 2 + first; - diff = mid->insn - value; - if (diff == 0) - return mid->nextinsn; - else if (diff < 0) - first = mid+1; - else - last = mid-1; - } - return 0; -} - -extern spinlock_t modlist_lock; - -static inline unsigned long -search_dbe_table(unsigned long addr) -{ - unsigned long ret; - -#ifndef CONFIG_MODULES - /* There is only the kernel to search. */ - ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr); - return ret; -#else - unsigned long flags; - - /* The kernel is the last "module" -- no need to treat it special. */ - struct module *mp; - struct archdata *ap; - - spin_lock_irqsave(&modlist_lock, flags); - for (mp = module_list; mp != NULL; mp = mp->next) { - if (!mod_member_present(mp, archdata_end) || - !mod_archdata_member_present(mp, struct archdata, - dbe_table_end)) - continue; - ap = (struct archdata *)(mod->archdata_start); - - if (ap->dbe_table_start == NULL || - !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING))) - continue; - ret = search_one_table(ap->dbe_table_start, - ap->dbe_table_end - 1, addr); - if (ret) - break; - } - spin_unlock_irqrestore(&modlist_lock, flags); - return ret; -#endif -} - -void do_ibe(struct pt_regs *regs) -{ - printk("Got ibe at 0x%lx\n", regs->cp0_epc); - show_regs(regs); - dump_tlb_addr(regs->cp0_epc); - force_sig(SIGBUS, current); - while(1); -} - -static void dump_hub_information(unsigned long errst0, unsigned long errst1) -{ - static char *err_type[2][8] = { - { NULL, "Uncached Partial Read PRERR", "DERR", "Read Timeout", - NULL, NULL, NULL, NULL }, - { "WERR", "Uncached Partial Write", "PWERR", "Write Timeout", - NULL, NULL, NULL, NULL } - }; - int wrb = errst1 & PI_ERR_ST1_WRBRRB_MASK; - - if (!(errst0 & PI_ERR_ST0_VALID_MASK)) { - printk("Hub does not contain valid error information\n"); - return; - } - - - printk("Hub has valid error information:\n"); - if (errst0 & PI_ERR_ST0_OVERRUN_MASK) - printk("Overrun is set. Error stack may contain additional " - "information.\n"); - printk("Hub error address is %08lx\n", - (errst0 & PI_ERR_ST0_ADDR_MASK) >> (PI_ERR_ST0_ADDR_SHFT - 3)); - printk("Incoming message command 0x%lx\n", - (errst0 & PI_ERR_ST0_CMD_MASK) >> PI_ERR_ST0_CMD_SHFT); - printk("Supplemental field of incoming message is 0x%lx\n", - (errst0 & PI_ERR_ST0_SUPPL_MASK) >> PI_ERR_ST0_SUPPL_SHFT); - printk("T5 Rn (for RRB only) is 0x%lx\n", - (errst0 & PI_ERR_ST0_REQNUM_MASK) >> PI_ERR_ST0_REQNUM_SHFT); - printk("Error type is %s\n", err_type[wrb] - [(errst0 & PI_ERR_ST0_TYPE_MASK) >> PI_ERR_ST0_TYPE_SHFT] - ? : "invalid"); -} - -void do_dbe(struct pt_regs *regs) -{ - unsigned long fixup, errst0, errst1; - int cpu = LOCAL_HUB_L(PI_CPU_NUM); - - fixup = search_dbe_table(regs->cp0_epc); - if (fixup) { - long new_epc; - - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); - regs->cp0_epc = new_epc; - return; - } - - printk("Slice %c got dbe at 0x%lx\n", 'A' + cpu, regs->cp0_epc); - printk("Hub information:\n"); - printk("ERR_INT_PEND = 0x%06lx\n", LOCAL_HUB_L(PI_ERR_INT_PEND)); - errst0 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS0_B : PI_ERR_STATUS0_A); - errst1 = LOCAL_HUB_L(cpu ? PI_ERR_STATUS1_B : PI_ERR_STATUS1_A); - dump_hub_information(errst0, errst1); - show_regs(regs); - dump_tlb_all(); - while(1); - force_sig(SIGBUS, current); -} - -void __init -bus_error_init(void) -{ - /* XXX Initialize all the Hub & Bridge error handling here. */ - int cpu = LOCAL_HUB_L(PI_CPU_NUM); - int cpuoff = cpu << 8; - - set_except_vector(6, handle_ibe); - set_except_vector(7, handle_dbe); - - LOCAL_HUB_S(PI_ERR_INT_PEND, - cpu ? PI_ERR_CLEAR_ALL_B : PI_ERR_CLEAR_ALL_A); - LOCAL_HUB_S(PI_ERR_INT_MASK_A + cpuoff, 0); - LOCAL_HUB_S(PI_ERR_STACK_ADDR_A + cpuoff, 0); - LOCAL_HUB_S(PI_ERR_STACK_SIZE, 0); /* Disable error stack */ - LOCAL_HUB_S(PI_SYSAD_ERRCHK_EN, PI_SYSAD_CHECK_ALL); -} diff -Nru a/arch/mips64/sgi-ip27/ip27-console.c b/arch/mips64/sgi-ip27/ip27-console.c --- a/arch/mips64/sgi-ip27/ip27-console.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,58 +0,0 @@ -/* - * 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) 2001 Ralf Baechle - */ -#include <linux/init.h> -#include <linux/console.h> -#include <linux/kdev_t.h> -#include <linux/major.h> -#include <asm/sn/addrs.h> -#include <asm/sn/sn0/hub.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/ioc3.h> -#include <asm/sn/sn_private.h> - -void prom_putchar(char c) -{ - struct ioc3 *ioc3; - struct ioc3_uartregs *uart; - - ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base; - uart = &ioc3->sregs.uarta; - - while ((uart->iu_lsr & 0x20) == 0); - uart->iu_thr = c; -} - -char __init prom_getchar(void) -{ - return 0; -} - -static void -ip27prom_console_write(struct console *con, const char *s, unsigned n) -{ - prom_printf("%s", s); -} - -static kdev_t -ip27prom_console_dev(struct console *c) -{ - return MKDEV(TTY_MAJOR, 64 + c->index); -} - -static struct console ip27_prom_console = { - .name = "prom", - .write = ip27prom_console_write, - .device = ip27prom_console_dev, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -__init void ip27_setup_console(void) -{ - register_console(&ip27_prom_console); -} diff -Nru a/arch/mips64/sgi-ip27/ip27-init.c b/arch/mips64/sgi-ip27/ip27-init.c --- a/arch/mips64/sgi-ip27/ip27-init.c Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,840 +0,0 @@ -/* - * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com) - * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. - */ - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/mmzone.h> /* for numnodes */ -#include <linux/mm.h> -#include <asm/pgalloc.h> -#include <asm/pgtable.h> -#include <asm/sn/types.h> -#include <asm/sn/sn0/addrs.h> -#include <asm/sn/sn0/hubni.h> -#include <asm/sn/sn0/hubio.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/ioc3.h> -#include <asm/mipsregs.h> -#include <asm/sn/gda.h> -#include <asm/sn/intr.h> -#include <asm/current.h> -#include <asm/smp.h> -#include <asm/processor.h> -#include <asm/mmu_context.h> -#include <asm/sn/launch.h> -#include <asm/sn/sn_private.h> -#include <asm/sn/sn0/ip27.h> -#include <asm/sn/mapped_kernel.h> -#include <asm/sn/sn0/addrs.h> -#include <asm/sn/gda.h> - -#define CPU_NONE (cpuid_t)-1 - -/* - * The following should work till 64 nodes, ie 128p SN0s. - */ -#define CNODEMASK_CLRALL(p) (p) = 0 -#define CNODEMASK_TSTB(p, bit) ((p) & (1ULL << (bit))) -#define CNODEMASK_SETB(p, bit) ((p) |= 1ULL << (bit)) - -cpumask_t boot_cpumask; -hubreg_t region_mask = 0; -static int fine_mode = 0; -int maxcpus; -static spinlock_t hub_mask_lock = SPIN_LOCK_UNLOCKED; -static cnodemask_t hub_init_mask; -static atomic_t numstarted = ATOMIC_INIT(1); -static int router_distance; -nasid_t master_nasid = INVALID_NASID; - -cnodeid_t nasid_to_compact_node[MAX_NASIDS]; -nasid_t compact_to_nasid_node[MAX_COMPACT_NODES]; -cnodeid_t cpuid_to_compact_node[MAXCPUS]; -char node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES]; - -hubreg_t get_region(cnodeid_t cnode) -{ - if (fine_mode) - return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; - else - return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; -} - -static void gen_region_mask(hubreg_t *region_mask, int maxnodes) -{ - cnodeid_t cnode; - - (*region_mask) = 0; - for (cnode = 0; cnode < maxnodes; cnode++) { - (*region_mask) |= 1ULL << get_region(cnode); - } -} - -int is_fine_dirmode(void) -{ - return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) - >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE); -} - -nasid_t get_actual_nasid(lboard_t *brd) -{ - klhub_t *hub; - - if (!brd) - return INVALID_NASID; - - /* find out if we are a completely disabled brd. */ - hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB); - if (!hub) - return INVALID_NASID; - if (!(hub->hub_info.flags & KLINFO_ENABLE)) /* disabled node brd */ - return hub->hub_info.physid; - else - return brd->brd_nasid; -} - -/* Tweak this for maximum number of CPUs to activate */ -static int max_cpus = NR_CPUS; - -int do_cpumask(cnodeid_t cnode, nasid_t nasid, cpumask_t *boot_cpumask, - int *highest) -{ - static int tot_cpus_found = 0; - lboard_t *brd; - klcpu_t *acpu; - int cpus_found = 0; - cpuid_t cpuid; - - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); - - do { - acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU); - while (acpu) { - cpuid = acpu->cpu_info.virtid; - /* cnode is not valid for completely disabled brds */ - if (get_actual_nasid(brd) == brd->brd_nasid) - cpuid_to_compact_node[cpuid] = cnode; - if (cpuid > *highest) - *highest = cpuid; - /* Only let it join in if it's marked enabled */ - if ((acpu->cpu_info.flags & KLINFO_ENABLE) && - (tot_cpus_found != max_cpus)) { - CPUMASK_SETB(*boot_cpumask, cpuid); - cpus_found++; - tot_cpus_found++; - } - acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, - KLSTRUCT_CPU); - } - brd = KLCF_NEXT(brd); - if (brd) - brd = find_lboard(brd,KLTYPE_IP27); - else - break; - } while (brd); - - return cpus_found; -} - -cpuid_t cpu_node_probe(cpumask_t *boot_cpumask, int *numnodes) -{ - int i, cpus = 0, highest = 0; - gda_t *gdap = GDA; - nasid_t nasid; - - /* - * Initialize the arrays to invalid nodeid (-1) - */ - for (i = 0; i < MAX_COMPACT_NODES; i++) - compact_to_nasid_node[i] = INVALID_NASID; - for (i = 0; i < MAX_NASIDS; i++) - nasid_to_compact_node[i] = INVALID_CNODEID; - for (i = 0; i < MAXCPUS; i++) - cpuid_to_compact_node[i] = INVALID_CNODEID; - - *numnodes = 0; - for (i = 0; i < MAX_COMPACT_NODES; i++) { - if ((nasid = gdap->g_nasidtable[i]) == INVALID_NASID) { - break; - } else { - compact_to_nasid_node[i] = nasid; - nasid_to_compact_node[nasid] = i; - (*numnodes)++; - cpus += do_cpumask(i, nasid, boot_cpumask, &highest); - } - } - - /* - * Cpus are numbered in order of cnodes. Currently, disabled - * cpus are not numbered. - */ - - return(highest + 1); -} - -int cpu_enabled(cpuid_t cpu) -{ - if (cpu == CPU_NONE) - return 0; - return (CPUMASK_TSTB(boot_cpumask, cpu) != 0); -} - -void mlreset (void) -{ - int i; - void init_topology_matrix(void); - void dump_topology(void); - - - master_nasid = get_nasid(); - fine_mode = is_fine_dirmode(); - - /* - * Probe for all CPUs - this creates the cpumask and - * sets up the mapping tables. - */ - CPUMASK_CLRALL(boot_cpumask); - maxcpus = cpu_node_probe(&boot_cpumask, &numnodes); - printk("Discovered %d cpus on %d nodes\n", maxcpus, numnodes); - - init_topology_matrix(); - dump_topology(); - - gen_region_mask(®ion_mask, numnodes); - CNODEMASK_CLRALL(hub_init_mask); - - setup_replication_mask(numnodes); - - /* - * Set all nodes' calias sizes to 8k - */ - for (i = 0; i < numnodes; i++) { - nasid_t nasid; - - nasid = COMPACT_TO_NASID_NODEID(i); - - /* - * Always have node 0 in the region mask, otherwise - * CALIAS accesses get exceptions since the hub - * thinks it is a node 0 address. - */ - REMOTE_HUB_S(nasid, PI_REGION_PRESENT, (region_mask | 1)); -#ifdef CONFIG_REPLICATE_EXHANDLERS - REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_8K); -#else - REMOTE_HUB_S(nasid, PI_CALIAS_SIZE, PI_CALIAS_SIZE_0); -#endif - -#ifdef LATER - /* - * Set up all hubs to have a big window pointing at - * widget 0. Memory mode, widget 0, offset 0 - */ - REMOTE_HUB_S(nasid, IIO_ITTE(SWIN0_BIGWIN), - ((HUB_PIO_MAP_TO_MEM << IIO_ITTE_IOSP_SHIFT) | - (0 << IIO_ITTE_WIDGET_SHIFT))); -#endif - } -} - - -void intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level, - char *name) -{ - volatile hubreg_t bits; - int i; - - /* Check pending interrupts */ - if ((bits = HUB_L(pend)) != 0) - for (i = 0; i < N_INTPEND_BITS; i++) - if (bits & (1 << i)) - LOCAL_HUB_CLR_INTR(base_level + i); -} - -void intr_clear_all(nasid_t nasid) -{ - REMOTE_HUB_S(nasid, PI_INT_MASK0_A, 0); - REMOTE_HUB_S(nasid, PI_INT_MASK0_B, 0); - REMOTE_HUB_S(nasid, PI_INT_MASK1_A, 0); - REMOTE_HUB_S(nasid, PI_INT_MASK1_B, 0); - intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND0), - INT_PEND0_BASELVL, "INT_PEND0"); - intr_clear_bits(nasid, REMOTE_HUB_ADDR(nasid, PI_INT_PEND1), - INT_PEND1_BASELVL, "INT_PEND1"); -} - -void sn_mp_setup(void) -{ - cnodeid_t cnode; -#if 0 - cpuid_t cpu; -#endif - - for (cnode = 0; cnode < numnodes; cnode++) { -#if 0 - init_platform_nodepda(); -#endif - intr_clear_all(COMPACT_TO_NASID_NODEID(cnode)); - } -#if 0 - for (cpu = 0; cpu < maxcpus; cpu++) { - init_platform_pda(); - } -#endif -} - -void per_hub_init(cnodeid_t cnode) -{ - extern void pcibr_setup(cnodeid_t); - cnodemask_t done; - nasid_t nasid; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - - spin_lock(&hub_mask_lock); - /* Test our bit. */ - if (!(done = CNODEMASK_TSTB(hub_init_mask, cnode))) { - /* Turn our bit on in the mask. */ - CNODEMASK_SETB(hub_init_mask, cnode); - /* - * Do the actual initialization if it hasn't been done yet. - * We don't need to hold a lock for this work. - */ - /* - * Set CRB timeout at 5ms, (< PI timeout of 10ms) - */ - REMOTE_HUB_S(nasid, IIO_ICTP, 0x800); - REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); - hub_rtc_init(cnode); - pcibr_setup(cnode); -#ifdef CONFIG_REPLICATE_EXHANDLERS - /* - * If this is not a headless node initialization, - * copy over the caliased exception handlers. - */ - if (get_compact_nodeid() == cnode) { - extern char except_vec0, except_vec1_r10k; - extern char except_vec2_generic, except_vec3_generic; - - memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, - 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, - 0x80); - memcpy((void *)KSEG0, &except_vec0, 0x80); - memcpy((void *)KSEG0 + 0x080, &except_vec1_r10k, 0x80); - memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80); - memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, - 0x100); - flush_cache_l1(); - flush_cache_l2(); - } -#endif - } - spin_unlock(&hub_mask_lock); -} - -/* - * This is similar to hard_smp_processor_id(). - */ -cpuid_t getcpuid(void) -{ - klcpu_t *klcpu; - - klcpu = nasid_slice_to_cpuinfo(get_nasid(),LOCAL_HUB_L(PI_CPU_NUM)); - return klcpu->cpu_info.virtid; -} - -void per_cpu_init(void) -{ - extern void install_cpu_nmi_handler(int slice); - extern void load_mmu(void); - static int is_slave = 0; - int cpu = smp_processor_id(); - cnodeid_t cnode = get_compact_nodeid(); - - current_cpu_data.asid_cache = ASID_FIRST_VERSION; - TLBMISS_HANDLER_SETUP(); -#if 0 - intr_init(); -#endif - set_cp0_status(ST0_IM, 0); - per_hub_init(cnode); - cpu_time_init(); - if (smp_processor_id()) /* master can't do this early, no kmalloc */ - install_cpuintr(cpu); - /* Install our NMI handler if symmon hasn't installed one. */ - install_cpu_nmi_handler(cputoslice(cpu)); -#if 0 - install_tlbintr(cpu); -#endif - set_cp0_status(SRB_DEV0 | SRB_DEV1, SRB_DEV0 | SRB_DEV1); - if (is_slave) { - set_cp0_status(ST0_BEV, 0); - if (mips4_available) - set_cp0_status(ST0_XX, ST0_XX); - set_cp0_status(ST0_KX|ST0_SX|ST0_UX, ST0_KX|ST0_SX|ST0_UX); - sti(); - load_mmu(); - atomic_inc(&numstarted); - } else { - is_slave = 1; - } -} - -cnodeid_t get_compact_nodeid(void) -{ - nasid_t nasid; - - nasid = get_nasid(); - /* - * Map the physical node id to a virtual node id (virtual node ids - * are contiguous). - */ - return NASID_TO_COMPACT_NODEID(nasid); -} - -#ifdef CONFIG_SMP - -/* - * Takes as first input the PROM assigned cpu id, and the kernel - * assigned cpu id as the second. - */ -static void alloc_cpupda(cpuid_t cpu, int cpunum) -{ - cnodeid_t node; - nasid_t nasid; - - node = get_cpu_cnode(cpu); - nasid = COMPACT_TO_NASID_NODEID(node); - - cputonasid(cpunum) = nasid; - cputocnode(cpunum) = node; - cputoslice(cpunum) = get_cpu_slice(cpu); - cpu_data[cpunum].p_cpuid = cpu; -} - -void __init smp_callin(void) -{ -#if 0 - calibrate_delay(); - smp_store_cpu_info(cpuid); -#endif -} - -int __init start_secondary(void) -{ - extern int cpu_idle(void); - extern atomic_t smp_commenced; - - smp_callin(); - while (!atomic_read(&smp_commenced)); - return cpu_idle(); -} - -static volatile cpumask_t boot_barrier; - -void cboot(void) -{ - CPUMASK_CLRB(boot_barrier, getcpuid()); /* needs atomicity */ - per_cpu_init(); -#if 0 - ecc_init(); - bte_lateinit(); - init_mfhi_war(); -#endif - _flush_tlb_all(); - flush_cache_l1(); - flush_cache_l2(); - start_secondary(); -} - -void allowboot(void) -{ - int num_cpus = 0; - cpuid_t cpu, mycpuid = getcpuid(); - cnodeid_t cnode; - extern void bootstrap(void); - - sn_mp_setup(); - /* Master has already done per_cpu_init() */ - install_cpuintr(smp_processor_id()); -#if 0 - bte_lateinit(); - ecc_init(); -#endif - - replicate_kernel_text(numnodes); - boot_barrier = boot_cpumask; - /* Launch slaves. */ - for (cpu = 0; cpu < maxcpus; cpu++) { - if (cpu == mycpuid) { - alloc_cpupda(cpu, num_cpus); - num_cpus++; - /* We're already started, clear our bit */ - CPUMASK_CLRB(boot_barrier, cpu); - continue; - } - - /* Skip holes in CPU space */ - if (CPUMASK_TSTB(boot_cpumask, cpu)) { - struct task_struct *p; - - /* - * The following code is purely to make sure - * Linux can schedule processes on this slave. - */ - kernel_thread(0, NULL, CLONE_IDLETASK); - p = prev_task(&init_task); - sprintf(p->comm, "%s%d", "Idle", num_cpus); - init_tasks[num_cpus] = p; - alloc_cpupda(cpu, num_cpus); - del_from_runqueue(p); - p->processor = num_cpus; - p->cpus_runnable = 1 << num_cpus; /* we schedule the first task manually */ - unhash_process(p); - /* Attach to the address space of init_task. */ - atomic_inc(&init_mm.mm_count); - p->active_mm = &init_mm; - - /* - * Launch a slave into bootstrap(). - * It doesn't take an argument, and we - * set sp to the kernel stack of the newly - * created idle process, gp to the proc struct - * (so that current-> works). - */ - LAUNCH_SLAVE(cputonasid(num_cpus),cputoslice(num_cpus), - (launch_proc_t)MAPPED_KERN_RW_TO_K0(bootstrap), - 0, (void *)((unsigned long)p + - KERNEL_STACK_SIZE - 32), (void *)p); - - /* - * Now optimistically set the mapping arrays. We - * need to wait here, verify the cpu booted up, then - * fire up the next cpu. - */ - __cpu_number_map[cpu] = num_cpus; - __cpu_logical_map[num_cpus] = cpu; - num_cpus++; - /* - * Wait this cpu to start up and initialize its hub, - * and discover the io devices it will control. - * - * XXX: We really want to fire up launch all the CPUs - * at once. We have to preserve the order of the - * devices on the bridges first though. - */ - while(atomic_read(&numstarted) != num_cpus); - } - } - - -#ifdef LATER - Wait logic goes here. -#endif - for (cnode = 0; cnode < numnodes; cnode++) { -#if 0 - if (cnodetocpu(cnode) == -1) { - printk("Initializing headless hub,cnode %d", cnode); - per_hub_init(cnode); - } -#endif - } -#if 0 - cpu_io_setup(); - init_mfhi_war(); -#endif - smp_num_cpus = num_cpus; -} - -#else /* CONFIG_SMP */ -void cboot(void) {} -#endif /* CONFIG_SMP */ - - -#define rou_rflag rou_flags - -void -router_recurse(klrou_t *router_a, klrou_t *router_b, int depth) -{ - klrou_t *router; - lboard_t *brd; - int port; - - if (router_a->rou_rflag == 1) - return; - - if (depth >= router_distance) - return; - - router_a->rou_rflag = 1; - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - if (router_a->rou_port[port].port_nasid == INVALID_NASID) - continue; - - brd = (lboard_t *)NODE_OFFSET_TO_K0( - router_a->rou_port[port].port_nasid, - router_a->rou_port[port].port_offset); - - if (brd->brd_type == KLTYPE_ROUTER) { - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); - if (router == router_b) { - if (depth < router_distance) - router_distance = depth; - } - else - router_recurse(router, router_b, depth + 1); - } - } - - router_a->rou_rflag = 0; -} - -int -node_distance(nasid_t nasid_a, nasid_t nasid_b) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd, *dest_brd; - int port; - klrou_t *router, *router_a = NULL, *router_b = NULL; - - /* Figure out which routers nodes in question are connected to */ - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - if (nasid == -1) continue; - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - continue; - - do { - if (brd->brd_flags & DUPLICATE_BOARD) - continue; - - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); - router->rou_rflag = 0; - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - if (router->rou_port[port].port_nasid == INVALID_NASID) - continue; - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - router->rou_port[port].port_nasid, - router->rou_port[port].port_offset); - - if (dest_brd->brd_type == KLTYPE_IP27) { - if (dest_brd->brd_nasid == nasid_a) - router_a = router; - if (dest_brd->brd_nasid == nasid_b) - router_b = router; - } - } - - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); - } - - if (router_a == NULL) { - printk("node_distance: router_a NULL\n"); - return -1; - } - if (router_b == NULL) { - printk("node_distance: router_b NULL\n"); - return -1; - } - - if (nasid_a == nasid_b) - return 0; - - if (router_a == router_b) - return 1; - - router_distance = 100; - router_recurse(router_a, router_b, 2); - - return router_distance; -} - -void -init_topology_matrix(void) -{ - nasid_t nasid, nasid2; - cnodeid_t row, col; - - for (row = 0; row < MAX_COMPACT_NODES; row++) - for (col = 0; col < MAX_COMPACT_NODES; col++) - node_distances[row][col] = -1; - - for (row = 0; row < numnodes; row++) { - nasid = COMPACT_TO_NASID_NODEID(row); - for (col = 0; col < numnodes; col++) { - nasid2 = COMPACT_TO_NASID_NODEID(col); - node_distances[row][col] = node_distance(nasid, nasid2); - } - } -} - -void -dump_topology(void) -{ - nasid_t nasid; - cnodeid_t cnode; - lboard_t *brd, *dest_brd; - int port; - int router_num = 0; - klrou_t *router; - cnodeid_t row, col; - - printk("************** Topology ********************\n"); - - printk(" "); - for (col = 0; col < numnodes; col++) - printk("%02d ", col); - printk("\n"); - for (row = 0; row < numnodes; row++) { - printk("%02d ", row); - for (col = 0; col < numnodes; col++) - printk("%2d ", node_distances[row][col]); - printk("\n"); - } - - for (cnode = 0; cnode < numnodes; cnode++) { - nasid = COMPACT_TO_NASID_NODEID(cnode); - - if (nasid == -1) continue; - - brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_ROUTER); - - if (!brd) - continue; - - do { - if (brd->brd_flags & DUPLICATE_BOARD) - continue; - printk("Router %d:", router_num); - router_num++; - - router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); - - for (port = 1; port <= MAX_ROUTER_PORTS; port++) { - if (router->rou_port[port].port_nasid == INVALID_NASID) - continue; - - dest_brd = (lboard_t *)NODE_OFFSET_TO_K0( - router->rou_port[port].port_nasid, - router->rou_port[port].port_offset); - - if (dest_brd->brd_type == KLTYPE_IP27) - printk(" %d", dest_brd->brd_nasid); - if (dest_brd->brd_type == KLTYPE_ROUTER) - printk(" r"); - } - printk("\n"); - - } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); - } -} - -#if 0 -#define brd_widgetnum brd_slot -#define NODE_OFFSET_TO_KLINFO(n,off) ((klinfo_t*) TO_NODE_CAC(n,off)) -void -dump_klcfg(void) -{ - cnodeid_t cnode; - int i; - nasid_t nasid; - lboard_t *lbptr; - gda_t *gdap; - - gdap = (gda_t *)GDA_ADDR(get_nasid()); - if (gdap->g_magic != GDA_MAGIC) { - printk("dumpklcfg_cmd: Invalid GDA MAGIC\n"); - return; - } - - for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) { - nasid = gdap->g_nasidtable[cnode]; - - if (nasid == INVALID_NASID) - continue; - - printk("\nDumpping klconfig Nasid %d:\n", nasid); - - lbptr = KL_CONFIG_INFO(nasid); - - while (lbptr) { - printk(" %s, Nasid %d, Module %d, widget 0x%x, partition %d, NIC 0x%x lboard 0x%lx", - "board name here", /* BOARD_NAME(lbptr->brd_type), */ - lbptr->brd_nasid, lbptr->brd_module, - lbptr->brd_widgetnum, - lbptr->brd_partition, - (lbptr->brd_nic), lbptr); - if (lbptr->brd_flags & DUPLICATE_BOARD) - printk(" -D"); - printk("\n"); - for (i = 0; i < lbptr->brd_numcompts; i++) { - klinfo_t *kli; - kli = NODE_OFFSET_TO_KLINFO(NASID_GET(lbptr), lbptr->brd_compts[i]); - printk(" type %2d, flags 0x%04x, diagval %3d, physid %4d, virtid %2d: %s\n", - kli->struct_type, - kli->flags, - kli->diagval, - kli->physid, - kli->virtid, - "comp. name here"); - /* COMPONENT_NAME(kli->struct_type)); */ - } - lbptr = KLCF_NEXT(lbptr); - } - } - printk("\n"); - - /* Useful to print router maps also */ - - for (cnode = 0; cnode < MAX_COMPACT_NODES; cnode ++) { - klrou_t *kr; - int i; - - nasid = gdap->g_nasidtable[cnode]; - if (nasid == INVALID_NASID) - continue; - lbptr = KL_CONFIG_INFO(nasid); - - while (lbptr) { - - lbptr = find_lboard_class(lbptr, KLCLASS_ROUTER); - if(!lbptr) - break; - if (!KL_CONFIG_DUPLICATE_BOARD(lbptr)) { - printk("%llx -> \n", lbptr->brd_nic); - kr = (klrou_t *)find_first_component(lbptr, - KLSTRUCT_ROU); - for (i = 1; i <= MAX_ROUTER_PORTS; i++) { - printk("[%d, %llx]; ", - kr->rou_port[i].port_nasid, - kr->rou_port[i].port_offset); - } - printk("\n"); - } - lbptr = KLCF_NEXT(lbptr); - } - printk("\n"); - } - - dump_topology(); -} -#endif - diff -Nru a/arch/mips64/sgi-ip27/ip27-irq-glue.S b/arch/mips64/sgi-ip27/ip27-irq-glue.S --- a/arch/mips64/sgi-ip27/ip27-irq-glue.S Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,64 +0,0 @@ -/* - * 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) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include <asm/asm.h> -#include <asm/mipsregs.h> -#include <asm/regdef.h> -#include <asm/stackframe.h> - - .text - .set noat - .align 5 -NESTED(ip27_irq, PT_SIZE, sp) - SAVE_ALL - CLI - .set at - - /* IP27 may signal interrupt which we're not interested in. - Mask them out. */ - mfc0 s0, CP0_CAUSE - mfc0 t0, CP0_STATUS - and s0, t0 - - /* First check for RT interrupt. */ - andi a0, s0, CAUSEF_IP4 - beqz a0, 1f - - /* Ok, a timer interrupt. */ - move a0, sp - jal rt_timer_interrupt - - j ret_from_irq - -1: andi a0, s0, (CAUSEF_IP2 | CAUSEF_IP3) - beqz a0, 1f - - /* ... a device interrupt ... */ - move a0, sp - jal ip27_do_irq - - j ret_from_irq - -1: -#if 1 - mfc0 a1, CP0_STATUS - srl a1, a1, 8 - andi a1, 0xff - - mfc0 a2, CP0_CAUSE - srl a2, a2, 8 - andi a2, 0xff - - move a3, s0 - PRINT("Spurious interrupt, c0_status = %02x, c0_cause = %02x, pending %02x.\n") - ld a1, PT_EPC(sp) -0: b 0b -#endif - - j ret_from_irq - END(ip27_irq) diff -Nru a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c --- a/arch/mips64/sgi-ip27/ip27-irq.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,769 +0,0 @@ -/* - * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. - * - * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 1999 - 2001 Kanoj Sarcar - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/timex.h> -#include <linux/slab.h> -#include <linux/random.h> -#include <linux/smp_lock.h> -#include <linux/kernel_stat.h> -#include <linux/delay.h> -#include <linux/irq.h> -#include <linux/seq_file.h> - -#include <asm/bitops.h> -#include <asm/bootinfo.h> -#include <asm/io.h> -#include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/irq.h> - -#include <asm/ptrace.h> -#include <asm/processor.h> -#include <asm/pci/bridge.h> -#include <asm/sn/sn0/hub.h> -#include <asm/sn/sn0/ip27.h> -#include <asm/sn/arch.h> -#include <asm/sn/intr.h> -#include <asm/sn/intr_public.h> - -#undef DEBUG_IRQ -#ifdef DEBUG_IRQ -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* These should die */ -unsigned char bus_to_wid[256]; /* widget id for linux pci bus */ -unsigned char bus_to_nid[256]; /* nasid for linux pci bus */ -unsigned char num_bridges; /* number of bridges in the system */ - -/* - * Linux has a controller-independent x86 interrupt architecture. - * every controller has a 'controller-template', that is used - * by the main code to do the right thing. Each driver-visible - * interrupt source is transparently wired to the apropriate - * controller. Thus drivers need not be aware of the - * interrupt-controller. - * - * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, - * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. - * (IO-APICs assumed to be messaging to Pentium local-APICs) - * - * the code is designed to be easily extended with new/different - * interrupt controllers, without having to do assembly magic. - */ - -extern asmlinkage void ip27_irq(void); -extern int irq_to_bus[], irq_to_slot[], bus_to_cpu[]; -int intr_connect_level(int cpu, int bit); -int intr_disconnect_level(int cpu, int bit); - -unsigned long spurious_count = 0; - -/* - * There is a single intpend register per node, and we want to have - * distinct levels for intercpu intrs for both cpus A and B on a node. - */ -int node_level_to_irq[MAX_COMPACT_NODES][PERNODE_LEVELS]; - -/* - * use these macros to get the encoded nasid and widget id - * from the irq value - */ -#define IRQ_TO_BUS(i) irq_to_bus[(i)] -#define IRQ_TO_CPU(i) bus_to_cpu[IRQ_TO_BUS(i)] -#define NASID_FROM_PCI_IRQ(i) bus_to_nid[IRQ_TO_BUS(i)] -#define WID_FROM_PCI_IRQ(i) bus_to_wid[IRQ_TO_BUS(i)] -#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i] - -static inline int alloc_level(cpuid_t cpunum, int irq) -{ - cnodeid_t nodenum = CPUID_TO_COMPACT_NODEID(cpunum); - int j = LEAST_LEVEL + 3; /* resched & crosscall entries taken */ - - while (++j < PERNODE_LEVELS) { - if (node_level_to_irq[nodenum][j] == -1) { - node_level_to_irq[nodenum][j] = irq; - return j; - } - } - printk("Cpu %ld flooded with devices\n", cpunum); - while(1); - return -1; -} - -static inline int find_level(cpuid_t *cpunum, int irq) -{ - int j; - cnodeid_t nodenum = INVALID_CNODEID; - - while (++nodenum < MAX_COMPACT_NODES) { - j = LEAST_LEVEL + 3; /* resched & crosscall entries taken */ - while (++j < PERNODE_LEVELS) - if (node_level_to_irq[nodenum][j] == irq) { - *cpunum = 0; /* XXX Fixme */ - return(j); - } - } - printk("Could not identify cpu/level for irq %d\n", irq); - while(1); - return(-1); -} - - -void disable_irq(unsigned int irq_nr) -{ - panic("disable_irq() called ..."); -} - -void enable_irq(unsigned int irq_nr) -{ - panic("enable_irq() called ..."); -} - -/* This is stupid for an Origin which can have thousands of IRQs ... */ -static struct irqaction *irq_action[NR_IRQS]; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i; - struct irqaction * action; - unsigned long flags; - - for (i = 0 ; i < NR_IRQS ; i++) { - local_irq_save(flags); - action = irq_action[i]; - if (!action) - goto skip; - seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i], - (action->flags & SA_INTERRUPT) ? '+' : ' ', - action->name); - for (action=action->next; action; action = action->next) { - seq_printf(p, ",%s %s", - (action->flags & SA_INTERRUPT) - ? " +" : "", - action->name); - } - seq_putc(p, '\n'); -skip: - local_irq_restore(flags); - } - return 0; -} - -/* - * do_IRQ handles all normal device IRQ's (the special SMP cross-CPU interrupts - * have their own specific handlers). - */ -static void do_IRQ(cpuid_t thiscpu, int irq, struct pt_regs * regs) -{ - struct irqaction *action; - int do_random; - - irq_enter(thiscpu, irq); - kstat_cpu(thiscpu).irqs[irq]++; - - action = *(irq + irq_action); - if (action) { - if (!(action->flags & SA_INTERRUPT)) - local_irq_enable(); - do_random = 0; - do { - do_random |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (do_random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - local_irq_disable(); - } - irq_exit(thiscpu, irq); - - if (softirq_pending(thiscpu)) - do_softirq(); -} - -/* - * Find first bit set - */ -static int ms1bit(unsigned long x) -{ - int b; - - if (x >> 32) b = 32, x >>= 32; - else b = 0; - if (x >> 16) b += 16, x >>= 16; - if (x >> 8) b += 8, x >>= 8; - if (x >> 4) b += 4, x >>= 4; - if (x >> 2) b += 2, x >>= 2; - - return b + (int) (x >> 1); -} - -/* - * This code is unnecessarily complex, because we do SA_INTERRUPT - * intr enabling. Basically, once we grab the set of intrs we need - * to service, we must mask _all_ these interrupts; firstly, to make - * sure the same intr does not intr again, causing recursion that - * can lead to stack overflow. Secondly, we can not just mask the - * one intr we are do_IRQing, because the non-masked intrs in the - * first set might intr again, causing multiple servicings of the - * same intr. This effect is mostly seen for intercpu intrs. - * Kanoj 05.13.00 - */ -void ip27_do_irq(struct pt_regs *regs) -{ - int irq, swlevel; - hubreg_t pend0, mask0; - cpuid_t thiscpu = smp_processor_id(); - int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ? - PI_INT_MASK0_A : PI_INT_MASK0_B); - - /* copied from Irix intpend0() */ - while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) & - (mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) { - pend0 &= mask0; /* Pick intrs we should look at */ - if (pend0) { - /* Prevent any of the picked intrs from recursing */ - LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0)); - do { - swlevel = ms1bit(pend0); - LOCAL_HUB_CLR_INTR(swlevel); - /* "map" swlevel to irq */ - irq = LEVEL_TO_IRQ(thiscpu, swlevel); - do_IRQ(thiscpu, irq, regs); - /* clear bit in pend0 */ - pend0 ^= 1ULL << swlevel; - } while(pend0); - /* Now allow the set of serviced intrs again */ - LOCAL_HUB_S(pi_int_mask0, mask0); - LOCAL_HUB_L(PI_INT_PEND0); - } - } -} - - -/* Startup one of the (PCI ...) IRQs routes over a bridge. */ -static unsigned int bridge_startup(unsigned int irq) -{ - bridgereg_t device; - bridge_t *bridge; - int pin, swlevel; - cpuid_t cpu; - nasid_t master = NASID_FROM_PCI_IRQ(irq); - - bridge = (bridge_t *) NODE_SWIN_BASE(master, WID_FROM_PCI_IRQ(irq)); - pin = SLOT_FROM_PCI_IRQ(irq); - cpu = IRQ_TO_CPU(irq); - - DBG("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); - /* - * "map" irq to a swlevel greater than 6 since the first 6 bits - * of INT_PEND0 are taken - */ - swlevel = alloc_level(cpu, irq); - intr_connect_level(cpu, swlevel); - - bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (master << 8)); - bridge->b_int_enable |= (1 << pin); - /* more stuff in int_enable reg */ - bridge->b_int_enable |= 0x7ffffe00; - - /* - * XXX This only works if b_int_device is initialized to 0! - * We program the bridge to have a 1:1 mapping between devices - * (slots) and intr pins. - */ - device = bridge->b_int_device; - device |= (pin << (pin*3)); - bridge->b_int_device = device; - - bridge->b_widget.w_tflush; /* Flush */ - - return 0; /* Never anything pending. */ -} - -/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ -static unsigned int bridge_shutdown(unsigned int irq) -{ - bridge_t *bridge; - int pin, swlevel; - cpuid_t cpu; - - bridge = (bridge_t *) NODE_SWIN_BASE(NASID_FROM_PCI_IRQ(irq), - WID_FROM_PCI_IRQ(irq)); - DBG("bridge_shutdown: irq 0x%x\n", irq); - pin = SLOT_FROM_PCI_IRQ(irq); - - /* - * map irq to a swlevel greater than 6 since the first 6 bits - * of INT_PEND0 are taken - */ - swlevel = find_level(&cpu, irq); - intr_disconnect_level(cpu, swlevel); - LEVEL_TO_IRQ(cpu, swlevel) = -1; - - bridge->b_int_enable &= ~(1 << pin); - bridge->b_widget.w_tflush; /* Flush */ - - return 0; /* Never anything pending. */ -} - -void irq_debug(void) -{ - bridge_t *bridge = (bridge_t *) 0x9200000008000000; - - printk("bridge->b_int_status = 0x%x\n", bridge->b_int_status); - printk("bridge->b_int_enable = 0x%x\n", bridge->b_int_enable); - printk("PI_INT_PEND0 = 0x%lx\n", LOCAL_HUB_L(PI_INT_PEND0)); - printk("PI_INT_MASK0_A = 0x%lx\n", LOCAL_HUB_L(PI_INT_MASK0_A)); -} - -int setup_irq(unsigned int irq, struct irqaction *new) -{ - int shared = 0; - struct irqaction *old, **p; - unsigned long flags; - - DBG("setup_irq: 0x%x\n", irq); - if (irq >= NR_IRQS) { - printk("IRQ array overflow %d\n", irq); - while(1); - } - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_and_cli(flags); - p = irq_action + irq; - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) { - restore_flags(flags); - return -EBUSY; - } - - /* Add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - shared = 1; - } - - *p = new; - - if ((!shared) && (irq >= BASE_PCI_IRQ)) { - bridge_startup(irq); - } - restore_flags(flags); - - return 0; -} - -int request_irq(unsigned int irq, - void (*handler)(int, void *, struct pt_regs *), - unsigned long irqflags, const char * devname, void *dev_id) -{ - int retval; - struct irqaction *action; - - DBG("request_irq(): irq= 0x%x\n", irq); - if (!handler) - return -EINVAL; - - action = (struct irqaction *)kmalloc(sizeof(*action), GFP_KERNEL); - if (!action) - return -ENOMEM; - - action->handler = handler; - action->flags = irqflags; - action->mask = 0; - action->name = devname; - action->next = NULL; - action->dev_id = dev_id; - - DBG("request_irq(): %s devid= 0x%x\n", devname, dev_id); - retval = setup_irq(irq, action); - DBG("request_irq(): retval= %d\n", retval); - if (retval) - kfree(action); - return retval; -} - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irqaction * action, **p; - unsigned long flags; - - if (irq >= NR_IRQS) { - printk("Trying to free IRQ%d\n", irq); - return; - } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { - if (action->dev_id != dev_id) - continue; - - /* Found it - now free it */ - save_and_cli(flags); - *p = action->next; - if (irq >= BASE_PCI_IRQ) - bridge_shutdown(irq); - restore_flags(flags); - kfree(action); - return; - } - printk("Trying to free free IRQ%d\n",irq); -} - -/* Useless ISA nonsense. */ -unsigned long probe_irq_on (void) -{ - panic("probe_irq_on called!\n"); - return 0; -} - -int probe_irq_off (unsigned long irqs) -{ - return 0; -} - -void __init init_IRQ(void) -{ - set_except_vector(0, ip27_irq); -} - -#ifdef CONFIG_SMP - -/* - * This following are the global intr on off routines, copied almost - * entirely from i386 code. - */ - -int global_irq_holder = NO_PROC_ID; -spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; - -extern void show_stack(unsigned long* esp); - -static void show(char * str) -{ - int i; - int cpu = smp_processor_id(); - - printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [",irqs_running()); - for(i=0;i < smp_num_cpus;i++) - printk(" %d",local_irq_count(i)); - printk(" ]\nbh: %d [",spin_is_locked(&global_bh_lock) ? 1 : 0); - for(i=0;i < smp_num_cpus;i++) - printk(" %d",local_bh_count(i)); - - printk(" ]\nStack dumps:"); - for(i = 0; i < smp_num_cpus; i++) { - if (i == cpu) - continue; - printk("\nCPU %d:",i); - printk("Code not developed yet\n"); - /* show_stack(0); */ - } - printk("\nCPU %d:",cpu); - printk("Code not developed yet\n"); - /* show_stack(NULL); */ - printk("\n"); -} - -#define MAXCOUNT 100000000 -#define SYNC_OTHER_CORES(x) udelay(x+1) - -static inline void wait_on_irq(int cpu) -{ - int count = MAXCOUNT; - - for (;;) { - - /* - * Wait until all interrupts are gone. Wait - * for bottom half handlers unless we're - * already executing in one.. - */ - if (!irqs_running()) - if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock)) - break; - - /* Duh, we have to loop. Release the lock to avoid deadlocks */ - spin_unlock(&global_irq_lock); - - for (;;) { - if (!--count) { - show("wait_on_irq"); - count = ~0; - } - local_irq_enable(); - SYNC_OTHER_CORES(cpu); - local_irq_disable(); - if (irqs_running()) - continue; - if (spin_is_locked(&global_irq_lock)) - continue; - if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock)) - continue; - if (spin_trylock(&global_irq_lock)) - break; - } - } -} - -void synchronize_irq(void) -{ - if (irqs_running()) { - /* Stupid approach */ - cli(); - sti(); - } -} - -static inline void get_irqlock(int cpu) -{ - if (!spin_trylock(&global_irq_lock)) { - /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) - return; - /* Uhhuh.. Somebody else got it. Wait.. */ - spin_lock(&global_irq_lock); - } - /* - * We also to make sure that nobody else is running - * in an interrupt context. - */ - wait_on_irq(cpu); - - /* - * Ok, finally.. - */ - global_irq_holder = cpu; -} - -void __global_cli(void) -{ - unsigned int flags; - - local_save_flags(flags); - if (flags & ST0_IE) { - int cpu = smp_processor_id(); - local_irq_disable(); - if (!local_irq_count(cpu)) - get_irqlock(cpu); - } -} - -void __global_sti(void) -{ - int cpu = smp_processor_id(); - - if (!local_irq_count(cpu)) - release_irqlock(cpu); - local_irq_enable(); -} - -/* - * SMP flags value to restore to: - * 0 - global cli - * 1 - global sti - * 2 - local cli - * 3 - local sti - */ -unsigned long __global_save_flags(void) -{ - int retval; - int local_enabled; - unsigned long flags; - int cpu = smp_processor_id(); - - local_save_flags(flags); - local_enabled = (flags & ST0_IE); - /* default to local */ - retval = 2 + local_enabled; - - /* check for global flags if we're not in an interrupt */ - if (!local_irq_count(cpu)) { - if (local_enabled) - retval = 1; - if (global_irq_holder == cpu) - retval = 0; - } - return retval; -} - -void __global_restore_flags(unsigned long flags) -{ - switch (flags) { - case 0: - __global_cli(); - break; - case 1: - __global_sti(); - break; - case 2: - local_irq_disable(); - break; - case 3: - local_irq_enable(); - break; - default: - printk("global_restore_flags: %08lx\n", flags); - } -} - -#endif /* CONFIG_SMP */ - -/* - * Get values that vary depending on which CPU and bit we're operating on. - */ -static hub_intmasks_t *intr_get_ptrs(cpuid_t cpu, int bit, int *new_bit, - hubreg_t **intpend_masks, int *ip) -{ - hub_intmasks_t *hub_intmasks; - - hub_intmasks = &cpu_data[cpu].p_intmasks; - if (bit < N_INTPEND_BITS) { - *intpend_masks = hub_intmasks->intpend0_masks; - *ip = 0; - *new_bit = bit; - } else { - *intpend_masks = hub_intmasks->intpend1_masks; - *ip = 1; - *new_bit = bit - N_INTPEND_BITS; - } - return hub_intmasks; -} - -int intr_connect_level(int cpu, int bit) -{ - int ip; - int slice = cputoslice(cpu); - volatile hubreg_t *mask_reg; - hubreg_t *intpend_masks; - nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu)); - - (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip); - - /* Make sure it's not already pending when we connect it. */ - REMOTE_HUB_CLR_INTR(nasid, bit + ip * N_INTPEND_BITS); - - intpend_masks[0] |= (1ULL << (u64)bit); - - if (ip == 0) { - mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + - PI_INT_MASK_OFFSET * slice); - } else { - mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + - PI_INT_MASK_OFFSET * slice); - } - HUB_S(mask_reg, intpend_masks[0]); - return(0); -} - -int intr_disconnect_level(int cpu, int bit) -{ - int ip; - int slice = cputoslice(cpu); - volatile hubreg_t *mask_reg; - hubreg_t *intpend_masks; - nasid_t nasid = COMPACT_TO_NASID_NODEID(cputocnode(cpu)); - - (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &ip); - intpend_masks[0] &= ~(1ULL << (u64)bit); - if (ip == 0) { - mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK0_A + - PI_INT_MASK_OFFSET * slice); - } else { - mask_reg = REMOTE_HUB_ADDR(nasid, PI_INT_MASK1_A + - PI_INT_MASK_OFFSET * slice); - } - HUB_S(mask_reg, intpend_masks[0]); - return(0); -} - - -void handle_resched_intr(int irq, void *dev_id, struct pt_regs *regs) -{ - /* Nothing, the return from intr will work for us */ -} - -extern void smp_call_function_interrupt(void); - -void install_cpuintr(int cpu) -{ -#ifdef CONFIG_SMP -#if (CPUS_PER_NODE == 2) - static int done = 0; - - /* - * This is a hack till we have a pernode irqlist. Currently, - * just have the master cpu set up the handlers for the per - * cpu irqs. - */ - if (done == 0) { - int j; - - if (request_irq(CPU_RESCHED_A_IRQ, handle_resched_intr, - 0, "resched", 0)) - panic("intercpu intr unconnectible\n"); - if (request_irq(CPU_RESCHED_B_IRQ, handle_resched_intr, - 0, "resched", 0)) - panic("intercpu intr unconnectible\n"); - if (request_irq(CPU_CALL_A_IRQ, smp_call_function_interrupt, - 0, "callfunc", 0)) - panic("intercpu intr unconnectible\n"); - if (request_irq(CPU_CALL_B_IRQ, smp_call_function_interrupt, - 0, "callfunc", 0)) - panic("intercpu intr unconnectible\n"); - - for (j = 0; j < PERNODE_LEVELS; j++) - LEVEL_TO_IRQ(0, j) = -1; - LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ)) = - CPU_RESCHED_A_IRQ; - LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_RESCHED_B_IRQ)) = - CPU_RESCHED_B_IRQ; - LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ)) = - CPU_CALL_A_IRQ; - LEVEL_TO_IRQ(0, FAST_IRQ_TO_LEVEL(CPU_CALL_B_IRQ)) = - CPU_CALL_B_IRQ; - for (j = 1; j < MAX_COMPACT_NODES; j++) - memcpy(&node_level_to_irq[j][0], - &node_level_to_irq[0][0], - sizeof(node_level_to_irq[0][0])*PERNODE_LEVELS); - - done = 1; - } - - intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_RESCHED_A_IRQ + - cputoslice(cpu))); - intr_connect_level(cpu, FAST_IRQ_TO_LEVEL(CPU_CALL_A_IRQ + - cputoslice(cpu))); -#else /* CPUS_PER_NODE */ -#error Must redefine this for more than 2 CPUS. -#endif /* CPUS_PER_NODE */ -#endif /* CONFIG_SMP */ -} - -void install_tlbintr(int cpu) -{ -#if 0 - int intr_bit = N_INTPEND_BITS + TLB_INTR_A + cputoslice(cpu); - - intr_connect_level(cpu, intr_bit); -#endif -} diff -Nru a/arch/mips64/sgi-ip27/ip27-klconfig.c b/arch/mips64/sgi-ip27/ip27-klconfig.c --- a/arch/mips64/sgi-ip27/ip27-klconfig.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,135 +0,0 @@ -/* - * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <linux/param.h> -#include <linux/timex.h> -#include <linux/mm.h> - -#include <asm/sn/klconfig.h> -#include <asm/sn/arch.h> -#include <asm/sn/gda.h> - -klinfo_t *find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type) -{ - int index, j; - - if (kli == (klinfo_t *)NULL) { - index = 0; - } else { - for (j = 0; j < KLCF_NUM_COMPS(brd); j++) - if (kli == KLCF_COMP(brd, j)) - break; - index = j; - if (index == KLCF_NUM_COMPS(brd)) { - printk("find_component: Bad pointer: 0x%p\n", kli); - return (klinfo_t *)NULL; - } - index++; /* next component */ - } - - for (; index < KLCF_NUM_COMPS(brd); index++) { - kli = KLCF_COMP(brd, index); - if (KLCF_COMP_TYPE(kli) == struct_type) - return kli; - } - - /* Didn't find it. */ - return (klinfo_t *)NULL; -} - -klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type) -{ - return find_component(brd, (klinfo_t *)NULL, struct_type); -} - -lboard_t * find_lboard(lboard_t *start, unsigned char brd_type) -{ - /* Search all boards stored on this node. */ - while (start) { - if (start->brd_type == brd_type) - return start; - start = KLCF_NEXT(start); - } - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type) -{ - /* Search all boards stored on this node. */ - while (start) { - if (KLCLASS(start->brd_type) == KLCLASS(brd_type)) - return start; - start = KLCF_NEXT(start); - } - - /* Didn't find it. */ - return (lboard_t *)NULL; -} - -cnodeid_t get_cpu_cnode(cpuid_t cpu) -{ - return CPUID_TO_COMPACT_NODEID(cpu); -} - -klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice) -{ - lboard_t *brd; - klcpu_t *acpu; - - if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27))) - return (klcpu_t *)NULL; - - if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU))) - return (klcpu_t *)NULL; - - do { - if ((acpu->cpu_info.physid) == slice) - return acpu; - } while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu, - KLSTRUCT_CPU))); - return (klcpu_t *)NULL; -} - -klcpu_t * sn_get_cpuinfo(cpuid_t cpu) -{ - nasid_t nasid; - int slice; - klcpu_t *acpu; - gda_t *gdap = GDA; - cnodeid_t cnode; - - if (!(cpu < MAXCPUS)) { - printk("sn_get_cpuinfo: illegal cpuid 0x%lx\n", cpu); - return NULL; - } - - cnode = get_cpu_cnode(cpu); - if (cnode == INVALID_CNODEID) - return NULL; - - if ((nasid = gdap->g_nasidtable[cnode]) == INVALID_NASID) - return NULL; - - for (slice = 0; slice < CPUS_PER_NODE; slice++) { - acpu = nasid_slice_to_cpuinfo(nasid, slice); - if (acpu && acpu->cpu_info.virtid == cpu) - return acpu; - } - return NULL; -} - -int get_cpu_slice(cpuid_t cpu) -{ - klcpu_t *acpu; - - if ((acpu = sn_get_cpuinfo(cpu)) == NULL) - return -1; - return acpu->cpu_info.physid; -} diff -Nru a/arch/mips64/sgi-ip27/ip27-klnuma.c b/arch/mips64/sgi-ip27/ip27-klnuma.c --- a/arch/mips64/sgi-ip27/ip27-klnuma.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,143 +0,0 @@ -/* - * Ported from IRIX to Linux by Kanoj Sarcar, 06/08/00. - * Copyright 2000 - 2001 Silicon Graphics, Inc. - * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com) - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/mmzone.h> -#include <linux/kernel.h> -#include <linux/string.h> - -#include <asm/page.h> -#include <asm/smp.h> -#include <asm/sn/types.h> -#include <asm/sn/arch.h> -#include <asm/sn/gda.h> -#include <asm/mmzone.h> -#include <asm/sn/klkernvars.h> -#include <asm/sn/mapped_kernel.h> -#include <asm/sn/sn_private.h> - -extern char _end; -static cpumask_t ktext_repmask; - -/* - * XXX - This needs to be much smarter about where it puts copies of the - * kernel. For example, we should never put a copy on a headless node, - * and we should respect the topology of the machine. - */ -void __init setup_replication_mask(int maxnodes) -{ - static int numa_kernel_replication_ratio; - cnodeid_t cnode; - - /* Set only the master cnode's bit. The master cnode is always 0. */ - CPUMASK_CLRALL(ktext_repmask); - CPUMASK_SETB(ktext_repmask, 0); - - numa_kernel_replication_ratio = 0; -#ifdef CONFIG_REPLICATE_KTEXT -#ifndef CONFIG_MAPPED_KERNEL -#error Kernel replication works with mapped kernel support. No calias support. -#endif - numa_kernel_replication_ratio = 1; -#endif - - for (cnode = 1; cnode < numnodes; cnode++) { - /* See if this node should get a copy of the kernel */ - if (numa_kernel_replication_ratio && - !(cnode % numa_kernel_replication_ratio)) { - - /* Advertise that we have a copy of the kernel */ - CPUMASK_SETB(ktext_repmask, cnode); - } - } - - /* Set up a GDA pointer to the replication mask. */ - GDA->g_ktext_repmask = &ktext_repmask; -} - - -static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid) -{ - kern_vars_t *kvp; - cnodeid_t client_cnode; - - client_cnode = NASID_TO_COMPACT_NODEID(client_nasid); - - kvp = &(PLAT_NODE_DATA(client_cnode)->kern_vars); - - KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp; - - kvp->kv_magic = KV_MAGIC; - - kvp->kv_ro_nasid = server_nasid; - kvp->kv_rw_nasid = master_nasid; - kvp->kv_ro_baseaddr = NODE_CAC_BASE(server_nasid); - kvp->kv_rw_baseaddr = NODE_CAC_BASE(master_nasid); - printk("REPLICATION: ON nasid %d, ktext from nasid %d, kdata from nasid %d\n", client_nasid, server_nasid, master_nasid); -} - -/* XXX - When the BTE works, we should use it instead of this. */ -static __init void copy_kernel(nasid_t dest_nasid) -{ - extern char _stext, _etext; - unsigned long dest_kern_start, source_start, source_end, kern_size; - - source_start = (unsigned long)&_stext; - source_end = (unsigned long)&_etext; - kern_size = source_end - source_start; - - dest_kern_start = CHANGE_ADDR_NASID(MAPPED_KERN_RO_TO_K0(source_start), - dest_nasid); - memcpy((void *)dest_kern_start, (void *)source_start, kern_size); -} - -void __init replicate_kernel_text(int maxnodes) -{ - cnodeid_t cnode; - nasid_t client_nasid; - nasid_t server_nasid; - - server_nasid = master_nasid; - - /* Record where the master node should get its kernel text */ - set_ktext_source(master_nasid, master_nasid); - - for (cnode = 1; cnode < maxnodes; cnode++) { - client_nasid = COMPACT_TO_NASID_NODEID(cnode); - - /* Check if this node should get a copy of the kernel */ - if (CPUMASK_TSTB(ktext_repmask, cnode)) { - server_nasid = client_nasid; - copy_kernel(server_nasid); - } - - /* Record where this node should get its kernel text */ - set_ktext_source(client_nasid, server_nasid); - } -} - -/* - * Return pfn of first free page of memory on a node. PROM may allocate - * data structures on the first couple of pages of the first slot of each - * node. If this is the case, getfirstfree(node) > getslotstart(node, 0). - */ -pfn_t node_getfirstfree(cnodeid_t cnode) -{ - unsigned long loadbase = CKSEG0; - nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); - unsigned long offset; - -#ifdef CONFIG_MAPPED_KERNEL - loadbase = CKSSEG + 16777216; -#endif - offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; - if ((cnode == 0) || (CPUMASK_TSTB(ktext_repmask, cnode))) - return (TO_NODE(nasid, offset) >> PAGE_SHIFT); - else - return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> - PAGE_SHIFT); -} - diff -Nru a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c --- a/arch/mips64/sgi-ip27/ip27-memory.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,337 +0,0 @@ -/* - * 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) 2000 by Ralf Baechle - * Copyright (C) 2000 by Silicon Graphics, Inc. - * - * On SGI IP27 the ARC memory configuration data is completly bogus but - * alternate easier to use mechanisms are available. - */ -#include <linux/init.h> -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/bootmem.h> -#include <linux/swap.h> - -#include <asm/page.h> -#include <asm/bootinfo.h> -#include <asm/addrspace.h> -#include <asm/pgtable.h> -#include <asm/pgalloc.h> -#include <asm/sn/types.h> -#include <asm/sn/addrs.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/arch.h> -#include <asm/mmzone.h> - -/* ip27-klnuma.c */ -extern pfn_t node_getfirstfree(cnodeid_t cnode); - -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define SLOT_IGNORED 0xffff - -short slot_lastfilled_cache[MAX_COMPACT_NODES]; -unsigned short slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS]; -static pfn_t numpages; - -plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES]; -bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES]; - -int numa_debug(void) -{ - printk("NUMA debug\n"); - *(int *)0 = 0; - return(0); -} - -/* - * Return the number of pages of memory provided by the given slot - * on the specified node. - */ -pfn_t slot_getsize(cnodeid_t node, int slot) -{ - return (pfn_t) slot_psize_cache[node][slot]; -} - -/* - * Return highest slot filled - */ -int node_getlastslot(cnodeid_t node) -{ - return (int) slot_lastfilled_cache[node]; -} - -/* - * Return the pfn of the last free page of memory on a node. - */ -pfn_t node_getmaxclick(cnodeid_t node) -{ - pfn_t slot_psize; - int slot; - - /* - * Start at the top slot. When we find a slot with memory in it, - * that's the winner. - */ - for (slot = (node_getnumslots(node) - 1); slot >= 0; slot--) { - if ((slot_psize = slot_getsize(node, slot))) { - if (slot_psize == SLOT_IGNORED) - continue; - /* Return the basepfn + the slot size, minus 1. */ - return slot_getbasepfn(node, slot) + slot_psize - 1; - } - } - - /* - * If there's no memory on the node, return 0. This is likely - * to cause problems. - */ - return (pfn_t)0; -} - -static pfn_t slot_psize_compute(cnodeid_t node, int slot) -{ - nasid_t nasid; - lboard_t *brd; - klmembnk_t *banks; - unsigned long size; - - nasid = COMPACT_TO_NASID_NODEID(node); - /* Find the node board */ - brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27); - if (!brd) - return 0; - - /* Get the memory bank structure */ - banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK); - if (!banks) - return 0; - - /* Size in _Megabytes_ */ - size = (unsigned long)banks->membnk_bnksz[slot/4]; - - /* hack for 128 dimm banks */ - if (size <= 128) { - if (slot%4 == 0) { - size <<= 20; /* size in bytes */ - return(size >> PAGE_SHIFT); - } else { - return 0; - } - } else { - size /= 4; - size <<= 20; - return(size >> PAGE_SHIFT); - } -} - -pfn_t szmem(pfn_t fpage, pfn_t maxpmem) -{ - cnodeid_t node; - int slot, numslots; - pfn_t num_pages = 0, slot_psize; - pfn_t slot0sz = 0, nodebytes; /* Hack to detect problem configs */ - int ignore; - - for (node = 0; node < numnodes; node++) { - numslots = node_getnumslots(node); - ignore = nodebytes = 0; - for (slot = 0; slot < numslots; slot++) { - slot_psize = slot_psize_compute(node, slot); - if (slot == 0) slot0sz = slot_psize; - /* - * We need to refine the hack when we have replicated - * kernel text. - */ - nodebytes += SLOT_SIZE; - if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > - (slot0sz << PAGE_SHIFT)) - ignore = 1; - if (ignore && slot_psize) { - printk("Ignoring slot %d onwards on node %d\n", - slot, node); - slot_psize_cache[node][slot] = SLOT_IGNORED; - slot = numslots; - continue; - } - num_pages += slot_psize; - slot_psize_cache[node][slot] = - (unsigned short) slot_psize; - if (slot_psize) - slot_lastfilled_cache[node] = slot; - } - } - if (maxpmem) - return((maxpmem > num_pages) ? num_pages : maxpmem); - else - return num_pages; -} - -/* - * Currently, the intranode memory hole support assumes that each slot - * contains at least 32 MBytes of memory. We assume all bootmem data - * fits on the first slot. - */ -void __init prom_meminit(void) -{ - extern void mlreset(void); - cnodeid_t node; - pfn_t slot_firstpfn, slot_lastpfn, slot_freepfn; - unsigned long bootmap_size; - int node_datasz; - - node_datasz = PFN_UP(sizeof(plat_pg_data_t)); - mlreset(); - numpages = szmem(0, 0); - for (node = (numnodes - 1); node >= 0; node--) { - slot_firstpfn = slot_getbasepfn(node, 0); - slot_lastpfn = slot_firstpfn + slot_getsize(node, 0); - slot_freepfn = node_getfirstfree(node); - /* Foll line hack for non discontigmem; remove once discontigmem - * becomes the default. */ - max_low_pfn = (slot_lastpfn - slot_firstpfn); - - /* - * Allocate the node data structure on the node first. - */ - plat_node_data[node] = (plat_pg_data_t *)(__va(slot_freepfn \ - << PAGE_SHIFT)); - NODE_DATA(node)->bdata = plat_node_bdata + node; - slot_freepfn += node_datasz; - bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, - slot_firstpfn, slot_lastpfn); - free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, - (slot_lastpfn - slot_firstpfn) << PAGE_SHIFT); - reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, - ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size); - } - printk("Total memory probed : 0x%lx pages\n", numpages); -} - -int __init page_is_ram(unsigned long pagenr) -{ - return 1; -} - -void __init -prom_free_prom_memory (void) -{ - /* We got nothing to free here ... */ -} - -#ifdef CONFIG_DISCONTIGMEM - -static pfn_t pagenr = 0; - -void __init paging_init(void) -{ - pmd_t *pmd = kpmdtbl; - pte_t *pte = kptbl; - - cnodeid_t node; - unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; - int i; - - /* Initialize the entire pgd. */ - pgd_init((unsigned long)swapper_pg_dir); - pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); - memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE); - - /* This is for vmalloc */ - memset((void *)kptbl, 0, PAGE_SIZE << KPTBL_PAGE_ORDER); - memset((void *)kpmdtbl, 0, PAGE_SIZE); - pgd_set(swapper_pg_dir, kpmdtbl); - for (i = 0; i < (1 << KPTBL_PAGE_ORDER); pmd++,i++,pte+=PTRS_PER_PTE) - pmd_val(*pmd) = (unsigned long)pte; - - for (node = 0; node < numnodes; node++) { - pfn_t start_pfn = slot_getbasepfn(node, 0); - pfn_t end_pfn = node_getmaxclick(node); - - zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn; - free_area_init_node(node, NODE_DATA(node), 0, zones_size, - start_pfn, 0); - } -} - -void __init mem_init(void) -{ - extern char _stext, _etext, _fdata, _edata; - extern char __init_begin, __init_end; - extern unsigned long setup_zero_pages(void); - cnodeid_t nid; - unsigned long tmp; - unsigned long codesize, datasize, initsize; - int slot, numslots; - struct page *pg, *pslot; - - num_physpages = numpages; /* memory already sized by szmem */ - max_mapnr = pagenr; /* already found during paging_init */ - high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); - - for (nid = 0; nid < numnodes; nid++) { - - /* - * Hack till free_area_init_core() zeroes free_pages - */ - for (tmp = 0; tmp < MAX_NR_ZONES; tmp++) - PLAT_NODE_DATA(nid)->gendata.node_zones[tmp].free_pages=0; - /* - * This will free up the bootmem, ie, slot 0 memory. - */ - totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); - - /* - * We need to manually do the other slots. - */ - pg = NODE_DATA(nid)->node_mem_map + slot_getsize(nid, 0); - numslots = node_getlastslot(nid); - for (slot = 1; slot <= numslots; slot++) { - pslot = NODE_DATA(nid)->node_mem_map + - slot_getbasepfn(nid, slot) - slot_getbasepfn(nid, 0); - - /* - * Mark holes in previous slot. May also want to - * free up the pages that hold the memmap entries. - */ - while (pg < pslot) { - pg++; - } - - /* - * Free valid memory in current slot. - */ - pslot += slot_getsize(nid, slot); - while (pg < pslot) { - /* if (!page_is_ram(pgnr)) continue; */ - /* commented out until page_is_ram works */ - ClearPageReserved(pg); - atomic_set(&pg->count, 1); - __free_page(pg); - totalram_pages++; - pg++; pgnr++; - } - } - } - - totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ - - codesize = (unsigned long) &_etext - (unsigned long) &_stext; - datasize = (unsigned long) &_edata - (unsigned long) &_fdata; - initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - - tmp = (unsigned long) nr_free_pages(); - printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " - "%ldk data, %ldk init)\n", - tmp << (PAGE_SHIFT-10), - num_physpages << (PAGE_SHIFT-10), - codesize >> 10, - (num_physpages - tmp) << (PAGE_SHIFT-10), - datasize >> 10, - initsize >> 10); -} - -#endif /* CONFIG_DISCONTIGMEM */ diff -Nru a/arch/mips64/sgi-ip27/ip27-nmi.c b/arch/mips64/sgi-ip27/ip27-nmi.c --- a/arch/mips64/sgi-ip27/ip27-nmi.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,168 +0,0 @@ -#include <linux/kernel.h> -#include <linux/mmzone.h> -#include <linux/spinlock.h> -#include <linux/smp.h> -#include <asm/atomic.h> -#include <asm/sn/types.h> -#include <asm/sn/addrs.h> -#include <asm/sn/nmi.h> -#include <asm/sn/arch.h> -#include <asm/sn/sn0/hub.h> - -#if 0 -#define NODE_NUM_CPUS(n) CNODE_NUM_CPUS(n) -#else -#define NODE_NUM_CPUS(n) CPUS_PER_NODE -#endif - -#define CNODEID_NONE (cnodeid_t)-1 -#define enter_panic_mode() spin_lock(&nmi_lock) - -typedef unsigned long machreg_t; - -spinlock_t nmi_lock = SPIN_LOCK_UNLOCKED; - -/* - * Lets see what else we need to do here. Set up sp, gp? - */ -void nmi_dump(void) -{ - void cont_nmi_dump(void); - - cont_nmi_dump(); -} - -void install_cpu_nmi_handler(int slice) -{ - nmi_t *nmi_addr; - - nmi_addr = (nmi_t *)NMI_ADDR(get_nasid(), slice); - if (nmi_addr->call_addr) - return; - nmi_addr->magic = NMI_MAGIC; - nmi_addr->call_addr = (void *)nmi_dump; - nmi_addr->call_addr_c = - (void *)(~((unsigned long)(nmi_addr->call_addr))); - nmi_addr->call_parm = 0; -} - -/* - * Copy the cpu registers which have been saved in the IP27prom format - * into the eframe format for the node under consideration. - */ - -void -nmi_cpu_eframe_save(nasid_t nasid, - int slice) -{ - int i, numberof_nmi_cpu_regs; - machreg_t *prom_format; - - /* Get the total number of registers being saved by the prom */ - numberof_nmi_cpu_regs = sizeof(struct reg_struct) / sizeof(machreg_t); - - /* Get the pointer to the current cpu's register set. */ - prom_format = - (machreg_t *)(TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + - slice * IP27_NMI_KREGS_CPU_SIZE); - - printk("NMI nasid %d: slice %d\n", nasid, slice); - for (i = 0; i < numberof_nmi_cpu_regs; i++) - printk("0x%lx ", prom_format[i]); - printk("\n\n"); -} - -/* - * Copy the cpu registers which have been saved in the IP27prom format - * into the eframe format for the node under consideration. - */ -void -nmi_node_eframe_save(cnodeid_t cnode) -{ - int cpu; - nasid_t nasid; - - /* Make sure that we have a valid node */ - if (cnode == CNODEID_NONE) - return; - - nasid = COMPACT_TO_NASID_NODEID(cnode); - if (nasid == INVALID_NASID) - return; - - /* Save the registers into eframe for each cpu */ - for(cpu = 0; cpu < NODE_NUM_CPUS(cnode); cpu++) - nmi_cpu_eframe_save(nasid, cpu); -} - -/* - * Save the nmi cpu registers for all cpus in the system. - */ -void -nmi_eframes_save(void) -{ - cnodeid_t cnode; - - for(cnode = 0 ; cnode < numnodes; cnode++) - nmi_node_eframe_save(cnode); -} - -void -cont_nmi_dump(void) -{ -#ifndef REAL_NMI_SIGNAL - static atomic_t nmied_cpus = ATOMIC_INIT(0); - - atomic_inc(&nmied_cpus); -#endif - /* - * Use enter_panic_mode to allow only 1 cpu to proceed - */ - enter_panic_mode(); - -#ifdef REAL_NMI_SIGNAL - /* - * Wait up to 15 seconds for the other cpus to respond to the NMI. - * If a cpu has not responded after 10 sec, send it 1 additional NMI. - * This is for 2 reasons: - * - sometimes a MMSC fail to NMI all cpus. - * - on 512p SN0 system, the MMSC will only send NMIs to - * half the cpus. Unfortunately, we don't know which cpus may be - * NMIed - it depends on how the site chooses to configure. - * - * Note: it has been measure that it takes the MMSC up to 2.3 secs to - * send NMIs to all cpus on a 256p system. - */ - for (i=0; i < 1500; i++) { - for (node=0; node < numnodes; node++) - if (NODEPDA(node)->dump_count == 0) - break; - if (node == numnodes) - break; - if (i == 1000) { - for (node=0; node < numnodes; node++) - if (NODEPDA(node)->dump_count == 0) { - cpu = CNODE_TO_CPU_BASE(node); - for (n=0; n < CNODE_NUM_CPUS(node); cpu++, n++) { - CPUMASK_SETB(nmied_cpus, cpu); - /* - * cputonasid, cputoslice - * needs kernel cpuid - */ - SEND_NMI((cputonasid(cpu)), (cputoslice(cpu))); - } - } - - } - udelay(10000); - } -#else - while (atomic_read(&nmied_cpus) != smp_num_cpus); -#endif - - /* - * Save the nmi cpu registers for all cpu in the eframe format. - */ - nmi_eframes_save(); - LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); -} diff -Nru a/arch/mips64/sgi-ip27/ip27-pci-dma.c b/arch/mips64/sgi-ip27/ip27-pci-dma.c --- a/arch/mips64/sgi-ip27/ip27-pci-dma.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,164 +0,0 @@ -/* - * Dynamic DMA mapping support. - * - * On the Origin there is dynamic DMA address translation for all PCI DMA. - * However we don't use this facility yet but rely on the 2gb direct - * mapped DMA window for PCI64. So consistent alloc/free are merely page - * allocation/freeing. The rest of the dynamic DMA mapping interface is - * implemented in <asm/pci.h>. So this code will fail with more than - * 2gb of memory. - */ -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/pci.h> -#include <asm/io.h> - -/* Pure 2^n version of get_order */ -extern __inline__ int __get_order(unsigned long size) -{ - int order; - - size = (size-1) >> (PAGE_SHIFT-1); - order = -1; - do { - size >>= 1; - order++; - } while (size); - return order; -} - -void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t *dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC; - int order = __get_order(size); - - if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, order); - - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = (bus_to_baddr[hwdev->bus->number] | __pa(ret)); - } - - return ret; -} - -void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, __get_order(size)); -} - -/* - * Map a single buffer of the indicated size for DMA in streaming mode. - * The 32-bit bus address to use is returned. - * - * Once the device is given the dma address, the device owns this memory - * until either pci_unmap_single or pci_dma_sync_single is performed. - */ -dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, - int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - return (bus_to_baddr[hwdev->bus->number] | __pa(ptr)); -} - -/* - * Unmap a single streaming mode DMA translation. The dma_addr and size - * must match what was provided for in a previous pci_map_single call. All - * other usages are undefined. - * - * After this call, reads by the cpu to the buffer are guaranteed to see - * whatever the device wrote there. - */ -void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, - size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* Nothing to do */ -} - -/* - * Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scather-gather version of the - * above pci_map_single interface. Here the scatter gather list - * elements are each tagged with the appropriate dma address - * and length. They are obtained via sg_dma_{address,length}(SG). - * - * NOTE: An implementation may be able to use a smaller number of - * DMA address/length pairs than there are SG table elements. - * (for example via virtual mapping capabilities) - * The routine returns the number of addr/length pairs actually - * used, at most nents. - * - * Device ownership issues as mentioned above for pci_map_single are - * the same here. - */ -int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, - int direction) -{ - int i; - - if (direction == PCI_DMA_NONE) - BUG(); - - /* Make sure that gcc doesn't leave the empty loop body. */ - for (i = 0; i < nents; i++, sg++) { - sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address)); - } - - return nents; -} - -/* - * Unmap a set of streaming mode DMA translations. - * Again, cpu read rules concerning calls here are the same as for - * pci_unmap_single() above. - */ -void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, - int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); - - /* Nothing to do */ -} - -/* - * Make physical memory consistent for a single - * streaming mode DMA translation after a transfer. - * - * If you perform a pci_map_single() but wish to interrogate the - * buffer using the cpu, yet do not wish to teardown the PCI dma - * mapping, you must call this function before doing so. At the - * next point you give the PCI dma address back to the card, the - * device again owns the buffer. - */ -void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, - size_t size, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); -} - -/* - * Make physical memory consistent for a set of streaming - * mode DMA translations after a transfer. - * - * The same as pci_dma_sync_single but for a scatter-gather list, - * same rules and usage. - */ -void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, - int nelems, int direction) -{ - if (direction == PCI_DMA_NONE) - BUG(); -} diff -Nru a/arch/mips64/sgi-ip27/ip27-pci.c b/arch/mips64/sgi-ip27/ip27-pci.c --- a/arch/mips64/sgi-ip27/ip27-pci.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,406 +0,0 @@ -/* - * 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) 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <asm/sn/arch.h> -#include <asm/pci/bridge.h> -#include <asm/paccess.h> -#include <asm/sn/sn0/ip27.h> -#include <asm/sn/sn0/hub.h> - -/* - * Max #PCI busses we can handle; ie, max #PCI bridges. - */ -#define MAX_PCI_BUSSES 40 - -/* - * Max #PCI devices (like scsi controllers) we handle on a bus. - */ -#define MAX_DEVICES_PER_PCIBUS 8 - -/* - * No locking needed until PCI initialization is done parallely. - */ -int irqstore[MAX_PCI_BUSSES][MAX_DEVICES_PER_PCIBUS]; -int lastirq = BASE_PCI_IRQ; - -/* - * Translate from irq to software PCI bus number and PCI slot. - */ -int irq_to_bus[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; -int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; - -/* - * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is - * not really documented, so right now I can't write code which uses it. - * Therefore we use type 0 accesses for now even though they won't work - * correcly for PCI-to-PCI bridges. - */ -#define CF0_READ_PCI_CFG(dev,where,value,bm,mask) \ -do { \ - bridge_t *bridge; \ - int slot = PCI_SLOT(dev->devfn); \ - int fn = PCI_FUNC(dev->devfn); \ - volatile u32 *addr; \ - u32 cf, __bit; \ - unsigned int bus_id = (unsigned) dev->bus->number; \ - \ - bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], \ - bus_to_wid[bus_id]); \ - \ - if (dev->vendor == PCI_VENDOR_ID_SGI \ - && dev->device == PCI_DEVICE_ID_SGI_IOC3 \ - && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) { \ - *value = 0; \ - return PCIBIOS_SUCCESSFUL; \ - } \ - \ - __bit = (((where) & (bm)) << 3); \ - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; \ - if (get_dbe(cf, addr)) \ - return PCIBIOS_DEVICE_NOT_FOUND; \ - *value = (cf >> __bit) & (mask); \ - return PCIBIOS_SUCCESSFUL; \ -} while (0) - -static int -pci_conf0_read_config_byte(struct pci_dev *dev, int where, u8 *value) -{ - CF0_READ_PCI_CFG(dev,where,value,3,0xff); -} - -static int -pci_conf0_read_config_word(struct pci_dev *dev, int where, u16 *value) -{ - CF0_READ_PCI_CFG(dev,where,value,2,0xffff); -} - -static int -pci_conf0_read_config_dword(struct pci_dev *dev, int where, u32 *value) -{ - CF0_READ_PCI_CFG(dev,where,value,0,0xffffffff); -} - -#define CF0_WRITE_PCI_CFG(dev,where,value,bm,mask) \ -do { \ - bridge_t *bridge; \ - int slot = PCI_SLOT(dev->devfn); \ - int fn = PCI_FUNC(dev->devfn); \ - volatile u32 *addr; \ - u32 cf, __bit; \ - unsigned int bus_id = (unsigned) dev->bus->number; \ - \ - bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], \ - bus_to_wid[bus_id]); \ - \ - if (dev->vendor == PCI_VENDOR_ID_SGI \ - && dev->device == PCI_DEVICE_ID_SGI_IOC3 \ - && ((where >= 0x14 && where < 0x40) || (where >= 0x48))) \ - return PCIBIOS_SUCCESSFUL; \ - \ - __bit = (((where) & (bm)) << 3); \ - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; \ - if (get_dbe(cf, addr)) \ - return PCIBIOS_DEVICE_NOT_FOUND; \ - cf &= (~mask); \ - cf |= (value); \ - put_dbe(cf, addr); \ - return PCIBIOS_SUCCESSFUL; \ -} while (0) - -static int -pci_conf0_write_config_byte(struct pci_dev *dev, int where, u8 value) -{ - CF0_WRITE_PCI_CFG(dev,where,value,3,0xff); -} - -static int -pci_conf0_write_config_word(struct pci_dev *dev, int where, u16 value) -{ - CF0_WRITE_PCI_CFG(dev,where,value,2,0xffff); -} - -static int -pci_conf0_write_config_dword(struct pci_dev *dev, int where, u32 value) -{ - CF0_WRITE_PCI_CFG(dev,where,value,0,0xffffffff); -} - - -static struct pci_ops bridge_pci_ops = { - pci_conf0_read_config_byte, - pci_conf0_read_config_word, - pci_conf0_read_config_dword, - pci_conf0_write_config_byte, - pci_conf0_write_config_word, - pci_conf0_write_config_dword -}; - -void __init pcibios_init(void) -{ - struct pci_ops *ops = &bridge_pci_ops; - int i; - - ioport_resource.end = ~0UL; - - for (i=0; i<num_bridges; i++) { - printk("PCI: Probing PCI hardware on host bus %2d.\n", i); - pci_scan_bus(i, ops, NULL); - } -} - -static inline u8 -bridge_swizzle(u8 pin, u8 slot) -{ - return (((pin-1) + slot) % 4) + 1; -} - -static u8 __init -pci_swizzle(struct pci_dev *dev, u8 *pinp) -{ - u8 pin = *pinp; - - while (dev->bus->self) { /* Move up the chain of bridges. */ - pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); - dev = dev->bus->self; - } - *pinp = pin; - - return PCI_SLOT(dev->devfn); -} - -/* - * All observed requests have pin == 1. We could have a global here, that - * gets incremented and returned every time - unfortunately, pci_map_irq - * may be called on the same device over and over, and need to return the - * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7]. - * - * A given PCI device, in general, should be able to intr any of the cpus - * on any one of the hubs connected to its xbow. - */ -static int __init -pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if ((dev->bus->number >= MAX_PCI_BUSSES) - || (pin != 1) - || (slot >= MAX_DEVICES_PER_PCIBUS)) - panic("Increase supported PCI busses %d,%d,%d\n", - dev->bus->number, slot, pin); - - /* - * Already assigned? Then return previously assigned value ... - */ - if (irqstore[dev->bus->number][slot]) - return irqstore[dev->bus->number][slot]; - - irq_to_bus[lastirq] = dev->bus->number; - irq_to_slot[lastirq] = slot; - irqstore[dev->bus->number][slot] = lastirq; - lastirq++; - return lastirq - 1; -} - -void __init -pcibios_update_irq(struct pci_dev *dev, int irq) -{ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -#warning pcibios_update_resource() is now a generic implementation - please check - -void __init -pcibios_fixup_bus(struct pci_bus *b) -{ - pci_fixup_irqs(pci_swizzle, pci_map_irq); -} - -int __init -pcibios_enable_device(struct pci_dev *dev) -{ - /* Not needed, since we enable all devices at startup. */ - return 0; -} - -void __init -pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -unsigned __init int pcibios_assign_all_busses(void) -{ - return 0; -} - -char * __init -pcibios_setup(char *str) -{ - /* Nothing to do for now. */ - - return str; -} - -/* - * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses - * to find the slot number in sense of the bridge device register. - * XXX This also means multiple devices might rely on conflicting bridge - * settings. - */ - -static void __init -pci_disable_swapping(struct pci_dev *dev) -{ - unsigned int bus_id = (unsigned) dev->bus->number; - bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], - bus_to_wid[bus_id]); - int slot = PCI_SLOT(dev->devfn); - - /* Turn off byte swapping */ - bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR; - bridge->b_widget.w_tflush; /* Flush */ -} - -static void __init -pci_enable_swapping(struct pci_dev *dev) -{ - unsigned int bus_id = (unsigned) dev->bus->number; - bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], - bus_to_wid[bus_id]); - int slot = PCI_SLOT(dev->devfn); - - /* Turn on byte swapping */ - bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR; - bridge->b_widget.w_tflush; /* Flush */ -} - -static void __init -pci_fixup_ioc3(struct pci_dev *d) -{ - unsigned long bus_id = (unsigned) d->bus->number; - - printk("PCI: Fixing base addresses for IOC3 device %s\n", d->slot_name); - - d->resource[0].start |= NODE_OFFSET(bus_to_nid[bus_id]); - d->resource[0].end |= NODE_OFFSET(bus_to_nid[bus_id]); - - pci_disable_swapping(d); -} - -static void __init -pci_fixup_isp1020(struct pci_dev *d) -{ - unsigned short command; - - d->resource[0].start |= ((unsigned long)(bus_to_nid[d->bus->number])<<32); - printk("PCI: Fixing isp1020 in [bus:slot.fn] %s\n", d->slot_name); - - /* - * Configure device to allow bus mastering, i/o and memory mapping. - * Older qlogicisp driver expects to have the IO space enable - * bit set. Things stop working if we program the controllers as not - * having PCI_COMMAND_MEMORY, so we have to fudge the mem_flags. - */ - - pci_set_master(d); - pci_read_config_word(d, PCI_COMMAND, &command); - command |= PCI_COMMAND_MEMORY; - command |= PCI_COMMAND_IO; - pci_write_config_word(d, PCI_COMMAND, command); - d->resource[1].flags |= 1; - - pci_enable_swapping(d); -} - -static void __init -pci_fixup_isp2x00(struct pci_dev *d) -{ - unsigned int bus_id = (unsigned) d->bus->number; - bridge_t *bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[bus_id], - bus_to_wid[bus_id]); - bridgereg_t devreg; - int i; - int slot = PCI_SLOT(d->devfn); - unsigned int start; - unsigned short command; - - printk("PCI: Fixing isp2x00 in [bus:slot.fn] %s\n", d->slot_name); - - /* set the resource struct for this device */ - start = (u32) (u64)bridge; /* yes, we want to lose the upper 32 bits here */ - start |= BRIDGE_DEVIO(slot); - - d->resource[0].start = start; - d->resource[0].end = d->resource[0].start + 0xff; - d->resource[0].flags = IORESOURCE_IO; - - d->resource[1].start = start; - d->resource[1].end = d->resource[0].start + 0xfff; - d->resource[1].flags = IORESOURCE_MEM; - - /* - * set the bridge device(x) reg for this device - */ - devreg = bridge->b_device[slot].reg; - /* point device(x) to it appropriate small window */ - devreg &= ~BRIDGE_DEV_OFF_MASK; - devreg |= (start >> 20) & BRIDGE_DEV_OFF_MASK; - bridge->b_device[slot].reg = devreg; - - pci_enable_swapping(d); - - /* set card's base addr reg */ - //pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x500001); - //pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0x8b00000); - //pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, 0x8b20000); - - /* I got these from booting irix on system...*/ - pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_0, 0x200001); - //pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, 0xf800000); - pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, 0x10200000); - - pci_conf0_write_config_dword(d, PCI_BASE_ADDRESS_1, start); - //pci_conf0_write_config_dword(d, PCI_ROM_ADDRESS, (start | 0x20000)); - - /* set cache line size */ - pci_conf0_write_config_dword(d, PCI_CACHE_LINE_SIZE, 0xf080); - - /* set pci bus timeout */ - bridge->b_bus_timeout |= BRIDGE_BUS_PCI_RETRY_HLD(0x3); - bridge->b_wid_tflush; - printk("PCI: bridge bus timeout= 0x%x \n", bridge->b_bus_timeout); - - /* set host error field */ - bridge->b_int_host_err = 0x44; - bridge->b_wid_tflush; - - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - for (i=0; i<8; i++) - printk("PCI: device(%d)= 0x%x\n",i,bridge->b_device[i].reg); - - /* configure device to allow bus mastering, i/o and memory mapping */ - pci_set_master(d); - pci_read_config_word(d, PCI_COMMAND, &command); - command |= PCI_COMMAND_MEMORY; - command |= PCI_COMMAND_IO; - pci_write_config_word(d, PCI_COMMAND, command); - /*d->resource[1].flags |= 1;*/ -} - -struct pci_fixup pcibios_fixups[] = { - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, - pci_fixup_ioc3 }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, - pci_fixup_isp1020 }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100, - pci_fixup_isp2x00 }, - { PCI_FIXUP_HEADER, PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200, - pci_fixup_isp2x00 }, - { 0 } -}; diff -Nru a/arch/mips64/sgi-ip27/ip27-reset.c b/arch/mips64/sgi-ip27/ip27-reset.c --- a/arch/mips64/sgi-ip27/ip27-reset.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,76 +0,0 @@ -/* - * 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. - * - * Reset an IP27. - * - * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/smp.h> -#include <linux/mmzone.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/sgialib.h> -#include <asm/sn/addrs.h> -#include <asm/sn/arch.h> -#include <asm/sn/gda.h> -#include <asm/sn/sn0/hub.h> - -void machine_restart(char *command) __attribute__((noreturn)); -void machine_halt(void) __attribute__((noreturn)); -void machine_power_off(void) __attribute__((noreturn)); - -#define noreturn while(1); /* Silence gcc. */ - -/* XXX How to pass the reboot command to the firmware??? */ -void machine_restart(char *command) -{ -#if 0 - int i; -#endif - - printk("Reboot started from CPU %d\n", smp_processor_id()); -#ifdef CONFIG_SMP - smp_send_stop(); -#endif -#if 0 - for (i = 0; i < numnodes; i++) - REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, - PROMOP_REBOOT); -#else - LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); -#endif - noreturn; -} - -void machine_halt(void) -{ - int i; - -#ifdef CONFIG_SMP - smp_send_stop(); -#endif - for (i = 0; i < numnodes; i++) - REMOTE_HUB_S(COMPACT_TO_NASID_NODEID(i), PROMOP_REG, - PROMOP_RESTART); - LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET); - noreturn; -} - -void machine_power_off(void) -{ - /* To do ... */ - noreturn; -} - -void ip27_reboot_setup(void) -{ - /* Nothing to do on IP27. */ -} diff -Nru a/arch/mips64/sgi-ip27/ip27-rtc.c b/arch/mips64/sgi-ip27/ip27-rtc.c --- a/arch/mips64/sgi-ip27/ip27-rtc.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,319 +0,0 @@ -/* - * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip - * - * Real Time Clock interface for Linux - * - * TODO: Implement periodic interrupts. - * - * Copyright (C) 2000 Silicon Graphics, Inc. - * Written by Ulf Carlsson (ulfc@engr.sgi.com) - * - * Based on code written by Paul Gortmaker. - * - * This driver allows use of the real time clock (built into - * nearly all computers) from user space. It exports the /dev/rtc - * interface supporting various ioctl() and also the /proc/rtc - * pseudo-file for status information. - * - * 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 RTC_VERSION "1.09b" - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/miscdevice.h> -#include <linux/ioport.h> -#include <linux/fcntl.h> -#include <linux/rtc.h> -#include <linux/init.h> -#include <linux/poll.h> -#include <linux/proc_fs.h> -#include <linux/smp_lock.h> -#include <linux/bcd.h> - -#include <asm/m48t35.h> -#include <asm/sn/ioc3.h> -#include <asm/io.h> -#include <asm/uaccess.h> -#include <asm/system.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/sn0/ip27.h> -#include <asm/sn/sn0/hub.h> - -static int rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data); - -static void get_rtc_time(struct rtc_time *rtc_tm); - -static atomic_t rtc_ready = ATOMIC_INIT(1); -static unsigned long rtc_freq; /* Current periodic IRQ rate */ -static struct m48t35_rtc *rtc; - -/* - * If this driver ever becomes modularised, it will be really nice - * to make the epoch retain its value across module reload... - */ - -static unsigned long epoch = 1970; /* year corresponding to 0x00 */ - -static const unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - - struct rtc_time wtime; - - switch (cmd) { - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - get_rtc_time(&wtime); - break; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned int yrs; - unsigned long flags; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - yrs = rtc_tm.tm_year + 1900; - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm.tm_mday; - hrs = rtc_tm.tm_hour; - min = rtc_tm.tm_min; - sec = rtc_tm.tm_sec; - - if (yrs < 1970) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if ((yrs -= epoch) > 255) /* They are unsigned */ - return -EINVAL; - - save_flags(flags); - cli(); - if (yrs > 169) { - restore_flags(flags); - return -EINVAL; - } - if (yrs >= 100) - yrs -= 100; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - - rtc->control &= ~M48T35_RTC_SET; - rtc->year = yrs; - rtc->month = mon; - rtc->date = day; - rtc->hour = hrs; - rtc->min = min; - rtc->sec = sec; - rtc->control &= ~M48T35_RTC_SET; - - restore_flags(flags); - return 0; - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int rtc_open(struct inode *inode, struct file *file) -{ - if( atomic_dec_and_test( &rtc_ready ) ) - { - atomic_inc( &rtc_ready ); - return -EBUSY; - } - return 0; -} - -static int rtc_release(struct inode *inode, struct file *file) -{ - atomic_inc( &rtc_ready ); - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations rtc_fops = { - .owner = THIS_MODULE, - .ioctl = rtc_ioctl, - .open = rtc_open, - .release = rtc_release, -}; - -static struct miscdevice rtc_dev= -{ - RTC_MINOR, - "rtc", - &rtc_fops -}; - -static int __init rtc_init(void) -{ - unsigned long flags; - nasid_t nid; - - nid = get_nasid(); - rtc = (struct m48t35_rtc *) - KL_CONFIG_CH_CONS_INFO(nid)->memory_base + IOC3_BYTEBUS_DEV0; - - printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION); - if (misc_register(&rtc_dev)) { - printk(KERN_ERR "rtc: cannot register misc device.\n"); - return -ENODEV; - } - if (!create_proc_read_entry ("rtc", 0, NULL, rtc_read_proc, NULL)) { - printk(KERN_ERR "rtc: cannot create /proc/rtc.\n"); - misc_deregister(&rtc_dev); - return -ENOENT; - } - - save_flags(flags); - cli(); - restore_flags(flags); - rtc_freq = 1024; - return 0; -} - -static void __exit rtc_exit (void) -{ - /* interrupts and timer disabled at this point by rtc_release */ - - remove_proc_entry ("rtc", NULL); - misc_deregister(&rtc_dev); -} - -module_init(rtc_init); -module_exit(rtc_exit); - -/* - * Info exported via "/proc/rtc". - */ - -static int rtc_get_status(char *buf) -{ - char *p; - struct rtc_time tm; - - /* - * Just emulate the standard /proc/rtc - */ - - p = buf; - - get_rtc_time(&tm); - - /* - * There is no way to tell if the luser has the RTC set for local - * time or for Universal Standard Time (GMT). Probably local though. - */ - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d\n" - "rtc_date\t: %04d-%02d-%02d\n" - "rtc_epoch\t: %04lu\n" - "24hr\t\t: yes\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); - - return p - buf; -} - -static int rtc_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = rtc_get_status(page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - -static void get_rtc_time(struct rtc_time *rtc_tm) -{ - - unsigned long flags; - - /* - * Do we need to wait for the last update to finish? - */ - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - save_flags(flags); - cli(); - rtc->control |= M48T35_RTC_READ; - rtc_tm->tm_sec = rtc->sec; - rtc_tm->tm_min = rtc->min; - rtc_tm->tm_hour = rtc->hour; - rtc_tm->tm_mday = rtc->date; - rtc_tm->tm_mon = rtc->month; - rtc_tm->tm_year = rtc->year; - rtc->control &= ~M48T35_RTC_READ; - restore_flags(flags); - - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if ((rtc_tm->tm_year += (epoch - 1900)) <= 69) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} diff -Nru a/arch/mips64/sgi-ip27/ip27-setup.c b/arch/mips64/sgi-ip27/ip27-setup.c --- a/arch/mips64/sgi-ip27/ip27-setup.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,310 +0,0 @@ -/* - * 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. - * - * SGI IP27 specific setup. - * - * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copyright (C) 1999, 2000 Silcon Graphics, Inc. - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/spinlock.h> -#include <linux/sched.h> -#include <linux/smp.h> -#include <asm/io.h> -#include <asm/sn/types.h> -#include <asm/sn/sn0/addrs.h> -#include <asm/sn/sn0/hubni.h> -#include <asm/sn/sn0/hubio.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/ioc3.h> -#include <asm/mipsregs.h> -#include <asm/sn/arch.h> -#include <asm/sn/sn_private.h> -#include <asm/pci/bridge.h> -#include <asm/paccess.h> -#include <asm/sn/sn0/ip27.h> - -/* Check against user dumbness. */ -#ifdef CONFIG_VT -#error CONFIG_VT not allowed for IP27. -#endif - -#undef DEBUG_SETUP -#ifdef DEBUG_SETUP -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -unsigned long mips_io_port_base = IO_BASE; - -/* - * get_nasid() returns the physical node id number of the caller. - */ -nasid_t -get_nasid(void) -{ - return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK) - >> NSRI_NODEID_SHFT); -} - -/* Extracted from the IOC3 meta driver. FIXME. */ -static inline void ioc3_sio_init(void) -{ - struct ioc3 *ioc3; - nasid_t nid; - long loops; - - nid = get_nasid(); - ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; - - ioc3->sscr_a = 0; /* PIO mode for uarta. */ - ioc3->sscr_b = 0; /* PIO mode for uartb. */ - ioc3->sio_iec = ~0; - ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT); - - loops=1000000; while(loops--); - ioc3->sregs.uarta.iu_fcr = 0; - ioc3->sregs.uartb.iu_fcr = 0; - loops=1000000; while(loops--); -} - -static inline void ioc3_eth_init(void) -{ - struct ioc3 *ioc3; - nasid_t nid; - - nid = get_nasid(); - ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; - - ioc3->eier = 0; -} - -/* Try to catch kernel missconfigurations and give user an indication what - option to select. */ -static void __init verify_mode(void) -{ - int n_mode; - - n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK; - printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M'); -#ifdef CONFIG_SGI_SN0_N_MODE - if (!n_mode) - panic("Kernel compiled for M mode."); -#else - if (n_mode) - panic("Kernel compiled for N mode."); -#endif -} - -#define XBOW_WIDGET_PART_NUM 0x0 -#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ -#define BASE_XBOW_PORT 8 /* Lowest external port */ - -unsigned int bus_to_cpu[256]; -unsigned long bus_to_baddr[256]; - -void __init pcibr_setup(cnodeid_t nid) -{ - int i, start, num; - unsigned long masterwid; - bridge_t *bridge; - volatile u64 hubreg; - nasid_t nasid, masternasid; - xwidget_part_num_t partnum; - widgetreg_t widget_id; - static spinlock_t pcibr_setup_lock = SPIN_LOCK_UNLOCKED; - - /* - * If the master is doing this for headless node, nothing to do. - * This is because currently we require at least one of the hubs - * (master hub) connected to the xbow to have at least one enabled - * cpu to receive intrs. Else we need an array bus_to_intrnasid[] - * that bridge_startup() needs to use to target intrs. All dma is - * routed thru the widget of the master hub. The master hub wid - * is selectable by WIDGET_A below. - */ - if (nid != get_compact_nodeid()) - return; - /* - * find what's on our local node - */ - spin_lock(&pcibr_setup_lock); - start = num_bridges; /* Remember where we start from */ - nasid = COMPACT_TO_NASID_NODEID(nid); - hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); - if (hubreg & IIO_LLP_CSR_IS_UP) { - /* link is up */ - widget_id = *(volatile widgetreg_t *) - (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); - partnum = XWIDGET_PART_NUM(widget_id); - printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x", - smp_processor_id(), nasid, partnum); - if (partnum == BRIDGE_WIDGET_PART_NUM) { - /* - * found direct connected bridge so must be Origin200 - */ - printk("...is bridge\n"); - num_bridges = 1; - bus_to_wid[0] = 0x8; - bus_to_nid[0] = 0; - masterwid = 0xa; - bus_to_baddr[0] = 0xa100000000000000UL; - } else if (partnum == XBOW_WIDGET_PART_NUM) { - lboard_t *brd; - klxbow_t *xbow_p; - /* - * found xbow, so may have multiple bridges - * need to probe xbow - */ - printk("...is xbow\n"); - - if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), - KLTYPE_MIDPLANE8)) == NULL) - printk("argh\n"); - else - printk("brd = 0x%lx\n", (unsigned long) brd); - if ((xbow_p = (klxbow_t *) - find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL) - printk("argh\n"); - else { - /* - * Okay, here's a xbow. Lets arbitrate and find - * out if we should initialize it. Set enabled - * hub connected at highest or lowest widget as - * master. - */ -#ifdef WIDGET_A - i = HUB_WIDGET_ID_MAX + 1; - do { - i--; - } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) || - (!XBOW_PORT_IS_ENABLED(xbow_p, i))); -#else - i = HUB_WIDGET_ID_MIN - 1; - do { - i++; - } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) || - (!XBOW_PORT_IS_ENABLED(xbow_p, i))); -#endif - masterwid = i; - masternasid = XBOW_PORT_NASID(xbow_p, i); - if (nasid == masternasid) - for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) { - if (!XBOW_PORT_IS_ENABLED(xbow_p, i)) - continue; - if (XBOW_PORT_TYPE_IO(xbow_p, i)) { - widget_id = *(volatile widgetreg_t *) - (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID); - partnum = XWIDGET_PART_NUM(widget_id); - if (partnum == BRIDGE_WIDGET_PART_NUM) { - printk("widget 0x%x is a bridge\n", i); - bus_to_wid[num_bridges] = i; - bus_to_nid[num_bridges] = nasid; - bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56)); /* Barrier set */ - num_bridges++; - } - } - } - } - } else if (partnum == XXBOW_WIDGET_PART_NUM) { - /* - * found xbridge, assume ibrick for now - */ - printk("...is xbridge\n"); - bus_to_wid[0] = 0xb; - bus_to_wid[1] = 0xe; - bus_to_wid[2] = 0xf; - - bus_to_nid[0] = 0; - bus_to_nid[1] = 0; - bus_to_nid[2] = 0; - - bus_to_baddr[0] = 0xa100000000000000UL; - bus_to_baddr[1] = 0xa100000000000000UL; - bus_to_baddr[2] = 0xa100000000000000UL; - masterwid = 0xa; - num_bridges = 3; - } - } - num = num_bridges - start; - spin_unlock(&pcibr_setup_lock); - /* - * set bridge registers - */ - for (i = start; i < (start + num); i++) { - - DBG("pcibr_setup: bus= %d bus_to_wid[%2d]= %d bus_to_nid[%2d]= %d\n", - i, i, bus_to_wid[i], i, bus_to_nid[i]); - - bus_to_cpu[i] = smp_processor_id(); - /* - * point to this bridge - */ - bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]); - /* - * Clear all pending interrupts. - */ - bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR); - /* - * Until otherwise set up, assume all interrupts are from slot 0 - */ - bridge->b_int_device = (u32) 0x0; - /* - * swap pio's to pci mem and io space (big windows) - */ - bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP; - bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP; - - /* - * Hmm... IRIX sets additional bits in the address which - * are documented as reserved in the bridge docs. - */ - bridge->b_int_mode = 0x0; /* Don't clear ints */ - bridge->b_wid_int_upper = 0x8000 | (masterwid << 16); - bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/ - bridge->b_dir_map = (masterwid << 20); /* DMA */ - bridge->b_int_enable = 0; - - bridge->b_wid_tflush; /* wait until Bridge PIO complete */ - } -} - -extern void ip27_setup_console(void); - -void __init ip27_setup(void) -{ - nasid_t nid; - hubreg_t p, e; - - ip27_setup_console(); - - num_bridges = 0; - /* - * hub_rtc init and cpu clock intr enabled for later calibrate_delay. - */ - DBG("ip27_setup(): Entered.\n"); - nid = get_nasid(); - printk("IP27: Running on node %d.\n", nid); - - p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1; - e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1; - printk("Node %d has %s primary CPU%s.\n", nid, - p ? "a" : "no", - e ? ", CPU is running" : ""); - - p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1; - e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1; - printk("Node %d has %s secondary CPU%s.\n", nid, - p ? "a" : "no", - e ? ", CPU is running" : ""); - - verify_mode(); - ioc3_sio_init(); - ioc3_eth_init(); - per_cpu_init(); -} diff -Nru a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c --- a/arch/mips64/sgi-ip27/ip27-timer.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,294 +0,0 @@ -/* - * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) - * Copytight (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include <linux/config.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/kernel_stat.h> -#include <linux/param.h> -#include <linux/time.h> -#include <linux/timex.h> -#include <linux/mm.h> -#include <linux/bcd.h> - -#include <asm/pgtable.h> -#include <asm/sgialib.h> -#include <asm/sn/ioc3.h> -#include <asm/m48t35.h> -#include <asm/sn/klconfig.h> -#include <asm/sn/arch.h> -#include <asm/sn/addrs.h> -#include <asm/sn/sn_private.h> -#include <asm/sn/sn0/ip27.h> -#include <asm/sn/sn0/hub.h> - -/* - * This is a hack; we really need to figure these values out dynamically - * - * Since 800 ns works very well with various HUB frequencies, such as - * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. - * - * Ralf: which clock rate is used to feed the counter? - */ -#define NSEC_PER_CYCLE 800 -#define NSEC_PER_SEC 1000000000 -#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE) -#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ) - -static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ -static long last_rtc_update; /* Last time the rtc clock got updated */ - -extern volatile unsigned long wall_jiffies; - - -static int set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - struct m48t35_rtc *rtc; - nasid_t nid; - - nid = get_nasid(); - rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + - IOC3_BYTEBUS_DEV0); - - rtc->control |= M48T35_RTC_READ; - cmos_minutes = rtc->min; - BCD_TO_BIN(cmos_minutes); - rtc->control &= ~M48T35_RTC_READ; - - /* - * Since we're only adjusting minutes and seconds, don't interfere with - * hour overflow. This avoids messing with unknown time zones but - * requires your RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - rtc->control |= M48T35_RTC_SET; - rtc->sec = real_seconds; - rtc->min = real_minutes; - rtc->control &= ~M48T35_RTC_SET; - } else { - printk(KERN_WARNING - "set_rtc_mmss: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - return retval; -} - -void rt_timer_interrupt(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - int cpuA = ((cputoslice(cpu)) == 0); - int irq = 7; /* XXX Assign number */ - - write_seqlock(&xtime_lock); - -again: - LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ - ct_cur[cpu] += CYCLES_PER_JIFFY; - LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]); - - if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu]) - goto again; - - kstat_cpu(cpu).irqs[irq]++; /* kstat only for bootcpu? */ - - if (cpu == 0) - do_timer(regs); - -#ifdef CONFIG_SMP - { - int user = user_mode(regs); - - /* - * update_process_times() expects us to have done irq_enter(). - * Besides, if we don't timer interrupts ignore the global - * interrupt lock, which is the WrongThing (tm) to do. - * Picked from i386 code. - */ - irq_enter(cpu, 0); - update_process_times(user); - irq_exit(cpu, 0); - } -#endif /* CONFIG_SMP */ - - /* - * If we have an externally synchronized Linux clock, then update - * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to when a second starts. - */ - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660) { - if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) { - if (set_rtc_mmss(xtime.tv_sec + 1) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; - } else if (xtime.tv_usec <= ((unsigned) tick) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; - } - } - - write_sequnlock(&xtime_lock); - - if (softirq_pending(cpu)) - do_softirq(); -} - -unsigned long inline do_gettimeoffset(void) -{ - unsigned long ct_cur1; - ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; - return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; -} - -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long usec, sec; - unsigned long seq; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - - usec = do_gettimeoffset(); - { - unsigned long lost = jiffies - wall_jiffies; - if (lost) - usec += lost * (1000000 / HZ); - } - sec = xtime.tv_sec; - usec += xtime.tv_usec; - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - while (usec >= 1000000) { - usec -= 1000000; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} - -void do_settimeofday(struct timeval *tv) -{ - write_seqlock_irq(&xtime_lock); - tv->tv_usec -= do_gettimeoffset(); - tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); - - while (tv->tv_usec < 0) { - tv->tv_usec += 1000000; - tv->tv_sec--; - } - - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ - time_status |= STA_UNSYNC; - time_maxerror = NTP_PHASE_LIMIT; - time_esterror = NTP_PHASE_LIMIT; - write_sequnlock_irq(&xtime_lock); -} - -/* Includes for ioc3_init(). */ -#include <asm/sn/types.h> -#include <asm/sn/sn0/addrs.h> -#include <asm/sn/sn0/hubni.h> -#include <asm/sn/sn0/hubio.h> -#include <asm/pci/bridge.h> - -static __init unsigned long get_m48t35_time(void) -{ - unsigned int year, month, date, hour, min, sec; - struct m48t35_rtc *rtc; - nasid_t nid; - - nid = get_nasid(); - rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + - IOC3_BYTEBUS_DEV0); - - rtc->control |= M48T35_RTC_READ; - sec = rtc->sec; - min = rtc->min; - hour = rtc->hour; - date = rtc->date; - month = rtc->month; - year = rtc->year; - rtc->control &= ~M48T35_RTC_READ; - - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(date); - BCD_TO_BIN(month); - BCD_TO_BIN(year); - - year += 1970; - - return mktime(year, month, date, hour, min, sec); -} - -void __init time_init(void) -{ - xtime.tv_sec = get_m48t35_time(); - xtime.tv_usec = 0; -} - -void __init cpu_time_init(void) -{ - lboard_t *board; - klcpu_t *cpu; - int cpuid; - - /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */ - board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27); - if (!board) - panic("Can't find board info for myself."); - - cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX; - cpu = (klcpu_t *) KLCF_COMP(board, cpuid); - if (!cpu) - panic("No information about myself?"); - - printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); - - set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK); -} - -void __init hub_rtc_init(cnodeid_t cnode) -{ - /* - * We only need to initialize the current node. - * If this is not the current node then it is a cpuless - * node and timeouts will not happen there. - */ - if (get_compact_nodeid() == cnode) { - int cpu = smp_processor_id(); - LOCAL_HUB_S(PI_RT_EN_A, 1); - LOCAL_HUB_S(PI_RT_EN_B, 1); - LOCAL_HUB_S(PI_PROF_EN_A, 0); - LOCAL_HUB_S(PI_PROF_EN_B, 0); - ct_cur[cpu] = CYCLES_PER_JIFFY; - LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]); - LOCAL_HUB_S(PI_RT_COUNT, 0); - LOCAL_HUB_S(PI_RT_PEND_A, 0); - LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]); - LOCAL_HUB_S(PI_RT_COUNT, 0); - LOCAL_HUB_S(PI_RT_PEND_B, 0); - } -} diff -Nru a/arch/mips64/sgi-ip32/Makefile b/arch/mips64/sgi-ip32/Makefile --- a/arch/mips64/sgi-ip32/Makefile Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,13 +0,0 @@ -# -# Makefile for the SGI specific kernel interface routines -# under Linux. -# - -extra-y := ip32-irq-glue.o - -obj-y += ip32-irq.o ip32-rtc.o ip32-setup.o ip32-irq-glue.o \ - ip32-berr.o ip32-timer.o crime.o - -obj-$(CONFIG_PCI) += ip32-pci.o ip32-pci-dma.o - -EXTRA_AFLAGS := $(CFLAGS) diff -Nru a/arch/mips64/sgi-ip32/crime.c b/arch/mips64/sgi-ip32/crime.c --- a/arch/mips64/sgi-ip32/crime.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,50 +0,0 @@ -/* - * 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) 2001 Keith M Wesolowski - */ -#include <linux/types.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <asm/ip32/crime.h> -#include <asm/ptrace.h> -#include <asm/promlib.h> - -void __init crime_init (void) -{ - u64 id = crime_read_64 (CRIME_ID); - u64 rev = id & CRIME_ID_REV; - - id = (id & CRIME_ID_IDBITS) >> 4; - - printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev, - (unsigned long) CRIME_BASE); -} - -/* XXX Like on Sun, these give us various useful information to printk. */ -void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) -{ - u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT); - u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR); - memerr &= CRIME_MEM_ERROR_STAT_MASK; - - printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n", - addr << 2, memerr); - - crime_write_64 (CRIME_MEM_ERROR_STAT, 0); -} - -void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) -{ - u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT); - u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR); - cpuerr &= CRIME_CPU_ERROR_MASK; - addr <<= 2UL; - - printk ("CRIME CPU interface error detected at %09lx status %08lx\n", - addr, cpuerr); - - crime_write_64 (CRIME_CPU_ERROR_STAT, 0); -} diff -Nru a/arch/mips64/sgi-ip32/ip32-berr.c b/arch/mips64/sgi-ip32/ip32-berr.c --- a/arch/mips64/sgi-ip32/ip32-berr.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,97 +0,0 @@ -/* - * 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, 1995, 1996, 1999, 2000 by Ralf Baechle - * Copyright (C) 1999, 2000 by Silicon Graphics - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <asm/uaccess.h> -#include <asm/paccess.h> -#include <asm/addrspace.h> -#include <asm/ptrace.h> - -/* XXX I have no idea what this does --kmw */ - -extern asmlinkage void handle_ibe(void); -extern asmlinkage void handle_dbe(void); - -extern const struct exception_table_entry __start___dbe_table[]; -extern const struct exception_table_entry __stop___dbe_table[]; - -static inline unsigned long -search_one_table(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - while (first <= last) { - const struct exception_table_entry *mid; - long diff; - - mid = (last - first) / 2 + first; - diff = mid->insn - value; - if (diff == 0) - return mid->nextinsn; - else if (diff < 0) - first = mid+1; - else - last = mid-1; - } - return 0; -} - -static inline unsigned long -search_dbe_table(unsigned long addr) -{ - unsigned long ret; - - /* There is only the kernel to search. */ - ret = search_one_table(__start___dbe_table, __stop___dbe_table-1, addr); - if (ret) return ret; - - return 0; -} - -void do_ibe(struct pt_regs *regs) -{ - printk("Got ibe at 0x%lx\n", regs->cp0_epc); - show_regs(regs); - dump_tlb_addr(regs->cp0_epc); - force_sig(SIGBUS, current); - while(1); -} - -void do_dbe(struct pt_regs *regs) -{ - unsigned long fixup; - - fixup = search_dbe_table(regs->cp0_epc); - if (fixup) { - long new_epc; - - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); - regs->cp0_epc = new_epc; - return; - } - - printk("Got dbe at 0x%lx\n", regs->cp0_epc); - show_regs(regs); - dump_tlb_all(); - while(1); - force_sig(SIGBUS, current); -} - -void __init -bus_error_init(void) -{ - int dummy; - - set_except_vector(6, handle_ibe); - set_except_vector(7, handle_dbe); - - /* At this time nothing uses the DBE protection mechanism on the - O2, so this here is needed to make the kernel link. */ - get_dbe(dummy, (int *)KSEG0); -} diff -Nru a/arch/mips64/sgi-ip32/ip32-irq-glue.S b/arch/mips64/sgi-ip32/ip32-irq-glue.S --- a/arch/mips64/sgi-ip32/ip32-irq-glue.S Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,87 +0,0 @@ -/* - * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead - * - * 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) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include <asm/asm.h> -#include <asm/regdef.h> -#include <asm/mipsregs.h> -#include <asm/stackframe.h> -#include <asm/addrspace.h> -#include <asm/ip32/ip32_ints.h> - - .text - .set noreorder - .set noat - .align 5 - NESTED(ip32_handle_int, PT_SIZE, ra) - .set noat - SAVE_ALL - CLI # TEST: interrupts should be off - .set at - .set noreorder - - mfc0 s0,CP0_CAUSE - - andi t1, s0, IE_IRQ0 - bnez t1, handle_irq0 - andi t1, s0, IE_IRQ1 - bnez t1, handle_irq1 - andi t1, s0, IE_IRQ2 - bnez t1, handle_irq2 - andi t1, s0, IE_IRQ3 - bnez t1, handle_irq3 - andi t1, s0, IE_IRQ4 - bnez t1, handle_irq4 - andi t1, s0, IE_IRQ5 - bnez t1, handle_irq5 - nop - - /* Either someone has triggered the "software interrupts" - * or we lost an interrupt somehow. Ignore it. - */ - j ret_from_irq - nop - -handle_irq0: - jal ip32_irq0 - move a0, sp - j ret_from_irq - nop - -handle_irq1: - jal ip32_irq1 - move a0, sp - j ret_from_irq - nop - -handle_irq2: - jal ip32_irq2 - move a0, sp - j ret_from_irq - nop - -handle_irq3: - jal ip32_irq3 - move a0, sp - j ret_from_irq - nop - -handle_irq4: - jal ip32_irq4 - move a0, sp - j ret_from_irq - nop - -handle_irq5: - jal ip32_irq5 - move a0, sp - j ret_from_irq - nop - - END(ip32_handle_int) diff -Nru a/arch/mips64/sgi-ip32/ip32-irq.c b/arch/mips64/sgi-ip32/ip32-irq.c --- a/arch/mips64/sgi-ip32/ip32-irq.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,556 +0,0 @@ -/* - * Code to handle IP32 IRQs - * - * 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) 2000 Harald Koerfgen - * Copyright (C) 2001 Keith M Wesolowski - */ -#include <linux/init.h> -#include <linux/kernel_stat.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/bitops.h> - -#include <asm/bitops.h> -#include <asm/mipsregs.h> -#include <asm/system.h> -#include <asm/ip32/ip32_ints.h> -#include <asm/ip32/crime.h> -#include <asm/ip32/mace.h> -#include <asm/signal.h> - -#undef DEBUG_IRQ -#ifdef DEBUG_IRQ -#define DBG(x...) printk(x) -#else -#define DBG(x...) -#endif - -/* O2 irq map - * - * IP0 -> software (ignored) - * IP1 -> software (ignored) - * IP2 -> (irq0) C crime 1.1 all interrupts; crime 1.5 ??? - * IP3 -> (irq1) X unknown - * IP4 -> (irq2) X unknown - * IP5 -> (irq3) X unknown - * IP6 -> (irq4) X unknown - * IP7 -> (irq5) 0 CPU count/compare timer (system timer) - * - * crime: (C) - * - * CRIME_INT_STAT 31:0: - * - * 0 -> 1 Video in 1 - * 1 -> 2 Video in 2 - * 2 -> 3 Video out - * 3 -> 4 Mace ethernet - * 4 -> S SuperIO sub-interrupt - * 5 -> M Miscellaneous sub-interrupt - * 6 -> A Audio sub-interrupt - * 7 -> 8 PCI bridge errors - * 8 -> 9 PCI SCSI aic7xxx 0 - * 9 -> 10 PCI SCSI aic7xxx 1 - * 10 -> 11 PCI slot 0 - * 11 -> 12 unused (PCI slot 1) - * 12 -> 13 unused (PCI slot 2) - * 13 -> 14 unused (PCI shared 0) - * 14 -> 15 unused (PCI shared 1) - * 15 -> 16 unused (PCI shared 2) - * 16 -> 17 GBE0 (E) - * 17 -> 18 GBE1 (E) - * 18 -> 19 GBE2 (E) - * 19 -> 20 GBE3 (E) - * 20 -> 21 CPU errors - * 21 -> 22 Memory errors - * 22 -> 23 RE empty edge (E) - * 23 -> 24 RE full edge (E) - * 24 -> 25 RE idle edge (E) - * 25 -> 26 RE empty level - * 26 -> 27 RE full level - * 27 -> 28 RE idle level - * 28 -> 29 unused (software 0) (E) - * 29 -> 30 unused (software 1) (E) - * 30 -> 31 unused (software 2) - crime 1.5 CPU SysCorError (E) - * 31 -> 32 VICE - * - * S, M, A: Use the MACE ISA interrupt register - * MACE_ISA_INT_STAT 31:0 - * - * 0-7 -> 33-40 Audio - * 8 -> 41 RTC - * 9 -> 42 Keyboard - * 10 -> X Keyboard polled - * 11 -> 44 Mouse - * 12 -> X Mouse polled - * 13-15 -> 46-48 Count/compare timers - * 16-19 -> 49-52 Parallel (16 E) - * 20-25 -> 53-58 Serial 1 (22 E) - * 26-31 -> 59-64 Serial 2 (28 E) - * - * Note that this means IRQs 5-7, 43, and 45 do not exist. This is a - * different IRQ map than IRIX uses, but that's OK as Linux irq handling - * is quite different anyway. - */ - -/* Some initial interrupts to set up */ -extern void crime_memerr_intr (unsigned int irq, void *dev_id, - struct pt_regs *regs); -extern void crime_cpuerr_intr (unsigned int irq, void *dev_id, - struct pt_regs *regs); - -struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, - 0, "CRIME memory error", NULL, - NULL }; -struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, - 0, "CRIME CPU error", NULL, - NULL }; - -unsigned long spurious_count = 0; -extern void ip32_handle_int (void); -extern void do_IRQ (unsigned int irq, struct pt_regs *regs); - -/* For interrupts wired from a single device to the CPU. Only the clock - * uses this it seems, which is IRQ 0 and IP7. - */ - -static void enable_cpu_irq (unsigned int irq) -{ - set_cp0_status (STATUSF_IP7); -} - -static unsigned int startup_cpu_irq (unsigned int irq) { - enable_cpu_irq (irq); - return 0; -} - -static void disable_cpu_irq (unsigned int irq) -{ - clear_cp0_status (STATUSF_IP7); -} - -static void end_cpu_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_cpu_irq (irq); -} - -#define shutdown_cpu_irq disable_cpu_irq -#define mask_and_ack_cpu_irq disable_cpu_irq - -static struct hw_interrupt_type ip32_cpu_interrupt = { - "IP32 CPU", - startup_cpu_irq, - shutdown_cpu_irq, - enable_cpu_irq, - disable_cpu_irq, - mask_and_ack_cpu_irq, - end_cpu_irq, - NULL -}; - -/* - * This is for pure CRIME interrupts - ie not MACE. The advantage? - * We get to split the register in half and do faster lookups. - */ - -static void enable_crime_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static unsigned int startup_crime_irq (unsigned int irq) -{ - enable_crime_irq (irq); - return 0; /* This is probably not right; we could have pending irqs */ -} - -static void disable_crime_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static void mask_and_ack_crime_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - /* Edge triggered interrupts must be cleared. */ - if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ) - || (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ) - || (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) { - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_HARD_INT); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64 (CRIME_HARD_INT, crime_mask); - restore_flags (flags); - } - disable_crime_irq (irq); -} - -static void end_crime_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_crime_irq (irq); -} - -#define shutdown_crime_irq disable_crime_irq - -static struct hw_interrupt_type ip32_crime_interrupt = { - "IP32 CRIME", - startup_crime_irq, - shutdown_crime_irq, - enable_crime_irq, - disable_crime_irq, - mask_and_ack_crime_irq, - end_crime_irq, - NULL -}; - -/* This is for MACE PCI interrupts. We can decrease bus traffic by masking - * as close to the source as possible. This also means we can take the - * next chunk of the CRIME register in one piece. - */ - -static void enable_macepci_irq (unsigned int irq) -{ - u32 mace_mask; - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - mace_mask = mace_read_32 (MACEPCI_CONTROL); - mace_mask |= MACEPCI_CONTROL_INT (irq - 9); - mace_write_32 (MACEPCI_CONTROL, mace_mask); - /* In case the CRIME interrupt isn't enabled, we must enable it; - * however, we never disable interrupts at that level. - */ - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static unsigned int startup_macepci_irq (unsigned int irq) { - enable_macepci_irq (irq); - return 0; /* XXX */ -} - -static void disable_macepci_irq (unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - save_and_cli (flags); - mace_mask = mace_read_32 (MACEPCI_CONTROL); - mace_mask &= ~MACEPCI_CONTROL_INT (irq - 9); - mace_write_32 (MACEPCI_CONTROL, mace_mask); - restore_flags (flags); -} - -static void end_macepci_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_macepci_irq (irq); -} - -#define shutdown_macepci_irq disable_macepci_irq -#define mask_and_ack_macepci_irq disable_macepci_irq - -static struct hw_interrupt_type ip32_macepci_interrupt = { - "IP32 MACE PCI", - startup_macepci_irq, - shutdown_macepci_irq, - enable_macepci_irq, - disable_macepci_irq, - mask_and_ack_macepci_irq, - end_macepci_irq, - NULL -}; - -/* This is used for MACE ISA interrupts. That means bits 4-6 in the - * CRIME register. - */ - -static void enable_maceisa_irq (unsigned int irq) -{ - u64 crime_mask; - u32 mace_mask; - unsigned int crime_int = 0; - unsigned long flags; - - DBG ("maceisa enable: %u\n", irq); - - switch (irq) { - case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ: - crime_int = MACE_AUDIO_INT; - break; - case MACEISA_RTC_IRQ ... MACEISA_TIMER2_IRQ: - crime_int = MACE_MISC_INT; - break; - case MACEISA_PARALLEL_IRQ ... MACEISA_SERIAL2_RDMAOR_IRQ: - crime_int = MACE_SUPERIO_INT; - break; - } - DBG ("crime_int %016lx enabled\n", crime_int); - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask |= crime_int; - crime_write_64 (CRIME_INT_MASK, crime_mask); - mace_mask = mace_read_32 (MACEISA_INT_MASK); - mace_mask |= 1 << (irq - 33); - mace_write_32 (MACEISA_INT_MASK, mace_mask); - restore_flags (flags); -} - -static unsigned int startup_maceisa_irq (unsigned int irq) { - enable_maceisa_irq (irq); - return 0; -} - -static void disable_maceisa_irq (unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - save_and_cli (flags); - mace_mask = mace_read_32 (MACEISA_INT_MASK); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32 (MACEISA_INT_MASK, mace_mask); - restore_flags (flags); -} - -static void mask_and_ack_maceisa_irq (unsigned int irq) -{ - u32 mace_mask; - unsigned long flags; - - switch (irq) { - case MACEISA_PARALLEL_IRQ: - case MACEISA_SERIAL1_TDMAPR_IRQ: - case MACEISA_SERIAL2_TDMAPR_IRQ: - save_and_cli (flags); - mace_mask = mace_read_32 (MACEISA_INT_STAT); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32 (MACEISA_INT_STAT, mace_mask); - restore_flags (flags); - break; - } - disable_maceisa_irq (irq); -} - -static void end_maceisa_irq (unsigned irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_maceisa_irq (irq); -} - -#define shutdown_maceisa_irq disable_maceisa_irq - -static struct hw_interrupt_type ip32_maceisa_interrupt = { - "IP32 MACE ISA", - startup_maceisa_irq, - shutdown_maceisa_irq, - enable_maceisa_irq, - disable_maceisa_irq, - mask_and_ack_maceisa_irq, - end_maceisa_irq, - NULL -}; - -/* This is used for regular non-ISA, non-PCI MACE interrupts. That means - * bits 0-3 and 7 in the CRIME register. - */ - -static void enable_mace_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static unsigned int startup_mace_irq (unsigned int irq) -{ - enable_mace_irq (irq); - return 0; -} - -static void disable_mace_irq (unsigned int irq) -{ - u64 crime_mask; - unsigned long flags; - - save_and_cli (flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64 (CRIME_INT_MASK, crime_mask); - restore_flags (flags); -} - -static void end_mace_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_mace_irq (irq); -} - -#define shutdown_mace_irq disable_mace_irq -#define mask_and_ack_mace_irq disable_mace_irq - -static struct hw_interrupt_type ip32_mace_interrupt = { - "IP32 MACE", - startup_mace_irq, - shutdown_mace_irq, - enable_mace_irq, - disable_mace_irq, - mask_and_ack_mace_irq, - end_mace_irq, - NULL -}; - -static void ip32_unknown_interrupt (struct pt_regs *regs) -{ - u64 crime; - u32 mace; - - printk ("Unknown interrupt occurred!\n"); - printk ("cp0_status: %08x\tcp0_cause: %08x\n", - read_32bit_cp0_register (CP0_STATUS), - read_32bit_cp0_register (CP0_CAUSE)); - crime = crime_read_64 (CRIME_INT_MASK); - printk ("CRIME interrupt mask: %016lx\n", crime); - crime = crime_read_64 (CRIME_INT_STAT); - printk ("CRIME interrupt status: %016lx\n", crime); - crime = crime_read_64 (CRIME_HARD_INT); - printk ("CRIME hardware interrupt register: %016lx\n", crime); - mace = mace_read_32 (MACEISA_INT_MASK); - printk ("MACE ISA interrupt mask: %08x\n", mace); - mace = mace_read_32 (MACEISA_INT_STAT); - printk ("MACE ISA interrupt status: %08x\n", mace); - mace = mace_read_32 (MACEPCI_CONTROL); - printk ("MACE PCI control register: %08x\n", mace); - - printk ("Register dump:\n"); - show_regs (regs); - - printk ("Please mail this report to linux-mips@oss.sgi.com\n"); - printk ("Spinning..."); - while (1) ; -} - -void __init ip32_irq_init(void) -{ - unsigned int irq; - extern void init_generic_irq (void); - - /* Install our interrupt handler, then clear and disable all - * CRIME and MACE interrupts. - */ - crime_write_64 (CRIME_INT_MASK, 0); - crime_write_64 (CRIME_HARD_INT, 0); - crime_write_64 (CRIME_SOFT_INT, 0); - mace_write_32 (MACEISA_INT_STAT, 0); - mace_write_32 (MACEISA_INT_MASK, 0); - set_except_vector(0, ip32_handle_int); - - init_generic_irq (); - - for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { - hw_irq_controller *controller; - - if (irq == CLOCK_IRQ) - controller = &ip32_cpu_interrupt; - else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ) - controller = &ip32_mace_interrupt; - else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ) - controller = &ip32_macepci_interrupt; - else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ) - controller = &ip32_crime_interrupt; - else - controller = &ip32_maceisa_interrupt; - - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = 0; - irq_desc[irq].depth = 0; - irq_desc[irq].handler = controller; - } - setup_irq (CRIME_MEMERR_IRQ, &memerr_irq); - setup_irq (CRIME_CPUERR_IRQ, &cpuerr_irq); -} - -/* CRIME 1.1 appears to deliver all interrupts to this one pin. */ -void ip32_irq0 (struct pt_regs *regs) -{ - u64 crime_int = crime_read_64 (CRIME_INT_STAT); - int irq = 0; - - if (crime_int & CRIME_MACE_INT_MASK) { - crime_int &= CRIME_MACE_INT_MASK; - irq = ffs (crime_int); - } else if (crime_int & CRIME_MACEISA_INT_MASK) { - u32 mace_int; - mace_int = mace_read_32 (MACEISA_INT_STAT); - if (mace_int == 0) - irq = 0; - else - irq = ffs (mace_int) + 32; - } else if (crime_int & CRIME_MACEPCI_INT_MASK) { - crime_int &= CRIME_MACEPCI_INT_MASK; - crime_int >>= 8; - irq = ffs (crime_int) + 8; - } else if (crime_int & 0xffff0000) { - crime_int >>= 16; - irq = ffs (crime_int) + 16; - } - if (irq == 0) - ip32_unknown_interrupt (regs); - DBG ("*irq %u*\n", irq); - do_IRQ (irq, regs); -} - -void ip32_irq1 (struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq2 (struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq3 (struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq4 (struct pt_regs *regs) -{ - ip32_unknown_interrupt (regs); -} - -void ip32_irq5 (struct pt_regs *regs) -{ - do_IRQ (CLOCK_IRQ, regs); -} diff -Nru a/arch/mips64/sgi-ip32/ip32-pci-dma.c b/arch/mips64/sgi-ip32/ip32-pci-dma.c --- a/arch/mips64/sgi-ip32/ip32-pci-dma.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,41 +0,0 @@ -/* - * 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) 2000 Ani Joshi <ajoshi@unixbox.com> - * Copyright (C) 2000 Ralf Baechle <ralf@gnu.org> - * swiped from i386, and cloned for MIPS by Geert, polished by Ralf. - */ -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/pci.h> - -#include <asm/io.h> -#include <asm/addrspace.h> -#include <asm/ip32/mace.h> - -void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, - dma_addr_t * dma_handle) -{ - void *ret; - int gfp = GFP_ATOMIC; - - if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) - gfp |= GFP_DMA; - ret = (void *) __get_free_pages(gfp, get_order(size)); - - if (ret != NULL) { - memset(ret, 0, size); - dma_cache_wback_inv((unsigned long) ret, size); - *dma_handle = virt_to_bus(ret); - } - return ret; -} - -void pci_free_consistent(struct pci_dev *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long) vaddr, get_order(size)); -} diff -Nru a/arch/mips64/sgi-ip32/ip32-pci.c b/arch/mips64/sgi-ip32/ip32-pci.c --- a/arch/mips64/sgi-ip32/ip32-pci.c Fri Jun 27 14:20:06 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,425 +0,0 @@ -/* - * 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) 2000, 2001 Keith M Wesolowski - */ -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/types.h> -#include <asm/pci.h> -#include <asm/ip32/mace.h> -#include <asm/ip32/crime.h> -#include <asm/ip32/ip32_ints.h> -#include <linux/delay.h> - -#undef DEBUG_MACE_PCI - -/* - * O2 has up to 5 PCI devices connected into the MACE bridge. The device - * map looks like this: - * - * 0 aic7xxx 0 - * 1 aic7xxx 1 - * 2 expansion slot - * 3 N/C - * 4 N/C - */ - -#define chkslot(dev) \ -do { \ - if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1 \ - || PCI_SLOT ((dev)->devfn) > 3) \ - return PCIBIOS_DEVICE_NOT_FOUND; \ -} while (0) - -#define mkaddr(dev, where) \ -((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL)) - -void macepci_error (int irq, void *dev, struct pt_regs *regs); - -static int macepci_read_config_byte (struct pci_dev *dev, int where, - u8 *val) -{ - *val = 0xff; - chkslot (dev); - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL)); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_read_config_word (struct pci_dev *dev, int where, - u16 *val) -{ - *val = 0xffff; - chkslot (dev); - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL)); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_read_config_dword (struct pci_dev *dev, int where, - u32 *val) -{ - *val = 0xffffffff; - chkslot (dev); - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - *val = mace_read_32 (MACEPCI_CONFIG_DATA); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_byte (struct pci_dev *dev, int where, - u8 val) -{ - chkslot (dev); - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_word (struct pci_dev *dev, int where, - u16 val) -{ - chkslot (dev); - if (where & 1) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val); - - return PCIBIOS_SUCCESSFUL; -} - -static int macepci_write_config_dword (struct pci_dev *dev, int where, - u32 val) -{ - chkslot (dev); - if (where & 3) - return PCIBIOS_BAD_REGISTER_NUMBER; - mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where)); - mace_write_32 (MACEPCI_CONFIG_DATA, val); - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops macepci_ops = { - macepci_read_config_byte, - macepci_read_config_word, - macepci_read_config_dword, - macepci_write_config_byte, - macepci_write_config_word, - macepci_write_config_dword -}; - -struct pci_fixup pcibios_fixups[] = { { 0 } }; - -void __init pcibios_init (void) -{ - struct pci_dev *dev = NULL; - u32 start, size; - u16 cmd; - u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */ - u32 base_mem = 0x80100000; /* Likewise */ - u32 rev = mace_read_32 (MACEPCI_REV); - int i; - - printk ("MACE: PCI rev %d detected at %016lx\n", rev, - (u64) MACE_BASE + MACE_PCI); - - /* These are *bus* addresses */ - ioport_resource.start = 0; - ioport_resource.end = 0xffffffffUL; - iomem_resource.start = 0x80000000UL; - iomem_resource.end = 0xffffffffUL; - - /* Clear any outstanding errors and enable interrupts */ - mace_write_32 (MACEPCI_ERROR_ADDR, 0); - mace_write_32 (MACEPCI_ERROR_FLAGS, 0); - mace_write_32 (MACEPCI_CONTROL, 0xff008500); - crime_write_64 (CRIME_HARD_INT, 0UL); - crime_write_64 (CRIME_SOFT_INT, 0UL); - crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL); - - if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0, - "MACE PCI error", NULL)) - panic ("PCI bridge can't get interrupt; can't happen.\n"); - - pci_scan_bus (0, &macepci_ops, NULL); - -#ifdef DEBUG_MACE_PCI - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n", - dev->bus->number, PCI_SLOT (dev->devfn), - PCI_FUNC (dev->devfn)); - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start == 0) - continue; - printk ("%d: %016lx - %016lx (flags %04lx)\n", - i, dev->resource[i].start, - dev->resource[i].end, dev->resource[i].flags); - } - } -#endif - /* - * Assign sane resources to and enable all devices. The requirement - * for the SCSI controllers is well-known: a 256-byte I/O region - * which we must assign, and a 1-page memory region which is - * assigned by the system firmware. - */ - dev = NULL; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - switch (PCI_SLOT (dev->devfn)) { - case 1: /* SCSI bus 0 */ - dev->resource[0].start = 0x1000UL; - dev->resource[0].end = 0x10ffUL; - break; - case 2: /* SCSI bus 1 */ - dev->resource[0].start = 0x2000UL; - dev->resource[0].end = 0x20ffUL; - break; - default: /* Slots - I guess we have only 1 */ - for (i=0; i < 6; i++) { - size = dev->resource[i].end - - dev->resource[i].start; - if (!size - || !(dev->resource[i].flags - & (IORESOURCE_IO|IORESOURCE_MEM))) { - dev->resource[i].start - = dev->resource[i].end = 0UL; - continue; - } - if (dev->resource[i].flags & IORESOURCE_IO) { - dev->resource[i].start = base_io; - base_io += PAGE_ALIGN (size); - } else { - dev->resource[i].start = base_mem; - base_mem += 0x100000UL; - } - dev->resource[i].end = - dev->resource[i].start + size; - } - break; - } - for (i=0; i < 6; i++) { - if (dev->resource[i].start == 0) - continue; - start = dev->resource[i].start; - if (dev->resource[i].flags & IORESOURCE_IO) - start |= 1; - pci_write_config_dword (dev, - PCI_BASE_ADDRESS_0 + (i << 2), (u32) start); - } - pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20); - pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30); - pci_read_config_word (dev, PCI_COMMAND, &cmd); - cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_PARITY); - pci_write_config_word (dev, PCI_COMMAND, cmd); - pci_set_master (dev); - } - -#ifdef DEBUG_MACE_PCI - printk ("Triggering PCI bridge interrupt...\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST); - - dev = NULL; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - printk ("Device: %d/%d/%d final bus resource map\n", - dev->bus->number, PCI_SLOT (dev->devfn), - PCI_FUNC (dev->devfn)); - for (i=0; i < DEVICE_COUNT_RESOURCE; i++) { - if (dev->resource[i].start == 0) - continue; - printk ("%d: %016lx - %016lx (flags %04lx)\n", - i, dev->resource[i].start, - dev->resource[i].end, dev->resource[i].flags); - } - } -#endif -} - -/* - * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of - * the device (1-4 => A-D), tell what irq to use. Note that we don't - * in theory have slots 4 and 5, and we never normally use the shared - * irqs. I suppose a device without a pin A will thank us for doing it - * right if there exists such a broken piece of crap. - */ -static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin) -{ - chkslot (dev); - if (pin == 0) - pin = 1; - switch (slot) { - case 1: - return MACEPCI_SCSI0_IRQ; - case 2: - return MACEPCI_SCSI1_IRQ; - case 3: - switch (pin) { - case 2: - return MACEPCI_SHARED0_IRQ; - case 3: - return MACEPCI_SHARED1_IRQ; - case 4: - return MACEPCI_SHARED2_IRQ; - case 1: - default: - return MACEPCI_SLOT0_IRQ; - } - case 4: - switch (pin) { - case 2: - return MACEPCI_SHARED2_IRQ; - case 3: - return MACEPCI_SHARED0_IRQ; - case 4: - return MACEPCI_SHARED1_IRQ; - case 1: - default: - return MACEPCI_SLOT1_IRQ; - } - return MACEPCI_SLOT1_IRQ; - case 5: - switch (pin) { - case 2: - return MACEPCI_SHARED1_IRQ; - case 3: - return MACEPCI_SHARED2_IRQ; - case 4: - return MACEPCI_SHARED0_IRQ; - case 1: - default: - return MACEPCI_SLOT2_IRQ; - } - default: - return 0; - } -} - -/* - * It's not entirely clear what this does in a system with no bridges. - * In any case, bridges are not supported by Linux in O2. - */ -static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp) -{ - if (PCI_SLOT (dev->devfn) == 2) - *pinp = 2; - else - *pinp = 1; - return PCI_SLOT (dev->devfn); -} - -/* All devices are enabled during initialization. */ -int pcibios_enable_device (struct pci_dev *dev) -{ - return PCIBIOS_SUCCESSFUL; -} - -char * __init pcibios_setup (char *str) -{ - return str; -} - -void __init pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) -{ -} - -void __init pcibios_update_irq (struct pci_dev *dev, int irq) -{ - pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq); -} - -void __init pcibios_fixup_bus (struct pci_bus *b) -{ - pci_fixup_irqs (macepci_swizzle, macepci_map_irq); -} - -/* - * Handle errors from the bridge. This includes master and target aborts, - * various command and address errors, and the interrupt test. This gets - * registered on the bridge error irq. It's conceivable that some of these - * conditions warrant a panic. Anybody care to say which ones? - */ -void macepci_error (int irq, void *dev, struct pt_regs *regs) { - u32 flags, error_addr; - char space; - - flags = mace_read_32 (MACEPCI_ERROR_FLAGS); - error_addr = mace_read_32 (MACEPCI_ERROR_ADDR); - - if (flags & MACEPCI_ERROR_MEMORY_ADDR) - space = 'M'; - else if (flags & MACEPCI_ERROR_CONFIG_ADDR) - space = 'C'; - else space = 'X'; - - if (flags & MACEPCI_ERROR_MASTER_ABORT) { - printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_MASTER_ABORT); - } - if (flags & MACEPCI_ERROR_TARGET_ABORT) { - printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_TARGET_ABORT); - } - if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) { - printk ("MACEPCI: Data parity error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_DATA_PARITY_ERR); - } - if (flags & MACEPCI_ERROR_RETRY_ERR) { - printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_RETRY_ERR); - } - if (flags & MACEPCI_ERROR_ILLEGAL_CMD) { - printk ("MACEPCI: Illegal command at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, - flags & ~MACEPCI_ERROR_ILLEGAL_CMD); - } - if (flags & MACEPCI_ERROR_SYSTEM_ERR) { - printk ("MACEPCI: System error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_SYSTEM_ERR); - } - if (flags & MACEPCI_ERROR_PARITY_ERR) { - printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr, - space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_PARITY_ERR); - } - if (flags & MACEPCI_ERROR_OVERRUN) { - printk ("MACEPCI: Overrun error at 0x%08x (%c)\n", - error_addr, space); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_OVERRUN); - } - if (flags & MACEPCI_ERROR_SIG_TABORT) { - printk ("MACEPCI: Signaled target abort (clearing)\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_SIG_TABORT); - } - if (flags & MACEPCI_ERROR_INTERRUPT_TEST) { - printk ("MACEPCI: Interrupt test triggered (clearing)\n"); - mace_write_32 (MACEPCI_ERROR_FLAGS, flags - & ~MACEPCI_ERROR_INTERRUPT_TEST); - } -} diff -Nru a/arch/mips64/sgi-ip32/ip32-rtc.c b/arch/mips64/sgi-ip32/ip32-rtc.c --- a/arch/mips64/sgi-ip32/ip32-rtc.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,32 +0,0 @@ -/* - * RTC routines for IP32 style attached Dallas chip. - * - * 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) 2000 Harald Koerfgen - */ -#include <linux/mc146818rtc.h> -#include <asm/ip32/mace.h> - -static unsigned char ip32_rtc_read_data(unsigned long addr) -{ - return (unsigned char) mace_read_8 (MACEISA_RTC_BASE + (addr << 8)); -} - -static void ip32_rtc_write_data(unsigned char data, unsigned long addr) -{ - mace_write_8 (MACEISA_RTC_BASE + (addr << 8), data); -} - -static int ip32_rtc_bcd_mode(void) -{ - return 0; -} - -struct rtc_ops ip32_rtc_ops = { - &ip32_rtc_read_data, - &ip32_rtc_write_data, - &ip32_rtc_bcd_mode -}; diff -Nru a/arch/mips64/sgi-ip32/ip32-setup.c b/arch/mips64/sgi-ip32/ip32-setup.c --- a/arch/mips64/sgi-ip32/ip32-setup.c Fri Jun 27 14:20:02 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,62 +0,0 @@ -/* - * IP32 basic setup - * - * 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) 2000 Harald Koerfgen - */ -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/mc146818rtc.h> -#include <linux/param.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <asm/mipsregs.h> -#include <asm/bootinfo.h> -#include <asm/irq.h> -#include <asm/mmu_context.h> -#include <asm/ip32/crime.h> -#include <asm/ip32/mace.h> -#include <asm/ip32/ip32_ints.h> -#include <asm/sgialib.h> - -extern struct rtc_ops ip32_rtc_ops; -extern u32 cc_interval; - -void __init ip32_init (int argc, char **argv, char **envp) { - arc_meminit (); -} - -void __init ip32_setup(void) -{ -#ifdef CONFIG_SERIAL_CONSOLE - char *ctype; -#endif - TLBMISS_HANDLER_SETUP (); - -#ifdef CONFIG_SERIAL_CONSOLE - ctype = ArcGetEnvironmentVariable("console"); - if (*ctype == 'd') { - if (ctype[1] == '2') - console_setup ("ttyS1"); - else - console_setup ("ttyS0"); - } -#endif - -#ifdef CONFIG_VT - conswitchp = &dummy_con; -#endif - - rtc_ops = &ip32_rtc_ops; - - crime_init (); -} - -int __init page_is_ram (unsigned long pagenr) -{ - /* XXX: to do? */ - return 1; -} diff -Nru a/arch/mips64/sgi-ip32/ip32-timer.c b/arch/mips64/sgi-ip32/ip32-timer.c --- a/arch/mips64/sgi-ip32/ip32-timer.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,47 +0,0 @@ -/* - * IP32 timer calibration - * - * 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) 2001 Keith M Wesolowski - */ -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <asm/mipsregs.h> -#include <asm/param.h> -#include <asm/ip32/crime.h> -#include <asm/ip32/ip32_ints.h> - -extern u32 cc_interval; - -/* An arbitrary time; this can be decreased if reliability looks good */ -#define WAIT_MS 10 -#define PER_MHZ (1000000 / 2 / HZ) - -void __init ip32_timer_setup (struct irqaction *irq) { - u64 crime_time; - u32 cc_tick; - - printk("Calibrating system timer... "); - - crime_time = crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK; - cc_tick = read_32bit_cp0_register (CP0_COUNT); - - while ((crime_read_64 (CRIME_TIME) & CRIME_TIME_MASK) - crime_time - < WAIT_MS * 1000000 / CRIME_NS_PER_TICK) - ; - cc_tick = read_32bit_cp0_register (CP0_COUNT) - cc_tick; - cc_interval = cc_tick / HZ * (1000 / WAIT_MS); - /* The round-off seems unnecessary; in testing, the error of the - * above procedure is < 100 ticks, which means it gets filtered - * out by the HZ adjustment. - */ - cc_interval = (cc_interval / PER_MHZ) * PER_MHZ; - - printk("%d MHz CPU detected\n", (int) (cc_interval / PER_MHZ)); - - setup_irq (CLOCK_IRQ, irq); -} diff -Nru a/arch/mips64/tools/Makefile b/arch/mips64/tools/Makefile --- a/arch/mips64/tools/Makefile Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,23 +0,0 @@ -# -# Makefile for MIPS kernel build tools. -# -# Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) -# Copyright (C) 1997, 1999 Ralf Baechle (ralf@gnu.org) -# Copyright (C) 1999 Silicon Graphics, Inc. -# -TARGET := $(TOPDIR)/include/asm-$(ARCH)/offset.h - -$(TARGET): offset.h - cmp -s $^ $@ || (cp $^ $(TARGET).new && mv $(TARGET).new $(TARGET)) - -offset.h: offset.s - sed -n '/^@@@/s///p' $^ >$@ - -offset.s: offset.c $(TOPDIR)/include/linux/autoconf.h - -clean: - rm -f offset.[hs] $(TARGET).new - -mrproper: - rm -f offset.[hs] $(TARGET).new - rm -f $(TARGET) diff -Nru a/arch/mips64/tools/offset.c b/arch/mips64/tools/offset.c --- a/arch/mips64/tools/offset.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,150 +0,0 @@ -/* - * offset.c: Calculate pt_regs and task_struct offsets. - * - * Copyright (C) 1996 David S. Miller - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - */ -#include <linux/types.h> -#include <linux/sched.h> - -#include <asm/ptrace.h> -#include <asm/processor.h> - -#define text(t) __asm__("\n@@@" t) -#define _offset(type, member) (&(((type *)NULL)->member)) - -#define offset(string, ptr, member) \ - __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) -#define size(string, size) \ - __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) -#define linefeed text("") - -text("/* DO NOT TOUCH, AUTOGENERATED BY OFFSET.C */"); -linefeed; -text("#ifndef _MIPS_OFFSET_H"); -text("#define _MIPS_OFFSET_H"); -linefeed; - -void output_ptreg_defines(void) -{ - text("/* MIPS pt_regs offsets. */"); - offset("#define PT_R0 ", struct pt_regs, regs[0]); - offset("#define PT_R1 ", struct pt_regs, regs[1]); - offset("#define PT_R2 ", struct pt_regs, regs[2]); - offset("#define PT_R3 ", struct pt_regs, regs[3]); - offset("#define PT_R4 ", struct pt_regs, regs[4]); - offset("#define PT_R5 ", struct pt_regs, regs[5]); - offset("#define PT_R6 ", struct pt_regs, regs[6]); - offset("#define PT_R7 ", struct pt_regs, regs[7]); - offset("#define PT_R8 ", struct pt_regs, regs[8]); - offset("#define PT_R9 ", struct pt_regs, regs[9]); - offset("#define PT_R10 ", struct pt_regs, regs[10]); - offset("#define PT_R11 ", struct pt_regs, regs[11]); - offset("#define PT_R12 ", struct pt_regs, regs[12]); - offset("#define PT_R13 ", struct pt_regs, regs[13]); - offset("#define PT_R14 ", struct pt_regs, regs[14]); - offset("#define PT_R15 ", struct pt_regs, regs[15]); - offset("#define PT_R16 ", struct pt_regs, regs[16]); - offset("#define PT_R17 ", struct pt_regs, regs[17]); - offset("#define PT_R18 ", struct pt_regs, regs[18]); - offset("#define PT_R19 ", struct pt_regs, regs[19]); - offset("#define PT_R20 ", struct pt_regs, regs[20]); - offset("#define PT_R21 ", struct pt_regs, regs[21]); - offset("#define PT_R22 ", struct pt_regs, regs[22]); - offset("#define PT_R23 ", struct pt_regs, regs[23]); - offset("#define PT_R24 ", struct pt_regs, regs[24]); - offset("#define PT_R25 ", struct pt_regs, regs[25]); - offset("#define PT_R26 ", struct pt_regs, regs[26]); - offset("#define PT_R27 ", struct pt_regs, regs[27]); - offset("#define PT_R28 ", struct pt_regs, regs[28]); - offset("#define PT_R29 ", struct pt_regs, regs[29]); - offset("#define PT_R30 ", struct pt_regs, regs[30]); - offset("#define PT_R31 ", struct pt_regs, regs[31]); - offset("#define PT_LO ", struct pt_regs, lo); - offset("#define PT_HI ", struct pt_regs, hi); - offset("#define PT_EPC ", struct pt_regs, cp0_epc); - offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); - offset("#define PT_STATUS ", struct pt_regs, cp0_status); - offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); - size("#define PT_SIZE ", struct pt_regs); - linefeed; -} - -void output_task_defines(void) -{ - text("/* MIPS task_struct offsets. */"); - offset("#define TASK_STATE ", struct task_struct, state); - offset("#define TASK_FLAGS ", struct task_struct, flags); -#error offset("#define TASK_SIGPENDING ", struct task_struct, sigpending); -#error offset("#define TASK_NEED_RESCHED ", struct task_struct, need_resched); -#error offset("#define TASK_PTRACE ", struct task_struct, ptrace); - offset("#define TASK_COUNTER ", struct task_struct, counter); - offset("#define TASK_NICE ", struct task_struct, nice); - offset("#define TASK_MM ", struct task_struct, mm); - offset("#define TASK_PROCESSOR ", struct task_struct, processor); - size("#define TASK_STRUCT_SIZE ", struct task_struct); - linefeed; -} - -void output_thread_defines(void) -{ - text("/* MIPS specific thread_struct offsets. */"); - offset("#define THREAD_REG16 ", struct task_struct, thread.reg16); - offset("#define THREAD_REG17 ", struct task_struct, thread.reg17); - offset("#define THREAD_REG18 ", struct task_struct, thread.reg18); - offset("#define THREAD_REG19 ", struct task_struct, thread.reg19); - offset("#define THREAD_REG20 ", struct task_struct, thread.reg20); - offset("#define THREAD_REG21 ", struct task_struct, thread.reg21); - offset("#define THREAD_REG22 ", struct task_struct, thread.reg22); - offset("#define THREAD_REG23 ", struct task_struct, thread.reg23); - offset("#define THREAD_REG29 ", struct task_struct, thread.reg29); - offset("#define THREAD_REG30 ", struct task_struct, thread.reg30); - offset("#define THREAD_REG31 ", struct task_struct, thread.reg31); - offset("#define THREAD_STATUS ", struct task_struct, \ - thread.cp0_status); - offset("#define THREAD_FPU ", struct task_struct, thread.fpu); - offset("#define THREAD_BVADDR ", struct task_struct, \ - thread.cp0_badvaddr); - offset("#define THREAD_BUADDR ", struct task_struct, \ - thread.cp0_baduaddr); - offset("#define THREAD_ECODE ", struct task_struct, \ - thread.error_code); - offset("#define THREAD_TRAPNO ", struct task_struct, thread.trap_no); - offset("#define THREAD_MFLAGS ", struct task_struct, thread.mflags); - offset("#define THREAD_CURDS ", struct task_struct, \ - thread.current_ds); - offset("#define THREAD_TRAMP ", struct task_struct, \ - thread.irix_trampoline); - offset("#define THREAD_OLDCTX ", struct task_struct, \ - thread.irix_oldctx); - linefeed; -} - -void output_mm_defines(void) -{ - text("/* Linux mm_struct offsets. */"); - offset("#define MM_USERS ", struct mm_struct, mm_users); - offset("#define MM_PGD ", struct mm_struct, pgd); - offset("#define MM_CONTEXT ", struct mm_struct, context); - linefeed; -} - -void output_sc_defines(void) -{ - text("/* Linux sigcontext offsets. */"); - offset("#define SC_REGS ", struct sigcontext, sc_regs); - offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); - offset("#define SC_MDHI ", struct sigcontext, sc_mdhi); - offset("#define SC_MDLO ", struct sigcontext, sc_mdlo); - offset("#define SC_PC ", struct sigcontext, sc_pc); - offset("#define SC_STATUS ", struct sigcontext, sc_status); - offset("#define SC_OWNEDFP ", struct sigcontext, sc_ownedfp); - offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); - offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); - offset("#define SC_CAUSE ", struct sigcontext, sc_cause); - offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); - linefeed; -} - -text("#endif /* !(_MIPS_OFFSET_H) */"); diff -Nru a/arch/mips64/vmlinux.lds.S b/arch/mips64/vmlinux.lds.S --- a/arch/mips64/vmlinux.lds.S Fri Jun 27 14:19:56 2003 +++ b/arch/mips64/vmlinux.lds.S Fri Jun 27 14:19:56 2003 @@ -1,18 +1,38 @@ #include <asm-generic/vmlinux.lds.h> +#undef mips /* CPP really sucks for this job */ +#define mips mips OUTPUT_ARCH(mips) ENTRY(kernel_entry) +jiffies = jiffies_64; SECTIONS { +#ifdef CONFIG_BOOT_ELF64 /* Read-only sections, merged into text segment: */ - .init : { *(.init) } =0 - .text : - { + /* . = 0xc000000000000000; */ + + /* This is the value for an Origin kernel, taken from an IRIX kernel. */ + /* . = 0xc00000000001c000; */ + + /* Set the vaddr for the text segment to a value + >= 0xa800 0000 0001 9000 if no symmon is going to configured + >= 0xa800 0000 0030 0000 otherwise */ + + /* . = 0xa800000000300000; */ + /* . = 0xa800000000300000; */ + . = 0xffffffff80300000; +#endif + . = LOADADDR; + /* read-only */ + _text = .; /* Text and read-only data */ + .text : { *(.text) - /* .gnu.warning sections are handled specially by elf32.em. */ + *(.fixup) *(.gnu.warning) } =0 + _etext = .; /* End of text section */ + . = ALIGN(16); /* Exception table */ __start___ex_table = .; __ex_table : { *(__ex_table) } @@ -23,30 +43,74 @@ __stop___dbe_table = .; RODATA - - _etext = .; - . = ALIGN(16384); - . = . + MAPPED_OFFSET; /* for CONFIG_MAPPED_KERNEL */ - .data.init_task : { *(.data.init_task) } + . = ALIGN(64); + + /* writeable */ + .data : { /* Data */ + *(.data) + + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + + CONSTRUCTORS + } + _gp = . + 0x8000; + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + + . = ALIGN(4096); + __nosave_begin = .; + .data_nosave : { *(.data.nosave) } + . = ALIGN(4096); + __nosave_end = .; - /* Startup code */ . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + _edata = .; /* End of data section */ + + . = ALIGN(16384); /* init_task */ + . = . + MAPPED_OFFSET; /* for CONFIG_MAPPED_KERNEL */ + .data.init_task : { *(.data.init_task) } + + /* will be freed after init */ + . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } + /* /DISCARD/ doesn't work for .reginfo */ + .reginfo : { *(.reginfo) } + .init.text : { + _sinittext = .; + *(.init.text) + _einittext = .; + } + .init.data : { *(.init.data) } . = ALIGN(16); __setup_start = .; - .setup.init : { *(.setup.init) } + .init.setup : { *(.init.setup) } __setup_end = .; + __start___param = .; + __param : { *(__param) } + __stop___param = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) *(.initcall7.init) } __initcall_end = .; @@ -54,68 +118,40 @@ .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT - . = ALIGN(4096); /* Align double page for init_task_union */ - __init_end = .; - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - + __initramfs_start = .; + .init.ramfs : { *(.init.ramfs) } + __initramfs_end = .; . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } + __per_cpu_start = .; + .data.percpu : { *(.data.percpu) } + __per_cpu_end = .; + . = ALIGN(4096); + __init_end = .; + /* freed after init ends here */ - .fini : { *(.fini) } =0 - .reginfo : { *(.reginfo) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. It would - be more correct to do this: - . = .; - The current expression does not correctly handle the case of a - text segment ending precisely at the end of a page; it causes the - data segment to skip a page. The above expression does not have - this problem, but it will currently (2/95) cause BFD to allocate - a single segment, combining both text and data, for this case. - This will prevent the text segment from being shared among - multiple executions of the program; I think that is more - important than losing a page of the virtual address space (note - that no actual memory is lost; the page which is skipped can not - be referenced). */ - . = .; - .data : - { - _fdata = . ; - *(.data) - CONSTRUCTORS + __bss_start = .; /* BSS */ + .sbss : { + *(.sbss) + *(.scommon) } - .data1 : { *(.data1) } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - .got : { *(.got.plt) *(.got) } - .dynamic : { *(.dynamic) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } - _edata = .; + .bss : { + *(.bss) + *(COMMON) + } + __bss_stop = .; - .sbss : { *(.sbss) *(.scommon) } - .bss : - { - *(.dynbss) - *(.bss) - *(COMMON) _end = . ; - } /* Sections to be discarded */ - /DISCARD/ : - { - *(.text.exit) - *(.data.exit) + /DISCARD/ : { + *(.exit.text) + *(.exit.data) *(.exitcall.exit) } + /* This is the MIPS specific mdebug section. */ + .mdebug : { *(.mdebug) } /* These are needed for ELF backends which have not yet been converted to the new style linker. */ .stab 0 : { *(.stab) } @@ -133,4 +169,6 @@ /* These must appear regardless of . */ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + .comment : { *(.comment) } + .note : { *(.note) } } diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig --- a/arch/parisc/Kconfig Fri Jun 27 14:19:58 2003 +++ b/arch/parisc/Kconfig Fri Jun 27 14:19:58 2003 @@ -182,33 +182,7 @@ source "drivers/ide/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - -source drivers/scsi/Kconfig - - -endmenu +source "drivers/scsi/Kconfig" source "drivers/md/Kconfig" diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig --- a/arch/ppc/Kconfig Fri Jun 27 14:20:05 2003 +++ b/arch/ppc/Kconfig Fri Jun 27 14:20:05 2003 @@ -1175,33 +1175,8 @@ source "drivers/ide/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" -endmenu - source "drivers/message/fusion/Kconfig" source "drivers/ieee1394/Kconfig" @@ -1218,14 +1193,7 @@ source "drivers/video/Kconfig" -menu "Old CD-ROM drivers (not SCSI, not IDE)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - source "drivers/cdrom/Kconfig" - -endmenu source "drivers/input/Kconfig" diff -Nru a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S --- a/arch/ppc/kernel/entry.S Fri Jun 27 14:20:02 2003 +++ b/arch/ppc/kernel/entry.S Fri Jun 27 14:20:02 2003 @@ -173,8 +173,10 @@ cmpli 0,r0,NR_syscalls bge- 66f rlwinm r10,r1,0,0,18 /* current_thread_info() */ - lwz r10,TI_FLAGS(r10) - andi. r10,r10,_TIF_SYSCALL_TRACE + lwz r11,TI_FLAGS(r10) + rlwinm r11,r11,0,~_TIF_FORCE_NOERROR + stw r11,TI_FLAGS(r10) + andi. r11,r11,_TIF_SYSCALL_TRACE bne- syscall_dotrace syscall_dotrace_cont: lis r10,sys_call_table@h @@ -192,11 +194,12 @@ mr r6,r3 li r11,-_LAST_ERRNO cmpl 0,r3,r11 + rlwinm r12,r1,0,0,18 /* current_thread_info() */ blt+ 30f + lwz r11,TI_FLAGS(r12) + andi. r11,r11,_TIF_FORCE_NOERROR + bne 30f neg r3,r3 - cmpi 0,r3,ERESTARTNOHAND - bne 22f - li r3,EINTR 22: lwz r10,_CCR(r1) /* Set SO bit in CR */ oris r10,r10,0x1000 stw r10,_CCR(r1) @@ -205,7 +208,6 @@ 30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ SYNC MTMSRD(r10) - rlwinm r12,r1,0,0,18 /* current_thread_info() */ lwz r9,TI_FLAGS(r12) andi. r0,r9,(_TIF_SYSCALL_TRACE|_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne- syscall_exit_work diff -Nru a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c --- a/arch/ppc/kernel/process.c Fri Jun 27 14:19:56 2003 +++ b/arch/ppc/kernel/process.c Fri Jun 27 14:19:56 2003 @@ -69,8 +69,6 @@ /* only used to get secondary processor up */ struct task_struct *current_set[NR_CPUS] = {&init_task, }; -static void show_tsk_stack(struct task_struct *tsk, unsigned long sp); - #undef SHOW_TASK_SWITCHES #undef CHECK_STACK @@ -296,7 +294,7 @@ break; } printk("\n"); - show_tsk_stack(current, regs->gpr[1]); + show_stack(current, (unsigned long *) regs->gpr[1]); } void exit_thread(void) @@ -494,26 +492,29 @@ return error; } -void show_trace_task(struct task_struct *tsk) -{ - show_tsk_stack(tsk, tsk->thread.ksp); -} - void dump_stack(void) { - show_tsk_stack(current, _get_SP()); + show_stack(current, NULL); } -static void show_tsk_stack(struct task_struct *tsk, unsigned long sp) +void show_stack(struct task_struct *tsk, unsigned long *stack) { - unsigned long stack_top, prev_sp, ret; + unsigned long sp, stack_top, prev_sp, ret; int count = 0; unsigned long next_exc = 0; struct pt_regs *regs; extern char ret_from_except, ret_from_except_full, ret_from_syscall; + sp = (unsigned long) stack; if (tsk == NULL) - return; + tsk = current; + if (sp == 0) { + if (tsk == current) + asm("mr %0,1" : "=r" (sp)); + else + sp = tsk->thread.ksp; + } + prev_sp = (unsigned long) (tsk->thread_info + 1); stack_top = (unsigned long) tsk->thread_info + THREAD_SIZE; while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) { diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig --- a/arch/ppc64/Kconfig Fri Jun 27 14:19:57 2003 +++ b/arch/ppc64/Kconfig Fri Jun 27 14:19:57 2003 @@ -253,32 +253,7 @@ source "drivers/ide/Kconfig" - -menu "SCSI device support" - -config SCSI - tristate "SCSI device support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "drivers/md/Kconfig" diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig --- a/arch/s390/Kconfig Fri Jun 27 14:19:55 2003 +++ b/arch/s390/Kconfig Fri Jun 27 14:19:55 2003 @@ -231,14 +231,7 @@ source "drivers/base/Kconfig" -menu "SCSI support" - -config SCSI - tristate "SCSI support" - source "drivers/scsi/Kconfig" - -endmenu source "drivers/s390/Kconfig" diff -Nru a/arch/s390/defconfig b/arch/s390/defconfig --- a/arch/s390/defconfig Fri Jun 27 14:20:01 2003 +++ b/arch/s390/defconfig Fri Jun 27 14:20:01 2003 @@ -68,6 +68,11 @@ # CONFIG_PCMCIA is not set # +# Generic Driver Options +# +# CONFIG_FW_LOADER is not set + +# # SCSI support # # CONFIG_SCSI is not set @@ -166,6 +171,7 @@ # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_TUNNEL is not set # CONFIG_XFRM_USER is not set # diff -Nru a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c --- a/arch/s390/kernel/compat_ioctl.c Fri Jun 27 14:19:59 2003 +++ b/arch/s390/kernel/compat_ioctl.c Fri Jun 27 14:19:59 2003 @@ -42,12 +42,15 @@ #include <linux/random.h> #include <linux/raw.h> #include <linux/route.h> +#include <linux/rtc.h> #include <linux/vt.h> #include <linux/watchdog.h> #include <linux/auto_fs.h> +#include <linux/auto_fs4.h> #include <linux/devfs_fs.h> #include <linux/ext2_fs.h> +#include <linux/ncp_fs.h> #include <linux/smb_fs.h> #include <linux/if_bonding.h> diff -Nru a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c --- a/arch/s390/kernel/compat_linux.c Fri Jun 27 14:20:00 2003 +++ b/arch/s390/kernel/compat_linux.c Fri Jun 27 14:20:00 2003 @@ -2193,7 +2193,6 @@ sorts of things, like timeval and itimerval. */ extern struct timezone sys_tz; -extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); asmlinkage int sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) { @@ -2210,13 +2209,27 @@ return 0; } +static inline long get_ts32(struct timespec *o, struct compat_timeval *i) +{ + long usec; + + if (!access_ok(VERIFY_READ, i, sizeof(*i))) + return -EFAULT; + if (__get_user(o->tv_sec, &i->tv_sec)) + return -EFAULT; + if (__get_user(usec, &i->tv_usec)) + return -EFAULT; + o->tv_nsec = usec * 1000; + return 0; +} + asmlinkage int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) { - struct timeval ktv; + struct timespec kts; struct timezone ktz; if (tv) { - if (get_tv32(&ktv, tv)) + if (get_ts32(&kts, tv)) return -EFAULT; } if (tz) { @@ -2224,7 +2237,7 @@ return -EFAULT; } - return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL); + return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } asmlinkage int sys_utimes(char *, struct timeval *); diff -Nru a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c --- a/arch/s390/kernel/smp.c Fri Jun 27 14:19:52 2003 +++ b/arch/s390/kernel/smp.c Fri Jun 27 14:19:52 2003 @@ -419,8 +419,6 @@ boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; current_thread_info()->cpu = 0; num_cpus = 1; - cpu_possible_map = 1; - cpu_online_map = 1; for (curr_cpu = 0; curr_cpu <= 65535 && num_cpus < max_cpus; curr_cpu++) { if ((__u16) curr_cpu == boot_cpu_addr) diff -Nru a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S --- a/arch/s390/kernel/syscalls.S Fri Jun 27 14:19:53 2003 +++ b/arch/s390/kernel/syscalls.S Fri Jun 27 14:19:53 2003 @@ -118,7 +118,7 @@ SYSCALL(sys_newlstat,sys_newlstat,compat_sys_newlstat_wrapper) SYSCALL(sys_newfstat,sys_newfstat,compat_sys_newfstat_wrapper) NI_SYSCALL /* old uname syscall */ -NI_SYSCALL /* 110 iopl for i386 */ +NI_SYSCALL /* reserved for sys_lookup_dcache */ SYSCALL(sys_vhangup,sys_vhangup,sys_vhangup) NI_SYSCALL /* old "idle" system call */ NI_SYSCALL /* vm86old for i386 */ diff -Nru a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c --- a/arch/s390/kernel/traps.c Fri Jun 27 14:19:55 2003 +++ b/arch/s390/kernel/traps.c Fri Jun 27 14:19:55 2003 @@ -78,7 +78,7 @@ #endif /* CONFIG_ARCH_S390X */ -void show_trace(unsigned long * stack) +void show_trace(struct task_struct *task, unsigned long * stack) { unsigned long backchain, low_addr, high_addr, ret_addr; @@ -109,10 +109,10 @@ */ if (tsk->state == TASK_RUNNING) return; - show_trace((unsigned long *) tsk->thread.ksp); + show_trace(tsk, (unsigned long *) tsk->thread.ksp); } -void show_stack(unsigned long *sp) +void show_stack(struct task_struct *task, unsigned long *sp) { unsigned long *stack; int i; @@ -132,7 +132,7 @@ printk("%p ", (void *)*stack++); } printk("\n"); - show_trace(sp); + show_trace(task, sp); } /* @@ -140,7 +140,7 @@ */ void dump_stack(void) { - show_stack(0); + show_stack(current, 0); } void show_registers(struct pt_regs *regs) diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig --- a/arch/sh/Kconfig Fri Jun 27 14:20:05 2003 +++ b/arch/sh/Kconfig Fri Jun 27 14:20:05 2003 @@ -777,68 +777,9 @@ source "drivers/ide/Kconfig" - -menu "SCSI device support" - -config SCSI - tristate "SCSI device support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" -endmenu - - -menu "Old CD-ROM drivers (not SCSI, not IDE)" - -config CD_NO_IDESCSI - bool "Support non-SCSI/IDE/ATAPI CDROM drives" - ---help--- - If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y - here, otherwise N. Read the CD-ROM-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - Note that the answer to this question doesn't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about these CD-ROM drives. If you are unsure what you - have, say Y and find out whether you have one of the following - drives. - - For each of these drivers, a file Documentation/cdrom/{driver_name} - exists. Especially in cases where you do not know exactly which kind - of drive you have you should read there. Most of these drivers use a - file drivers/cdrom/{driver_name}.h where you can define your - interface parameters and switch some internal goodies. - - All these CD-ROM drivers are also usable as a module ( = code which - can be inserted in and removed from the running kernel whenever you - want). If you want to compile them as module, say M instead of Y and - read <file:Documentation/modules.txt>. - - If you want to use any of these CD-ROM drivers, you also have to - answer Y or M to "ISO 9660 CD-ROM file system support" below (this - answer will get "defaulted" for you if you enable any of the Linux - CD-ROM drivers). - source "drivers/cdrom/Kconfig" - -endmenu source "drivers/md/Kconfig" diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig --- a/arch/sparc/Kconfig Fri Jun 27 14:19:30 2003 +++ b/arch/sparc/Kconfig Fri Jun 27 14:19:30 2003 @@ -481,32 +481,7 @@ source "drivers/isdn/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "drivers/fc4/Kconfig" diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile --- a/arch/sparc/Makefile Fri Jun 27 14:19:53 2003 +++ b/arch/sparc/Makefile Fri Jun 27 14:19:53 2003 @@ -52,7 +52,9 @@ CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y)) DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y)) NET_Y := $(patsubst %/, %/built-in.o, $(net-y)) -LIBS_Y := $(patsubst %/, %/lib.a, $(libs-y)) +LIBS_Y1 := $(patsubst %/, %/lib.a, $(libs-y)) +LIBS_Y2 := $(patsubst %/, %/built-in.o, $(libs-y)) +LIBS_Y := $(LIBS_Y1) $(LIBS_Y2) export INIT_Y CORE_Y DRIVERS_Y NET_Y LIBS_Y HEAD_Y # Default target diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c --- a/arch/sparc/kernel/process.c Fri Jun 27 14:19:53 2003 +++ b/arch/sparc/kernel/process.c Fri Jun 27 14:19:53 2003 @@ -287,17 +287,14 @@ rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]); } -void show_trace_task(struct task_struct *tsk) +void show_stack(struct task_struct *tsk, unsigned long *_ksp) { unsigned long pc, fp; unsigned long task_base = (unsigned long) tsk; struct reg_window *rw; int count = 0; - if (!tsk) - return; - - fp = tsk->thread_info->ksp; + fp = (unsigned long) _ksp; do { /* Bogus frame pointer? */ if (fp < (task_base + sizeof(struct task_struct)) || @@ -309,6 +306,13 @@ fp = rw->ins[6]; } while (++count < 16); printk("\n"); +} + +void show_trace_task(struct task_struct *tsk) +{ + if (tsk) + show_stack(tsk, + (unsigned long *) tsk->thread_info->ksp); } /* diff -Nru a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S --- a/arch/sparc/kernel/systbls.S Fri Jun 27 14:19:56 2003 +++ b/arch/sparc/kernel/systbls.S Fri Jun 27 14:19:56 2003 @@ -64,9 +64,9 @@ /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 -/*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_nis_syscall +/*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64 /* "We are the Knights of the Forest of Ni!!" */ -/*235*/ .long sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall +/*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig --- a/arch/sparc64/Kconfig Fri Jun 27 14:20:01 2003 +++ b/arch/sparc64/Kconfig Fri Jun 27 14:20:01 2003 @@ -675,32 +675,7 @@ source "drivers/ide/Kconfig" - -menu "SCSI support" - -config SCSI - tristate "SCSI support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "drivers/fc4/Kconfig" diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig --- a/arch/sparc64/defconfig Fri Jun 27 14:19:55 2003 +++ b/arch/sparc64/defconfig Fri Jun 27 14:19:55 2003 @@ -27,7 +27,7 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y CONFIG_KMOD=y # @@ -162,7 +162,9 @@ # CONFIG_SERIAL_SUNCORE=y CONFIG_SERIAL_SUNZILOG=y +CONFIG_SERIAL_SUNZILOG_CONSOLE=y CONFIG_SERIAL_SUNSU=y +CONFIG_SERIAL_SUNSU_CONSOLE=y CONFIG_SERIAL_SUNSAB=m CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y @@ -197,8 +199,8 @@ CONFIG_MD_LINEAR=m CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID5=m +CONFIG_MD_MULTIPATH=m CONFIG_BLK_DEV_DM=m # CONFIG_BLK_DEV_RAM is not set @@ -243,26 +245,27 @@ # CONFIG_BLK_DEV_AEC62XX is not set CONFIG_BLK_DEV_ALI15X3=y # CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_AMD74XX=m +CONFIG_BLK_DEV_CMD64X=m +CONFIG_BLK_DEV_TRIFLEX=m +CONFIG_BLK_DEV_CY82C693=m +CONFIG_BLK_DEV_CS5520=m +CONFIG_BLK_DEV_HPT34X=m +CONFIG_BLK_DEV_HPT366=m +CONFIG_BLK_DEV_SC1200=m +CONFIG_BLK_DEV_PIIX=m +CONFIG_BLK_DEV_NS87415=m +CONFIG_BLK_DEV_OPTI621=m +CONFIG_BLK_DEV_PDC202XX_OLD=m +CONFIG_BLK_DEV_PDC202XX_NEW=m +CONFIG_BLK_DEV_SVWKS=m +CONFIG_BLK_DEV_SIIMAGE=m +CONFIG_BLK_DEV_SLC90E66=m +CONFIG_BLK_DEV_TRM290=m +CONFIG_BLK_DEV_VIA82CXXX=m CONFIG_IDEDMA_AUTO=y # CONFIG_IDEDMA_IVB is not set +CONFIG_BLK_DEV_PDC202XX=y CONFIG_BLK_DEV_IDE_MODES=y # @@ -408,14 +411,18 @@ CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set +CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set CONFIG_NET_IPIP=m CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y CONFIG_ARPD=y CONFIG_INET_ECN=y -# CONFIG_SYN_COOKIES is not set +CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y @@ -436,6 +443,7 @@ CONFIG_IP_NF_MATCH_MARK=m CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_DSCP=m CONFIG_IP_NF_MATCH_AH_ESP=m @@ -553,9 +561,9 @@ CONFIG_BRIDGE_EBT_DNAT=m CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_MARK_T=m -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set +CONFIG_X25=m +CONFIG_LAPB=m +CONFIG_NET_DIVERT=y # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -661,11 +669,13 @@ # # Ethernet (1000 Mbit) # -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_DL2K=m +CONFIG_E1000=m +CONFIG_E1000_NAPI=y CONFIG_MYRI_SBUS=m -# CONFIG_NS83820 is not set +CONFIG_NS83820=m CONFIG_HAMACHI=m CONFIG_YELLOWFIN=m CONFIG_R8169=m @@ -710,8 +720,11 @@ # # Wireless 802.11b ISA/PCI cards support # -# CONFIG_AIRO is not set -# CONFIG_HERMES is not set +CONFIG_AIRO=m +CONFIG_HERMES=m +CONFIG_PLX_HERMES=m +CONFIG_TMD_HERMES=m +CONFIG_PCI_HERMES=m CONFIG_NET_WIRELESS=y # @@ -934,7 +947,6 @@ # CONFIG_KEYBOARD_NEWTON is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_SERIAL=y # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S --- a/arch/sparc64/kernel/systbls.S Fri Jun 27 14:19:56 2003 +++ b/arch/sparc64/kernel/systbls.S Fri Jun 27 14:19:56 2003 @@ -65,8 +65,8 @@ .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex /*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 -/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_ni_syscall - .word sys_ni_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall +/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64 + .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl @@ -124,11 +124,8 @@ .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid - - /* 234 and 235 were for the hugetlb syscalls. They can be reused */ - -/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_nis_syscall - .word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall +/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64 + .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl diff -Nru a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c --- a/arch/sparc64/kernel/traps.c Fri Jun 27 14:20:05 2003 +++ b/arch/sparc64/kernel/traps.c Fri Jun 27 14:20:05 2003 @@ -1569,12 +1569,15 @@ printk("\n"); } -void show_trace_raw(struct thread_info *tp, unsigned long ksp) +void show_stack(struct task_struct *tsk, unsigned long *_ksp) { - unsigned long pc, fp, thread_base; + unsigned long pc, fp, thread_base, ksp; + struct thread_info *tp = tsk->thread_info; struct reg_window *rw; int count = 0; + ksp = (unsigned long) _ksp; + if (tp == current_thread_info()) flushw_all(); @@ -1596,17 +1599,17 @@ void show_trace_task(struct task_struct *tsk) { if (tsk) - show_trace_raw(tsk->thread_info, - tsk->thread_info->ksp); + show_stack(tsk, + (unsigned long *) tsk->thread_info->ksp); } void dump_stack(void) { - unsigned long ksp; + unsigned long *ksp; __asm__ __volatile__("mov %%fp, %0" : "=r" (ksp)); - show_trace_raw(current_thread_info(), ksp); + show_stack(current, ksp); } void die_if_kernel(char *str, struct pt_regs *regs) diff -Nru a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c --- a/arch/sparc64/mm/fault.c Fri Jun 27 14:20:05 2003 +++ b/arch/sparc64/mm/fault.c Fri Jun 27 14:20:05 2003 @@ -149,16 +149,14 @@ die_if_kernel("Oops", regs); } -extern void show_trace_raw(struct thread_info *, unsigned long); - static void bad_kernel_pc(struct pt_regs *regs) { - unsigned long ksp; + unsigned long *ksp; printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", regs->tpc); __asm__("mov %%sp, %0" : "=r" (ksp)); - show_trace_raw(current_thread_info(), ksp); + show_stack(current, ksp); unhandled_fault(regs->tpc, current, regs); } diff -Nru a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c --- a/arch/sparc64/solaris/fs.c Fri Jun 27 14:19:54 2003 +++ b/arch/sparc64/solaris/fs.c Fri Jun 27 14:19:54 2003 @@ -390,7 +390,7 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf) { - struct statfs s; + struct kstatfs s; int error; struct sol_statvfs *ss = (struct sol_statvfs *)A(buf); @@ -424,7 +424,7 @@ static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf) { - struct statfs s; + struct kstatfs s; int error; struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf); diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig --- a/arch/v850/Kconfig Fri Jun 27 14:19:56 2003 +++ b/arch/v850/Kconfig Fri Jun 27 14:19:56 2003 @@ -265,15 +265,6 @@ source "drivers/ide/Kconfig" -config SCSI - tristate "SCSI device support" - help - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - source "drivers/scsi/Kconfig" endmenu diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig --- a/arch/x86_64/Kconfig Fri Jun 27 14:20:00 2003 +++ b/arch/x86_64/Kconfig Fri Jun 27 14:20:00 2003 @@ -407,32 +407,7 @@ source "drivers/ide/Kconfig" - -menu "SCSI device support" - -config SCSI - tristate "SCSI device support" - ---help--- - If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or - any other SCSI device under Linux, say Y and make sure that you know - the name of your SCSI host adapter (the card inside your computer - that "speaks" the SCSI protocol, also called SCSI controller), - because you will be asked for it. - - You also need to say Y here if you want support for the parallel - port version of the 100 MB IOMEGA ZIP drive. - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called scsi_mod. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt> and - <file:Documentation/scsi/scsi.txt>. However, do not compile this as a - module if your root file system (the one containing the directory /) - is located on a SCSI device. - source "drivers/scsi/Kconfig" - -endmenu source "drivers/md/Kconfig" diff -Nru a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c --- a/arch/x86_64/ia32/ia32_binfmt.c Fri Jun 27 14:19:52 2003 +++ b/arch/x86_64/ia32/ia32_binfmt.c Fri Jun 27 14:19:52 2003 @@ -30,10 +30,12 @@ #define AT_SYSINFO 32 #define AT_SYSINFO_EHDR 33 +#if 0 /* disabled for now because the code has still problems */ #define ARCH_DLINFO do { \ NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \ } while(0) +#endif struct file; struct elf_phdr; diff -Nru a/arch/x86_64/ia32/ia32_ioctl.c b/arch/x86_64/ia32/ia32_ioctl.c --- a/arch/x86_64/ia32/ia32_ioctl.c Fri Jun 27 14:19:57 2003 +++ b/arch/x86_64/ia32/ia32_ioctl.c Fri Jun 27 14:19:57 2003 @@ -552,7 +552,7 @@ set_fs(old_fs); if (err >= 0 && - put_user(((u32)(long)kptr), compat_ptr(arg))) + put_user((u32)(u64)kptr, (u32 *)arg)) err = -EFAULT; return err; diff -Nru a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c --- a/arch/x86_64/ia32/ptrace32.c Fri Jun 27 14:19:54 2003 +++ b/arch/x86_64/ia32/ptrace32.c Fri Jun 27 14:19:54 2003 @@ -210,6 +210,7 @@ return child; } out: + if (child) put_task_struct(child); return NULL; diff -Nru a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c --- a/arch/x86_64/ia32/sys_ia32.c Fri Jun 27 14:19:56 2003 +++ b/arch/x86_64/ia32/sys_ia32.c Fri Jun 27 14:19:56 2003 @@ -946,10 +946,30 @@ struct sysinfo s; int ret; mm_segment_t old_fs = get_fs (); + int bitcount = 0; set_fs (KERNEL_DS); ret = sys_sysinfo(&s); set_fs (old_fs); + + /* Check to see if any memory value is too large for 32-bit and scale + * down if needed + */ + if ((s.totalram >> 32) || (s.totalswap >> 32)) { + while (s.mem_unit < PAGE_SIZE) { + s.mem_unit <<= 1; + bitcount++; + } + s.totalram >>= bitcount; + s.freeram >>= bitcount; + s.sharedram >>= bitcount; + s.bufferram >>= bitcount; + s.totalswap >>= bitcount; + s.freeswap >>= bitcount; + s.totalhigh >>= bitcount; + s.freehigh >>= bitcount; + } + if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) || __put_user (s.uptime, &info->uptime) || __put_user (s.loads[0], &info->loads[0]) || diff -Nru a/arch/x86_64/kernel/acpi/boot.c b/arch/x86_64/kernel/acpi/boot.c --- a/arch/x86_64/kernel/acpi/boot.c Fri Jun 27 14:19:54 2003 +++ b/arch/x86_64/kernel/acpi/boot.c Fri Jun 27 14:19:54 2003 @@ -100,7 +100,7 @@ if (madt->lapic_address) acpi_lapic_addr = (u64) madt->lapic_address; - printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", + printk(KERN_INFO PREFIX "Local APIC address 0x%016x\n", madt->lapic_address); return 0; diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c --- a/arch/x86_64/kernel/i8259.c Fri Jun 27 14:19:54 2003 +++ b/arch/x86_64/kernel/i8259.c Fri Jun 27 14:19:54 2003 @@ -26,9 +26,6 @@ #include <linux/irq.h> -/* When we have things working, we can switch to always use - IOAPIC. --pavel */ - /* * Common place to define all x86 IRQ vectors * diff -Nru a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c --- a/arch/x86_64/kernel/module.c Fri Jun 27 14:20:03 2003 +++ b/arch/x86_64/kernel/module.c Fri Jun 27 14:20:03 2003 @@ -31,9 +31,6 @@ #define DEBUGP(fmt...) -/* TODO this should be in vmlist, but we must fix get_vm_area first to - handle out of bounds entries properly. - Also need to fix /proc/kcore, /dev/kmem */ static struct vm_struct *mod_vmlist; void module_free(struct module *mod, void *module_region) diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c --- a/arch/x86_64/kernel/nmi.c Fri Jun 27 14:19:56 2003 +++ b/arch/x86_64/kernel/nmi.c Fri Jun 27 14:19:56 2003 @@ -34,7 +34,7 @@ extern void default_do_nmi(struct pt_regs *); -unsigned int nmi_watchdog = NMI_LOCAL_APIC; +unsigned int nmi_watchdog = NMI_IO_APIC; static unsigned int nmi_hz = HZ; unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ int nmi_watchdog_disabled; @@ -153,17 +153,19 @@ #include <linux/device.h> +static int nmi_pm_active; /* nmi_active before suspend */ + static int lapic_nmi_suspend(struct sys_device *dev, u32 state) { + nmi_pm_active = nmi_active; disable_lapic_nmi_watchdog(); return 0; } static int lapic_nmi_resume(struct sys_device *dev) { -#if 0 + if (nmi_pm_active > 0) enable_lapic_nmi_watchdog(); -#endif return 0; } @@ -234,6 +236,8 @@ switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: if (boot_cpu_data.x86 < 6) + return; + if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) return; setup_k7_watchdog(); break; diff -Nru a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c --- a/arch/x86_64/kernel/pci-gart.c Fri Jun 27 14:19:56 2003 +++ b/arch/x86_64/kernel/pci-gart.c Fri Jun 27 14:19:56 2003 @@ -236,7 +236,7 @@ static int dump; if (dump || !iommu_leak_tab) return; dump = 1; - show_stack(NULL); + show_stack(NULL,NULL); /* Very crude. dump some from the end of the table too */ printk("Dumping %d pages from end of IOMMU:\n", iommu_leak_pages); for (i = 0; i < iommu_leak_pages; i+=2) { diff -Nru a/arch/x86_64/kernel/suspend.c b/arch/x86_64/kernel/suspend.c --- a/arch/x86_64/kernel/suspend.c Fri Jun 27 14:19:56 2003 +++ b/arch/x86_64/kernel/suspend.c Fri Jun 27 14:19:56 2003 @@ -121,11 +121,12 @@ struct tss_struct * t = init_tss + cpu; set_tss_desc(cpu,t); /* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ - ((struct n_desc_struct *) &cpu_gdt_table[cpu][GDT_ENTRY_TSS])->b &= 0xfffffdff; + + cpu_gdt_table[cpu][GDT_ENTRY_TSS].type = 9; syscall_init(); /* This sets MSR_*STAR and related */ load_TR_desc(); /* This does ltr */ - load_LDT(¤t->mm->context); /* This does lldt */ + load_LDT(¤t->active_mm->context); /* This does lldt */ /* * Now maybe reload the debug registers diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c --- a/arch/x86_64/kernel/time.c Fri Jun 27 14:19:59 2003 +++ b/arch/x86_64/kernel/time.c Fri Jun 27 14:19:59 2003 @@ -47,6 +47,7 @@ unsigned long hpet_tick; /* HPET clocks / interrupt */ unsigned long vxtime_hz = 1193182; int report_lost_ticks; /* command line option */ +unsigned long long monotonic_base; struct vxtime_data __vxtime __section_vxtime; /* for vsyscalls */ @@ -137,6 +138,18 @@ tv->tv_sec--; } + wall_to_monotonic.tv_sec += xtime.tv_sec - tv->tv_sec; + wall_to_monotonic.tv_nsec += xtime.tv_nsec - tv->tv_nsec; + + if (wall_to_monotonic.tv_nsec > NSEC_PER_SEC) { + wall_to_monotonic.tv_nsec -= NSEC_PER_SEC; + wall_to_monotonic.tv_sec++; + } + if (wall_to_monotonic.tv_nsec < 0) { + wall_to_monotonic.tv_nsec += NSEC_PER_SEC; + wall_to_monotonic.tv_sec--; + } + xtime.tv_sec = tv->tv_sec; xtime.tv_nsec = tv->tv_nsec; @@ -219,6 +232,47 @@ spin_unlock(&rtc_lock); } + +/* monotonic_clock(): returns # of nanoseconds passed since time_init() + * Note: This function is required to return accurate + * time even in the absence of multiple timer ticks. + */ +unsigned long long monotonic_clock(void) +{ + unsigned long seq; + u32 last_offset, this_offset, offset; + unsigned long long base; + + if (vxtime.mode == VXTIME_HPET) { + do { + seq = read_seqbegin(&xtime_lock); + + last_offset = vxtime.last; + base = monotonic_base; + this_offset = hpet_readl(HPET_T0_CMP) - hpet_tick; + + } while (read_seqretry(&xtime_lock, seq)); + offset = (this_offset - last_offset); + offset *=(NSEC_PER_SEC/HZ)/hpet_tick; + return base + offset; + }else{ + do { + seq = read_seqbegin(&xtime_lock); + + last_offset = vxtime.last_tsc; + base = monotonic_base; + } while (read_seqretry(&xtime_lock, seq)); + sync_core(); + rdtscll(this_offset); + offset = (this_offset - last_offset)*1000/cpu_khz; + return base + offset; + } + + +} +EXPORT_SYMBOL(monotonic_clock); + + static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { static unsigned long rtc_update = 0; @@ -253,6 +307,9 @@ lost = (offset - vxtime.last) / hpet_tick - 1; } + monotonic_base += + (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; + vxtime.last = offset; } else { offset = (((tsc - vxtime.last_tsc) * @@ -266,6 +323,8 @@ offset %= (USEC_PER_SEC / HZ); } + monotonic_base += (tsc - vxtime.last_tsc)*1000000/cpu_khz ; + vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot; if ((((tsc - vxtime.last_tsc) * @@ -543,6 +602,9 @@ xtime.tv_sec = get_cmos_time(); xtime.tv_nsec = 0; + + wall_to_monotonic.tv_sec = -xtime.tv_sec; + wall_to_monotonic.tv_nsec = -xtime.tv_nsec; if (!hpet_init()) { vxtime_hz = (1000000000000000L + hpet_period / 2) / diff -Nru a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c --- a/arch/x86_64/kernel/traps.c Fri Jun 27 14:19:52 2003 +++ b/arch/x86_64/kernel/traps.c Fri Jun 27 14:19:52 2003 @@ -27,6 +27,7 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -206,7 +207,7 @@ show_trace((unsigned long *)rsp); } -void show_stack(unsigned long * rsp) +void show_stack(struct task_struct *tsk, unsigned long * rsp) { unsigned long *stack; int i; @@ -214,7 +215,7 @@ unsigned long *irqstack_end = (unsigned long *) (cpu_pda[cpu].irqstackptr); unsigned long *irqstack = (unsigned long *) (cpu_pda[cpu].irqstackptr - IRQSTACKSIZE); - // debugging aid: "show_stack(NULL);" prints the + // debugging aid: "show_stack(NULL, NULL);" prints the // back trace for this cpu. if(rsp==NULL) @@ -269,7 +270,7 @@ if (in_kernel) { printk("Stack: "); - show_stack((unsigned long*)rsp); + show_stack(NULL, (unsigned long*)rsp); printk("\nCode: "); if(regs->rip < PAGE_OFFSET) @@ -831,3 +832,4 @@ */ cpu_init(); } + diff -Nru a/drivers/Makefile b/drivers/Makefile --- a/drivers/Makefile Fri Jun 27 14:20:00 2003 +++ b/drivers/Makefile Fri Jun 27 14:20:00 2003 @@ -33,7 +33,6 @@ obj-$(CONFIG_ZORRO) += zorro/ obj-$(CONFIG_PPC_PMAC) += macintosh/ obj-$(CONFIG_MAC) += macintosh/ -obj-$(CONFIG_SGI) += sgi/ obj-$(CONFIG_PARIDE) += block/paride/ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_USB) += usb/ diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c --- a/drivers/acpi/osl.c Fri Jun 27 14:20:00 2003 +++ b/drivers/acpi/osl.c Fri Jun 27 14:20:00 2003 @@ -466,7 +466,8 @@ } result = raw_pci_ops->read(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, size, value); + PCI_DEVFN(pci_id->device, pci_id->function), + reg, size, value); return (result ? AE_ERROR : AE_OK); } @@ -491,7 +492,8 @@ } result = raw_pci_ops->write(pci_id->segment, pci_id->bus, - pci_id->device, pci_id->function, reg, size, value); + PCI_DEVFN(pci_id->device, pci_id->function), + reg, size, value); return (result ? AE_ERROR : AE_OK); } @@ -933,8 +935,8 @@ } /* Assumes no unreadable holes inbetween */ -BOOLEAN -acpi_os_readable(void *ptr, u32 len) +u8 +acpi_os_readable(void *ptr, acpi_size len) { #if defined(__i386__) || defined(__x86_64__) char tmp; @@ -943,8 +945,8 @@ return 1; } -BOOLEAN -acpi_os_writable(void *ptr, u32 len) +u8 +acpi_os_writable(void *ptr, acpi_size len) { /* could do dummy write (racy) or a kernel page table lookup. The later may be difficult at early boot when kmap doesn't work yet. */ diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c --- a/drivers/acpi/pci_root.c Fri Jun 27 14:19:54 2003 +++ b/drivers/acpi/pci_root.c Fri Jun 27 14:19:54 2003 @@ -246,8 +246,6 @@ switch (status) { case AE_OK: root->id.segment = (u16) value; - printk("_SEG exists! Unsupported. Abort.\n"); - BUG(); break; case AE_NOT_FOUND: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -309,7 +307,7 @@ * PCI namespace does not get created until this call is made (and * thus the root bridge's pci_dev does not exist). */ - root->bus = pcibios_scan_root(root->id.bus); + root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); if (!root->bus) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Bus %02x:%02x not present in PCI namespace\n", diff -Nru a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c --- a/drivers/atm/atmtcp.c Fri Jun 27 14:19:58 2003 +++ b/drivers/atm/atmtcp.c Fri Jun 27 14:19:58 2003 @@ -153,9 +153,10 @@ static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void *arg) { - unsigned long flags; struct atm_cirange ci; struct atm_vcc *vcc; + struct hlist_node *node; + struct sock *s; if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD; if (copy_from_user(&ci,(void *) arg,sizeof(ci))) return -EFAULT; @@ -163,14 +164,18 @@ if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS; if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 || ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL; - spin_lock_irqsave(&dev->lock, flags); - for (vcc = dev->vccs; vcc; vcc = vcc->next) + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + if (vcc->dev != dev) + continue; if ((vcc->vpi >> ci.vpi_bits) || (vcc->vci >> ci.vci_bits)) { - spin_unlock_irqrestore(&dev->lock, flags); + read_unlock(&vcc_sklist_lock); return -EBUSY; } - spin_unlock_irqrestore(&dev->lock, flags); + } + read_unlock(&vcc_sklist_lock); dev->ci_range = ci; return 0; } @@ -233,9 +238,10 @@ static void atmtcp_c_close(struct atm_vcc *vcc) { - unsigned long flags; struct atm_dev *atmtcp_dev; struct atmtcp_dev_data *dev_data; + struct sock *s; + struct hlist_node *node; struct atm_vcc *walk; atmtcp_dev = (struct atm_dev *) vcc->dev_data; @@ -246,19 +252,24 @@ kfree(dev_data); shutdown_atm_dev(atmtcp_dev); vcc->dev_data = NULL; - spin_lock_irqsave(&atmtcp_dev->lock, flags); - for (walk = atmtcp_dev->vccs; walk; walk = walk->next) + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + walk = atm_sk(s); + if (walk->dev != atmtcp_dev) + continue; wake_up(&walk->sleep); - spin_unlock_irqrestore(&atmtcp_dev->lock, flags); + } + read_unlock(&vcc_sklist_lock); } static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb) { - unsigned long flags; struct atm_dev *dev; struct atmtcp_hdr *hdr; - struct atm_vcc *out_vcc; + struct sock *s; + struct hlist_node *node; + struct atm_vcc *out_vcc = NULL; struct sk_buff *new_skb; int result = 0; @@ -270,13 +281,17 @@ (struct atmtcp_control *) skb->data); goto done; } - spin_lock_irqsave(&dev->lock, flags); - for (out_vcc = dev->vccs; out_vcc; out_vcc = out_vcc->next) + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + out_vcc = atm_sk(s); + if (out_vcc->dev != dev) + continue; if (out_vcc->vpi == ntohs(hdr->vpi) && out_vcc->vci == ntohs(hdr->vci) && out_vcc->qos.rxtp.traffic_class != ATM_NONE) break; - spin_unlock_irqrestore(&dev->lock, flags); + } + read_unlock(&vcc_sklist_lock); if (!out_vcc) { atomic_inc(&vcc->stats->tx_err); goto done; @@ -366,7 +381,7 @@ if (itf != -1) dev = atm_dev_lookup(itf); if (dev) { if (dev->ops != &atmtcp_v_dev_ops) { - atm_dev_release(dev); + atm_dev_put(dev); return -EMEDIUMTYPE; } if (PRIV(dev)->vcc) return -EBUSY; @@ -378,7 +393,8 @@ if (error) return error; } PRIV(dev)->vcc = vcc; - bind_vcc(vcc,&atmtcp_control_dev); + vcc->dev = &atmtcp_control_dev; + vcc_insert_socket(vcc->sk); set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); vcc->dev_data = dev; @@ -402,7 +418,7 @@ dev = atm_dev_lookup(itf); if (!dev) return -ENODEV; if (dev->ops != &atmtcp_v_dev_ops) { - atm_dev_release(dev); + atm_dev_put(dev); return -EMEDIUMTYPE; } dev_data = PRIV(dev); @@ -410,7 +426,7 @@ dev_data->persist = 0; if (PRIV(dev)->vcc) return 0; kfree(dev_data); - atm_dev_release(dev); + atm_dev_put(dev); shutdown_atm_dev(dev); return 0; } diff -Nru a/drivers/atm/eni.c b/drivers/atm/eni.c --- a/drivers/atm/eni.c Fri Jun 27 14:19:54 2003 +++ b/drivers/atm/eni.c Fri Jun 27 14:19:54 2003 @@ -1887,10 +1887,11 @@ static int get_ci(struct atm_vcc *vcc,short *vpi,int *vci) { - unsigned long flags; + struct sock *s; + struct hlist_node *node; struct atm_vcc *walk; - spin_lock_irqsave(&vcc->dev->lock, flags); + read_lock(&vcc_sklist_lock); if (*vpi == ATM_VPI_ANY) *vpi = 0; if (*vci == ATM_VCI_ANY) { for (*vci = ATM_NOT_RSV_VCI; *vci < NR_VCI; (*vci)++) { @@ -1898,40 +1899,48 @@ ENI_DEV(vcc->dev)->rx_map[*vci]) continue; if (vcc->qos.txtp.traffic_class != ATM_NONE) { - for (walk = vcc->dev->vccs; walk; - walk = walk->next) + sk_for_each(s, node, &vcc_sklist) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vci == *vci && walk->qos.txtp.traffic_class != ATM_NONE) break; - if (walk) continue; + } + if (node) + continue; } break; } - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return *vci == NR_VCI ? -EADDRINUSE : 0; } if (*vci == ATM_VCI_UNSPEC) { - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return 0; } if (vcc->qos.rxtp.traffic_class != ATM_NONE && ENI_DEV(vcc->dev)->rx_map[*vci]) { - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return -EADDRINUSE; } if (vcc->qos.txtp.traffic_class == ATM_NONE) { - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return 0; } - for (walk = vcc->dev->vccs; walk; walk = walk->next) + sk_for_each(s, node, &vcc_sklist) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vci == *vci && walk->qos.txtp.traffic_class != ATM_NONE) { - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return -EADDRINUSE; } - spin_unlock_irqrestore(&vcc->dev->lock, flags); + } + read_unlock(&vcc_sklist_lock); return 0; } @@ -2139,7 +2148,8 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page) { - unsigned long flags; + struct hlist_node *node; + struct sock *s; static const char *signal[] = { "LOST","unknown","okay" }; struct eni_dev *eni_dev = ENI_DEV(dev); struct atm_vcc *vcc; @@ -2212,11 +2222,15 @@ return sprintf(page,"%10sbacklog %u packets\n","", skb_queue_len(&tx->backlog)); } - spin_lock_irqsave(&dev->lock, flags); - for (vcc = dev->vccs; vcc; vcc = vcc->next) { - struct eni_vcc *eni_vcc = ENI_VCC(vcc); + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + struct eni_vcc *eni_vcc; int length; + vcc = atm_sk(s); + if (vcc->dev != dev) + continue; + eni_vcc = ENI_VCC(vcc); if (--left) continue; length = sprintf(page,"vcc %4d: ",vcc->vci); if (eni_vcc->rx) { @@ -2231,10 +2245,10 @@ length += sprintf(page+length,"tx[%d], txing %d bytes", eni_vcc->tx->index,eni_vcc->txing); page[length] = '\n'; - spin_unlock_irqrestore(&dev->lock, flags); + read_unlock(&vcc_sklist_lock); return length+1; } - spin_unlock_irqrestore(&dev->lock, flags); + read_unlock(&vcc_sklist_lock); for (i = 0; i < eni_dev->free_len; i++) { struct eni_free *fe = eni_dev->free_list+i; unsigned long offset; diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c --- a/drivers/atm/fore200e.c Fri Jun 27 14:20:05 2003 +++ b/drivers/atm/fore200e.c Fri Jun 27 14:20:05 2003 @@ -1069,18 +1069,23 @@ static struct atm_vcc* fore200e_find_vcc(struct fore200e* fore200e, struct rpd* rpd) { - unsigned long flags; + struct sock *s; struct atm_vcc* vcc; + struct hlist_node *node; - spin_lock_irqsave(&fore200e->atm_dev->lock, flags); - for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { - - if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) - break; + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + if (vcc->dev != fore200e->atm_dev) + continue; + if (vcc->vpi == rpd->atm_header.vpi && vcc->vci == rpd->atm_header.vci) { + read_unlock(&vcc_sklist_lock); + return vcc; + } } - spin_unlock_irqrestore(&fore200e->atm_dev->lock, flags); - - return vcc; + read_unlock(&vcc_sklist_lock); + + return NULL; } @@ -1350,20 +1355,26 @@ static int fore200e_walk_vccs(struct atm_vcc *vcc, short *vpi, int *vci) { - unsigned long flags; struct atm_vcc* walk; + struct sock *s; + struct hlist_node *node; /* find a free VPI */ - spin_lock_irqsave(&vcc->dev->lock, flags); + read_lock(&vcc_sklist_lock); if (*vpi == ATM_VPI_ANY) { - for (*vpi = 0, walk = vcc->dev->vccs; walk; walk = walk->next) { + *vpi = 0; +restart_vpi_search: + sk_for_each(s, node, &vcc_sklist) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if ((walk->vci == *vci) && (walk->vpi == *vpi)) { (*vpi)++; - walk = vcc->dev->vccs; + goto restart_vpi_search; } } } @@ -1371,16 +1382,21 @@ /* find a free VCI */ if (*vci == ATM_VCI_ANY) { - for (*vci = ATM_NOT_RSV_VCI, walk = vcc->dev->vccs; walk; walk = walk->next) { + *vci = ATM_NOT_RSV_VCI; +restart_vci_search: + sk_for_each(s, node, &vcc_sklist) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if ((walk->vpi = *vpi) && (walk->vci == *vci)) { *vci = walk->vci + 1; - walk = vcc->dev->vccs; + goto restart_vci_search; } } } - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return 0; } @@ -2642,7 +2658,8 @@ static int fore200e_proc_read(struct atm_dev *dev,loff_t* pos,char* page) { - unsigned long flags; + struct sock *s; + struct hlist_node *node; struct fore200e* fore200e = FORE200E_DEV(dev); int len, left = *pos; @@ -2889,8 +2906,12 @@ len = sprintf(page,"\n" " VCCs:\n address\tVPI.VCI:AAL\t(min/max tx PDU size) (min/max rx PDU size)\n"); - spin_lock_irqsave(&fore200e->atm_dev->lock, flags); - for (vcc = fore200e->atm_dev->vccs; vcc; vcc = vcc->next) { + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + + if (vcc->dev != fore200e->atm_dev) + continue; fore200e_vcc = FORE200E_VCC(vcc); @@ -2904,7 +2925,7 @@ fore200e_vcc->rx_max_pdu ); } - spin_unlock_irqrestore(&fore200e->atm_dev->lock, flags); + read_unlock(&vcc_sklist_lock); return len; } diff -Nru a/drivers/atm/he.c b/drivers/atm/he.c --- a/drivers/atm/he.c Fri Jun 27 14:19:54 2003 +++ b/drivers/atm/he.c Fri Jun 27 14:19:54 2003 @@ -79,7 +79,6 @@ #include <linux/sonet.h> #define USE_TASKLET -#define USE_HE_FIND_VCC #undef USE_SCATTERGATHER #undef USE_CHECKSUM_HW /* still confused about this */ #define USE_RBPS @@ -328,25 +327,25 @@ he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7) static __inline__ struct atm_vcc* -he_find_vcc(struct he_dev *he_dev, unsigned cid) +__find_vcc(struct he_dev *he_dev, unsigned cid) { - unsigned long flags; struct atm_vcc *vcc; + struct hlist_node *node; + struct sock *s; short vpi; int vci; vpi = cid >> he_dev->vcibits; vci = cid & ((1 << he_dev->vcibits) - 1); - spin_lock_irqsave(&he_dev->atm_dev->lock, flags); - for (vcc = he_dev->atm_dev->vccs; vcc; vcc = vcc->next) - if (vcc->vci == vci && vcc->vpi == vpi - && vcc->qos.rxtp.traffic_class != ATM_NONE) { - spin_unlock_irqrestore(&he_dev->atm_dev->lock, flags); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + if (vcc->dev == he_dev->atm_dev && + vcc->vci == vci && vcc->vpi == vpi && + vcc->qos.rxtp.traffic_class != ATM_NONE) { return vcc; - } - - spin_unlock_irqrestore(&he_dev->atm_dev->lock, flags); + } + } return NULL; } @@ -1566,17 +1565,6 @@ reg |= RX_ENABLE; he_writel(he_dev, reg, RC_CONFIG); -#ifndef USE_HE_FIND_VCC - he_dev->he_vcc_table = kmalloc(sizeof(struct he_vcc_table) * - (1 << (he_dev->vcibits + he_dev->vpibits)), GFP_KERNEL); - if (he_dev->he_vcc_table == NULL) { - hprintk("failed to alloc he_vcc_table\n"); - return -ENOMEM; - } - memset(he_dev->he_vcc_table, 0, sizeof(struct he_vcc_table) * - (1 << (he_dev->vcibits + he_dev->vpibits))); -#endif - for (i = 0; i < HE_NUM_CS_STPER; ++i) { he_dev->cs_stper[i].inuse = 0; he_dev->cs_stper[i].pcr = -1; @@ -1712,11 +1700,6 @@ he_dev->tpd_base, he_dev->tpd_base_phys); #endif -#ifndef USE_HE_FIND_VCC - if (he_dev->he_vcc_table) - kfree(he_dev->he_vcc_table); -#endif - if (he_dev->pci_dev) { pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command); command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); @@ -1798,6 +1781,7 @@ int pdus_assembled = 0; int updated = 0; + read_lock(&vcc_sklist_lock); while (he_dev->rbrq_head != rbrq_tail) { ++updated; @@ -1823,13 +1807,10 @@ buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; cid = RBRQ_CID(he_dev->rbrq_head); -#ifdef USE_HE_FIND_VCC if (cid != lastcid) - vcc = he_find_vcc(he_dev, cid); + vcc = __find_vcc(he_dev, cid); lastcid = cid; -#else - vcc = HE_LOOKUP_VCC(he_dev, cid); -#endif + if (vcc == NULL) { hprintk("vcc == NULL (cid 0x%x)\n", cid); if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) @@ -1966,6 +1947,7 @@ RBRQ_MASK(++he_dev->rbrq_head)); } + read_unlock(&vcc_sklist_lock); if (updated) { if (updated > he_dev->rbrq_peak) @@ -2565,10 +2547,6 @@ #endif spin_unlock_irqrestore(&he_dev->global_lock, flags); - -#ifndef USE_HE_FIND_VCC - HE_LOOKUP_VCC(he_dev, cid) = vcc; -#endif } open_failed: @@ -2634,9 +2612,6 @@ if (timeout == 0) hprintk("close rx timeout cid 0x%x\n", cid); -#ifndef USE_HE_FIND_VCC - HE_LOOKUP_VCC(he_dev, cid) = NULL; -#endif HPRINTK("close rx cid 0x%x complete\n", cid); } diff -Nru a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c --- a/drivers/atm/idt77252.c Fri Jun 27 14:19:56 2003 +++ b/drivers/atm/idt77252.c Fri Jun 27 14:19:56 2003 @@ -2403,37 +2403,43 @@ static int idt77252_find_vcc(struct atm_vcc *vcc, short *vpi, int *vci) { - unsigned long flags; + struct sock *s; struct atm_vcc *walk; - spin_lock_irqsave(&vcc->dev->lock, flags); + read_lock(&vcc_sklist_lock); if (*vpi == ATM_VPI_ANY) { *vpi = 0; - walk = vcc->dev->vccs; - while (walk) { + s = sk_head(&vcc_sklist); + while (s) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if ((walk->vci == *vci) && (walk->vpi == *vpi)) { (*vpi)++; - walk = vcc->dev->vccs; + s = sk_head(&vcc_sklist); continue; } - walk = walk->next; + s = sk_next(s); } } if (*vci == ATM_VCI_ANY) { *vci = ATM_NOT_RSV_VCI; - walk = vcc->dev->vccs; - while (walk) { + s = sk_head(&vcc_sklist); + while (s) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if ((walk->vci == *vci) && (walk->vpi == *vpi)) { (*vci)++; - walk = vcc->dev->vccs; + s = sk_head(&vcc_sklist); continue; } - walk = walk->next; + s = sk_next(s); } } - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return 0; } diff -Nru a/drivers/block/loop.c b/drivers/block/loop.c --- a/drivers/block/loop.c Fri Jun 27 14:19:57 2003 +++ b/drivers/block/loop.c Fri Jun 27 14:19:57 2003 @@ -2,7 +2,7 @@ * linux/drivers/block/loop.c * * Written by Theodore Ts'o, 3/29/93 - * + * * Copyright 1993 by Theodore Ts'o. Redistribution of this file is * permitted under the GNU General Public License. * @@ -21,12 +21,12 @@ * Loadable modules and other fixes by AK, 1998 * * Make real block number available to downstream transfer functions, enables - * CBC (and relatives) mode encryption requiring unique IVs per data block. + * CBC (and relatives) mode encryption requiring unique IVs per data block. * Reed H. Petty, rhp@draper.net * * Maximum number of loop devices now dynamic via max_loop module parameter. * Russell Kroll <rkroll@exploits.org> 19990701 - * + * * Maximum number of loop devices when compiled-in now selectable by passing * max_loop=<1-255> to the kernel on boot. * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999 @@ -40,19 +40,10 @@ * Heinz Mauelshagen <mge@sistina.com>, Feb 2002 * * Still To Fix: - * - Advisory locking is ignored here. - * - Should use an own CAP_* category instead of CAP_SYS_ADMIN + * - Advisory locking is ignored here. + * - Should use an own CAP_* category instead of CAP_SYS_ADMIN * - * WARNING/FIXME: - * - The block number as IV passing to low level transfer functions is broken: - * it passes the underlying device's block number instead of the - * offset. This makes it change for a given block when the file is - * moved/restored/copied and also doesn't work over NFS. - * AV, Feb 12, 2000: we pass the logical block number now. It fixes the - * problem above. Encryption modules that used to rely on the old scheme - * should just call ->i_mapping->bmap() to calculate the physical block - * number. - */ + */ #include <linux/config.h> #include <linux/module.h> @@ -60,12 +51,10 @@ #include <linux/sched.h> #include <linux/fs.h> #include <linux/file.h> -#include <linux/bio.h> #include <linux/stat.h> #include <linux/errno.h> #include <linux/major.h> #include <linux/wait.h> -#include <linux/blk.h> #include <linux/blkpg.h> #include <linux/init.h> #include <linux/devfs_fs_kernel.h> @@ -120,49 +109,60 @@ return 0; } -static int xor_status(struct loop_device *lo, const struct loop_info64 *info) +static int xor_init(struct loop_device *lo, const struct loop_info64 *info) { if (info->lo_encrypt_key_size <= 0) return -EINVAL; return 0; } -struct loop_func_table none_funcs = { +static struct loop_func_table none_funcs = { .number = LO_CRYPT_NONE, .transfer = transfer_none, }; -struct loop_func_table xor_funcs = { +static struct loop_func_table xor_funcs = { .number = LO_CRYPT_XOR, .transfer = transfer_xor, - .init = xor_status + .init = xor_init }; -/* xfer_funcs[0] is special - its release function is never called */ -struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { +/* xfer_funcs[0] is special - its release function is never called */ +static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { &none_funcs, - &xor_funcs + &xor_funcs }; -static int figure_loop_size(struct loop_device *lo) +static int +figure_loop_size(struct loop_device *lo) { - loff_t size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size; + loff_t size, offset, loopsize; sector_t x; + + /* Compute loopsize in bytes */ + size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size; + offset = lo->lo_offset; + loopsize = size - offset; + if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize) + loopsize = lo->lo_sizelimit; + /* * Unfortunately, if we want to do I/O on the device, * the number of 512-byte sectors has to fit into a sector_t. */ - size = (size - lo->lo_offset) >> 9; + size = loopsize >> 9; x = (sector_t)size; + if ((loff_t)x != size) return -EFBIG; - set_capacity(disks[lo->lo_number], size); + set_capacity(disks[lo->lo_number], x); return 0; } -static inline int lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf, - char *lbuf, int size, sector_t rblock) +static inline int +lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf, + char *lbuf, int size, sector_t rblock) { if (!lo->transfer) return 0; @@ -189,9 +189,11 @@ data = kmap(bvec->bv_page) + bvec->bv_offset; len = bvec->bv_len; while (len > 0) { - sector_t IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize; + sector_t IV; int transfer_result; + IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); + size = PAGE_CACHE_SIZE - offset; if (size > len) size = len; @@ -202,7 +204,8 @@ if (aops->prepare_write(file, page, offset, offset+size)) goto unlock; kaddr = kmap(page); - transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV); + transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, + data, size, IV); if (transfer_result) { /* * The transfer failed, but we still write the data to @@ -271,7 +274,9 @@ unsigned long count = desc->count; struct lo_read_data *p = (struct lo_read_data*)desc->buf; struct loop_device *lo = p->lo; - int IV = page->index * (PAGE_CACHE_SIZE/p->bsize) + offset/p->bsize; + sector_t IV; + + IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); if (size > count) size = count; @@ -326,20 +331,6 @@ return ret; } -static inline unsigned long -loop_get_iv(struct loop_device *lo, unsigned long sector) -{ - int bs = lo->lo_blocksize; - unsigned long offset, IV; - - IV = sector / (bs >> 9) + lo->lo_offset / bs; - offset = ((sector % (bs >> 9)) << 9) + lo->lo_offset % bs; - if (offset >= bs) - IV++; - - return IV; -} - static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) { loff_t pos; @@ -503,11 +494,13 @@ static int loop_transfer_bio(struct loop_device *lo, struct bio *to_bio, struct bio *from_bio) { - unsigned long IV = loop_get_iv(lo, from_bio->bi_sector); + sector_t IV; struct bio_vec *from_bvec, *to_bvec; char *vto, *vfrom; int ret = 0, i; + IV = from_bio->bi_sector + (lo->lo_offset >> 9); + __bio_for_each_segment(from_bvec, from_bio, i, 0) { to_bvec = &to_bio->bi_io_vec[i]; @@ -614,9 +607,12 @@ daemonize("loop%d", lo->lo_number); - current->flags |= PF_IOTHREAD; /* loop can be used in an encrypted device - hence, it mustn't be stopped at all because it could - be indirectly used during suspension */ + /* + * loop can be used in an encrypted device, + * hence, it mustn't be stopped at all + * because it could be indirectly used during suspension + */ + current->flags |= PF_IOTHREAD; set_user_nice(current, -20); @@ -724,6 +720,7 @@ lo->lo_backing_file = file; lo->transfer = NULL; lo->ioctl = NULL; + lo->lo_sizelimit = 0; if (figure_loop_size(lo)) { error = -EFBIG; fput(file); @@ -771,36 +768,42 @@ return error; } -static int loop_release_xfer(struct loop_device *lo) +static int +loop_release_xfer(struct loop_device *lo) { - int err = 0; - if (lo->lo_encrypt_type) { - struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type]; - if (xfer && xfer->release) - err = xfer->release(lo); - if (xfer && xfer->unlock) - xfer->unlock(lo); - lo->lo_encrypt_type = 0; + int err = 0; + struct loop_func_table *xfer = lo->lo_encryption; + + if (xfer) { + if (xfer->release) + err = xfer->release(lo); + lo->transfer = NULL; + lo->lo_encryption = NULL; + module_put(xfer->owner); } return err; } static int -loop_init_xfer(struct loop_device *lo, int type, const struct loop_info64 *i) +loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer, + const struct loop_info64 *i) { - int err = 0; - if (type) { - struct loop_func_table *xfer = xfer_funcs[type]; + int err = 0; + + if (xfer) { + struct module *owner = xfer->owner; + + if (!try_module_get(owner)) + return -EINVAL; if (xfer->init) err = xfer->init(lo, i); - if (!err) { - lo->lo_encrypt_type = type; - if (xfer->lock) - xfer->lock(lo); - } + if (err) + module_put(owner); + else + lo->lo_encryption = xfer; } return err; -} +} static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) { @@ -809,9 +812,11 @@ if (lo->lo_state != Lo_bound) return -ENXIO; + if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ return -EBUSY; - if (filp==NULL) + + if (filp == NULL) return -EINVAL; spin_lock_irq(&lo->lo_lock); @@ -828,8 +833,9 @@ lo->transfer = NULL; lo->ioctl = NULL; lo->lo_device = NULL; - lo->lo_encrypt_type = 0; + lo->lo_encryption = NULL; lo->lo_offset = 0; + lo->lo_sizelimit = 0; lo->lo_encrypt_key_size = 0; lo->lo_flags = 0; lo->lo_queue.queuedata = NULL; @@ -849,49 +855,57 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) { int err; - unsigned int type; - loff_t offset; + struct loop_func_table *xfer; - if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid && + if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid && !capable(CAP_SYS_ADMIN)) return -EPERM; if (lo->lo_state != Lo_bound) return -ENXIO; if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) return -EINVAL; - type = info->lo_encrypt_type; - if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL) - return -EINVAL; - if (type == LO_CRYPT_XOR && info->lo_encrypt_key_size == 0) - return -EINVAL; err = loop_release_xfer(lo); - if (!err) - err = loop_init_xfer(lo, type, info); + if (err) + return err; - offset = lo->lo_offset; - if (offset != info->lo_offset) { - lo->lo_offset = info->lo_offset; - if (figure_loop_size(lo)){ - err = -EFBIG; - lo->lo_offset = offset; - } - } + if (info->lo_encrypt_type) { + unsigned int type = info->lo_encrypt_type; + + if (type >= MAX_LO_CRYPT) + return -EINVAL; + xfer = xfer_funcs[type]; + if (xfer == NULL) + return -EINVAL; + } else + xfer = NULL; + err = loop_init_xfer(lo, xfer, info); if (err) - return err; + return err; + + if (lo->lo_offset != info->lo_offset || + lo->lo_sizelimit != info->lo_sizelimit) { + lo->lo_offset = info->lo_offset; + lo->lo_sizelimit = info->lo_sizelimit; + if (figure_loop_size(lo)) + return -EFBIG; + } strlcpy(lo->lo_name, info->lo_name, LO_NAME_SIZE); - lo->transfer = xfer_funcs[type]->transfer; - lo->ioctl = xfer_funcs[type]->ioctl; + if (!xfer) + xfer = &none_funcs; + lo->transfer = xfer->transfer; + lo->ioctl = xfer->ioctl; + lo->lo_encrypt_key_size = info->lo_encrypt_key_size; lo->lo_init[0] = info->lo_init[0]; lo->lo_init[1] = info->lo_init[1]; if (info->lo_encrypt_key_size) { - memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, + memcpy(lo->lo_encrypt_key, info->lo_encrypt_key, info->lo_encrypt_key_size); - lo->lo_key_owner = current->uid; + lo->lo_key_owner = current->uid; } return 0; @@ -915,9 +929,11 @@ info->lo_inode = stat.ino; info->lo_rdevice = lo->lo_device ? stat.rdev : stat.dev; info->lo_offset = lo->lo_offset; + info->lo_sizelimit = lo->lo_sizelimit; info->lo_flags = lo->lo_flags; strlcpy(info->lo_name, lo->lo_name, LO_NAME_SIZE); - info->lo_encrypt_type = lo->lo_encrypt_type; + info->lo_encrypt_type = + lo->lo_encryption ? lo->lo_encryption->number : 0; if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { info->lo_encrypt_key_size = lo->lo_encrypt_key_size; memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, @@ -929,11 +945,13 @@ static void loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64) { + memset(info64, 0, sizeof(*info64)); info64->lo_number = info->lo_number; info64->lo_device = info->lo_device; info64->lo_inode = info->lo_inode; info64->lo_rdevice = info->lo_rdevice; info64->lo_offset = info->lo_offset; + info64->lo_sizelimit = 0; info64->lo_encrypt_type = info->lo_encrypt_type; info64->lo_encrypt_key_size = info->lo_encrypt_key_size; info64->lo_flags = info->lo_flags; @@ -946,6 +964,7 @@ static int loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info) { + memset(info, 0, sizeof(*info)); info->lo_number = info64->lo_number; info->lo_device = info64->lo_device; info->lo_inode = info64->lo_inode; @@ -1060,30 +1079,22 @@ static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; - int type; down(&lo->lo_ctl_mutex); - - type = lo->lo_encrypt_type; - if (type && xfer_funcs[type] && xfer_funcs[type]->lock) - xfer_funcs[type]->lock(lo); lo->lo_refcnt++; up(&lo->lo_ctl_mutex); + return 0; } static int lo_release(struct inode *inode, struct file *file) { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; - int type; down(&lo->lo_ctl_mutex); - type = lo->lo_encrypt_type; --lo->lo_refcnt; - if (xfer_funcs[type] && xfer_funcs[type]->unlock) - xfer_funcs[type]->unlock(lo); - up(&lo->lo_ctl_mutex); + return 0; } @@ -1103,38 +1114,45 @@ int loop_register_transfer(struct loop_func_table *funcs) { - if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number]) + unsigned int n = funcs->number; + + if (n >= MAX_LO_CRYPT || xfer_funcs[n]) return -EINVAL; - xfer_funcs[funcs->number] = funcs; - return 0; + xfer_funcs[n] = funcs; + return 0; } int loop_unregister_transfer(int number) { - struct loop_device *lo; + unsigned int n = number; + struct loop_device *lo; + struct loop_func_table *xfer; - if ((unsigned)number >= MAX_LO_CRYPT) - return -EINVAL; - for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { - int type = lo->lo_encrypt_type; - if (type == number) { - xfer_funcs[type]->release(lo); - lo->transfer = NULL; - lo->lo_encrypt_type = 0; - } + if (n == 0 || n >= MAX_LO_CRYPT || (xfer = xfer_funcs[n]) == NULL) + return -EINVAL; + + xfer_funcs[n] = NULL; + + for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { + down(&lo->lo_ctl_mutex); + + if (lo->lo_encryption == xfer) + loop_release_xfer(lo); + + up(&lo->lo_ctl_mutex); } - xfer_funcs[number] = NULL; - return 0; + + return 0; } EXPORT_SYMBOL(loop_register_transfer); EXPORT_SYMBOL(loop_unregister_transfer); -int __init loop_init(void) +int __init loop_init(void) { int i; - if ((max_loop < 1) || (max_loop > 256)) { + if (max_loop < 1 || max_loop > 256) { printk(KERN_WARNING "loop: invalid max_loop (must be between" " 1 and 256), using default (8)\n"); max_loop = 8; @@ -1143,22 +1161,22 @@ if (register_blkdev(LOOP_MAJOR, "loop")) return -EIO; - devfs_mk_dir("loop"); - loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); if (!loop_dev) - return -ENOMEM; + goto out_mem1; disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); if (!disks) - goto out_mem; + goto out_mem2; for (i = 0; i < max_loop; i++) { disks[i] = alloc_disk(1); if (!disks[i]) - goto out_mem2; + goto out_mem3; } + devfs_mk_dir("loop"); + for (i = 0; i < max_loop; i++) { struct loop_device *lo = &loop_dev[i]; struct gendisk *disk = disks[i]; @@ -1180,19 +1198,22 @@ printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); return 0; -out_mem2: +out_mem3: while (i--) put_disk(disks[i]); kfree(disks); -out_mem: +out_mem2: kfree(loop_dev); +out_mem1: + unregister_blkdev(LOOP_MAJOR, "loop"); printk(KERN_ERR "loop: ran out of memory\n"); return -ENOMEM; } -void loop_exit(void) +void loop_exit(void) { int i; + for (i = 0; i < max_loop; i++) { del_gendisk(disks[i]); put_disk(disks[i]); diff -Nru a/drivers/block/nbd.c b/drivers/block/nbd.c --- a/drivers/block/nbd.c Fri Jun 27 14:19:54 2003 +++ b/drivers/block/nbd.c Fri Jun 27 14:19:54 2003 @@ -28,6 +28,9 @@ * the transmit lock. <steve@chygwyn.com> * 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes. * <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com> + * 03-06-22 Make nbd work with new linux 2.5 block layer design. This fixes + * memory corruption from module removal and possible memory corruption + * from sending/receiving disk data. <ldl@aros.net> * * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall * why not: would need verify_area and friends, would share yet another @@ -63,6 +66,16 @@ static struct nbd_device nbd_dev[MAX_NBD]; +/* + * Use just one lock (or at most 1 per NIC). Two arguments for this: + * 1. Each NIC is essentially a synchronization point for all servers + * accessed through that NIC so there's no need to have more locks + * than NICs anyway. + * 2. More locks lead to more "Dirty cache line bouncing" which will slow + * down each lock to the point where they're actually slower than just + * a single lock. + * Thanks go to Jens Axboe and Al Viro for their LKML emails explaining this! + */ static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED; #define DEBUG( s ) @@ -168,6 +181,17 @@ return result; } +static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec, + int flags) +{ + int result; + void *kaddr = kmap(bvec->bv_page); + result = nbd_xmit(1, sock, kaddr + bvec->bv_offset, bvec->bv_len, + flags); + kunmap(bvec->bv_page); + return result; +} + #define FAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); goto error_out; } void nbd_send_req(struct nbd_device *lo, struct request *req) @@ -209,7 +233,7 @@ if ((i < (bio->bi_vcnt - 1)) || bio->bi_next) flags = MSG_MORE; DEBUG("data, "); - result = nbd_xmit(1, sock, page_address(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, flags); + result = sock_send_bvec(sock, bvec, flags); if (result <= 0) FAIL("Send data failed."); } @@ -244,6 +268,16 @@ return NULL; } +static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec) +{ + int result; + void *kaddr = kmap(bvec->bv_page); + result = nbd_xmit(0, sock, kaddr + bvec->bv_offset, bvec->bv_len, + MSG_WAITALL); + kunmap(bvec->bv_page); + return result; +} + #define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; } struct request *nbd_read_stat(struct nbd_device *lo) /* NULL returned = something went wrong, inform userspace */ @@ -251,10 +285,11 @@ int result; struct nbd_reply reply; struct request *req; + struct socket *sock = lo->sock; DEBUG("reading control, "); reply.magic = 0; - result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply), MSG_WAITALL); + result = nbd_xmit(0, sock, (char *) &reply, sizeof(reply), MSG_WAITALL); if (result <= 0) HARDFAIL("Recv control failed."); req = nbd_find_request(lo, reply.handle); @@ -268,14 +303,17 @@ FAIL("Other side returned error."); if (nbd_cmd(req) == NBD_CMD_READ) { - struct bio *bio = req->bio; + int i; + struct bio *bio; DEBUG("data, "); - do { - result = nbd_xmit(0, lo->sock, bio_data(bio), bio->bi_size, MSG_WAITALL); - if (result <= 0) - HARDFAIL("Recv data failed."); - bio = bio->bi_next; - } while(bio); + rq_for_each_bio(bio, req) { + struct bio_vec *bvec; + bio_for_each_segment(bvec, bio, i) { + result = sock_recv_bvec(sock, bvec); + if (result <= 0) + HARDFAIL("Recv data failed."); + } + } } DEBUG("done.\n"); return req; @@ -538,8 +576,6 @@ * (Just smiley confuses emacs :-) */ -static struct request_queue nbd_queue; - static int __init nbd_init(void) { int err = -ENOMEM; @@ -555,6 +591,17 @@ if (!disk) goto out; nbd_dev[i].disk = disk; + /* + * The new linux 2.5 block layer implementation requires + * every gendisk to have its very own request_queue struct. + * These structs are big so we dynamically allocate them. + */ + disk->queue = kmalloc(sizeof(struct request_queue), GFP_KERNEL); + if (!disk->queue) { + put_disk(disk); + goto out; + } + blk_init_queue(disk->queue, do_nbd_request, &nbd_lock); } if (register_blkdev(NBD_MAJOR, "nbd")) { @@ -564,7 +611,6 @@ #ifdef MODULE printk("nbd: registered device at major %d\n", NBD_MAJOR); #endif - blk_init_queue(&nbd_queue, do_nbd_request, &nbd_lock); devfs_mk_dir("nbd"); for (i = 0; i < MAX_NBD; i++) { struct gendisk *disk = nbd_dev[i].disk; @@ -582,7 +628,6 @@ disk->first_minor = i; disk->fops = &nbd_fops; disk->private_data = &nbd_dev[i]; - disk->queue = &nbd_queue; sprintf(disk->disk_name, "nbd%d", i); sprintf(disk->devfs_name, "nbd/%d", i); set_capacity(disk, 0x3ffffe); @@ -591,8 +636,10 @@ return 0; out: - while (i--) + while (i--) { + kfree(nbd_dev[i].disk->queue); put_disk(nbd_dev[i].disk); + } return err; } @@ -600,12 +647,22 @@ { int i; for (i = 0; i < MAX_NBD; i++) { - del_gendisk(nbd_dev[i].disk); - put_disk(nbd_dev[i].disk); + struct gendisk *disk = nbd_dev[i].disk; + if (disk) { + if (disk->queue) { + blk_cleanup_queue(disk->queue); + kfree(disk->queue); + disk->queue = NULL; + } + del_gendisk(disk); + put_disk(disk); + } } devfs_remove("nbd"); - blk_cleanup_queue(&nbd_queue); unregister_blkdev(NBD_MAJOR, "nbd"); +#ifdef MODULE + printk("nbd: unregistered device at major %d\n", NBD_MAJOR); +#endif } module_init(nbd_init); diff -Nru a/drivers/block/rd.c b/drivers/block/rd.c --- a/drivers/block/rd.c Fri Jun 27 14:19:58 2003 +++ b/drivers/block/rd.c Fri Jun 27 14:19:58 2003 @@ -271,9 +271,6 @@ { unsigned unit = minor(inode->i_rdev); - if (unit >= NUM_RAMDISKS) - return -ENODEV; - /* * Immunize device against invalidate_buffers() and prune_icache(). */ diff -Nru a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig --- a/drivers/cdrom/Kconfig Fri Jun 27 14:20:00 2003 +++ b/drivers/cdrom/Kconfig Fri Jun 27 14:20:00 2003 @@ -1,6 +1,39 @@ # # CDROM driver configuration # + +menu "Old CD-ROM drivers (not SCSI, not IDE)" + depends on ISA + +config CD_NO_IDESCSI + bool "Support non-SCSI/IDE/ATAPI CDROM drives" + ---help--- + If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y + here, otherwise N. Read the CD-ROM-HOWTO, available from + <http://www.tldp.org/docs.html#howto>. + + Note that the answer to this question doesn't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about these CD-ROM drives. If you are unsure what you + have, say Y and find out whether you have one of the following + drives. + + For each of these drivers, a file Documentation/cdrom/{driver_name} + exists. Especially in cases where you do not know exactly which kind + of drive you have you should read there. Most of these drivers use a + file drivers/cdrom/{driver_name}.h where you can define your + interface parameters and switch some internal goodies. + + All these CD-ROM drivers are also usable as a module ( = code which + can be inserted in and removed from the running kernel whenever you + want). If you want to compile them as module, say M instead of Y and + read <file:Documentation/modules.txt>. + + If you want to use any of these CD-ROM drivers, you also have to + answer Y or M to "ISO 9660 CD-ROM file system support" below (this + answer will get "defaulted" for you if you enable any of the Linux + CD-ROM drivers). + config AZTCD tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM CDROM support" depends on CD_NO_IDESCSI @@ -248,3 +281,4 @@ The module will be called sonycd535. If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. +endmenu diff -Nru a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c --- a/drivers/char/agp/nvidia-agp.c Fri Jun 27 14:19:54 2003 +++ b/drivers/char/agp/nvidia-agp.c Fri Jun 27 14:19:54 2003 @@ -169,7 +169,8 @@ mem->is_flushed = TRUE; } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) - agp_bridge->gatt_table[nvidia_private.pg_offset + j] = mem->memory[i]; + agp_bridge->gatt_table[nvidia_private.pg_offset + j] = + agp_bridge->driver->mask_memory(mem->memory[i], mem->type); agp_bridge->driver->tlb_flush(mem); return 0; diff -Nru a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c --- a/drivers/char/agp/sis-agp.c Fri Jun 27 14:19:52 2003 +++ b/drivers/char/agp/sis-agp.c Fri Jun 27 14:19:52 2003 @@ -151,6 +151,10 @@ .device_id = PCI_DEVICE_ID_SI_550, .chipset_name = "550", }, + { + .device_id = PCI_DEVICE_ID_SI_655, + .chipset_name = "655", + }, { }, /* dummy final entry, always present */ }; diff -Nru a/drivers/char/ip2main.c b/drivers/char/ip2main.c --- a/drivers/char/ip2main.c Fri Jun 27 14:20:06 2003 +++ b/drivers/char/ip2main.c Fri Jun 27 14:20:06 2003 @@ -707,40 +707,42 @@ } } #else /* LINUX_VERSION_CODE > 2.1.99 */ - struct pci_dev *pci_dev_i = NULL; - pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE, - PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); - if (pci_dev_i != NULL) { - unsigned int addr; - unsigned char pci_irq; + { + struct pci_dev *pci_dev_i = NULL; + pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE, + PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); + if (pci_dev_i != NULL) { + unsigned int addr; + unsigned char pci_irq; - ip2config.type[i] = PCI; - status = - pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); - if ( addr & 1 ) { - ip2config.addr[i]=(USHORT)(addr&0xfffe); - } else { - printk( KERN_ERR "IP2: PCI I/O address error\n"); - } - status = - pci_read_config_byte(pci_dev_i, PCI_INTERRUPT_LINE, &pci_irq); + ip2config.type[i] = PCI; + status = + pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); + if ( addr & 1 ) { + ip2config.addr[i]=(USHORT)(addr&0xfffe); + } else { + printk( KERN_ERR "IP2: PCI I/O address error\n"); + } + status = + pci_read_config_byte(pci_dev_i, PCI_INTERRUPT_LINE, &pci_irq); // If the PCI BIOS assigned it, lets try and use it. If we // can't acquire it or it screws up, deal with it then. -// if (!is_valid_irq(pci_irq)) { -// printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); -// pci_irq = 0; -// } - ip2config.irq[i] = pci_irq; - } else { // ann error - ip2config.addr[i] = 0; - if (status == PCIBIOS_DEVICE_NOT_FOUND) { - printk( KERN_ERR "IP2: PCI board %d not found\n", i ); - } else { - pcibios_strerror(status); - } - } +// if (!is_valid_irq(pci_irq)) { +// printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); +// pci_irq = 0; +// } + ip2config.irq[i] = pci_irq; + } else { // ann error + ip2config.addr[i] = 0; + if (status == PCIBIOS_DEVICE_NOT_FOUND) { + printk( KERN_ERR "IP2: PCI board %d not found\n", i ); + } else { + pcibios_strerror(status); + } + } + } #endif /* ! 2_0_X */ #else printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); diff -Nru a/drivers/char/lcd.c b/drivers/char/lcd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/char/lcd.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,633 @@ +/* + * LCD, LED and Button interface for Cobalt + * + * 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) 1996, 1997 by Andrew Bose + * + * Linux kernel version history: + * March 2001: Ported from 2.0.34 by Liam Davies + * + */ + +#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/miscdevice.h> +#include <linux/slab.h> +#include <linux/ioport.h> +#include <linux/fcntl.h> +#include <linux/mc146818rtc.h> +#include <linux/netdevice.h> +#include <linux/sched.h> + +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/system.h> +#include <linux/delay.h> + +#include "lcd.h" + +static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg); + +static int lcd_present = 1; + +int led_state = 0; + +#if defined(CONFIG_TULIP) && 0 + +#define MAX_INTERFACES 8 +static linkcheck_func_t linkcheck_callbacks[MAX_INTERFACES]; +static void *linkcheck_cookies[MAX_INTERFACES]; + +int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie) +{ + if (iface_num < 0 || + iface_num >= MAX_INTERFACES || + linkcheck_callbacks[iface_num] != NULL) + return -1; + linkcheck_callbacks[iface_num] = (linkcheck_func_t) func; + linkcheck_cookies[iface_num] = cookie; + return 0; +} +#endif + +static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct lcd_display button_display; + unsigned long address, a; + int index; + + switch (cmd) { + case LCD_On: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0F); + break; + + case LCD_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x08); + break; + + case LCD_Reset: + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x3F); + udelay(150); + LCDWriteInst(0x01); + udelay(150); + LCDWriteInst(0x06); + break; + + case LCD_Clear: + udelay(150); + BusyCheck(); + LCDWriteInst(0x01); + break; + + case LCD_Cursor_Left: + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + break; + + case LCD_Cursor_Right: + udelay(150); + BusyCheck(); + LCDWriteInst(0x14); + break; + + case LCD_Cursor_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0C); + break; + + case LCD_Cursor_On: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0F); + break; + + case LCD_Blink_Off: + udelay(150); + BusyCheck(); + LCDWriteInst(0x0E); + break; + + case LCD_Get_Cursor_Pos:{ + struct lcd_display display; + + udelay(150); + BusyCheck(); + display.cursor_address = ( LCDReadInst ); + display.cursor_address = ( display.cursor_address & 0x07F ); + if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) + return -EFAULT; + + break; + } + + + case LCD_Set_Cursor_Pos: { + struct lcd_display display; + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + + a = (display.cursor_address | kLCD_Addr ); + + udelay(150); + BusyCheck(); + LCDWriteInst( a ); + + break; + } + + case LCD_Get_Cursor: { + struct lcd_display display; + + udelay(150); + BusyCheck(); + display.character = LCDReadData; + + if(copy_to_user((struct lcd_display*)arg, &display, sizeof(struct lcd_display))) + return -EFAULT; + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; + } + + case LCD_Set_Cursor:{ + struct lcd_display display; + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + + udelay(150); + BusyCheck(); + LCDWriteData( display.character ); + udelay(150); + BusyCheck(); + LCDWriteInst(0x10); + + break; + } + + + case LCD_Disp_Left: + udelay(150); + BusyCheck(); + LCDWriteInst(0x18); + break; + + case LCD_Disp_Right: + udelay(150); + BusyCheck(); + LCDWriteInst(0x1C); + break; + + case LCD_Home: + udelay(150); + BusyCheck(); + LCDWriteInst(0x02); + break; + + case LCD_Write: { + struct lcd_display display; + + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + + udelay(150); + BusyCheck(); + LCDWriteInst(0x80); + udelay(150); + BusyCheck(); + + for (index = 0; index < (display.size1); index++) { + udelay(150); + BusyCheck(); + LCDWriteData( display.line1[index]); + BusyCheck(); + } + + udelay(150); + BusyCheck(); + LCDWriteInst(0xC0); + udelay(150); + BusyCheck(); + for (index = 0; index < (display.size2); index++) { + udelay(150); + BusyCheck(); + LCDWriteData( display.line2[index]); + } + + break; + } + + case LCD_Read: { + struct lcd_display display; + + BusyCheck(); + for (address = kDD_R00; address <= kDD_R01; address++) { + a = (address | kLCD_Addr ); + + udelay(150); + BusyCheck(); + LCDWriteInst( a ); + udelay(150); + BusyCheck(); + display.line1[address] = LCDReadData; + } + + display.line1[ 0x27 ] = '\0'; + + for (address = kDD_R10; address <= kDD_R11; address++) { + a = (address | kLCD_Addr ); + + udelay(150); + BusyCheck(); + LCDWriteInst( a ); + + udelay(150); + BusyCheck(); + display.line2[address - 0x40 ] = LCDReadData; + } + + display.line2[ 0x27 ] = '\0'; + + if(copy_to_user((struct lcd_display*)arg, &display, + sizeof(struct lcd_display))) + return -EFAULT; + break; + } + +// set all GPIO leds to led_display.leds + + case LED_Set: { + struct lcd_display led_display; + + + if(copy_from_user(&led_display, (struct lcd_display*)arg, + sizeof(struct lcd_display))) + return -EFAULT; + + led_state = led_display.leds; + LEDSet(led_state); + + break; + } + + +// set only bit led_display.leds + + case LED_Bit_Set: { + int i; + int bit=1; + struct lcd_display led_display; + + + if(copy_from_user(&led_display, (struct lcd_display*)arg, + sizeof(struct lcd_display))) + return -EFAULT; + + for (i=0;i<(int)led_display.leds;i++) + { + bit = 2*bit; + } + + led_state = led_state | bit; + LEDSet(led_state); + break; + } + +// clear only bit led_display.leds + + case LED_Bit_Clear: { + int i; + int bit=1; + struct lcd_display led_display; + + + if(copy_from_user(&led_display, (struct lcd_display*)arg, + sizeof(struct lcd_display))) + return -EFAULT; + + for (i=0;i<(int)led_display.leds;i++) + { + bit = 2*bit; + } + + led_state = led_state & ~bit; + LEDSet(led_state); + break; + } + + + case BUTTON_Read: { + button_display.buttons = GPIRead; + if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) + return -EFAULT; + break; + } + + case LINK_Check: { + button_display.buttons = *((volatile unsigned long *) (0xB0100060) ); + if(copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) + return -EFAULT; + break; + } + + case LINK_Check_2: { + int iface_num; + + /* panel-utils should pass in the desired interface status is wanted for + * in "buttons" of the structure. We will set this to non-zero if the + * link is in fact up for the requested interface. --DaveM + */ + if(copy_from_user(&button_display, (struct lcd_display *)arg, sizeof(button_display))) + return -EFAULT; + iface_num = button_display.buttons; +#if defined(CONFIG_TULIP) && 0 + if (iface_num >= 0 && + iface_num < MAX_INTERFACES && + linkcheck_callbacks[iface_num] != NULL) { + button_display.buttons = + linkcheck_callbacks[iface_num](linkcheck_cookies[iface_num]); + } else +#endif + button_display.buttons = 0; + + if(__copy_to_user((struct lcd_display*)arg, &button_display, sizeof(struct lcd_display))) + return -EFAULT; + break; + } + +// Erase the flash + + case FLASH_Erase: { + + int ctr=0; + + // Chip Erase Sequence + WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); + WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Erase3 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); + WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Erase6 ); + + printk( "Erasing Flash.\n"); + + while ( (!dqpoll(0x00000000,0xFF)) && (!timeout(0x00000000)) ) { + ctr++; + } + + printk("\n"); + printk("\n"); + printk("\n"); + + if (READ_FLASH(0x07FFF0)==0xFF) { printk("Erase Successful\r\n"); } + else if (timeout) { printk("Erase Timed Out\r\n"); } + + break; + } + +// burn the flash + + case FLASH_Burn: { + + volatile unsigned long burn_addr; + unsigned long flags; + int i; + unsigned char *rom; + + + struct lcd_display display; + + if(copy_from_user(&display, (struct lcd_display*)arg, sizeof(struct lcd_display))) + return -EFAULT; + rom = (unsigned char *) kmalloc((128),GFP_ATOMIC); + if ( rom == NULL ) { + printk ("broken\n"); + return 1; + } + + printk("Churning and Burning -"); + save_flags(flags); + for (i=0; i<FLASH_SIZE; i=i+128) { + + if(copy_from_user(rom, display.RomImage + i, 128)) + return -EFAULT; + burn_addr = kFlashBase + i; + cli(); + for ( index = 0; index < ( 128 ) ; index++ ) + { + + WRITE_FLASH( kFlash_Addr1, kFlash_Data1 ); + WRITE_FLASH( kFlash_Addr2, kFlash_Data2 ); + WRITE_FLASH( kFlash_Addr1, kFlash_Prog ); + *((volatile unsigned char *)burn_addr) = (volatile unsigned char) rom[index]; + + while ( (!dqpoll(burn_addr,(volatile unsigned char) rom[index])) && (!timeout(burn_addr)) ) { + } + burn_addr++; + } + restore_flags(flags); + if ( *((volatile unsigned char *)(burn_addr-1)) == (volatile unsigned char) rom[index-1] ) { + } else if (timeout) { + printk("Program timed out\r\n"); + } + + + } + kfree(rom); + + break; + } + +// read the flash all at once + + case FLASH_Read: { + + unsigned char *user_bytes; + volatile unsigned long read_addr; + int i; + + user_bytes = &(((struct lcd_display *)arg)->RomImage[0]); + + if(!access_ok(VERIFY_WRITE, user_bytes, FLASH_SIZE)) + return -EFAULT; + + printk("Reading Flash"); + for (i=0; i<FLASH_SIZE; i++) { + unsigned char tmp_byte; + read_addr = kFlashBase + i; + tmp_byte = *((volatile unsigned char *)read_addr); + if(__put_user (tmp_byte, &user_bytes[i])) + return -EFAULT; + } + + + break; + } + + + + + + default: + return 0; + break; + + } + + return 0; + +} + +static int lcd_open(struct inode *inode, struct file *file) +{ + if (!lcd_present) + return -ENXIO; + else + return 0; +} + +/* Only RESET or NEXT counts as button pressed */ + +static inline int button_pressed(void) +{ + unsigned long buttons = GPIRead; + + if ( (buttons == BUTTON_Next) || (buttons == BUTTON_Next_B) || (buttons == BUTTON_Reset_B) ) + return buttons; + return 0; +} + +/* LED daemon sits on this and we wake him up once a key is pressed. */ + +static int lcd_waiters = 0; + +static long lcd_read(struct inode *inode, struct file *file, char *buf, unsigned long count) +{ + long buttons_now; + + if(lcd_waiters > 0) + return -EINVAL; + + lcd_waiters++; + while(((buttons_now = (long)button_pressed()) == 0) && + !(signal_pending(current))) { + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(2 * HZ); + } + lcd_waiters--; + + if(signal_pending(current)) + return -ERESTARTSYS; + return buttons_now; +} + +/* + * The various file operations we support. + */ + +static struct file_operations lcd_fops = { + read: lcd_read, + ioctl: lcd_ioctl, + open: lcd_open, +}; + +static struct miscdevice lcd_dev= +{ + LCD_MINOR, + "lcd", + &lcd_fops +}; + +int lcd_init(void) +{ +unsigned long data; + + printk("%s\n", LCD_DRIVER); + misc_register(&lcd_dev); + + /* Check region? Naaah! Just snarf it up. */ +/* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/ + + udelay(150); + data = LCDReadData; + if ( (data & 0x000000FF) == (0x00) ) { + lcd_present = 0; + printk("LCD Not Present\n"); + } + else { + lcd_present = 1; + WRITE_GAL( kGal_DevBank2PReg, kGal_DevBank2Cfg ); + WRITE_GAL( kGal_DevBank3PReg, kGal_DevBank3Cfg ); + } + + return 0; +} + + +// +// Function: dqpoll +// +// Description: Polls the data lines to see if the flash is busy +// +// In: address, byte data +// +// Out: 0 = busy, 1 = write or erase complete +// +// + +int dqpoll( volatile unsigned long address, volatile unsigned char data ) { + +volatile unsigned char dq7; + +dq7 = data & 0x80; + +return ( (READ_FLASH(address) & 0x80) == dq7 ); + +} + + +// +// Function: timeout +// +// Description: Checks to see if erase or write has timed out +// By polling dq5 +// +// In: address +// +// +// Out: 0 = not timed out, 1 = timed out + +int timeout( volatile unsigned long address ) { + + +return ( (READ_FLASH(address) & 0x20) == 0x20 ); + +} + + + diff -Nru a/drivers/char/n_tty.c b/drivers/char/n_tty.c --- a/drivers/char/n_tty.c Fri Jun 27 14:19:52 2003 +++ b/drivers/char/n_tty.c Fri Jun 27 14:19:52 2003 @@ -325,7 +325,7 @@ { if (tty->erasing) { put_char('/', tty); - tty->column += 2; + tty->column++; tty->erasing = 0; } } diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig --- a/drivers/i2c/Kconfig Fri Jun 27 14:19:54 2003 +++ b/drivers/i2c/Kconfig Fri Jun 27 14:19:54 2003 @@ -42,6 +42,26 @@ <file:Documentation/modules.txt>. The module will be called i2c-algo-bit. +config I2C_PROSAVAGE + tristate "S3/VIA (Pro)Savage" + depends on I2C_ALGOBIT && PCI && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8 + graphics processors. + chipsets supported: + S3/VIA KM266/VT8375 aka ProSavage8 + S3/VIA KM133/VT8365 aka Savage4 + + This can also be built as a module which can be inserted and removed + while the kernel is running. If you want to compile it as a module, + say M here and read <file:Documentation/modules.txt>. + The module will be called i2c-prosavage. + + You will also need the latest user-space utilties: you can find them + in the lm_sensors package, which you can download at + http://www.lm-sensors.nu + config I2C_PHILIPSPAR tristate "Philips style parallel port adapter" depends on I2C_ALGOBIT && PARPORT diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile --- a/drivers/i2c/Makefile Fri Jun 27 14:19:52 2003 +++ b/drivers/i2c/Makefile Fri Jun 27 14:19:52 2003 @@ -5,6 +5,7 @@ obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o +obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o obj-$(CONFIG_I2C_PHILIPSPAR) += i2c-philips-par.o obj-$(CONFIG_I2C_ELV) += i2c-elv.o obj-$(CONFIG_I2C_VELLEMAN) += i2c-velleman.o diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig --- a/drivers/i2c/busses/Kconfig Fri Jun 27 14:20:01 2003 +++ b/drivers/i2c/busses/Kconfig Fri Jun 27 14:20:01 2003 @@ -4,6 +4,22 @@ menu "I2C Hardware Sensors Mainboard support" +config I2C_ALI1535 + tristate " ALI 1535" + depends on I2C && PCI && EXPERIMENTAL + help + If you say yes to this option, support will be included for the SMB + Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB + controller is part of the 7101 device, which is an ACPI-compliant + Power Management Unit (PMU). + + This can also be built as a module. If so, the module will be + called i2c-ali1535. + + You will also need the latest user-space utilties: you can find them + in the lm_sensors package, which you can download at + http://www.lm-sensors.nu + config I2C_ALI15X3 tristate " ALI 15x3" depends on I2C && PCI && EXPERIMENTAL diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile --- a/drivers/i2c/busses/Makefile Fri Jun 27 14:19:53 2003 +++ b/drivers/i2c/busses/Makefile Fri Jun 27 14:19:53 2003 @@ -2,6 +2,7 @@ # Makefile for the kernel hardware sensors bus drivers. # +obj-$(CONFIG_I2C_ALI1535) += i2c-ali1535.o obj-$(CONFIG_I2C_ALI15X3) += i2c-ali15x3.o obj-$(CONFIG_I2C_AMD756) += i2c-amd756.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/i2c/busses/i2c-ali1535.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,555 @@ +/* + i2c-ali1535.c - Part of lm_sensors, Linux kernel modules for hardware + monitoring + Copyright (c) 2000 Frodo Looijaard <frodol@dds.nl>, + Philip Edelbrock <phil@netroedge.com>, + Mark D. Studebaker <mdsxyz123@yahoo.com>, + Dan Eaton <dan.eaton@rocketlogix.com> and + Stephen Rousset<stephen.rousset@rocketlogix.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + This is the driver for the SMB Host controller on + Acer Labs Inc. (ALI) M1535 South Bridge. + + The M1535 is a South bridge for portable systems. + It is very similar to the M15x3 South bridges also produced + by Acer Labs Inc. Some of the registers within the part + have moved and some have been redefined slightly. Additionally, + the sequencing of the SMBus transactions has been modified + to be more consistent with the sequencing recommended by + the manufacturer and observed through testing. These + changes are reflected in this driver and can be identified + by comparing this driver to the i2c-ali15x3 driver. + For an overview of these chips see http://www.acerlabs.com + + The SMB controller is part of the 7101 device, which is an + ACPI-compliant Power Management Unit (PMU). + + The whole 7101 device has to be enabled for the SMB to work. + You can't just enable the SMB alone. + The SMB and the ACPI have separate I/O spaces. + We make sure that the SMB is enabled. We leave the ACPI alone. + + This driver controls the SMB Host only. + + This driver does not use interrupts. +*/ + + +/* Note: we assume there can only be one ALI1535, with one SMBus interface */ + +/* #define DEBUG 1 */ + +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/stddef.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/i2c.h> +#include <linux/init.h> +#include <asm/io.h> +#include <asm/semaphore.h> + + +/* ALI1535 SMBus address offsets */ +#define SMBHSTSTS (0 + ali1535_smba) +#define SMBHSTTYP (1 + ali1535_smba) +#define SMBHSTPORT (2 + ali1535_smba) +#define SMBHSTCMD (7 + ali1535_smba) +#define SMBHSTADD (3 + ali1535_smba) +#define SMBHSTDAT0 (4 + ali1535_smba) +#define SMBHSTDAT1 (5 + ali1535_smba) +#define SMBBLKDAT (6 + ali1535_smba) + +/* PCI Address Constants */ +#define SMBCOM 0x004 +#define SMBREV 0x008 +#define SMBCFG 0x0D1 +#define SMBBA 0x0E2 +#define SMBHSTCFG 0x0F0 +#define SMBCLK 0x0F2 + +/* Other settings */ +#define MAX_TIMEOUT 500 /* times 1/100 sec */ +#define ALI1535_SMB_IOSIZE 32 + +#define ALI1535_SMB_DEFAULTBASE 0x8040 + +/* ALI1535 address lock bits */ +#define ALI1535_LOCK 0x06 /* dwe */ + +/* ALI1535 command constants */ +#define ALI1535_QUICK 0x00 +#define ALI1535_BYTE 0x10 +#define ALI1535_BYTE_DATA 0x20 +#define ALI1535_WORD_DATA 0x30 +#define ALI1535_BLOCK_DATA 0x40 +#define ALI1535_I2C_READ 0x60 + +#define ALI1535_DEV10B_EN 0x80 /* Enable 10-bit addressing in */ + /* I2C read */ +#define ALI1535_T_OUT 0x08 /* Time-out Command (write) */ +#define ALI1535_A_HIGH_BIT9 0x08 /* Bit 9 of 10-bit address in */ + /* Alert-Response-Address */ + /* (read) */ +#define ALI1535_KILL 0x04 /* Kill Command (write) */ +#define ALI1535_A_HIGH_BIT8 0x04 /* Bit 8 of 10-bit address in */ + /* Alert-Response-Address */ + /* (read) */ + +#define ALI1535_D_HI_MASK 0x03 /* Mask for isolating bits 9-8 */ + /* of 10-bit address in I2C */ + /* Read Command */ + +/* ALI1535 status register bits */ +#define ALI1535_STS_IDLE 0x04 +#define ALI1535_STS_BUSY 0x08 /* host busy */ +#define ALI1535_STS_DONE 0x10 /* transaction complete */ +#define ALI1535_STS_DEV 0x20 /* device error */ +#define ALI1535_STS_BUSERR 0x40 /* bus error */ +#define ALI1535_STS_FAIL 0x80 /* failed bus transaction */ +#define ALI1535_STS_ERR 0xE0 /* all the bad error bits */ + +#define ALI1535_BLOCK_CLR 0x04 /* reset block data index */ + +/* ALI1535 device address register bits */ +#define ALI1535_RD_ADDR 0x01 /* Read/Write Bit in Device */ + /* Address field */ + /* -> Write = 0 */ + /* -> Read = 1 */ +#define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */ + + +static unsigned short ali1535_smba; +DECLARE_MUTEX(i2c_ali1535_sem); + +/* Detect whether a ALI1535 can be found, and initialize it, where necessary. + Note the differences between kernels with the old PCI BIOS interface and + newer kernels with the real PCI interface. In compat.h some things are + defined to make the transition easier. */ +static int ali1535_setup(struct pci_dev *dev) +{ + int retval = -ENODEV; + unsigned char temp; + + /* Check the following things: + - SMB I/O address is initialized + - Device is enabled + - We can use the addresses + */ + + /* Determine the address of the SMBus area */ + pci_read_config_word(dev, SMBBA, &ali1535_smba); + ali1535_smba &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1)); + if (ali1535_smba == 0) { + dev_warn(&dev->dev, + "ALI1535_smb region uninitialized - upgrade BIOS?\n"); + goto exit; + } + + if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, "ali1535-smb")) { + dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n", + ali1535_smba); + goto exit; + } + + /* check if whole device is enabled */ + pci_read_config_byte(dev, SMBCFG, &temp); + if ((temp & ALI1535_SMBIO_EN) == 0) { + dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n"); + goto exit_free; + } + + /* Is SMB Host controller enabled? */ + pci_read_config_byte(dev, SMBHSTCFG, &temp); + if ((temp & 1) == 0) { + dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n"); + goto exit_free; + } + + /* set SMB clock to 74KHz as recommended in data sheet */ + pci_write_config_byte(dev, SMBCLK, 0x20); + + /* + The interrupt routing for SMB is set up in register 0x77 in the + 1533 ISA Bridge device, NOT in the 7101 device. + Don't bother with finding the 1533 device and reading the register. + if ((....... & 0x0F) == 1) + dev_dbg(&dev->dev, "ALI1535 using Interrupt 9 for SMBus.\n"); + */ + pci_read_config_byte(dev, SMBREV, &temp); + dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); + dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba); + + retval = 0; +exit: + return retval; + +exit_free: + release_region(ali1535_smba, ALI1535_SMB_IOSIZE); + return retval; +} + +static void ali1535_do_pause(unsigned int amount) +{ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(amount); +} + +static int ali1535_transaction(struct i2c_adapter *adap) +{ + int temp; + int result = 0; + int timeout = 0; + + dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, " + "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", + inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD), + inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); + + /* get status */ + temp = inb_p(SMBHSTSTS); + + /* Make sure the SMBus host is ready to start transmitting */ + /* Check the busy bit first */ + if (temp & ALI1535_STS_BUSY) { + /* If the host controller is still busy, it may have timed out + * in the previous transaction, resulting in a "SMBus Timeout" + * printk. I've tried the following to reset a stuck busy bit. + * 1. Reset the controller with an KILL command. (this + * doesn't seem to clear the controller if an external + * device is hung) + * 2. Reset the controller and the other SMBus devices with a + * T_OUT command. (this clears the host busy bit if an + * external device is hung, but it comes back upon a new + * access to a device) + * 3. Disable and reenable the controller in SMBHSTCFG. Worst + * case, nothing seems to work except power reset. + */ + + /* Try resetting entire SMB bus, including other devices - This + * may not work either - it clears the BUSY bit but then the + * BUSY bit may come back on when you try and use the chip + * again. If that's the case you are stuck. + */ + dev_info(&adap->dev, + "Resetting entire SMB Bus to clear busy condition (%02x)\n", + temp); + outb_p(ALI1535_T_OUT, SMBHSTTYP); + temp = inb_p(SMBHSTSTS); + } + + /* now check the error bits and the busy bit */ + if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) { + /* do a clear-on-write */ + outb_p(0xFF, SMBHSTSTS); + if ((temp = inb_p(SMBHSTSTS)) & + (ALI1535_STS_ERR | ALI1535_STS_BUSY)) { + /* This is probably going to be correctable only by a + * power reset as one of the bits now appears to be + * stuck */ + /* This may be a bus or device with electrical problems. */ + dev_err(&adap->dev, + "SMBus reset failed! (0x%02x) - controller or " + "device on bus is probably hung\n", temp); + return -1; + } + } else { + /* check and clear done bit */ + if (temp & ALI1535_STS_DONE) { + outb_p(temp, SMBHSTSTS); + } + } + + /* start the transaction by writing anything to the start register */ + outb_p(0xFF, SMBHSTPORT); + + /* We will always wait for a fraction of a second! */ + timeout = 0; + do { + ali1535_do_pause(1); + temp = inb_p(SMBHSTSTS); + } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE)) + && (timeout++ < MAX_TIMEOUT)); + + /* If the SMBus is still busy, we give up */ + if (timeout >= MAX_TIMEOUT) { + result = -1; + dev_err(&adap->dev, "SMBus Timeout!\n"); + } + + if (temp & ALI1535_STS_FAIL) { + result = -1; + dev_dbg(&adap->dev, "Error: Failed bus transaction\n"); + } + + /* Unfortunately the ALI SMB controller maps "no response" and "bus + * collision" into a single bit. No reponse is the usual case so don't + * do a printk. This means that bus collisions go unreported. + */ + if (temp & ALI1535_STS_BUSERR) { + result = -1; + dev_dbg(&adap->dev, + "Error: no response or bus collision ADD=%02x\n", + inb_p(SMBHSTADD)); + } + + /* haven't ever seen this */ + if (temp & ALI1535_STS_DEV) { + result = -1; + dev_err(&adap->dev, "Error: device error\n"); + } + + /* check to see if the "command complete" indication is set */ + if (!(temp & ALI1535_STS_DONE)) { + result = -1; + dev_err(&adap->dev, "Error: command never completed\n"); + } + + dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, " + "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", + inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD), + inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1)); + + /* take consequent actions for error conditions */ + if (!(temp & ALI1535_STS_DONE)) { + /* issue "kill" to reset host controller */ + outb_p(ALI1535_KILL,SMBHSTTYP); + outb_p(0xFF,SMBHSTSTS); + } else if (temp & ALI1535_STS_ERR) { + /* issue "timeout" to reset all devices on bus */ + outb_p(ALI1535_T_OUT,SMBHSTTYP); + outb_p(0xFF,SMBHSTSTS); + } + + return result; +} + +/* Return -1 on error. */ +static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data) +{ + int i, len; + int temp; + int timeout; + s32 result = 0; + + down(&i2c_ali1535_sem); + /* make sure SMBus is idle */ + temp = inb_p(SMBHSTSTS); + for (timeout = 0; + (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE); + timeout++) { + ali1535_do_pause(1); + temp = inb_p(SMBHSTSTS); + } + if (timeout >= MAX_TIMEOUT) + dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp); + + /* clear status register (clear-on-write) */ + outb_p(0xFF, SMBHSTSTS); + + switch (size) { + case I2C_SMBUS_PROC_CALL: + dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); + result = -1; + goto EXIT; + case I2C_SMBUS_QUICK: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD); + size = ALI1535_QUICK; + outb_p(size, SMBHSTTYP); /* output command */ + break; + case I2C_SMBUS_BYTE: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD); + size = ALI1535_BYTE; + outb_p(size, SMBHSTTYP); /* output command */ + if (read_write == I2C_SMBUS_WRITE) + outb_p(command, SMBHSTCMD); + break; + case I2C_SMBUS_BYTE_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD); + size = ALI1535_BYTE_DATA; + outb_p(size, SMBHSTTYP); /* output command */ + outb_p(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) + outb_p(data->byte, SMBHSTDAT0); + break; + case I2C_SMBUS_WORD_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD); + size = ALI1535_WORD_DATA; + outb_p(size, SMBHSTTYP); /* output command */ + outb_p(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) { + outb_p(data->word & 0xff, SMBHSTDAT0); + outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); + } + break; + case I2C_SMBUS_BLOCK_DATA: + outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), + SMBHSTADD); + size = ALI1535_BLOCK_DATA; + outb_p(size, SMBHSTTYP); /* output command */ + outb_p(command, SMBHSTCMD); + if (read_write == I2C_SMBUS_WRITE) { + len = data->block[0]; + if (len < 0) { + len = 0; + data->block[0] = len; + } + if (len > 32) { + len = 32; + data->block[0] = len; + } + outb_p(len, SMBHSTDAT0); + /* Reset SMBBLKDAT */ + outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP); + for (i = 1; i <= len; i++) + outb_p(data->block[i], SMBBLKDAT); + } + break; + } + + if (ali1535_transaction(adap)) { + /* Error in transaction */ + result = -1; + goto EXIT; + } + + if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) { + result = 0; + goto EXIT; + } + + switch (size) { + case ALI1535_BYTE: /* Result put in SMBHSTDAT0 */ + data->byte = inb_p(SMBHSTDAT0); + break; + case ALI1535_BYTE_DATA: + data->byte = inb_p(SMBHSTDAT0); + break; + case ALI1535_WORD_DATA: + data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); + break; + case ALI1535_BLOCK_DATA: + len = inb_p(SMBHSTDAT0); + if (len > 32) + len = 32; + data->block[0] = len; + /* Reset SMBBLKDAT */ + outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP); + for (i = 1; i <= data->block[0]; i++) { + data->block[i] = inb_p(SMBBLKDAT); + dev_dbg(&adap->dev, "Blk: len=%d, i=%d, data=%02x\n", + len, i, data->block[i]); + } + break; + } +EXIT: + up(&i2c_ali1535_sem); + return result; +} + + +u32 ali1535_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +static struct i2c_algorithm smbus_algorithm = { + .name = "Non-i2c SMBus adapter", + .id = I2C_ALGO_SMBUS, + .smbus_xfer = ali1535_access, + .functionality = ali1535_func, +}; + +static struct i2c_adapter ali1535_adapter = { + .owner = THIS_MODULE, + .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI1535, + .algo = &smbus_algorithm, + .dev = { + .name = "unset", + } +}; + +static struct pci_device_id ali1535_ids[] __devinitdata = { + { + .vendor = PCI_VENDOR_ID_AL, + .device = PCI_DEVICE_ID_AL_M7101, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { }, +}; + +static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + if (ali1535_setup(dev)) { + dev_warn(&dev->dev, + "ALI1535 not detected, module not inserted.\n"); + return -ENODEV; + } + + /* set up the driverfs linkage to our parent device */ + ali1535_adapter.dev.parent = &dev->dev; + + snprintf(ali1535_adapter.dev.name, DEVICE_NAME_SIZE, + "SMBus ALI1535 adapter at %04x", ali1535_smba); + return i2c_add_adapter(&ali1535_adapter); +} + +static void __devexit ali1535_remove(struct pci_dev *dev) +{ + i2c_del_adapter(&ali1535_adapter); +} + +static struct pci_driver ali1535_driver = { + .name = "ali1535_smbus", + .id_table = ali1535_ids, + .probe = ali1535_probe, + .remove = __devexit_p(ali1535_remove), +}; + +static int __init i2c_ali1535_init(void) +{ + printk(KERN_INFO "i2c-ali1535 version %s (%s)\n", I2C_VERSION, I2C_DATE); + return pci_module_init(&ali1535_driver); +} + +static void __exit i2c_ali1535_exit(void) +{ + pci_unregister_driver(&ali1535_driver); + release_region(ali1535_smba, ALI1535_SMB_IOSIZE); +} + +MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " + "Philip Edelbrock <phil@netroedge.com>, " + "Mark D. Studebaker <mdsxyz123@yahoo.com> " + "and Dan Eaton <dan.eaton@rocketlogix.com>"); +MODULE_DESCRIPTION("ALI1535 SMBus driver"); +MODULE_LICENSE("GPL"); + +module_init(i2c_ali1535_init); +module_exit(i2c_ali1535_exit); diff -Nru a/drivers/i2c/i2c-prosavage.c b/drivers/i2c/i2c-prosavage.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/i2c/i2c-prosavage.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,362 @@ +/* + * kernel/busses/i2c-prosavage.c + * + * i2c bus driver for S3/VIA 8365/8375 graphics processor. + * Copyright (c) 2003 Henk Vergonet <henk@god.dyndns.org> + * Based on code written by: + * Frodo Looijaard <frodol@dds.nl>, + * Philip Edelbrock <phil@netroedge.com>, + * Ralph Metzler <rjkm@thp.uni-koeln.de>, and + * Mark D. Studebaker <mdsxyz123@yahoo.com> + * Simon Vogl + * and others + * + * Please read the lm_sensors documentation for details on use. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/* 18-05-2003 HVE - created + * 14-06-2003 HVE - adapted for lm_sensors2 + * 17-06-2003 HVE - linux 2.5.xx compatible + * 18-06-2003 HVE - codingstyle + * 21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx + * codingstyle, mmio enabled + * + * This driver interfaces to the I2C bus of the VIA north bridge embedded + * ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips. + * + * Graphics cores: + * S3/VIA KM266/VT8375 aka ProSavage8 + * S3/VIA KM133/VT8365 aka Savage4 + * + * Two serial busses are implemented: + * SERIAL1 - I2C serial communications interface + * SERIAL2 - DDC2 monitor communications interface + * + * Tested on a FX41 mainboard, see http://www.shuttle.com + * + * + * TODO: + * - integration with prosavage framebuffer device + * (Additional documentation needed :( + */ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> + +#include <asm/io.h> + + +/* + * driver configuration + */ +#define DRIVER_ID "i2c-prosavage" +#define DRIVER_VERSION "20030621" + +/* lm_sensors2 / kernel 2.5.xx compatibility */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define ADAPTER_NAME(x) (x).name +#else +#define ADAPTER_NAME(x) (x).dev.name +#endif /* LINUX_VERSION_CODE */ + +#define MAX_BUSSES 2 + +struct s_i2c_bus { + u8 *mmvga; + int i2c_reg; + int adap_ok; + struct i2c_adapter adap; + struct i2c_algo_bit_data algo; +}; + +struct s_i2c_chip { + u8 *mmio; + struct s_i2c_bus i2c_bus[MAX_BUSSES]; +}; + + +/* + * i2c configuration + */ +#ifndef I2C_HW_B_S3VIA +#define I2C_HW_B_S3VIA 0x18 /* S3VIA ProSavage adapter */ +#endif + +/* delays */ +#define CYCLE_DELAY 10 +#define TIMEOUT (HZ / 2) + + +/* + * S3/VIA 8365/8375 registers + */ +#ifndef PCI_VENDOR_ID_S3 +#define PCI_VENDOR_ID_S3 0x5333 +#endif +#ifndef PCI_DEVICE_ID_S3_SAVAGE4 +#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25 +#endif +#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8 +#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04 +#endif + +#define VGA_CR_IX 0x3d4 +#define VGA_CR_DATA 0x3d5 + +#define CR_SERIAL1 0xa0 /* I2C serial communications interface */ +#define MM_SERIAL1 0xff20 +#define CR_SERIAL2 0xb1 /* DDC2 monitor communications interface */ + +/* based on vt8365 documentation */ +#define I2C_ENAB 0x10 +#define I2C_SCL_OUT 0x01 +#define I2C_SDA_OUT 0x02 +#define I2C_SCL_IN 0x04 +#define I2C_SDA_IN 0x08 + +#define SET_CR_IX(p, val) *((p)->mmvga + VGA_CR_IX) = (u8)(val) +#define SET_CR_DATA(p, val) *((p)->mmvga + VGA_CR_DATA) = (u8)(val) +#define GET_CR_DATA(p) *((p)->mmvga + VGA_CR_DATA) + + +/* + * Serial bus line handling + * + * serial communications register as parameter in private data + * + * TODO: locks with other code sections accessing video registers? + */ +static void bit_s3via_setscl(void *bus, int val) +{ + struct s_i2c_bus *p = (struct s_i2c_bus *)bus; + unsigned int r; + + SET_CR_IX(p, p->i2c_reg); + r = GET_CR_DATA(p); + r |= I2C_ENAB; + if (val) { + r |= I2C_SCL_OUT; + } else { + r &= ~I2C_SCL_OUT; + } + SET_CR_DATA(p, r); +} + +static void bit_s3via_setsda(void *bus, int val) +{ + struct s_i2c_bus *p = (struct s_i2c_bus *)bus; + unsigned int r; + + SET_CR_IX(p, p->i2c_reg); + r = GET_CR_DATA(p); + r |= I2C_ENAB; + if (val) { + r |= I2C_SDA_OUT; + } else { + r &= ~I2C_SDA_OUT; + } + SET_CR_DATA(p, r); +} + +static int bit_s3via_getscl(void *bus) +{ + struct s_i2c_bus *p = (struct s_i2c_bus *)bus; + + SET_CR_IX(p, p->i2c_reg); + return (0 != (GET_CR_DATA(p) & I2C_SCL_IN)); +} + +static int bit_s3via_getsda(void *bus) +{ + struct s_i2c_bus *p = (struct s_i2c_bus *)bus; + + SET_CR_IX(p, p->i2c_reg); + return (0 != (GET_CR_DATA(p) & I2C_SDA_IN)); +} + + +/* + * adapter initialisation + */ +static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg) +{ + int ret; + p->adap.owner = THIS_MODULE; + p->adap.id = I2C_HW_B_S3VIA; + p->adap.algo_data = &p->algo; + p->algo.setsda = bit_s3via_setsda; + p->algo.setscl = bit_s3via_setscl; + p->algo.getsda = bit_s3via_getsda; + p->algo.getscl = bit_s3via_getscl; + p->algo.udelay = CYCLE_DELAY; + p->algo.mdelay = CYCLE_DELAY; + p->algo.timeout = TIMEOUT; + p->algo.data = p; + p->mmvga = mmvga; + p->i2c_reg = i2c_reg; + + ret = i2c_bit_add_bus(&p->adap); + if (ret) { + return ret; + } + + p->adap_ok = 1; + return 0; +} + + +/* + * Cleanup stuff + */ +static void __devexit prosavage_remove(struct pci_dev *dev) +{ + struct s_i2c_chip *chip; + int i, ret; + + chip = (struct s_i2c_chip *)pci_get_drvdata(dev); + + if (!chip) { + return; + } + for (i = MAX_BUSSES - 1; i >= 0; i--) { + if (chip->i2c_bus[i].adap_ok == 0) + continue; + + ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap); + if (ret) { + printk(DRIVER_ID ": %s not removed\n", + ADAPTER_NAME(chip->i2c_bus[i].adap)); + } + } + if (chip->mmio) { + iounmap(chip->mmio); + } + kfree(chip); +} + + +/* + * Detect chip and initialize it + */ +static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int ret; + unsigned long base, len; + struct s_i2c_chip *chip; + struct s_i2c_bus *bus; + + pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); + chip = (struct s_i2c_chip *)pci_get_drvdata(dev); + if (chip == NULL) { + return -ENOMEM; + } + + memset(chip, 0, sizeof(struct s_i2c_chip)); + + base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK; + len = dev->resource[0].end - base + 1; + chip->mmio = ioremap_nocache(base, len); + + if (chip->mmio == NULL) { + printk (DRIVER_ID ": ioremap failed\n"); + prosavage_remove(dev); + return -ENODEV; + } + + + /* + * Chip initialisation + */ + /* Unlock Extended IO Space ??? */ + + + /* + * i2c bus registration + */ + bus = &chip->i2c_bus[0]; + snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)), + "ProSavage I2C bus at %02x:%02x.%x", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1); + if (ret) { + goto err_adap; + } + /* + * ddc bus registration + */ + bus = &chip->i2c_bus[1]; + snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)), + "ProSavage DDC bus at %02x:%02x.%x", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2); + if (ret) { + goto err_adap; + } + return 0; +err_adap: + printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap)); + prosavage_remove(dev); + return ret; +} + + +/* + * Data for PCI driver interface + */ +static struct pci_device_id prosavage_pci_tbl[] __devinitdata = { + { + .vendor = PCI_VENDOR_ID_S3, + .device = PCI_DEVICE_ID_S3_SAVAGE4, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + },{ + .vendor = PCI_VENDOR_ID_S3, + .device = PCI_DEVICE_ID_S3_PROSAVAGE8, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + },{ 0, } +}; + +static struct pci_driver prosavage_driver = { + .name = "prosavage-smbus", + .id_table = prosavage_pci_tbl, + .probe = prosavage_probe, + .remove = __devexit_p(prosavage_remove), +}; + +static int __init i2c_prosavage_init(void) +{ + printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION); + return pci_module_init(&prosavage_driver); +} + +static void __exit i2c_prosavage_exit(void) +{ + pci_unregister_driver(&prosavage_driver); +} + +MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl); +MODULE_AUTHOR("Henk Vergonet"); +MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver"); +MODULE_LICENSE("GPL"); + +module_init (i2c_prosavage_init); +module_exit (i2c_prosavage_exit); diff -Nru a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c --- a/drivers/ide/ide-dma.c Fri Jun 27 14:19:56 2003 +++ b/drivers/ide/ide-dma.c Fri Jun 27 14:19:56 2003 @@ -248,8 +248,11 @@ #if 1 if (sector_count > 256) BUG(); - + if (sector_count > 128) { +#else + while (sector_count > 128) { +#endif memset(&sg[nents], 0, sizeof(*sg)); sg[nents].page = virt_to_page(virt_addr); sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; @@ -263,22 +266,7 @@ sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; sg[nents].length = sector_count * SECTOR_SIZE; nents++; -#else - while (sector_count > 128) { - memset(&sg[nents], 0, sizeof(*sg)); - sg[nents].address = virt_to_page(virt_addr); - sg[nents].offset = (unsigned long)virt_addr & ~PAGE_MASK; - sg[nents].length = 128 * SECTOR_SIZE; - nents++; - virt_addr = virt_addr + (128 * SECTOR_SIZE); - sector_count -= 128; - }; - memset(&sg[nents], 0, sizeof(*sg)); - sg[nents].page = virt_to_page(virt_addr); - sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK; - sg[nents].length = sector_count * SECTOR_SIZE; - nents++; -#endif + return pci_map_sg(hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } @@ -523,8 +511,7 @@ if (HWIF(drive)->ide_dma_host_off(drive)) return 1; - if (drive->queue_setup) - HWIF(drive)->ide_dma_queued_off(drive); + HWIF(drive)->ide_dma_queued_off(drive); return 0; } @@ -585,8 +572,9 @@ if (HWIF(drive)->ide_dma_host_on(drive)) return 1; - if (drive->queue_setup) - HWIF(drive)->ide_dma_queued_on(drive); +#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT + HWIF(drive)->ide_dma_queued_on(drive); +#endif return 0; } diff -Nru a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c --- a/drivers/ide/ide-io.c Fri Jun 27 14:20:00 2003 +++ b/drivers/ide/ide-io.c Fri Jun 27 14:20:00 2003 @@ -1264,7 +1264,7 @@ #endif /* CONFIG_BLK_DEV_IDEPCI */ } spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_HANDLED; + return IRQ_NONE; } drive = hwgroup->drive; if (!drive) { @@ -1286,7 +1286,7 @@ * enough advance overhead that the latter isn't a problem. */ spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_HANDLED; + return IRQ_NONE; } if (!hwgroup->busy) { hwgroup->busy = 1; /* paranoia */ diff -Nru a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c --- a/drivers/ide/ide-pnp.c Fri Jun 27 14:19:58 2003 +++ b/drivers/ide/ide-pnp.c Fri Jun 27 14:19:58 2003 @@ -4,7 +4,7 @@ * This file provides autodetection for ISA PnP IDE interfaces. * It was tested with "ESS ES1868 Plug and Play AudioDrive" IDE interface. * - * Copyright (C) 2000 Andrey Panin <pazke@orbita.don.sitek.net> + * Copyright (C) 2000 Andrey Panin <pazke@donpac.ru> * * 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 diff -Nru a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c --- a/drivers/ide/ide-probe.c Fri Jun 27 14:19:57 2003 +++ b/drivers/ide/ide-probe.c Fri Jun 27 14:19:57 2003 @@ -634,64 +634,8 @@ return drive->present; } -static int hwif_check_region(ide_hwif_t *hwif, unsigned long addr, int num) -{ - int err; - - if(hwif->mmio) - err = check_mem_region(addr, num); - else - err = check_region(addr, num); - - if(err) - { - printk("%s: %s resource 0x%lX-0x%lX not free.\n", - hwif->name, hwif->mmio?"MMIO":"I/O", addr, addr+num-1); - } - return err; -} - - -/** - * hwif_check_regions - check resources for IDE - * @hwif: interface to use - * - * Checks if all the needed resources for an interface are free - * providing the interface is PIO. Right now core IDE code does - * this work which is deeply wrong. MMIO leaves it to the controller - * driver, PIO will migrate this way over time - */ - -static int hwif_check_regions (ide_hwif_t *hwif) -{ - u32 i = 0; - int addr_errs = 0; - - if (hwif->mmio == 2) - return 0; - addr_errs = hwif_check_region(hwif, hwif->io_ports[IDE_DATA_OFFSET], 1); - for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; i++) - addr_errs += hwif_check_region(hwif, hwif->io_ports[i], 1); - if (hwif->io_ports[IDE_CONTROL_OFFSET]) - addr_errs += hwif_check_region(hwif, hwif->io_ports[IDE_CONTROL_OFFSET], 1); -#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) - if (hwif->io_ports[IDE_IRQ_OFFSET]) - addr_errs += hwif_check_region(hwif, hwif->io_ports[IDE_IRQ_OFFSET], 1); -#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ - /* If any errors are return, we drop the hwif interface. */ - hwif->straight8 = 0; - return(addr_errs); -} - -//EXPORT_SYMBOL(hwif_check_regions); - -#define hwif_request_region(addr, num, name) \ - ((hwif->mmio) ? request_mem_region((addr),(num),(name)) : request_region((addr),(num),(name))) - static void hwif_register (ide_hwif_t *hwif) { - u32 i = 0; - /* register with global device tree */ strlcpy(hwif->gendev.bus_id,hwif->name,BUS_ID_SIZE); snprintf(hwif->gendev.name,DEVICE_NAME_SIZE,"IDE Controller"); @@ -701,24 +645,6 @@ else hwif->gendev.parent = NULL; /* Would like to do = &device_legacy */ device_register(&hwif->gendev); - - if (hwif->mmio == 2) - return; - if (hwif->io_ports[IDE_CONTROL_OFFSET]) - hwif_request_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1, hwif->name); -#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) - if (hwif->io_ports[IDE_IRQ_OFFSET]) - hwif_request_region(hwif->io_ports[IDE_IRQ_OFFSET], 1, hwif->name); -#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ - if (((unsigned long)hwif->io_ports[IDE_DATA_OFFSET] | 7) == - ((unsigned long)hwif->io_ports[IDE_STATUS_OFFSET])) { - hwif_request_region(hwif->io_ports[IDE_DATA_OFFSET], 8, hwif->name); - hwif->straight8 = 1; - return; - } - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hwif_request_region(hwif->io_ports[i], 1, hwif->name); } //EXPORT_SYMBOL(hwif_register); @@ -778,7 +704,7 @@ #ifdef CONFIG_BLK_DEV_PDC4030 (hwif->chipset != ide_pdc4030 || hwif->channel == 0) && #endif /* CONFIG_BLK_DEV_PDC4030 */ - (hwif_check_regions(hwif))) { + (ide_hwif_request_regions(hwif))) { u16 msgout = 0; for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; @@ -869,6 +795,11 @@ if (irqd) enable_irq(irqd); + if (!hwif->present) { + ide_hwif_release_regions(hwif); + return; + } + for (unit = 0; unit < MAX_DRIVES; ++unit) { ide_drive_t *drive = &hwif->drives[unit]; int enable_dma = 1; @@ -983,7 +914,6 @@ blk_init_queue(q, do_ide_request, &ide_lock); q->queuedata = HWGROUP(drive); - drive->queue_setup = 1; blk_queue_segment_boundary(q, 0xffff); if (!hwif->rqsize) @@ -1005,10 +935,6 @@ static void ide_init_drive(ide_drive_t *drive) { ide_toggle_bounce(drive, 1); - -#ifdef CONFIG_BLK_DEV_IDE_TCQ_DEFAULT - HWIF(drive)->ide_dma_queued_on(drive); -#endif } /* diff -Nru a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c --- a/drivers/ide/ide-taskfile.c Fri Jun 27 14:19:52 2003 +++ b/drivers/ide/ide-taskfile.c Fri Jun 27 14:19:52 2003 @@ -954,6 +954,9 @@ return startstop; } + if (!drive->unmask) + local_irq_disable(); + return task_out_intr(drive); } EXPORT_SYMBOL(pre_task_out_intr); @@ -1030,6 +1033,9 @@ return startstop; } + if (!drive->unmask) + local_irq_disable(); + return task_mulout_intr(drive); } EXPORT_SYMBOL(pre_task_mulout_intr); @@ -1361,8 +1367,6 @@ EXPORT_SYMBOL(ide_init_drive_taskfile); -#if 1 - int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) { struct request rq; @@ -1400,69 +1404,6 @@ rq.special = args; return ide_do_drive_cmd(drive, &rq, ide_wait); } - -#else - -int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) -{ - struct request *rq; - unsigned long flags; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - struct list_head *queue_head = &drive->queue.queue_head; - DECLARE_COMPLETION(wait); - - if (HWIF(drive)->chipset == ide_pdc4030 && buf != NULL) - return -ENOSYS; /* special drive cmds not supported */ - - memset(rq, 0, sizeof(*rq)); - rq->flags = REQ_DRIVE_TASKFILE; - rq->buffer = buf; - - /* - * (ks) We transfer currently only whole sectors. - * This is suffient for now. But, it would be great, - * if we would find a solution to transfer any size. - * To support special commands like READ LONG. - */ - if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { - if (data_size == 0) { - ata_nsector_t nsector; - nsector.b.low = args->hobRegister[IDE_NSECTOR_OFFSET_HOB]; - nsector.b.high = args->tfRegister[IDE_NSECTOR_OFFSET]; - rq.nr_sectors = nsector.all; - } else { - rq.nr_sectors = data_size / SECTOR_SIZE; - } - rq.current_nr_sectors = rq.nr_sectors; - // rq.hard_cur_sectors = rq.nr_sectors; - } - - if (args->tf_out_flags.all == 0) { - /* - * clean up kernel settings for driver sanity, regardless. - * except for discrete diag services. - */ - args->posthandler = ide_post_handler_parser( - (struct hd_drive_task_hdr *) args->tfRegister, - (struct hd_drive_hob_hdr *) args->hobRegister); - } - rq->special = args; - rq->errors = 0; - rq->rq_status = RQ_ACTIVE; - rq->rq_disk = drive->disk; - rq->waiting = &wait; - - spin_lock_irqsave(&ide_lock, flags); - queue_head = queue_head->prev; - list_add(&rq->queue, queue_head); - ide_do_request(hwgroup, 0); - spin_unlock_irqrestore(&ide_lock, flags); - - wait_for_completion(&wait); /* wait for it to be serviced */ - return rq->errors ? -EIO : 0; /* return -EIO if errors */ -} - -#endif EXPORT_SYMBOL(ide_diag_taskfile); diff -Nru a/drivers/ide/ide-tcq.c b/drivers/ide/ide-tcq.c --- a/drivers/ide/ide-tcq.c Fri Jun 27 14:20:06 2003 +++ b/drivers/ide/ide-tcq.c Fri Jun 27 14:20:06 2003 @@ -501,8 +501,10 @@ * bit 14 and 1 must be set in word 83 of the device id to indicate * support for dma queued protocol, and bit 15 must be cleared */ - if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask) + if ((drive->id->command_set_2 & tcq_bits) ^ tcq_mask) { + printk(KERN_INFO "%s: TCQ not supported\n", drive->name); return -EIO; + } args = kmalloc(sizeof(*args), GFP_ATOMIC); if (!args) @@ -655,21 +657,24 @@ int __ide_dma_queued_on(ide_drive_t *drive) { + ide_hwif_t *hwif = HWIF(drive); + + if (drive->media != ide_disk) + return 1; if (!drive->using_dma) return 1; - if (HWIF(drive)->chipset == ide_pdc4030) + if (hwif->chipset == ide_pdc4030) return 1; if (ide_tcq_check_blacklist(drive)) { printk(KERN_WARNING "%s: tcq forbidden by blacklist\n", drive->name); return 1; } - if (drive->next != drive) { + if (hwif->drives[0].present && hwif->drives[1].present) { printk(KERN_WARNING "%s: only one drive on a channel supported" " for tcq\n", drive->name); return 1; } - if (ata_pending_commands(drive)) { printk(KERN_WARNING "ide-tcq; can't toggle tcq feature on " "busy drive\n"); @@ -681,6 +686,8 @@ int __ide_dma_queued_off(ide_drive_t *drive) { + if (drive->media != ide_disk) + return 1; if (ata_pending_commands(drive)) { printk("ide-tcq; can't toggle tcq feature on busy drive\n"); return 1; diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c --- a/drivers/ide/ide.c Fri Jun 27 14:19:54 2003 +++ b/drivers/ide/ide.c Fri Jun 27 14:19:54 2003 @@ -216,7 +216,7 @@ EXPORT_SYMBOL(idescsi); extern ide_driver_t idedefault_driver; -static void setup_driver_defaults (ide_drive_t *drive); +static void setup_driver_defaults(ide_driver_t *driver); /* * Do not even *think* about calling this! @@ -275,7 +275,6 @@ drive->using_dma = 0; drive->is_flash = 0; drive->driver = &idedefault_driver; - setup_driver_defaults(drive); drive->vdma = 0; INIT_LIST_HEAD(&drive->list); } @@ -308,6 +307,8 @@ return; /* already initialized */ magic_cookie = 0; + setup_driver_defaults(&idedefault_driver); + /* Initialise all interface structures */ for (index = 0; index < MAX_HWIFS; ++index) init_hwif_data(index); @@ -507,12 +508,87 @@ }; #endif +static struct resource* hwif_request_region(ide_hwif_t *hwif, + unsigned long addr, int num) +{ + struct resource *res; + + if (hwif->mmio) + res = request_mem_region(addr, num, hwif->name); + else + res = request_region(addr, num, hwif->name); + + if (!res) + printk(KERN_ERR "%s: %s resource 0x%lX-0x%lX not free.\n", + hwif->name, hwif->mmio ? "MMIO" : "I/O", + addr, addr+num-1); + return res; +} #define hwif_release_region(addr, num) \ ((hwif->mmio) ? release_mem_region((addr),(num)) : release_region((addr),(num))) /** - * hwif_unregister - free IDE resources + * ide_hwif_request_regions - request resources for IDE + * @hwif: interface to use + * + * Requests all the needed resources for an interface. + * Right now core IDE code does this work which is deeply wrong. + * MMIO leaves it to the controller driver, + * PIO will migrate this way over time. + */ +int ide_hwif_request_regions(ide_hwif_t *hwif) +{ + unsigned long addr; + unsigned int i; + + if (hwif->mmio == 2) + return 0; + addr = hwif->io_ports[IDE_CONTROL_OFFSET]; + if (addr && !hwif_request_region(hwif, addr, 1)) + goto control_region_busy; +#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) + addr = hwif->io_ports[IDE_IRQ_OFFSET]; + if (addr && !hwif_request_region(hwif, addr, 1)) + goto irq_region_busy; +#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ + hwif->straight8 = 0; + addr = hwif->io_ports[IDE_DATA_OFFSET]; + if ((addr | 7) == hwif->io_ports[IDE_STATUS_OFFSET]) { + if (!hwif_request_region(hwif, addr, 8)) + goto data_region_busy; + hwif->straight8 = 1; + return 0; + } + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + addr = hwif->io_ports[i]; + if (!hwif_request_region(hwif, addr, 1)) { + while (--i) + hwif_release_region(addr, 1); + goto data_region_busy; + } + } + return 0; + +data_region_busy: +#if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) + addr = hwif->io_ports[IDE_IRQ_OFFSET]; + if (addr) + hwif_release_region(addr, 1); +irq_region_busy: +#endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ + addr = hwif->io_ports[IDE_CONTROL_OFFSET]; + if (addr) + hwif_release_region(addr, 1); +control_region_busy: + /* If any errors are return, we drop the hwif interface. */ + return -EBUSY; +} + +EXPORT_SYMBOL(ide_hwif_request_regions); + +/** + * ide_hwif_release_regions - free IDE resources * * Note that we only release the standard ports, * and do not even try to handle any extra ports @@ -522,8 +598,7 @@ * importantly our caller should be doing this so we need to * restructure this as a helper function for drivers. */ - -void hwif_unregister (ide_hwif_t *hwif) +void ide_hwif_release_regions(ide_hwif_t *hwif) { u32 i = 0; @@ -547,7 +622,7 @@ } } -EXPORT_SYMBOL(hwif_unregister); +EXPORT_SYMBOL(ide_hwif_release_regions); extern void init_hwif_data(unsigned int index); @@ -634,7 +709,7 @@ * and do not even try to handle any extra ports * allocated for weird IDE interface chipsets. */ - hwif_unregister(hwif); + ide_hwif_release_regions(hwif); /* * Remove us from the hwgroup, and free @@ -673,8 +748,8 @@ blk_cleanup_queue(&drive->queue); } if (hwif->next == hwif) { - kfree(hwgroup); BUG_ON(hwgroup->hwif != hwif); + kfree(hwgroup); } else { /* There is another interface in hwgroup. * Unlink us, and set hwgroup->drive and ->hwif to @@ -1134,13 +1209,12 @@ * * Automatically remove all the driver specific settings for this * drive. This function may sleep and must not be called from IRQ - * context. Takes the settings_lock + * context. The caller must hold ide_setting_sem. */ static void auto_remove_settings (ide_drive_t *drive) { ide_settings_t *setting; - down(&ide_setting_sem); repeat: setting = drive->settings; while (setting) { @@ -1150,7 +1224,6 @@ } setting = setting->next; } - up(&ide_setting_sem); } /** @@ -2099,10 +2172,9 @@ #ifdef CONFIG_BLK_DEV_IDEPCI hwif->udma_four = 1; goto done; -#else /* !CONFIG_BLK_DEV_IDEPCI */ - hwif->udma_four = 0; +#else goto bad_hwif; -#endif /* CONFIG_BLK_DEV_IDEPCI */ +#endif case -6: /* dma */ hwif->autodma = 1; goto done; @@ -2346,10 +2418,8 @@ return ide_abort(drive, msg); } -static void setup_driver_defaults (ide_drive_t *drive) +static void setup_driver_defaults (ide_driver_t *d) { - ide_driver_t *d = drive->driver; - if (d->cleanup == NULL) d->cleanup = default_cleanup; if (d->shutdown == NULL) d->shutdown = default_shutdown; if (d->flushcache == NULL) d->flushcache = default_flushcache; @@ -2377,7 +2447,6 @@ return 1; } drive->driver = driver; - setup_driver_defaults(drive); spin_unlock_irqrestore(&ide_lock, flags); spin_lock(&drives_lock); list_add_tail(&drive->list, &driver->drives); @@ -2408,9 +2477,11 @@ { unsigned long flags; + down(&ide_setting_sem); spin_lock_irqsave(&ide_lock, flags); if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) { spin_unlock_irqrestore(&ide_lock, flags); + up(&ide_setting_sem); return 1; } #if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP) && defined(MODULE) @@ -2422,8 +2493,8 @@ #endif auto_remove_settings(drive); drive->driver = &idedefault_driver; - setup_driver_defaults(drive); spin_unlock_irqrestore(&ide_lock, flags); + up(&ide_setting_sem); spin_lock(&drives_lock); list_del_init(&drive->list); spin_unlock(&drives_lock); @@ -2446,6 +2517,8 @@ struct list_head *list_loop; struct list_head *tmp_storage; + setup_driver_defaults(driver); + spin_lock(&drivers_lock); list_add(&driver->drivers, &drivers); spin_unlock(&drivers_lock); @@ -2520,13 +2593,9 @@ */ int __init ide_init (void) { - static char banner_printed; - if (!banner_printed) { - printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); - devfs_mk_dir("ide"); - system_bus_speed = ide_system_bus_speed(); - banner_printed = 1; - } + printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n"); + devfs_mk_dir("ide"); + system_bus_speed = ide_system_bus_speed(); bus_register(&ide_bus_type); diff -Nru a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c --- a/drivers/ide/legacy/ide-cs.c Fri Jun 27 14:19:59 2003 +++ b/drivers/ide/legacy/ide-cs.c Fri Jun 27 14:19:59 2003 @@ -473,7 +473,7 @@ static struct pcmcia_driver ide_cs_driver = { .owner = THIS_MODULE, .drv = { - .name = "ide_cs", + .name = "ide-cs", }, .attach = ide_attach, .detach = ide_detach, diff -Nru a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c --- a/drivers/ide/legacy/pdc4030.c Fri Jun 27 14:19:56 2003 +++ b/drivers/ide/legacy/pdc4030.c Fri Jun 27 14:19:56 2003 @@ -613,8 +613,6 @@ */ taskfile_output_data(drive, buffer, nsect<<7); } while (mcount); - - return 0; } #endif @@ -624,7 +622,9 @@ static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive) { ide_hwgroup_t *hwgroup = HWGROUP(drive); +#ifdef CONFIG_IDE_TASKFILE_IO struct request *rq = hwgroup->rq; +#endif if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) { if (time_before(jiffies, hwgroup->poll_timeout)) { @@ -818,7 +818,8 @@ Feature register. FIXME: Is promise_selectproc now redundant?? */ - int drive_number = (HWIF(drive)->channel << 1) + drive->select.b.unit; + ide_hwif_t *hwif = HWIF(drive); + int drive_number = (hwif->channel << 1) + drive->select.b.unit; #ifdef CONFIG_IDE_TASKFILE_IO struct hd_drive_task_hdr taskfile; ide_task_t args; diff -Nru a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c --- a/drivers/ide/pci/sc1200.c Fri Jun 27 14:19:58 2003 +++ b/drivers/ide/pci/sc1200.c Fri Jun 27 14:19:58 2003 @@ -32,17 +32,6 @@ #include "ide_modes.h" #include "sc1200.h" -#define DISPLAY_SC1200_TIMINGS - -#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS) -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static int sc1200_get_info(char *, char **, off_t, int); -extern int (*sc1200_display_info)(char *, char **, off_t, int); /* ide-proc.c */ -extern char *ide_media_verbose(ide_drive_t *); -static u8 sc1200_proc = 0; - #define SC1200_REV_A 0x00 #define SC1200_REV_B1 0x01 #define SC1200_REV_B3 0x02 @@ -80,6 +69,17 @@ } return pci_clock; } + +#define DISPLAY_SC1200_TIMINGS + +#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS) +#include <linux/stat.h> +#include <linux/proc_fs.h> + +static int sc1200_get_info(char *, char **, off_t, int); +extern int (*sc1200_display_info)(char *, char **, off_t, int); /* ide-proc.c */ +extern char *ide_media_verbose(ide_drive_t *); +static u8 sc1200_proc = 0; static struct pci_dev *bmide_dev; diff -Nru a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile --- a/drivers/ieee1394/Makefile Fri Jun 27 14:20:05 2003 +++ b/drivers/ieee1394/Makefile Fri Jun 27 14:20:05 2003 @@ -18,6 +18,9 @@ clean-files := oui.c +quiet_cmd_oui2c = OUI2C $@ + cmd_oui2c = $(CONFIG_SHELL) $(obj)/oui2c.sh < $(obj)/oui.db > $@ + $(obj)/oui.o: $(obj)/oui.c $(obj)/oui.c: $(obj)/oui.db $(obj)/oui2c.sh - $(CONFIG_SHELL) $(obj)/oui2c.sh < $(obj)/oui.db > $@ + $(call if_changed,oui2c) diff -Nru a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c --- a/drivers/ieee1394/amdtp.c Fri Jun 27 14:19:58 2003 +++ b/drivers/ieee1394/amdtp.c Fri Jun 27 14:19:58 2003 @@ -732,7 +732,7 @@ /* Fill IEEE1394 headers */ packet->db->header_desc.header[0] = - (SPEED_100 << 16) | (0x01 << 14) | + (IEEE1394_SPEED_100 << 16) | (0x01 << 14) | (s->iso_channel << 8) | (TCODE_ISO_DATA << 4); packet->db->header_desc.header[1] = size << 16; diff -Nru a/drivers/ieee1394/cmp.c b/drivers/ieee1394/cmp.c --- a/drivers/ieee1394/cmp.c Fri Jun 27 14:19:59 2003 +++ b/drivers/ieee1394/cmp.c Fri Jun 27 14:19:59 2003 @@ -138,7 +138,7 @@ } ch->host = host; - ch->u.ompr.rate = SPEED_100; + ch->u.ompr.rate = IEEE1394_SPEED_100; ch->u.ompr.bcast_channel_base = 63; ch->u.ompr.nplugs = 2; diff -Nru a/drivers/ieee1394/csr.h b/drivers/ieee1394/csr.h --- a/drivers/ieee1394/csr.h Fri Jun 27 14:19:52 2003 +++ b/drivers/ieee1394/csr.h Fri Jun 27 14:19:52 2003 @@ -2,6 +2,10 @@ #ifndef _IEEE1394_CSR_H #define _IEEE1394_CSR_H +#ifdef CONFIG_PREEMPT +#include <linux/sched.h> +#endif + #define CSR_REGISTER_BASE 0xfffff0000000ULL /* register offsets relative to CSR_REGISTER_BASE */ diff -Nru a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c --- a/drivers/ieee1394/dma.c Fri Jun 27 14:19:57 2003 +++ b/drivers/ieee1394/dma.c Fri Jun 27 14:19:57 2003 @@ -31,7 +31,7 @@ prog->n_pages = n_bytes / PAGE_SIZE; prog->kvirt = pci_alloc_consistent(dev, prog->n_pages * PAGE_SIZE, &prog->bus_addr); - if(!prog->kvirt) { + if (!prog->kvirt) { printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n"); dma_prog_region_free(prog); return -ENOMEM; @@ -44,7 +44,7 @@ void dma_prog_region_free(struct dma_prog_region *prog) { - if(prog->kvirt) { + if (prog->kvirt) { pci_free_consistent(prog->dev, prog->n_pages * PAGE_SIZE, prog->kvirt, prog->bus_addr); } @@ -75,7 +75,7 @@ n_pages = n_bytes / PAGE_SIZE; dma->kvirt = vmalloc_32(n_pages * PAGE_SIZE); - if(!dma->kvirt) { + if (!dma->kvirt) { printk(KERN_ERR "dma_region_alloc: vmalloc_32() failed\n"); goto err; } @@ -87,7 +87,7 @@ /* allocate scatter/gather list */ dma->sglist = kmalloc(dma->n_pages * sizeof(struct scatterlist), GFP_KERNEL); - if(!dma->sglist) { + if (!dma->sglist) { printk(KERN_ERR "dma_region_alloc: kmalloc(sglist) failed\n"); goto err; } @@ -96,7 +96,7 @@ memset(dma->sglist, 0, dma->n_pages * sizeof(struct scatterlist)); /* fill scatter/gather list with pages */ - for(i = 0; i < dma->n_pages; i++) { + for (i = 0; i < dma->n_pages; i++) { unsigned long va = (unsigned long) dma->kvirt + i * PAGE_SIZE; dma->sglist[i].page = vmalloc_to_page((void *)va); @@ -106,7 +106,7 @@ /* map sglist to the IOMMU */ dma->n_dma_pages = pci_map_sg(dev, &dma->sglist[0], dma->n_pages, direction); - if(dma->n_dma_pages == 0) { + if (dma->n_dma_pages == 0) { printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n"); goto err; } @@ -123,18 +123,18 @@ void dma_region_free(struct dma_region *dma) { - if(dma->n_dma_pages) { + if (dma->n_dma_pages) { pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction); dma->n_dma_pages = 0; dma->dev = NULL; } - if(dma->sglist) { + if (dma->sglist) { kfree(dma->sglist); dma->sglist = NULL; } - if(dma->kvirt) { + if (dma->kvirt) { vfree(dma->kvirt); dma->kvirt = NULL; dma->n_pages = 0; @@ -148,8 +148,8 @@ int i; unsigned long off = offset; - for(i = 0; i < dma->n_dma_pages; i++) { - if(off < sg_dma_len(&dma->sglist[i])) { + for (i = 0; i < dma->n_dma_pages; i++) { + if (off < sg_dma_len(&dma->sglist[i])) { *rem = off; return i; } @@ -173,7 +173,7 @@ int first, last; unsigned long rem; - if(!len) + if (!len) len = 1; first = dma_region_find(dma, offset, &rem); @@ -193,10 +193,10 @@ struct dma_region *dma = (struct dma_region*) area->vm_private_data; - if(!dma->kvirt) + if (!dma->kvirt) goto out; - if( (address < (unsigned long) area->vm_start) || + if ( (address < (unsigned long) area->vm_start) || (address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) ) goto out; @@ -216,16 +216,16 @@ { unsigned long size; - if(!dma->kvirt) + if (!dma->kvirt) return -EINVAL; /* must be page-aligned */ - if(vma->vm_pgoff != 0) + if (vma->vm_pgoff != 0) return -EINVAL; /* check the length */ size = vma->vm_end - vma->vm_start; - if(size > (PAGE_SIZE * dma->n_pages)) + if (size > (PAGE_SIZE * dma->n_pages)) return -EINVAL; vma->vm_ops = &dma_region_vm_ops; diff -Nru a/drivers/ieee1394/dma.h b/drivers/ieee1394/dma.h --- a/drivers/ieee1394/dma.h Fri Jun 27 14:20:01 2003 +++ b/drivers/ieee1394/dma.h Fri Jun 27 14:20:01 2003 @@ -76,7 +76,7 @@ /* round up a number of bytes to be a multiple of the PAGE_SIZE */ static inline unsigned long round_up_to_page(unsigned long len) { - if(len % PAGE_SIZE) + if (len % PAGE_SIZE) len += PAGE_SIZE - (len % PAGE_SIZE); return len; } diff -Nru a/drivers/ieee1394/dv1394-private.h b/drivers/ieee1394/dv1394-private.h --- a/drivers/ieee1394/dv1394-private.h Fri Jun 27 14:19:58 2003 +++ b/drivers/ieee1394/dv1394-private.h Fri Jun 27 14:19:58 2003 @@ -97,7 +97,7 @@ omi->q[3] = 0; /* IT packet header */ - omi->q[4] = cpu_to_le32( (0x0 << 16) /* DMA_SPEED_100 */ + omi->q[4] = cpu_to_le32( (0x0 << 16) /* IEEE1394_SPEED_100 */ | (tag << 14) | (channel << 8) | (TCODE_ISO_DATA << 4) @@ -129,10 +129,10 @@ u32 temp = 0; temp |= 1 << 28; /* OUTPUT_LAST */ - if(want_timestamp) /* controller will update timestamp at DMA time */ + if (want_timestamp) /* controller will update timestamp at DMA time */ temp |= 1 << 27; - if(want_interrupt) + if (want_interrupt) temp |= 3 << 20; temp |= 3 << 18; /* must take branch */ diff -Nru a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c --- a/drivers/ieee1394/dv1394.c Fri Jun 27 14:19:59 2003 +++ b/drivers/ieee1394/dv1394.c Fri Jun 27 14:19:59 2003 @@ -201,14 +201,14 @@ static struct frame* frame_new(unsigned int frame_num, struct video_card *video) { struct frame *f = kmalloc(sizeof(*f), GFP_KERNEL); - if(!f) + if (!f) return NULL; f->video = video; f->frame_num = frame_num; f->header_pool = pci_alloc_consistent(f->video->ohci->dev, PAGE_SIZE, &f->header_pool_dma); - if(!f->header_pool) { + if (!f->header_pool) { printk(KERN_ERR "dv1394: failed to allocate CIP header pool\n"); kfree(f); return NULL; @@ -224,7 +224,7 @@ f->descriptor_pool = pci_alloc_consistent(f->video->ohci->dev, f->descriptor_pool_size, &f->descriptor_pool_dma); - if(!f->descriptor_pool) { + if (!f->descriptor_pool) { pci_free_consistent(f->video->ohci->dev, PAGE_SIZE, f->header_pool, f->header_pool_dma); kfree(f); return NULL; @@ -284,12 +284,12 @@ - if(video->pal_or_ntsc == DV1394_PAL) + if (video->pal_or_ntsc == DV1394_PAL) packets_per_frame = DV1394_PAL_PACKETS_PER_FRAME; else packets_per_frame = DV1394_NTSC_PACKETS_PER_FRAME; - while( full_packets < packets_per_frame ) { + while ( full_packets < packets_per_frame ) { empty_packet = first_packet = last_packet = mid_packet = 0; data_p = f->data + full_packets * 480; @@ -300,7 +300,7 @@ /* note: these should NOT cross a page boundary (DMA restriction) */ - if(f->n_packets >= MAX_PACKETS) { + if (f->n_packets >= MAX_PACKETS) { printk(KERN_ERR "dv1394: FATAL ERROR: max packet count exceeded\n"); return; } @@ -316,7 +316,7 @@ /* the whole CIP pool fits on one page, so no worries about boundaries */ - if( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) + if ( ((unsigned long) &(f->header_pool[f->n_packets]) - (unsigned long) f->header_pool) > PAGE_SIZE) { printk(KERN_ERR "dv1394: FATAL ERROR: no room to allocate CIP header\n"); return; @@ -331,7 +331,7 @@ /* is this an empty packet? */ - if(video->cip_accum > (video->cip_d - video->cip_n)) { + if (video->cip_accum > (video->cip_d - video->cip_n)) { empty_packet = 1; payload_size = 8; video->cip_accum -= (video->cip_d - video->cip_n); @@ -364,7 +364,7 @@ the timestamp before DMA starts on the next frame. */ - if(f->n_packets == 0) { + if (f->n_packets == 0) { first_packet = 1; } else if ( full_packets == (packets_per_frame-1) ) { last_packet = 1; @@ -383,12 +383,12 @@ need a timestamp. */ /* first packet in the frame needs a timestamp */ - if(first_packet) { + if (first_packet) { f->cip_syt1 = cip; - if(empty_packet) + if (empty_packet) first_packet_empty = 1; - } else if(first_packet_empty && (f->n_packets == 1) ) { + } else if (first_packet_empty && (f->n_packets == 1) ) { /* if the first packet was empty, the second packet's CIP header also needs a timestamp */ f->cip_syt2 = cip; @@ -402,7 +402,7 @@ 0xFFFF /* the timestamp is filled in later */); /* advance counter, only for full packets */ - if( ! empty_packet ) + if ( ! empty_packet ) video->continuity_counter++; /******************************/ @@ -412,7 +412,7 @@ /* first descriptor - OUTPUT_MORE_IMMEDIATE, for the controller's IT header */ fill_output_more_immediate( &(block->u.out.omi), 1, video->channel, 0, payload_size); - if(empty_packet) { + if (empty_packet) { /* second descriptor - OUTPUT_LAST for CIP header */ fill_output_last( &(block->u.out.u.empty.ol), @@ -425,18 +425,18 @@ sizeof(struct CIP_header), /* data size */ cip_dma); - if(first_packet) + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.empty.ol.q[3]); - else if(mid_packet) + else if (mid_packet) f->mid_frame_timestamp = &(block->u.out.u.empty.ol.q[3]); - else if(last_packet) { + else if (last_packet) { f->frame_end_timestamp = &(block->u.out.u.empty.ol.q[3]); f->frame_end_branch = &(block->u.out.u.empty.ol.q[2]); } branch_address = &(block->u.out.u.empty.ol.q[2]); n_descriptors = 3; - if(first_packet) + if (first_packet) f->first_n_descriptors = n_descriptors; } else { /* full packet */ @@ -452,7 +452,7 @@ we need to split it into two DMA descriptors */ /* does the 480-byte data payload cross a page boundary? */ - if( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) { + if ( (PAGE_SIZE- ((unsigned long)data_p % PAGE_SIZE) ) < 480 ) { /* page boundary crossed */ @@ -479,11 +479,11 @@ dma_region_offset_to_bus(&video->dv_buf, data_p + PAGE_SIZE - (data_p % PAGE_SIZE) - (unsigned long) video->dv_buf.kvirt)); - if(first_packet) + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); - else if(mid_packet) + else if (mid_packet) f->mid_frame_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); - else if(last_packet) { + else if (last_packet) { f->frame_end_timestamp = &(block->u.out.u.full.u.cross.ol.q[3]); f->frame_end_branch = &(block->u.out.u.full.u.cross.ol.q[2]); } @@ -491,7 +491,7 @@ branch_address = &(block->u.out.u.full.u.cross.ol.q[2]); n_descriptors = 5; - if(first_packet) + if (first_packet) f->first_n_descriptors = n_descriptors; full_packets++; @@ -514,11 +514,11 @@ dma_region_offset_to_bus(&video->dv_buf, data_p - (unsigned long) video->dv_buf.kvirt)); - if(first_packet) + if (first_packet) f->frame_begin_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); - else if(mid_packet) + else if (mid_packet) f->mid_frame_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); - else if(last_packet) { + else if (last_packet) { f->frame_end_timestamp = &(block->u.out.u.full.u.nocross.ol.q[3]); f->frame_end_branch = &(block->u.out.u.full.u.nocross.ol.q[2]); } @@ -526,7 +526,7 @@ branch_address = &(block->u.out.u.full.u.nocross.ol.q[2]); n_descriptors = 4; - if(first_packet) + if (first_packet) f->first_n_descriptors = n_descriptors; full_packets++; @@ -538,7 +538,7 @@ /* note: we are not linked into the active DMA chain yet */ - if(last_branch_address) { + if (last_branch_address) { *(last_branch_address) = cpu_to_le32(block_dma | n_descriptors); } @@ -564,7 +564,7 @@ video->n_clear_frames--; last_frame = video->first_clear_frame - 1; - if(last_frame == -1) + if (last_frame == -1) last_frame = video->n_frames-1; video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; @@ -578,11 +578,11 @@ (unsigned long) f->frame_end_timestamp, (unsigned long) f->frame_end_branch); - if(video->active_frame != -1) { + if (video->active_frame != -1) { /* if DMA is already active, we are almost done */ /* just link us onto the active DMA chain */ - if(video->frames[last_frame]->frame_end_branch) { + if (video->frames[last_frame]->frame_end_branch) { u32 temp; /* point the previous frame's tail to this frame's head */ @@ -650,11 +650,11 @@ f->assigned_timestamp = (ts_cyc&0xF) << 12; /* now actually write the timestamp into the appropriate CIP headers */ - if(f->cip_syt1) { + if (f->cip_syt1) { f->cip_syt1->b[6] = f->assigned_timestamp >> 8; f->cip_syt1->b[7] = f->assigned_timestamp & 0xFF; } - if(f->cip_syt2) { + if (f->cip_syt2) { f->cip_syt2->b[6] = f->assigned_timestamp >> 8; f->cip_syt2->b[7] = f->assigned_timestamp & 0xFF; } @@ -706,10 +706,10 @@ { /* check if DMA is really running */ int i = 0; - while(i < 20) { + while (i < 20) { mb(); mdelay(1); - if(reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) { + if (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) { printk("DMA ACTIVE after %d msec\n", i); break; } @@ -721,7 +721,7 @@ reg_read(video->ohci, video->ohci_IsoXmitCommandPtr) ); - if( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { + if ( ! (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { printk("DMA did NOT go active after 20ms, event = %x\n", reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & 0x1F); } else @@ -821,14 +821,14 @@ { int i; - for(i = 0; i < 1000; ++i) { + for (i = 0; i < 1000; ++i) { mdelay(1); - if(reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { + if (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) { printk("DMA ACTIVE after %d msec\n", i); break; } } - if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { printk("DEAD, event = %x\n", reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); } else @@ -836,7 +836,7 @@ } #endif } - else if( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { + else if ( reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 11) ) { debug_printk("DEAD, event = %x\n", reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & 0x1F); @@ -912,36 +912,36 @@ int retval = -EINVAL; debug_printk("dv1394: initialising %d\n", video->id); - if(init->api_version != DV1394_API_VERSION) + if (init->api_version != DV1394_API_VERSION) return -EINVAL; /* first sanitize all the parameters */ - if( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) ) + if ( (init->n_frames < 2) || (init->n_frames > DV1394_MAX_FRAMES) ) return -EINVAL; - if( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) ) + if ( (init->format != DV1394_NTSC) && (init->format != DV1394_PAL) ) return -EINVAL; - if( (init->syt_offset == 0) || (init->syt_offset > 50) ) + if ( (init->syt_offset == 0) || (init->syt_offset > 50) ) /* default SYT offset is 3 cycles */ init->syt_offset = 3; - if( (init->channel > 63) || (init->channel < 0) ) + if ( (init->channel > 63) || (init->channel < 0) ) init->channel = 63; chan_mask = (u64)1 << init->channel; /* calculate what size DMA buffer is needed */ - if(init->format == DV1394_NTSC) + if (init->format == DV1394_NTSC) new_buf_size = DV1394_NTSC_FRAME_SIZE * init->n_frames; else new_buf_size = DV1394_PAL_FRAME_SIZE * init->n_frames; /* round up to PAGE_SIZE */ - if(new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE); + if (new_buf_size % PAGE_SIZE) new_buf_size += PAGE_SIZE - (new_buf_size % PAGE_SIZE); /* don't allow the user to allocate the DMA buffer more than once */ - if(video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) { + if (video->dv_buf.kvirt && video->dv_buf_size != new_buf_size) { printk("dv1394: re-sizing the DMA buffer is not allowed\n"); return -EINVAL; } @@ -953,7 +953,7 @@ /* try to claim the ISO channel */ spin_lock_irqsave(&video->ohci->IR_channel_lock, flags); - if(video->ohci->ISO_channel_usage & chan_mask) { + if (video->ohci->ISO_channel_usage & chan_mask) { spin_unlock_irqrestore(&video->ohci->IR_channel_lock, flags); retval = -EBUSY; goto err; @@ -981,7 +981,7 @@ video->current_packet = -1; video->first_frame = 0; - if(video->pal_or_ntsc == DV1394_NTSC) { + if (video->pal_or_ntsc == DV1394_NTSC) { video->cip_n = init->cip_n != 0 ? init->cip_n : CIP_N_NTSC; video->cip_d = init->cip_d != 0 ? init->cip_d : CIP_D_NTSC; video->frame_size = DV1394_NTSC_FRAME_SIZE; @@ -995,7 +995,7 @@ /* find and claim DMA contexts on the OHCI card */ - if(video->ohci_it_ctx == -1) { + if (video->ohci_it_ctx == -1) { ohci1394_init_iso_tasklet(&video->it_tasklet, OHCI_ISO_TRANSMIT, it_tasklet_func, (unsigned long) video); @@ -1009,7 +1009,7 @@ debug_printk("dv1394: claimed IT DMA context %d\n", video->ohci_it_ctx); } - if(video->ohci_ir_ctx == -1) { + if (video->ohci_ir_ctx == -1) { ohci1394_init_iso_tasklet(&video->ir_tasklet, OHCI_ISO_RECEIVE, ir_tasklet_func, (unsigned long) video); @@ -1023,20 +1023,20 @@ } /* allocate struct frames */ - for(i = 0; i < init->n_frames; i++) { + for (i = 0; i < init->n_frames; i++) { video->frames[i] = frame_new(i, video); - if(!video->frames[i]) { + if (!video->frames[i]) { printk(KERN_ERR "dv1394: Cannot allocate frame structs\n"); retval = -ENOMEM; goto err; } } - if(!video->dv_buf.kvirt) { + if (!video->dv_buf.kvirt) { /* allocate the ringbuffer */ retval = dma_region_alloc(&video->dv_buf, new_buf_size, video->ohci->dev, PCI_DMA_TODEVICE); - if(retval) + if (retval) goto err; video->dv_buf_size = new_buf_size; @@ -1047,10 +1047,10 @@ } /* set up the frame->data pointers */ - for(i = 0; i < video->n_frames; i++) + for (i = 0; i < video->n_frames; i++) video->frames[i]->data = (unsigned long) video->dv_buf.kvirt + i * video->frame_size; - if(!video->packet_buf.kvirt) { + if (!video->packet_buf.kvirt) { /* allocate packet buffer */ video->packet_buf_size = sizeof(struct packet) * video->n_frames * MAX_PACKETS; if (video->packet_buf_size % PAGE_SIZE) @@ -1058,7 +1058,7 @@ retval = dma_region_alloc(&video->packet_buf, video->packet_buf_size, video->ohci->dev, PCI_DMA_FROMDEVICE); - if(retval) + if (retval) goto err; debug_printk("dv1394: Allocated %d packets in buffer, total %u pages (%u DMA pages), %lu bytes\n", @@ -1124,11 +1124,11 @@ video->dma_running = 0; - if( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) ) + if ( (video->ohci_it_ctx == -1) && (video->ohci_ir_ctx == -1) ) goto out; /* stop DMA if in progress */ - if( (video->active_frame != -1) || + if ( (video->active_frame != -1) || (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { @@ -1142,12 +1142,12 @@ /* wait until DMA really stops */ i = 0; - while(i < 1000) { + while (i < 1000) { /* wait 0.1 millisecond */ udelay(100); - if( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || + if ( (reg_read(video->ohci, video->ohci_IsoXmitContextControlClear) & (1 << 10)) || (reg_read(video->ohci, video->ohci_IsoRcvContextControlClear) & (1 << 10)) ) { /* still active */ debug_printk("dv1394: stop_dma: DMA not stopped yet\n" ); @@ -1160,7 +1160,7 @@ i++; } - if(i == 1000) { + if (i == 1000) { printk(KERN_ERR "dv1394: stop_dma: DMA still going after %d ms!\n", i/10); } } @@ -1183,7 +1183,7 @@ stop_dma(video); /* release the DMA contexts */ - if(video->ohci_it_ctx != -1) { + if (video->ohci_it_ctx != -1) { video->ohci_IsoXmitContextControlSet = 0; video->ohci_IsoXmitContextControlClear = 0; video->ohci_IsoXmitCommandPtr = 0; @@ -1197,7 +1197,7 @@ video->ohci_it_ctx = -1; } - if(video->ohci_ir_ctx != -1) { + if (video->ohci_ir_ctx != -1) { video->ohci_IsoRcvContextControlSet = 0; video->ohci_IsoRcvContextControlClear = 0; video->ohci_IsoRcvCommandPtr = 0; @@ -1213,7 +1213,7 @@ } /* release the ISO channel */ - if(video->channel != -1) { + if (video->channel != -1) { u64 chan_mask; unsigned long flags; @@ -1227,8 +1227,8 @@ } /* free the frame structs */ - for(i = 0; i < DV1394_MAX_FRAMES; i++) { - if(video->frames[i]) + for (i = 0; i < DV1394_MAX_FRAMES; i++) { + if (video->frames[i]) frame_delete(video->frames[i]); video->frames[i] = NULL; } @@ -1238,7 +1238,7 @@ /* we can't free the DMA buffer unless it is guaranteed that no more user-space mappings exist */ - if(free_dv_buf) { + if (free_dv_buf) { dma_region_free(&video->dv_buf); video->dv_buf_size = 0; } @@ -1282,9 +1282,9 @@ /* serialize mmap */ down(&video->sem); - if( ! video_card_initialized(video) ) { + if ( ! video_card_initialized(video) ) { retval = do_dv1394_init_default(video); - if(retval) + if (retval) goto out; } @@ -1306,14 +1306,14 @@ poll_wait(file, &video->waitq, wait); spin_lock_irqsave(&video->spinlock, flags); - if( video->n_frames == 0 ) { + if ( video->n_frames == 0 ) { - } else if( video->active_frame == -1 ) { + } else if ( video->active_frame == -1 ) { /* nothing going on */ mask |= POLLOUT; } else { /* any clear/ready buffers? */ - if(video->n_clear_frames >0) + if (video->n_clear_frames >0) mask |= POLLOUT | POLLIN; } spin_unlock_irqrestore(&video->spinlock, flags); @@ -1345,17 +1345,17 @@ int target_frame; /* serialize this to prevent multi-threaded mayhem */ - if(file->f_flags & O_NONBLOCK) { - if(down_trylock(&video->sem)) + if (file->f_flags & O_NONBLOCK) { + if (down_trylock(&video->sem)) return -EAGAIN; } else { - if(down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) return -ERESTARTSYS; } - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) { + if (ret) { up(&video->sem); return ret; } @@ -1364,7 +1364,7 @@ ret = 0; add_wait_queue(&video->waitq, &wait); - while(count > 0) { + while (count > 0) { /* must set TASK_INTERRUPTIBLE *before* checking for free buffers; otherwise we could miss a wakeup if the interrupt @@ -1378,7 +1378,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if(video->frames[target_frame]->state == FRAME_CLEAR) { + if (video->frames[target_frame]->state == FRAME_CLEAR) { /* how much room is left in the target frame buffer */ cnt = video->frame_size - (video->write_off - target_frame * video->frame_size); @@ -1388,12 +1388,12 @@ cnt = 0; } - if(cnt > count) + if (cnt > count) cnt = count; if (cnt <= 0) { /* no room left, gotta wait */ - if(file->f_flags & O_NONBLOCK) { + if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; break; @@ -1409,8 +1409,8 @@ continue; /* start over from 'while(count > 0)...' */ } - if(copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) { - if(!ret) + if (copy_from_user(video->dv_buf.kvirt + video->write_off, buffer, cnt)) { + if (!ret) ret = -EFAULT; break; } @@ -1421,7 +1421,7 @@ buffer += cnt; ret += cnt; - if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) + if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) frame_prepare(video, target_frame); } @@ -1442,17 +1442,17 @@ int target_frame; /* serialize this to prevent multi-threaded mayhem */ - if(file->f_flags & O_NONBLOCK) { - if(down_trylock(&video->sem)) + if (file->f_flags & O_NONBLOCK) { + if (down_trylock(&video->sem)) return -EAGAIN; } else { - if(down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) return -ERESTARTSYS; } - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) { + if (ret) { up(&video->sem); return ret; } @@ -1466,7 +1466,7 @@ ret = 0; add_wait_queue(&video->waitq, &wait); - while(count > 0) { + while (count > 0) { /* must set TASK_INTERRUPTIBLE *before* checking for free buffers; otherwise we could miss a wakeup if the interrupt @@ -1480,7 +1480,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if(target_frame >= 0 && + if (target_frame >= 0 && video->n_clear_frames > 0 && video->frames[target_frame]->state == FRAME_CLEAR) { @@ -1492,12 +1492,12 @@ cnt = 0; } - if(cnt > count) + if (cnt > count) cnt = count; if (cnt <= 0) { /* no room left, gotta wait */ - if(file->f_flags & O_NONBLOCK) { + if (file->f_flags & O_NONBLOCK) { if (!ret) ret = -EAGAIN; break; @@ -1513,8 +1513,8 @@ continue; /* start over from 'while(count > 0)...' */ } - if(copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) { - if(!ret) + if (copy_to_user(buffer, video->dv_buf.kvirt + video->write_off, cnt)) { + if (!ret) ret = -EFAULT; break; } @@ -1525,7 +1525,7 @@ buffer += cnt; ret += cnt; - if(video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) { + if (video->write_off == video->frame_size * ((target_frame + 1) % video->n_frames)) { spin_lock_irqsave(&video->spinlock, flags); video->n_clear_frames--; video->first_clear_frame = (video->first_clear_frame + 1) % video->n_frames; @@ -1555,11 +1555,11 @@ DECLARE_WAITQUEUE(wait, current); /* serialize this to prevent multi-threaded mayhem */ - if(file->f_flags & O_NONBLOCK) { - if(down_trylock(&video->sem)) + if (file->f_flags & O_NONBLOCK) { + if (down_trylock(&video->sem)) return -EAGAIN; } else { - if(down_interruptible(&video->sem)) + if (down_interruptible(&video->sem)) return -ERESTARTSYS; } @@ -1568,20 +1568,20 @@ case DV1394_IOC_SUBMIT_FRAMES: { unsigned int n_submit; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) + if (ret) goto out; } n_submit = (unsigned int) arg; - if(n_submit > video->n_frames) { + if (n_submit > video->n_frames) { ret = -EINVAL; goto out; } - while(n_submit > 0) { + while (n_submit > 0) { add_wait_queue(&video->waitq, &wait); set_current_state(TASK_INTERRUPTIBLE); @@ -1589,11 +1589,11 @@ spin_lock_irqsave(&video->spinlock, flags); /* wait until video->first_clear_frame is really CLEAR */ - while(video->frames[video->first_clear_frame]->state != FRAME_CLEAR) { + while (video->frames[video->first_clear_frame]->state != FRAME_CLEAR) { spin_unlock_irqrestore(&video->spinlock, flags); - if(signal_pending(current)) { + if (signal_pending(current)) { remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); ret = -EINTR; @@ -1622,7 +1622,7 @@ case DV1394_IOC_WAIT_FRAMES: { unsigned int n_wait; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = -EINVAL; goto out; } @@ -1633,7 +1633,7 @@ never actually have n_frames clear frames; at most only n_frames - 1 */ - if(n_wait > (video->n_frames-1) ) { + if (n_wait > (video->n_frames-1) ) { ret = -EINVAL; goto out; } @@ -1643,11 +1643,11 @@ spin_lock_irqsave(&video->spinlock, flags); - while(video->n_clear_frames < n_wait) { + while (video->n_clear_frames < n_wait) { spin_unlock_irqrestore(&video->spinlock, flags); - if(signal_pending(current)) { + if (signal_pending(current)) { remove_wait_queue(&video->waitq, &wait); set_current_state(TASK_RUNNING); ret = -EINTR; @@ -1671,7 +1671,7 @@ case DV1394_IOC_RECEIVE_FRAMES: { unsigned int n_recv; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = -EINVAL; goto out; } @@ -1679,7 +1679,7 @@ n_recv = (unsigned int) arg; /* at least one frame must be active */ - if(n_recv > (video->n_frames-1) ) { + if (n_recv > (video->n_frames-1) ) { ret = -EINVAL; goto out; } @@ -1702,9 +1702,9 @@ } case DV1394_IOC_START_RECEIVE: { - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = do_dv1394_init_default(video); - if(ret) + if (ret) goto out; } @@ -1720,10 +1720,10 @@ case DV1394_IOC_INIT: { struct dv1394_init init; - if(arg == (unsigned long) NULL) { + if (arg == (unsigned long) NULL) { ret = do_dv1394_init_default(video); } else { - if(copy_from_user(&init, (void*)arg, sizeof(init))) { + if (copy_from_user(&init, (void*)arg, sizeof(init))) { ret = -EFAULT; goto out; } @@ -1741,7 +1741,7 @@ case DV1394_IOC_GET_STATUS: { struct dv1394_status status; - if( !video_card_initialized(video) ) { + if ( !video_card_initialized(video) ) { ret = -EINVAL; goto out; } @@ -1769,7 +1769,7 @@ spin_unlock_irqrestore(&video->spinlock, flags); - if(copy_to_user((void*)arg, &status, sizeof(status))) { + if (copy_to_user((void*)arg, &status, sizeof(status))) { ret = -EFAULT; goto out; } @@ -1797,7 +1797,7 @@ /* if the device was opened through devfs, then file->private_data has already been set to video by devfs */ - if(file->private_data) { + if (file->private_data) { video = (struct video_card*) file->private_data; } else { @@ -1807,11 +1807,11 @@ unsigned long flags; spin_lock_irqsave(&dv1394_cards_lock, flags); - if(!list_empty(&dv1394_cards)) { + if (!list_empty(&dv1394_cards)) { struct video_card *p; list_for_each(lh, &dv1394_cards) { p = list_entry(lh, struct video_card, list); - if((p->id) == ieee1394_file_to_instance(file)) { + if ((p->id) == ieee1394_file_to_instance(file)) { video = p; break; } @@ -1819,7 +1819,7 @@ } spin_unlock_irqrestore(&dv1394_cards_lock, flags); - if(!video) { + if (!video) { debug_printk("dv1394: OHCI card %d not found", ieee1394_file_to_instance(file)); return -ENODEV; } @@ -1829,7 +1829,7 @@ #ifndef DV1394_ALLOW_MORE_THAN_ONE_OPEN - if( test_and_set_bit(0, &video->open) ) { + if ( test_and_set_bit(0, &video->open) ) { /* video is already open by someone else */ return -EBUSY; } @@ -1971,10 +1971,10 @@ struct dv1394_procfs_entry *p; spin_lock( &dv1394_procfs_lock); - if(!list_empty(&dv1394_procfs)) { + if (!list_empty(&dv1394_procfs)) { list_for_each(lh, &dv1394_procfs) { p = list_entry(lh, struct dv1394_procfs_entry, list); - if(!strncmp(p->name, name, sizeof(p->name))) { + if (!strncmp(p->name, name, sizeof(p->name))) { spin_unlock( &dv1394_procfs_lock); return p; } @@ -1991,7 +1991,7 @@ struct dv1394_procfs_entry *parent; p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL); - if(!p) { + if (!p) { printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n"); goto err; } @@ -2043,7 +2043,7 @@ struct dv1394_procfs_entry *p; p = kmalloc(sizeof(struct dv1394_procfs_entry), GFP_KERNEL); - if(!p) { + if (!p) { printk(KERN_ERR "dv1394: cannot allocate dv1394_procfs_entry\n"); goto err; } @@ -2104,7 +2104,7 @@ spin_lock(&video->spinlock); - if(!video->dma_running) + if (!video->dma_running) goto out; irq_printk("ContextControl = %08x, CommandPtr = %08x\n", @@ -2113,24 +2113,24 @@ ); - if( (video->ohci_it_ctx != -1) && + if ( (video->ohci_it_ctx != -1) && (reg_read(video->ohci, video->ohci_IsoXmitContextControlSet) & (1 << 10)) ) { struct frame *f; unsigned int frame, i; - if(video->active_frame == -1) + if (video->active_frame == -1) frame = 0; else frame = video->active_frame; /* check all the DMA-able frames */ - for(i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) { + for (i = 0; i < video->n_frames; i++, frame = (frame+1) % video->n_frames) { irq_printk("IRQ checking frame %d...", frame); f = video->frames[frame]; - if(f->state != FRAME_READY) { + if (f->state != FRAME_READY) { irq_printk("clear, skipping\n"); /* we don't own this frame */ continue; @@ -2139,7 +2139,7 @@ irq_printk("DMA\n"); /* check the frame begin semaphore to see if we can free the previous frame */ - if( *(f->frame_begin_timestamp) ) { + if ( *(f->frame_begin_timestamp) ) { int prev_frame; struct frame *prev_f; @@ -2149,13 +2149,13 @@ irq_printk(" BEGIN\n"); prev_frame = frame - 1; - if(prev_frame == -1) + if (prev_frame == -1) prev_frame += video->n_frames; prev_f = video->frames[prev_frame]; /* make sure we can actually garbage collect this frame */ - if( (prev_f->state == FRAME_READY) && + if ( (prev_f->state == FRAME_READY) && prev_f->done && (!f->done) ) { frame_reset(prev_f); @@ -2173,7 +2173,7 @@ /* see if we need to set the timestamp for the next frame */ - if( *(f->mid_frame_timestamp) ) { + if ( *(f->mid_frame_timestamp) ) { struct frame *next_frame; u32 begin_ts, ts_cyc, ts_off; @@ -2188,7 +2188,7 @@ /* prepare next frame and assign timestamp */ next_frame = video->frames[ (frame+1) % video->n_frames ]; - if(next_frame->state == FRAME_READY) { + if (next_frame->state == FRAME_READY) { irq_printk(" MIDDLE - next frame is ready, good\n"); } else { debug_printk("dv1394: Underflow! At least one frame has been dropped.\n"); @@ -2207,11 +2207,11 @@ ts_off %= 3072; next_frame->assigned_timestamp = ((ts_cyc&0xF) << 12) + ts_off; - if(next_frame->cip_syt1) { + if (next_frame->cip_syt1) { next_frame->cip_syt1->b[6] = next_frame->assigned_timestamp >> 8; next_frame->cip_syt1->b[7] = next_frame->assigned_timestamp & 0xFF; } - if(next_frame->cip_syt2) { + if (next_frame->cip_syt2) { next_frame->cip_syt2->b[6] = next_frame->assigned_timestamp >> 8; next_frame->cip_syt2->b[7] = next_frame->assigned_timestamp & 0xFF; } @@ -2219,7 +2219,7 @@ } /* see if the frame looped */ - if( *(f->frame_end_timestamp) ) { + if ( *(f->frame_end_timestamp) ) { *(f->frame_end_timestamp) = 0; @@ -2230,10 +2230,10 @@ - } /* for(each frame) */ + } /* for (each frame) */ } - if(wake) { + if (wake) { kill_fasync(&video->fasync, SIGIO, POLL_OUT); /* wake readers/writers/ioctl'ers */ @@ -2251,10 +2251,10 @@ spin_lock(&video->spinlock); - if(!video->dma_running) + if (!video->dma_running) goto out; - if( (video->ohci_ir_ctx != -1) && + if ( (video->ohci_ir_ctx != -1) && (reg_read(video->ohci, video->ohci_IsoRcvContextControlSet) & (1 << 10)) ) { @@ -2374,7 +2374,7 @@ prev_i = (next_i == 0) ? (MAX_PACKETS * video->n_frames - 1) : (next_i - 1); f = video->frames[prev_i / MAX_PACKETS]; prev = &(f->descriptor_pool[prev_i % MAX_PACKETS]); - if(prev_i % (MAX_PACKETS/2)) { + if (prev_i % (MAX_PACKETS/2)) { prev->u.in.il.q[0] &= ~(3 << 20); /* no interrupt */ } else { prev->u.in.il.q[0] |= 3 << 20; /* enable interrupt */ @@ -2394,7 +2394,7 @@ } /* receive interrupt */ - if(wake) { + if (wake) { kill_fasync(&video->fasync, SIGIO, POLL_IN); /* wake readers/writers/ioctl'ers */ @@ -2453,7 +2453,7 @@ int i; video = kmalloc(sizeof(struct video_card), GFP_KERNEL); - if(!video) { + if (!video) { printk(KERN_ERR "dv1394: cannot allocate video_card\n"); goto err; } @@ -2497,7 +2497,7 @@ goto err_free; #endif - for(i = 0; i < DV1394_MAX_FRAMES; i++) + for (i = 0; i < DV1394_MAX_FRAMES; i++) video->frames[i] = NULL; dma_region_init(&video->dv_buf); @@ -2574,10 +2574,10 @@ /* find the corresponding video_cards */ spin_lock_irqsave(&dv1394_cards_lock, flags); - if(!list_empty(&dv1394_cards)) { + if (!list_empty(&dv1394_cards)) { list_for_each_safe(lh, templh, &dv1394_cards) { video = list_entry(lh, struct video_card, list); - if((video->id >> 2) == ohci->id) + if ((video->id >> 2) == ohci->id) dv1394_un_init(video); } } @@ -2655,32 +2655,32 @@ /* find the corresponding video_cards */ spin_lock_irqsave(&dv1394_cards_lock, flags); - if(!list_empty(&dv1394_cards)) { + if (!list_empty(&dv1394_cards)) { list_for_each(lh, &dv1394_cards) { video = list_entry(lh, struct video_card, list); - if((video->id >> 2) == ohci->id) + if ((video->id >> 2) == ohci->id) break; } } spin_unlock_irqrestore(&dv1394_cards_lock, flags); - if(!video) + if (!video) return; spin_lock_irqsave(&video->spinlock, flags); - if(!video->dma_running) + if (!video->dma_running) goto out; /* check IT context */ - if(video->ohci_it_ctx != -1) { + if (video->ohci_it_ctx != -1) { u32 ctx; ctx = reg_read(video->ohci, video->ohci_IsoXmitContextControlSet); - /* if(RUN but not ACTIVE) */ - if( (ctx & (1<<15)) && + /* if (RUN but not ACTIVE) */ + if ( (ctx & (1<<15)) && !(ctx & (1<<10)) ) { debug_printk("dv1394: IT context stopped due to bus reset; waking it up\n"); @@ -2710,13 +2710,13 @@ } /* check IR context */ - if(video->ohci_ir_ctx != -1) { + if (video->ohci_ir_ctx != -1) { u32 ctx; ctx = reg_read(video->ohci, video->ohci_IsoRcvContextControlSet); - /* if(RUN but not ACTIVE) */ - if( (ctx & (1<<15)) && + /* if (RUN but not ACTIVE) */ + if ( (ctx & (1<<15)) && !(ctx & (1<<10)) ) { debug_printk("dv1394: IR context stopped due to bus reset; waking it up\n"); diff -Nru a/drivers/ieee1394/dv1394.h b/drivers/ieee1394/dv1394.h --- a/drivers/ieee1394/dv1394.h Fri Jun 27 14:19:59 2003 +++ b/drivers/ieee1394/dv1394.h Fri Jun 27 14:19:59 2003 @@ -64,7 +64,7 @@ ioctl(fd, DV1394_INIT, &init); - while(1) { + while (1) { read( <a raw DV file>, buf, DV1394_NTSC_FRAME_SIZE ); write( <the dv1394 FD>, buf, DV1394_NTSC_FRAME_SIZE ); } @@ -145,7 +145,7 @@ (checks of system call return values omitted for brevity; always check return values in your code!) - while( frames left ) { + while ( frames left ) { struct pollfd *pfd = ...; @@ -157,15 +157,15 @@ poll(pfd, 1, -1); (or select(); add a timeout if you want) - if(pfd->revents) { + if (pfd->revents) { struct dv1394_status status; ioctl(dv1394_fd, DV1394_GET_STATUS, &status); - if(status.dropped_frames > 0) { + if (status.dropped_frames > 0) { reset_dv1394(); } else { - for(int i = 0; i < status.n_clear_frames; i++) { + for (int i = 0; i < status.n_clear_frames; i++) { copy_DV_frame(); } } diff -Nru a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c --- a/drivers/ieee1394/eth1394.c Fri Jun 27 14:19:58 2003 +++ b/drivers/ieee1394/eth1394.c Fri Jun 27 14:19:58 2003 @@ -30,7 +30,7 @@ * TODO: * RFC 2734 related: * - Add Config ROM entry - * - Add MCAP and multicast + * - Add MCAP. Limited Multicast exists only to 224.0.0.1 and 224.0.0.2. * * Non-RFC 2734 related: * - Fix bug related to fragmented broadcast datagrams @@ -59,9 +59,12 @@ #include <linux/if_arp.h> #include <linux/if_ether.h> #include <linux/ip.h> +#include <linux/in.h> #include <linux/tcp.h> #include <linux/skbuff.h> #include <linux/bitops.h> +#include <linux/ethtool.h> +#include <asm/uaccess.h> #include <asm/delay.h> #include <asm/semaphore.h> #include <net/arp.h> @@ -76,17 +79,17 @@ #include "eth1394.h" #define ETH1394_PRINT_G(level, fmt, args...) \ - printk(level ETHER1394_DRIVER_NAME": "fmt, ## args) + printk(level "%s: " fmt, driver_name, ## args) #define ETH1394_PRINT(level, dev_name, fmt, args...) \ - printk(level ETHER1394_DRIVER_NAME": %s: " fmt, dev_name, ## args) + printk(level "%s: %s: " fmt, driver_name, dev_name, ## args) #define DEBUG(fmt, args...) \ - printk(KERN_ERR "eth1394:%s[%d]: "fmt"\n", __FUNCTION__, __LINE__, ## args) -#define TRACE() printk(KERN_ERR "eth1394:%s[%d] ---- TRACE\n", __FUNCTION__, __LINE__) + printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args) +#define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__) static char version[] __devinitdata = - "$Rev: 951 $ Ben Collins <bcollins@debian.org>"; + "$Rev: 971 $ Ben Collins <bcollins@debian.org>"; struct fragment_info { struct list_head list; @@ -105,7 +108,7 @@ }; /* Our ieee1394 highlevel driver */ -#define ETHER1394_DRIVER_NAME "ether1394" +static const char driver_name[] = "eth1394"; static kmem_cache_t *packet_task_cache; @@ -156,15 +159,26 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev); static void ether1394_iso(struct hpsb_iso *iso); +static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); +static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr); + +static void eth1394_iso_shutdown(struct eth1394_priv *priv) +{ + priv->bc_state = ETHER1394_BC_CLOSED; + + if (priv->iso != NULL) { + hpsb_iso_shutdown(priv->iso); + priv->iso = NULL; + } +} static int ether1394_init_bc(struct net_device *dev) { - int ret = 0; struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; /* First time sending? Need a broadcast channel for ARP and for * listening on */ - if(priv->bc_state == ETHER1394_BC_CHECK) { + if (priv->bc_state == ETHER1394_BC_CHECK) { quadlet_t bc; /* Get the local copy of the broadcast channel and check its @@ -172,30 +186,26 @@ bc = priv->host->csr.broadcast_channel; - if((bc & 0xc0000000) != 0xc0000000) { + if ((bc & 0xc0000000) != 0xc0000000) { /* broadcast channel not validated yet */ ETH1394_PRINT(KERN_WARNING, dev->name, "Error BROADCAST_CHANNEL register valid " "bit not set, can't send IP traffic\n"); - if(!in_interrupt()) { - hpsb_iso_shutdown(priv->iso); - priv->bc_state = ETHER1394_BC_CLOSED; - } - ret = -EAGAIN; - goto fail; + + if (!in_interrupt()) + eth1394_iso_shutdown(priv); + + return -EAGAIN; } - if(priv->broadcast_channel != (bc & 0x3f)) { + if (priv->broadcast_channel != (bc & 0x3f)) { /* This really shouldn't be possible, but just in case * the IEEE 1394 spec changes regarding broadcast * channels in the future. */ - if(in_interrupt()) { - ret = -EAGAIN; - goto fail; - - } + if (in_interrupt()) + return -EAGAIN; - hpsb_iso_shutdown(priv->iso); + eth1394_iso_shutdown(priv); priv->broadcast_channel = bc & 0x3f; ETH1394_PRINT(KERN_INFO, dev->name, @@ -205,29 +215,26 @@ priv->iso = hpsb_iso_recv_init(priv->host, 16 * 4096, 16, priv->broadcast_channel, 1, ether1394_iso); - if(priv->iso == NULL) { + if (priv->iso == NULL) { ETH1394_PRINT(KERN_ERR, dev->name, "failed to change broadcast " "channel\n"); - ret = -EAGAIN; - goto fail; + return -EAGAIN; } } - if(hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) { + if (hpsb_iso_recv_start(priv->iso, -1, (1 << 3), -1) < 0) { ETH1394_PRINT(KERN_ERR, dev->name, "Could not start data stream reception\n"); - if(!in_interrupt()) { - hpsb_iso_shutdown(priv->iso); - priv->bc_state = ETHER1394_BC_CLOSED; - } - ret = -EAGAIN; - goto fail; + + if (!in_interrupt()) + eth1394_iso_shutdown(priv); + + return -EAGAIN; } priv->bc_state = ETHER1394_BC_OPENED; } -fail: - return ret; + return 0; } /* This is called after an "ifup" */ @@ -243,7 +250,7 @@ ret = ether1394_init_bc(dev); spin_unlock_irqrestore(&priv->lock, flags); - if(ret) + if (ret) return ret; netif_start_queue (dev); @@ -280,9 +287,9 @@ struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; int phy_id = NODEID_TO_NODE(priv->host->node_id); - if ((new_mtu < 68) || (new_mtu > (priv->maxpayload[phy_id] - + if ((new_mtu < 68) || (new_mtu > MIN(ETH_DATA_LEN, (priv->maxpayload[phy_id] - (sizeof(union eth1394_hdr) + - ETHER1394_GASP_OVERHEAD)))) + ETHER1394_GASP_OVERHEAD))))) return -EINVAL; dev->mtu = new_mtu; return 0; @@ -315,7 +322,8 @@ struct eth1394_priv *priv = (struct eth1394_priv *)dev->priv; struct hpsb_host *host = priv->host; int phy_id = NODEID_TO_NODE(host->node_id); - u64 guid = *((u64*)&(host->csr.rom[3])); + u64 guid = (u64)(((u64)be32_to_cpu(host->csr.rom[3]) << 32) | + be32_to_cpu(host->csr.rom[4])); u16 maxpayload = 1 << (((be32_to_cpu(host->csr.rom[2]) >> 12) & 0xf) + 1); spin_lock_irqsave (&priv->lock, flags); @@ -325,14 +333,14 @@ memset (priv->sspd, 0, sizeof (priv->sspd)); memset (priv->fifo, 0, sizeof (priv->fifo)); -#if 0 +#if 1 /* Compile this out to make testing of fragmented broadcast datagrams * easier. */ - priv->sspd[ALL_NODES] = SPEED_MAX; - priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[SPEED_MAX]; + priv->sspd[ALL_NODES] = IEEE1394_SPEED_MAX; + priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[IEEE1394_SPEED_MAX]; #else - priv->sspd[ALL_NODES] = SPEED_100; - priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[SPEED_100]; + priv->sspd[ALL_NODES] = IEEE1394_SPEED_100; + priv->maxpayload[ALL_NODES] = eth1394_speedto_maxpayload[IEEE1394_SPEED_100]; #endif priv->bc_state = ETHER1394_BC_CHECK; @@ -344,8 +352,9 @@ /* We'll use our maxpayload as the default mtu */ if (set_mtu) { - dev->mtu = priv->maxpayload[phy_id] - (sizeof(union eth1394_hdr) + - ETHER1394_GASP_OVERHEAD); + dev->mtu = MIN(ETH_DATA_LEN, priv->maxpayload[phy_id] - + (sizeof(union eth1394_hdr) + + ETHER1394_GASP_OVERHEAD)); /* Set our hardware address while we're at it */ *(u64*)dev->dev_addr = guid; @@ -354,11 +363,11 @@ spin_unlock_irqrestore (&priv->lock, flags); - for(i = 0; i < ALL_NODES; i++) { + for (i = 0; i < ALL_NODES; i++) { struct list_head *lh, *n; spin_lock_irqsave(&priv->pdg[i].lock, flags); - if(!set_mtu) { + if (!set_mtu) { list_for_each_safe(lh, n, &priv->pdg[i].list) { purge_partial_datagram(lh); } @@ -386,11 +395,12 @@ dev->header_cache_update= ether1394_header_cache_update; dev->hard_header_parse = ether1394_header_parse; dev->set_mac_address = ether1394_mac_addr; + dev->do_ioctl = ether1394_do_ioctl; /* Some constants */ dev->watchdog_timeo = ETHER1394_TIMEOUT; - dev->flags = IFF_BROADCAST; /* | IFF_MULTICAST someday */ - dev->features = NETIF_F_NO_CSUM|NETIF_F_SG|NETIF_F_HIGHDMA|NETIF_F_FRAGLIST; + dev->flags = IFF_BROADCAST | IFF_MULTICAST; + dev->features = NETIF_F_HIGHDMA; dev->addr_len = ETH1394_ALEN; dev->hard_header_len = ETH1394_HLEN; dev->type = ARPHRD_IEEE1394; @@ -421,8 +431,12 @@ * it for ourselves. That way we'd be a real networking device. */ dev = alloc_etherdev(sizeof (struct eth1394_priv)); - if (dev == NULL) + if (dev == NULL) { + ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to allocate " + "etherdevice for IEEE 1394 device %s-%d\n", + host->driver->name, host->id); goto out; + } SET_MODULE_OWNER(dev); @@ -433,7 +447,7 @@ priv->host = host; spin_lock_init(&priv->lock); - for(i = 0; i < ALL_NODES; i++) { + for (i = 0; i < ALL_NODES; i++) { spin_lock_init(&priv->pdg[i].lock); INIT_LIST_HEAD(&priv->pdg[i].list); priv->pdg[i].sz = 0; @@ -441,8 +455,12 @@ hi = hpsb_create_hostinfo(ð1394_highlevel, host, sizeof(*hi)); - if (hi == NULL) + if (hi == NULL) { + ETH1394_PRINT_G (KERN_ERR, "Out of memory trying to create " + "hostinfo for IEEE 1394 device %s-%d\n", + host->driver->name, host->id); goto out; + } if (register_netdev (dev)) { ETH1394_PRINT (KERN_ERR, dev->name, "Error registering network driver\n"); @@ -472,8 +490,6 @@ if (hi) hpsb_destroy_hostinfo(ð1394_highlevel, host); - ETH1394_PRINT_G (KERN_ERR, "Out of memory\n"); - return; } @@ -486,10 +502,12 @@ struct eth1394_priv *priv = (struct eth1394_priv *)hi->dev->priv; priv->bc_state = ETHER1394_BC_CLOSED; - unregister_netdev (hi->dev); - hpsb_iso_shutdown(priv->iso); + eth1394_iso_shutdown(priv); - kfree(hi->dev); + if (hi->dev) { + unregister_netdev (hi->dev); + kfree(hi->dev); + } } return; @@ -536,7 +554,7 @@ return(dev->hard_header_len); } - if(daddr) + if (daddr) { memcpy(eth->h_dest,daddr,dev->addr_len); return dev->hard_header_len; @@ -579,7 +597,7 @@ { struct net_device *dev = skb->dev; memcpy(haddr, dev->dev_addr, ETH1394_ALEN); - return ETH_ALEN; + return ETH1394_ALEN; } @@ -635,15 +653,15 @@ skb_pull (skb, ETH1394_HLEN); eth = (struct eth1394hdr*)skb->mac.raw; - if(*eth->h_dest & 1) { - if(memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0) + if (*eth->h_dest & 1) { + if (memcmp(eth->h_dest, dev->broadcast, dev->addr_len)==0) skb->pkt_type = PACKET_BROADCAST; #if 0 else skb->pkt_type = PACKET_MULTICAST; #endif } else { - if(memcmp(eth->h_dest, dev->dev_addr, dev->addr_len)) + if (memcmp(eth->h_dest, dev->dev_addr, dev->addr_len)) skb->pkt_type = PACKET_OTHERHOST; } @@ -671,7 +689,7 @@ /* Setup our hw addresses. We use these to build the * ethernet header. */ - if(destid == (LOCAL_BUS | ALL_NODES)) + if (destid == (LOCAL_BUS | ALL_NODES)) dest_hw = ~0ULL; /* broadcast */ else dest_hw = priv->eui[NODEID_TO_NODE(destid)]; @@ -716,7 +734,7 @@ *(u32*)arp_ptr = arp1394->sip; /* move sender IP addr */ arp_ptr += arp->ar_pln; /* skip over sender IP addr */ - if(arp->ar_op == 1) + if (arp->ar_op == 1) /* just set ARP req target unique ID to 0 */ memset(arp_ptr, 0, ETH1394_ALEN); else @@ -739,7 +757,7 @@ list_for_each(lh, frag_list) { fi = list_entry(lh, struct fragment_info, list); - if( ! ((offset > (fi->offset + fi->len - 1)) || + if ( ! ((offset > (fi->offset + fi->len - 1)) || ((offset + len - 1) < fi->offset))) return 1; } @@ -753,7 +771,7 @@ list_for_each(lh, pdgl) { pd = list_entry(lh, struct partial_datagram, list); - if(pd->dgl == dgl) + if (pd->dgl == dgl) return lh; } return NULL; @@ -767,32 +785,32 @@ list_for_each(lh, frag_info) { fi = list_entry(lh, struct fragment_info, list); - if((fi->offset + fi->len) == offset) { + if ((fi->offset + fi->len) == offset) { /* The new fragment can be tacked on to the end */ fi->len += len; /* Did the new fragment plug a hole? */ fi2 = list_entry(lh->next, struct fragment_info, list); - if((fi->offset + fi->len) == fi2->offset) { + if ((fi->offset + fi->len) == fi2->offset) { /* glue fragments together */ fi->len += fi2->len; list_del(lh->next); kfree(fi2); } return 0; - } else if((offset + len) == fi->offset) { + } else if ((offset + len) == fi->offset) { /* The new fragment can be tacked on to the beginning */ fi->offset = offset; fi->len += len; /* Did the new fragment plug a hole? */ fi2 = list_entry(lh->prev, struct fragment_info, list); - if((fi2->offset + fi2->len) == fi->offset) { + if ((fi2->offset + fi2->len) == fi->offset) { /* glue fragments together */ fi2->len += fi->len; list_del(lh); kfree(fi); } return 0; - } else if(offset > (fi->offset + fi->len)) { + } else if (offset > (fi->offset + fi->len)) { break; } else if ((offset + len) < fi->offset) { lh = lh->prev; @@ -801,7 +819,7 @@ } new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC); - if(!new) + if (!new) return -ENOMEM; new->offset = offset; @@ -820,12 +838,12 @@ struct partial_datagram *new; new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC); - if(!new) + if (!new) return -ENOMEM; INIT_LIST_HEAD(&new->frag_info); - if(new_fragment(&new->frag_info, frag_off, frag_len) < 0) { + if (new_fragment(&new->frag_info, frag_off, frag_len) < 0) { kfree(new); return -ENOMEM; } @@ -834,7 +852,7 @@ new->dg_size = dg_size; new->skb = dev_alloc_skb(dg_size + dev->hard_header_len + 15); - if(!new->skb) { + if (!new->skb) { struct fragment_info *fi = list_entry(new->frag_info.next, struct fragment_info, list); @@ -857,7 +875,7 @@ { struct partial_datagram *pd = list_entry(lh, struct partial_datagram, list); - if(new_fragment(&pd->frag_info, frag_off, frag_len) < 0) { + if (new_fragment(&pd->frag_info, frag_off, frag_len) < 0) { return -ENOMEM; } @@ -915,7 +933,7 @@ hdr_len = hdr_type_len[hdr->common.lf]; - if(hdr->common.lf == ETH1394_HDR_LF_UF) { + if (hdr->common.lf == ETH1394_HDR_LF_UF) { /* An unfragmented datagram has been received by the ieee1394 * bus. Build an skbuff around it so we can pass it to the * high level network layer. */ @@ -945,15 +963,15 @@ hdr->words.word3 = ntohs(hdr->words.word3); /* The 4th header word is reserved so no need to do ntohs() */ - if(hdr->common.lf == ETH1394_HDR_LF_FF) { + if (hdr->common.lf == ETH1394_HDR_LF_FF) { ether_type = hdr->ff.ether_type; dgl = hdr->ff.dgl; - dg_size = hdr->ff.dg_size; + dg_size = hdr->ff.dg_size + 1; fg_off = 0; } else { hdr->words.word2 = ntohs(hdr->words.word2); dgl = hdr->sf.dgl; - dg_size = hdr->sf.dg_size; + dg_size = hdr->sf.dg_size + 1; fg_off = hdr->sf.fg_off; } spin_lock_irqsave(&pdg->lock, flags); @@ -961,8 +979,8 @@ pdgl = &(pdg->list); lh = find_partial_datagram(pdgl, dgl); - if(lh == NULL) { - if(pdg->sz == max_partial_datagrams) { + if (lh == NULL) { + if (pdg->sz == max_partial_datagrams) { /* remove the oldest */ purge_partial_datagram(pdgl->prev); pdg->sz--; @@ -971,7 +989,7 @@ retval = new_partial_datagram(dev, pdgl, dgl, dg_size, buf + hdr_len, fg_off, fg_len); - if(retval < 0) { + if (retval < 0) { spin_unlock_irqrestore(&pdg->lock, flags); goto bad_proto; } @@ -982,7 +1000,7 @@ pd = list_entry(lh, struct partial_datagram, list); - if(fragment_overlap(&pd->frag_info, fg_off, fg_len)) { + if (fragment_overlap(&pd->frag_info, fg_off, fg_len)) { /* Overlapping fragments, obliterate old * datagram and start new one. */ purge_partial_datagram(lh); @@ -990,7 +1008,7 @@ dg_size, buf + hdr_len, fg_off, fg_len); - if(retval < 0) { + if (retval < 0) { pdg->sz--; spin_unlock_irqrestore(&pdg->lock, flags); goto bad_proto; @@ -999,7 +1017,7 @@ retval = update_partial_datagram(pdgl, lh, buf + hdr_len, fg_off, fg_len); - if(retval < 0) { + if (retval < 0) { /* Couldn't save off fragment anyway * so might as well obliterate the * datagram now. */ @@ -1013,11 +1031,11 @@ pd = list_entry(lh, struct partial_datagram, list); - if(hdr->common.lf == ETH1394_HDR_LF_FF) { + if (hdr->common.lf == ETH1394_HDR_LF_FF) { pd->ether_type = ether_type; } - if(is_datagram_complete(lh, dg_size)) { + if (is_datagram_complete(lh, dg_size)) { ether_type = pd->ether_type; pdg->sz--; skb = skb_get(pd->skb); @@ -1044,14 +1062,14 @@ spin_lock_irqsave(&priv->lock, flags); - if(!skb->protocol) { + if (!skb->protocol) { priv->stats.rx_errors++; priv->stats.rx_dropped++; dev_kfree_skb_any(skb); goto bad_proto; } - if(netif_rx(skb) == NET_RX_DROP) { + if (netif_rx(skb) == NET_RX_DROP) { priv->stats.rx_errors++; priv->stats.rx_dropped++; goto bad_proto; @@ -1062,7 +1080,7 @@ priv->stats.rx_bytes += skb->len; bad_proto: - if(netif_queue_stopped(dev)) + if (netif_queue_stopped(dev)) netif_wake_queue(dev); spin_unlock_irqrestore(&priv->lock, flags); @@ -1076,13 +1094,13 @@ { struct host_info *hi = hpsb_get_hostinfo(ð1394_highlevel, host); - if(hi == NULL) { + if (hi == NULL) { ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n", host->driver->name); return RCODE_ADDRESS_ERROR; } - if(ether1394_data_handler(hi->dev, srcid, destid, (char*)data, len)) + if (ether1394_data_handler(hi->dev, srcid, destid, (char*)data, len)) return RCODE_ADDRESS_ERROR; else return RCODE_COMPLETE; @@ -1101,7 +1119,7 @@ int i; int nready; - if(hi == NULL) { + if (hi == NULL) { ETH1394_PRINT_G(KERN_ERR, "Could not find net device for host %s\n", iso->host->driver->name); return; @@ -1110,7 +1128,7 @@ dev = hi->dev; nready = hpsb_iso_n_ready(iso); - for(i = 0; i < nready; i++) { + for (i = 0; i < nready; i++) { struct hpsb_iso_packet_info *info = &iso->infos[iso->first_packet + i]; data = (quadlet_t*) (iso->data_buf.kvirt + info->offset); @@ -1124,7 +1142,7 @@ priv = (struct eth1394_priv *)dev->priv; - if(info->channel != (iso->host->csr.broadcast_channel & 0x3f) || + if (info->channel != (iso->host->csr.broadcast_channel & 0x3f) || specifier_id != ETHER1394_GASP_SPECIFIER_ID) { /* This packet is not for us */ continue; @@ -1185,13 +1203,13 @@ unsigned int adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_UF]; /* Does it all fit in one packet? */ - if(dg_size <= adj_max_payload) { + if (dg_size <= adj_max_payload) { hdr->uf.lf = ETH1394_HDR_LF_UF; hdr->uf.ether_type = proto; } else { hdr->ff.lf = ETH1394_HDR_LF_FF; hdr->ff.ether_type = proto; - hdr->ff.dg_size = dg_size; + hdr->ff.dg_size = dg_size - 1; hdr->ff.dgl = dgl; adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF]; } @@ -1229,7 +1247,7 @@ default: hdr->sf.fg_off += adj_max_payload; bufhdr = (union eth1394_hdr *)skb_pull(skb, adj_max_payload); - if(max_payload >= skb->len) + if (max_payload >= skb->len) hdr->common.lf = ETH1394_HDR_LF_LF; bufhdr->words.word1 = htons(hdr->words.word1); bufhdr->words.word2 = htons(hdr->words.word2); @@ -1245,7 +1263,7 @@ struct hpsb_packet *p; p = alloc_hpsb_packet(0); - if(p) { + if (p) { p->host = host; p->data = NULL; p->generation = get_hpsb_generation(host); @@ -1269,8 +1287,9 @@ p->header_size = 16; p->expect_response = 1; - if(hpsb_get_tlabel(p, !in_interrupt())) { - ETH1394_PRINT_G(KERN_ERR, "No more tlabels left"); + if (hpsb_get_tlabel(p, !in_interrupt())) { + ETH1394_PRINT_G(KERN_ERR, "No more tlabels left while sending " + "to node " NODE_BUS_FMT "\n", NODE_BUS_ARGS(node)); return -1; } p->header[0] = (p->node_id << 16) | (p->tlabel << 10) @@ -1309,41 +1328,45 @@ static inline void ether1394_free_packet(struct hpsb_packet *packet) { + if (packet->tcode != TCODE_STREAM_DATA) + hpsb_free_tlabel(packet); packet->data = NULL; free_hpsb_packet(packet); } static void ether1394_complete_cb(void *__ptask); + static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) { struct eth1394_priv *priv = ptask->priv; - struct hpsb_packet *packet; + struct hpsb_packet *packet = NULL; packet = ether1394_alloc_common_packet(priv->host); - if(!packet) + if (!packet) return -1; - if(ptask->tx_type == ETH1394_GASP) { + if (ptask->tx_type == ETH1394_GASP) { int length = tx_len + (2 * sizeof(quadlet_t)); ether1394_prep_gasp_packet(packet, priv, ptask->skb, length); - - } else { - if(ether1394_prep_write_packet(packet, priv->host, + } else if (ether1394_prep_write_packet(packet, priv->host, ptask->dest_node, ptask->addr, ptask->skb->data, - tx_len)) - goto fail; + tx_len)) { + goto fail; } ptask->packet = packet; hpsb_set_packet_complete_task(ptask->packet, ether1394_complete_cb, ptask); - if(hpsb_send_packet(packet)) { + if (hpsb_send_packet(packet)) return 0; - } + fail: + if (packet) + ether1394_free_packet(packet); + return -1; } @@ -1357,7 +1380,7 @@ unsigned long flags; /* Statistics */ - if(fail) { + if (fail) { spin_lock_irqsave(&priv->lock, flags); priv->stats.tx_dropped++; priv->stats.tx_errors++; @@ -1382,22 +1405,20 @@ struct hpsb_packet *packet = ptask->packet; int fail = 0; - if(packet->tcode != TCODE_STREAM_DATA) { + if (packet->tcode != TCODE_STREAM_DATA) fail = hpsb_packet_success(packet); - hpsb_free_tlabel(packet); - } ether1394_free_packet(packet); ptask->outstanding_pkts--; - if(ptask->outstanding_pkts > 0 && !fail) + if (ptask->outstanding_pkts > 0 && !fail) { int tx_len; /* Add the encapsulation header to the fragment */ tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload, &ptask->hdr); - if(ether1394_send_packet(ptask, tx_len)) + if (ether1394_send_packet(ptask, tx_len)) ether1394_dg_complete(ptask, 1); } else { ether1394_dg_complete(ptask, fail); @@ -1424,14 +1445,8 @@ struct packet_task *ptask; struct node_entry *ne; - if (skb_is_nonlinear(skb)) { - ret = skb_linearize(skb, kmflags); - if(ret) - goto fail; - } - ptask = kmem_cache_alloc(packet_task_cache, kmflags); - if(ptask == NULL) { + if (ptask == NULL) { ret = -ENOMEM; goto fail; } @@ -1446,7 +1461,7 @@ } if (priv->bc_state == ETHER1394_BC_CHECK) { - if(ether1394_init_bc(dev)) { + if (ether1394_init_bc(dev)) { spin_unlock_irqrestore (&priv->lock, flags); goto fail; } @@ -1464,7 +1479,7 @@ skb_pull(skb, ETH1394_HLEN); ne = hpsb_guid_get_entry(be64_to_cpu(*(u64*)eth->h_dest)); - if(!ne) + if (!ne) dest_node = LOCAL_BUS | ALL_NODES; else dest_node = ne->nodeid; @@ -1479,7 +1494,7 @@ /* This check should be unnecessary, but we'll keep it for safety for * a while longer. */ - if(max_payload < 512) { + if (max_payload < 512) { ETH1394_PRINT(KERN_WARNING, dev->name, "max_payload too small: %d (setting to 512)\n", max_payload); @@ -1487,13 +1502,11 @@ } /* Set the transmission type for the packet. ARP packets and IP - * broadcast packets are sent via GASP, however, we cheat a little bit - * when detecting IP broadcast packets. This will need to change when - * we switch from using node id for the hardware address to the EUI - * which we should be using instead. IP multicast is not yet - * supported. */ - if((memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0) || - (proto == __constant_htons(ETH_P_ARP))) { + * broadcast packets are sent via GASP. */ + if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 || + proto == __constant_htons(ETH_P_ARP) || + (proto == __constant_htons(ETH_P_IP) && + IN_MULTICAST(__constant_ntohl(skb->nh.iph->daddr)))) { tx_type = ETH1394_GASP; max_payload -= ETHER1394_GASP_OVERHEAD; } else { @@ -1504,7 +1517,7 @@ spin_lock_irqsave (&priv->lock, flags); dgl = priv->dgl[NODEID_TO_NODE(dest_node)]; - if(max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) + if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) priv->dgl[NODEID_TO_NODE(dest_node)]++; spin_unlock_irqrestore (&priv->lock, flags); @@ -1516,14 +1529,14 @@ ptask->priv = priv; ptask->tx_type = tx_type; - if(tx_type != ETH1394_GASP) { + if (tx_type != ETH1394_GASP) { u64 addr; /* This test is just temporary until ConfigROM support has * been added to eth1394. Until then, we need an ARP packet * after a bus reset from the current destination node so that * we can get FIFO information. */ - if(priv->fifo[NODEID_TO_NODE(dest_node)] == 0ULL) { + if (priv->fifo[NODEID_TO_NODE(dest_node)] == 0ULL) { ret = -EAGAIN; goto fail; } @@ -1545,19 +1558,17 @@ /* Add the encapsulation header to the fragment */ tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr); dev->trans_start = jiffies; - if(ether1394_send_packet(ptask, tx_len)) + if (ether1394_send_packet(ptask, tx_len)) goto fail; netif_wake_queue(dev); return 0; fail: - if(ptask->packet) - ether1394_free_packet(ptask->packet); - if(ptask) + if (ptask) kmem_cache_free(packet_task_cache, ptask); - if(skb != NULL) { + + if (skb != NULL) dev_kfree_skb(skb); - } spin_lock_irqsave (&priv->lock, flags); priv->stats.tx_dropped++; @@ -1570,6 +1581,53 @@ return 0; /* returning non-zero causes serious problems */ } +static int ether1394_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + switch(cmd) { + case SIOCETHTOOL: + return ether1394_ethtool_ioctl(dev, (void *) ifr->ifr_data); + + case SIOCGMIIPHY: /* Get address of MII PHY in use. */ + case SIOCGMIIREG: /* Read MII PHY register. */ + case SIOCSMIIREG: /* Write MII PHY register. */ + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int ether1394_ethtool_ioctl(struct net_device *dev, void *useraddr) +{ + u32 ethcmd; + + if (get_user(ethcmd, (u32 *)useraddr)) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; + strcpy (info.driver, driver_name); + strcpy (info.version, "$Rev: 971 $"); + /* FIXME XXX provide sane businfo */ + strcpy (info.bus_info, "ieee1394"); + if (copy_to_user (useraddr, &info, sizeof (info))) + return -EFAULT; + break; + } + case ETHTOOL_GSET: + case ETHTOOL_SSET: + case ETHTOOL_NWAY_RST: + case ETHTOOL_GLINK: + case ETHTOOL_GMSGLVL: + case ETHTOOL_SMSGLVL: + default: + return -EOPNOTSUPP; + } + + return 0; +} + /* Function for incoming 1394 packets */ static struct hpsb_address_ops addr_ops = { .write = ether1394_write, @@ -1577,7 +1635,7 @@ /* Ieee1394 highlevel driver functions */ static struct hpsb_highlevel eth1394_highlevel = { - .name = ETHER1394_DRIVER_NAME, + .name = driver_name, .add_host = ether1394_add_host, .remove_host = ether1394_remove_host, .host_reset = ether1394_host_reset, diff -Nru a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h --- a/drivers/ieee1394/ieee1394.h Fri Jun 27 14:19:54 2003 +++ b/drivers/ieee1394/ieee1394.h Fri Jun 27 14:19:54 2003 @@ -46,14 +46,14 @@ #define ACKX_TIMEOUT (-4) -#define SPEED_100 0x00 -#define SPEED_200 0x01 -#define SPEED_400 0x02 -#define SPEED_800 0x03 -#define SPEED_1600 0x04 -#define SPEED_3200 0x05 +#define IEEE1394_SPEED_100 0x00 +#define IEEE1394_SPEED_200 0x01 +#define IEEE1394_SPEED_400 0x02 +#define IEEE1394_SPEED_800 0x03 +#define IEEE1394_SPEED_1600 0x04 +#define IEEE1394_SPEED_3200 0x05 /* The current highest tested speed supported by the subsystem */ -#define SPEED_MAX SPEED_800 +#define IEEE1394_SPEED_MAX IEEE1394_SPEED_800 /* Maps speed values above to a string representation */ extern const char *hpsb_speedto_str[]; diff -Nru a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c --- a/drivers/ieee1394/ieee1394_core.c Fri Jun 27 14:19:54 2003 +++ b/drivers/ieee1394/ieee1394_core.c Fri Jun 27 14:19:54 2003 @@ -289,7 +289,7 @@ for (i = 0; i < (nodecount * 64); i += 64) { for (j = 0; j < nodecount; j++) { - map[i+j] = SPEED_MAX; + map[i+j] = IEEE1394_SPEED_MAX; } } @@ -458,7 +458,7 @@ struct hpsb_packet *packet; int retval = 0; - if(rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 || + if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 || (rootid == -1 && gapcnt == -1)) { HPSB_DEBUG("Invalid Parameter: rootid = %d gapcnt = %d", rootid, gapcnt); @@ -470,22 +470,21 @@ return -ENOMEM; packet->host = host; - packet->header_size = 16; + packet->header_size = 8; packet->data_size = 0; packet->expect_response = 0; packet->no_waiter = 0; packet->type = hpsb_raw; packet->header[0] = 0; - if(rootid != -1) + if (rootid != -1) packet->header[0] |= rootid << 24 | 1 << 23; - if(gapcnt != -1) + if (gapcnt != -1) packet->header[0] |= gapcnt << 16 | 1 << 22; packet->header[1] = ~packet->header[0]; packet->generation = get_hpsb_generation(host); - HPSB_DEBUG("Sending PHY configuration packet (I hope)..."); if (!hpsb_send_packet(packet)) { retval = -EINVAL; goto fail; @@ -1030,12 +1029,12 @@ { int retval; - if( (blocknum < 0) || (blocknum > 15) ) + if ( (blocknum < 0) || (blocknum > 15) ) return -EINVAL; write_lock(&ieee1394_chardevs_lock); - if(ieee1394_chardevs[blocknum].file_ops == NULL) { + if (ieee1394_chardevs[blocknum].file_ops == NULL) { /* grab the minor block */ ieee1394_chardevs[blocknum].file_ops = file_ops; ieee1394_chardevs[blocknum].module = module; @@ -1054,12 +1053,12 @@ /* release a block of minor numbers */ void ieee1394_unregister_chardev(int blocknum) { - if( (blocknum < 0) || (blocknum > 15) ) + if ( (blocknum < 0) || (blocknum > 15) ) return; write_lock(&ieee1394_chardevs_lock); - if(ieee1394_chardevs[blocknum].file_ops) { + if (ieee1394_chardevs[blocknum].file_ops) { ieee1394_chardevs[blocknum].file_ops = NULL; ieee1394_chardevs[blocknum].module = NULL; } @@ -1139,7 +1138,7 @@ /* look up the driver */ - if(ieee1394_get_chardev(blocknum, &module, &file_ops) == 0) + if (ieee1394_get_chardev(blocknum, &module, &file_ops) == 0) return -ENODEV; /* redirect all subsequent requests to the driver's diff -Nru a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h --- a/drivers/ieee1394/ieee1394_core.h Fri Jun 27 14:19:54 2003 +++ b/drivers/ieee1394/ieee1394_core.h Fri Jun 27 14:19:54 2003 @@ -34,7 +34,7 @@ } __attribute__((packed)) state; /* These are core internal. */ - char tlabel; + signed char tlabel; char ack_code; char tcode; diff -Nru a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c --- a/drivers/ieee1394/ieee1394_transactions.c Fri Jun 27 14:19:55 2003 +++ b/drivers/ieee1394/ieee1394_transactions.c Fri Jun 27 14:19:55 2003 @@ -95,7 +95,7 @@ packet->data_size = 0; packet->expect_response = 0; packet->type = hpsb_raw; /* No CRC added */ - packet->speed_code = SPEED_100; /* Force speed to be 100Mbps */ + packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */ } static void fill_async_stream_packet(struct hpsb_packet *packet, int length, @@ -147,7 +147,7 @@ spin_lock_irqsave(&tp->lock, flags); packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next); - if(packet->tlabel > 63) + if (packet->tlabel > 63) packet->tlabel = find_first_zero_bit(tp->pool, 64); tp->next = (packet->tlabel + 1) % 64; /* Should _never_ happen */ diff -Nru a/drivers/ieee1394/ieee1394_types.h b/drivers/ieee1394/ieee1394_types.h --- a/drivers/ieee1394/ieee1394_types.h Fri Jun 27 14:19:59 2003 +++ b/drivers/ieee1394/ieee1394_types.h Fri Jun 27 14:19:59 2003 @@ -40,7 +40,7 @@ (_tp)->next = 0; \ (_tp)->allocations = 0; \ sema_init(&(_tp)->count, 63); \ -} while(0) +} while (0) typedef u32 quadlet_t; diff -Nru a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c --- a/drivers/ieee1394/iso.c Fri Jun 27 14:20:00 2003 +++ b/drivers/ieee1394/iso.c Fri Jun 27 14:20:00 2003 @@ -25,7 +25,7 @@ void hpsb_iso_shutdown(struct hpsb_iso *iso) { - if(iso->flags & HPSB_ISO_DRIVER_INIT) { + if (iso->flags & HPSB_ISO_DRIVER_INIT) { hpsb_iso_stop(iso); iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ? XMIT_SHUTDOWN : RECV_SHUTDOWN, 0); @@ -47,7 +47,7 @@ int dma_direction; /* make sure driver supports the ISO API */ - if(!host->driver->isoctl) { + if (!host->driver->isoctl) { printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n", host->driver->name); return NULL; @@ -55,23 +55,23 @@ /* sanitize parameters */ - if(buf_packets < 2) + if (buf_packets < 2) buf_packets = 2; - if(irq_interval < 1 || irq_interval > buf_packets / 2) + if (irq_interval < 1 || irq_interval > buf_packets / 2) irq_interval = buf_packets / 2; - if(channel < -1 || channel >= 64) + if (channel < -1 || channel >= 64) return NULL; /* channel = -1 is OK for multi-channel recv but not for xmit */ - if(type == HPSB_ISO_XMIT && channel < 0) + if (type == HPSB_ISO_XMIT && channel < 0) return NULL; /* allocate and write the struct hpsb_iso */ iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL); - if(!iso) + if (!iso) return NULL; iso->infos = (struct hpsb_iso_packet_info *)(iso + 1); @@ -90,7 +90,7 @@ iso->first_packet = 0; spin_lock_init(&iso->lock); - if(iso->type == HPSB_ISO_XMIT) { + if (iso->type == HPSB_ISO_XMIT) { iso->n_ready_packets = iso->buf_packets; dma_direction = PCI_DMA_TODEVICE; } else { @@ -103,7 +103,7 @@ iso->prebuffer = 0; /* allocate the packet buffer */ - if(dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) + if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction)) goto err; return iso; @@ -137,13 +137,13 @@ struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT, data_buf_size, buf_packets, channel, irq_interval, callback); - if(!iso) + if (!iso) return NULL; iso->speed = speed; /* tell the driver to start working */ - if(host->driver->isoctl(iso, XMIT_INIT, 0)) + if (host->driver->isoctl(iso, XMIT_INIT, 0)) goto err; iso->flags |= HPSB_ISO_DRIVER_INIT; @@ -164,11 +164,11 @@ struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV, data_buf_size, buf_packets, channel, irq_interval, callback); - if(!iso) + if (!iso) return NULL; /* tell the driver to start working */ - if(host->driver->isoctl(iso, RECV_INIT, 0)) + if (host->driver->isoctl(iso, RECV_INIT, 0)) goto err; iso->flags |= HPSB_ISO_DRIVER_INIT; @@ -181,21 +181,21 @@ int hpsb_iso_recv_listen_channel(struct hpsb_iso *iso, unsigned char channel) { - if(iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) + if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) return -EINVAL; return iso->host->driver->isoctl(iso, RECV_LISTEN_CHANNEL, channel); } int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel) { - if(iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) + if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64) return -EINVAL; return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel); } int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask) { - if(iso->type != HPSB_ISO_RECV || iso->channel != -1) + if (iso->type != HPSB_ISO_RECV || iso->channel != -1) return -EINVAL; return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask); } @@ -203,7 +203,7 @@ static int do_iso_xmit_start(struct hpsb_iso *iso, int cycle) { int retval = iso->host->driver->isoctl(iso, XMIT_START, cycle); - if(retval) + if (retval) return retval; iso->flags |= HPSB_ISO_DRIVER_STARTED; @@ -212,25 +212,25 @@ int hpsb_iso_xmit_start(struct hpsb_iso *iso, int cycle, int prebuffer) { - if(iso->type != HPSB_ISO_XMIT) + if (iso->type != HPSB_ISO_XMIT) return -1; - if(iso->flags & HPSB_ISO_DRIVER_STARTED) + if (iso->flags & HPSB_ISO_DRIVER_STARTED) return 0; - if(cycle < -1) + if (cycle < -1) cycle = -1; - else if(cycle >= 8000) + else if (cycle >= 8000) cycle %= 8000; iso->xmit_cycle = cycle; - if(prebuffer < 0) + if (prebuffer < 0) prebuffer = iso->buf_packets; - else if(prebuffer == 0) + else if (prebuffer == 0) prebuffer = 1; - if(prebuffer > iso->buf_packets) + if (prebuffer > iso->buf_packets) prebuffer = iso->buf_packets; iso->prebuffer = prebuffer; @@ -247,20 +247,20 @@ int retval = 0; int isoctl_args[3]; - if(iso->type != HPSB_ISO_RECV) + if (iso->type != HPSB_ISO_RECV) return -1; - if(iso->flags & HPSB_ISO_DRIVER_STARTED) + if (iso->flags & HPSB_ISO_DRIVER_STARTED) return 0; - if(cycle < -1) + if (cycle < -1) cycle = -1; - else if(cycle >= 8000) + else if (cycle >= 8000) cycle %= 8000; isoctl_args[0] = cycle; - if(tag_mask < 0) + if (tag_mask < 0) /* match all tags */ tag_mask = 0xF; isoctl_args[1] = tag_mask; @@ -268,7 +268,7 @@ isoctl_args[2] = sync; retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]); - if(retval) + if (retval) return retval; iso->flags |= HPSB_ISO_DRIVER_STARTED; @@ -282,15 +282,15 @@ unsigned int offset, unsigned short len, unsigned int *out_offset, unsigned short *out_len) { - if(offset >= iso->buf_size) + if (offset >= iso->buf_size) return -EFAULT; /* make sure the packet does not go beyond the end of the buffer */ - if(offset + len > iso->buf_size) + if (offset + len > iso->buf_size) return -EFAULT; /* check for wrap-around */ - if(offset + len < offset) + if (offset + len < offset) return -EFAULT; /* now we can trust 'offset' and 'length' */ @@ -307,18 +307,18 @@ unsigned long flags; int rv; - if(iso->type != HPSB_ISO_XMIT) + if (iso->type != HPSB_ISO_XMIT) return -EINVAL; /* is there space in the buffer? */ - if(iso->n_ready_packets <= 0) { + if (iso->n_ready_packets <= 0) { return -EBUSY; } info = &iso->infos[iso->first_packet]; /* check for bogus offset/length */ - if(hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len)) + if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len)) return -EFAULT; info->tag = tag; @@ -327,7 +327,7 @@ spin_lock_irqsave(&iso->lock, flags); rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info); - if(rv) + if (rv) goto out; /* increment cursors */ @@ -335,9 +335,9 @@ iso->xmit_cycle = (iso->xmit_cycle+1) % 8000; iso->n_ready_packets--; - if(iso->prebuffer != 0) { + if (iso->prebuffer != 0) { iso->prebuffer--; - if(iso->prebuffer <= 0) { + if (iso->prebuffer <= 0) { iso->prebuffer = 0; rv = do_iso_xmit_start(iso, iso->start_cycle); } @@ -350,7 +350,7 @@ int hpsb_iso_xmit_sync(struct hpsb_iso *iso) { - if(iso->type != HPSB_ISO_XMIT) + if (iso->type != HPSB_ISO_XMIT) return -EINVAL; return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets); @@ -371,7 +371,7 @@ iso->n_ready_packets++; iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets; - if(iso->n_ready_packets == iso->buf_packets || error != 0) { + if (iso->n_ready_packets == iso->buf_packets || error != 0) { /* the buffer has run empty! */ atomic_inc(&iso->overflows); } @@ -385,7 +385,7 @@ unsigned long flags; spin_lock_irqsave(&iso->lock, flags); - if(iso->n_ready_packets == iso->buf_packets) { + if (iso->n_ready_packets == iso->buf_packets) { /* overflow! */ atomic_inc(&iso->overflows); } else { @@ -410,14 +410,14 @@ unsigned int i; int rv = 0; - if(iso->type != HPSB_ISO_RECV) + if (iso->type != HPSB_ISO_RECV) return -1; spin_lock_irqsave(&iso->lock, flags); - for(i = 0; i < n_packets; i++) { + for (i = 0; i < n_packets; i++) { rv = iso->host->driver->isoctl(iso, RECV_RELEASE, (unsigned long) &iso->infos[iso->first_packet]); - if(rv) + if (rv) break; iso->first_packet = (iso->first_packet+1) % iso->buf_packets; @@ -431,6 +431,6 @@ { wake_up_interruptible(&iso->waitq); - if(iso->callback) + if (iso->callback) iso->callback(iso); } diff -Nru a/drivers/ieee1394/iso.h b/drivers/ieee1394/iso.h --- a/drivers/ieee1394/iso.h Fri Jun 27 14:20:02 2003 +++ b/drivers/ieee1394/iso.h Fri Jun 27 14:20:02 2003 @@ -66,7 +66,7 @@ /* wait for buffer space */ wait_queue_head_t waitq; - int speed; /* SPEED_100, 200, or 400 */ + int speed; /* IEEE1394_SPEED_100, 200, or 400 */ int channel; /* -1 if multichannel */ /* greatest # of packets between interrupts - controls diff -Nru a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c --- a/drivers/ieee1394/nodemgr.c Fri Jun 27 14:19:58 2003 +++ b/drivers/ieee1394/nodemgr.c Fri Jun 27 14:19:58 2003 @@ -1167,7 +1167,7 @@ return -ENOMEM; \ ++length; \ scratch = buffer + length; \ -} while(0) +} while (0) PUT_ENVP("VENDOR_ID=%06x", ud->vendor_id); PUT_ENVP("MODEL_ID=%06x", ud->model_id); @@ -1547,12 +1547,12 @@ /* If there is no bus manager then we should set the root node's * force_root bit to promote bus stability per the 1394 * spec. (8.4.2.6) */ - if (host->busmgr_id == 0x3f && host->node_count > 1) + if (host->busmgr_id == 0xffff && host->node_count > 1) { u16 root_node = host->node_count - 1; - struct node_entry *ne = hpsb_nodeid_get_entry(host, root_node); + struct node_entry *ne = find_entry_by_nodeid(host, root_node | LOCAL_BUS); - if (ne->busopt.cmc) + if (ne && ne->busopt.cmc) hpsb_send_phy_config(host, root_node, -1); else { HPSB_DEBUG("The root node is not cycle master capable; " diff -Nru a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c --- a/drivers/ieee1394/ohci1394.c Fri Jun 27 14:20:01 2003 +++ b/drivers/ieee1394/ohci1394.c Fri Jun 27 14:20:01 2003 @@ -164,7 +164,7 @@ printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args) static char version[] __devinitdata = - "$Rev: 948 $ Ben Collins <bcollins@debian.org>"; + "$Rev: 952 $ Ben Collins <bcollins@debian.org>"; /* Module Parameters */ static int phys_dma = 1; @@ -428,7 +428,7 @@ d->buf_ind = 0; d->buf_offset = 0; - if(d->type == DMA_CTX_ISO) { + if (d->type == DMA_CTX_ISO) { /* Clear contextControl */ reg_write(ohci, d->ctrlClear, 0xffffffff); @@ -470,7 +470,7 @@ INIT_LIST_HEAD(&d->fifo_list); INIT_LIST_HEAD(&d->pending_list); - if(d->type == DMA_CTX_ISO) { + if (d->type == DMA_CTX_ISO) { /* enable interrupts */ reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, 1 << d->ctx); } @@ -490,8 +490,8 @@ DBGMSG(ohci->id,"Iso contexts reg: %08x implemented: %08x", reg, tmp); /* Count the number of contexts */ - for(i=0; i<32; i++) { - if(tmp & 1) ctx++; + for (i=0; i<32; i++) { + if (tmp & 1) ctx++; tmp >>= 1; } return ctx; @@ -856,8 +856,8 @@ * case. I don't see anyone sending ISO packets from * interrupt context anyway... */ - if(ohci->it_legacy_context.ohci == NULL) { - if(in_interrupt()) { + if (ohci->it_legacy_context.ohci == NULL) { + if (in_interrupt()) { PRINT(KERN_ERR, ohci->id, "legacy IT context cannot be initialized during interrupt"); return 0; @@ -1074,7 +1074,7 @@ spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); DBGMSG(ohci->id, "Listening disabled on channel %d", arg); - if(ohci->ir_legacy_channels == 0) { + if (ohci->ir_legacy_channels == 0) { free_dma_rcv_ctx(&ohci->ir_legacy_context); DBGMSG(ohci->id, "ISO receive legacy context deactivated"); } @@ -1162,7 +1162,7 @@ int ret = -ENOMEM; recv = kmalloc(sizeof(*recv), SLAB_KERNEL); - if(!recv) + if (!recv) return -ENOMEM; iso->hostdata = recv; @@ -1174,7 +1174,7 @@ /* use buffer-fill mode, unless irq_interval is 1 (note: multichannel requires buffer-fill) */ - if(iso->irq_interval == 1 && iso->channel != -1) { + if (iso->irq_interval == 1 && iso->channel != -1) { recv->dma_mode = PACKET_PER_BUFFER_MODE; } else { recv->dma_mode = BUFFER_FILL_MODE; @@ -1182,12 +1182,12 @@ /* set nblocks, buf_stride, block_irq_interval */ - if(recv->dma_mode == BUFFER_FILL_MODE) { + if (recv->dma_mode == BUFFER_FILL_MODE) { recv->buf_stride = PAGE_SIZE; /* one block per page of data in the DMA buffer, minus the final guard page */ recv->nblocks = iso->buf_size/PAGE_SIZE - 1; - if(recv->nblocks < 3) { + if (recv->nblocks < 3) { DBGMSG(ohci->id, "ohci_iso_recv_init: DMA buffer too small"); goto err; } @@ -1195,9 +1195,9 @@ /* iso->irq_interval is in packets - translate that to blocks */ /* (err, sort of... 1 is always the safest value) */ recv->block_irq_interval = iso->irq_interval / recv->nblocks; - if(recv->block_irq_interval*4 > recv->nblocks) + if (recv->block_irq_interval*4 > recv->nblocks) recv->block_irq_interval = recv->nblocks/4; - if(recv->block_irq_interval < 1) + if (recv->block_irq_interval < 1) recv->block_irq_interval = 1; } else { @@ -1211,10 +1211,10 @@ max_packet_size = iso->buf_size / iso->buf_packets; - for(recv->buf_stride = 8; recv->buf_stride < max_packet_size; + for (recv->buf_stride = 8; recv->buf_stride < max_packet_size; recv->buf_stride *= 2); - if(recv->buf_stride*iso->buf_packets > iso->buf_size || + if (recv->buf_stride*iso->buf_packets > iso->buf_size || recv->buf_stride > PAGE_SIZE) { /* this shouldn't happen, but anyway... */ DBGMSG(ohci->id, "ohci_iso_recv_init: problem choosing a buffer stride"); @@ -1243,7 +1243,7 @@ ohci_iso_recv_packetperbuf_task, (unsigned long) iso); - if(ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) + if (ohci1394_register_iso_tasklet(recv->ohci, &recv->task) < 0) goto err; recv->task_active = 1; @@ -1255,7 +1255,7 @@ recv->CommandPtr = OHCI1394_IsoRcvCommandPtr + 32 * ctx; recv->ContextMatch = OHCI1394_IsoRcvContextMatch + 32 * ctx; - if(iso->channel == -1) { + if (iso->channel == -1) { /* clear multi-channel selection mask */ reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, 0xFFFFFFFF); reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, 0xFFFFFFFF); @@ -1293,7 +1293,7 @@ { struct ohci_iso_recv *recv = iso->hostdata; - if(recv->task_active) { + if (recv->task_active) { ohci_iso_recv_stop(iso); ohci1394_unregister_iso_tasklet(recv->ohci, &recv->task); recv->task_active = 0; @@ -1363,7 +1363,7 @@ struct ohci_iso_recv *recv = iso->hostdata; int reg, i; - if(channel < 32) { + if (channel < 32) { reg = listen ? OHCI1394_IRMultiChanMaskLoSet : OHCI1394_IRMultiChanMaskLoClear; i = channel; } else { @@ -1383,14 +1383,14 @@ struct ohci_iso_recv *recv = iso->hostdata; int i; - for(i = 0; i < 64; i++) { - if(mask & (1ULL << i)) { - if(i < 32) + for (i = 0; i < 64; i++) { + if (mask & (1ULL << i)) { + if (i < 32) reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoSet, (1 << i)); else reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiSet, (1 << (i-32))); } else { - if(i < 32) + if (i < 32) reg_write(recv->ohci, OHCI1394_IRMultiChanMaskLoClear, (1 << i)); else reg_write(recv->ohci, OHCI1394_IRMultiChanMaskHiClear, (1 << (i-32))); @@ -1413,7 +1413,7 @@ /* always keep ISO headers */ command = (1 << 30); - if(recv->dma_mode == BUFFER_FILL_MODE) + if (recv->dma_mode == BUFFER_FILL_MODE) command |= (1 << 31); reg_write(recv->ohci, recv->ContextControlSet, command); @@ -1421,7 +1421,7 @@ /* match on specified tags */ contextMatch = tag_mask << 28; - if(iso->channel == -1) { + if (iso->channel == -1) { /* enable multichannel reception */ reg_write(recv->ohci, recv->ContextControlSet, (1 << 28)); } else { @@ -1429,7 +1429,7 @@ contextMatch |= iso->channel; } - if(cycle != -1) { + if (cycle != -1) { u32 seconds; /* enable cycleMatch */ @@ -1450,7 +1450,7 @@ contextMatch |= cycle << 12; } - if(sync != -1) { + if (sync != -1) { /* set sync flag on first DMA descriptor */ struct dma_cmd *cmd = &recv->block[recv->block_dma]; cmd->control |= DMA_CTL_WAIT; @@ -1482,7 +1482,7 @@ reg_read(recv->ohci, OHCI1394_IsochronousCycleTimer); /* check RUN */ - if(!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) { + if (!(reg_read(recv->ohci, recv->ContextControlSet) & 0x8000)) { PRINT(KERN_ERR, recv->ohci->id, "Error starting IR DMA (ContextControl 0x%08x)\n", reg_read(recv->ohci, recv->ContextControlSet)); @@ -1515,7 +1515,7 @@ | 1); /* Z=1 */ /* disable interrupt on previous DMA descriptor, except at intervals */ - if((prev_i % recv->block_irq_interval) == 0) { + if ((prev_i % recv->block_irq_interval) == 0) { prev->control |= cpu_to_le32(3 << 20); /* enable interrupt */ } else { prev->control &= cpu_to_le32(~(3<<20)); /* disable interrupt */ @@ -1535,7 +1535,7 @@ len = info->len; /* add the wasted space for padding to 4 bytes */ - if(len % 4) + if (len % 4) len += 4 - (len % 4); /* add 8 bytes for the OHCI DMA data format overhead */ @@ -1544,7 +1544,7 @@ recv->released_bytes += len; /* have we released enough memory for one block? */ - while(recv->released_bytes > recv->buf_stride) { + while (recv->released_bytes > recv->buf_stride) { ohci_iso_recv_release_block(recv, recv->block_reader); recv->block_reader = (recv->block_reader + 1) % recv->nblocks; recv->released_bytes -= recv->buf_stride; @@ -1554,7 +1554,7 @@ static inline void ohci_iso_recv_release(struct hpsb_iso *iso, struct hpsb_iso_packet_info *info) { struct ohci_iso_recv *recv = iso->hostdata; - if(recv->dma_mode == BUFFER_FILL_MODE) { + if (recv->dma_mode == BUFFER_FILL_MODE) { ohci_iso_recv_bufferfill_release(recv, info); } else { ohci_iso_recv_release_block(recv, info - iso->infos); @@ -1567,7 +1567,7 @@ int wake = 0; int runaway = 0; - while(1) { + while (1) { /* we expect the next parsable packet to begin at recv->dma_offset */ /* note: packet layout is as shown in section 10.6.1.1 of the OHCI spec */ @@ -1580,7 +1580,7 @@ unsigned int this_block = recv->dma_offset/recv->buf_stride; /* don't loop indefinitely */ - if(runaway++ > 100000) { + if (runaway++ > 100000) { atomic_inc(&iso->overflows); PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - Runaway during buffer parsing!\n"); @@ -1588,7 +1588,7 @@ } /* stop parsing once we arrive at block_dma (i.e. don't get ahead of DMA) */ - if(this_block == recv->block_dma) + if (this_block == recv->block_dma) break; wake = 1; @@ -1600,7 +1600,7 @@ len = p[recv->dma_offset+2] | (p[recv->dma_offset+3] << 8); - if(len > 4096) { + if (len > 4096) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - bogus 'len' value %u\n", len); } @@ -1613,7 +1613,7 @@ recv->dma_offset += 4; /* check for wrap-around */ - if(recv->dma_offset >= recv->buf_stride*recv->nblocks) { + if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { recv->dma_offset -= recv->buf_stride*recv->nblocks; } @@ -1624,12 +1624,12 @@ recv->dma_offset += len; /* payload is padded to 4 bytes */ - if(len % 4) { + if (len % 4) { recv->dma_offset += 4 - (len%4); } /* check for wrap-around */ - if(recv->dma_offset >= recv->buf_stride*recv->nblocks) { + if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { /* uh oh, the packet data wraps from the last to the first DMA block - make the packet contiguous by copying its "tail" into the @@ -1638,7 +1638,7 @@ int guard_off = recv->buf_stride*recv->nblocks; int tail_len = len - (guard_off - offset); - if(tail_len > 0 && tail_len < recv->buf_stride) { + if (tail_len > 0 && tail_len < recv->buf_stride) { memcpy(iso->data_buf.kvirt + guard_off, iso->data_buf.kvirt, tail_len); @@ -1655,14 +1655,14 @@ recv->dma_offset += 4; /* check for wrap-around */ - if(recv->dma_offset >= recv->buf_stride*recv->nblocks) { + if (recv->dma_offset >= recv->buf_stride*recv->nblocks) { recv->dma_offset -= recv->buf_stride*recv->nblocks; } hpsb_iso_packet_received(iso, offset, len, cycle, channel, tag, sy); } - if(wake) + if (wake) hpsb_iso_wake(iso); } @@ -1674,7 +1674,7 @@ int loop; /* loop over all blocks */ - for(loop = 0; loop < recv->nblocks; loop++) { + for (loop = 0; loop < recv->nblocks; loop++) { /* check block_dma to see if it's done */ @@ -1688,18 +1688,18 @@ unsigned char event = xferstatus & 0x1F; - if(!event) { + if (!event) { /* nothing has happened to this block yet */ break; } - if(event != 0x11) { + if (event != 0x11) { atomic_inc(&iso->overflows); PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - OHCI error code 0x%02x\n", event); } - if(rescount != 0) { + if (rescount != 0) { /* the card is still writing to this block; we can't touch it until it's done */ break; @@ -1716,7 +1716,7 @@ /* advance block_dma */ recv->block_dma = (recv->block_dma + 1) % recv->nblocks; - if((recv->block_dma+1) % recv->nblocks == recv->block_reader) { + if ((recv->block_dma+1) % recv->nblocks == recv->block_reader) { atomic_inc(&iso->overflows); DBGMSG(recv->ohci->id, "ISO reception overflow - " "ran out of DMA blocks"); @@ -1735,7 +1735,7 @@ int wake = 0; /* loop over the entire buffer */ - for(count = 0; count < recv->nblocks; count++) { + for (count = 0; count < recv->nblocks; count++) { u32 packet_len = 0; /* pointer to the DMA descriptor */ @@ -1747,21 +1747,21 @@ unsigned char event = xferstatus & 0x1F; - if(!event) { + if (!event) { /* this packet hasn't come in yet; we are done for now */ goto out; } - if(event == 0x11) { + if (event == 0x11) { /* packet received successfully! */ /* rescount is the number of bytes *remaining* in the packet buffer, after the packet was written */ packet_len = recv->buf_stride - rescount; - } else if(event == 0x02) { + } else if (event == 0x02) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - packet too long for buffer\n"); - } else if(event) { + } else if (event) { PRINT(KERN_ERR, recv->ohci->id, "IR DMA error - OHCI error code 0x%02x\n", event); } @@ -1800,7 +1800,7 @@ } out: - if(wake) + if (wake) hpsb_iso_wake(iso); } @@ -1844,7 +1844,7 @@ int ret = -ENOMEM; xmit = kmalloc(sizeof(*xmit), SLAB_KERNEL); - if(!xmit) + if (!xmit) return -ENOMEM; iso->hostdata = xmit; @@ -1855,13 +1855,13 @@ prog_size = sizeof(struct iso_xmit_cmd) * iso->buf_packets; - if(dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev)) + if (dma_prog_region_alloc(&xmit->prog, prog_size, xmit->ohci->dev)) goto err; ohci1394_init_iso_tasklet(&xmit->task, OHCI_ISO_TRANSMIT, ohci_iso_xmit_task, (unsigned long) iso); - if(ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) + if (ohci1394_register_iso_tasklet(xmit->ohci, &xmit->task) < 0) goto err; xmit->task_active = 1; @@ -1887,7 +1887,7 @@ reg_write(xmit->ohci, OHCI1394_IsoXmitIntMaskClear, 1 << xmit->task.context); /* halt DMA */ - if(ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) { + if (ohci1394_stop_context(xmit->ohci, xmit->ContextControlClear, NULL)) { /* XXX the DMA context will lock up if you try to send too much data! */ PRINT(KERN_ERR, xmit->ohci->id, "you probably exceeded the OHCI card's bandwidth limit - " @@ -1899,7 +1899,7 @@ { struct ohci_iso_xmit *xmit = iso->hostdata; - if(xmit->task_active) { + if (xmit->task_active) { ohci_iso_xmit_stop(iso); ohci1394_unregister_iso_tasklet(xmit->ohci, &xmit->task); xmit->task_active = 0; @@ -1918,7 +1918,7 @@ int count; /* check the whole buffer if necessary, starting at pkt_dma */ - for(count = 0; count < iso->buf_packets; count++) { + for (count = 0; count < iso->buf_packets; count++) { int cycle; /* DMA descriptor */ @@ -1928,12 +1928,12 @@ u16 xferstatus = le32_to_cpu(cmd->output_last.status) >> 16; u8 event = xferstatus & 0x1F; - if(!event) { + if (!event) { /* packet hasn't been sent yet; we are done for now */ break; } - if(event != 0x11) + if (event != 0x11) PRINT(KERN_ERR, xmit->ohci->id, "IT DMA error - OHCI error code 0x%02x\n", event); @@ -1950,7 +1950,7 @@ cmd->output_last.status = 0; } - if(wake) + if (wake) hpsb_iso_wake(iso); } @@ -1967,7 +1967,7 @@ /* check that the packet doesn't cross a page boundary (we could allow this if we added OUTPUT_MORE descriptor support) */ - if(cross_bound(info->offset, info->len)) { + if (cross_bound(info->offset, info->len)) { PRINT(KERN_ERR, xmit->ohci->id, "rawiso xmit: packet %u crosses a page boundary", iso->first_packet); @@ -2030,7 +2030,7 @@ dma_prog_region_offset_to_bus(&xmit->prog, sizeof(struct iso_xmit_cmd) * next_i) | 3); /* disable interrupt, unless required by the IRQ interval */ - if(prev_i % iso->irq_interval) { + if (prev_i % iso->irq_interval) { prev->output_last.control &= cpu_to_le32(~(3 << 20)); /* no interrupt */ } else { prev->output_last.control |= cpu_to_le32(3 << 20); /* enable interrupt */ @@ -2062,7 +2062,7 @@ dma_prog_region_offset_to_bus(&xmit->prog, iso->pkt_dma * sizeof(struct iso_xmit_cmd)) | 3); /* cycle match */ - if(cycle != -1) { + if (cycle != -1) { u32 start = cycle & 0x1FFF; /* 'cycle' is only mod 8000, but we also need two 'seconds' bits - @@ -2088,7 +2088,7 @@ udelay(100); /* check the RUN bit */ - if(!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) { + if (!(reg_read(xmit->ohci, xmit->ContextControlSet) & 0x8000)) { PRINT(KERN_ERR, xmit->ohci->id, "Error starting IT DMA (ContextControl 0x%08x)\n", reg_read(xmit->ohci, xmit->ContextControlSet)); return -1; @@ -2694,7 +2694,7 @@ #ifdef OHCI1394_DEBUG if (datasize) - if(((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa) + if (((le32_to_cpu(d->prg_cpu[d->sent_ind]->data[0])>>4)&0xf) == 0xa) DBGMSG(ohci->id, "Stream packet sent to channel %d tcode=0x%X " "ack=0x%X spd=%d dataLength=%d ctx=%d", @@ -2807,7 +2807,7 @@ DBGMSG(d->ohci->id, "Freeing dma_rcv_ctx %d", d->ctx); - if(d->ctrlClear) { + if (d->ctrlClear) { ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); if (d->type == DMA_CTX_ISO) { @@ -2969,7 +2969,7 @@ DBGMSG(d->ohci->id, "Freeing dma_trm_ctx %d", d->ctx); - if(d->ctrlClear) { + if (d->ctrlClear) { ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); if (d->type == DMA_CTX_ISO) { @@ -3261,7 +3261,7 @@ PRINT_G(KERN_ERR, fmt , ## args); \ ohci1394_pci_remove(dev); \ return err; \ -} while(0) +} while (0) static int __devinit ohci1394_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) @@ -3624,8 +3624,8 @@ usage = &ohci->ir_ctx_usage; /* only one receive context can be multichannel (OHCI sec 10.4.1) */ - if(tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { - if(test_and_set_bit(0, &ohci->ir_multichannel_used)) { + if (tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { + if (test_and_set_bit(0, &ohci->ir_multichannel_used)) { return r; } } @@ -3660,7 +3660,7 @@ else { clear_bit(tasklet->context, &ohci->ir_ctx_usage); - if(tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { + if (tasklet->type == OHCI_ISO_MULTICHANNEL_RECEIVE) { clear_bit(0, &ohci->ir_multichannel_used); } } diff -Nru a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c --- a/drivers/ieee1394/raw1394.c Fri Jun 27 14:19:52 2003 +++ b/drivers/ieee1394/raw1394.c Fri Jun 27 14:19:52 2003 @@ -601,7 +601,7 @@ if (fi->listen_channels & (1ULL << channel)) { req->req.error = RAW1394_ERROR_ALREADY; } else { - if(hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) { + if (hpsb_listen_channel(&raw1394_highlevel, fi->host, channel)) { req->req.error = RAW1394_ERROR_ALREADY; } else { fi->listen_channels |= 1ULL << channel; @@ -2008,7 +2008,7 @@ list_for_each(lh, &fi->req_complete) { req = list_entry(lh, struct pending_request, list); - if(req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) { + if (req->req.type == RAW1394_REQ_RAWISO_ACTIVITY) { return 1; } } @@ -2024,17 +2024,17 @@ spin_lock_irqsave(&fi->reqlists_lock, flags); /* only one ISO activity event may be in the queue */ - if(!__rawiso_event_in_queue(fi)) { + if (!__rawiso_event_in_queue(fi)) { struct pending_request *req = __alloc_pending_request(SLAB_ATOMIC); - if(req) { + if (req) { req->file_info = fi; req->req.type = RAW1394_REQ_RAWISO_ACTIVITY; req->req.generation = get_hpsb_generation(fi->host); __queue_complete_req(req); } else { /* on allocation failure, signal an overflow */ - if(fi->iso_handle) { + if (fi->iso_handle) { atomic_inc(&fi->iso_handle->overflows); } } @@ -2054,7 +2054,7 @@ if (hi != NULL) { list_for_each(lh, &hi->file_info_list) { struct file_info *fi = list_entry(lh, struct file_info, list); - if(fi->iso_handle == iso) + if (fi->iso_handle == iso) queue_rawiso_event(fi); } } @@ -2079,7 +2079,7 @@ { struct raw1394_iso_status stat; - if(copy_from_user(&stat, uaddr, sizeof(stat))) + if (copy_from_user(&stat, uaddr, sizeof(stat))) return -EFAULT; fi->iso_handle = hpsb_iso_xmit_init(fi->host, @@ -2089,13 +2089,13 @@ stat.config.speed, stat.config.irq_interval, rawiso_activity_cb); - if(!fi->iso_handle) + if (!fi->iso_handle) return -ENOMEM; fi->iso_state = RAW1394_ISO_XMIT; raw1394_iso_fill_status(fi->iso_handle, &stat); - if(copy_to_user(uaddr, &stat, sizeof(stat))) + if (copy_to_user(uaddr, &stat, sizeof(stat))) return -EFAULT; /* queue an event to get things started */ @@ -2108,7 +2108,7 @@ { struct raw1394_iso_status stat; - if(copy_from_user(&stat, uaddr, sizeof(stat))) + if (copy_from_user(&stat, uaddr, sizeof(stat))) return -EFAULT; fi->iso_handle = hpsb_iso_recv_init(fi->host, @@ -2117,13 +2117,13 @@ stat.config.channel, stat.config.irq_interval, rawiso_activity_cb); - if(!fi->iso_handle) + if (!fi->iso_handle) return -ENOMEM; fi->iso_state = RAW1394_ISO_RECV; raw1394_iso_fill_status(fi->iso_handle, &stat); - if(copy_to_user(uaddr, &stat, sizeof(stat))) + if (copy_to_user(uaddr, &stat, sizeof(stat))) return -EFAULT; return 0; } @@ -2134,7 +2134,7 @@ struct hpsb_iso *iso = fi->iso_handle; raw1394_iso_fill_status(fi->iso_handle, &stat); - if(copy_to_user(uaddr, &stat, sizeof(stat))) + if (copy_to_user(uaddr, &stat, sizeof(stat))) return -EFAULT; /* reset overflow counter */ @@ -2150,20 +2150,20 @@ unsigned int packet = fi->iso_handle->first_packet; int i; - if(copy_from_user(&upackets, uaddr, sizeof(upackets))) + if (copy_from_user(&upackets, uaddr, sizeof(upackets))) return -EFAULT; - if(upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) + if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) return -EINVAL; /* ensure user-supplied buffer is accessible and big enough */ - if(verify_area(VERIFY_WRITE, upackets.infos, + if (verify_area(VERIFY_WRITE, upackets.infos, upackets.n_packets * sizeof(struct raw1394_iso_packet_info))) return -EFAULT; /* copy the packet_infos out */ - for(i = 0; i < upackets.n_packets; i++) { - if(__copy_to_user(&upackets.infos[i], + for (i = 0; i < upackets.n_packets; i++) { + if (__copy_to_user(&upackets.infos[i], &fi->iso_handle->infos[packet], sizeof(struct raw1394_iso_packet_info))) return -EFAULT; @@ -2180,28 +2180,28 @@ struct raw1394_iso_packets upackets; int i, rv; - if(copy_from_user(&upackets, uaddr, sizeof(upackets))) + if (copy_from_user(&upackets, uaddr, sizeof(upackets))) return -EFAULT; - if(upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) + if (upackets.n_packets > hpsb_iso_n_ready(fi->iso_handle)) return -EINVAL; /* ensure user-supplied buffer is accessible and big enough */ - if(verify_area(VERIFY_READ, upackets.infos, + if (verify_area(VERIFY_READ, upackets.infos, upackets.n_packets * sizeof(struct raw1394_iso_packet_info))) return -EFAULT; /* copy the infos structs in and queue the packets */ - for(i = 0; i < upackets.n_packets; i++) { + for (i = 0; i < upackets.n_packets; i++) { struct raw1394_iso_packet_info info; - if(__copy_from_user(&info, &upackets.infos[i], + if (__copy_from_user(&info, &upackets.infos[i], sizeof(struct raw1394_iso_packet_info))) return -EFAULT; rv = hpsb_iso_xmit_queue_packet(fi->iso_handle, info.offset, info.len, info.tag, info.sy); - if(rv) + if (rv) return rv; } @@ -2210,7 +2210,7 @@ static void raw1394_iso_shutdown(struct file_info *fi) { - if(fi->iso_handle) + if (fi->iso_handle) hpsb_iso_shutdown(fi->iso_handle); fi->iso_handle = NULL; @@ -2222,7 +2222,7 @@ { struct file_info *fi = file->private_data; - if(fi->iso_state == RAW1394_ISO_INACTIVE) + if (fi->iso_state == RAW1394_ISO_INACTIVE) return -EINVAL; return dma_region_mmap(&fi->iso_handle->data_buf, file, vma); @@ -2249,7 +2249,7 @@ case RAW1394_IOC_ISO_RECV_START: { /* copy args from user-space */ int args[3]; - if(copy_from_user(&args[0], (void*) arg, sizeof(args))) + if (copy_from_user(&args[0], (void*) arg, sizeof(args))) return -EFAULT; return hpsb_iso_recv_start(fi->iso_handle, args[0], args[1], args[2]); } @@ -2263,7 +2263,7 @@ case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: { /* copy the u64 from user-space */ u64 mask; - if(copy_from_user(&mask, (void*) arg, sizeof(mask))) + if (copy_from_user(&mask, (void*) arg, sizeof(mask))) return -EFAULT; return hpsb_iso_recv_set_channel_mask(fi->iso_handle, mask); } @@ -2286,7 +2286,7 @@ case RAW1394_IOC_ISO_XMIT_START: { /* copy two ints from user-space */ int args[2]; - if(copy_from_user(&args[0], (void*) arg, sizeof(args))) + if (copy_from_user(&args[0], (void*) arg, sizeof(args))) return -EFAULT; return hpsb_iso_xmit_start(fi->iso_handle, args[0], args[1]); } @@ -2374,7 +2374,7 @@ struct arm_addr *arm_addr = NULL; int another_host; - if(fi->iso_state != RAW1394_ISO_INACTIVE) + if (fi->iso_state != RAW1394_ISO_INACTIVE) raw1394_iso_shutdown(fi); for (i = 0; i < 64; i++) { diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c --- a/drivers/ieee1394/sbp2.c Fri Jun 27 14:19:53 2003 +++ b/drivers/ieee1394/sbp2.c Fri Jun 27 14:19:53 2003 @@ -79,7 +79,7 @@ #include "sbp2.h" static char version[] __devinitdata = - "$Rev: 942 $ Ben Collins <bcollins@debian.org>"; + "$Rev: 967 $ Ben Collins <bcollins@debian.org>"; /* * Module load parameter definitions @@ -93,7 +93,7 @@ * (probably due to PCI latency/throughput issues with the part). You can * bump down the speed if you are running into problems. */ -static int max_speed = SPEED_MAX; +static int max_speed = IEEE1394_SPEED_MAX; module_param(max_speed, int, 0644); MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb default, 1 = 200mb, 0 = 100mb)"); @@ -780,8 +780,8 @@ scsi_id->ne = ud->ne; scsi_id->hi = hi; - scsi_id->speed_code = SPEED_100; - scsi_id->max_payload_size = sbp2_speedto_max_payload[SPEED_100]; + scsi_id->speed_code = IEEE1394_SPEED_100; + scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; atomic_set(&scsi_id->sbp2_login_complete, 0); INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); diff -Nru a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c --- a/drivers/ieee1394/video1394.c Fri Jun 27 14:19:54 2003 +++ b/drivers/ieee1394/video1394.c Fri Jun 27 14:19:54 2003 @@ -589,7 +589,7 @@ it_prg[i].begin.status = 0; it_prg[i].data[0] = cpu_to_le32( - (SPEED_100 << 16) + (IEEE1394_SPEED_100 << 16) | (/* tag */ 1 << 14) | (d->channel << 8) | (TCODE_ISO_DATA << 4)); @@ -705,7 +705,7 @@ struct dma_iso_ctx *d; int i; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; /* if channel < 0, find lowest available one */ @@ -802,7 +802,7 @@ v.channel); } - if(copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user((void *)arg, &v, sizeof(v))) return -EFAULT; return 0; @@ -814,7 +814,7 @@ u64 mask; struct dma_iso_ctx *d; - if(copy_from_user(&channel, (void *)arg, sizeof(int))) + if (copy_from_user(&channel, (void *)arg, sizeof(int))) return -EFAULT; if (channel<0 || channel>(ISO_CHANNELS-1)) { @@ -849,7 +849,7 @@ struct video1394_wait v; struct dma_iso_ctx *d; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -911,7 +911,7 @@ struct dma_iso_ctx *d; int i; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); @@ -939,12 +939,12 @@ } #if 1 - while(d->buffer_status[v.buffer]!= + while (d->buffer_status[v.buffer]!= VIDEO1394_BUFFER_READY) { spin_unlock_irqrestore(&d->lock, flags); interruptible_sleep_on(&d->waitq); spin_lock_irqsave(&d->lock, flags); - if(signal_pending(current)) { + if (signal_pending(current)) { spin_unlock_irqrestore(&d->lock,flags); return -EINTR; } @@ -981,7 +981,7 @@ spin_unlock_irqrestore(&d->lock, flags); v.buffer=i; - if(copy_to_user((void *)arg, &v, sizeof(v))) + if (copy_to_user((void *)arg, &v, sizeof(v))) return -EFAULT; return 0; @@ -994,7 +994,7 @@ qv.packet_sizes = NULL; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1097,7 +1097,7 @@ struct video1394_wait v; struct dma_iso_ctx *d; - if(copy_from_user(&v, (void *)arg, sizeof(v))) + if (copy_from_user(&v, (void *)arg, sizeof(v))) return -EFAULT; d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); @@ -1114,10 +1114,10 @@ return 0; case VIDEO1394_BUFFER_QUEUED: #if 1 - while(d->buffer_status[v.buffer]!= + while (d->buffer_status[v.buffer]!= VIDEO1394_BUFFER_READY) { interruptible_sleep_on(&d->waitq); - if(signal_pending(current)) return -EINTR; + if (signal_pending(current)) return -EINTR; } #else if (wait_event_interruptible(d->waitq, diff -Nru a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c --- a/drivers/media/common/saa7146_core.c Fri Jun 27 14:19:59 2003 +++ b/drivers/media/common/saa7146_core.c Fri Jun 27 14:19:59 2003 @@ -20,10 +20,6 @@ #include <media/saa7146.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME saa7146 -#endif - /* global variables */ struct list_head saa7146_devices; struct semaphore saa7146_devices_lock; @@ -53,8 +49,7 @@ ****************************************************************************/ /* this is videobuf_vmalloc_to_sg() from video-buf.c */ -static -struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) +static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) { struct scatterlist *sglist; struct page *pg; @@ -207,7 +202,6 @@ } saa7146_write(dev, ISR, isr); -// DEB_INT(("0x%08x\n",isr)); if( 0 != (dev->ext)) { if( 0 != (dev->ext->irq_mask & isr )) { @@ -260,8 +254,7 @@ /*********************************************************************************/ /* configuration-functions */ -static -int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent) +static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent) { unsigned long adr = 0, len = 0; struct saa7146_dev* dev = kmalloc (sizeof(struct saa7146_dev),GFP_KERNEL); @@ -340,33 +333,33 @@ } /* get memory for various stuff */ - dev->rps0 = (u32*)kmalloc(SAA7146_RPS_MEM, GFP_KERNEL); - if( NULL == dev->rps0 ) { + dev->d_rps0.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps0.dma_handle); + if( NULL == dev->d_rps0.cpu_addr ) { err = -ENOMEM; goto kmalloc_error_1; } - memset(dev->rps0, 0x0, SAA7146_RPS_MEM); + memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM); - dev->rps1 = (u32*)kmalloc(SAA7146_RPS_MEM, GFP_KERNEL); - if( NULL == dev->rps1 ) { + dev->d_rps1.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_rps1.dma_handle); + if( NULL == dev->d_rps1.cpu_addr ) { err = -ENOMEM; goto kmalloc_error_2; } - memset(dev->rps1, 0x0, SAA7146_RPS_MEM); + memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM); - dev->i2c_mem = (u32*)kmalloc(SAA7146_I2C_MEM, GFP_KERNEL); - if( NULL == dev->i2c_mem ) { + dev->d_i2c.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_RPS_MEM, &dev->d_i2c.dma_handle); + if( NULL == dev->d_i2c.cpu_addr ) { err = -ENOMEM; goto kmalloc_error_3; } - memset(dev->i2c_mem, 0x00, SAA7146_I2C_MEM); + memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM); /* the rest + print status message */ /* create a nice device name */ sprintf(&dev->name[0], "saa7146 (%d)",saa7146_num); - INFO(("found saa7146 @ mem 0x%08x (revision %d, irq %d) (0x%04x,0x%04x).\n", (unsigned int)dev->mem, dev->revision,dev->pci->irq,dev->pci->subsystem_vendor,dev->pci->subsystem_device)); + INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision,dev->pci->irq,dev->pci->subsystem_vendor,dev->pci->subsystem_device)); dev->ext = ext; pci_set_drvdata(pci,dev); @@ -406,11 +399,11 @@ attach_error: probe_error: pci_set_drvdata(pci,NULL); - kfree( dev->i2c_mem ); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle); kmalloc_error_3: - kfree( dev->rps1 ); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle); kmalloc_error_2: - kfree( dev->rps0 ); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle); kmalloc_error_1: free_irq(dev->pci->irq, (void *)dev); irq_error: @@ -423,8 +416,7 @@ return err; } -static -void saa7146_remove_one(struct pci_dev *pdev) +static void saa7146_remove_one(struct pci_dev *pdev) { struct saa7146_dev* dev = (struct saa7146_dev*) pci_get_drvdata(pdev); DEB_EE(("dev:%p\n",dev)); @@ -440,9 +432,9 @@ free_irq(dev->pci->irq, (void *)dev); /* free kernel memory */ - kfree(dev->rps0 ); - kfree(dev->rps1 ); - kfree(dev->i2c_mem); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle); iounmap(dev->mem); release_mem_region(pci_resource_start(dev->pci,0), pci_resource_len(dev->pci,0)); @@ -483,8 +475,7 @@ return 0; } -static -int __init saa7146_init_module(void) +static int __init saa7146_init_module(void) { if( 0 == initialized ) { INIT_LIST_HEAD(&saa7146_devices); @@ -494,8 +485,7 @@ return 0; } -static -void __exit saa7146_cleanup_module(void) +static void __exit saa7146_cleanup_module(void) { } diff -Nru a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c --- a/drivers/media/common/saa7146_fops.c Fri Jun 27 14:19:56 2003 +++ b/drivers/media/common/saa7146_fops.c Fri Jun 27 14:19:56 2003 @@ -1,9 +1,5 @@ #include <media/saa7146_vv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME saa7146 -#endif - #define BOARD_CAN_DO_VBI(dev) (dev->revision != 0 && dev->vv_data->vbi_minor != -1) /********************************************************************************/ @@ -111,7 +107,7 @@ saa7146_write(dev, PROT_ADDR1, 0); /* write the address of the rps-program */ - saa7146_write(dev, RPS_ADDR0, virt_to_bus(&dev->rps0[ 0])); + saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle); /* turn on rps */ saa7146_write(dev, MC1, (MASK_12 | MASK_28)); } @@ -148,8 +144,7 @@ /********************************************************************************/ /* file operations */ -static -int fops_open(struct inode *inode, struct file *file) +static int fops_open(struct inode *inode, struct file *file) { unsigned int minor = minor(inode->i_rdev); struct saa7146_dev *h = NULL, *dev = NULL; @@ -322,11 +317,11 @@ switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%d\n",file, data, count)); + DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count)); return saa7146_video_uops.read(file,data,count,ppos); } case V4L2_BUF_TYPE_VBI_CAPTURE: { - DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%d\n",file, data, count)); + DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); return saa7146_vbi_uops.read(file,data,count,ppos); } break; @@ -393,13 +388,13 @@ vv->video_minor = -1; vv->vbi_minor = -1; - vv->clipping = (u32*)kmalloc(SAA7146_CLIPPING_MEM, GFP_KERNEL); - if( NULL == vv->clipping ) { + vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle); + if( NULL == vv->d_clipping.cpu_addr ) { ERR(("out of memory. aborting.\n")); kfree(vv); return -1; } - memset(vv->clipping, 0x0, SAA7146_CLIPPING_MEM); + memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); saa7146_video_uops.init(dev,vv); saa7146_vbi_uops.init(dev,vv); @@ -416,6 +411,7 @@ DEB_EE(("dev:%p\n",dev)); + pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); kfree(vv); dev->vv_data = NULL; dev->vv_callback = NULL; @@ -466,15 +462,13 @@ return 0; } -static -int __init saa7146_vv_init_module(void) +static int __init saa7146_vv_init_module(void) { return 0; } -static -void __exit saa7146_vv_cleanup_module(void) +static void __exit saa7146_vv_cleanup_module(void) { } diff -Nru a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c --- a/drivers/media/common/saa7146_hlp.c Fri Jun 27 14:19:58 2003 +++ b/drivers/media/common/saa7146_hlp.c Fri Jun 27 14:19:58 2003 @@ -1,16 +1,11 @@ #include <media/saa7146_vv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME saa7146 -#endif - #define my_min(type,x,y) \ ({ type __x = (x), __y = (y); __x < __y ? __x: __y; }) #define my_max(type,x,y) \ ({ type __x = (x), __y = (y); __x > __y ? __x: __y; }) -static -void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format) +static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format) { /* clear out the necessary bits */ *clip_format &= 0x0000ffff; @@ -18,21 +13,18 @@ *clip_format |= (( ((palette&0xf00)>>8) << 30) | ((palette&0x00f) << 24) | (((palette&0x0f0)>>4) << 16)); } -static -void calculate_bcs_ctrl_register(struct saa7146_dev *dev, int brightness, int contrast, int colour, u32 *bcs_ctrl) +static void calculate_bcs_ctrl_register(struct saa7146_dev *dev, int brightness, int contrast, int colour, u32 *bcs_ctrl) { *bcs_ctrl = ((brightness << 24) | (contrast << 16) | (colour << 0)); } -static -void calculate_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync, u32* hps_ctrl) +static void calculate_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync, u32* hps_ctrl) { *hps_ctrl &= ~(MASK_30 | MASK_31 | MASK_28); *hps_ctrl |= (source << 30) | (sync << 28); } -static -void calculate_hxo_and_hyo(struct saa7146_vv *vv, u32* hps_h_scale, u32* hps_ctrl) +static void calculate_hxo_and_hyo(struct saa7146_vv *vv, u32* hps_h_scale, u32* hps_ctrl) { int hyo = 0, hxo = 0; @@ -77,8 +69,7 @@ u8 h_attenuation[] = { 1, 2, 4, 8, 2, 4, 8, 16, 0}; /* calculate horizontal scale registers */ -static -int calculate_h_scale_registers(struct saa7146_dev *dev, +static int calculate_h_scale_registers(struct saa7146_dev *dev, int in_x, int out_x, int flip_lr, u32* hps_ctrl, u32* hps_v_gain, u32* hps_h_prescale, u32* hps_h_scale) { @@ -225,8 +216,7 @@ u16 v_attenuation[] = { 2, 4, 8, 16, 32, 64, 128, 256, 0}; /* calculate vertical scale registers */ -static -int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field field, +static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field field, int in_y, int out_y, u32* hps_v_scale, u32* hps_v_gain) { int lpi = 0; @@ -322,8 +312,7 @@ } /* simple bubble-sort algorithm with duplicate elimination */ -static -int sort_and_eliminate(u32* values, int* count) +static int sort_and_eliminate(u32* values, int* count) { int low = 0, high = 0, top = 0, temp = 0; int cur = 0, next = 0; @@ -355,12 +344,11 @@ return 0; } -static -void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh, +static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh, struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field) { struct saa7146_vv *vv = dev->vv_data; - u32 *clipping = vv->clipping; + u32 *clipping = vv->d_clipping.cpu_addr; int width = fh->ov.win.w.width; int height = fh->ov.win.w.height; @@ -469,9 +457,9 @@ *arbtr_ctrl &= 0xffff00ff; *arbtr_ctrl |= 0x00001c00; - vdma2->base_even = virt_to_bus(clipping); - vdma2->base_odd = virt_to_bus(clipping); - vdma2->prot_addr = virt_to_bus(clipping)+((sizeof(u32))*(numdwords)); + vdma2->base_even = vv->d_clipping.dma_handle; + vdma2->base_odd = vv->d_clipping.dma_handle; + vdma2->prot_addr = vv->d_clipping.dma_handle+((sizeof(u32))*(numdwords)); vdma2->base_page = 0x04; vdma2->pitch = 0x00; vdma2->num_line_byte = (0 << 16 | (sizeof(u32))*(numdwords-1) ); @@ -488,8 +476,7 @@ } /* disable clipping */ -static -void saa7146_disable_clipping(struct saa7146_dev *dev) +static void saa7146_disable_clipping(struct saa7146_dev *dev) { u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL); @@ -504,8 +491,7 @@ saa7146_write(dev, MC1, (MASK_21)); } -static -void saa7146_set_clipping_rect(struct saa7146_dev *dev, struct saa7146_fh *fh) +static void saa7146_set_clipping_rect(struct saa7146_dev *dev, struct saa7146_fh *fh) { enum v4l2_field field = fh->ov.win.field; int clipcount = fh->ov.nclips; @@ -547,8 +533,7 @@ saa7146_write(dev, MC1, (MASK_05 | MASK_21)); } -static -void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field) +static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field) { struct saa7146_vv *vv = dev->vv_data; @@ -584,8 +569,7 @@ } /* calculate the new memory offsets for a desired position */ -static -void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field) +static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field) { struct saa7146_vv *vv = dev->vv_data; @@ -628,8 +612,7 @@ saa7146_write_out_dma(dev, 1, &vdma1); } -static -void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette) +static void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette) { u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL); @@ -746,8 +729,7 @@ printk("vdma%d.num_line_byte: 0x%08x\n", which,vdma->num_line_byte); */ } -static -int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf) +static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf) { struct saa7146_vv *vv = dev->vv_data; struct saa7146_video_dma vdma1; @@ -795,8 +777,7 @@ return 0; } -static -int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3) +static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3) { int height = buf->fmt->height; int width = buf->fmt->width; @@ -826,8 +807,7 @@ return 0; } -static -int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3) +static int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3) { int height = buf->fmt->height; int width = buf->fmt->width; @@ -857,8 +837,7 @@ } -static -int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf) +static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf) { struct saa7146_vv *vv = dev->vv_data; struct saa7146_video_dma vdma1; @@ -953,67 +932,68 @@ return 0; } -static -void program_capture_engine(struct saa7146_dev *dev, int planar) +static void program_capture_engine(struct saa7146_dev *dev, int planar) { struct saa7146_vv *vv = dev->vv_data; - int count = 0; unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B; unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B; - /* write beginning of rps-program */ - count = 0; + if( 0 != (dev->ext->ext_vv_data->flags & SAA7146_EXT_SWAP_ODD_EVEN)) { + unsigned long tmp = e_wait; + e_wait = o_wait; + o_wait = tmp; + } /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 0 is not set*/ - dev->rps0[ count++ ] = CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait; - dev->rps0[ count++ ] = CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait; + WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait); + WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait); /* set bit 0 */ - dev->rps0[ count++ ] = CMD_WR_REG | (1 << 8) | (MC2/4); - dev->rps0[ count++ ] = MASK_27 | MASK_11; + WRITE_RPS0(CMD_WR_REG | (1 << 8) | (MC2/4)); + WRITE_RPS0(MASK_27 | MASK_11); /* turn on video-dma1 */ - dev->rps0[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps0[ count++ ] = MASK_06 | MASK_22; /* => mask */ - dev->rps0[ count++ ] = MASK_06 | MASK_22; /* => values */ + WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS0(MASK_06 | MASK_22); /* => mask */ + WRITE_RPS0(MASK_06 | MASK_22); /* => values */ if( 0 != planar ) { /* turn on video-dma2 */ - dev->rps0[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps0[ count++ ] = MASK_05 | MASK_21; /* => mask */ - dev->rps0[ count++ ] = MASK_05 | MASK_21; /* => values */ + WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS0(MASK_05 | MASK_21); /* => mask */ + WRITE_RPS0(MASK_05 | MASK_21); /* => values */ /* turn on video-dma3 */ - dev->rps0[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps0[ count++ ] = MASK_04 | MASK_20; /* => mask */ - dev->rps0[ count++ ] = MASK_04 | MASK_20; /* => values */ + WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS0(MASK_04 | MASK_20); /* => mask */ + WRITE_RPS0(MASK_04 | MASK_20); /* => values */ } /* wait for o_fid_a/b / e_fid_a/b toggle */ - dev->rps0[ count++ ] = CMD_PAUSE | e_wait; - dev->rps0[ count++ ] = CMD_PAUSE | o_wait; + WRITE_RPS0(CMD_PAUSE | e_wait); + WRITE_RPS0(CMD_PAUSE | o_wait); /* turn off video-dma1 */ - dev->rps0[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps0[ count++ ] = MASK_22 | MASK_06; /* => mask */ - dev->rps0[ count++ ] = MASK_22; /* => values */ + WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS0(MASK_22 | MASK_06); /* => mask */ + WRITE_RPS0(MASK_22); /* => values */ if( 0 != planar ) { /* turn off video-dma2 */ - dev->rps0[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps0[ count++ ] = MASK_05 | MASK_21; /* => mask */ - dev->rps0[ count++ ] = MASK_21; /* => values */ + WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS0(MASK_05 | MASK_21); /* => mask */ + WRITE_RPS0(MASK_21); /* => values */ /* turn off video-dma3 */ - dev->rps0[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps0[ count++ ] = MASK_04 | MASK_20; /* => mask */ - dev->rps0[ count++ ] = MASK_20; /* => values */ + WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS0(MASK_04 | MASK_20); /* => mask */ + WRITE_RPS0(MASK_20); /* => values */ } /* generate interrupt */ - dev->rps0[ count++ ] = CMD_INTERRUPT; + WRITE_RPS0(CMD_INTERRUPT); /* stop */ - dev->rps0[ count++ ] = CMD_STOP; + WRITE_RPS0(CMD_STOP); } void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) @@ -1035,7 +1015,7 @@ } /* write the address of the rps-program */ - saa7146_write(dev, RPS_ADDR0, virt_to_bus(&dev->rps0[ 0])); + saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle); /* turn on rps */ saa7146_write(dev, MC1, (MASK_12 | MASK_28)); diff -Nru a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c --- a/drivers/media/common/saa7146_i2c.c Fri Jun 27 14:20:05 2003 +++ b/drivers/media/common/saa7146_i2c.c Fri Jun 27 14:20:05 2003 @@ -1,12 +1,7 @@ #include <media/saa7146_vv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME saa7146 -#endif - /* helper function */ -static -void my_wait(struct saa7146_dev *dev, long ms) +static void my_wait(struct saa7146_dev *dev, long ms) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((((ms+10)/10)*HZ)/1000); @@ -23,8 +18,7 @@ } /* this function returns the status-register of our i2c-device */ -static inline -u32 saa7146_i2c_status(struct saa7146_dev *dev) +static inline u32 saa7146_i2c_status(struct saa7146_dev *dev) { u32 iicsta = saa7146_read(dev, I2C_STATUS); /* @@ -37,8 +31,7 @@ sent through the saa7146. have a look at the specifications p. 122 ff to understand this. it returns the number of u32s to send, or -1 in case of an error. */ -static -int saa7146_i2c_msg_prepare(const struct i2c_msg m[], int num, u32 *op) +static int saa7146_i2c_msg_prepare(const struct i2c_msg m[], int num, u32 *op) { int h1, h2; int i, j, addr; @@ -102,8 +95,7 @@ which bytes were read through the adapter and write them back to the corresponding i2c-message. but instead, we simply write back all bytes. fixme: this could be improved. */ -static -int saa7146_i2c_msg_cleanup(const struct i2c_msg m[], int num, u32 *op) +static int saa7146_i2c_msg_cleanup(const struct i2c_msg m[], int num, u32 *op) { int i, j; int op_count = 0; @@ -125,8 +117,7 @@ } /* this functions resets the i2c-device and returns 0 if everything was fine, otherwise -1 */ -static -int saa7146_i2c_reset(struct saa7146_dev *dev) +static int saa7146_i2c_reset(struct saa7146_dev *dev) { /* get current status */ u32 status = saa7146_i2c_status(dev); @@ -190,8 +181,7 @@ /* this functions writes out the data-byte 'dword' to the i2c-device. it returns 0 if ok, -1 if the transfer failed, -2 if the transfer failed badly (e.g. address error) */ -static -int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) +static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword) { u32 status = 0, mc2 = 0; int timeout; @@ -284,7 +274,7 @@ int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg msgs[], int num, int retries) { int i = 0, count = 0; - u32* buffer = dev->i2c_mem; + u32* buffer = dev->d_i2c.cpu_addr; int err = 0; int address_err = 0; @@ -377,13 +367,10 @@ } /* utility functions */ -static -int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg msg[], int num) +static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg msg[], int num) { struct saa7146_dev* dev = i2c_get_adapdata(adapter); - DEB_I2C(("adapter: '%s'.\n", adapter->dev.name)); - /* use helper function to transfer data */ return saa7146_i2c_transfer(dev, msg, num, adapter->retries); } @@ -394,8 +381,7 @@ #include <linux/i2c-id.h> /* exported algorithm data */ -static -struct i2c_algorithm saa7146_algo = { +static struct i2c_algorithm saa7146_algo = { .name = "saa7146 i2c algorithm", .id = I2C_ALGO_SAA7146, .master_xfer = saa7146_i2c_xfer, diff -Nru a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c --- a/drivers/media/common/saa7146_vbi.c Fri Jun 27 14:19:52 2003 +++ b/drivers/media/common/saa7146_vbi.c Fri Jun 27 14:19:52 2003 @@ -1,20 +1,15 @@ #include <media/saa7146_vv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME saa7146 -#endif - static int vbi_pixel_to_capture = 720 * 2; -static -int vbi_workaround(struct saa7146_dev *dev) +static int vbi_workaround(struct saa7146_dev *dev) { struct saa7146_vv *vv = dev->vv_data; u32 *cpu; dma_addr_t dma_addr; - int i, index; + int i; DECLARE_WAITQUEUE(wait, current); @@ -38,54 +33,51 @@ saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0)); saa7146_write(dev, MC2, MASK_04|MASK_20); - - /* we have to do the workaround two times to be sure that - everything is ok */ - for(i = 0; i < 2; i++) { - - /* indicate to the irq handler that we do the workaround */ - saa7146_write(dev, MC2, MASK_31|MASK_15); - - saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0)); - saa7146_write(dev, MC2, MASK_04|MASK_20); - - index = 0; - /* load brs-control register */ - dev->rps1[index++] = CMD_WR_REG | (1 << 8) | (BRS_CTRL/4); + WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); /* BXO = 1h, BRS to outbound */ - dev->rps1[index++]=0xc000008c; + WRITE_RPS1(0xc000008c); /* wait for vbi_a */ - dev->rps1[index++] = CMD_PAUSE | MASK_10; + WRITE_RPS1(CMD_PAUSE | MASK_10); /* upload brs */ - dev->rps1[index++] = CMD_UPLOAD | MASK_08; + WRITE_RPS1(CMD_UPLOAD | MASK_08); /* load brs-control register */ - dev->rps1[index++] = CMD_WR_REG | (1 << 8) | (BRS_CTRL/4); + WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */ - dev->rps1[index++] = ((1728-(vbi_pixel_to_capture)) << 7) | MASK_19; + WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19); /* wait for brs_done */ - dev->rps1[index++] = CMD_PAUSE | MASK_08; + WRITE_RPS1(CMD_PAUSE | MASK_08); /* upload brs */ - dev->rps1[index++] = CMD_UPLOAD | MASK_08; + WRITE_RPS1(CMD_UPLOAD | MASK_08); /* load video-dma3 NumLines3 and NumBytes3 */ - dev->rps1[index++] = CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4); + WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4)); /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */ - dev->rps1[index++]= (2 << 16) | (vbi_pixel_to_capture); + WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture)); /* load brs-control register */ - dev->rps1[index++] = CMD_WR_REG | (1 << 8) | (BRS_CTRL/4); + WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4)); /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */ - dev->rps1[index++] = (540 << 7) | (5 << 19); // 5 == vbi_start + WRITE_RPS1((540 << 7) | (5 << 19)); // 5 == vbi_start /* wait for brs_done */ - dev->rps1[index++] = CMD_PAUSE | MASK_08; + WRITE_RPS1(CMD_PAUSE | MASK_08); /* upload brs and video-dma3*/ - dev->rps1[index++] = CMD_UPLOAD | MASK_08 | MASK_04; + WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04); /* load mc2 register: enable dma3 */ - dev->rps1[index++] = CMD_WR_REG | (1 << 8) | (MC1/4); - dev->rps1[index++] = MASK_20 | MASK_04; + WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4)); + WRITE_RPS1(MASK_20 | MASK_04); /* generate interrupt */ - dev->rps1[index++] = CMD_INTERRUPT; + WRITE_RPS1(CMD_INTERRUPT); /* stop rps1 */ - dev->rps1[index++] = CMD_STOP; + WRITE_RPS1(CMD_STOP); + + /* we have to do the workaround twice to be sure that + everything is ok */ + for(i = 0; i < 2; i++) { + + /* indicate to the irq handler that we do the workaround */ + saa7146_write(dev, MC2, MASK_31|MASK_15); + + saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0)); + saa7146_write(dev, MC2, MASK_04|MASK_20); /* enable rps1 irqs */ IER_ENABLE(dev,MASK_28); @@ -95,7 +87,7 @@ current->state = TASK_INTERRUPTIBLE; /* start rps1 to enable workaround */ - saa7146_write(dev, RPS_ADDR1, virt_to_bus(&dev->rps1[ 0])); + saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); saa7146_write(dev, MC1, (MASK_13 | MASK_29)); schedule(); @@ -164,40 +156,39 @@ but by doing this, we can use the whole engine from video-buf.c... */ /* - dev->rps1[ count++ ] = CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait; - dev->rps1[ count++ ] = CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait; + WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait); + WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait); */ /* set bit 1 */ - dev->rps1[ count++ ] = CMD_WR_REG | (1 << 8) | (MC2/4); - dev->rps1[ count++ ] = MASK_28 | MASK_12; + WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4)); + WRITE_RPS1(MASK_28 | MASK_12); /* turn on video-dma3 */ - dev->rps1[ count++ ] = CMD_WR_REG_MASK | (MC1/4); - dev->rps1[ count++ ] = MASK_04 | MASK_20; /* => mask */ - dev->rps1[ count++ ] = MASK_04 | MASK_20; /* => values */ + WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4)); + WRITE_RPS1(MASK_04 | MASK_20); /* => mask */ + WRITE_RPS1(MASK_04 | MASK_20); /* => values */ /* wait for o_fid_a/b / e_fid_a/b toggle */ - dev->rps1[ count++ ] = CMD_PAUSE | o_wait; - dev->rps1[ count++ ] = CMD_PAUSE | e_wait; + WRITE_RPS1(CMD_PAUSE | o_wait); + WRITE_RPS1(CMD_PAUSE | e_wait); /* generate interrupt */ - dev->rps1[ count++ ] = CMD_INTERRUPT; + WRITE_RPS1(CMD_INTERRUPT); /* stop */ - dev->rps1[ count++ ] = CMD_STOP; + WRITE_RPS1(CMD_STOP); /* enable rps1 irqs */ IER_ENABLE(dev, MASK_28); /* write the address of the rps-program */ - saa7146_write(dev, RPS_ADDR1, virt_to_bus(&dev->rps1[ 0])); + saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); /* turn on rps */ saa7146_write(dev, MC1, (MASK_13 | MASK_29)); } -static -int buffer_activate(struct saa7146_dev *dev, +static int buffer_activate(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) { @@ -211,8 +202,7 @@ return 0; } -static -int buffer_prepare(struct file *file, struct videobuf_buffer *vb,enum v4l2_field field) +static int buffer_prepare(struct file *file, struct videobuf_buffer *vb,enum v4l2_field field) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; @@ -261,8 +251,7 @@ return err; } -static int -buffer_setup(struct file *file, unsigned int *count, unsigned int *size) +static int buffer_setup(struct file *file, unsigned int *count, unsigned int *size) { int llength,lines; @@ -277,8 +266,7 @@ return 0; } -static -void buffer_queue(struct file *file, struct videobuf_buffer *vb) +static void buffer_queue(struct file *file, struct videobuf_buffer *vb) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; @@ -289,8 +277,7 @@ saa7146_buffer_queue(dev,&vv->vbi_q,buf); } -static -void buffer_release(struct file *file, struct videobuf_buffer *vb) +static void buffer_release(struct file *file, struct videobuf_buffer *vb) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; @@ -300,8 +287,7 @@ saa7146_dma_free(dev,buf); } -static -struct videobuf_queue_ops vbi_qops = { +static struct videobuf_queue_ops vbi_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, @@ -310,8 +296,7 @@ /* ------------------------------------------------------------------ */ -static -void vbi_stop(struct saa7146_fh *fh) +static void vbi_stop(struct saa7146_fh *fh) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -333,8 +318,7 @@ spin_unlock_irqrestore(&dev->slock, flags); } -static -void vbi_read_timeout(unsigned long data) +static void vbi_read_timeout(unsigned long data) { struct saa7146_fh *fh = (struct saa7146_fh *)data; struct saa7146_dev *dev = fh->dev; @@ -344,8 +328,7 @@ vbi_stop(fh); } -static -void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv) +static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv) { DEB_VBI(("dev:%p\n",dev)); @@ -359,8 +342,7 @@ init_waitqueue_head(&vv->vbi_wq); } -static -void vbi_open(struct saa7146_dev *dev, struct saa7146_fh *fh) +static void vbi_open(struct saa7146_dev *dev, struct saa7146_fh *fh) { DEB_VBI(("dev:%p, fh:%p\n",dev,fh)); @@ -391,8 +373,7 @@ vbi_workaround(dev); } -static -void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file) +static void vbi_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file) { struct saa7146_vv *vv = dev->vv_data; DEB_VBI(("dev:%p, fh:%p\n",dev,fh)); @@ -402,8 +383,7 @@ } } -static -void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) +static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status) { struct saa7146_vv *vv = dev->vv_data; spin_lock(&dev->slock); @@ -422,8 +402,7 @@ spin_unlock(&dev->slock); } -static -ssize_t vbi_read(struct file *file, char *data, size_t count, loff_t *ppos) +static ssize_t vbi_read(struct file *file, char *data, size_t count, loff_t *ppos) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; diff -Nru a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c --- a/drivers/media/common/saa7146_video.c Fri Jun 27 14:19:58 2003 +++ b/drivers/media/common/saa7146_video.c Fri Jun 27 14:19:58 2003 @@ -1,18 +1,12 @@ #include <media/saa7146_vv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME saa7146 -#endif - -static -int memory = 32; +static int memory = 32; MODULE_PARM(memory,"i"); MODULE_PARM_DESC(memory, "maximum memory usage for capture buffers (default: 32Mb)"); /* format descriptions for capture and preview */ -static -struct saa7146_format formats[] = { +static struct saa7146_format formats[] = { { .name = "RGB-8 (3-3-2)", .pixelformat = V4L2_PIX_FMT_RGB332, @@ -67,8 +61,7 @@ due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped (like V4L2_PIX_FMT_YUYV) ... 8-( */ -static -int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); +static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) { @@ -84,8 +77,7 @@ return NULL; } -static -int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f) +static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f) { struct saa7146_dev *dev = fh->dev; DEB_EE(("dev:%p, fh:%p\n",dev,fh)); @@ -108,8 +100,7 @@ } } -static -int try_win(struct saa7146_dev *dev, struct v4l2_window *win) +static int try_win(struct saa7146_dev *dev, struct v4l2_window *win) { struct saa7146_vv *vv = dev->vv_data; enum v4l2_field field; @@ -165,8 +156,7 @@ return 0; } -static -int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f) +static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -230,8 +220,7 @@ } } -static -int start_preview(struct saa7146_fh *fh) +static int start_preview(struct saa7146_fh *fh) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -277,8 +266,7 @@ return 0; } -static -int stop_preview(struct saa7146_fh *fh) +static int stop_preview(struct saa7146_fh *fh) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -302,8 +290,7 @@ return 0; } -static -int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) +static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -362,8 +349,7 @@ /********************************************************************************/ /* device controls */ -static -struct v4l2_queryctrl controls[] = { +static struct v4l2_queryctrl controls[] = { { id: V4L2_CID_BRIGHTNESS, name: "Brightness", @@ -402,13 +388,11 @@ type: V4L2_CTRL_TYPE_BOOLEAN, }, }; -static -int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl); +static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl); #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0) -static -struct v4l2_queryctrl* ctrl_by_id(int id) +static struct v4l2_queryctrl* ctrl_by_id(int id) { int i; @@ -418,8 +402,7 @@ return NULL; } -static -int get_control(struct saa7146_fh *fh, struct v4l2_control *c) +static int get_control(struct saa7146_fh *fh, struct v4l2_control *c) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -434,20 +417,25 @@ case V4L2_CID_BRIGHTNESS: value = saa7146_read(dev, BCS_CTRL); c->value = 0xff & (value >> 24); + DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value)); break; case V4L2_CID_CONTRAST: value = saa7146_read(dev, BCS_CTRL); c->value = 0x7f & (value >> 16); + DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value)); break; case V4L2_CID_SATURATION: value = saa7146_read(dev, BCS_CTRL); c->value = 0x7f & (value >> 0); + DEB_D(("V4L2_CID_SATURATION: %d\n",c->value)); break; case V4L2_CID_VFLIP: c->value = vv->vflip; + DEB_D(("V4L2_CID_VFLIP: %d\n",c->value)); break; case V4L2_CID_HFLIP: c->value = vv->hflip; + DEB_D(("V4L2_CID_HFLIP: %d\n",c->value)); break; default: return -EINVAL; @@ -456,8 +444,7 @@ return 0; } -static -int set_control(struct saa7146_fh *fh, struct v4l2_control *c) +static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -547,8 +534,7 @@ /********************************************************************************/ /* common pagetable functions */ -static -int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) +static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) { struct pci_dev *pci = dev->pci; struct scatterlist *list = buf->vb.dma.sglist; @@ -666,8 +652,7 @@ /********************************************************************************/ /* file operations */ -static -int video_begin(struct saa7146_fh *fh) +static int video_begin(struct saa7146_fh *fh) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -700,8 +685,7 @@ return 0; } -static -int video_end(struct saa7146_fh *fh) +static int video_end(struct saa7146_fh *fh) { struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; @@ -876,7 +860,7 @@ return -EINVAL; } - DEB_EE(("VIDIOC_ENUMSTD: type:%d, index:%d\n",f->type,f->index)); + DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index)); return 0; } case VIDIOC_QUERYCTRL: @@ -974,6 +958,8 @@ struct saa7146_fh *ov_fh = NULL; + DEB_EE(("VIDIOC_S_STD\n")); + if( 0 != vv->streaming ) { return -EBUSY; } @@ -1112,8 +1098,7 @@ /*********************************************************************************/ /* buffer handling functions */ -static -int buffer_activate (struct saa7146_dev *dev, +static int buffer_activate (struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) { @@ -1126,8 +1111,7 @@ return 0; } -static -int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4l2_field field) +static int buffer_prepare(struct file *file, struct videobuf_buffer *vb, enum v4l2_field field) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; @@ -1205,8 +1189,7 @@ return err; } -static -int buffer_setup(struct file *file, unsigned int *count, unsigned int *size) +static int buffer_setup(struct file *file, unsigned int *count, unsigned int *size) { struct saa7146_fh *fh = file->private_data; @@ -1225,8 +1208,7 @@ return 0; } -static -void buffer_queue(struct file *file, struct videobuf_buffer *vb) +static void buffer_queue(struct file *file, struct videobuf_buffer *vb) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; @@ -1238,8 +1220,7 @@ } -static -void buffer_release(struct file *file, struct videobuf_buffer *vb) +static void buffer_release(struct file *file, struct videobuf_buffer *vb) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; @@ -1249,8 +1230,7 @@ saa7146_dma_free(dev,buf); } -static -struct videobuf_queue_ops video_qops = { +static struct videobuf_queue_ops video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, @@ -1260,8 +1240,7 @@ /********************************************************************************/ /* file operations */ -static -void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) +static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) { INIT_LIST_HEAD(&vv->video_q.queue); @@ -1279,8 +1258,7 @@ } -static -void video_open(struct saa7146_dev *dev, struct saa7146_fh *fh) +static void video_open(struct saa7146_dev *dev, struct saa7146_fh *fh) { struct saa7146_format *sfmt; @@ -1301,8 +1279,7 @@ } -static -void video_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file) +static void video_close(struct saa7146_dev *dev, struct saa7146_fh *fh, struct file *file) { struct saa7146_vv *vv = dev->vv_data; unsigned long flags; @@ -1323,8 +1300,7 @@ } -static -void video_irq_done(struct saa7146_dev *dev, unsigned long st) +static void video_irq_done(struct saa7146_dev *dev, unsigned long st) { struct saa7146_vv *vv = dev->vv_data; struct saa7146_dmaqueue *q = &vv->video_q; @@ -1341,8 +1317,7 @@ spin_unlock(&dev->slock); } -static -ssize_t video_read(struct file *file, char *data, size_t count, loff_t *ppos) +static ssize_t video_read(struct file *file, char *data, size_t count, loff_t *ppos) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; diff -Nru a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile --- a/drivers/media/dvb/dvb-core/Makefile Fri Jun 27 14:20:05 2003 +++ b/drivers/media/dvb/dvb-core/Makefile Fri Jun 27 14:20:05 2003 @@ -3,6 +3,6 @@ # dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_frontend.o dvb_i2c.o dvb_net.o dvb_ksyms.o dvb_ringbuffer.o + dvb_functions.o dvb_frontend.o dvb_i2c.o dvb_net.o dvb_ksyms.o dvb_ringbuffer.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff -Nru a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h --- a/drivers/media/dvb/dvb-core/demux.h Fri Jun 27 14:19:55 2003 +++ b/drivers/media/dvb/dvb-core/demux.h Fri Jun 27 14:19:55 2003 @@ -25,14 +25,10 @@ #ifndef __DEMUX_H #define __DEMUX_H -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - #include <linux/types.h> +#include <linux/errno.h> #include <linux/list.h> #include <linux/time.h> -#include <linux/errno.h> /*--------------------------------------------------------------------------*/ /* Common definitions */ @@ -47,10 +43,10 @@ #endif /* - * dmx_success_t: Success codes for the Demux Callback API. + * enum dmx_success: Success codes for the Demux Callback API. */ -typedef enum { +enum dmx_success { DMX_OK = 0, /* Received Ok */ DMX_LENGTH_ERROR, /* Incorrect length */ DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ @@ -58,7 +54,7 @@ DMX_FRAME_ERROR, /* Frame alignment error */ DMX_FIFO_ERROR, /* Receiver FIFO overrun */ DMX_MISSED_ERROR /* Receiver missed packet */ -} dmx_success_t; +} ; /*--------------------------------------------------------------------------*/ /* TS packet reception */ @@ -74,7 +70,7 @@ /* PES type for filters which write to built-in decoder */ /* these should be kept identical to the types in dmx.h */ -typedef enum +enum dmx_ts_pes { /* also send packets to decoder (if it exists) */ DMX_TS_PES_AUDIO0, DMX_TS_PES_VIDEO0, @@ -101,7 +97,7 @@ DMX_TS_PES_PCR3, DMX_TS_PES_OTHER -} dmx_ts_pes_t; +}; #define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0 #define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0 @@ -110,39 +106,37 @@ #define DMX_TS_PES_PCR DMX_TS_PES_PCR0 -struct dmx_ts_feed_s { +struct dmx_ts_feed { int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s *parent; /* Back-pointer */ + struct dmx_demux *parent; /* Back-pointer */ void *priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_ts_feed_s *feed, - uint16_t pid, + int (*set) (struct dmx_ts_feed *feed, + u16 pid, int type, - dmx_ts_pes_t pes_type, + enum dmx_ts_pes pes_type, size_t callback_length, size_t circular_buffer_size, int descramble, struct timespec timeout); - int (*start_filtering) (struct dmx_ts_feed_s* feed); - int (*stop_filtering) (struct dmx_ts_feed_s* feed); + int (*start_filtering) (struct dmx_ts_feed* feed); + int (*stop_filtering) (struct dmx_ts_feed* feed); }; -typedef struct dmx_ts_feed_s dmx_ts_feed_t; - /*--------------------------------------------------------------------------*/ /* Section reception */ /*--------------------------------------------------------------------------*/ -typedef struct { - __u8 filter_value [DMX_MAX_FILTER_SIZE]; - __u8 filter_mask [DMX_MAX_FILTER_SIZE]; - __u8 filter_mode [DMX_MAX_FILTER_SIZE]; - struct dmx_section_feed_s* parent; /* Back-pointer */ +struct dmx_section_filter { + u8 filter_value [DMX_MAX_FILTER_SIZE]; + u8 filter_mask [DMX_MAX_FILTER_SIZE]; + u8 filter_mode [DMX_MAX_FILTER_SIZE]; + struct dmx_section_feed* parent; /* Back-pointer */ void* priv; /* Pointer to private data of the API client */ -} dmx_section_filter_t; +}; -struct dmx_section_feed_s { +struct dmx_section_feed { int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux_s* parent; /* Back-pointer */ + struct dmx_demux* parent; /* Back-pointer */ void* priv; /* Pointer to private data of the API client */ int check_crc; @@ -152,19 +146,18 @@ int secbufp; int seclen; - int (*set) (struct dmx_section_feed_s* feed, - __u16 pid, + int (*set) (struct dmx_section_feed* feed, + u16 pid, size_t circular_buffer_size, int descramble, int check_crc); - int (*allocate_filter) (struct dmx_section_feed_s* feed, - dmx_section_filter_t** filter); - int (*release_filter) (struct dmx_section_feed_s* feed, - dmx_section_filter_t* filter); - int (*start_filtering) (struct dmx_section_feed_s* feed); - int (*stop_filtering) (struct dmx_section_feed_s* feed); + int (*allocate_filter) (struct dmx_section_feed* feed, + struct dmx_section_filter** filter); + int (*release_filter) (struct dmx_section_feed* feed, + struct dmx_section_filter* filter); + int (*start_filtering) (struct dmx_section_feed* feed); + int (*stop_filtering) (struct dmx_section_feed* feed); }; -typedef struct dmx_section_feed_s dmx_section_feed_t; /*--------------------------------------------------------------------------*/ /* Callback functions */ @@ -174,21 +167,21 @@ size_t buffer1_length, const u8 * buffer2, size_t buffer2_length, - dmx_ts_feed_t* source, - dmx_success_t success); + struct dmx_ts_feed* source, + enum dmx_success success); typedef int (*dmx_section_cb) ( const u8 * buffer1, size_t buffer1_len, const u8 * buffer2, size_t buffer2_len, - dmx_section_filter_t * source, - dmx_success_t success); + struct dmx_section_filter * source, + enum dmx_success success); /*--------------------------------------------------------------------------*/ /* DVB Front-End */ /*--------------------------------------------------------------------------*/ -typedef enum { +enum dmx_frontend_source { DMX_MEMORY_FE, DMX_FRONTEND_0, DMX_FRONTEND_1, @@ -198,26 +191,22 @@ DMX_STREAM_1, DMX_STREAM_2, DMX_STREAM_3 -} dmx_frontend_source_t; +}; -typedef struct { - /* The following char* fields point to NULL terminated strings */ - char* id; /* Unique front-end identifier */ - char* vendor; /* Name of the front-end vendor */ - char* model; /* Name of the front-end model */ +struct dmx_frontend { struct list_head connectivity_list; /* List of front-ends that can be connected to a particular demux */ void* priv; /* Pointer to private data of the API client */ - dmx_frontend_source_t source; -} dmx_frontend_t; + enum dmx_frontend_source source; +}; /*--------------------------------------------------------------------------*/ /* MPEG-2 TS Demux */ /*--------------------------------------------------------------------------*/ /* - * Flags OR'ed in the capabilites field of struct dmx_demux_s. + * Flags OR'ed in the capabilites field of struct dmx_demux. */ #define DMX_TS_FILTERING 1 @@ -236,61 +225,56 @@ /* * DMX_FE_ENTRY(): Casts elements in the list of registered * front-ends from the generic type struct list_head - * to the type * dmx_frontend_t + * to the type * struct dmx_frontend *. */ -#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) +#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list) -struct dmx_demux_s { - /* The following char* fields point to NULL terminated strings */ - char* id; /* Unique demux identifier */ - char* vendor; /* Name of the demux vendor */ - char* model; /* Name of the demux model */ - __u32 capabilities; /* Bitfield of capability flags */ - dmx_frontend_t* frontend; /* Front-end connected to the demux */ +struct dmx_demux { + u32 capabilities; /* Bitfield of capability flags */ + struct dmx_frontend* frontend; /* Front-end connected to the demux */ struct list_head reg_list; /* List of registered demuxes */ void* priv; /* Pointer to private data of the API client */ int users; /* Number of users */ - int (*open) (struct dmx_demux_s* demux); - int (*close) (struct dmx_demux_s* demux); - int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); - int (*allocate_ts_feed) (struct dmx_demux_s* demux, - dmx_ts_feed_t** feed, + int (*open) (struct dmx_demux* demux); + int (*close) (struct dmx_demux* demux); + int (*write) (struct dmx_demux* demux, const char* buf, size_t count); + int (*allocate_ts_feed) (struct dmx_demux* demux, + struct dmx_ts_feed** feed, dmx_ts_cb callback); - int (*release_ts_feed) (struct dmx_demux_s* demux, - dmx_ts_feed_t* feed); - int (*allocate_section_feed) (struct dmx_demux_s* demux, - dmx_section_feed_t** feed, + int (*release_ts_feed) (struct dmx_demux* demux, + struct dmx_ts_feed* feed); + int (*allocate_section_feed) (struct dmx_demux* demux, + struct dmx_section_feed** feed, dmx_section_cb callback); - int (*release_section_feed) (struct dmx_demux_s* demux, - dmx_section_feed_t* feed); - int (*descramble_mac_address) (struct dmx_demux_s* demux, - __u8* buffer1, + int (*release_section_feed) (struct dmx_demux* demux, + struct dmx_section_feed* feed); + int (*descramble_mac_address) (struct dmx_demux* demux, + u8* buffer1, size_t buffer1_length, - __u8* buffer2, + u8* buffer2, size_t buffer2_length, - __u16 pid); - int (*descramble_section_payload) (struct dmx_demux_s* demux, - __u8* buffer1, + u16 pid); + int (*descramble_section_payload) (struct dmx_demux* demux, + u8* buffer1, size_t buffer1_length, - __u8* buffer2, size_t buffer2_length, - __u16 pid); - int (*add_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - int (*remove_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - struct list_head* (*get_frontends) (struct dmx_demux_s* demux); - int (*connect_frontend) (struct dmx_demux_s* demux, - dmx_frontend_t* frontend); - int (*disconnect_frontend) (struct dmx_demux_s* demux); + u8* buffer2, size_t buffer2_length, + u16 pid); + int (*add_frontend) (struct dmx_demux* demux, + struct dmx_frontend* frontend); + int (*remove_frontend) (struct dmx_demux* demux, + struct dmx_frontend* frontend); + struct list_head* (*get_frontends) (struct dmx_demux* demux); + int (*connect_frontend) (struct dmx_demux* demux, + struct dmx_frontend* frontend); + int (*disconnect_frontend) (struct dmx_demux* demux); - int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids); + int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids); - int (*get_stc) (struct dmx_demux_s* demux, unsigned int num, - uint64_t *stc, unsigned int *base); + int (*get_stc) (struct dmx_demux* demux, unsigned int num, + u64 *stc, unsigned int *base); }; -typedef struct dmx_demux_s dmx_demux_t; /*--------------------------------------------------------------------------*/ /* Demux directory */ @@ -298,14 +282,14 @@ /* * DMX_DIR_ENTRY(): Casts elements in the list of registered - * demuxes from the generic type struct list_head* to the type dmx_demux_t + * demuxes from the generic type struct list_head* to the type struct dmx_demux *. */ -#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list) +#define DMX_DIR_ENTRY(list) list_entry(list, struct dmx_demux, reg_list) -int dmx_register_demux (dmx_demux_t* demux); -int dmx_unregister_demux (dmx_demux_t* demux); +int dmx_register_demux (struct dmx_demux* demux); +int dmx_unregister_demux (struct dmx_demux* demux); struct list_head* dmx_get_demuxes (void); #endif /* #ifndef __DEMUX_H */ diff -Nru a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c --- a/drivers/media/dvb/dvb-core/dmxdev.c Fri Jun 27 14:20:00 2003 +++ b/drivers/media/dvb/dvb-core/dmxdev.c Fri Jun 27 14:20:00 2003 @@ -21,41 +21,38 @@ * */ +#include <linux/spinlock.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/module.h> +#include <linux/sched.h> #include <linux/poll.h> +#include <linux/ioctl.h> +#include <linux/wait.h> #include <asm/uaccess.h> +#include <asm/system.h> #include "dmxdev.h" +#include "dvb_functions.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #include "compat.h" -#endif - -//MODULE_DESCRIPTION(""); -//MODULE_AUTHOR("Ralph Metzler, Marcus Metzler"); -//#ifdef MODULE_LICENSE -//MODULE_LICENSE("GPL"); -//#endif MODULE_PARM(debug,"i"); static int debug = 0; #define dprintk if (debug) printk -inline dmxdev_filter_t * +inline struct dmxdev_filter * dvb_dmxdev_file_to_filter(struct file *file) { - return (dmxdev_filter_t *) file->private_data; + return (struct dmxdev_filter *) file->private_data; } -inline dmxdev_dvr_t * -dvb_dmxdev_file_to_dvr(dmxdev_t *dmxdev, struct file *file) +inline struct dmxdev_dvr * +dvb_dmxdev_file_to_dvr(struct dmxdev *dmxdev, struct file *file) { - return (dmxdev_dvr_t *) file->private_data; + return (struct dmxdev_dvr *) file->private_data; } -static inline void -dvb_dmxdev_buffer_init(dmxdev_buffer_t *buffer) +static inline void dvb_dmxdev_buffer_init(struct dmxdev_buffer *buffer) { buffer->data=0; buffer->size=8192; @@ -65,8 +62,7 @@ init_waitqueue_head(&buffer->queue); } -static inline -int dvb_dmxdev_buffer_write(dmxdev_buffer_t *buf, const u8 *src, int len) +static inline int dvb_dmxdev_buffer_write(struct dmxdev_buffer *buf, const u8 *src, int len) { int split; int free; @@ -100,9 +96,8 @@ return len; } -static ssize_t -dvb_dmxdev_buffer_read(dmxdev_buffer_t *src, int non_blocking, - char *buf, size_t count, loff_t *ppos) +static ssize_t dvb_dmxdev_buffer_read(struct dmxdev_buffer *src, + int non_blocking, char *buf, size_t count, loff_t *ppos) { unsigned long todo=count; int split, avail, error; @@ -161,8 +156,7 @@ return count; } -static dmx_frontend_t * -get_fe(dmx_demux_t *demux, int type) +static struct dmx_frontend * get_fe(struct dmx_demux *demux, int type) { struct list_head *head, *pos; @@ -176,8 +170,7 @@ return 0; } -static inline void -dvb_dmxdev_dvr_state_set(dmxdev_dvr_t *dmxdevdvr, int state) +static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int state) { spin_lock_irq(&dmxdevdvr->dev->lock); dmxdevdvr->state=state; @@ -187,8 +180,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv; - dmx_frontend_t *front; + struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; + struct dmx_frontend *front; dprintk ("function : %s\n", __FUNCTION__); @@ -236,7 +229,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv; + struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; if (down_interruptible (&dmxdev->mutex)) return -ERESTARTSYS; @@ -260,11 +253,11 @@ return 0; } -static ssize_t -dvb_dvr_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t dvb_dvr_write(struct file *file, const char *buf, + size_t count, loff_t *ppos) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv; + struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; int ret; if (!dmxdev->demux->write) @@ -278,11 +271,11 @@ return ret; } -static ssize_t -dvb_dvr_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t dvb_dvr_read(struct file *file, char *buf, size_t count, + loff_t *ppos) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv; + struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; int ret; //down(&dmxdev->mutex); @@ -293,18 +286,16 @@ return ret; } -static inline void -dvb_dmxdev_filter_state_set(dmxdev_filter_t *dmxdevfilter, int state) +static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter *dmxdevfilter, int state) { spin_lock_irq(&dmxdevfilter->dev->lock); dmxdevfilter->state=state; spin_unlock_irq(&dmxdevfilter->dev->lock); } -static int -dvb_dmxdev_set_buffer_size(dmxdev_filter_t *dmxdevfilter, unsigned long size) +static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, unsigned long size) { - dmxdev_buffer_t *buf=&dmxdevfilter->buffer; + struct dmxdev_buffer *buf=&dmxdevfilter->buffer; void *mem; if (buf->size==size) @@ -331,10 +322,9 @@ return 0; } -static void -dvb_dmxdev_filter_timeout(unsigned long data) +static void dvb_dmxdev_filter_timeout(unsigned long data) { - dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *)data; + struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *)data; dmxdevfilter->buffer.error=-ETIMEDOUT; spin_lock_irq(&dmxdevfilter->dev->lock); @@ -343,8 +333,7 @@ wake_up(&dmxdevfilter->buffer.queue); } -static void -dvb_dmxdev_filter_timer(dmxdev_filter_t *dmxdevfilter) +static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) { struct dmx_sct_filter_params *para=&dmxdevfilter->params.sec; @@ -357,12 +346,11 @@ } } -static int -dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, +static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - dmx_section_filter_t *filter, dmx_success_t success) + struct dmx_section_filter *filter, enum dmx_success success) { - dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) filter->priv; + struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) filter->priv; int ret; if (dmxdevfilter->buffer.error) { @@ -394,13 +382,12 @@ return 0; } -static int -dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, +static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - dmx_ts_feed_t *feed, dmx_success_t success) + struct dmx_ts_feed *feed, enum dmx_success success) { - dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) feed->priv; - dmxdev_buffer_t *buffer; + struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) feed->priv; + struct dmxdev_buffer *buffer; int ret; spin_lock(&dmxdevfilter->dev->lock); @@ -433,8 +420,7 @@ /* stop feed but only mark the specified filter as stopped (state set) */ -static int -dvb_dmxdev_feed_stop(dmxdev_filter_t *dmxdevfilter) +static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) { dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); @@ -455,8 +441,7 @@ /* start feed associated with the specified filter */ -static -int dvb_dmxdev_feed_start(dmxdev_filter_t *filter) +static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) { dvb_dmxdev_filter_state_set (filter, DMXDEV_STATE_GO); @@ -478,12 +463,11 @@ /* restart section feed if it has filters left associated with it, otherwise release the feed */ -static -int dvb_dmxdev_feed_restart(dmxdev_filter_t *filter) +static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter) { int i; - dmxdev_t *dmxdev = filter->dev; - uint16_t pid = filter->params.sec.pid; + struct dmxdev *dmxdev = filter->dev; + u16 pid = filter->params.sec.pid; for (i=0; i<dmxdev->filternum; i++) if (dmxdev->filter[i].state>=DMXDEV_STATE_GO && @@ -498,8 +482,7 @@ return 0; } -static int -dvb_dmxdev_filter_stop(dmxdev_filter_t *dmxdevfilter) +static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) { if (dmxdevfilter->state<DMXDEV_STATE_GO) return 0; @@ -534,8 +517,7 @@ return 0; } -static inline int -dvb_dmxdev_filter_reset(dmxdev_filter_t *dmxdevfilter) +static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) { if (dmxdevfilter->state<DMXDEV_STATE_SET) return 0; @@ -546,10 +528,9 @@ return 0; } -static int -dvb_dmxdev_filter_start(dmxdev_filter_t *filter) +static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) { - dmxdev_t *dmxdev = filter->dev; + struct dmxdev *dmxdev = filter->dev; void *mem; int ret, i; @@ -574,8 +555,8 @@ case DMXDEV_TYPE_SEC: { struct dmx_sct_filter_params *para=&filter->params.sec; - dmx_section_filter_t **secfilter=&filter->filter.sec; - dmx_section_feed_t **secfeed=&filter->feed.sec; + struct dmx_section_filter **secfilter=&filter->filter.sec; + struct dmx_section_feed **secfeed=&filter->feed.sec; *secfilter=0; *secfeed=0; @@ -656,13 +637,13 @@ dmx_output_t otype; int ret; int ts_type; - dmx_ts_pes_t ts_pes; - dmx_ts_feed_t **tsfeed = &filter->feed.ts; + enum dmx_ts_pes ts_pes; + struct dmx_ts_feed **tsfeed = &filter->feed.ts; filter->feed.ts = 0; otype=para->output; - ts_pes=(dmx_ts_pes_t) para->pes_type; + ts_pes=(enum dmx_ts_pes) para->pes_type; if (ts_pes<DMX_PES_OTHER) ts_type=TS_DECODER; @@ -709,9 +690,9 @@ static int dvb_demux_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv; + struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; int i; - dmxdev_filter_t *dmxdevfilter; + struct dmxdev_filter *dmxdevfilter; if (!dmxdev->filter) return -EINVAL; @@ -744,8 +725,7 @@ } -static -int dvb_dmxdev_filter_free(dmxdev_t *dmxdev, dmxdev_filter_t *dmxdevfilter) +static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) { if (down_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; @@ -774,8 +754,7 @@ return 0; } -static inline void -invert_mode(dmx_filter_t *filter) +static inline void invert_mode(dmx_filter_t *filter) { int i; @@ -784,9 +763,8 @@ } -static int -dvb_dmxdev_filter_set(dmxdev_t *dmxdev, - dmxdev_filter_t *dmxdevfilter, +static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, + struct dmxdev_filter *dmxdevfilter, struct dmx_sct_filter_params *params) { dprintk ("function : %s\n", __FUNCTION__); @@ -806,9 +784,8 @@ return 0; } -static int -dvb_dmxdev_pes_filter_set(dmxdev_t *dmxdev, - dmxdev_filter_t *dmxdevfilter, +static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, + struct dmxdev_filter *dmxdevfilter, struct dmx_pes_filter_params *params) { dvb_dmxdev_filter_stop(dmxdevfilter); @@ -828,9 +805,8 @@ return 0; } -static ssize_t -dvb_dmxdev_read_sec(dmxdev_filter_t *dfil, struct file *file, - char *buf, size_t count, loff_t *ppos) +static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil, + struct file *file, char *buf, size_t count, loff_t *ppos) { int result, hcount; int done=0; @@ -871,7 +847,7 @@ ssize_t dvb_demux_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - dmxdev_filter_t *dmxdevfilter=dvb_dmxdev_file_to_filter(file); + struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file); int ret=0; if (down_interruptible(&dmxdevfilter->mutex)) @@ -892,8 +868,8 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { - dmxdev_filter_t *dmxdevfilter=dvb_dmxdev_file_to_filter(file); - dmxdev_t *dmxdev=dmxdevfilter->dev; + struct dmxdev_filter *dmxdevfilter=dvb_dmxdev_file_to_filter(file); + struct dmxdev *dmxdev=dmxdevfilter->dev; unsigned long arg=(unsigned long) parg; int ret=0; @@ -959,7 +935,7 @@ ret=-EINVAL; break; } - dmxdev->demux->get_pes_pids(dmxdev->demux, (uint16_t *)parg); + dmxdev->demux->get_pes_pids(dmxdev->demux, (u16 *)parg); break; case DMX_GET_STC: @@ -987,10 +963,9 @@ } -static -unsigned int dvb_demux_poll (struct file *file, poll_table *wait) +static unsigned int dvb_demux_poll (struct file *file, poll_table *wait) { - dmxdev_filter_t *dmxdevfilter = dvb_dmxdev_file_to_filter(file); + struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file); unsigned int mask = 0; if (!dmxdevfilter) @@ -999,7 +974,8 @@ poll_wait(file, &dmxdevfilter->buffer.queue, wait); if (dmxdevfilter->state != DMXDEV_STATE_GO && - dmxdevfilter->state != DMXDEV_STATE_DONE) + dmxdevfilter->state != DMXDEV_STATE_DONE && + dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT) return 0; if (dmxdevfilter->buffer.error) @@ -1012,11 +988,10 @@ } -static -int dvb_demux_release(struct inode *inode, struct file *file) +static int dvb_demux_release(struct inode *inode, struct file *file) { - dmxdev_filter_t *dmxdevfilter = dvb_dmxdev_file_to_filter(file); - dmxdev_t *dmxdev = dmxdevfilter->dev; + struct dmxdev_filter *dmxdevfilter = dvb_dmxdev_file_to_filter(file); + struct dmxdev *dmxdev = dmxdevfilter->dev; return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); } @@ -1041,7 +1016,7 @@ unsigned int cmd, void *parg) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - dmxdev_t *dmxdev=(dmxdev_t *) dvbdev->priv; + struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; int ret=0; @@ -1068,11 +1043,10 @@ } -static -unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) +static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) { struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - dmxdev_t *dmxdev = (dmxdev_t *) dvbdev->priv; + struct dmxdev *dmxdev = (struct dmxdev *) dvbdev->priv; unsigned int mask = 0; dprintk ("function : %s\n", __FUNCTION__); @@ -1092,8 +1066,7 @@ } -static -struct file_operations dvb_dvr_fops = { +static struct file_operations dvb_dvr_fops = { .owner = THIS_MODULE, .read = dvb_dvr_read, .write = dvb_dvr_write, @@ -1111,23 +1084,24 @@ }; int -dvb_dmxdev_init(dmxdev_t *dmxdev, struct dvb_adapter *dvb_adapter) +dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) { int i; if (dmxdev->demux->open(dmxdev->demux)<0) return -EUSERS; - dmxdev->filter=vmalloc(dmxdev->filternum*sizeof(dmxdev_filter_t)); + dmxdev->filter = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_filter)); if (!dmxdev->filter) return -ENOMEM; - dmxdev->dvr=vmalloc(dmxdev->filternum*sizeof(dmxdev_dvr_t)); + dmxdev->dvr = vmalloc(dmxdev->filternum*sizeof(struct dmxdev_dvr)); if (!dmxdev->dvr) { vfree(dmxdev->filter); - dmxdev->filter=0; + dmxdev->filter = NULL; return -ENOMEM; } + sema_init(&dmxdev->mutex, 1); spin_lock_init(&dmxdev->lock); for (i=0; i<dmxdev->filternum; i++) { @@ -1143,13 +1117,12 @@ dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR); dvb_dmxdev_buffer_init(&dmxdev->dvr_buffer); - /* fixme: is this correct? */ - try_module_get(THIS_MODULE); + return 0; } void -dvb_dmxdev_release(dmxdev_t *dmxdev) +dvb_dmxdev_release(struct dmxdev *dmxdev) { dvb_unregister_device(dmxdev->dvbdev); dvb_unregister_device(dmxdev->dvr_dvbdev); @@ -1162,8 +1135,6 @@ dmxdev->dvr=0; } dmxdev->demux->close(dmxdev->demux); - /* fixme: is this correct? */ - module_put(THIS_MODULE); } diff -Nru a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h --- a/drivers/media/dvb/dvb-core/dmxdev.h Fri Jun 27 14:20:06 2003 +++ b/drivers/media/dvb/dvb-core/dmxdev.h Fri Jun 27 14:20:06 2003 @@ -24,55 +24,54 @@ #ifndef _DMXDEV_H_ #define _DMXDEV_H_ -#ifndef __KERNEL__ -#define __KERNEL__ -#endif - -#include <linux/dvb/dmx.h> - -#include <linux/version.h> -#include <linux/wait.h> #include <linux/types.h> +#include <linux/spinlock.h> +#include <linux/kernel.h> +#include <linux/timer.h> +#include <linux/wait.h> #include <linux/fs.h> +#include <linux/string.h> +#include <asm/semaphore.h> + +#include <linux/dvb/dmx.h> #include "dvbdev.h" #include "demux.h" -typedef enum { +enum dmxdevype { DMXDEV_TYPE_NONE, DMXDEV_TYPE_SEC, DMXDEV_TYPE_PES, -} dmxdev_type_t; +}; -typedef enum { +enum dmxdev_state { DMXDEV_STATE_FREE, DMXDEV_STATE_ALLOCATED, DMXDEV_STATE_SET, DMXDEV_STATE_GO, DMXDEV_STATE_DONE, DMXDEV_STATE_TIMEDOUT -} dmxdev_state_t; +}; -typedef struct dmxdev_buffer_s { - uint8_t *data; - uint32_t size; - int32_t pread; - int32_t pwrite; +struct dmxdev_buffer { + u8 *data; + int size; + int pread; + int pwrite; wait_queue_head_t queue; int error; -} dmxdev_buffer_t; - +}; -typedef struct dmxdev_filter_s { +struct dmxdev_filter { struct dvb_device *dvbdev; union { - dmx_section_filter_t *sec; + struct dmx_section_filter *sec; } filter; union { - dmx_ts_feed_t *ts; - dmx_section_feed_t *sec; + struct dmx_ts_feed *ts; + struct dmx_section_feed *sec; } feed; union { @@ -81,50 +80,50 @@ } params; int type; - dmxdev_state_t state; - struct dmxdev_s *dev; - dmxdev_buffer_t buffer; + enum dmxdev_state state; + struct dmxdev *dev; + struct dmxdev_buffer buffer; struct semaphore mutex; - // only for sections + /* only for sections */ struct timer_list timer; int todo; - uint8_t secheader[3]; + u8 secheader[3]; u16 pid; -} dmxdev_filter_t; +}; -typedef struct dmxdev_dvr_s { +struct dmxdev_dvr { int state; - struct dmxdev_s *dev; - dmxdev_buffer_t buffer; -} dmxdev_dvr_t; + struct dmxdev *dev; + struct dmxdev_buffer buffer; +}; -typedef struct dmxdev_s { +struct dmxdev { struct dvb_device *dvbdev; struct dvb_device *dvr_dvbdev; - dmxdev_filter_t *filter; - dmxdev_dvr_t *dvr; - dmx_demux_t *demux; + struct dmxdev_filter *filter; + struct dmxdev_dvr *dvr; + struct dmx_demux *demux; int filternum; int capabilities; #define DMXDEV_CAP_DUPLEX 1 - dmx_frontend_t *dvr_orig_fe; + struct dmx_frontend *dvr_orig_fe; - dmxdev_buffer_t dvr_buffer; + struct dmxdev_buffer dvr_buffer; #define DVR_BUFFER_SIZE (10*188*1024) struct semaphore mutex; spinlock_t lock; -} dmxdev_t; +}; -int dvb_dmxdev_init(dmxdev_t *dmxdev, struct dvb_adapter *); -void dvb_dmxdev_release(dmxdev_t *dmxdev); +int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *); +void dvb_dmxdev_release(struct dmxdev *dmxdev); #endif /* _DMXDEV_H_ */ diff -Nru a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c --- a/drivers/media/dvb/dvb-core/dvb_demux.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/dvb-core/dvb_demux.c Fri Jun 27 14:19:54 2003 @@ -21,46 +21,31 @@ * */ +#include <linux/spinlock.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/module.h> #include <linux/poll.h> -#include <linux/version.h> -#include <asm/uaccess.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #include "compat.h" -#else +#include <linux/string.h> #include <linux/crc32.h> -#endif +#include <asm/uaccess.h> #include "dvb_demux.h" +#include "dvb_functions.h" #define NOBUFS LIST_HEAD(dmx_muxs); -int dmx_register_demux(dmx_demux_t *demux) +int dmx_register_demux(struct dmx_demux *demux) { - struct list_head *pos; - - if (!(demux->id && demux->vendor && demux->model)) - return -EINVAL; - - list_for_each(pos, &dmx_muxs) { - if (!strcmp(DMX_DIR_ENTRY(pos)->id, demux->id)) - return -EEXIST; - } - demux->users = 0; list_add(&demux->reg_list, &dmx_muxs); - /* fixme: is this correct? */ - try_module_get(THIS_MODULE); - return 0; } -int dmx_unregister_demux(dmx_demux_t* demux) +int dmx_unregister_demux(struct dmx_demux* demux) { struct list_head *pos, *n, *head=&dmx_muxs; @@ -69,8 +54,6 @@ if (demux->users>0) return -EINVAL; list_del(pos); - /* fixme: is this correct? */ - module_put(THIS_MODULE); return 0; } } @@ -92,22 +75,19 @@ ******************************************************************************/ -static inline -u16 section_length(const u8 *buf) +static inline u16 section_length(const u8 *buf) { return 3+((buf[1]&0x0f)<<8)+buf[2]; } -static inline -u16 ts_pid(const u8 *buf) +static inline u16 ts_pid(const u8 *buf) { return ((buf[1]&0x1f)<<8)+buf[2]; } -static inline -int payload(const u8 *tsp) +static inline int payload(const u8 *tsp) { if (!(tsp[3]&0x10)) // no payload? return 0; @@ -134,15 +114,13 @@ } -static -u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len) +static u32 dvb_dmx_crc32 (struct dvb_demux_feed *f, const u8 *src, size_t len) { return (f->feed.sec.crc_val = crc32_le (f->feed.sec.crc_val, src, len)); } -static -void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len) +static void dvb_dmx_memcopy (struct dvb_demux_feed *f, u8 *d, const u8 *s, size_t len) { memcpy (d, s, len); } @@ -152,8 +130,7 @@ * Software filter functions ******************************************************************************/ -static inline -int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf) +static inline int dvb_dmx_swfilter_payload (struct dvb_demux_feed *feed, const u8 *buf) { int count = payload(buf); int p; @@ -182,8 +159,7 @@ } -static -int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed, +static int dvb_dmx_swfilter_sectionfilter (struct dvb_demux_feed *feed, struct dvb_demux_filter *f) { u8 neq = 0; @@ -206,12 +182,11 @@ } -static inline -int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed) +static inline int dvb_dmx_swfilter_section_feed (struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct dvb_demux_filter *f = feed->filter; - dmx_section_feed_t *sec = &feed->feed.sec; + struct dmx_section_feed *sec = &feed->feed.sec; u8 *buf = sec->secbuf; if (sec->secbufp != sec->seclen) @@ -239,11 +214,10 @@ } -static -int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) +static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, const u8 *buf) { struct dvb_demux *demux = feed->demux; - dmx_section_feed_t *sec = &feed->feed.sec; + struct dmx_section_feed *sec = &feed->feed.sec; int p, count; int ccok, rest; u8 cc; @@ -366,8 +340,7 @@ } -static inline -void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf) +static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf) { switch(feed->type) { case DMX_TYPE_TS: @@ -459,8 +432,7 @@ } -static -struct dvb_demux_filter* dvb_dmx_filter_alloc(struct dvb_demux *demux) +static struct dvb_demux_filter * dvb_dmx_filter_alloc(struct dvb_demux *demux) { int i; @@ -476,8 +448,7 @@ return &demux->filter[i]; } -static -struct dvb_demux_feed* dvb_dmx_feed_alloc(struct dvb_demux *demux) +static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux) { int i; @@ -494,8 +465,7 @@ } -static -int dmx_pid_set (u16 pid, struct dvb_demux_feed *feed) +static int dmx_pid_set (u16 pid, struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct list_head *pos, *n, *head=&demux->feed_list; @@ -506,12 +476,14 @@ if (pid == feed->pid) return 0; - if (feed->pid <= DMX_MAX_PID) - list_for_each_safe(pos, n, head) + if (feed->pid <= DMX_MAX_PID) { + list_for_each_safe(pos, n, head) { if (DMX_FEED_ENTRY(pos)->pid == feed->pid) { list_del(pos); break; } + } + } list_add(&feed->list_head, head); feed->pid = pid; @@ -520,9 +492,8 @@ } -static -int dmx_ts_feed_set (struct dmx_ts_feed_s* ts_feed, u16 pid, int ts_type, - dmx_ts_pes_t pes_type, size_t callback_length, +static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type, + enum dmx_ts_pes pes_type, size_t callback_length, size_t circular_buffer_size, int descramble, struct timespec timeout) { @@ -596,8 +567,7 @@ } -static -int dmx_ts_feed_start_filtering(struct dmx_ts_feed_s* ts_feed) +static int dmx_ts_feed_start_filtering(struct dmx_ts_feed* ts_feed) { struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; struct dvb_demux *demux = feed->demux; @@ -630,8 +600,7 @@ return 0; } -static -int dmx_ts_feed_stop_filtering(struct dmx_ts_feed_s* ts_feed) +static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed* ts_feed) { struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; struct dvb_demux *demux = feed->demux; @@ -661,8 +630,7 @@ return ret; } -static -int dvbdmx_allocate_ts_feed (dmx_demux_t *dmx, dmx_ts_feed_t **ts_feed, +static int dvbdmx_allocate_ts_feed (struct dmx_demux *dmx, struct dmx_ts_feed **ts_feed, dmx_ts_cb callback) { struct dvb_demux *demux = (struct dvb_demux *) dmx; @@ -684,12 +652,12 @@ feed->buffer = 0; (*ts_feed) = &feed->feed.ts; - (*ts_feed)->is_filtering = 0; (*ts_feed)->parent = dmx; (*ts_feed)->priv = 0; - (*ts_feed)->set = dmx_ts_feed_set; + (*ts_feed)->is_filtering = 0; (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering; (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering; + (*ts_feed)->set = dmx_ts_feed_set; if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { @@ -707,8 +675,7 @@ return 0; } -static -int dvbdmx_release_ts_feed(dmx_demux_t *dmx, dmx_ts_feed_t *ts_feed) +static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_feed) { struct dvb_demux *demux = (struct dvb_demux *) dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed; @@ -753,9 +720,8 @@ * dmx_section_feed API calls ******************************************************************************/ -static int -dmx_section_feed_allocate_filter(struct dmx_section_feed_s* feed, - dmx_section_filter_t** filter) +static int dmx_section_feed_allocate_filter(struct dmx_section_feed* feed, + struct dmx_section_filter** filter) { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdemux=dvbdmxfeed->demux; @@ -767,8 +733,9 @@ dvbdmxfilter=dvb_dmx_filter_alloc(dvbdemux); if (!dvbdmxfilter) { up(&dvbdemux->mutex); - return -ENOSPC; + return -EBUSY; } + spin_lock_irq(&dvbdemux->lock); *filter=&dvbdmxfilter->filter; (*filter)->parent=feed; @@ -784,8 +751,8 @@ return 0; } -static int -dmx_section_feed_set(struct dmx_section_feed_s* feed, + +static int dmx_section_feed_set(struct dmx_section_feed* feed, u16 pid, size_t circular_buffer_size, int descramble, int check_crc) { @@ -799,16 +766,18 @@ if (down_interruptible (&dvbdmx->mutex)) return -ERESTARTSYS; - if (dvbdmxfeed->pid <= DMX_MAX_PID) - list_for_each_safe(pos, n, head) + if (dvbdmxfeed->pid <= DMX_MAX_PID) { + list_for_each_safe(pos, n, head) { if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) { list_del(pos); break; } + } + } list_add(&dvbdmxfeed->list_head, head); - dvbdmxfeed->pid=pid; + dvbdmxfeed->pid = pid; dvbdmxfeed->buffer_size=circular_buffer_size; dvbdmxfeed->descramble=descramble; if (dvbdmxfeed->descramble) { @@ -834,8 +803,8 @@ static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed) { int i; - dmx_section_filter_t *sf; struct dvb_demux_filter *f; + struct dmx_section_filter *sf; u8 mask, mode, doneq; if (!(f=dvbdmxfeed->filter)) @@ -854,8 +823,7 @@ } -static int -dmx_section_feed_start_filtering(dmx_section_feed_t *feed) +static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=dvbdmxfeed->demux; @@ -895,8 +863,8 @@ return 0; } -static int -dmx_section_feed_stop_filtering(struct dmx_section_feed_s* feed) + +static int dmx_section_feed_stop_filtering(struct dmx_section_feed* feed) { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=dvbdmxfeed->demux; @@ -918,9 +886,9 @@ return ret; } -static int -dmx_section_feed_release_filter(dmx_section_feed_t *feed, - dmx_section_filter_t* filter) + +static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, + struct dmx_section_filter* filter) { struct dvb_demux_filter *dvbdmxfilter=(struct dvb_demux_filter *) filter, *f; struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; @@ -938,9 +906,10 @@ spin_lock_irq(&dvbdmx->lock); f=dvbdmxfeed->filter; - if (f==dvbdmxfilter) + + if (f == dvbdmxfilter) { dvbdmxfeed->filter=dvbdmxfilter->next; - else { + } else { while(f->next!=dvbdmxfilter) f=f->next; f->next=f->next->next; @@ -951,8 +920,8 @@ return 0; } -static int dvbdmx_allocate_section_feed(dmx_demux_t *demux, - dmx_section_feed_t **feed, +static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, + struct dmx_section_feed **feed, dmx_section_cb callback) { struct dvb_demux *dvbdmx=(struct dvb_demux *) demux; @@ -977,18 +946,19 @@ (*feed)->is_filtering=0; (*feed)->parent=demux; (*feed)->priv=0; + (*feed)->set=dmx_section_feed_set; (*feed)->allocate_filter=dmx_section_feed_allocate_filter; - (*feed)->release_filter=dmx_section_feed_release_filter; (*feed)->start_filtering=dmx_section_feed_start_filtering; (*feed)->stop_filtering=dmx_section_feed_stop_filtering; + (*feed)->release_filter = dmx_section_feed_release_filter; up(&dvbdmx->mutex); return 0; } -static int dvbdmx_release_section_feed(dmx_demux_t *demux, - dmx_section_feed_t *feed) +static int dvbdmx_release_section_feed(struct dmx_demux *demux, + struct dmx_section_feed *feed) { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed; struct dvb_demux *dvbdmx=(struct dvb_demux *) demux; @@ -1010,11 +980,12 @@ dvbdmxfeed->state=DMX_STATE_FREE; if (dvbdmxfeed->pid <= DMX_MAX_PID) { - list_for_each_safe(pos, n, head) + list_for_each_safe(pos, n, head) { if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) { list_del(pos); break; } + } dvbdmxfeed->pid = 0xffff; } @@ -1027,7 +998,7 @@ * dvb_demux kernel data API calls ******************************************************************************/ -static int dvbdmx_open(dmx_demux_t *demux) +static int dvbdmx_open(struct dmx_demux *demux) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; @@ -1037,7 +1008,8 @@ return 0; } -static int dvbdmx_close(struct dmx_demux_s *demux) + +static int dvbdmx_close(struct dmx_demux *demux) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; @@ -1048,12 +1020,12 @@ return 0; } -static int dvbdmx_write(dmx_demux_t *demux, const char *buf, size_t count) + +static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; - if ((!demux->frontend) || - (demux->frontend->source!=DMX_MEMORY_FE)) + if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) return -EINVAL; if (down_interruptible (&dvbdemux->mutex)) @@ -1065,35 +1037,24 @@ } -static int dvbdmx_add_frontend(dmx_demux_t *demux, - dmx_frontend_t *frontend) +static int dvbdmx_add_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; - struct list_head *pos, *head=&dvbdemux->frontend_list; - - if (!(frontend->id && frontend->vendor && frontend->model)) - return -EINVAL; - list_for_each(pos, head) - { - if (!strcmp(DMX_FE_ENTRY(pos)->id, frontend->id)) - return -EEXIST; - } + struct list_head *head = &dvbdemux->frontend_list; list_add(&(frontend->connectivity_list), head); + return 0; } -static int -dvbdmx_remove_frontend(dmx_demux_t *demux, - dmx_frontend_t *frontend) + +static int dvbdmx_remove_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; struct list_head *pos, *n, *head=&dvbdemux->frontend_list; - list_for_each_safe (pos, n, head) - { - if (DMX_FE_ENTRY(pos)==frontend) - { + list_for_each_safe (pos, n, head) { + if (DMX_FE_ENTRY(pos) == frontend) { list_del(pos); return 0; } @@ -1101,8 +1062,8 @@ return -ENODEV; } -static struct list_head * -dvbdmx_get_frontends(dmx_demux_t *demux) + +static struct list_head * dvbdmx_get_frontends(struct dmx_demux *demux) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; @@ -1111,8 +1072,8 @@ return &dvbdemux->frontend_list; } -static int dvbdmx_connect_frontend(dmx_demux_t *demux, - dmx_frontend_t *frontend) + +int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; @@ -1127,7 +1088,8 @@ return 0; } -static int dvbdmx_disconnect_frontend(dmx_demux_t *demux) + +int dvbdmx_disconnect_frontend(struct dmx_demux *demux) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; @@ -1139,7 +1101,8 @@ return 0; } -static int dvbdmx_get_pes_pids(dmx_demux_t *demux, u16 *pids) + +static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 *pids) { struct dvb_demux *dvbdemux=(struct dvb_demux *) demux; @@ -1150,8 +1113,8 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux) { - int i; - dmx_demux_t *dmx=&dvbdemux->dmx; + int i, err; + struct dmx_demux *dmx = &dvbdemux->dmx; dvbdemux->users=0; dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(struct dvb_demux_filter)); @@ -1176,8 +1139,11 @@ dvbdemux->pesfilter[i]=NULL; dvbdemux->pids[i]=0xffff; } - dvbdemux->playing=dvbdemux->recording=0; + INIT_LIST_HEAD(&dvbdemux->feed_list); + + dvbdemux->playing = 0; + dvbdemux->recording = 0; dvbdemux->tsbufp=0; if (!dvbdemux->check_crc32) @@ -1187,9 +1153,8 @@ dvbdemux->memcopy = dvb_dmx_memcopy; dmx->frontend=0; - dmx->reg_list.next=dmx->reg_list.prev=&dmx->reg_list; + dmx->reg_list.prev = dmx->reg_list.next = &dmx->reg_list; dmx->priv=(void *) dvbdemux; - //dmx->users=0; // reset in dmx_register_demux() dmx->open=dvbdmx_open; dmx->close=dvbdmx_close; dmx->write=dvbdmx_write; @@ -1210,8 +1175,8 @@ sema_init(&dvbdemux->mutex, 1); spin_lock_init(&dvbdemux->lock); - if (dmx_register_demux(dmx)<0) - return -1; + if ((err = dmx_register_demux(dmx)) < 0) + return err; return 0; } @@ -1219,7 +1184,7 @@ int dvb_dmx_release(struct dvb_demux *dvbdemux) { - dmx_demux_t *dmx=&dvbdemux->dmx; + struct dmx_demux *dmx = &dvbdemux->dmx; dmx_unregister_demux(dmx); if (dvbdemux->filter) @@ -1228,10 +1193,3 @@ vfree(dvbdemux->feed); return 0; } - -#if 0 -MODULE_DESCRIPTION("Software MPEG Demultiplexer"); -MODULE_AUTHOR("Ralph Metzler, Markus Metzler"); -MODULE_LICENSE("GPL"); -#endif - diff -Nru a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h --- a/drivers/media/dvb/dvb-core/dvb_demux.h Fri Jun 27 14:19:55 2003 +++ b/drivers/media/dvb/dvb-core/dvb_demux.h Fri Jun 27 14:19:55 2003 @@ -25,8 +25,10 @@ #ifndef _DVB_DEMUX_H_ #define _DVB_DEMUX_H_ -#include <asm/semaphore.h> +#include <linux/time.h> #include <linux/timer.h> +#include <linux/spinlock.h> +#include <asm/semaphore.h> #include "demux.h" @@ -43,7 +45,7 @@ #define DVB_DEMUX_MASK_MAX 18 struct dvb_demux_filter { - dmx_section_filter_t filter; + struct dmx_section_filter filter; u8 maskandmode [DMX_MAX_FILTER_SIZE]; u8 maskandnotmode [DMX_MAX_FILTER_SIZE]; int doneq; @@ -66,8 +68,8 @@ struct dvb_demux_feed { union { - dmx_ts_feed_t ts; - dmx_section_feed_t sec; + struct dmx_ts_feed ts; + struct dmx_section_feed sec; } feed; union { @@ -89,7 +91,7 @@ int cb_length; int ts_type; - dmx_ts_pes_t pes_type; + enum dmx_ts_pes pes_type; int cc; @@ -99,7 +101,7 @@ }; struct dvb_demux { - dmx_demux_t dmx; + struct dmx_demux dmx; void *priv; int filternum; int feednum; @@ -140,4 +142,8 @@ void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, size_t count); void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count); +int dvbdmx_connect_frontend(struct dmx_demux *demux, struct dmx_frontend *frontend); +int dvbdmx_disconnect_frontend(struct dmx_demux *demux); + #endif /* _DVB_DEMUX_H_ */ + diff -Nru a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c --- a/drivers/media/dvb/dvb-core/dvb_filter.c Fri Jun 27 14:20:06 2003 +++ b/drivers/media/dvb/dvb-core/dvb_filter.c Fri Jun 27 14:20:06 2003 @@ -1,4 +1,6 @@ +#include <linux/kernel.h> #include <linux/module.h> +#include <linux/string.h> #include "dvb_filter.h" unsigned int bitrates[3][16] = @@ -6,14 +8,14 @@ {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; -uint32_t freq[4] = {441, 480, 320, 0}; +u32 freq[4] = {441, 480, 320, 0}; unsigned int ac3_bitrates[32] = {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, 0,0,0,0,0,0,0,0,0,0,0,0,0}; -uint32_t ac3_freq[4] = {480, 441, 320, 0}; -uint32_t ac3_frames[3][32] = +u32 ac3_freq[4] = {480, 441, 320, 0}; +u32 ac3_frames[3][32] = {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, @@ -24,8 +26,7 @@ #if 0 -static -void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, +static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, void (*pes_write)(u8 *buf, int count, void *data), void *priv) { @@ -39,8 +40,7 @@ #endif #if 0 -static -void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) +static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) { u8 off = 0; @@ -66,10 +66,9 @@ #if 0 /* needs 5 byte input, returns picture coding type*/ -static -int read_picture_header(uint8_t *headr, mpg_picture *pic, int field, int pr) +static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr) { - uint8_t pct; + u8 pct; if (pr) printk( "Pic header: "); pic->temporal_reference[field] = (( headr[0] << 2 ) | @@ -113,8 +112,7 @@ #if 0 /* needs 4 byte input */ -static -int read_gop_header(uint8_t *headr, mpg_picture *pic, int pr) +static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr) { if (pr) printk("GOP header: "); @@ -145,8 +143,7 @@ #if 0 /* needs 8 byte input */ -static -int read_sequence_header(uint8_t *headr, VideoInfo *vi, int pr) +static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr) { int sw; int form = -1; @@ -260,15 +257,14 @@ #if 0 -static -int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr) +static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr) { - uint8_t *headr; + u8 *headr; int found = 0; int c = 0; while (found < 4 && c+4 < count){ - uint8_t *b; + u8 *b; b = mbuf+c; if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 @@ -290,16 +286,15 @@ #if 0 -static -int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr) +static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) { - uint8_t *headr; + u8 *headr; int found = 0; int c = 0; int fr = 0; while (found < 2 && c < count){ - uint8_t b[2]; + u8 b[2]; memcpy( b, mbuf+c, 2); if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) @@ -346,16 +341,16 @@ #endif -int dvb_filter_get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr) +int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) { - uint8_t *headr; + u8 *headr; int found = 0; int c = 0; - uint8_t frame = 0; + u8 frame = 0; int fr = 0; while ( !found && c < count){ - uint8_t *b = mbuf+c; + u8 *b = mbuf+c; if ( b[0] == 0x0b && b[1] == 0x77 ) found = 1; @@ -378,18 +373,18 @@ ai->bit_rate = ac3_bitrates[frame >> 1]*1000; if (pr) - printk(" BRate: %d kb/s", ai->bit_rate/1000); + printk(" BRate: %d kb/s", (int) ai->bit_rate/1000); ai->frequency = (headr[2] & 0xc0 ) >> 6; fr = (headr[2] & 0xc0 ) >> 6; ai->frequency = freq[fr]*100; - if (pr) printk (" Freq: %d Hz\n", ai->frequency); + if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency); ai->framesize = ac3_frames[fr][frame >> 1]; if ((frame & 1) && (fr == 1)) ai->framesize++; ai->framesize = ai->framesize << 1; - if (pr) printk (" Framesize %d\n", ai->framesize); + if (pr) printk (" Framesize %d\n",(int) ai->framesize); return 0; @@ -397,12 +392,11 @@ #if 0 -static -uint8_t *skip_pes_header(uint8_t **bufp) +static u8 *skip_pes_header(u8 **bufp) { - uint8_t *inbuf = *bufp; - uint8_t *buf = inbuf; - uint8_t *pts = NULL; + u8 *inbuf = *bufp; + u8 *buf = inbuf; + u8 *pts = NULL; int skip = 0; static const int mpeg1_skip_table[16] = { @@ -436,8 +430,7 @@ #endif #if 0 -static -void initialize_quant_matrix( uint32_t *matrix ) +static void initialize_quant_matrix( u32 *matrix ) { int i; @@ -464,8 +457,7 @@ #endif #if 0 -static -void initialize_mpg_picture(mpg_picture *pic) +static void initialize_mpg_picture(struct mpg_picture *pic) { int i; @@ -492,8 +484,7 @@ #endif #if 0 -static -void mpg_set_picture_parameter( int32_t field_type, mpg_picture *pic ) +static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic ) { int16_t last_h_offset; int16_t last_v_offset; @@ -531,8 +522,7 @@ #endif #if 0 -static -void init_mpg_picture( mpg_picture *pic, int chan, int32_t field_type) +static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type) { pic->picture_header = 0; pic->sequence_header_data @@ -561,7 +551,7 @@ } #endif -void dvb_filter_pes2ts_init(dvb_filter_pes2ts_t *p2ts, unsigned short pid, +void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, dvb_filter_pes2ts_cb_t *cb, void *priv) { unsigned char *buf=p2ts->buf; @@ -574,7 +564,7 @@ p2ts->priv=priv; } -int dvb_filter_pes2ts(dvb_filter_pes2ts_t *p2ts, unsigned char *pes, int len) +int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, int len) { unsigned char *buf=p2ts->buf; int ret=0, rest; diff -Nru a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h --- a/drivers/media/dvb/dvb-core/dvb_filter.h Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/dvb-core/dvb_filter.h Fri Jun 27 14:19:54 2003 @@ -2,23 +2,22 @@ #define _DVB_FILTER_H_ #include <linux/slab.h> -#include <linux/vmalloc.h> #include "demux.h" typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *); -typedef struct dvb_filter_pes2ts_s { +struct dvb_filter_pes2ts { unsigned char buf[188]; unsigned char cc; dvb_filter_pes2ts_cb_t *cb; void *priv; -} dvb_filter_pes2ts_t; +}; -void dvb_filter_pes2ts_init(dvb_filter_pes2ts_t *p2ts, unsigned short pid, +void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, dvb_filter_pes2ts_cb_t *cb, void *priv); -int dvb_filter_pes2ts(dvb_filter_pes2ts_t *p2ts, unsigned char *pes, int len); +int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, int len); #define PROG_STREAM_MAP 0xBC @@ -35,14 +34,14 @@ #define ISO13522_STREAM 0xF3 #define PROG_STREAM_DIR 0xFF -#define PICTURE_START 0x00 -#define USER_START 0xb2 -#define SEQUENCE_HEADER 0xb3 -#define SEQUENCE_ERROR 0xb4 -#define EXTENSION_START 0xb5 -#define SEQUENCE_END 0xb7 -#define GOP_START 0xb8 -#define EXCEPT_SLICE 0xb0 +#define DVB_PICTURE_START 0x00 +#define DVB_USER_START 0xb2 +#define DVB_SEQUENCE_HEADER 0xb3 +#define DVB_SEQUENCE_ERROR 0xb4 +#define DVB_EXTENSION_START 0xb5 +#define DVB_SEQUENCE_END 0xb7 +#define DVB_GOP_START 0xb8 +#define DVB_EXCEPT_SLICE 0xb0 #define SEQUENCE_EXTENSION 0x01 #define SEQUENCE_DISPLAY_EXTENSION 0x02 @@ -111,12 +110,12 @@ #define IPACKS 2048 #endif -typedef struct ipack_s { +struct ipack { int size; int found; u8 *buf; u8 cid; - uint32_t plength; + u32 plength; u8 plen[2]; u8 flag1; u8 flag2; @@ -131,34 +130,33 @@ void (*func)(u8 *buf, int size, void *priv); int count; int repack_subids; -} ipack; - -typedef struct video_i{ - uint32_t horizontal_size; - uint32_t vertical_size; - uint32_t aspect_ratio; - uint32_t framerate; - uint32_t video_format; - uint32_t bit_rate; - uint32_t comp_bit_rate; - uint32_t vbv_buffer_size; - int16_t vbv_delay; - uint32_t CSPF; - uint32_t off; -} VideoInfo; +}; +struct dvb_video_info { + u32 horizontal_size; + u32 vertical_size; + u32 aspect_ratio; + u32 framerate; + u32 video_format; + u32 bit_rate; + u32 comp_bit_rate; + u32 vbv_buffer_size; + s16 vbv_delay; + u32 CSPF; + u32 off; +}; #define OFF_SIZE 4 #define FIRST_FIELD 0 #define SECOND_FIELD 1 #define VIDEO_FRAME_PICTURE 0x03 -typedef struct mpg_picture_s{ +struct mpg_picture { int channel; - VideoInfo vinfo; - uint32_t *sequence_gop_header; - uint32_t *picture_header; - int32_t time_code; + struct dvb_video_info vinfo; + u32 *sequence_gop_header; + u32 *picture_header; + s32 time_code; int low_delay; int closed_gop; int broken_link; @@ -166,12 +164,12 @@ int gop_flag; int sequence_end_flag; - uint8_t profile_and_level; - int32_t picture_coding_parameter; - uint32_t matrix[32]; - int8_t matrix_change_flag; + u8 profile_and_level; + s32 picture_coding_parameter; + u32 matrix[32]; + s8 matrix_change_flag; - uint8_t picture_header_parameter; + u8 picture_header_parameter; /* bit 0 - 2: bwd f code bit 3 : fpb vector bit 4 - 6: fwd f code @@ -180,11 +178,11 @@ int mpeg1_flag; int progressive_sequence; int sequence_display_extension_flag; - uint32_t sequence_header_data; - int16_t last_frame_centre_horizontal_offset; - int16_t last_frame_centre_vertical_offset; + u32 sequence_header_data; + s16 last_frame_centre_horizontal_offset; + s16 last_frame_centre_vertical_offset; - uint32_t pts[2]; /* [0] 1st field, [1] 2nd field */ + u32 pts[2]; /* [0] 1st field, [1] 2nd field */ int top_field_first; int repeat_first_field; int progressive_frame; @@ -192,39 +190,36 @@ int forward_bank; int backward_bank; int compress; - int16_t frame_centre_horizontal_offset[OFF_SIZE]; + s16 frame_centre_horizontal_offset[OFF_SIZE]; /* [0-2] 1st field, [3] 2nd field */ - int16_t frame_centre_vertical_offset[OFF_SIZE]; + s16 frame_centre_vertical_offset[OFF_SIZE]; /* [0-2] 1st field, [3] 2nd field */ - int16_t temporal_reference[2]; + s16 temporal_reference[2]; /* [0] 1st field, [1] 2nd field */ - int8_t picture_coding_type[2]; + s8 picture_coding_type[2]; /* [0] 1st field, [1] 2nd field */ - int8_t picture_structure[2]; + s8 picture_structure[2]; /* [0] 1st field, [1] 2nd field */ - int8_t picture_display_extension_flag[2]; + s8 picture_display_extension_flag[2]; /* [0] 1st field, [1] 2nd field */ /* picture_display_extenion() 0:no 1:exit*/ - int8_t pts_flag[2]; + s8 pts_flag[2]; /* [0] 1st field, [1] 2nd field */ -} mpg_picture; - - - +}; -typedef struct audio_i{ +struct dvb_audio_info { int layer ; - uint32_t bit_rate ; - uint32_t frequency ; - uint32_t mode ; - uint32_t mode_extension ; - uint32_t emphasis ; - uint32_t framesize; - uint32_t off; -} AudioInfo; + u32 bit_rate; + u32 frequency; + u32 mode; + u32 mode_extension ; + u32 emphasis; + u32 framesize; + u32 off; +}; -int dvb_filter_get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr); +int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr); #endif diff -Nru a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c --- a/drivers/media/dvb/dvb-core/dvb_frontend.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c Fri Jun 27 14:19:54 2003 @@ -22,15 +22,20 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ +#include <linux/string.h> +#include <linux/kernel.h> #include <linux/sched.h> -#include <linux/smp_lock.h> +#include <linux/wait.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/module.h> #include <linux/list.h> +#include <asm/processor.h> +#include <asm/semaphore.h> #include "dvb_frontend.h" #include "dvbdev.h" +#include "dvb_functions.h" static int dvb_frontend_debug = 0; @@ -59,7 +64,7 @@ struct semaphore sem; struct list_head list_head; wait_queue_head_t wait_queue; - struct task_struct *thread; + pid_t thread_pid; unsigned long release_jiffies; unsigned long lost_sync_jiffies; int bending; @@ -97,16 +102,7 @@ static DECLARE_MUTEX(frontend_mutex); -static -inline void ddelay (int ms) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout((HZ*ms)/1000); -} - - -static -int dvb_frontend_internal_ioctl (struct dvb_frontend *frontend, +static int dvb_frontend_internal_ioctl (struct dvb_frontend *frontend, unsigned int cmd, void *arg) { int err = -EOPNOTSUPP; @@ -116,10 +112,10 @@ if (frontend->before_ioctl) err = frontend->before_ioctl (frontend, cmd, arg); - if (err) { + if (err == -EOPNOTSUPP) { err = frontend->ioctl (frontend, cmd, arg); - if (err && frontend->after_ioctl) + if ((err == -EOPNOTSUPP) && frontend->after_ioctl) err = frontend->after_ioctl (frontend, cmd, arg); } @@ -134,8 +130,7 @@ * should make it still possible to receive the requested transponder * on both tuners... */ -static -void dvb_bend_frequency (struct dvb_frontend_data *this_fe, int recursive) +static void dvb_bend_frequency (struct dvb_frontend_data *this_fe, int recursive) { struct list_head *entry; int stepsize = this_fe->info->frequency_stepsize; @@ -188,8 +183,7 @@ } -static -void dvb_call_frontend_notifiers (struct dvb_frontend_data *fe, +static void dvb_call_frontend_notifiers (struct dvb_frontend_data *fe, fe_status_t s) { dprintk ("%s\n", __FUNCTION__); @@ -198,7 +192,7 @@ fe->lost_sync_jiffies = jiffies; if (((s ^ fe->status) & FE_HAS_LOCK) && (s & FE_HAS_LOCK)) - ddelay (fe->info->notifier_delay); + dvb_delay (fe->info->notifier_delay); fe->status = s; @@ -213,8 +207,7 @@ } -static -void dvb_frontend_add_event (struct dvb_frontend_data *fe, fe_status_t status) +static void dvb_frontend_add_event (struct dvb_frontend_data *fe, fe_status_t status) { struct dvb_fe_events *events = &fe->events; struct dvb_frontend_event *e; @@ -252,8 +245,7 @@ } -static -int dvb_frontend_get_event (struct dvb_frontend_data *fe, +static int dvb_frontend_get_event (struct dvb_frontend_data *fe, struct dvb_frontend_event *event, int flags) { struct dvb_fe_events *events = &fe->events; @@ -291,8 +283,7 @@ } -static -int dvb_frontend_set_parameters (struct dvb_frontend_data *fe, +static int dvb_frontend_set_parameters (struct dvb_frontend_data *fe, struct dvb_frontend_parameters *param, int first_trial) { @@ -313,7 +304,7 @@ dvb_bend_frequency (fe, 0); dprintk ("%s: f == %i, drift == %i\n", - __FUNCTION__, param->frequency, fe->lnb_drift); + __FUNCTION__, (int) param->frequency, (int) fe->lnb_drift); param->frequency += fe->lnb_drift + fe->bending; err = dvb_frontend_internal_ioctl (frontend, FE_SET_FRONTEND, param); @@ -324,8 +315,7 @@ return err; } -static -void dvb_frontend_init (struct dvb_frontend_data *fe) +static void dvb_frontend_init (struct dvb_frontend_data *fe) { struct dvb_frontend *frontend = &fe->frontend; @@ -337,8 +327,7 @@ } -static -void update_delay (int *quality, int *delay, int locked) +static void update_delay (int *quality, int *delay, int locked) { int q2; @@ -363,8 +352,7 @@ * here we only come when we have lost the lock bit, * let's try to do something useful... */ -static -void dvb_frontend_recover (struct dvb_frontend_data *fe) +static void dvb_frontend_recover (struct dvb_frontend_data *fe) { dprintk ("%s\n", __FUNCTION__); @@ -391,6 +379,8 @@ if (fe->info->type == FE_QPSK) stepsize = fe->parameters.u.qpsk.symbol_rate / 16000; + else if (fe->info->type == FE_QAM) + stepsize = 0; else stepsize = fe->info->frequency_stepsize * 2; @@ -410,8 +400,7 @@ -static -int dvb_frontend_is_exiting (struct dvb_frontend_data *fe) +static int dvb_frontend_is_exiting (struct dvb_frontend_data *fe) { if (fe->exit) return 1; @@ -424,46 +413,34 @@ } -static -int dvb_frontend_thread (void *data) +static int dvb_frontend_thread (void *data) { struct dvb_frontend_data *fe = (struct dvb_frontend_data *) data; + char name [15]; int quality = 0, delay = 3*HZ; fe_status_t s; dprintk ("%s\n", __FUNCTION__); - lock_kernel (); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61)) - daemonize (); -#else - daemonize ("dvb fe"); -#endif -/* not needed anymore in 2.5.x, done in daemonize() */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - reparent_to_init (); -#endif - - sigfillset (¤t->blocked); - fe->thread = current; - snprintf (current->comm, sizeof (current->comm), "kdvb-fe-%i:%i", + snprintf (name, sizeof(name), "kdvb-fe-%i:%i", fe->frontend.i2c->adapter->num, fe->frontend.i2c->id); - unlock_kernel (); - dvb_call_frontend_notifiers (fe, 0); - dvb_frontend_init (fe); + dvb_kernel_thread_setup (name); fe->lost_sync_count = -1; + dvb_call_frontend_notifiers (fe, 0); + dvb_frontend_init (fe); + while (!dvb_frontend_is_exiting (fe)) { up (&fe->sem); /* is locked when we enter the thread... */ interruptible_sleep_on_timeout (&fe->wait_queue, delay); + if (signal_pending(current)) + break; - if (down_interruptible (&fe->sem)) { - fe->thread = NULL; - return -ERESTARTSYS; - } + if (down_interruptible (&fe->sem)) + break; if (fe->lost_sync_count == -1) continue; @@ -505,47 +482,79 @@ dvb_frontend_internal_ioctl (&fe->frontend, FE_SLEEP, NULL); up (&fe->sem); - fe->thread = NULL; + + fe->thread_pid = 0; + mb(); + + wake_up_interruptible (&fe->wait_queue); return 0; } -static -void dvb_frontend_stop (struct dvb_frontend_data *fe) +static void dvb_frontend_stop (struct dvb_frontend_data *fe) { dprintk ("%s\n", __FUNCTION__); - while (fe->thread) { fe->exit = 1; + mb(); + + if (!fe->thread_pid) + return; + + /* check if the thread is really alive */ + if (kill_proc(fe->thread_pid, 0, 1) == -ESRCH) { + printk("dvb_frontend_stop: thread PID %d already died\n", + fe->thread_pid); + /* make sure the mutex was not held by the thread */ + init_MUTEX (&fe->sem); + return; + } + wake_up_interruptible (&fe->wait_queue); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (5); - if (signal_pending(current)) - break; - }; + interruptible_sleep_on(&fe->wait_queue); + + /* paranoia check */ + if (fe->thread_pid) + printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", + fe->thread_pid); } -static -void dvb_frontend_start (struct dvb_frontend_data *fe) +static int dvb_frontend_start (struct dvb_frontend_data *fe) { + int ret; + dprintk ("%s\n", __FUNCTION__); - if (fe->thread) + if (fe->thread_pid) { + if (!fe->exit) + return 0; + else dvb_frontend_stop (fe); + } + if (signal_pending(current)) + return -EINTR; if (down_interruptible (&fe->sem)) - return; + return -EINTR; fe->exit = 0; - fe->thread = (void*) ~0; + fe->thread_pid = 0; + mb(); - kernel_thread (dvb_frontend_thread, fe, 0); + ret = kernel_thread (dvb_frontend_thread, fe, 0); + if (ret < 0) { + printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); + up(&fe->sem); + return ret; + } + fe->thread_pid = ret; + + return 0; } -static -int dvb_frontend_ioctl (struct inode *inode, struct file *file, +static int dvb_frontend_ioctl (struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev = file->private_data; @@ -588,8 +597,7 @@ } -static -unsigned int dvb_frontend_poll (struct file *file, struct poll_table_struct *wait) +static unsigned int dvb_frontend_poll (struct file *file, struct poll_table_struct *wait) { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend_data *fe = dvbdev->priv; @@ -605,8 +613,7 @@ } -static -int dvb_frontend_open (struct inode *inode, struct file *file) +static int dvb_frontend_open (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend_data *fe = dvbdev->priv; @@ -618,18 +625,19 @@ return ret; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - dvb_frontend_start (fe); + ret = dvb_frontend_start (fe); + if (ret) + dvb_generic_release (inode, file); /* empty event queue */ - fe->events.eventr = fe->events.eventw; + fe->events.eventr = fe->events.eventw = 0; } return ret; } -static -int dvb_frontend_release (struct inode *inode, struct file *file) +static int dvb_frontend_release (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dvb_frontend_data *fe = dvbdev->priv; @@ -830,8 +838,7 @@ } -static -struct file_operations dvb_frontend_fops = { +static struct file_operations dvb_frontend_fops = { .owner = THIS_MODULE, .ioctl = dvb_generic_ioctl, .poll = dvb_frontend_poll, diff -Nru a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h --- a/drivers/media/dvb/dvb-core/dvb_frontend.h Fri Jun 27 14:20:04 2003 +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h Fri Jun 27 14:20:04 2003 @@ -25,15 +25,12 @@ #ifndef _DVB_FRONTEND_H_ #define _DVB_FRONTEND_H_ -#include <asm/types.h> +#include <linux/types.h> #include <linux/sched.h> #include <linux/ioctl.h> #include <linux/i2c.h> #include <linux/module.h> - -#ifndef MODULE_LICENSE -#define MODULE_LICENSE(x) -#endif +#include <linux/errno.h> #include <linux/dvb/frontend.h> diff -Nru a/drivers/media/dvb/dvb-core/dvb_functions.c b/drivers/media/dvb/dvb-core/dvb_functions.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/dvb/dvb-core/dvb_functions.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,86 @@ +#include <linux/version.h> +#include <linux/string.h> +#include <linux/smp_lock.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/module.h> +#include <linux/ioctl.h> +#include <linux/slab.h> +#include <asm/uaccess.h> + +void dvb_kernel_thread_setup (const char *thread_name) +{ + lock_kernel (); + + daemonize (thread_name); + + sigfillset (¤t->blocked); + + unlock_kernel (); +} + +/* if the miracle happens and "generic_usercopy()" is included into + the kernel, then this can vanish. please don't make the mistake and + define this as video_usercopy(). this will introduce a dependecy + to the v4l "videodev.o" module, which is unnecessary for some + cards (ie. the budget dvb-cards don't need the v4l module...) */ +int dvb_usercopy(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg)) +{ + char sbuf[128]; + void *mbuf = NULL; + void *parg = NULL; + int err = -EINVAL; + + /* Copy arguments into temp kernel buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: + parg = (void *)arg; + break; + case _IOC_READ: /* some v4l ioctls are marked wrong ... */ + case _IOC_WRITE: + case (_IOC_WRITE | _IOC_READ): + if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { + parg = sbuf; + } else { + /* too big to allocate from stack */ + mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); + if (NULL == mbuf) + return -ENOMEM; + parg = mbuf; + } + + err = -EFAULT; + if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd))) + goto out; + break; + } + + /* call driver */ + if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD) + err = -EINVAL; + + if (err < 0) + goto out; + + /* Copy results into user buffer */ + switch (_IOC_DIR(cmd)) + { + case _IOC_READ: + case (_IOC_WRITE | _IOC_READ): + if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd))) + err = -EFAULT; + break; + } + +out: + if (mbuf) + kfree(mbuf); + + return err; +} + +EXPORT_SYMBOL(dvb_usercopy); +EXPORT_SYMBOL(dvb_kernel_thread_setup); diff -Nru a/drivers/media/dvb/dvb-core/dvb_functions.h b/drivers/media/dvb/dvb-core/dvb_functions.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/dvb/dvb-core/dvb_functions.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,27 @@ +#ifndef __DVB_FUNCTIONS_H__ +#define __DVB_FUNCTIONS_H__ + +/** + * a sleeping delay function, waits i ms + * + */ +static inline +void dvb_delay(int i) +{ + current->state=TASK_INTERRUPTIBLE; + schedule_timeout((HZ*i)/1000); +} + +/* we don't mess with video_usercopy() any more, +we simply define out own dvb_usercopy(), which will hopefull become +generic_usercopy() someday... */ + +extern int dvb_usercopy(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg)); + +extern void dvb_kernel_thread_setup (const char *thread_name); + +#endif + diff -Nru a/drivers/media/dvb/dvb-core/dvb_i2c.c b/drivers/media/dvb/dvb-core/dvb_i2c.c --- a/drivers/media/dvb/dvb-core/dvb_i2c.c Fri Jun 27 14:19:59 2003 +++ b/drivers/media/dvb/dvb-core/dvb_i2c.c Fri Jun 27 14:19:59 2003 @@ -19,16 +19,15 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */ +#include <linux/errno.h> #include <linux/slab.h> #include <linux/list.h> #include <linux/module.h> -#include <linux/version.h> - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #include "compat.h" -#endif +#include <asm/semaphore.h> #include "dvb_i2c.h" +#include "dvb_functions.h" + struct dvb_i2c_device { struct list_head list_head; @@ -42,8 +41,7 @@ DECLARE_MUTEX(dvb_i2c_mutex); -static -int register_i2c_client (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) +static int register_i2c_client (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) { struct dvb_i2c_device *client; @@ -61,8 +59,7 @@ } -static -void try_attach_device (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) +static void try_attach_device (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) { if (dev->owner) { if (!try_module_get(dev->owner)) @@ -78,8 +75,7 @@ } -static -void detach_device (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) +static void detach_device (struct dvb_i2c_bus *i2c, struct dvb_i2c_device *dev) { dev->detach (i2c); @@ -88,8 +84,7 @@ } -static -void unregister_i2c_client_from_bus (struct dvb_i2c_device *dev, +static void unregister_i2c_client_from_bus (struct dvb_i2c_device *dev, struct dvb_i2c_bus *i2c) { struct list_head *entry, *n; @@ -107,8 +102,7 @@ } -static -void unregister_i2c_client_from_all_busses (struct dvb_i2c_device *dev) +static void unregister_i2c_client_from_all_busses (struct dvb_i2c_device *dev) { struct list_head *entry, *n; @@ -122,8 +116,7 @@ } -static -void unregister_all_clients_from_bus (struct dvb_i2c_bus *i2c) +static void unregister_all_clients_from_bus (struct dvb_i2c_bus *i2c) { struct list_head *entry, *n; @@ -137,8 +130,7 @@ } -static -void probe_device_on_all_busses (struct dvb_i2c_device *dev) +static void probe_device_on_all_busses (struct dvb_i2c_device *dev) { struct list_head *entry; @@ -152,8 +144,7 @@ } -static -void probe_devices_on_bus (struct dvb_i2c_bus *i2c) +static void probe_devices_on_bus (struct dvb_i2c_bus *i2c) { struct list_head *entry; @@ -167,8 +158,7 @@ } -static -struct dvb_i2c_bus* dvb_find_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c, +static struct dvb_i2c_bus* dvb_find_i2c_bus (int (*xfer) (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num), struct dvb_adapter *adapter, diff -Nru a/drivers/media/dvb/dvb-core/dvb_ksyms.c b/drivers/media/dvb/dvb-core/dvb_ksyms.c --- a/drivers/media/dvb/dvb-core/dvb_ksyms.c Fri Jun 27 14:20:05 2003 +++ b/drivers/media/dvb/dvb-core/dvb_ksyms.c Fri Jun 27 14:20:05 2003 @@ -1,76 +1,15 @@ +#include <linux/errno.h> #include <linux/module.h> +#include <linux/ioctl.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <asm/uaccess.h> #include "dmxdev.h" -#include "dvb_filter.h" -#include "dvb_frontend.h" -#include "dvb_i2c.h" -#include "dvbdev.h" #include "dvb_demux.h" +#include "dvb_frontend.h" #include "dvb_net.h" - -/* if the miracle happens and "generic_usercopy()" is included into - the kernel, then this can vanish. please don't make the mistake and - define this as video_usercopy(). this will introduce a dependecy - to the v4l "videodev.o" module, which is unnecessary for some - cards (ie. the budget dvb-cards don't need the v4l module...) */ -int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)) -{ - char sbuf[128]; - void *mbuf = NULL; - void *parg = NULL; - int err = -EINVAL; - - /* Copy arguments into temp kernel buffer */ - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: - parg = (void *)arg; - break; - case _IOC_READ: /* some v4l ioctls are marked wrong ... */ - case _IOC_WRITE: - case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; - } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; - } - - err = -EFAULT; - if (copy_from_user(parg, (void *)arg, _IOC_SIZE(cmd))) - goto out; - break; - } - - /* call driver */ - if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD) - err = -EINVAL; - - if (err < 0) - goto out; - - /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { - case _IOC_READ: - case (_IOC_WRITE | _IOC_READ): - if (copy_to_user((void *)arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; - break; - } - -out: - if (mbuf) - kfree(mbuf); - - return err; -} -EXPORT_SYMBOL(dvb_usercopy); +#include "dvb_filter.h" EXPORT_SYMBOL(dvb_dmxdev_init); EXPORT_SYMBOL(dvb_dmxdev_release); @@ -79,6 +18,8 @@ EXPORT_SYMBOL(dvb_dmx_swfilter_packet); EXPORT_SYMBOL(dvb_dmx_swfilter_packets); EXPORT_SYMBOL(dvb_dmx_swfilter); +EXPORT_SYMBOL(dvbdmx_connect_frontend); +EXPORT_SYMBOL(dvbdmx_disconnect_frontend); EXPORT_SYMBOL(dvb_register_frontend); EXPORT_SYMBOL(dvb_unregister_frontend); diff -Nru a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c --- a/drivers/media/dvb/dvb-core/dvb_net.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/dvb-core/dvb_net.c Fri Jun 27 14:19:54 2003 @@ -24,15 +24,18 @@ * */ +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/ioctl.h> +#include <linux/slab.h> #include <asm/uaccess.h> #include <linux/dvb/net.h> + #include "dvb_demux.h" #include "dvb_net.h" - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #include "compat.h" -#endif +#include "dvb_functions.h" #define DVB_NET_MULTICAST_MAX 10 @@ -40,11 +43,11 @@ struct net_device_stats stats; char name[6]; u16 pid; - struct dmx_demux_s *demux; - dmx_section_feed_t *secfeed; - dmx_section_filter_t *secfilter; + struct dmx_demux *demux; + struct dmx_section_feed *secfeed; + struct dmx_section_filter *secfilter; int multi_num; - dmx_section_filter_t *multi_secfilter[DVB_NET_MULTICAST_MAX]; + struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX]; unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6]; int mode; }; @@ -95,8 +98,7 @@ return htons(ETH_P_802_2); } -static void -dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len) +static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int pkt_len) { u8 *eth; struct sk_buff *skb; @@ -132,11 +134,10 @@ netif_rx(skb); } -static int -dvb_net_callback(const u8 *buffer1, size_t buffer1_len, +static int dvb_net_callback(const u8 *buffer1, size_t buffer1_len, const u8 *buffer2, size_t buffer2_len, - dmx_section_filter_t *filter, - dmx_success_t success) + struct dmx_section_filter *filter, + enum dmx_success success) { struct net_device *dev=(struct net_device *) filter->priv; @@ -146,8 +147,7 @@ return 0; } -static int -dvb_net_tx(struct sk_buff *skb, struct net_device *dev) +static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev) { return 0; } @@ -157,9 +157,8 @@ static u8 mac_allmulti[6]={0x01, 0x00, 0x5e, 0x00, 0x00, 0x00}; static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -static int -dvb_net_filter_set(struct net_device *dev, - dmx_section_filter_t **secfilter, +static int dvb_net_filter_set(struct net_device *dev, + struct dmx_section_filter **secfilter, u8 *mac, u8 *mac_mask) { struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; @@ -200,12 +199,11 @@ return 0; } -static int -dvb_net_feed_start(struct net_device *dev) +static int dvb_net_feed_start(struct net_device *dev) { int ret, i; struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; - dmx_demux_t *demux = priv->demux; + struct dmx_demux *demux = priv->demux; unsigned char *mac = (unsigned char *) dev->dev_addr; priv->secfeed=0; @@ -252,8 +250,7 @@ return 0; } -static void -dvb_net_feed_stop(struct net_device *dev) +static void dvb_net_feed_stop(struct net_device *dev) { struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; int i; @@ -283,8 +280,7 @@ printk("%s: no feed to stop\n", dev->name); } -static int -dvb_add_mc_filter(struct net_device *dev, struct dev_mc_list *mc) +static int dvb_add_mc_filter(struct net_device *dev, struct dev_mc_list *mc) { struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; int ret; @@ -300,8 +296,7 @@ return ret; } -static void -dvb_net_set_multi(struct net_device *dev) +static void dvb_net_set_multi(struct net_device *dev) { struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; struct dev_mc_list *mc; @@ -343,16 +338,14 @@ } } -static int -dvb_net_set_config(struct net_device *dev, struct ifmap *map) +static int dvb_net_set_config(struct net_device *dev, struct ifmap *map) { if (netif_running(dev)) return -EBUSY; return 0; } -static int -dvb_net_set_mac(struct net_device *dev, void *p) +static int dvb_net_set_mac(struct net_device *dev, void *p) { struct sockaddr *addr=p; int update; @@ -367,29 +360,25 @@ } -static int -dvb_net_open(struct net_device *dev) +static int dvb_net_open(struct net_device *dev) { dvb_net_feed_start(dev); return 0; } -static int -dvb_net_stop(struct net_device *dev) +static int dvb_net_stop(struct net_device *dev) { dvb_net_feed_stop(dev); return 0; } -static struct net_device_stats * -dvb_net_get_stats(struct net_device *dev) +static struct net_device_stats * dvb_net_get_stats(struct net_device *dev) { return &((struct dvb_net_priv*) dev->priv)->stats; } -static int -dvb_net_init_dev(struct net_device *dev) +static int dvb_net_init_dev(struct net_device *dev) { ether_setup(dev); @@ -411,8 +400,7 @@ return 0; } -static int -get_if(struct dvb_net *dvbnet) +static int get_if(struct dvb_net *dvbnet) { int i; @@ -430,7 +418,7 @@ dvb_net_add_if(struct dvb_net *dvbnet, u16 pid) { struct net_device *net; - dmx_demux_t *demux; + struct dmx_demux *demux; struct dvb_net_priv *priv; int result; int if_num; @@ -524,15 +512,14 @@ break; } case NET_REMOVE_IF: - return dvb_net_remove_if(dvbnet, (int) parg); + return dvb_net_remove_if(dvbnet, (long) parg); default: return -EINVAL; } return 0; } -static int -dvb_net_ioctl(struct inode *inode, struct file *file, +static int dvb_net_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); @@ -569,7 +556,7 @@ } int -dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet, dmx_demux_t *dmx) +dvb_net_init(struct dvb_adapter *adap, struct dvb_net *dvbnet, struct dmx_demux *dmx) { int i; diff -Nru a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h --- a/drivers/media/dvb/dvb-core/dvb_net.h Fri Jun 27 14:19:53 2003 +++ b/drivers/media/dvb/dvb-core/dvb_net.h Fri Jun 27 14:19:53 2003 @@ -33,18 +33,18 @@ #define DVB_NET_DEVICES_MAX 10 -typedef struct dvb_net { +struct dvb_net { struct dvb_device *dvbdev; int card_num; int dev_num; struct net_device device[DVB_NET_DEVICES_MAX]; int state[DVB_NET_DEVICES_MAX]; - dmx_demux_t *demux; -} dvb_net_t; + struct dmx_demux *demux; +}; void dvb_net_release(struct dvb_net *); -int dvb_net_init(struct dvb_adapter *, struct dvb_net *, dmx_demux_t *); +int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *); #endif diff -Nru a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c Fri Jun 27 14:19:59 2003 +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c Fri Jun 27 14:19:59 2003 @@ -32,16 +32,18 @@ #define __KERNEL_SYSCALLS__ +#include <linux/errno.h> #include <linux/kernel.h> -#include <linux/sched.h> #include <linux/module.h> +#include <linux/sched.h> +#include <linux/string.h> #include <asm/uaccess.h> #include "dvb_ringbuffer.h" -void dvb_ringbuffer_init(dvb_ringbuffer_t *rbuf, void *data, size_t len) +void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) { rbuf->pread=rbuf->pwrite=0; rbuf->data=data; @@ -50,19 +52,18 @@ init_waitqueue_head(&rbuf->queue); spin_lock_init(&(rbuf->lock)); - rbuf->lock=SPIN_LOCK_UNLOCKED; } -int dvb_ringbuffer_empty(dvb_ringbuffer_t *rbuf) +int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf) { return (rbuf->pread==rbuf->pwrite); } -ssize_t dvb_ringbuffer_free(dvb_ringbuffer_t *rbuf) +ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf) { ssize_t free; @@ -74,7 +75,7 @@ -ssize_t dvb_ringbuffer_avail(dvb_ringbuffer_t *rbuf) +ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) { ssize_t avail; @@ -86,14 +87,14 @@ -void dvb_ringbuffer_flush(dvb_ringbuffer_t *rbuf) +void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) { rbuf->pread = rbuf->pwrite; } -void dvb_ringbuffer_flush_spinlock_wakeup(dvb_ringbuffer_t *rbuf) +void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf) { unsigned long flags; @@ -106,7 +107,7 @@ -ssize_t dvb_ringbuffer_read(dvb_ringbuffer_t *rbuf, u8 *buf, size_t len, int usermem) +ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem) { size_t todo = len; size_t split; @@ -135,7 +136,7 @@ -ssize_t dvb_ringbuffer_write(dvb_ringbuffer_t *rbuf, const u8 *buf, +ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len, int usermem) { size_t todo = len; diff -Nru a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h Fri Jun 27 14:20:06 2003 +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h Fri Jun 27 14:20:06 2003 @@ -32,8 +32,10 @@ #ifndef _DVB_RINGBUFFER_H_ #define _DVB_RINGBUFFER_H_ +#include <linux/spinlock.h> +#include <linux/wait.h> -typedef struct dvb_ringbuffer { +struct dvb_ringbuffer { u8 *data; ssize_t size; ssize_t pread; @@ -41,7 +43,7 @@ wait_queue_head_t queue; spinlock_t lock; -} dvb_ringbuffer_t; +}; /* @@ -73,25 +75,25 @@ */ /* initialize ring buffer, lock and queue */ -extern void dvb_ringbuffer_init(dvb_ringbuffer_t *rbuf, void *data, size_t len); +extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len); /* test whether buffer is empty */ -extern int dvb_ringbuffer_empty(dvb_ringbuffer_t *rbuf); +extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf); /* return the number of free bytes in the buffer */ -extern ssize_t dvb_ringbuffer_free(dvb_ringbuffer_t *rbuf); +extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf); /* return the number of bytes waiting in the buffer */ -extern ssize_t dvb_ringbuffer_avail(dvb_ringbuffer_t *rbuf); +extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf); /* read routines & macros */ /* ---------------------- */ /* flush buffer */ -extern void dvb_ringbuffer_flush(dvb_ringbuffer_t *rbuf); +extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf); /* flush buffer protected by spinlock and wake-up waiting task(s) */ -extern void dvb_ringbuffer_flush_spinlock_wakeup(dvb_ringbuffer_t *rbuf); +extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); /* peek at byte <offs> in the buffer */ #define DVB_RINGBUFFER_PEEK(rbuf,offs) \ @@ -106,7 +108,7 @@ ** <usermem> specifies whether <buf> resides in user space ** returns number of bytes transferred or -EFAULT */ -extern ssize_t dvb_ringbuffer_read(dvb_ringbuffer_t *rbuf, u8 *buf, +extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem); @@ -121,7 +123,7 @@ ** <usermem> specifies whether <buf> resides in user space ** returns number of bytes transferred or -EFAULT */ -extern ssize_t dvb_ringbuffer_write(dvb_ringbuffer_t *rbuf, const u8 *buf, +extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len, int usermem); #endif /* _DVB_RINGBUFFER_H_ */ diff -Nru a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c --- a/drivers/media/dvb/dvb-core/dvbdev.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/dvb-core/dvbdev.c Fri Jun 27 14:19:54 2003 @@ -21,26 +21,19 @@ * */ -#include <linux/config.h> -#include <linux/version.h> -#include <linux/module.h> #include <linux/types.h> +#include <linux/errno.h> +#include <linux/string.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/errno.h> #include <linux/init.h> -#include <asm/uaccess.h> -#include <asm/system.h> -#include <linux/kmod.h> #include <linux/slab.h> +#include <linux/version.h> +#include <asm/semaphore.h> #include "dvbdev.h" - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #include "compat.h" -#endif +#include "dvb_functions.h" static int dvbdev_debug = 0; #define dprintk if (dvbdev_debug) printk @@ -58,8 +51,7 @@ #define DVB_MAX_IDS 4 #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) -static -struct dvb_device* dvbdev_find_device (int minor) +static struct dvb_device* dvbdev_find_device (int minor) { struct list_head *entry; @@ -79,8 +71,7 @@ } -static -int dvb_device_open(struct inode *inode, struct file *file) +static int dvb_device_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev; @@ -164,8 +155,7 @@ } -static -int dvbdev_get_free_id (struct dvb_adapter *adap, int type) +static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) { u32 id = 0; @@ -188,8 +178,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, const struct dvb_device *template, void *priv, int type) { - u32 id; struct dvb_device *dvbdev; + int id; if (down_interruptible (&dvbdev_register_lock)) return -ERESTARTSYS; @@ -241,8 +231,7 @@ } -static -int dvbdev_get_free_adapter_num (void) +static int dvbdev_get_free_adapter_num (void) { int num = 0; @@ -284,10 +273,6 @@ memset (adap, 0, sizeof(struct dvb_adapter)); INIT_LIST_HEAD (&adap->device_list); - /* fixme: is this correct? */ - /* No */ - try_module_get(THIS_MODULE); - printk ("DVB: registering new adapter (%s).\n", name); devfs_mk_dir("dvb/adapter%d", num); @@ -310,15 +295,11 @@ list_del (&adap->list_head); up (&dvbdev_register_lock); kfree (adap); - /* fixme: is this correct? */ - /* No. */ - module_put(THIS_MODULE); return 0; } -static -int __init init_dvbdev(void) +static int __init init_dvbdev(void) { devfs_mk_dir("dvb"); @@ -331,8 +312,7 @@ } -static -void __exit exit_dvbdev(void) +static void __exit exit_dvbdev(void) { unregister_chrdev(DVB_MAJOR, "DVB"); devfs_remove("dvb"); diff -Nru a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h --- a/drivers/media/dvb/dvb-core/dvbdev.h Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/dvb-core/dvbdev.h Fri Jun 27 14:19:54 2003 @@ -25,8 +25,8 @@ #define _DVBDEV_H_ #include <linux/types.h> -#include <linux/version.h> #include <linux/poll.h> +#include <linux/fs.h> #include <linux/devfs_fs_kernel.h> #include <linux/list.h> @@ -84,9 +84,5 @@ extern int dvb_generic_release (struct inode *inode, struct file *file); extern int dvb_generic_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)); #endif /* #ifndef _DVBDEV_H_ */ diff -Nru a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig --- a/drivers/media/dvb/frontends/Kconfig Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/frontends/Kconfig Fri Jun 27 14:19:54 2003 @@ -5,10 +5,9 @@ tristate "STV0299 based DVB-S frontend (QPSK)" depends on DVB_CORE help - A DVB-S tuner module. - - Say Y when you want to support frontend based on this - demodulator. + The stv0299 by ST is used in many DVB-S tuner modules, + say Y when you want to support frontends based on this + DVB-S demodulator. Some examples are the Alps BSRU6, the Philips SU1278 and the LG TDQB-S00x. @@ -61,6 +60,17 @@ If you don't know what tuner module is soldered on your DVB adapter simply enable all supported frontends, the + right one will get autodetected. + +config DVB_CX24110 + tristate "Frontends with Connexant CX24110 demodulator (QPSK)" + depends on DVB_CORE + help + The CX24110 Demodulator is used in some DVB-S frontends. + Say Y if you want support for this chip in your kernel. + + If you don't know what tuner module is soldered on your + DVB adapter simply enable all supported frontends, the right one will get autodetected. config DVB_GRUNDIG_29504_491 diff -Nru a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile --- a/drivers/media/dvb/frontends/Makefile Fri Jun 27 14:19:52 2003 +++ b/drivers/media/dvb/frontends/Makefile Fri Jun 27 14:19:52 2003 @@ -9,6 +9,7 @@ obj-$(CONFIG_DVB_ALPS_TDLB7) += alps_tdlb7.o obj-$(CONFIG_DVB_ALPS_TDMB7) += alps_tdmb7.o obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o +obj-$(CONFIG_DVB_CX24110) += cx24110.o obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o obj-$(CONFIG_DVB_VES1820) += ves1820.o diff -Nru a/drivers/media/dvb/frontends/alps_bsrv2.c b/drivers/media/dvb/frontends/alps_bsrv2.c --- a/drivers/media/dvb/frontends/alps_bsrv2.c Fri Jun 27 14:19:53 2003 +++ b/drivers/media/dvb/frontends/alps_bsrv2.c Fri Jun 27 14:19:53 2003 @@ -20,8 +20,11 @@ */ +#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/string.h> +#include <linux/slab.h> #include "dvb_frontend.h" @@ -29,19 +32,18 @@ #define dprintk if (debug) printk -static -struct dvb_frontend_info bsrv2_info = { - name: "Alps BSRV2", - type: FE_QPSK, - frequency_min: 950000, - frequency_max: 2150000, - frequency_stepsize: 250, /* kHz for QPSK frontends */ - frequency_tolerance: 29500, - symbol_rate_min: 1000000, - symbol_rate_max: 45000000, -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 50, /* 1/20 s */ - caps: FE_CAN_INVERSION_AUTO | +static struct dvb_frontend_info bsrv2_info = { + .name = "Alps BSRV2", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 250, /* kHz for QPSK frontends */ + .frequency_tolerance = 29500, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, +/* . symbol_rate_tolerance = ???,*/ + .notifier_delay = 50, /* 1/20 s */ + .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK @@ -49,8 +51,7 @@ -static -u8 init_1893_tab [] = { +static u8 init_1893_tab [] = { 0x01, 0xA4, 0x35, 0x81, 0x2A, 0x0d, 0x55, 0xC4, 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7F, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -61,8 +62,7 @@ }; -static -u8 init_1893_wtab[] = +static u8 init_1893_wtab[] = { 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, @@ -71,11 +71,10 @@ }; -static -int ves1893_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int ves1893_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { u8 buf [] = { 0x00, reg, data }; - struct i2c_msg msg = { addr: 0x08, flags: 0, buf: buf, len: 3 }; + struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 3 }; int err; if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { @@ -87,14 +86,13 @@ } -static -u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static u8 ves1893_readreg (struct dvb_i2c_bus *i2c, u8 reg) { int ret; u8 b0 [] = { 0x00, reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x08, flags: 0, buf: b0, len: 2 }, - { addr: 0x08, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b0, .len = 2 }, + { .addr = 0x08, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c->xfer (i2c, msg, 2); @@ -105,11 +103,10 @@ } -static -int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) +static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -125,8 +122,7 @@ * set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static -int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) +static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, u8 pwr) { u32 div = (freq + 479500) / 125; u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x95, (pwr << 5) | 0x30 }; @@ -135,8 +131,7 @@ } -static -int ves1893_init (struct dvb_i2c_bus *i2c) +static int ves1893_init (struct dvb_i2c_bus *i2c) { int i; @@ -150,8 +145,7 @@ } -static -int ves1893_clr_bit (struct dvb_i2c_bus *i2c) +static int ves1893_clr_bit (struct dvb_i2c_bus *i2c) { ves1893_writereg (i2c, 0, init_1893_tab[0] & 0xfe); ves1893_writereg (i2c, 0, init_1893_tab[0]); @@ -160,8 +154,7 @@ } -static -int ves1893_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) +static int ves1893_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) { u8 val; @@ -183,8 +176,7 @@ } -static -int ves1893_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +static int ves1893_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) { if (fec == FEC_AUTO) return ves1893_writereg (i2c, 0x0d, 0x08); @@ -195,15 +187,13 @@ } -static -fe_code_rate_t ves1893_get_fec (struct dvb_i2c_bus *i2c) +static fe_code_rate_t ves1893_get_fec (struct dvb_i2c_bus *i2c) { return FEC_1_2 + ((ves1893_readreg (i2c, 0x0d) >> 4) & 0x7); } -static -int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) +static int ves1893_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) { u32 BDR; u32 ratio; @@ -211,7 +201,7 @@ u32 BDRI; u32 tmp; - dprintk("%s: srate == %d\n", __FUNCTION__, srate); + dprintk("%s: srate == %ud\n", __FUNCTION__, (unsigned int) srate); if (srate > 90100000UL/2) srate = 90100000UL/2; @@ -257,9 +247,9 @@ BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; dprintk("FNR= %d\n", FNR); - dprintk("ratio= %08x\n", ratio); - dprintk("BDR= %08x\n", BDR); - dprintk("BDRI= %02x\n", BDRI); + dprintk("ratio= %08x\n", (unsigned int) ratio); + dprintk("BDR= %08x\n", (unsigned int) BDR); + dprintk("BDRI= %02x\n", (unsigned int) BDRI); if (BDRI > 0xff) BDRI = 0xff; @@ -286,22 +276,22 @@ } -static -int ves1893_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) +static int ves1893_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) { switch (voltage) { case SEC_VOLTAGE_13: return ves1893_writereg (i2c, 0x1f, 0x20); case SEC_VOLTAGE_18: return ves1893_writereg (i2c, 0x1f, 0x30); + case SEC_VOLTAGE_OFF: + return ves1893_writereg (i2c, 0x1f, 0x00); default: return -EINVAL; } } -static -int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int bsrv2_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { struct dvb_i2c_bus *i2c = fe->i2c; @@ -387,12 +377,12 @@ case FE_GET_FRONTEND: { struct dvb_frontend_parameters *p = arg; - s32 afc; + int afc; afc = ((int)((char)(ves1893_readreg (i2c, 0x0a) << 1)))/2; - afc = (afc * (int)(p->u.qpsk.symbol_rate/8))/16; + afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; - p->frequency += afc; + p->frequency -= afc; p->inversion = (ves1893_readreg (i2c, 0x0f) & 2) ? INVERSION_ON : INVERSION_OFF; p->u.qpsk.fec_inner = ves1893_get_fec (i2c); @@ -425,8 +415,7 @@ } -static -int bsrv2_attach (struct dvb_i2c_bus *i2c) +static int bsrv2_attach (struct dvb_i2c_bus *i2c) { if ((ves1893_readreg (i2c, 0x1e) & 0xf0) != 0xd0) return -ENODEV; @@ -437,22 +426,19 @@ } -static -void bsrv2_detach (struct dvb_i2c_bus *i2c) +static void bsrv2_detach (struct dvb_i2c_bus *i2c) { dvb_unregister_frontend (bsrv2_ioctl, i2c); } -static -int __init init_bsrv2 (void) +static int __init init_bsrv2 (void) { return dvb_register_i2c_device (THIS_MODULE, bsrv2_attach, bsrv2_detach); } -static -void __exit exit_bsrv2 (void) +static void __exit exit_bsrv2 (void) { dvb_unregister_i2c_device (bsrv2_attach); } diff -Nru a/drivers/media/dvb/frontends/alps_tdlb7.c b/drivers/media/dvb/frontends/alps_tdlb7.c --- a/drivers/media/dvb/frontends/alps_tdlb7.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/frontends/alps_tdlb7.c Fri Jun 27 14:19:54 2003 @@ -70,31 +70,29 @@ static int errno; -static -struct dvb_frontend_info tdlb7_info = { - name: "Alps TDLB7", - type: FE_OFDM, - frequency_min: 470000000, - frequency_max: 860000000, - frequency_stepsize: 166666, +static struct dvb_frontend_info tdlb7_info = { + .name = "Alps TDLB7", + .type = FE_OFDM, + .frequency_min = 470000000, + .frequency_max = 860000000, + .frequency_stepsize = 166666, #if 0 - frequency_tolerance: ???, - symbol_rate_min: ???, - symbol_rate_max: ???, - symbol_rate_tolerance: ???, - notifier_delay: 0, + .frequency_tolerance = ???, + .symbol_rate_min = ???, + .symbol_rate_max = ???, + .symbol_rate_tolerance = ???, + .notifier_delay = 0, #endif - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 }; -static -int sp8870_writereg (struct dvb_i2c_bus *i2c, u16 reg, u16 data) +static int sp8870_writereg (struct dvb_i2c_bus *i2c, u16 reg, u16 data) { u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { addr: 0x71, flags: 0, buf: buf, len: 4 }; + struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = buf, .len = 4 }; int err; if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { @@ -106,14 +104,13 @@ } -static -u16 sp8870_readreg (struct dvb_i2c_bus *i2c, u16 reg) +static u16 sp8870_readreg (struct dvb_i2c_bus *i2c, u16 reg) { int ret; u8 b0 [] = { reg >> 8 , reg & 0xff }; u8 b1 [] = { 0, 0 }; - struct i2c_msg msg [] = { { addr: 0x71, flags: 0, buf: b0, len: 2 }, - { addr: 0x71, flags: I2C_M_RD, buf: b1, len: 2 } }; + struct i2c_msg msg [] = { { .addr = 0x71, .flags = 0, .buf = b0, .len = 2 }, + { .addr = 0x71, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; ret = i2c->xfer (i2c, msg, 2); @@ -124,11 +121,10 @@ } -static -int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) +static int sp5659_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x60, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -139,8 +135,7 @@ } -static -int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +static int sp5659_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) { u32 div = (freq + 36200000) / 166666; u8 buf [4]; @@ -160,8 +155,7 @@ } -static -int sp8870_read_code(const char *fn, char **fp) +static int sp8870_read_code(const char *fn, char **fp) { int fd; loff_t l; @@ -197,8 +191,7 @@ } -static -int sp8870_load_code(struct dvb_i2c_bus *i2c) +static int sp8870_load_code(struct dvb_i2c_bus *i2c) { /* this takes a long time. is there a way to do it faster? */ char *lcode; @@ -245,8 +238,7 @@ }; -static -int sp8870_init (struct dvb_i2c_bus *i2c) +static int sp8870_init (struct dvb_i2c_bus *i2c) { dprintk ("%s\n", __FUNCTION__); @@ -285,8 +277,7 @@ } -static -int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int tdlb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { struct dvb_i2c_bus *i2c = fe->i2c; @@ -415,11 +406,10 @@ } -static -int tdlb7_attach (struct dvb_i2c_bus *i2c) +static int tdlb7_attach (struct dvb_i2c_bus *i2c) { - struct i2c_msg msg = { addr: 0x71, flags: 0, buf: NULL, len: 0 }; + struct i2c_msg msg = { .addr = 0x71, .flags = 0, .buf = NULL, .len = 0 }; dprintk ("%s\n", __FUNCTION__); @@ -440,8 +430,7 @@ } -static -void tdlb7_detach (struct dvb_i2c_bus *i2c) +static void tdlb7_detach (struct dvb_i2c_bus *i2c) { dprintk ("%s\n", __FUNCTION__); @@ -449,8 +438,7 @@ } -static -int __init init_tdlb7 (void) +static int __init init_tdlb7 (void) { dprintk ("%s\n", __FUNCTION__); @@ -458,8 +446,7 @@ } -static -void __exit exit_tdlb7 (void) +static void __exit exit_tdlb7 (void) { dprintk ("%s\n", __FUNCTION__); diff -Nru a/drivers/media/dvb/frontends/alps_tdmb7.c b/drivers/media/dvb/frontends/alps_tdmb7.c --- a/drivers/media/dvb/frontends/alps_tdmb7.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/frontends/alps_tdmb7.c Fri Jun 27 14:19:54 2003 @@ -20,47 +20,41 @@ */ +#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> #include "dvb_frontend.h" +#include "dvb_functions.h" static int debug = 0; #define dprintk if (debug) printk -static -struct dvb_frontend_info tdmb7_info = { - name: "Alps TDMB7", - type: FE_OFDM, - frequency_min: 470000000, - frequency_max: 860000000, - frequency_stepsize: 166667, +static struct dvb_frontend_info tdmb7_info = { + .name = "Alps TDMB7", + .type = FE_OFDM, + .frequency_min = 470000000, + .frequency_max = 860000000, + .frequency_stepsize = 166667, #if 0 - frequency_tolerance: ???, - symbol_rate_min: ???, - symbol_rate_max: ???, - symbol_rate_tolerance: 500, /* ppm */ - notifier_delay: 0, + .frequency_tolerance = ???, + .symbol_rate_min = ???, + .symbol_rate_max = ???, + .symbol_rate_tolerance = 500, /* ppm */ + .notifier_delay = 0, #endif - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_CLEAN_SETUP | FE_CAN_RECOVER }; -static -inline void ddelay (int timeout) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout(timeout); -} - - -static -u8 init_tab [] = { +static u8 init_tab [] = { 0x04, 0x10, 0x05, 0x09, 0x06, 0x00, @@ -82,12 +76,11 @@ }; -static -int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int cx22700_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x43, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = buf, .len = 2 }; dprintk ("%s\n", __FUNCTION__); @@ -101,14 +94,13 @@ } -static -u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static u8 cx22700_readreg (struct dvb_i2c_bus *i2c, u8 reg) { int ret; u8 b0 [] = { reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x43, flags: 0, buf: b0, len: 1 }, - { addr: 0x43, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x43, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x43, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; dprintk ("%s\n", __FUNCTION__); @@ -121,10 +113,9 @@ } -static -int pll_write (struct dvb_i2c_bus *i2c, u8 data [4]) +static int pll_write (struct dvb_i2c_bus *i2c, u8 data [4]) { - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; int ret; cx22700_writereg (i2c, 0x0a, 0x00); /* open i2c bus switch */ @@ -142,8 +133,7 @@ * set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static -int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) { u32 div = (freq + 36166667) / 166667; #if 1 //ALPS_SETTINGS @@ -154,14 +144,13 @@ freq < 470000000 ? 0x42 : freq < 862000000 ? 0x41 : 0x81 }; #endif - dprintk ("%s: freq == %i, div == %i\n", __FUNCTION__, freq, div); + dprintk ("%s: freq == %i, div == %i\n", __FUNCTION__, (int) freq, (int) div); return pll_write (i2c, buf); } -static -int cx22700_init (struct dvb_i2c_bus *i2c) +static int cx22700_init (struct dvb_i2c_bus *i2c) { int i; @@ -170,7 +159,7 @@ cx22700_writereg (i2c, 0x00, 0x02); /* soft reset */ cx22700_writereg (i2c, 0x00, 0x00); - ddelay (HZ/100); + dvb_delay (HZ/100); for (i=0; i<sizeof(init_tab); i+=2) cx22700_writereg (i2c, init_tab[i], init_tab[i+1]); @@ -181,8 +170,7 @@ } -static -int cx22700_set_inversion (struct dvb_i2c_bus *i2c, int inversion) +static int cx22700_set_inversion (struct dvb_i2c_bus *i2c, int inversion) { u8 val; @@ -203,8 +191,7 @@ } -static -int cx22700_set_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p) +static int cx22700_set_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p) { static const u8 qam_tab [4] = { 0, 1, 0, 2 }; static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 }; @@ -267,8 +254,7 @@ } -static -int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p) +static int cx22700_get_tps (struct dvb_i2c_bus *i2c, struct dvb_ofdm_parameters *p) { static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 }; static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4, @@ -315,8 +301,7 @@ } -static -int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int tdmb7_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { struct dvb_i2c_bus *i2c = fe->i2c; @@ -355,7 +340,7 @@ } case FE_READ_BER: - *((uint32_t*) arg) = cx22700_readreg (i2c, 0x0c) & 0x7f; + *((u32*) arg) = cx22700_readreg (i2c, 0x0c) & 0x7f; cx22700_writereg (i2c, 0x0c, 0x00); break; @@ -363,18 +348,18 @@ { u16 rs_ber = (cx22700_readreg (i2c, 0x0d) << 9) | (cx22700_readreg (i2c, 0x0e) << 1); - *((uint16_t*) arg) = ~rs_ber; + *((u16*) arg) = ~rs_ber; break; } case FE_READ_SNR: { u16 rs_ber = (cx22700_readreg (i2c, 0x0d) << 9) | (cx22700_readreg (i2c, 0x0e) << 1); - *((uint16_t*) arg) = ~rs_ber; + *((u16*) arg) = ~rs_ber; break; } case FE_READ_UNCORRECTED_BLOCKS: - *((uint32_t*) arg) = cx22700_readreg (i2c, 0x0f); + *((u32*) arg) = cx22700_readreg (i2c, 0x0f); cx22700_writereg (i2c, 0x0f, 0x00); break; @@ -417,10 +402,9 @@ -static -int tdmb7_attach (struct dvb_i2c_bus *i2c) +static int tdmb7_attach (struct dvb_i2c_bus *i2c) { - struct i2c_msg msg = { addr: 0x43, flags: 0, buf: NULL, len: 0 }; + struct i2c_msg msg = { .addr = 0x43, .flags = 0, .buf = NULL,. len = 0 }; dprintk ("%s\n", __FUNCTION__); @@ -433,8 +417,7 @@ } -static -void tdmb7_detach (struct dvb_i2c_bus *i2c) +static void tdmb7_detach (struct dvb_i2c_bus *i2c) { dprintk ("%s\n", __FUNCTION__); @@ -442,8 +425,7 @@ } -static -int __init init_tdmb7 (void) +static int __init init_tdmb7 (void) { dprintk ("%s\n", __FUNCTION__); @@ -451,8 +433,7 @@ } -static -void __exit exit_tdmb7 (void) +static void __exit exit_tdmb7 (void) { dprintk ("%s\n", __FUNCTION__); diff -Nru a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c --- a/drivers/media/dvb/frontends/at76c651.c Fri Jun 27 14:20:01 2003 +++ b/drivers/media/dvb/frontends/at76c651.c Fri Jun 27 14:20:01 2003 @@ -22,11 +22,11 @@ * */ -#include <linux/module.h> #include <linux/init.h> -#include <linux/delay.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/string.h> #include <linux/slab.h> -#include <linux/i2c.h> #if defined(__powerpc__) #include <asm/bitops.h> @@ -34,6 +34,7 @@ #include "dvb_frontend.h" #include "dvb_i2c.h" +#include "dvb_functions.h" static int debug = 0; @@ -67,14 +68,13 @@ FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | - FE_CAN_QAM_256, - /* FE_CAN_QAM_512 | FE_CAN_QAM_1024 | */ + FE_CAN_QAM_256 /* | FE_CAN_QAM_512 | FE_CAN_QAM_1024 */ | + FE_CAN_RECOVER | FE_CAN_CLEAN_SETUP | FE_CAN_MUTE_TS }; #if ! defined(__powerpc__) -static __inline__ int -__ilog2(unsigned long x) +static __inline__ int __ilog2(unsigned long x) { int i; @@ -88,13 +88,12 @@ } #endif -static int -at76c651_writereg(struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int at76c651_writereg(struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf[] = { reg, data }; - struct i2c_msg msg = { addr:0x1a >> 1, flags:0, buf:buf, len:2 }; + struct i2c_msg msg = { .addr = 0x1a >> 1, .flags = 0, .buf = buf, .len = 2 }; ret = i2c->xfer(i2c, &msg, 1); @@ -103,21 +102,20 @@ "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret); - mdelay(10); + dvb_delay(10); return (ret != 1) ? -EREMOTEIO : 0; } -static u8 -at76c651_readreg(struct dvb_i2c_bus *i2c, u8 reg) +static u8 at76c651_readreg(struct dvb_i2c_bus *i2c, u8 reg) { int ret; u8 b0[] = { reg }; u8 b1[] = { 0 }; - struct i2c_msg msg[] = { {addr: 0x1a >> 1, flags: 0, buf: b0, len:1}, - {addr: 0x1a >> 1, flags: I2C_M_RD, buf: b1, len:1} }; + struct i2c_msg msg[] = { {.addr = 0x1a >> 1, .flags = 0, .buf = b0, .len = 1}, + {.addr = 0x1a >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1} }; ret = i2c->xfer(i2c, msg, 2); @@ -128,8 +126,7 @@ } -static int -at76c651_set_auto_config(struct dvb_i2c_bus *i2c) +static int at76c651_set_auto_config(struct dvb_i2c_bus *i2c) { at76c651_writereg(i2c, 0x06, 0x01); @@ -148,8 +145,7 @@ } -static int -at76c651_set_bbfreq(struct dvb_i2c_bus *i2c) +static int at76c651_set_bbfreq(struct dvb_i2c_bus *i2c) { at76c651_writereg(i2c, 0x04, 0x3f); @@ -159,24 +155,21 @@ } -static int -at76c651_reset(struct dvb_i2c_bus *i2c) +static int at76c651_reset(struct dvb_i2c_bus *i2c) { return at76c651_writereg(i2c, 0x07, 0x01); } -static int -at76c651_disable_interrupts(struct dvb_i2c_bus *i2c) +static int at76c651_disable_interrupts(struct dvb_i2c_bus *i2c) { return at76c651_writereg(i2c, 0x0b, 0x00); } -static int -at76c651_switch_tuner_i2c(struct dvb_i2c_bus *i2c, u8 enable) +static int at76c651_switch_tuner_i2c(struct dvb_i2c_bus *i2c, u8 enable) { if (enable) @@ -186,13 +179,12 @@ } -static int -dat7021_write(struct dvb_i2c_bus *i2c, u32 tw) +static int dat7021_write(struct dvb_i2c_bus *i2c, u32 tw) { int ret; struct i2c_msg msg = - { addr:0xc2 >> 1, flags:0, buf:(u8 *) & tw, len:sizeof (tw) }; + { .addr = 0xc2 >> 1, .flags = 0, .buf = (u8 *) & tw, .len = sizeof (tw) }; at76c651_switch_tuner_i2c(i2c, 1); @@ -209,8 +201,7 @@ } -static int -dat7021_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq) +static int dat7021_set_tv_freq(struct dvb_i2c_bus *i2c, u32 freq) { u32 dw; @@ -238,8 +229,7 @@ } -static int -at76c651_set_symbolrate(struct dvb_i2c_bus *i2c, u32 symbolrate) +static int at76c651_set_symbolrate(struct dvb_i2c_bus *i2c, u32 symbolrate) { u8 exponent; @@ -265,8 +255,7 @@ } -static int -at76c651_set_qam(struct dvb_i2c_bus *i2c, fe_modulation_t qam) +static int at76c651_set_qam(struct dvb_i2c_bus *i2c, fe_modulation_t qam) { u8 qamsel = 0; @@ -308,8 +297,7 @@ } -static int -at76c651_set_inversion(struct dvb_i2c_bus *i2c, +static int at76c651_set_inversion(struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) { @@ -337,8 +325,7 @@ } -static int -at76c651_set_parameters(struct dvb_i2c_bus *i2c, +static int at76c651_set_parameters(struct dvb_i2c_bus *i2c, struct dvb_frontend_parameters *p) { @@ -351,8 +338,7 @@ } -static int -at76c651_set_defaults(struct dvb_i2c_bus *i2c) +static int at76c651_set_defaults(struct dvb_i2c_bus *i2c) { at76c651_set_symbolrate(i2c, 6900000); @@ -365,8 +351,7 @@ } -static int -at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int at76c651_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) { switch (cmd) { @@ -462,8 +447,7 @@ } -static int -at76c651_attach(struct dvb_i2c_bus *i2c) +static int at76c651_attach(struct dvb_i2c_bus *i2c) { if (at76c651_readreg(i2c, 0x0e) != 0x65) { @@ -502,8 +486,7 @@ } -static void -at76c651_detach(struct dvb_i2c_bus *i2c) +static void at76c651_detach(struct dvb_i2c_bus *i2c) { dvb_unregister_frontend(at76c651_ioctl, i2c); @@ -512,8 +495,7 @@ } -static int __init -at76c651_init(void) +static int __init at76c651_init(void) { return dvb_register_i2c_device(THIS_MODULE, at76c651_attach, @@ -521,8 +503,7 @@ } -static void __exit -at76c651_exit(void) +static void __exit at76c651_exit(void) { dvb_unregister_i2c_device(at76c651_attach); diff -Nru a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/media/dvb/frontends/cx24110.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,686 @@ +/* + cx24110 - Single Chip Satellite Channel Receiver driver module + used on the the Pinnacle PCTV Sat cards + + Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> based on + work + Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +/* currently drives the Conexant cx24110 and cx24106 QPSK decoder chips, + connected via i2c to a Conexant Fusion 878 (this uses the standard + linux bttv driver). The tuner chip is supposed to be the Conexant + cx24108 digital satellite tuner, driven through the tuner interface + of the cx24110. SEC is also supplied by the cx24110. + + Oct-2002: Migrate to API V3 (formerly known as NEWSTRUCT) +*/ + +#include <linux/slab.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> + +#include "dvb_frontend.h" +#include "dvb_functions.h" + +static int debug = 0; +#define dprintk if (debug) printk + + +static struct dvb_frontend_info cx24110_info = { + .name = "Conexant CX24110 with CX24108 tuner, aka HM1221/HM1811", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 1011, /* kHz for QPSK frontends, can be reduced + to 253kHz on the cx24108 tuner */ + .frequency_tolerance = 29500, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, +/* .symbol_rate_tolerance = ???,*/ + .notifier_delay = 50, /* 1/20 s */ + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | + FE_CAN_CLEAN_SETUP +}; +/* fixme: are these values correct? especially ..._tolerance and caps */ + + +static struct {u8 reg; u8 data;} cx24110_regdata[]= + /* Comments beginning with @ denote this value should + be the default */ + {{0x09,0x01}, /* SoftResetAll */ + {0x09,0x00}, /* release reset */ + {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ + {0x02,0x17}, /* middle byte " */ + {0x03,0x29}, /* LSB " */ + {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */ + {0x06,0xa5}, /* @ PLL 60MHz */ + {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ + {0x0a,0x00}, /* @ partial chip disables, do not set */ + {0x0b,0x01}, /* set output clock in gapped mode, start signal low + active for first byte */ + {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ + {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ + {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 + to avoid starting the BER counter. Reset the + CRC test bit. Finite counting selected */ + {0x15,0xff}, /* @ size of the limited time window for RS BER + estimation. It is <value>*256 RS blocks, this + gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ + {0x16,0x00}, /* @ enable all RS output ports */ + {0x17,0x04}, /* @ time window allowed for the RS to sync */ + {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned + for automatically */ + /* leave the current code rate and normalization + registers as they are after reset... */ + {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting + only once */ + {0x23,0x18}, /* @ size of the limited time window for Viterbi BER + estimation. It is <value>*65536 channel bits, i.e. + approx. 38ms at 27.5MS/s, rate 3/4 */ + {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ + /* leave front-end AGC parameters at default values */ + /* leave decimation AGC parameters at default values */ + {0x35,0x40}, /* disable all interrupts. They are not connected anyway */ + {0x36,0xff}, /* clear all interrupt pending flags */ + {0x37,0x00}, /* @ fully enable AutoAcqq state machine */ + {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */ + /* leave the equalizer parameters on their default values */ + /* leave the final AGC parameters on their default values */ + {0x41,0x00}, /* @ MSB of front-end derotator frequency */ + {0x42,0x00}, /* @ middle bytes " */ + {0x43,0x00}, /* @ LSB " */ + /* leave the carrier tracking loop parameters on default */ + /* leave the bit timing loop parameters at gefault */ + {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */ + /* the cx24108 data sheet for symbol rates above 15MS/s */ + {0x57,0x00}, /* @ Filter sigma delta enabled, positive */ + {0x61,0x95}, /* GPIO pins 1-4 have special function */ + {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */ + {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */ + {0x64,0x20}, /* GPIO 6 is input, all others are outputs */ + {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */ + {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */ + {0x73,0x00}, /* @ disable several demod bypasses */ + {0x74,0x00}, /* @ " */ + {0x75,0x00} /* @ " */ + /* the remaining registers are for SEC */ + }; + + +static int cx24110_writereg (struct dvb_i2c_bus *i2c, int reg, int data) +{ + u8 buf [] = { reg, data }; + struct i2c_msg msg = { .addr = 0x55, .flags = 0, .buf = buf, .len = 2 }; +/* fixme (medium): HW allows any i2c address. 0x55 is the default, but the + cx24110 might show up at any address */ + int err; + + if ((err = i2c->xfer (i2c, &msg, 1)) != 1) { + dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data); + return -EREMOTEIO; + } + + return 0; +} + + +static u8 cx24110_readreg (struct dvb_i2c_bus *i2c, u8 reg) +{ + int ret; + u8 b0 [] = { reg }; + u8 b1 [] = { 0 }; + struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; +/* fixme (medium): address might be different from 0x55 */ + ret = i2c->xfer (i2c, msg, 2); + + if (ret != 2) + dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); + + return b1[0]; +} + + +static int cx24108_write (struct dvb_i2c_bus *i2c, u32 data) +{ +/* tuner data is 21 bits long, must be left-aligned in data */ +/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ +/* FIXME (low): add error handling, avoid infinite loops if HW fails... */ + +dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data); + + cx24110_writereg(i2c,0x6d,0x30); /* auto mode at 62kHz */ + cx24110_writereg(i2c,0x70,0x15); /* auto mode 21 bits */ + /* if the auto tuner writer is still busy, clear it out */ + while (cx24110_readreg(i2c,0x6d)&0x80) + cx24110_writereg(i2c,0x72,0); + /* write the topmost 8 bits */ + cx24110_writereg(i2c,0x72,(data>>24)&0xff); + /* wait for the send to be completed */ + while ((cx24110_readreg(i2c,0x6d)&0xc0)==0x80) + ; + /* send another 8 bytes */ + cx24110_writereg(i2c,0x72,(data>>16)&0xff); + while ((cx24110_readreg(i2c,0x6d)&0xc0)==0x80) + ; + /* and the topmost 5 bits of this byte */ + cx24110_writereg(i2c,0x72,(data>>8)&0xff); + while ((cx24110_readreg(i2c,0x6d)&0xc0)==0x80) + ; + /* now strobe the enable line once */ + cx24110_writereg(i2c,0x6d,0x32); + cx24110_writereg(i2c,0x6d,0x30); + + return 0; +} + + +static int cx24108_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +{ +/* fixme (low): error handling */ + int i, a, n, pump; + u32 band, pll; + + + static const u32 osci[]={ 950000,1019000,1075000,1178000, + 1296000,1432000,1576000,1718000, + 1856000,2036000,2150000}; + static const u32 bandsel[]={0,0x00020000,0x00040000,0x00100800, + 0x00101000,0x00102000,0x00104000, + 0x00108000,0x00110000,0x00120000, + 0x00140000}; + +#define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ + dprintk("cx24110 debug: cx24108_set_tv_freq, freq=%d\n",freq); + + if (freq<950000) + freq=950000; /* kHz */ + if (freq>2150000) + freq=2150000; /* satellite IF is 950..2150MHz */ + /* decide which VCO to use for the input frequency */ + for (i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++) + ; + dprintk("cx24110 debug: select vco #%d (f=%d)\n",i,freq); + band=bandsel[i]; + /* the gain values must be set by SetSymbolrate */ + /* compute the pll divider needed, from Conexant data sheet, + resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, + depending on the divider bit. It is set to /4 on the 2 lowest + bands */ + n=((i<=2?2:1)*freq*10L)/(XTAL/100); + a=n%32; n/=32; + if (a==0) + n--; + pump=(freq<(osci[i-1]+osci[i])/2); + pll=0xf8000000| + ((pump?1:2)<<(14+11))| + ((n&0x1ff)<<(5+11))| + ((a&0x1f)<<11); + /* everything is shifted left 11 bits to left-align the bits in the + 32bit word. Output to the tuner goes MSB-aligned, after all */ + dprintk("cx24110 debug: pump=%d, n=%d, a=%d\n",pump,n,a); + cx24108_write(i2c,band); + /* set vga and vca to their widest-band settings, as a precaution. + SetSymbolrate might not be called to set this up */ + cx24108_write(i2c,0x500c0000); + cx24108_write(i2c,0x83f1f800); + cx24108_write(i2c,pll); + cx24110_writereg(i2c,0x56,0x7f); + + dvb_delay(HZ/10); /* wait a moment for the tuner pll to lock */ + + /* tuner pll lock can be monitored on GPIO pin 4 of cx24110 */ + while (!(cx24110_readreg(i2c,0x66)&0x20)&&i<1000) + i++; + dprintk("cx24110 debug: GPIO IN=%2.2x(loop=%d)\n", + cx24110_readreg(i2c,0x66),i); + return 0; + +} + + +static int cx24110_init (struct dvb_i2c_bus *i2c) +{ +/* fixme (low): error handling */ + int i; + + dprintk("%s: init chip\n", __FUNCTION__); + + for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) { + cx24110_writereg(i2c,cx24110_regdata[i].reg,cx24110_regdata[i].data); + }; + + return 0; +} + + +static int cx24110_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) +{ +/* fixme (low): error handling */ + + switch (inversion) { + case INVERSION_OFF: + cx24110_writereg(i2c,0x37,cx24110_readreg(i2c,0x37)|0x1); + /* AcqSpectrInvDis on. No idea why someone should want this */ + cx24110_writereg(i2c,0x5,cx24110_readreg(i2c,0x5)&0xf7); + /* Initial value 0 at start of acq */ + cx24110_writereg(i2c,0x22,cx24110_readreg(i2c,0x22)&0xef); + /* current value 0 */ + /* The cx24110 manual tells us this reg is read-only. + But what the heck... set it ayways */ + break; + case INVERSION_ON: + cx24110_writereg(i2c,0x37,cx24110_readreg(i2c,0x37)|0x1); + /* AcqSpectrInvDis on. No idea why someone should want this */ + cx24110_writereg(i2c,0x5,cx24110_readreg(i2c,0x5)|0x08); + /* Initial value 1 at start of acq */ + cx24110_writereg(i2c,0x22,cx24110_readreg(i2c,0x22)|0x10); + /* current value 1 */ + break; + case INVERSION_AUTO: + cx24110_writereg(i2c,0x37,cx24110_readreg(i2c,0x37)&0xfe); + /* AcqSpectrInvDis off. Leave initial & current states as is */ + break; + default: + return -EINVAL; + } + + return 0; +} + + +static int cx24110_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +{ +/* fixme (low): error handling */ + + static const int rate[]={-1,1,2,3,5,7,-1}; + static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1}; + static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1}; + + /* Well, the AutoAcq engine of the cx24106 and 24110 automatically + searches all enabled viterbi rates, and can handle non-standard + rates as well. */ + + if (fec>FEC_AUTO) + fec=FEC_AUTO; + + if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */ + cx24110_writereg(i2c,0x37,cx24110_readreg(i2c,0x37)&0xdf); + /* clear AcqVitDis bit */ + cx24110_writereg(i2c,0x18,0xae); + /* allow all DVB standard code rates */ + cx24110_writereg(i2c,0x05,(cx24110_readreg(i2c,0x05)&0xf0)|0x3); + /* set nominal Viterbi rate 3/4 */ + cx24110_writereg(i2c,0x22,(cx24110_readreg(i2c,0x22)&0xf0)|0x3); + /* set current Viterbi rate 3/4 */ + cx24110_writereg(i2c,0x1a,0x05); cx24110_writereg(i2c,0x1b,0x06); + /* set the puncture registers for code rate 3/4 */ + return 0; + } else { + cx24110_writereg(i2c,0x37,cx24110_readreg(i2c,0x37)|0x20); + /* set AcqVitDis bit */ + if(rate[fec]>0) { + cx24110_writereg(i2c,0x05,(cx24110_readreg(i2c,0x05)&0xf0)|rate[fec]); + /* set nominal Viterbi rate */ + cx24110_writereg(i2c,0x22,(cx24110_readreg(i2c,0x22)&0xf0)|rate[fec]); + /* set current Viterbi rate */ + cx24110_writereg(i2c,0x1a,g1[fec]); + cx24110_writereg(i2c,0x1b,g2[fec]); + /* not sure if this is the right way: I always used AutoAcq mode */ + } else + return -EOPNOTSUPP; +/* fixme (low): which is the correct return code? */ + }; + return 0; +} + + +static fe_code_rate_t cx24110_get_fec (struct dvb_i2c_bus *i2c) +{ + int i; + + i=cx24110_readreg(i2c,0x22)&0x0f; + if(!(i&0x08)) { + return FEC_1_2 + i - 1; + } else { +/* fixme (low): a special code rate has been selected. In theory, we need to + return a denominator value, a numerator value, and a pair of puncture + maps to correctly describe this mode. But this should never happen in + practice, because it cannot be set by cx24110_get_fec. */ + return FEC_NONE; + } +} + + +static int cx24110_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) +{ +/* fixme (low): add error handling */ + u32 ratio; + u32 tmp, fclk, BDRI; + + static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; + static const u32 vca[]={0x80f03800,0x81f0f800,0x83f1f800}; + static const u32 vga[]={0x5f8fc000,0x580f0000,0x500c0000}; + static const u8 filtune[]={0xa2,0xcc,0x66}; + int i; + +dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); + if (srate>90999000UL/2) + srate=90999000UL/2; + if (srate<500000) + srate=500000; + + for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++) + ; + /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, + and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, + R06[3:0] PLLphaseDetGain */ + tmp=cx24110_readreg(i2c,0x07)&0xfc; + if(srate<90999000UL/4) { /* sample rate 45MHz*/ + cx24110_writereg(i2c,0x07,tmp); + cx24110_writereg(i2c,0x06,0x78); + fclk=90999000UL/2; + } else if(srate<60666000UL/2) { /* sample rate 60MHz */ + cx24110_writereg(i2c,0x07,tmp|0x1); + cx24110_writereg(i2c,0x06,0xa5); + fclk=60666000UL; + } else if(srate<80888000UL/2) { /* sample rate 80MHz */ + cx24110_writereg(i2c,0x07,tmp|0x2); + cx24110_writereg(i2c,0x06,0x87); + fclk=80888000UL; + } else { /* sample rate 90MHz */ + cx24110_writereg(i2c,0x07,tmp|0x3); + cx24110_writereg(i2c,0x06,0x78); + fclk=90999000UL; + }; + dprintk("cx24110 debug: fclk %d Hz\n",fclk); + /* we need to divide two integers with approx. 27 bits in 32 bit + arithmetic giving a 25 bit result */ + /* the maximum dividend is 90999000/2, 0x02b6446c, this number is + also the most complex divisor. Hence, the dividend has, + assuming 32bit unsigned arithmetic, 6 clear bits on top, the + divisor 2 unused bits at the bottom. Also, the quotient is + always less than 1/2. Borrowed from VES1893.c, of course */ + + tmp=srate<<6; + BDRI=fclk>>2; + ratio=(tmp/BDRI); + + tmp=(tmp%BDRI)<<8; + ratio=(ratio<<8)+(tmp/BDRI); + + tmp=(tmp%BDRI)<<8; + ratio=(ratio<<8)+(tmp/BDRI); + + tmp=(tmp%BDRI)<<1; + ratio=(ratio<<1)+(tmp/BDRI); + + dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]); + dprintk("fclk = %d\n", fclk); + dprintk("ratio= %08x\n", ratio); + + cx24110_writereg(i2c, 0x1, (ratio>>16)&0xff); + cx24110_writereg(i2c, 0x2, (ratio>>8)&0xff); + cx24110_writereg(i2c, 0x3, (ratio)&0xff); + + /* please see the cx24108 data sheet, this controls tuner gain + and bandwidth settings depending on the symbol rate */ + cx24108_write(i2c,vga[i]); + cx24108_write(i2c,vca[i]); /* gain is set on tuner chip */ + cx24110_writereg(i2c,0x56,filtune[i]); /* bw is contolled by filtune voltage */ + + return 0; + +} + + +static int cx24110_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) +{ + switch (voltage) { + case SEC_VOLTAGE_13: + return cx24110_writereg(i2c,0x76,(cx24110_readreg(i2c,0x76)&0x3b)|0xc0); + case SEC_VOLTAGE_18: + return cx24110_writereg(i2c,0x76,(cx24110_readreg(i2c,0x76)&0x3b)|0x40); + default: + return -EINVAL; + }; +} + +static void sendDiSEqCMessage(struct dvb_i2c_bus *i2c, struct dvb_diseqc_master_cmd *pCmd) +{ + int i, rv; + + for (i = 0; i < pCmd->msg_len; i++) + cx24110_writereg(i2c, 0x79 + i, pCmd->msg[i]); + + rv = cx24110_readreg(i2c, 0x76); + + cx24110_writereg(i2c, 0x76, ((rv & 0x90) | 0x40) | ((pCmd->msg_len-3) & 3)); + for (i=500; i-- > 0 && !(cx24110_readreg(i2c,0x76)&0x40);) + ; /* wait for LNB ready */ +} + + +static int cx24110_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +{ + struct dvb_i2c_bus *i2c = fe->i2c; + static int lastber=0, lastbyer=0,lastbler=0, lastesn0=0, sum_bler=0; + + switch (cmd) { + case FE_GET_INFO: + memcpy (arg, &cx24110_info, sizeof(struct dvb_frontend_info)); + break; + + case FE_READ_STATUS: + { + fe_status_t *status = arg; + int sync = cx24110_readreg (i2c, 0x55); + + *status = 0; + + if (sync & 0x10) + *status |= FE_HAS_SIGNAL; + + if (sync & 0x08) + *status |= FE_HAS_CARRIER; + + sync = cx24110_readreg (i2c, 0x08); + + if (sync & 0x40) + *status |= FE_HAS_VITERBI; + + if (sync & 0x20) + *status |= FE_HAS_SYNC; + + if ((sync & 0x60) == 0x60) + *status |= FE_HAS_LOCK; + + if(cx24110_readreg(i2c,0x10)&0x40) { + /* the RS error counter has finished one counting window */ + cx24110_writereg(i2c,0x10,0x60); /* select the byer reg */ + lastbyer=cx24110_readreg(i2c,0x12)| + (cx24110_readreg(i2c,0x13)<<8)| + (cx24110_readreg(i2c,0x14)<<16); + cx24110_writereg(i2c,0x10,0x70); /* select the bler reg */ + lastbler=cx24110_readreg(i2c,0x12)| + (cx24110_readreg(i2c,0x13)<<8)| + (cx24110_readreg(i2c,0x14)<<16); + cx24110_writereg(i2c,0x10,0x20); /* start new count window */ + sum_bler += lastbler; + } + if(cx24110_readreg(i2c,0x24)&0x10) { + /* the Viterbi error counter has finished one counting window */ + cx24110_writereg(i2c,0x24,0x04); /* select the ber reg */ + lastber=cx24110_readreg(i2c,0x25)| + (cx24110_readreg(i2c,0x26)<<8); + cx24110_writereg(i2c,0x24,0x04); /* start new count window */ + cx24110_writereg(i2c,0x24,0x14); + } + if(cx24110_readreg(i2c,0x6a)&0x80) { + /* the Es/N0 error counter has finished one counting window */ + lastesn0=cx24110_readreg(i2c,0x69)| + (cx24110_readreg(i2c,0x68)<<8); + cx24110_writereg(i2c,0x6a,0x84); /* start new count window */ + } + break; + } + + case FE_READ_BER: + { + u32 *ber = (u32 *) arg; + + *ber = lastber; +/* fixme (maybe): value range is 16 bit. Scale? */ + break; + } + + case FE_READ_SIGNAL_STRENGTH: + { +/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */ + u8 signal = cx24110_readreg (i2c, 0x27)+128; + *((u16*) arg) = (signal << 8) | signal; + break; + } + + case FE_READ_SNR: + { +/* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */ + *(u16*) arg = lastesn0; + break; + } + + case FE_READ_UNCORRECTED_BLOCKS: + { + *(u16*) arg = sum_bler&0xffff; + sum_bler=0; + break; + } + + case FE_SET_FRONTEND: + { + struct dvb_frontend_parameters *p = arg; + + cx24108_set_tv_freq (i2c, p->frequency); + cx24110_set_inversion (i2c, p->inversion); + cx24110_set_fec (i2c, p->u.qpsk.fec_inner); + cx24110_set_symbolrate (i2c, p->u.qpsk.symbol_rate); + cx24110_writereg(i2c,0x04,0x05); /* start aquisition */ + break; + } + + case FE_GET_FRONTEND: + { + struct dvb_frontend_parameters *p = arg; + s32 afc; unsigned sclk; + +/* cannot read back tuner settings (freq). Need to have some private storage */ + + sclk = cx24110_readreg (i2c, 0x07) & 0x03; +/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz. + * Need 64 bit arithmetic. Is thiss possible in the kernel? */ + if (sclk==0) sclk=90999000L/2L; + else if (sclk==1) sclk=60666000L; + else if (sclk==2) sclk=80888000L; + else sclk=90999000L; + sclk>>=8; + afc = sclk*(cx24110_readreg (i2c, 0x44)&0x1f)+ + ((sclk*cx24110_readreg (i2c, 0x45))>>8)+ + ((sclk*cx24110_readreg (i2c, 0x46))>>16); + + p->frequency += afc; + p->inversion = (cx24110_readreg (i2c, 0x22) & 0x10) ? + INVERSION_ON : INVERSION_OFF; + p->u.qpsk.fec_inner = cx24110_get_fec (i2c); + break; + } + + case FE_SLEEP: +/* cannot do this from the FE end. How to communicate this to the place where it can be done? */ + break; + case FE_INIT: + return cx24110_init (i2c); + + case FE_RESET: +/* no idea what to do for this call */ +/* fixme (medium): fill me in */ + break; + + case FE_SET_TONE: + return cx24110_writereg(i2c,0x76,(cx24110_readreg(i2c,0x76)&~0x10)|((((fe_sec_tone_mode_t) arg)==SEC_TONE_ON)?0x10:0)); + case FE_SET_VOLTAGE: + return cx24110_set_voltage (i2c, (fe_sec_voltage_t) arg); + + case FE_DISEQC_SEND_MASTER_CMD: + sendDiSEqCMessage(i2c, (struct dvb_diseqc_master_cmd*) arg); + return 0; + + default: + return -EOPNOTSUPP; + }; + + return 0; +} + + +static int cx24110_attach (struct dvb_i2c_bus *i2c) +{ + u8 sig; + + sig=cx24110_readreg (i2c, 0x00); + if ( sig != 0x5a && sig != 0x69 ) + return -ENODEV; + + dvb_register_frontend (cx24110_ioctl, i2c, NULL, &cx24110_info); + + return 0; +} + + +static void cx24110_detach (struct dvb_i2c_bus *i2c) +{ + dvb_unregister_frontend (cx24110_ioctl, i2c); +} + + +static int __init init_cx24110 (void) +{ + return dvb_register_i2c_device (THIS_MODULE, cx24110_attach, cx24110_detach); +} + + +static void __exit exit_cx24110 (void) +{ + dvb_unregister_i2c_device (cx24110_attach); +} + + +module_init(init_cx24110); +module_exit(exit_cx24110); + + +MODULE_DESCRIPTION("DVB Frontend driver module for the Conexant cx24108/cx24110 chipset"); +MODULE_AUTHOR("Peter Hettkamp"); +MODULE_LICENSE("GPL"); +MODULE_PARM(debug,"i"); + diff -Nru a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c Fri Jun 27 14:19:54 2003 @@ -30,26 +30,24 @@ /* depending on module parameter sct deliver different infos */ -static -struct dvb_frontend_info dvb_s_dummyfe_info = { - name: "DVB-S dummy frontend", - type: FE_QPSK, - frequency_min: 950000, - frequency_max: 2150000, - frequency_stepsize: 250, /* kHz for QPSK frontends */ - frequency_tolerance: 29500, - symbol_rate_min: 1000000, - symbol_rate_max: 45000000, -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 50, /* 1/20 s */ - caps: FE_CAN_INVERSION_AUTO | +static struct dvb_frontend_info dvb_s_dummyfe_info = { + .name = "DVB-S dummy frontend", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 250, /* kHz for QPSK frontends */ + .frequency_tolerance = 29500, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, +/* .symbol_rate_tolerance = ???,*/ + .notifier_delay = 50, /* 1/20 s */ + .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK }; -static -struct dvb_frontend_info dvb_c_dummyfe_info = { +static struct dvb_frontend_info dvb_c_dummyfe_info = { .name = "DVB-C dummy frontend", .type = FE_QAM, .frequency_stepsize = 62500, @@ -58,9 +56,9 @@ .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */ .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */ #if 0 - frequency_tolerance: ???, - symbol_rate_tolerance: ???, /* ppm */ /* == 8% (spec p. 5) */ - notifier_delay: ?, + .frequency_tolerance = ???, + .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ + .notifier_delay = ?, #endif .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | @@ -103,8 +101,7 @@ } -static -int dvbdummyfe_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int dvbdummyfe_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { switch (cmd) { case FE_GET_INFO: @@ -176,23 +173,20 @@ } -static -int dvbdummyfe_attach (struct dvb_i2c_bus *i2c) +static int dvbdummyfe_attach (struct dvb_i2c_bus *i2c) { dvb_register_frontend (dvbdummyfe_ioctl, i2c, NULL, frontend_info()); return 0; } -static -void dvbdummyfe_detach (struct dvb_i2c_bus *i2c) +static void dvbdummyfe_detach (struct dvb_i2c_bus *i2c) { dvb_unregister_frontend (dvbdummyfe_ioctl, i2c); } -static -int __init init_dvbdummyfe (void) +static int __init init_dvbdummyfe (void) { return dvb_register_i2c_device (THIS_MODULE, dvbdummyfe_attach, @@ -201,8 +195,7 @@ } -static -void __exit exit_dvbdummyfe (void) +static void __exit exit_dvbdummyfe (void) { dvb_unregister_i2c_device (dvbdummyfe_attach); return; diff -Nru a/drivers/media/dvb/frontends/grundig_29504-401.c b/drivers/media/dvb/frontends/grundig_29504-401.c --- a/drivers/media/dvb/frontends/grundig_29504-401.c Fri Jun 27 14:19:53 2003 +++ b/drivers/media/dvb/frontends/grundig_29504-401.c Fri Jun 27 14:19:53 2003 @@ -22,10 +22,14 @@ */ -#include <linux/module.h> #include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> #include "dvb_frontend.h" +#include "dvb_functions.h" static int debug = 0; @@ -33,27 +37,26 @@ struct dvb_frontend_info grundig_29504_401_info = { - name: "Grundig 29504-401", - type: FE_OFDM, -/* frequency_min: ???,*/ -/* frequency_max: ???,*/ - frequency_stepsize: 166666, -/* frequency_tolerance: ???,*/ -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 0, - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + .name = "Grundig 29504-401", + .type = FE_OFDM, +/* .frequency_min = ???,*/ +/* .frequency_max = ???,*/ + .frequency_stepsize = 166666, +/* .frequency_tolerance = ???,*/ +/* .symbol_rate_tolerance = ???,*/ + .notifier_delay = 0, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_MUTE_TS /*| FE_CAN_CLEAN_SETUP*/ }; -static -int l64781_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int l64781_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x55, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x55, .flags = 0, .buf = buf, .len = 2 }; if ((ret = i2c->xfer (i2c, &msg, 1)) != 1) dprintk ("%s: write_reg error (reg == %02x) = %02x!\n", @@ -63,14 +66,13 @@ } -static -u8 l64781_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static u8 l64781_readreg (struct dvb_i2c_bus *i2c, u8 reg) { int ret; u8 b0 [] = { reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x55, flags: 0, buf: b0, len: 1 }, - { addr: 0x55, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c->xfer (i2c, msg, 2); @@ -81,11 +83,10 @@ } -static -int tsa5060_write (struct dvb_i2c_bus *i2c, u8 data [4]) +static int tsa5060_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; if ((ret = i2c->xfer (i2c, &msg, 1)) != 1) dprintk ("%s: write_reg error == %02x!\n", __FUNCTION__, ret); @@ -97,29 +98,32 @@ /** * set up the downconverter frequency divisor for a * reference clock comparision frequency of 166666 Hz. - * frequency offset is 36000000 Hz. + * frequency offset is 36125000 Hz. */ -static -int tsa5060_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +static int tsa5060_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) { u32 div; u8 buf [4]; - u8 cfg; + u8 cfg, cpump, band_select; - div = (36000000 + freq) / 166666; + div = (36125000 + freq) / 166666; cfg = 0x88; + cpump = div < 175000000 ? 2 : div < 390000000 ? 1 : + div < 470000000 ? 2 : div < 750000000 ? 1 : 3; + + band_select = div < 175000000 ? 0x0e : div < 470000000 ? 0x05 : 0x03; + buf [0] = (div >> 8) & 0x7f; buf [1] = div & 0xff; buf [2] = ((div >> 10) & 0x60) | cfg; - buf [3] = 0xc0; + buf [3] = cpump | band_select; return tsa5060_write (i2c, buf); } -static -void apply_tps (struct dvb_i2c_bus *i2c) +static void apply_tps (struct dvb_i2c_bus *i2c) { l64781_writereg (i2c, 0x2a, 0x00); l64781_writereg (i2c, 0x2a, 0x01); @@ -133,8 +137,7 @@ } -static -void reset_afc (struct dvb_i2c_bus *i2c) +static void reset_afc (struct dvb_i2c_bus *i2c) { /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for timing offset */ @@ -152,8 +155,7 @@ } -static -int apply_frontend_param (struct dvb_i2c_bus *i2c, +static int apply_frontend_param (struct dvb_i2c_bus *i2c, struct dvb_frontend_parameters *param) { /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */ @@ -265,19 +267,17 @@ } -static -void reset_and_configure (struct dvb_i2c_bus *i2c) +static void reset_and_configure (struct dvb_i2c_bus *i2c) { u8 buf [] = { 0x06 }; - struct i2c_msg msg = { addr: 0x00, flags: 0, buf: buf, len: 1 }; + struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 }; i2c->xfer (i2c, &msg, 1); } -static -int init (struct dvb_i2c_bus *i2c) +static int init (struct dvb_i2c_bus *i2c) { reset_and_configure (i2c); @@ -415,13 +415,12 @@ } -static -int l64781_attach (struct dvb_i2c_bus *i2c) +static int l64781_attach (struct dvb_i2c_bus *i2c) { u8 b0 [] = { 0x1a }; u8 b1 [] = { 0x00 }; - struct i2c_msg msg [] = { { addr: 0x55, flags: 0, buf: b0, len: 1 }, - { addr: 0x55, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x55, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x55, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; if (i2c->xfer (i2c, msg, 2) == 2) /* probably an EEPROM... */ return -ENODEV; @@ -440,23 +439,20 @@ } -static -void l64781_detach (struct dvb_i2c_bus *i2c) +static void l64781_detach (struct dvb_i2c_bus *i2c) { dvb_unregister_frontend (grundig_29504_401_ioctl, i2c); } -static -int __init init_grundig_29504_401 (void) +static int __init init_grundig_29504_401 (void) { return dvb_register_i2c_device (THIS_MODULE, l64781_attach, l64781_detach); } -static -void __exit exit_grundig_29504_401 (void) +static void __exit exit_grundig_29504_401 (void) { dvb_unregister_i2c_device (l64781_attach); } diff -Nru a/drivers/media/dvb/frontends/grundig_29504-491.c b/drivers/media/dvb/frontends/grundig_29504-491.c --- a/drivers/media/dvb/frontends/grundig_29504-491.c Fri Jun 27 14:20:00 2003 +++ b/drivers/media/dvb/frontends/grundig_29504-491.c Fri Jun 27 14:20:00 2003 @@ -25,27 +25,30 @@ */ #include <linux/init.h> +#include <linux/kernel.h> #include <linux/module.h> +#include <linux/string.h> +#include <linux/slab.h> #include "dvb_frontend.h" +#include "dvb_functions.h" static int debug = 0; #define dprintk if (debug) printk -static -struct dvb_frontend_info grundig_29504_491_info = { - name: "Grundig 29504-491, (TDA8083 based)", - type: FE_QPSK, - frequency_min: 950000, /* FIXME: guessed! */ - frequency_max: 1400000, /* FIXME: guessed! */ - frequency_stepsize: 125, /* kHz for QPSK frontends */ -/* frequency_tolerance: ???,*/ - symbol_rate_min: 1000000, /* FIXME: guessed! */ - symbol_rate_max: 45000000, /* FIXME: guessed! */ -/* symbol_rate_tolerance: ???,*/ - notifier_delay: 0, - caps: FE_CAN_INVERSION_AUTO | +static struct dvb_frontend_info grundig_29504_491_info = { + .name = "Grundig 29504-491, (TDA8083 based)", + .type = FE_QPSK, + .frequency_min = 950000, /* FIXME: guessed! */ + .frequency_max = 1400000, /* FIXME: guessed! */ + .frequency_stepsize = 125, /* kHz for QPSK frontends */ +/* .frequency_tolerance = ???,*/ + .symbol_rate_min = 1000000, /* FIXME: guessed! */ + .symbol_rate_max = 45000000, /* FIXME: guessed! */ +/* .symbol_rate_tolerance = ???,*/ + .notifier_delay = 0, + .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | @@ -55,8 +58,7 @@ -static -u8 tda8083_init_tab [] = { +static u8 tda8083_init_tab [] = { 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea, 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10, 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8, @@ -67,12 +69,11 @@ -static -int tda8083_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int tda8083_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 }; + struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 }; ret = i2c->xfer (i2c, &msg, 1); @@ -84,12 +85,11 @@ } -static -int tda8083_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) +static int tda8083_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) { int ret; - struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: ®1, len: 1 }, - { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } }; + struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = ®1, .len = 1 }, + { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } }; ret = i2c->xfer (i2c, msg, 2); @@ -101,8 +101,7 @@ } -static inline -u8 tda8083_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static inline u8 tda8083_readreg (struct dvb_i2c_bus *i2c, u8 reg) { u8 val; @@ -112,11 +111,10 @@ } -static -int tsa5522_write (struct dvb_i2c_bus *i2c, u8 data [4]) +static int tsa5522_write (struct dvb_i2c_bus *i2c, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: 0x61, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -131,8 +129,7 @@ * set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static -int tsa5522_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) +static int tsa5522_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq) { u32 div = freq / 125; u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x8e, 0x00 }; @@ -141,8 +138,7 @@ } -static int -tda8083_init (struct dvb_i2c_bus *i2c) +static int tda8083_init (struct dvb_i2c_bus *i2c) { int i; @@ -155,8 +151,7 @@ } -static int -tda8083_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) +static int tda8083_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion) { /* XXX FIXME: implement other modes than FEC_AUTO */ if (inversion == INVERSION_AUTO) @@ -166,8 +161,7 @@ } -static int -tda8083_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +static int tda8083_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) { if (fec == FEC_AUTO) return tda8083_writereg (i2c, 0x07, 0xff); @@ -179,8 +173,7 @@ } -static -fe_code_rate_t tda8083_get_fec (struct dvb_i2c_bus *i2c) +static fe_code_rate_t tda8083_get_fec (struct dvb_i2c_bus *i2c) { u8 index; static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, @@ -195,8 +188,7 @@ } -static -int tda8083_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) +static int tda8083_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) { u32 ratio; u32 tmp; @@ -222,7 +214,7 @@ tmp = (tmp % srate) << 8; ratio = (ratio << 8) + tmp / srate; - dprintk("tda8083: ratio == %08x\n", ratio); + dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio); tda8083_writereg (i2c, 0x05, filter); tda8083_writereg (i2c, 0x02, (ratio >> 16) & 0xff); @@ -236,22 +228,19 @@ } -static -void tda8083_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout) +static void tda8083_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout) { unsigned long start = jiffies; while (jiffies - start < timeout && !(tda8083_readreg(i2c, 0x02) & 0x80)) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (5); + dvb_delay(50); }; } -static -int tda8083_send_diseqc_msg (struct dvb_i2c_bus *i2c, +static int tda8083_send_diseqc_msg (struct dvb_i2c_bus *i2c, struct dvb_diseqc_master_cmd *m) { int i; @@ -269,8 +258,7 @@ } -static -int tda8083_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst) +static int tda8083_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst) { switch (burst) { case SEC_MINI_A: @@ -289,8 +277,7 @@ } -static -int tda8083_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone) +static int tda8083_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone) { tda8083_writereg (i2c, 0x26, 0xf1); @@ -305,8 +292,7 @@ } -static -int tda8083_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) +static int tda8083_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) { switch (voltage) { case SEC_VOLTAGE_13: @@ -319,8 +305,7 @@ } -static -int grundig_29504_491_ioctl (struct dvb_frontend *fe, unsigned int cmd, +static int grundig_29504_491_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { struct dvb_i2c_bus *i2c = fe->i2c; @@ -451,8 +436,7 @@ } -static -int tda8083_attach (struct dvb_i2c_bus *i2c) +static int tda8083_attach (struct dvb_i2c_bus *i2c) { if ((tda8083_readreg (i2c, 0x00)) != 0x05) return -ENODEV; @@ -464,23 +448,20 @@ } -static -void tda8083_detach (struct dvb_i2c_bus *i2c) +static void tda8083_detach (struct dvb_i2c_bus *i2c) { dvb_unregister_frontend (grundig_29504_491_ioctl, i2c); } -static -int __init init_tda8083 (void) +static int __init init_tda8083 (void) { return dvb_register_i2c_device (THIS_MODULE, tda8083_attach, tda8083_detach); } -static -void __exit exit_tda8083 (void) +static void __exit exit_tda8083 (void) { dvb_unregister_i2c_device (tda8083_attach); } diff -Nru a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c --- a/drivers/media/dvb/frontends/nxt6000.c Fri Jun 27 14:19:59 2003 +++ b/drivers/media/dvb/frontends/nxt6000.c Fri Jun 27 14:19:59 2003 @@ -25,13 +25,11 @@ */ -#include <linux/module.h> #include <linux/init.h> -#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/string.h> #include <linux/slab.h> -#include <linux/poll.h> -#include <asm/io.h> -#include <linux/i2c.h> #include "dvb_frontend.h" #include "nxt6000.h" @@ -90,11 +88,11 @@ { u8 buf[] = {reg, data}; - struct i2c_msg msg = {addr: addr >> 1, flags: 0, buf: buf, len: 2}; + struct i2c_msg msg = {.addr = addr >> 1, .flags = 0, .buf = buf, .len = 2}; int ret; if ((ret = i2c->xfer(i2c, &msg, 1)) != 1) - dprintk("nxt6000: nxt6000_write error (addr: 0x%02X, reg: 0x%02X, data: 0x%02X, ret: %d)\n", addr, reg, data, ret); + dprintk("nxt6000: nxt6000_write error (.addr = 0x%02X, reg: 0x%02X, data: 0x%02X, ret: %d)\n", addr, reg, data, ret); return (ret != 1) ? -EFAULT : 0; @@ -115,13 +113,13 @@ int ret; u8 b0[] = {reg}; u8 b1[] = {0}; - struct i2c_msg msgs[] = {{addr: addr >> 1, flags: 0, buf: b0, len: 1}, - {addr: addr >> 1, flags: I2C_M_RD, buf: b1, len: 1}}; + struct i2c_msg msgs[] = {{.addr = addr >> 1, .flags = 0, .buf = b0, .len = 1}, + {.addr = addr >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1}}; ret = i2c->xfer(i2c, msgs, 2); if (ret != 2) - dprintk("nxt6000: nxt6000_read error (addr: 0x%02X, reg: 0x%02X, ret: %d)\n", addr, reg, ret); + dprintk("nxt6000: nxt6000_read error (.addr = 0x%02X, reg: 0x%02X, ret: %d)\n", addr, reg, ret); return b1[0]; @@ -139,7 +137,7 @@ static int pll_write(struct dvb_i2c_bus *i2c, u8 demod_addr, u8 tuner_addr, u8 *buf, u8 len) { - struct i2c_msg msg = {addr: tuner_addr >> 1, flags: 0, buf: buf, len: len}; + struct i2c_msg msg = {.addr = tuner_addr >> 1, .flags = 0, .buf = buf, .len = len}; int ret; nxt6000_write(i2c, demod_addr, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ diff -Nru a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c --- a/drivers/media/dvb/frontends/stv0299.c Fri Jun 27 14:20:06 2003 +++ b/drivers/media/dvb/frontends/stv0299.c Fri Jun 27 14:20:06 2003 @@ -36,35 +36,42 @@ */ #include <linux/init.h> +#include <linux/kernel.h> #include <linux/module.h> +#include <linux/string.h> #include "dvb_frontend.h" +#include "dvb_functions.h" + +#if 0 +#define dprintk(x...) printk(x) +#else +#define dprintk(x...) +#endif -static int debug = 0; -#define dprintk if (debug) printk /* frontend types */ #define UNKNOWN_FRONTEND -1 #define PHILIPS_SU1278SH 0 #define ALPS_BSRU6 1 #define LG_TDQF_S001F 2 +#define PHILIPS_SU1278 3 /* Master Clock = 88 MHz */ #define M_CLK (88000000UL) -static -struct dvb_frontend_info uni0299_info = { - name: "STV0299/TSA5059/SL1935 based", - type: FE_QPSK, - frequency_min: 950000, - frequency_max: 2150000, - frequency_stepsize: 125, /* kHz for QPSK frontends */ - frequency_tolerance: M_CLK/2000, - symbol_rate_min: 1000000, - symbol_rate_max: 45000000, - symbol_rate_tolerance: 500, /* ppm */ - notifier_delay: 0, - caps: FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | +static struct dvb_frontend_info uni0299_info = { + .name = "STV0299/TSA5059/SL1935 based", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 125, /* kHz for QPSK frontends */ + .frequency_tolerance = M_CLK/2000, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 500, /* ppm */ + .notifier_delay = 0, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_QPSK | FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO | @@ -72,13 +79,7 @@ }; -static -u8 init_tab [] = { - /* clock registers */ - 0x01, 0x15, /* K = 0, DIRCLK = 0, M = 0x15 */ - 0x02, 0x30, /* STDBY = 0, VCO = 0 (ON), SERCLK = 0, P = 0 */ - /* f_VCO = 4MHz * 4 * (M+1) / (K+1) = 352 MHz */ - 0x03, 0x00, /* auxiliary clock not used */ +static u8 init_tab [] = { 0x04, 0x7d, /* F22FR = 0x7d */ /* F22 = f_VCO / 128 / 0x7d = 22 kHz */ @@ -90,7 +91,7 @@ 0x07, 0x00, /* DAC LSB */ /* DiSEqC registers */ - 0x08, 0x40, /* DiSEqC off */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ 0x09, 0x00, /* FIFO */ /* Input/Output configuration register */ @@ -105,34 +106,27 @@ 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 0x10, 0x3f, // AGC2 0x3d + 0x11, 0x84, 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on - 0x13, 0xb6, // alpha_car b:4 a:0 noise est:256ks derot:on - 0x14, 0x93, // beat carc:0 d:0 e:0xf phase detect algo: 1 + 0x15, 0xc9, // lock detector threshold - 0x16, 0x1d, /* AGC1 integrator value */ + 0x16, 0x00, 0x17, 0x00, - 0x18, 0x14, - 0x19, 0xf2, - - 0x1a, 0x11, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, - 0x1b, 0x9c, - 0x1c, 0x00, - 0x1d, 0x00, - 0x1e, 0x0b, 0x1f, 0x50, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, - 0x24, 0xff, - 0x25, 0xff, - 0x26, 0xff, 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 + 0x29, 0x1e, // 1/2 threshold 0x2a, 0x14, // 2/3 threshold 0x2b, 0x0f, // 3/4 threshold @@ -145,70 +139,32 @@ 0x32, 0x19, // viterbi and synchro search 0x33, 0xfc, // rs control 0x34, 0x93, // error control - - 0x0b, 0x00, - 0x27, 0x00, - 0x2f, 0x00, - 0x30, 0x00, - 0x35, 0x00, - 0x36, 0x00, - 0x37, 0x00, - 0x38, 0x00, - 0x39, 0x00, - 0x3a, 0x00, - 0x3b, 0x00, - 0x3c, 0x00, - 0x3d, 0x00, - 0x3e, 0x00, - 0x3f, 0x00, - 0x40, 0x00, - 0x41, 0x00, - 0x42, 0x00, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x48, 0x00, - 0x49, 0x00, - 0x4a, 0x00, - 0x4b, 0x00, - 0x4c, 0x00, - 0x4d, 0x00, - 0x4e, 0x00, - 0x4f, 0x00 }; -static -int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) +static int stv0299_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data) { int ret; u8 buf [] = { reg, data }; - struct i2c_msg msg = { addr: 0x68, flags: 0, buf: buf, len: 2 }; - - dprintk ("%s\n", __FUNCTION__); + struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 }; ret = i2c->xfer (i2c, &msg, 1); if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __FUNCTION__, reg, data, ret); + dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " + "ret == %i)\n", __FUNCTION__, reg, data, ret); return (ret != 1) ? -1 : 0; } -static -u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg) +static u8 stv0299_readreg (struct dvb_i2c_bus *i2c, u8 reg) { int ret; u8 b0 [] = { reg }; u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: b0, len: 1 }, - { addr: 0x68, flags: I2C_M_RD, buf: b1, len: 1 } }; - - dprintk ("%s\n", __FUNCTION__); + struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = b0, .len = 1 }, + { .addr = 0x68, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c->xfer (i2c, msg, 2); @@ -219,53 +175,40 @@ } -static -int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) +static int stv0299_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len) { int ret; - struct i2c_msg msg [] = { { addr: 0x68, flags: 0, buf: ®1, len: 1 }, - { addr: 0x68, flags: I2C_M_RD, buf: b, len: len } }; - - dprintk ("%s\n", __FUNCTION__); + struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = ®1, .len = 1 }, + { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } }; ret = i2c->xfer (i2c, msg, 2); if (ret != 2) dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); - return ret == 2 ? 0 : -1; + return ret == 2 ? 0 : ret; } -static -int pll_write (struct dvb_i2c_bus *i2c, u8 data [4], int ftype) +static int pll_write (struct dvb_i2c_bus *i2c, u8 addr, u8 *data, int len) { int ret; u8 rpt1 [] = { 0x05, 0xb5 }; /* enable i2c repeater on stv0299 */ - /* TSA5059 i2c-bus address */ - u8 addr = (ftype == PHILIPS_SU1278SH) ? 0x60 : 0x61; - struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 }, - { addr: addr, flags: 0, buf: data, len: 4 }}; + u8 rpt2 [] = { 0x05, 0x35 }; /* disable i2c repeater on stv0299 */ + struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 }, + { addr: addr, .flags = 0, .buf = data, .len = len }, + { .addr = 0x68, .flags = 0, .buf = rpt2, .len = 2 }}; - dprintk ("%s\n", __FUNCTION__); + ret = i2c->xfer (i2c, msg, 3); - if (ftype == LG_TDQF_S001F || ftype == ALPS_BSRU6) { - ret = i2c->xfer (i2c, &msg[0], 1); - ret += i2c->xfer (i2c, &msg[1], 1); - } - else { - ret = i2c->xfer (i2c, msg, 2); - } + if (ret != 3) + printk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret); - if (ret != 2) - dprintk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret); - - return (ret != 2) ? -1 : 0; + return (ret != 3) ? ret : 0; } -static -int sl1935_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) +static int sl1935_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) { u8 buf[4]; u32 div; @@ -288,20 +231,21 @@ else buf[3] = 0x00; - return pll_write (i2c, buf, ftype); + return pll_write (i2c, 0x61, buf, sizeof(buf)); } /** * set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static -int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) +static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) { + u8 addr = (ftype == PHILIPS_SU1278SH) ? 0x60 : 0x61; u32 div = freq / 125; - u8 buf[4] = { (div >> 8) & 0x7f, div & 0xff, 0x84 }; + dprintk ("%s: freq %i, ftype %i\n", __FUNCTION__, freq, ftype); + if (ftype == PHILIPS_SU1278SH) /* activate f_xtal/f_comp signal output */ /* charge pump current C0/C1 = 00 */ @@ -309,30 +253,155 @@ else buf[3] = freq > 1530000 ? 0xc0 : 0xc4; - dprintk ("%s\n", __FUNCTION__); + return pll_write (i2c, addr, buf, sizeof(buf)); +} + + + +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define MIN2(a,b) ((a) < (b) ? (a) : (b)) +#define MIN3(a,b,c) MIN2(MIN2(a,b),c) + +static int tua6100_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, + int ftype, int srate) +{ + u8 reg0 [2] = { 0x00, 0x00 }; + u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; + u8 reg2 [3] = { 0x02, 0x00, 0x00 }; + int _fband; + int first_ZF; + int R, A, N, P, M; + int err; + + first_ZF = (freq) / 1000; + + if (ABS(MIN2(ABS(first_ZF-1190),ABS(first_ZF-1790))) < + ABS(MIN3(ABS(first_ZF-1202),ABS(first_ZF-1542),ABS(first_ZF-1890)))) + _fband = 2; + else + _fband = 3; + + if (_fband == 2) { + if (((first_ZF >= 950) && (first_ZF < 1350)) || + ((first_ZF >= 1430) && (first_ZF < 1950))) + reg0[1] = 0x07; + else if (((first_ZF >= 1350) && (first_ZF < 1430)) || + ((first_ZF >= 1950) && (first_ZF < 2150))) + reg0[1] = 0x0B; + } + + if(_fband == 3) { + if (((first_ZF >= 950) && (first_ZF < 1350)) || + ((first_ZF >= 1455) && (first_ZF < 1950))) + reg0[1] = 0x07; + else if (((first_ZF >= 1350) && (first_ZF < 1420)) || + ((first_ZF >= 1950) && (first_ZF < 2150))) + reg0[1] = 0x0B; + else if ((first_ZF >= 1420) && (first_ZF < 1455)) + reg0[1] = 0x0F; +} + + if (first_ZF > 1525) + reg1[1] |= 0x80; + else + reg1[1] &= 0x7F; + + if (_fband == 2) { + if (first_ZF > 1430) { /* 1430MHZ */ + reg1[1] &= 0xCF; /* N2 */ + reg2[1] &= 0xCF; /* R2 */ + reg2[1] |= 0x10; + } else { + reg1[1] &= 0xCF; /* N2 */ + reg1[1] |= 0x20; + reg2[1] &= 0xCF; /* R2 */ + reg2[1] |= 0x10; + } +} + + if (_fband == 3) { + if ((first_ZF >= 1455) && + (first_ZF < 1630)) { + reg1[1] &= 0xCF; /* N2 */ + reg1[1] |= 0x20; + reg2[1] &= 0xCF; /* R2 */ + } else { + if (first_ZF < 1455) { + reg1[1] &= 0xCF; /* N2 */ + reg1[1] |= 0x20; + reg2[1] &= 0xCF; /* R2 */ + reg2[1] |= 0x10; + } else { + if (first_ZF >= 1630) { + reg1[1] &= 0xCF; /* N2 */ + reg2[1] &= 0xCF; /* R2 */ + reg2[1] |= 0x10; + } + } + } + } + + /* set ports, enable P0 for symbol rates > 4Ms/s */ + if (srate >= 4000000) + reg1[1] |= 0x0c; + else + reg1[1] |= 0x04; - return pll_write (i2c, buf, ftype); + reg2[1] |= 0x0c; + + R = 64; + A = 64; + P = 64; //32 + + M = (freq * R) / 4; /* in Mhz */ + N = (M - A * 1000) / (P * 1000); + + reg1[1] |= (N >> 9) & 0x03; + reg1[2] = (N >> 1) & 0xff; + reg1[3] = (N << 7) & 0x80; + + reg2[1] |= (R >> 8) & 0x03; + reg2[2] = R & 0xFF; /* R */ + + reg1[3] |= A & 0x7f; /* A */ + + if (P == 64) + reg1[1] |= 0x40; /* Prescaler 64/65 */ + + reg0[1] |= 0x03; + + if ((err = pll_write(i2c, 0x60, reg0, sizeof(reg0)))) + return err; + + if ((err = pll_write(i2c, 0x60, reg1, sizeof(reg1)))) + return err; + + if ((err = pll_write(i2c, 0x60, reg2, sizeof(reg2)))) + return err; + + return 0; } -static -int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype) + +static int pll_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq, int ftype, int srate) { if (ftype == LG_TDQF_S001F) return sl1935_set_tv_freq(i2c, freq, ftype); + else if (ftype == PHILIPS_SU1278) + return tua6100_set_tv_freq(i2c, freq, ftype, srate); else return tsa5059_set_tv_freq(i2c, freq, ftype); } #if 0 -static -int tsa5059_read_status (struct dvb_i2c_bus *i2c) +static int tsa5059_read_status (struct dvb_i2c_bus *i2c) { int ret; u8 rpt1 [] = { 0x05, 0xb5 }; u8 stat [] = { 0 }; - struct i2c_msg msg [] = {{ addr: 0x68, flags: 0, buf: rpt1, len: 2 }, - { addr: 0x60, flags: I2C_M_RD, buf: stat, len: 1 }}; + struct i2c_msg msg [] = {{ .addr = 0x68, .flags = 0, .buf = rpt1, .len = 2 }, + { .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }}; dprintk ("%s\n", __FUNCTION__); @@ -346,19 +415,24 @@ #endif -static -int stv0299_init (struct dvb_i2c_bus *i2c, int ftype) +static int stv0299_init (struct dvb_i2c_bus *i2c, int ftype) { int i; dprintk("stv0299: init chip\n"); + stv0299_writereg (i2c, 0x01, 0x15); + stv0299_writereg (i2c, 0x02, ftype == PHILIPS_SU1278 ? 0x00 : 0x30); + stv0299_writereg (i2c, 0x03, 0x00); + for (i=0; i<sizeof(init_tab); i+=2) stv0299_writereg (i2c, init_tab[i], init_tab[i+1]); /* AGC1 reference register setup */ if (ftype == PHILIPS_SU1278SH) stv0299_writereg (i2c, 0x0f, 0xd2); /* Iagc = Inverse, m1 = 18 */ + else if (ftype == PHILIPS_SU1278) + stv0299_writereg (i2c, 0x0f, 0x94); /* Iagc = Inverse, m1 = 18 */ else stv0299_writereg (i2c, 0x0f, 0x52); /* Iagc = Normal, m1 = 18 */ @@ -366,22 +440,23 @@ } -static -int stv0299_check_inversion (struct dvb_i2c_bus *i2c) +static int stv0299_check_inversion (struct dvb_i2c_bus *i2c) { dprintk ("%s\n", __FUNCTION__); if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) { + dvb_delay(30); + if ((stv0299_readreg (i2c, 0x1b) & 0x98) != 0x98) { u8 val = stv0299_readreg (i2c, 0x0c); return stv0299_writereg (i2c, 0x0c, val ^ 0x01); } + } return 0; } -static -int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) +static int stv0299_set_FEC (struct dvb_i2c_bus *i2c, fe_code_rate_t fec) { dprintk ("%s\n", __FUNCTION__); @@ -404,8 +479,7 @@ } -static -fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c) +static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c) { static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_1_2 }; @@ -423,8 +497,7 @@ } -static -int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout) +static int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout) { unsigned long start = jiffies; @@ -435,16 +508,14 @@ dprintk ("%s: timeout!!\n", __FUNCTION__); return -ETIMEDOUT; } - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (1); + dvb_delay(10); }; return 0; } -static -int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout) +static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c, int timeout) { unsigned long start = jiffies; @@ -455,16 +526,14 @@ dprintk ("%s: timeout!!\n", __FUNCTION__); return -ETIMEDOUT; } - current->state = TASK_INTERRUPTIBLE; - schedule_timeout (1); + dvb_delay(10); }; return 0; } -static -int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c, +static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c, struct dvb_diseqc_master_cmd *m) { u8 val; @@ -495,8 +564,7 @@ } -static -int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst) +static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst) { u8 val; @@ -523,12 +591,13 @@ } -static -int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone) +static int stv0299_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone) { u8 val; - dprintk ("%s\n", __FUNCTION__); + dprintk("%s: %s\n", __FUNCTION__, + tone == SEC_TONE_ON ? "SEC_TONE_ON" : + tone == SEC_TONE_OFF ? "SEC_TONE_OFF" : "??"); if (stv0299_wait_diseqc_idle (i2c, 100) < 0) return -ETIMEDOUT; @@ -546,30 +615,43 @@ } -static -int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) +static int stv0299_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage) { - u8 val; + u8 reg0x08; + u8 reg0x0c; - dprintk ("%s\n", __FUNCTION__); - - val = stv0299_readreg (i2c, 0x0c); - val &= 0x0f; - val |= 0x40; /* LNB power on */ + dprintk("%s: %s\n", __FUNCTION__, + voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : + voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); + + reg0x08 = stv0299_readreg (i2c, 0x08); + reg0x0c = stv0299_readreg (i2c, 0x0c); + + /** + * H/V switching over OP0, OP1 and OP2 are LNB power enable bits + */ + reg0x0c &= 0x0f; + + if (voltage == SEC_VOLTAGE_OFF) { + stv0299_writereg (i2c, 0x08, reg0x08 & ~0x40); + return stv0299_writereg (i2c, 0x0c, reg0x0c & ~0x40); + } else { + stv0299_writereg (i2c, 0x08, reg0x08 | 0x40); + reg0x0c |= 0x40; /* LNB power on */ switch (voltage) { case SEC_VOLTAGE_13: - return stv0299_writereg (i2c, 0x0c, val); + return stv0299_writereg (i2c, 0x0c, reg0x0c); case SEC_VOLTAGE_18: - return stv0299_writereg (i2c, 0x0c, val | 0x10); + return stv0299_writereg (i2c, 0x0c, reg0x0c | 0x10); default: return -EINVAL; }; } +} -static -int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) +static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate) { u32 ratio; u32 tmp; @@ -607,8 +689,7 @@ } -static -int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c) +static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c) { u32 Mclk = M_CLK / 4096L; u32 srate; @@ -639,14 +720,11 @@ } -static -int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int uni0299_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { - int tuner_type = (int)fe->data; + int tuner_type = (long) fe->data; struct dvb_i2c_bus *i2c = fe->i2c; - dprintk ("%s\n", __FUNCTION__); - switch (cmd) { case FE_GET_INFO: memcpy (arg, &uni0299_info, sizeof(struct dvb_frontend_info)); @@ -692,7 +770,7 @@ dprintk ("AGC2I: 0x%02x%02x, signal=0x%04x\n", stv0299_readreg (i2c, 0x18), - stv0299_readreg (i2c, 0x19), signal); + stv0299_readreg (i2c, 0x19), (int) signal); signal = signal * 5 / 4; *((u16*) arg) = (signal > 0xffff) ? 0xffff : @@ -716,15 +794,16 @@ { struct dvb_frontend_parameters *p = arg; - pll_set_tv_freq (i2c, p->frequency, tuner_type); + pll_set_tv_freq (i2c, p->frequency, tuner_type, + p->u.qpsk.symbol_rate); + stv0299_set_FEC (i2c, p->u.qpsk.fec_inner); stv0299_set_symbolrate (i2c, p->u.qpsk.symbol_rate); - stv0299_check_inversion (i2c); - /* pll_set_tv_freq (i2c, p->frequency, tuner_type); */ stv0299_writereg (i2c, 0x22, 0x00); stv0299_writereg (i2c, 0x23, 0x00); stv0299_readreg (i2c, 0x23); stv0299_writereg (i2c, 0x12, 0xb9); + stv0299_check_inversion (i2c); /* printk ("%s: tsa5059 status: %x\n", __FUNCTION__, tsa5059_read_status(i2c)); */ break; @@ -752,19 +831,13 @@ case FE_SLEEP: stv0299_writereg (i2c, 0x0c, 0x00); /* LNB power off! */ + stv0299_writereg (i2c, 0x08, 0x00); /* LNB power off! */ stv0299_writereg (i2c, 0x02, 0x80); break; case FE_INIT: return stv0299_init (i2c, tuner_type); - case FE_RESET: - stv0299_writereg (i2c, 0x22, 0x00); - stv0299_writereg (i2c, 0x23, 0x00); - stv0299_readreg (i2c, 0x23); - stv0299_writereg (i2c, 0x12, 0xb9); - break; - case FE_DISEQC_SEND_MASTER_CMD: return stv0299_send_diseqc_msg (i2c, arg); @@ -784,48 +857,65 @@ return 0; } -static -int probe_tuner (struct dvb_i2c_bus *i2c) +static long probe_tuner (struct dvb_i2c_bus *i2c) { - int type; - /* read the status register of TSA5059 */ u8 rpt[] = { 0x05, 0xb5 }; u8 stat [] = { 0 }; - struct i2c_msg msg1 [] = {{ addr: 0x68, flags: 0, buf: rpt, len: 2 }, - { addr: 0x60, flags: I2C_M_RD, buf: stat, len: 1 }}; - struct i2c_msg msg2 [] = {{ addr: 0x68, flags: 0, buf: rpt, len: 2 }, - { addr: 0x61, flags: I2C_M_RD, buf: stat, len: 1 }}; + u8 tda6100_buf [] = { 0, 0 }; + int ret; + struct i2c_msg msg1 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt, len: 2 }, + { .addr = 0x60, .flags = I2C_M_RD, .buf = stat, .len = 1 }}; + struct i2c_msg msg2 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt, len: 2 }, + { .addr = 0x61, .flags = I2C_M_RD, .buf = stat, .len = 1 }}; + struct i2c_msg msg3 [] = {{ .addr = 0x68, .flags = 0, .buf = rpt, len: 2 }, + { .addr = 0x60, .flags = 0, .buf = tda6100_buf, .len = 2 }}; + + stv0299_writereg (i2c, 0x01, 0x15); + stv0299_writereg (i2c, 0x02, 0x30); + stv0299_writereg (i2c, 0x03, 0x00); - if (i2c->xfer(i2c, msg1, 2) == 2) { - type = PHILIPS_SU1278SH; + if ((ret = i2c->xfer(i2c, msg1, 2)) == 2) { printk ("%s: setup for tuner SU1278/SH\n", __FILE__); - } else if (i2c->xfer(i2c, msg2, 2) == 2) { -if (0) { // if ((stat[0] & 0x3f) == 0) { - type = LG_TDQF_S001F; - printk ("%s: setup for tuner TDQF-S001F\n", __FILE__); - } - else { - type = ALPS_BSRU6; - printk ("%s: setup for tuner BSRU6, TDQB-S00x\n", __FILE__); + return PHILIPS_SU1278SH; } + + if ((ret = i2c->xfer(i2c, msg2, 2)) == 2) { + //if ((stat[0] & 0x3f) == 0) { + if (0) { + printk ("%s: setup for tuner TDQF-S001F\n", __FILE__); + return LG_TDQF_S001F; } else { - type = UNKNOWN_FRONTEND; - printk ("%s: unknown PLL synthesizer, " - "please report to <linuxdvb@linuxtv.org>!!\n", + printk ("%s: setup for tuner BSRU6, TDQB-S00x\n", __FILE__); + return ALPS_BSRU6; + } + } + + /** + * setup i2c timing for SU1278... + */ + stv0299_writereg (i2c, 0x02, 0x00); + + if ((ret = i2c->xfer(i2c, msg3, 2)) == 2) { + printk ("%s: setup for tuner Philips SU1278\n", __FILE__); + return PHILIPS_SU1278; } - return type; + + printk ("%s: unknown PLL synthesizer (ret == %i), " + "please report to <linuxdvb@linuxtv.org>!!\n", + __FILE__, ret); + + return UNKNOWN_FRONTEND; } -static -int uni0299_attach (struct dvb_i2c_bus *i2c) +static int uni0299_attach (struct dvb_i2c_bus *i2c) { - int tuner_type; + long tuner_type; u8 id = stv0299_readreg (i2c, 0x00); - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s: id == 0x%02x\n", __FUNCTION__, id); /* register 0x00 contains 0xa1 for STV0299 and STV0299B */ /* register 0x00 might contain 0x80 when returning from standby */ @@ -842,8 +932,7 @@ } -static -void uni0299_detach (struct dvb_i2c_bus *i2c) +static void uni0299_detach (struct dvb_i2c_bus *i2c) { dprintk ("%s\n", __FUNCTION__); @@ -851,17 +940,14 @@ } -static -int __init init_uni0299 (void) +static int __init init_uni0299 (void) { dprintk ("%s\n", __FUNCTION__); - - return dvb_register_i2c_device (THIS_MODULE, uni0299_attach, uni0299_detach); + return dvb_register_i2c_device (NULL, uni0299_attach, uni0299_detach); } -static -void __exit exit_uni0299 (void) +static void __exit exit_uni0299 (void) { dprintk ("%s\n", __FUNCTION__); @@ -870,9 +956,6 @@ module_init (init_uni0299); module_exit (exit_uni0299); - -MODULE_PARM(debug,"i"); -MODULE_PARM_DESC(debug, "enable verbose debug messages"); MODULE_DESCRIPTION("Universal STV0299/TSA5059/SL1935 DVB Frontend driver"); MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter"); diff -Nru a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c --- a/drivers/media/dvb/frontends/ves1820.c Fri Jun 27 14:19:56 2003 +++ b/drivers/media/dvb/frontends/ves1820.c Fri Jun 27 14:19:56 2003 @@ -19,11 +19,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/errno.h> #include <linux/init.h> +#include <linux/kernel.h> #include <linux/module.h> -#include <linux/delay.h> +#include <linux/string.h> +#include <linux/slab.h> #include "dvb_frontend.h" +#include "dvb_functions.h" #if 0 @@ -39,48 +43,43 @@ */ #define SET_PWM(data,pwm) do { \ - (int) data &= ~0xff; \ - (int) data |= pwm; \ + (long) data &= ~0xff; \ + (long) data |= pwm; \ } while (0) #define SET_REG0(data,reg0) do { \ - (int) data &= ~(0xff << 8); \ - (int) data |= reg0 << 8; \ + (long) data &= ~(0xff << 8); \ + (long) data |= reg0 << 8; \ } while (0) #define SET_TUNER(data,type) do { \ - (int) data &= ~(0xff << 16); \ - (int) data |= type << 16; \ + (long) data &= ~(0xff << 16); \ + (long) data |= type << 16; \ } while (0) #define SET_DEMOD_ADDR(data,type) do { \ - (int) data &= ~(0xff << 24); \ - (int) data |= type << 24; \ + (long) data &= ~(0xff << 24); \ + (long) data |= type << 24; \ } while (0) -#define GET_PWM(data) ((u8) ((int) data & 0xff)) -#define GET_REG0(data) ((u8) (((int) data >> 8) & 0xff)) -#define GET_TUNER(data) ((u8) (((int) data >> 16) & 0xff)) -#define GET_DEMOD_ADDR(data) ((u8) (((int) data >> 24) & 0xff)) +#define GET_PWM(data) ((u8) ((long) data & 0xff)) +#define GET_REG0(data) ((u8) (((long) data >> 8) & 0xff)) +#define GET_TUNER(data) ((u8) (((long) data >> 16) & 0xff)) +#define GET_DEMOD_ADDR(data) ((u8) (((long) data >> 24) & 0xff)) +#define XIN 57840000UL +#define FIN (XIN >> 4) -static inline -void ddelay (int ms) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout((HZ*ms)/1000); -} -static -struct dvb_frontend_info ves1820_info = { +static struct dvb_frontend_info ves1820_info = { .name = "VES1820 based DVB-C frontend", .type = FE_QAM, .frequency_stepsize = 62500, .frequency_min = 51000000, .frequency_max = 858000000, - .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */ - .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */ + .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ + .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ #if 0 frequency_tolerance: ???, symbol_rate_tolerance: ???, /* ppm */ /* == 8% (spec p. 5) */ @@ -94,8 +93,7 @@ -static -u8 ves1820_inittab [] = +static u8 ves1820_inittab [] = { 0x69, 0x6A, 0x9B, 0x0A, 0x52, 0x46, 0x26, 0x1A, 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x28, @@ -107,12 +105,11 @@ }; -static -int ves1820_writereg (struct dvb_frontend *fe, u8 reg, u8 data) +static int ves1820_writereg (struct dvb_frontend *fe, u8 reg, u8 data) { u8 addr = GET_DEMOD_ADDR(fe->data); u8 buf[] = { 0x00, reg, data }; - struct i2c_msg msg = { addr: addr, flags: 0, buf: buf, len: 3 }; + struct i2c_msg msg = { addr: addr, .flags = 0, .buf = buf, .len = 3 }; struct dvb_i2c_bus *i2c = fe->i2c; int ret; @@ -123,19 +120,18 @@ "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret); - mdelay(10); + dvb_delay(10); return (ret != 1) ? -EREMOTEIO : 0; } -static -u8 ves1820_readreg (struct dvb_frontend *fe, u8 reg) +static u8 ves1820_readreg (struct dvb_frontend *fe, u8 reg) { u8 b0 [] = { 0x00, reg }; u8 b1 [] = { 0 }; u8 addr = GET_DEMOD_ADDR(fe->data); - struct i2c_msg msg [] = { { addr: addr, flags: 0, buf: b0, len: 2 }, - { addr: addr, flags: I2C_M_RD, buf: b1, len: 1 } }; + struct i2c_msg msg [] = { { addr: addr, .flags = 0, .buf = b0, .len = 2 }, + { addr: addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; struct dvb_i2c_bus *i2c = fe->i2c; int ret; @@ -148,11 +144,10 @@ } -static -int tuner_write (struct dvb_i2c_bus *i2c, u8 addr, u8 data [4]) +static int tuner_write (struct dvb_i2c_bus *i2c, u8 addr, u8 data [4]) { int ret; - struct i2c_msg msg = { addr: addr, flags: 0, buf: data, len: 4 }; + struct i2c_msg msg = { addr: addr, .flags = 0, .buf = data, .len = 4 }; ret = i2c->xfer (i2c, &msg, 1); @@ -167,10 +162,9 @@ * set up the downconverter frequency divisor for a * reference clock comparision frequency of 62.5 kHz. */ -static -int tuner_set_tv_freq (struct dvb_frontend *fe, u32 freq) +static int tuner_set_tv_freq (struct dvb_frontend *fe, u32 freq) { - u32 div; + u32 div, ifreq; static u8 addr [] = { 0x61, 0x62 }; static u8 byte3 [] = { 0x8e, 0x85 }; int tuner_type = GET_TUNER(fe->data); @@ -179,7 +173,13 @@ if (tuner_type == 0xff) /* PLL not reachable over i2c ... */ return 0; - div = (freq + 36125000 + 31250) / 62500; + if (strstr (fe->i2c->adapter->name, "Technotrend")) + ifreq = 35937500; + else + ifreq = 36125000; + + div = (freq + ifreq + 31250) / 62500; + buf[0] = (div >> 8) & 0x7f; buf[1] = div & 0xff; buf[2] = byte3[tuner_type]; @@ -197,19 +197,24 @@ } -static -int ves1820_setup_reg0 (struct dvb_frontend *fe, u8 reg0) +static int ves1820_setup_reg0 (struct dvb_frontend *fe, u8 reg0, + fe_spectral_inversion_t inversion) { reg0 |= GET_REG0(fe->data) & 0x62; + if (INVERSION_ON == inversion) + reg0 &= ~0x20; + else if (INVERSION_OFF == inversion) + reg0 |= 0x20; + ves1820_writereg (fe, 0x00, reg0 & 0xfe); ves1820_writereg (fe, 0x00, reg0 | 0x01); /** * check lock and toggle inversion bit if required... */ - if (!(ves1820_readreg (fe, 0x11) & 0x08)) { - ddelay(1); + if (INVERSION_AUTO == inversion && !(ves1820_readreg (fe, 0x11) & 0x08)) { + dvb_delay(10); if (!(ves1820_readreg (fe, 0x11) & 0x08)) { reg0 ^= 0x20; ves1820_writereg (fe, 0x00, reg0 & 0xfe); @@ -223,8 +228,7 @@ } -static -int ves1820_init (struct dvb_frontend *fe) +static int ves1820_init (struct dvb_frontend *fe) { int i; @@ -241,8 +245,7 @@ } -static -int ves1820_set_symbolrate (struct dvb_frontend *fe, u32 symbolrate) +static int ves1820_set_symbolrate (struct dvb_frontend *fe, u32 symbolrate) { s32 BDR; s32 BDRI; @@ -250,9 +253,6 @@ u16 NDEC = 0; u32 tmp, ratio; -#define XIN 57840000UL -#define FIN (XIN >> 4) - if (symbolrate > XIN/2) symbolrate = XIN/2; @@ -300,12 +300,11 @@ } -static -int ves1820_set_parameters (struct dvb_frontend *fe, +static int ves1820_set_parameters (struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { static const u8 reg0x00 [] = { 0x00, 0x04, 0x08, 0x0c, 0x10 }; - static const u8 reg0x01 [] = { 140, 140, 106, 120, 92 }; + static const u8 reg0x01 [] = { 140, 140, 106, 100, 92 }; static const u8 reg0x05 [] = { 135, 100, 70, 54, 38 }; static const u8 reg0x08 [] = { 162, 116, 67, 52, 35 }; static const u8 reg0x09 [] = { 145, 150, 106, 126, 107 }; @@ -323,15 +322,14 @@ ves1820_writereg (fe, 0x08, reg0x08[real_qam]); ves1820_writereg (fe, 0x09, reg0x09[real_qam]); - ves1820_setup_reg0 (fe, reg0x00[real_qam]); + ves1820_setup_reg0 (fe, reg0x00[real_qam], p->inversion); return 0; } -static -int ves1820_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int ves1820_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { switch (cmd) { case FE_GET_INFO: @@ -400,15 +398,31 @@ return ves1820_set_parameters (fe, arg); case FE_GET_FRONTEND: - /* XXX FIXME: implement! */ -/* - struct frontend *front = (struct frontend *)arg; + { + struct dvb_frontend_parameters *p = (struct dvb_frontend_parameters *)arg; + u8 reg0 = GET_REG0(fe->data); + int sync; + s8 afc = 0; - front->afc=(int)((char)(readreg(client,0x19))); - front->afc=(front->afc*(int)(front->param.u.qam.SymbolRate/8))/128; -*/ - break; + sync = ves1820_readreg (fe, 0x11); + if (sync & 2) + /* AFC only valid when carrier has been recovered */ + afc = ves1820_readreg(fe, 0x19); + printk ("%s: AFC (%d) %dHz\n", __FILE__, afc, + -((s32)(p->u.qam.symbol_rate >> 3) * afc >> 7)); + + p->inversion = reg0 & 0x20 ? INVERSION_OFF : INVERSION_ON; + p->u.qam.modulation = ((reg0 >> 2) & 7) + QAM_16; + + p->u.qam.fec_inner = FEC_NONE; + + p->frequency = ((p->frequency + 31250) / 62500) * 62500; + // To prevent overflow, shift symbol rate first a + // couple of bits. + p->frequency -= (s32)(p->u.qam.symbol_rate >> 3) * afc >> 7; + break; + } case FE_SLEEP: ves1820_writereg (fe, 0x1b, 0x02); /* pdown ADC */ ves1820_writereg (fe, 0x00, 0x80); /* standby */ @@ -425,13 +439,12 @@ } -static -int probe_tuner (struct dvb_i2c_bus *i2c) +static long probe_tuner (struct dvb_i2c_bus *i2c) { - static const - struct i2c_msg msg1 = { addr: 0x61, flags: 0, buf: NULL, len: 0 }; - static const - struct i2c_msg msg2 = { addr: 0x62, flags: 0, buf: NULL, len: 0 }; + static const struct i2c_msg msg1 = + { .addr = 0x61, .flags = 0, .buf = NULL, .len = 0 }; + static const struct i2c_msg msg2 = + { .addr = 0x62, .flags = 0, .buf = NULL, .len = 0 }; int type; if (i2c->xfer(i2c, &msg1, 1) == 1) { @@ -451,13 +464,12 @@ } -static -u8 read_pwm (struct dvb_i2c_bus *i2c) +static u8 read_pwm (struct dvb_i2c_bus *i2c) { u8 b = 0xff; u8 pwm; - struct i2c_msg msg [] = { { addr: 0x50, flags: 0, buf: &b, len: 1 }, - { addr: 0x50, flags: I2C_M_RD, buf: &pwm, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x50, .flags = 0, .buf = &b, .len = 1 }, + { .addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1 } }; i2c->xfer (i2c, msg, 2); @@ -470,13 +482,12 @@ } -static -int probe_demod_addr (struct dvb_i2c_bus *i2c) +static long probe_demod_addr (struct dvb_i2c_bus *i2c) { u8 b [] = { 0x00, 0x1a }; u8 id; - struct i2c_msg msg [] = { { addr: 0x08, flags: 0, buf: b, len: 2 }, - { addr: 0x08, flags: I2C_M_RD, buf: &id, len: 1 } }; + struct i2c_msg msg [] = { { .addr = 0x08, .flags = 0, .buf = b, .len = 2 }, + { .addr = 0x08, .flags = I2C_M_RD, .buf = &id, .len = 1 } }; if (i2c->xfer(i2c, msg, 2) == 2 && (id & 0xf0) == 0x70) return msg[0].addr; @@ -490,12 +501,11 @@ } -static -int ves1820_attach (struct dvb_i2c_bus *i2c) +static int ves1820_attach (struct dvb_i2c_bus *i2c) { void *data = NULL; - int demod_addr; - int tuner_type; + long demod_addr; + long tuner_type; if ((demod_addr = probe_demod_addr(i2c)) < 0) return -ENODEV; @@ -514,23 +524,20 @@ } -static -void ves1820_detach (struct dvb_i2c_bus *i2c) +static void ves1820_detach (struct dvb_i2c_bus *i2c) { dvb_unregister_frontend (ves1820_ioctl, i2c); } -static -int __init init_ves1820 (void) +static int __init init_ves1820 (void) { return dvb_register_i2c_device (THIS_MODULE, ves1820_attach, ves1820_detach); } -static -void __exit exit_ves1820 (void) +static void __exit exit_ves1820 (void) { dvb_unregister_i2c_device (ves1820_attach); } diff -Nru a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c --- a/drivers/media/dvb/ttpci/av7110.c Fri Jun 27 14:19:59 2003 +++ b/drivers/media/dvb/ttpci/av7110.c Fri Jun 27 14:19:59 2003 @@ -58,23 +58,25 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/pci.h> -#include <asm/system.h> -#include <asm/bitops.h> -#include <asm/io.h> -#include <asm/dma.h> -#include <asm/semaphore.h> #include <linux/init.h> #include <linux/vmalloc.h> - #include <linux/netdevice.h> #include <linux/inetdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> +#include <asm/system.h> +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/dma.h> +#include <asm/semaphore.h> + #include <linux/dvb/frontend.h> #include "dvb_i2c.h" #include "dvb_frontend.h" +#include "dvb_functions.h" + #if 1 #define DEBUG_VARIABLE av7110_debug @@ -87,15 +89,16 @@ #include "av7110.h" #include "av7110_ipack.h" -static int AV_StartPlay(av7110_t *av7110, int av); -static void restart_feeds(av7110_t *av7110); -static int bootarm(av7110_t *av7110); -static inline int i2c_writereg(av7110_t *av7110, u8 id, u8 reg, u8 val); -static inline u8 i2c_readreg(av7110_t *av7110, u8 id, u8 reg); -static int outcom(av7110_t *av7110, int type, int com, int num, ...); -static void SetMode(av7110_t *av7110, int mode); +static int AV_StartPlay(struct av7110 *av7110, int av); +static void restart_feeds(struct av7110 *av7110); +static int bootarm(struct av7110 *av7110); +static inline int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val); +static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg); +static int outcom(struct av7110 *av7110, int type, int com, int num, ...); +static void SetMode(struct av7110 *av7110, int mode); +static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event); -void pes_to_ts(u8 const *buf, long int length, u16 pid, p2t_t *p); +void pes_to_ts(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p); void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, struct dvb_demux_feed *feed); static int av7110_debug = 0; @@ -107,20 +110,7 @@ int av7110_num = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME av7110 -#endif - -/**************************************************************************** - * General helper functions - ****************************************************************************/ - -static inline void ddelay(int i) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout((HZ*i)/100); -} - +#define FW_CI_LL_SUPPORT(arm_app) (((arm_app) >> 16) & 0x8000) /**************************************************************************** * DEBI functions @@ -129,8 +119,7 @@ /* This DEBI code is based on the Stradis driver by Nathan Laredo <laredo@gnu.org> */ -static -int wait_for_debi_done(av7110_t *av7110) +static int wait_for_debi_done(struct av7110 *av7110) { struct saa7146_dev *dev = av7110->dev; int start; @@ -163,7 +152,7 @@ return 0; } -static int debiwrite(av7110_t *av7110, u32 config, +static int debiwrite(struct av7110 *av7110, u32 config, int addr, u32 val, int count) { struct saa7146_dev *dev = av7110->dev; @@ -183,7 +172,7 @@ return 0; } -static u32 debiread(av7110_t *av7110, u32 config, int addr, int count) +static u32 debiread(struct av7110 *av7110, u32 config, int addr, int count) { struct saa7146_dev *dev = av7110->dev; u32 result = 0; @@ -207,16 +196,16 @@ /* DEBI during interrupt */ -static inline void -iwdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count) +/* fixme: val can be a pointer to a memory or an u32 value -- this + won't work on 64bit platforms! */ +static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) { if (count>4 && val) memcpy(av7110->debi_virt, (char *) val, count); debiwrite(av7110, config, addr, val, count); } -static inline u32 -irdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count) +static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) { u32 res; @@ -228,8 +217,7 @@ /* DEBI outside interrupts, only for count<=4! */ -static inline void -wdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count) +static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) { unsigned long flags; @@ -238,8 +226,7 @@ spin_unlock_irqrestore(&av7110->debilock, flags); } -static inline u32 -rdebi(av7110_t *av7110, u32 config, int addr, u32 val, int count) +static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) { unsigned long flags; u32 res; @@ -251,8 +238,7 @@ } -static inline char -chtrans(char c) +static inline char chtrans(char c) { if (c<32 || c>126) c=0x20; @@ -262,8 +248,7 @@ /* handle mailbox registers of the dual ported RAM */ -static inline void -ARM_ResetMailBox(av7110_t *av7110) +static inline void ARM_ResetMailBox(struct av7110 *av7110) { unsigned long flags; @@ -276,20 +261,17 @@ spin_unlock_irqrestore(&av7110->debilock, flags); } -static inline void -ARM_ClearMailBox(av7110_t *av7110) +static inline void ARM_ClearMailBox(struct av7110 *av7110) { iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); } -static inline void -ARM_ClearIrq(av7110_t *av7110) +static inline void ARM_ClearIrq(struct av7110 *av7110) { irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); } -static void -reset_arm(av7110_t *av7110) +static void reset_arm(struct av7110 *av7110) { saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); @@ -315,8 +297,7 @@ printk("av7110: ARM RESET\n"); } -static void -recover_arm(av7110_t *av7110) +static void recover_arm(struct av7110 *av7110) { DEB_EE(("av7110: %p\n",av7110)); @@ -326,12 +307,13 @@ printk("OOPS, no current->files\n"); reset_arm(av7110); } - ddelay(10); + + dvb_delay(100); restart_feeds(av7110); + outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); } -static void -arm_error(av7110_t *av7110) +static void arm_error(struct av7110 *av7110) { DEB_EE(("av7110: %p\n",av7110)); @@ -342,25 +324,13 @@ static int arm_thread(void *data) { - av7110_t *av7110 = data; + struct av7110 *av7110 = data; u16 newloops = 0; DEB_EE(("av7110: %p\n",av7110)); - lock_kernel(); -#if 0 - daemonize(); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - reparent_to_init (); -#endif -#else - exit_mm(current); - current->session=current->pgrp=1; -#endif - sigfillset(¤t->blocked); - strcpy(current->comm, "arm_mon"); + dvb_kernel_thread_setup ("arm_mon"); av7110->arm_thread = current; - unlock_kernel(); while (!av7110->arm_rmmod && !signal_pending(current)) { interruptible_sleep_on_timeout(&av7110->arm_wait, 5*HZ); @@ -394,12 +364,11 @@ } -static int -record_cb(dvb_filter_pes2ts_t *p2t, u8 *buf, size_t len) +static int record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) p2t->priv; - DEB_EE(("dvb_filter_pes2ts_t:%p\n",p2t)); + DEB_EE(("struct dvb_filter_pes2ts:%p\n",p2t)); if (!(dvbdmxfeed->ts_type & TS_PACKET)) return 0; @@ -412,8 +381,7 @@ return dvb_filter_pes2ts(p2t, buf, len); } -static int -dvb_filter_pes2ts_cb(void *priv, unsigned char *data) +static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) { struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) priv; @@ -425,8 +393,7 @@ return 0; } -static int -AV_StartRecord(av7110_t *av7110, int av, +static int AV_StartRecord(struct av7110 *av7110, int av, struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx=dvbdmxfeed->demux; @@ -471,8 +438,7 @@ return 0; } -static int -AV_StartPlay(av7110_t *av7110, int av) +static int AV_StartPlay(struct av7110 *av7110, int av) { DEB_EE(("av7110: %p\n",av7110)); @@ -505,8 +471,7 @@ return av7110->playing; } -static void -AV_Stop(av7110_t *av7110, int av) +static void AV_Stop(struct av7110 *av7110, int av) { DEB_EE(("av7110: %p\n",av7110)); @@ -548,9 +513,9 @@ * * If we want to support multiple controls we would have to do much more... */ -void av7110_setup_irc_config (av7110_t *av7110, u32 ir_config) +void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config) { - static av7110_t *last; + static struct av7110 *last; DEB_EE(("av7110: %p\n",av7110)); @@ -559,8 +524,10 @@ else last = av7110; - if (av7110) + if (av7110) { outcom(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); + av7110->ir_config = ir_config; + } } static void (*irc_handler)(u32); @@ -585,7 +552,7 @@ DECLARE_TASKLET(irtask,run_handlers,0); -void IR_handle(av7110_t *av7110, u32 ircom) +void IR_handle(struct av7110 *av7110, u32 ircom) { DEB_S(("av7110: ircommand = %08x\n", ircom)); irtask.data = (unsigned long) ircom; @@ -596,7 +563,7 @@ * IRQ handling ****************************************************************************/ -void CI_handle(av7110_t *av7110, u8 *data, u16 len) +void CI_handle(struct av7110 *av7110, u8 *data, u16 len) { //CI_out(av7110, data, len); @@ -629,12 +596,11 @@ } -static inline int -DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len, +static inline int DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len, u8 * buffer2, size_t buffer2_len, struct dvb_demux_filter *dvbdmxfilter, - dmx_success_t success, - av7110_t *av7110) + enum dmx_success success, + struct av7110 *av7110) { DEB_EE(("av7110: %p\n",av7110)); @@ -648,7 +614,7 @@ if ((((buffer1[1]<<8)|buffer1[2])&0xfff)+3!=buffer1_len) return 0; if (dvbdmxfilter->doneq) { - dmx_section_filter_t *filter=&dvbdmxfilter->filter; + struct dmx_section_filter *filter=&dvbdmxfilter->filter; int i; u8 xor, neq=0; @@ -691,8 +657,7 @@ //#define DEBUG_TIMING -inline static void -print_time(char *s) +static inline void print_time(char *s) { #ifdef DEBUG_TIMING struct timeval tv; @@ -701,8 +666,7 @@ #endif } -static void -ci_get_data(dvb_ringbuffer_t *cibuf, u8 *data, int len) +static void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len) { if (dvb_ringbuffer_free(cibuf) < len+2) return; @@ -715,10 +679,9 @@ wake_up_interruptible(&cibuf->queue); } -static -void debiirq (unsigned long data) +static void debiirq (unsigned long data) { - struct av7110_s *av7110 = (struct av7110_s*) data; + struct av7110 *av7110 = (struct av7110*) data; int type=av7110->debitype; int handle=(type>>8)&0x1f; @@ -731,8 +694,10 @@ if (type==-1) { printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",jiffies,saa7146_read(av7110->dev,PSR),saa7146_read(av7110->dev,SSR)); + spin_lock(&av7110->debilock); ARM_ClearMailBox(av7110); ARM_ClearIrq(av7110); + spin_unlock(&av7110->debilock); return; } av7110->debitype=-1; @@ -844,8 +809,7 @@ spin_unlock(&av7110->debilock); } -static int -pes_play(void *dest, dvb_ringbuffer_t *buf, int dlen) +static int pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) { int len; u32 sync; @@ -876,23 +840,22 @@ blen|=DVB_RINGBUFFER_PEEK(buf,5); blen+=6; if (len<blen || blen>dlen) { - printk("buffer empty - avail %d blen %u dlen %d\n",len,blen,dlen); + //printk("buffer empty - avail %d blen %u dlen %d\n",len,blen,dlen); wake_up(&buf->queue); return -1; } (void)dvb_ringbuffer_read(buf,dest,(size_t)blen,0); - DEB_S(("pread=%08x, pwrite=%08x\n",buf->pread, buf->pwrite)); + DEB_S(("pread=0x%08lx, pwrite=0x%08lx\n",(unsigned long)buf->pread, (unsigned long)buf->pwrite)); wake_up(&buf->queue); return blen; } -static -void gpioirq (unsigned long data) +static void gpioirq (unsigned long data) { - struct av7110_s *av7110 = (struct av7110_s*) data; + struct av7110 *av7110 = (struct av7110*) data; u32 rxbuf, txbuf; int len; @@ -926,10 +889,51 @@ case DATA_PES_PLAY: break; + case DATA_MPEG_VIDEO_EVENT: + { + u32 h_ar; + struct video_event event; + + av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2); + h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2); + + iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); + iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); + + av7110->video_size.h = h_ar & 0xfff; + DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", + av7110->video_size.w, + av7110->video_size.h, + av7110->video_size.aspect_ratio)); + + event.type = VIDEO_EVENT_SIZE_CHANGED; + event.u.size.w = av7110->video_size.w; + event.u.size.h = av7110->video_size.h; + switch ((h_ar >> 12) & 0xf) + { + case 3: + av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9; + event.u.size.aspect_ratio = VIDEO_FORMAT_16_9; + av7110->videostate.video_format = VIDEO_FORMAT_16_9; + break; + case 4: + av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1; + event.u.size.aspect_ratio = VIDEO_FORMAT_221_1; + av7110->videostate.video_format = VIDEO_FORMAT_221_1; + break; + default: + av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3; + event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; + av7110->videostate.video_format = VIDEO_FORMAT_4_3; + } + dvb_video_add_event(av7110, &event); + break; + } + case DATA_CI_PUT: { int avail; - dvb_ringbuffer_t *cibuf=&av7110->ci_wbuffer; + struct dvb_ringbuffer *cibuf=&av7110->ci_wbuffer; avail=dvb_ringbuffer_avail(cibuf); if (avail<=2) { @@ -1077,7 +1081,7 @@ ****************************************************************************/ -static int OutCommand(av7110_t *av7110, u16* buf, int length) +static int OutCommand(struct av7110 *av7110, u16* buf, int length) { int i; u32 start; @@ -1095,7 +1099,7 @@ start = jiffies; while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_FREE) { printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__); return -1; @@ -1106,7 +1110,7 @@ start = jiffies; while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_SHAKE) { printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); return -1; @@ -1117,7 +1121,7 @@ start = jiffies; while ( rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_OSD) { printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__); return -1; @@ -1137,7 +1141,7 @@ start = jiffies; while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_FREE) { printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); return -1; @@ -1158,8 +1162,7 @@ return 0; } -inline static int -SOutCommand(av7110_t *av7110, u16* buf, int length) +static inline int SOutCommand(struct av7110 *av7110, u16* buf, int length) { int ret; @@ -1181,7 +1184,7 @@ } -static int outcom(av7110_t *av7110, int type, int com, int num, ...) +static int outcom(struct av7110 *av7110, int type, int com, int num, ...) { va_list args; u16 buf[num+2]; @@ -1205,7 +1208,7 @@ return ret; } -int SendCICommand(av7110_t *av7110, u8 subcom, u8 *Params, u8 ParamLen) +int SendCICommand(struct av7110 *av7110, u8 subcom, u8 *Params, u8 ParamLen) { int i, ret; u16 CommandBuffer[18] = { ((COMTYPE_COMMON_IF << 8) + subcom), @@ -1228,7 +1231,7 @@ } -static int CommandRequest(av7110_t *av7110, u16 *Buff, int length, u16 *buf, int n) +static int CommandRequest(struct av7110 *av7110, u16 *Buff, int length, u16 *buf, int n) { int err; s16 i; @@ -1257,7 +1260,7 @@ while ( rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) ) { #ifdef _NOHANDSHAKE - ddelay(1); + dvb_delay(1); #endif if ((jiffies - start) > ARM_WAIT_FREE) { printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); @@ -1269,7 +1272,7 @@ #ifndef _NOHANDSHAKE start = jiffies; while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_SHAKE) { printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); up(&av7110->dcomlock); @@ -1300,8 +1303,7 @@ } -static inline int -RequestParameter(av7110_t *av7110, u16 tag, u16* Buff, s16 length) +static inline int RequestParameter(struct av7110 *av7110, u16 tag, u16* Buff, s16 length) { int ret; ret = CommandRequest(av7110, &tag, 0, Buff, length); @@ -1315,19 +1317,29 @@ * Firmware commands ****************************************************************************/ +static inline int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) +{ + u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff }; + struct dvb_i2c_bus *i2c = av7110->i2c_bus; + struct i2c_msg msgs; + + msgs.flags=0; + msgs.addr=0x40; + msgs.len=5; + msgs.buf=msg; + return i2c->xfer(i2c, &msgs, 1); +} -inline static int -SendDAC(av7110_t *av7110, u8 addr, u8 data) +static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data) { DEB_EE(("av7110: %p\n",av7110)); return outcom(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data); } -static int -SetVolume(av7110_t *av7110, int volleft, int volright) +static int SetVolume(struct av7110 *av7110, int volleft, int volright) { - int err; + int err, vol, val, balance = 0; DEB_EE(("av7110: %p\n",av7110)); @@ -1349,54 +1361,65 @@ i2c_writereg(av7110, 0x20, 0x03, volleft); i2c_writereg(av7110, 0x20, 0x04, volright); return 0; + + case DVB_ADAC_MSP: + vol = (volleft > volright) ? volleft : volright; + val = (vol * 0x73 / 255) << 8; + if (vol > 0) { + balance = ((volright-volleft) * 127) / vol; + } + msp_writereg(av7110, 0x12, 0x0001, balance << 8); + msp_writereg(av7110, 0x12, 0x0000, val); /* loudspeaker */ + msp_writereg(av7110, 0x12, 0x0006, val); /* headphonesr */ + return 0; } return 0; } #ifdef CONFIG_DVB_AV7110_OSD -inline static int ResetBlend(av7110_t *av7110, u8 windownr) +static inline int ResetBlend(struct av7110 *av7110, u8 windownr) { return outcom(av7110, COMTYPE_OSD, SetNonBlend, 1, windownr); } -inline static int SetColorBlend(av7110_t *av7110, u8 windownr) +static inline int SetColorBlend(struct av7110 *av7110, u8 windownr) { return outcom(av7110, COMTYPE_OSD, SetCBlend, 1, windownr); } -inline static int SetWindowBlend(av7110_t *av7110, u8 windownr, u8 blending) +static inline int SetWindowBlend(struct av7110 *av7110, u8 windownr, u8 blending) { return outcom(av7110, COMTYPE_OSD, SetWBlend, 2, windownr, blending); } -inline static int SetBlend_(av7110_t *av7110, u8 windownr, - OSDPALTYPE colordepth, u16 index, u8 blending) +static inline int SetBlend_(struct av7110 *av7110, u8 windownr, + enum av7110_osd_palette_type colordepth, u16 index, u8 blending) { return outcom(av7110, COMTYPE_OSD, SetBlend, 4, windownr, colordepth, index, blending); } -inline static int SetColor_(av7110_t *av7110, u8 windownr, - OSDPALTYPE colordepth, u16 index, u16 colorhi, u16 colorlo) +static inline int SetColor_(struct av7110 *av7110, u8 windownr, + enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo) { return outcom(av7110, COMTYPE_OSD, SetColor, 5, windownr, colordepth, index, colorhi, colorlo); } -inline static int BringToTop(av7110_t *av7110, u8 windownr) +static inline int BringToTop(struct av7110 *av7110, u8 windownr) { return outcom(av7110, COMTYPE_OSD, WTop, 1, windownr); } -inline static int SetFont(av7110_t *av7110, u8 windownr, u8 fontsize, +static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize, u16 colorfg, u16 colorbg) { return outcom(av7110, COMTYPE_OSD, Set_Font, 4, windownr, fontsize, colorfg, colorbg); } -static int FlushText(av7110_t *av7110) +static int FlushText(struct av7110 *av7110) { u32 start; @@ -1404,7 +1427,7 @@ return -ERESTARTSYS; start = jiffies; while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_OSD) { printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); up(&av7110->dcomlock); @@ -1415,7 +1438,7 @@ return 0; } -static int WriteText(av7110_t *av7110, u8 win, u16 x, u16 y, u8* buf) +static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) { int i, ret; u32 start; @@ -1427,7 +1450,7 @@ start = jiffies; while ( rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_OSD) { printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", __FUNCTION__); up(&av7110->dcomlock); @@ -1437,7 +1460,7 @@ #ifndef _NOHANDSHAKE start = jiffies; while ( rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 ) ) { - ddelay(1); + dvb_delay(1); if ((jiffies - start) > ARM_WAIT_SHAKE) { printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); up(&av7110->dcomlock); @@ -1457,42 +1480,42 @@ return ret; } -inline static int DrawLine(av7110_t *av7110, u8 windownr, +static inline int DrawLine(struct av7110 *av7110, u8 windownr, u16 x, u16 y, u16 dx, u16 dy, u16 color) { return outcom(av7110, COMTYPE_OSD, DLine, 6, windownr, x, y, dx, dy, color); } -inline static int DrawBlock(av7110_t *av7110, u8 windownr, +static inline int DrawBlock(struct av7110 *av7110, u8 windownr, u16 x, u16 y, u16 dx, u16 dy, u16 color) { return outcom(av7110, COMTYPE_OSD, DBox, 6, windownr, x, y, dx, dy, color); } -inline static int HideWindow(av7110_t *av7110, u8 windownr) +static inline int HideWindow(struct av7110 *av7110, u8 windownr) { return outcom(av7110, COMTYPE_OSD, WHide, 1, windownr); } -inline static int MoveWindowRel(av7110_t *av7110, u8 windownr, u16 x, u16 y) +static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y) { return outcom(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y); } -inline static int MoveWindowAbs(av7110_t *av7110, u8 windownr, u16 x, u16 y) +static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y) { return outcom(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y); } -inline static int DestroyOSDWindow(av7110_t *av7110, u8 windownr) +static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr) { return outcom(av7110, COMTYPE_OSD, WDestroy, 1, windownr); } #if 0 -static void DestroyOSDWindows(av7110_t *av7110) +static void DestroyOSDWindows(struct av7110 *av7110) { int i; @@ -1501,20 +1524,18 @@ } #endif -static inline int -CreateOSDWindow(av7110_t *av7110, u8 windownr, - DISPTYPE disptype, u16 width, u16 height) +static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, + enum av7110_window_display_type disptype, u16 width, u16 height) { return outcom(av7110, COMTYPE_OSD, WCreate, 4, windownr, disptype, width, height); } -static OSDPALTYPE bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit}; -static DISPTYPE bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8}; +static enum av7110_osd_palette_type bpp2pal[8]={Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit}; +static enum av7110_window_display_type bpp2bit[8]={BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8}; -static inline int -LoadBitmap(av7110_t *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data) +static inline int LoadBitmap(struct av7110 *av7110, u16 format, u16 dx, u16 dy, int inc, u8* data) { int bpp; int i; @@ -1533,7 +1554,7 @@ break; schedule(); } - current->state=TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&av7110->bmpq, &wait); } if (av7110->bmp_state==BMP_LOADING) @@ -1573,8 +1594,7 @@ return outcom(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy); } -static int -BlitBitmap(av7110_t *av7110, u16 win, u16 x, u16 y, u16 trans) +static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans) { DECLARE_WAITQUEUE(wait, current); @@ -1591,7 +1611,7 @@ break; schedule(); } - current->state=TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&av7110->bmpq, &wait); } if (av7110->bmp_state==BMP_LOADED) @@ -1599,8 +1619,7 @@ return -1; } -static inline int -ReleaseBitmap(av7110_t *av7110) +static inline int ReleaseBitmap(struct av7110 *av7110) { DEB_EE(("av7110: %p\n",av7110)); @@ -1626,8 +1645,7 @@ return Cr|(Cb<<16)|(Y<<8); } -static void -OSDSetColor(av7110_t *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) +static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) { u16 ch, cl; u32 yuv; @@ -1641,8 +1659,7 @@ color, ((blend>>4)&0x0f)); } -static int -OSDSetBlock(av7110_t *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data) +static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, int x1, int y1, int inc, u8 *data) { uint w, h, bpp, bpl, size, lpb, bnum, brest; int i; @@ -1672,8 +1689,7 @@ return 0; } -static int -OSD_DrawCommand(av7110_t *av7110, osd_cmd_t *dc) +static int OSD_DrawCommand(struct av7110 *av7110, osd_cmd_t *dc) { switch (dc->cmd) { case OSD_Close: @@ -1779,12 +1795,11 @@ } -static int -dvb_osd_ioctl(struct inode *inode, struct file *file, +static int dvb_osd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -1815,8 +1830,7 @@ /* get version of the firmware ROM, RTSL, video ucode and ARM application */ -static void -firmversion(av7110_t *av7110) +static void firmversion(struct av7110 *av7110) { u16 buf[20]; @@ -1837,7 +1851,7 @@ av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); /* print firmware capabilities */ - if ((av7110->arm_app >> 16) & 0x8000) + if (FW_CI_LL_SUPPORT(av7110->arm_app)) printk ("DVB: AV711%d(%d) - firmware supports CI link layer interface\n", av7110->avtype, av7110->dvb_adapter->num); else @@ -1847,8 +1861,7 @@ return; } -static int -waitdebi(av7110_t *av7110, int adr, int state) +static int waitdebi(struct av7110 *av7110, int adr, int state) { int k; @@ -1862,8 +1875,7 @@ } -static int -load_dram(av7110_t *av7110, u32 *data, int len) +static int load_dram(struct av7110 *av7110, u32 *data, int len) { int i; int blocks, rest; @@ -1911,8 +1923,7 @@ } -static u8 -bootcode[] = { +static u8 bootcode[] = { 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, /* 0x0000 */ 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04, @@ -1938,8 +1949,7 @@ #include "av7110_firm.h" -static int -bootarm(av7110_t *av7110) +static int bootarm(struct av7110 *av7110) { struct saa7146_dev *dev= av7110->dev; u32 ret; @@ -1986,7 +1996,7 @@ wait_for_debi_done(av7110); saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); - current->state=TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); DEB_D(("bootarm: load dram code\n")); @@ -2018,22 +2028,25 @@ return 0; } -static inline int -SetPIDs(av7110_t *av7110, u16 vpid, u16 apid, u16 ttpid, +static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, u16 subpid, u16 pcrpid) { DEB_EE(("av7110: %p\n",av7110)); if (vpid == 0x1fff || apid == 0x1fff || - ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) + ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) { vpid = apid = ttpid = subpid = pcrpid = 0; + av7110->pids[DMX_PES_VIDEO] = 0; + av7110->pids[DMX_PES_AUDIO] = 0; + av7110->pids[DMX_PES_TELETEXT] = 0; + av7110->pids[DMX_PES_PCR] = 0; + } return outcom(av7110, COMTYPE_PIDFILTER, MultiPID, 5, pcrpid, vpid, apid, ttpid, subpid); } -static void -ChangePIDs(av7110_t *av7110, u16 vpid, u16 apid, u16 ttpid, +static void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, u16 subpid, u16 pcrpid) { DEB_EE(("av7110: %p\n",av7110)); @@ -2048,15 +2061,16 @@ av7110->pids[DMX_PES_SUBTITLE]=0; - if (av7110->fe_synced) + if (av7110->fe_synced) { + pcrpid = av7110->pids[DMX_PES_PCR]; SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); + } up(&av7110->pid_mutex); } -static void -SetMode(av7110_t *av7110, int mode) +static void SetMode(struct av7110 *av7110, int mode) { DEB_EE(("av7110: %p\n",av7110)); @@ -2071,23 +2085,20 @@ } } -inline static void -TestMode(av7110_t *av7110, int mode) +static inline void TestMode(struct av7110 *av7110, int mode) { DEB_EE(("av7110: %p\n",av7110)); outcom(av7110, COMTYPE_ENCODER, SetTestMode, 1, mode); } -inline static void -VidMode(av7110_t *av7110, int mode) +static inline void VidMode(struct av7110 *av7110, int mode) { DEB_EE(("av7110: %p\n",av7110)); outcom(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode); } -static int inline -vidcom(av7110_t *av7110, u32 com, u32 arg) +static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg) { DEB_EE(("av7110: %p\n",av7110)); return outcom(av7110, 0x80, 0x02, 4, @@ -2095,24 +2106,21 @@ (arg>>16), (arg&0xffff)); } -static int inline -audcom(av7110_t *av7110, u32 com) +static inline int audcom(struct av7110 *av7110, u32 com) { DEB_EE(("av7110: %p\n",av7110)); return outcom(av7110, 0x80, 0x03, 4, (com>>16), (com&0xffff)); } -inline static void -Set22K(av7110_t *av7110, int state) +static inline void Set22K(struct av7110 *av7110, int state) { DEB_EE(("av7110: %p\n",av7110)); outcom(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); } -static -int SendDiSEqCMsg(av7110_t *av7110, int len, u8 *msg, int burst) +static int SendDiSEqCMsg(struct av7110 *av7110, int len, u8 *msg, unsigned long burst) { int i; u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), @@ -2144,8 +2152,7 @@ * I2C client commands ****************************************************************************/ -static inline int -i2c_writereg(av7110_t *av7110, u8 id, u8 reg, u8 val) +static inline int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) { u8 msg[2]={ reg, val }; struct dvb_i2c_bus *i2c = av7110->i2c_bus; @@ -2158,22 +2165,7 @@ return i2c->xfer (i2c, &msgs, 1); } -static inline int -msp_writereg(av7110_t *av7110, u8 dev, u16 reg, u16 val) -{ - u8 msg[5]={ dev, reg>>8, reg&0xff, val>>8 , val&0xff }; - struct dvb_i2c_bus *i2c = av7110->i2c_bus; - struct i2c_msg msgs; - - msgs.flags=0; - msgs.addr=0x40; - msgs.len=5; - msgs.buf=msg; - return i2c->xfer(i2c, &msgs, 1); -} - -static inline u8 -i2c_readreg(av7110_t *av7110, u8 id, u8 reg) +static inline u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) { struct dvb_i2c_bus *i2c = av7110->i2c_bus; u8 mm1[] = {0x00}; @@ -2203,8 +2195,7 @@ VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, }; -static void -get_video_format(av7110_t *av7110, u8 *buf, int count) +static void get_video_format(struct av7110 *av7110, u8 *buf, int count) { int i; int hsize,vsize; @@ -2230,8 +2221,7 @@ } } -static inline long -aux_ring_buffer_write(dvb_ringbuffer_t *rbuf, const char *buf, unsigned long count) +static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, const char *buf, unsigned long count) { unsigned long todo = count; int free; @@ -2253,10 +2243,9 @@ return count-todo; } -static void -play_video_cb(u8 *buf, int count, void *priv) +static void play_video_cb(u8 *buf, int count, void *priv) { - av7110_t *av7110=(av7110_t *) priv; + struct av7110 *av7110=(struct av7110 *) priv; DEB_EE(("av7110: %p\n",av7110)); if ((buf[3]&0xe0)==0xe0) { @@ -2266,10 +2255,9 @@ aux_ring_buffer_write(&av7110->aout, buf, count); } -static void -play_audio_cb(u8 *buf, int count, void *priv) +static void play_audio_cb(u8 *buf, int count, void *priv) { - av7110_t *av7110=(av7110_t *) priv; + struct av7110 *av7110=(struct av7110 *) priv; DEB_EE(("av7110: %p\n",av7110)); aux_ring_buffer_write(&av7110->aout, buf, count); @@ -2277,8 +2265,7 @@ #define FREE_COND (dvb_ringbuffer_free(&av7110->avout)>=20*1024 && dvb_ringbuffer_free(&av7110->aout)>=20*1024) -static ssize_t -dvb_play(av7110_t *av7110, const u8 *buf, +static ssize_t dvb_play(struct av7110 *av7110, const u8 *buf, unsigned long count, int nonblock, int type, int umem) { unsigned long todo = count, n; @@ -2316,8 +2303,7 @@ return count-todo; } -static ssize_t -dvb_aplay(av7110_t *av7110, const u8 *buf, +static ssize_t dvb_aplay(struct av7110 *av7110, const u8 *buf, unsigned long count, int nonblock, int type) { unsigned long todo = count, n; @@ -2351,7 +2337,7 @@ return count-todo; } -void init_p2t(p2t_t *p, struct dvb_demux_feed *feed) +void init_p2t(struct av7110_p2t *p, struct dvb_demux_feed *feed) { memset(p->pes,0,TS_SIZE); p->counter = 0; @@ -2360,7 +2346,7 @@ if (feed) p->feed = feed; } -void clear_p2t(p2t_t *p) +void clear_p2t(struct av7110_p2t *p) { memset(p->pes,0,TS_SIZE); // p->counter = 0; @@ -2414,7 +2400,7 @@ return c; } -void pes_to_ts( u8 const *buf, long int length, u16 pid, p2t_t *p) +void pes_to_ts( u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) { int c,c2,l,add; int check,rest; @@ -2634,11 +2620,10 @@ return 0; } -static -unsigned int dvb_audio_poll(struct file *file, poll_table *wait) +static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) { struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - av7110_t *av7110 = (av7110_t *) dvbdev->priv; + struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; unsigned int mask = 0; DEB_EE(("av7110: %p\n",av7110)); @@ -2669,11 +2654,10 @@ * hardware filter functions ******************************************************************************/ -static int -StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) +static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) { struct dvb_demux_feed *dvbdmxfeed=dvbdmxfilter->feed; - av7110_t *av7110=(av7110_t *) dvbdmxfeed->demux->priv; + struct av7110 *av7110=(struct av7110 *) dvbdmxfeed->demux->priv; u16 buf[20]; int ret, i; u16 handle; @@ -2713,10 +2697,9 @@ return ret; } -static int -StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) +static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) { - av7110_t *av7110=(av7110_t *) dvbdmxfilter->feed->demux->priv; + struct av7110 *av7110=(struct av7110 *) dvbdmxfilter->feed->demux->priv; u16 buf[3]; u16 answ[2]; int ret; @@ -2749,12 +2732,11 @@ } -static int -av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) +static int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) { struct dvb_demux *demux = feed->demux; - av7110_t *av7110 = (av7110_t *) demux->priv; - ipack *ipack = &av7110->ipack[feed->pes_type]; + struct av7110 *av7110 = (struct av7110 *) demux->priv; + struct ipack *ipack = &av7110->ipack[feed->pes_type]; DEB_EE(("av7110: %p\n",av7110)); @@ -2789,11 +2771,10 @@ } -static void -dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) +static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx=dvbdmxfeed->demux; - av7110_t *av7110=(av7110_t *) dvbdmx->priv; + struct av7110 *av7110=(struct av7110 *) dvbdmx->priv; u16 *pid=dvbdmx->pids, npids[5]; int i; @@ -2809,7 +2790,7 @@ StartHWFilter(dvbdmxfeed->filter); return; } - if (dvbdmxfeed->pes_type<=2) + if (dvbdmxfeed->pes_type<=2 || dvbdmxfeed->pes_type==4) ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); if (dvbdmxfeed->pes_type<2 && npids[0]) @@ -2828,11 +2809,10 @@ } } -static void -dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) +static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *dvbdmx=dvbdmxfeed->demux; - av7110_t *av7110=(av7110_t *) dvbdmx->priv; + struct av7110 *av7110=(struct av7110 *) dvbdmx->priv; u16 *pid=dvbdmx->pids, npids[5]; int i; @@ -2866,11 +2846,10 @@ ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); } -static int -av7110_start_feed(struct dvb_demux_feed *feed) +static int av7110_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - av7110_t *av7110 = (av7110_t *) demux->priv; + struct av7110 *av7110 = (struct av7110 *) demux->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -2925,11 +2904,10 @@ } -static int -av7110_stop_feed(struct dvb_demux_feed *feed) +static int av7110_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; - av7110_t *av7110 = (av7110_t *) demux->priv; + struct av7110 *av7110 = (struct av7110 *) demux->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -2966,8 +2944,7 @@ } -static void -restart_feeds(av7110_t *av7110) +static void restart_feeds(struct av7110 *av7110) { struct dvb_demux *dvbdmx=&av7110->demux; struct dvb_demux_feed *feed; @@ -2990,14 +2967,53 @@ AV_StartPlay(av7110, mode); } +static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, + uint64_t *stc, unsigned int *base) +{ + int ret; + u16 fwstc[4]; + u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC); + struct dvb_demux *dvbdemux; + struct av7110 *av7110; + + /* pointer casting paranoia... */ + if (!demux) + BUG(); + dvbdemux = (struct dvb_demux *) demux->priv; + if (!dvbdemux) + BUG(); + av7110 = (struct av7110 *) dvbdemux->priv; + + DEB_EE(("av7110: %p\n",av7110)); + + if (num != 0) + return -EINVAL; + + ret = CommandRequest(av7110, &tag, 0, fwstc, 4); + if (ret) { + printk(KERN_ERR "%s: CommandRequest error\n", __FUNCTION__); + return -EIO; + } + DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n", + fwstc[0], fwstc[1], fwstc[2], fwstc[3])); + + *stc = (((uint64_t)fwstc[2] & 1) << 32) | + (((uint64_t)fwstc[1]) << 16) | ((uint64_t)fwstc[0]); + *base = 1; + + DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc)); + + return 0; +} + + /****************************************************************************** * SEC device file operations ******************************************************************************/ -static -int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) +static int av7110_diseqc_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg) { - av7110_t *av7110 = fe->before_after_data; + struct av7110 *av7110 = fe->before_after_data; DEB_EE(("av7110: %p\n",av7110)); @@ -3018,13 +3034,12 @@ case FE_DISEQC_SEND_MASTER_CMD: { struct dvb_diseqc_master_cmd *cmd = arg; - - SendDiSEqCMsg (av7110, cmd->msg_len, cmd->msg, 0); + SendDiSEqCMsg (av7110, cmd->msg_len, cmd->msg, -1); break; } case FE_DISEQC_SEND_BURST: - SendDiSEqCMsg (av7110, 0, NULL, (int) arg); + SendDiSEqCMsg (av7110, 0, NULL, (unsigned long)arg); break; default: @@ -3038,20 +3053,20 @@ * CI link layer file ops (FIXME: move this to separate module later) ******************************************************************************/ -int ci_ll_init(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf, int size) +int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size) { dvb_ringbuffer_init(cirbuf, vmalloc(size), size); dvb_ringbuffer_init(ciwbuf, vmalloc(size), size); return 0; } -void ci_ll_flush(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf) +void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) { dvb_ringbuffer_flush_spinlock_wakeup(cirbuf); dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf); } -void ci_ll_release(dvb_ringbuffer_t *cirbuf, dvb_ringbuffer_t *ciwbuf) +void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) { vfree(cirbuf->data); cirbuf->data=0; @@ -3060,7 +3075,7 @@ } -int ci_ll_reset(dvb_ringbuffer_t *cibuf, struct file *file, +int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, int slots, ca_slot_info_t *slot) { int i; @@ -3086,8 +3101,7 @@ return 0; } -static ssize_t -ci_ll_write(dvb_ringbuffer_t *cibuf, struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, const char *buf, size_t count, loff_t *ppos) { int free; int non_blocking=file->f_flags&O_NONBLOCK; @@ -3109,8 +3123,7 @@ return dvb_ringbuffer_write(cibuf,buf,count,1); } -static ssize_t -ci_ll_read(dvb_ringbuffer_t *cibuf, struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, char *buf, size_t count, loff_t *ppos) { int avail; int non_blocking=file->f_flags&O_NONBLOCK; @@ -3135,11 +3148,10 @@ return dvb_ringbuffer_read(cibuf,buf,len,1); } -static int -dvb_ca_open(struct inode *inode, struct file *file) +static int dvb_ca_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; int err=dvb_generic_open(inode, file); DEB_EE(("av7110: %p\n",av7110)); @@ -3150,13 +3162,12 @@ return 0; } -static -unsigned int dvb_ca_poll (struct file *file, poll_table *wait) +static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) { struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - av7110_t *av7110 = (av7110_t *) dvbdev->priv; - dvb_ringbuffer_t *rbuf = &av7110->ci_rbuffer; - dvb_ringbuffer_t *wbuf = &av7110->ci_wbuffer; + struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; + struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer; + struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer; unsigned int mask = 0; DEB_EE(("av7110: %p\n",av7110)); @@ -3172,12 +3183,11 @@ return mask; } -static -int dvb_ca_ioctl(struct inode *inode, struct file *file, +static int dvb_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; unsigned long arg=(unsigned long) parg; DEB_EE(("av7110: %p\n",av7110)); @@ -3196,7 +3206,7 @@ cap.slot_num=2; #ifdef NEW_CI - cap.slot_type=CA_CI_LINK|CA_DESCR; + cap.slot_type=(FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI) | CA_DESCR; #else cap.slot_type=CA_CI|CA_DESCR; #endif @@ -3214,7 +3224,7 @@ return -EINVAL; av7110->ci_slot[info->num].num = info->num; #ifdef NEW_CI - av7110->ci_slot[info->num].type = CA_CI_LINK; + av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? CA_CI_LINK : CA_CI; #else av7110->ci_slot[info->num].type = CA_CI; #endif @@ -3261,22 +3271,20 @@ return 0; } -static ssize_t -dvb_ca_write(struct file *file, const char *buf, +static ssize_t dvb_ca_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos); } -static ssize_t -dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos) +static ssize_t dvb_ca_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); @@ -3285,35 +3293,103 @@ /****************************************************************************** + * Video MPEG decoder events + ******************************************************************************/ +static void dvb_video_add_event (struct av7110 *av7110, struct video_event *event) +{ + struct dvb_video_events *events = &av7110->video_events; + int wp; + + DEB_D(("\n")); + + spin_lock_bh(&events->lock); + + wp = (events->eventw + 1) % MAX_VIDEO_EVENT; + + if (wp == events->eventr) { + events->overflow = 1; + events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; + } + + //FIXME: timestamp? + memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); + + events->eventw = wp; + + spin_unlock_bh(&events->lock); + + wake_up_interruptible (&events->wait_queue); +} + + +static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) +{ + struct dvb_video_events *events = &av7110->video_events; + + DEB_D(("\n")); + + if (events->overflow) { + events->overflow = 0; + return -EOVERFLOW; + } + + if (events->eventw == events->eventr) { + int ret; + + if (flags & O_NONBLOCK) + return -EWOULDBLOCK; + + ret = wait_event_interruptible (events->wait_queue, + events->eventw != events->eventr); + if (ret < 0) + return ret; + } + + spin_lock_bh(&events->lock); + + memcpy (event, &events->events[events->eventr], + sizeof(struct video_event)); + + events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; + + spin_unlock_bh(&events->lock); + + return 0; +} + + +/****************************************************************************** * DVB device file operations ******************************************************************************/ -static -unsigned int dvb_video_poll(struct file *file, poll_table *wait) +static unsigned int dvb_video_poll(struct file *file, poll_table *wait) { struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; - av7110_t *av7110 = (av7110_t *) dvbdev->priv; + struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; unsigned int mask = 0; DEB_EE(("av7110: %p\n",av7110)); poll_wait(file, &av7110->avout.queue, wait); + poll_wait(file, &av7110->video_events.wait_queue, wait); + + if (av7110->video_events.eventw != av7110->video_events.eventr) + mask = POLLPRI; if (av7110->playing) { if (FREE_COND) mask |= (POLLOUT | POLLWRNORM); } else /* if not playing: may play if asked for */ - mask = (POLLOUT | POLLWRNORM); + mask |= (POLLOUT | POLLWRNORM); return mask; } -static ssize_t -dvb_video_write(struct file *file, const char *buf, +static ssize_t dvb_video_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -3323,12 +3399,11 @@ return dvb_play(av7110, buf, count, file->f_flags&O_NONBLOCK, 1, 1); } -static ssize_t -dvb_audio_write(struct file *file, const char *buf, +static ssize_t dvb_audio_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -3343,33 +3418,34 @@ #define MIN_IFRAME 400000 -static void -play_iframe(av7110_t *av7110, u8 *buf, unsigned int len, int nonblock) +static int play_iframe(struct av7110 *av7110, u8 *buf, unsigned int len, int nonblock) { int i, n=1; DEB_EE(("av7110: %p\n",av7110)); if (!(av7110->playing&RP_VIDEO)) { - AV_StartPlay(av7110, RP_VIDEO); + if (AV_StartPlay(av7110, RP_VIDEO) < 0) + return -EBUSY; n=MIN_IFRAME/len+1; } + /* FIXME: nonblock? */ dvb_play(av7110, iframe_header, sizeof(iframe_header), 0, 1, 0); for (i=0; i<n; i++) dvb_play(av7110, buf, len, 0, 1, 1); av7110_ipack_flush(&av7110->ipack[1]); + return 0; } -static int -dvb_video_ioctl(struct inode *inode, struct file *file, +static int dvb_video_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; unsigned long arg=(unsigned long) parg; int ret=0; @@ -3441,8 +3517,12 @@ break; case VIDEO_GET_EVENT: - //FIXME: write firmware support for this - ret=-EOPNOTSUPP; + ret=dvb_video_get_event(av7110, parg, file->f_flags); + break; + + case VIDEO_GET_SIZE: + memcpy(parg, &av7110->video_size, sizeof(video_size_t)); + break; case VIDEO_SET_DISPLAY_FORMAT: { @@ -3488,8 +3568,9 @@ { struct video_still_picture *pic= (struct video_still_picture *) parg; + av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - play_iframe(av7110, pic->iFrame, pic->size, + ret = play_iframe(av7110, pic->iFrame, pic->size, file->f_flags&O_NONBLOCK); break; } @@ -3555,12 +3636,11 @@ return ret; } -static int -dvb_audio_ioctl(struct inode *inode, struct file *file, +static int dvb_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; unsigned long arg=(unsigned long) parg; int ret=0; @@ -3680,7 +3760,7 @@ static int dvb_video_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; int err; DEB_EE(("av7110: %p\n",av7110)); @@ -3692,13 +3772,18 @@ av7110->video_blank=1; av7110->audiostate.AV_sync_state=1; av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX; + + if ((file->f_flags & O_ACCMODE) != O_RDONLY) + /* empty event queue */ + av7110->video_events.eventr = av7110->video_events.eventw = 0; + return 0; } static int dvb_video_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -3709,7 +3794,7 @@ static int dvb_audio_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; int err=dvb_generic_open(inode, file); DEB_EE(("av7110: %p\n",av7110)); @@ -3724,7 +3809,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file) { struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; - av7110_t *av7110=(av7110_t *) dvbdev->priv; + struct av7110 *av7110=(struct av7110 *) dvbdev->priv; DEB_EE(("av7110: %p\n",av7110)); @@ -3791,10 +3876,9 @@ }; -static -void av7110_before_after_tune (fe_status_t s, void *data) +static void av7110_before_after_tune (fe_status_t s, void *data) { - struct av7110_s *av7110 = data; + struct av7110 *av7110 = data; DEB_EE(("av7110: %p\n",av7110)); @@ -3819,11 +3903,9 @@ } -static -int av7110_register(av7110_t *av7110) +static int av7110_register(struct av7110 *av7110) { int ret, i; - dmx_frontend_t *dvbfront=&av7110->hw_frontend; struct dvb_demux *dvbdemux=&av7110->demux; DEB_EE(("av7110: %p\n",av7110)); @@ -3856,8 +3938,6 @@ av7110->videostate.display_format=VIDEO_CENTER_CUT_OUT; av7110->display_ar=VIDEO_FORMAT_4_3; - memcpy(av7110->demux_id, "demux0_0", 9); - av7110->demux_id[5] = av7110->dvb_adapter->num + '0'; dvbdemux->priv = (void *) av7110; for (i=0; i<32; i++) @@ -3868,18 +3948,11 @@ dvbdemux->start_feed = av7110_start_feed; dvbdemux->stop_feed = av7110_stop_feed; dvbdemux->write_to_decoder = av7110_write_to_decoder; - dvbdemux->dmx.vendor = "TI"; - dvbdemux->dmx.model = "AV7110"; - dvbdemux->dmx.id = av7110->demux_id; dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); dvb_dmx_init(&av7110->demux); - - dvbfront->id = "hw_frontend"; - dvbfront->vendor = "VLSI"; - dvbfront->model = "DVB Frontend"; - dvbfront->source = DMX_FRONTEND_0; + av7110->demux.dmx.get_stc = dvb_get_stc; av7110->dmxdev.filternum = 32; av7110->dmxdev.demux = &dvbdemux->dmx; @@ -3887,14 +3960,13 @@ dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter); - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, - &av7110->hw_frontend); + av7110->hw_frontend.source = DMX_FRONTEND_0; + + ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend); + if (ret < 0) return ret; - av7110->mem_frontend.id = "mem_frontend"; - av7110->mem_frontend.vendor = "memory"; - av7110->mem_frontend.model = "sw"; av7110->mem_frontend.source = DMX_MEMORY_FE; ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend); @@ -3907,6 +3979,12 @@ if (ret < 0) return ret; + init_waitqueue_head(&av7110->video_events.wait_queue); + spin_lock_init(&av7110->video_events.lock); + av7110->video_events.eventw = av7110->video_events.eventr = 0; + av7110->video_events.overflow = 0; + memset(&av7110->video_size, 0, sizeof (video_size_t)); + dvb_register_device(av7110->dvb_adapter, &av7110->video_dev, &dvbdev_video, av7110, DVB_DEVICE_VIDEO); @@ -3935,8 +4013,7 @@ } -static void -dvb_unregister(av7110_t *av7110) +static void dvb_unregister(struct av7110 *av7110) { struct dvb_demux *dvbdemux=&av7110->demux; @@ -3970,8 +4047,7 @@ // } } -static -int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) +static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) { struct saa7146_dev *dev = i2c->data; return saa7146_i2c_transfer(dev, msgs, num, 6); @@ -3988,21 +4064,20 @@ { 0, 0 } }; -static -int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) +static int av7110_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) { - av7110_t *av7110 = NULL; + struct av7110 *av7110 = NULL; int ret = 0; - if (!(av7110 = kmalloc (sizeof (struct av7110_s), GFP_KERNEL))) { + if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) { printk ("%s: out of memory!\n", __FUNCTION__); return -ENOMEM; } - memset(av7110, 0, sizeof(av7110_t)); + memset(av7110, 0, sizeof(struct av7110)); av7110->card_name = (char*)pci_ext->ext_priv; - (av7110_t*)dev->ext_priv = av7110; + (struct av7110*)dev->ext_priv = av7110; DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); @@ -4062,9 +4137,6 @@ av7110->debilock=SPIN_LOCK_UNLOCKED; av7110->debitype=-1; - /* default ADAC type */ - av7110->adac_type = adac; - /* default OSD window */ av7110->osdwin=1; @@ -4120,30 +4192,32 @@ kernel_thread(arm_thread, (void *) av7110, 0); + /* set internal volume control to maximum */ + av7110->adac_type = DVB_ADAC_TI; SetVolume(av7110, 0xff, 0xff); + VidMode(av7110, vidmode); /* remaining inits according to card and frontend type */ if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) { - printk ("av7110%d: Crystal audio DAC detected\n", + printk ("av7110(%d): Crystal audio DAC detected\n", av7110->dvb_adapter->num); av7110->adac_type = DVB_ADAC_CRYSTAL; i2c_writereg(av7110, 0x20, 0x01, 0xd2); i2c_writereg(av7110, 0x20, 0x02, 0x49); i2c_writereg(av7110, 0x20, 0x03, 0x00); i2c_writereg(av7110, 0x20, 0x04, 0x00); - } - /** - * some special handling for the Siemens DVB-C card... + * some special handling for the Siemens DVB-C cards... */ - if (dev->pci->subsystem_vendor == 0x110a) { - if (i2c_writereg(av7110, 0x80, 0x0, 0x80)==1) { + } else if (i2c_writereg(av7110, 0x80, 0x0, 0x80)==1) { i2c_writereg(av7110, 0x80, 0x0, 0); - printk ("av7110: DVB-C analog module detected, " - "initializing MSP3400\n"); - ddelay(10); + printk ("av7110(%d): DVB-C analog module detected, " + "initializing MSP3400\n", + av7110->dvb_adapter->num); + av7110->adac_type = DVB_ADAC_MSP; + dvb_delay(100); msp_writereg(av7110, 0x12, 0x0013, 0x0c00); msp_writereg(av7110, 0x12, 0x0000, 0x7f00); // loudspeaker + headphone msp_writereg(av7110, 0x12, 0x0008, 0x0220); // loudspeaker source @@ -4151,17 +4225,26 @@ msp_writereg(av7110, 0x12, 0x000a, 0x0220); // SCART 1 source msp_writereg(av7110, 0x12, 0x0007, 0x7f00); // SCART 1 volume msp_writereg(av7110, 0x12, 0x000d, 0x4800); // prescale SCART + } else if (dev->pci->subsystem_vendor == 0x110a) { + printk("av7110(%d): DVB-C w/o analog module detected\n", + av7110->dvb_adapter->num); + av7110->adac_type = DVB_ADAC_NONE; + } else { + av7110->adac_type = adac; + printk("av7110(%d): adac type set to %d\n", + av7110->dvb_adapter->num, av7110->adac_type); } - + if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { // switch DVB SCART on outcom(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); outcom(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); //saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 - av7110->adac_type = DVB_ADAC_NONE; } + SetVolume(av7110, 0xff, 0xff); + av7110_setup_irc_config (av7110, 0); av7110_register(av7110); @@ -4185,10 +4268,9 @@ return ret; } -static -int av7110_detach (struct saa7146_dev* saa) +static int av7110_detach (struct saa7146_dev* saa) { - av7110_t *av7110 = (av7110_t*)saa->ext_priv; + struct av7110 *av7110 = (struct av7110*)saa->ext_priv; DEB_EE(("av7110: %p\n",av7110)); saa7146_unregister_device(&av7110->vd, saa); @@ -4197,7 +4279,7 @@ wake_up_interruptible(&av7110->arm_wait); while (av7110->arm_thread) - ddelay(1); + dvb_delay(1); dvb_unregister(av7110); @@ -4226,10 +4308,9 @@ } -static -void av7110_irq(struct saa7146_dev* dev, u32 *isr) +static void av7110_irq(struct saa7146_dev* dev, u32 *isr) { - av7110_t *av7110 = (av7110_t*)dev->ext_priv; + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; DEB_EE(("dev: %p, av7110: %p\n",dev,av7110)); @@ -4243,15 +4324,13 @@ /* FIXME: these values are experimental values that look better than the values from the latest "official" driver -- at least for me... (MiHu) */ -static -struct saa7146_standard standard[] = { +static struct saa7146_standard standard[] = { { "PAL", V4L2_STD_PAL, 0x15, 288, 576, 0x4a, 708, 709, 576, 768 }, // { "PAL", V4L2_STD_PAL, 0x15, 288, 576, 0x3a, 720, 721, 576, 768 }, { "NTSC", V4L2_STD_NTSC, 0x10, 244, 480, 0x40, 708, 709, 480, 640 }, }; -static -struct saa7146_extension av7110_extension; +static struct saa7146_extension av7110_extension; #define MAKE_AV7110_INFO(x_var,x_name) \ static struct saa7146_pci_extension_data x_var = { \ @@ -4268,8 +4347,7 @@ MAKE_AV7110_INFO(unkwn2, "Technotrend/Hauppauge PCI rev?(unknown2)?"); MAKE_AV7110_INFO(nexus, "Technotrend/Hauppauge Nexus PCI DVB-S"); -static -struct pci_device_id pci_tbl[] = { +static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0xffff), MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0x0000), MAKE_EXTENSION_PCI(fs_1_3, 0x13c2, 0x0000), @@ -4280,6 +4358,7 @@ MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0004), MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0006), MAKE_EXTENSION_PCI(tt_t, 0x13c2, 0x0008), + MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x1102), MAKE_EXTENSION_PCI(unkwn1, 0xffc2, 0x0000), MAKE_EXTENSION_PCI(unkwn2, 0x00a1, 0x00a1), MAKE_EXTENSION_PCI(nexus, 0x00a1, 0xa1a0), @@ -4288,9 +4367,11 @@ } }; +MODULE_DEVICE_TABLE(pci, pci_tbl); + static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) { - av7110_t *av7110 = (av7110_t*)dev->ext_priv; + struct av7110 *av7110 = (struct av7110*)dev->ext_priv; if (std->id == V4L2_STD_PAL) { av7110->vidmode = VIDEO_MODE_PAL; SetMode(av7110, av7110->vidmode); @@ -4306,8 +4387,7 @@ } -static -struct saa7146_ext_vv av7110_vv_data = { +static struct saa7146_ext_vv av7110_vv_data = { .inputs = 1, .audios = 1, .capabilities = 0, @@ -4321,8 +4401,7 @@ .ioctl = av7110_ioctl, }; -static -struct saa7146_extension av7110_extension = { +static struct saa7146_extension av7110_extension = { .name = "dvb\0", .ext_vv_data = &av7110_vv_data, @@ -4336,8 +4415,7 @@ }; -static -int __init av7110_init(void) +static int __init av7110_init(void) { if (saa7146_register_extension(&av7110_extension)) return -ENODEV; @@ -4348,8 +4426,7 @@ } -static -void __exit av7110_exit(void) +static void __exit av7110_exit(void) { av7110_ir_exit(); saa7146_unregister_extension(&av7110_extension); diff -Nru a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h --- a/drivers/media/dvb/ttpci/av7110.h Fri Jun 27 14:19:52 2003 +++ b/drivers/media/dvb/ttpci/av7110.h Fri Jun 27 14:19:52 2003 @@ -40,39 +40,32 @@ #include "dvb_net.h" #include "dvb_ringbuffer.h" -typedef enum BOOTSTATES +enum av7110_bootstate { BOOTSTATE_BUFFER_EMPTY = 0, BOOTSTATE_BUFFER_FULL = 1, BOOTSTATE_BOOT_COMPLETE = 2 -} BOOTSTATES; +}; -typedef enum +enum av7110_type_rec_play_format { RP_None, AudioPES, AudioMp2, AudioPCM, VideoPES, AV_PES -} TYPE_REC_PLAY_FORMAT; - -typedef struct PARAMSTRUCT -{ - unsigned int wCommand; - int error; - unsigned long pdwData[100]; -} PARAMSTRUCT, *PPARAMSTRUCT; +}; -typedef enum OSDPALTYPE +enum av7110_osd_palette_type { NoPalet = 0, /* No palette */ Pal1Bit = 2, /* 2 colors for 1 Bit Palette */ Pal2Bit = 4, /* 4 colors for 2 bit palette */ Pal4Bit = 16, /* 16 colors for 4 bit palette */ Pal8Bit = 256 /* 256 colors for 16 bit palette */ -} OSDPALTYPE, *POSDPALTYPE; +}; -typedef enum { +enum av7110_window_display_type { BITMAP1, /* 1 bit bitmap */ BITMAP2, /* 2 bit bitmap */ BITMAP4, /* 4 bit bitmap */ @@ -93,9 +86,9 @@ VIDEOTDSIZE, /* True Size MPEG Video Display Double Resolution */ VIDEONSIZE, /* Full Size MPEG Video Display */ CURSOR /* Cursor */ -} DISPTYPE; /* Window display type */ +}; -// switch defines +/* switch defines */ #define SB_GPIO 3 #define SB_OFF SAA7146_GPIO_OUTLO //SlowBlank aus (TV-Mode) #define SB_ON SAA7146_GPIO_INPUT //SlowBlank an (AV-Mode) @@ -106,14 +99,13 @@ #define FB_ON SAA7146_GPIO_OUTHI //FastBlank an (RGB-Mode) #define FB_LOOP SAA7146_GPIO_INPUT //FastBlank der PC-Grafik durchschleifen -typedef enum VIDEOOUTPUTMODE +enum av7110_video_output_mode { NO_OUT = 0, //disable analog Output CVBS_RGB_OUT = 1, CVBS_YC_OUT = 2, YC_OUT = 3 -} VIDEOOUTPUTMODE, *PVIDEOOUTPUTMODE; - +}; #define GPMQFull 0x0001 //Main Message Queue Full #define GPMQOver 0x0002 //Main Message Queue Overflow @@ -127,9 +119,9 @@ #define SECTION_CYCLE 0x02 #define SECTION_CONTINUOS 0x04 #define SECTION_MODE 0x06 -#define SECTION_IPMPE 0x0C // bis zu 4k gro_ -#define SECTION_HIGH_SPEED 0x1C // vergrv_erter Puffer f|r High Speed Filter -#define DATA_PIPING_FLAG 0x20 // f|r Data Piping Filter +#define SECTION_IPMPE 0x0C // bis zu 4k groß +#define SECTION_HIGH_SPEED 0x1C // vergrößerter Puffer für High Speed Filter +#define DATA_PIPING_FLAG 0x20 // für Data Piping Filter #define PBUFSIZE_NONE 0x0000 #define PBUFSIZE_1P 0x0100 @@ -141,7 +133,7 @@ #define PBUFSIZE_16K 0x0700 #define PBUFSIZE_32K 0x0800 -typedef enum { +enum av7110_osd_command { WCreate, WDestroy, WMoveD, @@ -162,9 +154,9 @@ ReleaseBmp, SetWTrans, SetWNoTrans -} OSDCOM; +}; -typedef enum { +enum av7110_pid_command { MultiPID, VideoPID, AudioPID, @@ -177,13 +169,13 @@ Scan, SetDescr, SetIR -} PIDCOM; +}; -typedef enum { +enum av7110_mpeg_command { SelAudChannels -} MPEGCOM; +}; -typedef enum { +enum av7110_audio_command { AudioDAC, CabADAC, ON22K, @@ -192,9 +184,9 @@ ADSwitch, SendDiSEqC, SetRegister -} AUDCOM; +}; -typedef enum { +enum av7110_request_command { AudioState, AudioBuffState, VideoState1, @@ -203,19 +195,21 @@ CrashCounter, ReqVersion, ReqVCXO, - ReqRegister -} REQCOM; + ReqRegister, + ReqSecFilterError, + ReqSTC +}; -typedef enum { +enum av7110_encoder_command { SetVidMode, SetTestMode, LoadVidCode, SetMonitorType, SetPanScanType, SetFreezeMode -} ENC; +}; -typedef enum { +enum av7110_rec_play_state { __Record, __Stop, __Play, @@ -224,9 +218,9 @@ __FF_IP, __Scan_I, __Continue -} REC_PLAY; +}; -typedef enum { +enum av7110_command_type { COMTYPE_NOCOM, COMTYPE_PIDFILTER, COMTYPE_MPEGDECODER, @@ -244,17 +238,7 @@ COMTYPE_VIDEO, COMTYPE_AUDIO, COMTYPE_CI_LL, -} COMTYPE; - -typedef enum { - AV7110_VIDEO_FREEZE, - AV7110_VIDEO_CONTINUE -} VIDEOCOM; - -typedef enum { - DVB_AUDIO_PAUSE, -} AUDIOCOM; - +}; #define VID_NONE_PREF 0x00 /* No aspect ration processing preferred */ #define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */ @@ -275,6 +259,7 @@ #define DATA_STREAMING 0x0a #define DATA_CI_GET 0x0b #define DATA_CI_PUT 0x0c +#define DATA_MPEG_VIDEO_EVENT 0x0d #define DATA_PES_RECORD 0x10 #define DATA_PES_PLAY 0x11 @@ -364,14 +349,6 @@ #define MAX_PLENGTH 0xFFFF #define MAX_VID_PES 0x1FFF -typedef struct section_s { - int id; - int length; - int found; - u8 payload[4096+3]; -} section_t; - - #define MY_STATE_PES_START 1 #define MY_STATE_PES_STARTED 2 #define MY_STATE_FULL 4 @@ -393,64 +370,34 @@ enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM}; -typedef struct ps_packet_s{ - u8 scr[6]; - u8 mux_rate[3]; - u8 stuff_length; - u8 data[20]; - u8 sheader_llength[2]; - int sheader_length; - u8 rate_bound[3]; - u8 audio_bound; - u8 video_bound; - u8 reserved; - int npes; - int mpeg; -} ps_packet_t; - -typedef struct a2p_s{ - int type; - int found; - int length; - int headr; - u8 cid; - u8 flags; - u8 abuf[MAX_PLENGTH]; - int alength; - u8 vbuf[MAX_PLENGTH]; - int vlength; - int plength; - u8 last_av_pts[4]; - u8 av_pts[4]; - u8 scr[4]; - u16 count0; - u16 count1; - u16 pidv; - u16 pida; - u16 countv; - u16 counta; - void *dataA; - void *dataV; - void (*write_cb)(u8 const *buf, long int count, - void *data); -} a2p_t; - - -typedef struct p2t_s { +struct av7110_p2t { u8 pes[TS_SIZE]; u8 counter; long int pos; int frags; struct dvb_demux_feed *feed; -} p2t_t; +}; + +/* video MPEG decoder events: */ +/* (code copied from dvb_frontend.c, should maybe be factored out...) */ +#define MAX_VIDEO_EVENT 8 +struct dvb_video_events { + struct video_event events[MAX_VIDEO_EVENT]; + int eventw; + int eventr; + int overflow; + wait_queue_head_t wait_queue; + spinlock_t lock; +}; + /* place to store all the necessary device information */ -typedef struct av7110_s { +struct av7110 { /* devices */ struct dvb_device dvb_dev; - dvb_net_t dvb_net; + struct dvb_net dvb_net; struct video_device vd; struct saa7146_dev *dev; @@ -464,15 +411,16 @@ int adac_type; /* audio DAC type */ #define DVB_ADAC_TI 0 #define DVB_ADAC_CRYSTAL 1 +#define DVB_ADAC_MSP 2 #define DVB_ADAC_NONE -1 /* buffers */ void *iobuf; /* memory for all buffers */ - dvb_ringbuffer_t avout; /* buffer for video or A/V mux */ + struct dvb_ringbuffer avout; /* buffer for video or A/V mux */ #define AVOUTLEN (128*1024) - dvb_ringbuffer_t aout; /* buffer for audio */ + struct dvb_ringbuffer aout; /* buffer for audio */ #define AOUTLEN (64*1024) void *bmpbuf; #define BMPLEN (8*32768+1024) @@ -522,12 +470,11 @@ ca_slot_info_t ci_slot[2]; int vidmode; - dmxdev_t dmxdev; + struct dmxdev dmxdev; struct dvb_demux demux; - char demux_id[16]; - dmx_frontend_t hw_frontend; - dmx_frontend_t mem_frontend; + struct dmx_frontend hw_frontend; + struct dmx_frontend mem_frontend; int fe_synced; struct semaphore pid_mutex; @@ -543,9 +490,9 @@ struct audio_status audiostate; struct dvb_demux_filter *handle2filter[32]; - p2t_t p2t_filter[MAXFILT]; - dvb_filter_pes2ts_t p2t[2]; - struct ipack_s ipack[2]; + struct av7110_p2t p2t_filter[MAXFILT]; + struct dvb_filter_pes2ts p2t[2]; + struct ipack ipack[2]; u8 *kbuf[2]; int sinfo; @@ -573,8 +520,8 @@ u16 pids[DMX_PES_OTHER]; - dvb_ringbuffer_t ci_rbuffer; - dvb_ringbuffer_t ci_wbuffer; + struct dvb_ringbuffer ci_rbuffer; + struct dvb_ringbuffer ci_wbuffer; struct dvb_adapter *dvb_adapter; @@ -583,8 +530,13 @@ struct dvb_device *ca_dev; struct dvb_device *osd_dev; + struct dvb_video_events video_events; + video_size_t video_size; + int dsp_dev; -} av7110_t; + + u32 ir_config; +}; #define DPRAM_BASE 0x4000 @@ -623,26 +575,15 @@ #define Reserved (DPRAM_BASE + 0x1E00) #define Reserved_SIZE 0x1C0 -#define DEBUG_WINDOW (DPRAM_BASE + 0x1FC0) -#define DBG_LOOP_CNT (DEBUG_WINDOW + 0x00) -#define DBG_SEC_CNT (DEBUG_WINDOW + 0x02) -#define DBG_AVRP_BUFF (DEBUG_WINDOW + 0x04) -#define DBG_AVRP_PEAK (DEBUG_WINDOW + 0x06) -#define DBG_MSG_CNT (DEBUG_WINDOW + 0x08) -#define DBG_CODE_REG (DEBUG_WINDOW + 0x0a) -#define DBG_TTX_Q (DEBUG_WINDOW + 0x0c) -#define DBG_AUD_EN (DEBUG_WINDOW + 0x0e) -#define DBG_WRONG_COM (DEBUG_WINDOW + 0x10) -#define DBG_ARR_OVFL (DEBUG_WINDOW + 0x12) -#define DBG_BUFF_OVFL (DEBUG_WINDOW + 0x14) -#define DBG_OVFL_CNT (DEBUG_WINDOW + 0x16) -#define DBG_SEC_OVFL (DEBUG_WINDOW + 0x18) - #define STATUS_BASE (DPRAM_BASE + 0x1FC0) #define STATUS_SCR (STATUS_BASE + 0x00) #define STATUS_MODES (STATUS_BASE + 0x04) #define STATUS_LOOPS (STATUS_BASE + 0x08) +#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C) +/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */ +#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E) + #define RX_TYPE (DPRAM_BASE + 0x1FE8) #define RX_LEN (DPRAM_BASE + 0x1FEA) #define TX_TYPE (DPRAM_BASE + 0x1FEC) @@ -673,7 +614,7 @@ extern void av7110_register_irc_handler(void (*func)(u32)); extern void av7110_unregister_irc_handler(void (*func)(u32)); -extern void av7110_setup_irc_config (av7110_t *av7110, u32 ir_config); +extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config); extern int av7110_ir_init (void); extern void av7110_ir_exit (void); diff -Nru a/drivers/media/dvb/ttpci/av7110_firm.h b/drivers/media/dvb/ttpci/av7110_firm.h --- a/drivers/media/dvb/ttpci/av7110_firm.h Fri Jun 27 14:19:52 2003 +++ b/drivers/media/dvb/ttpci/av7110_firm.h Fri Jun 27 14:19:52 2003 @@ -1,5 +1,5 @@ -#include <asm/types.h> +#include <linux/types.h> u8 Dpram [] __initdata = { 0xe5, 0x9f, 0xf0, 0x1c, 0xe1, 0xb0, 0xf0, 0x0e, diff -Nru a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c --- a/drivers/media/dvb/ttpci/av7110_ipack.c Fri Jun 27 14:19:55 2003 +++ b/drivers/media/dvb/ttpci/av7110_ipack.c Fri Jun 27 14:19:55 2003 @@ -1,9 +1,10 @@ #include "dvb_filter.h" #include "av7110_ipack.h" #include <linux/string.h> /* for memcpy() */ +#include <linux/vmalloc.h> -void av7110_ipack_reset(ipack *p) +void av7110_ipack_reset(struct ipack *p) { p->found = 0; p->cid = 0; @@ -19,7 +20,7 @@ } -void av7110_ipack_init(ipack *p, int size, +void av7110_ipack_init(struct ipack *p, int size, void (*func)(u8 *buf, int size, void *priv)) { if ( !(p->buf = vmalloc(size*sizeof(u8))) ){ @@ -32,17 +33,17 @@ } -void av7110_ipack_free(ipack * p) +void av7110_ipack_free(struct ipack * p) { - if (p->buf) vfree(p->buf); + if (p->buf) + vfree(p->buf); } -static -void send_ipack(ipack *p) +static void send_ipack(struct ipack *p) { int off; - AudioInfo ai; + struct dvb_audio_info ai; int ac3_off = 0; int streamid=0; int nframes= 0; @@ -109,7 +110,7 @@ } -void av7110_ipack_flush(ipack *p) +void av7110_ipack_flush(struct ipack *p) { if (p->plength != MMAX_PLENGTH-6 || p->found<=6) return; @@ -120,8 +121,7 @@ } -static -void write_ipack(ipack *p, const u8 *data, int count) +static void write_ipack(struct ipack *p, const u8 *data, int count) { u8 headr[3] = { 0x00, 0x00, 0x01} ; @@ -144,7 +144,7 @@ } -int av7110_ipack_instant_repack (const u8 *buf, int count, ipack *p) +int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p) { int l; int c=0; diff -Nru a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/dvb/ttpci/av7110_ipack.h --- a/drivers/media/dvb/ttpci/av7110_ipack.h Fri Jun 27 14:19:52 2003 +++ b/drivers/media/dvb/ttpci/av7110_ipack.h Fri Jun 27 14:19:52 2003 @@ -1,13 +1,13 @@ #ifndef _AV7110_IPACK_H_ #define _AV7110_IPACK_H_ -extern void av7110_ipack_init(ipack *p, int size, +extern void av7110_ipack_init(struct ipack *p, int size, void (*func)(u8 *buf, int size, void *priv)); -extern void av7110_ipack_reset(ipack *p); -extern int av7110_ipack_instant_repack(const u8 *buf, int count, ipack *p); -extern void av7110_ipack_free(ipack * p); -extern void av7110_ipack_flush(ipack *p); +extern void av7110_ipack_reset(struct ipack *p); +extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p); +extern void av7110_ipack_free(struct ipack * p); +extern void av7110_ipack_flush(struct ipack *p); #endif diff -Nru a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c --- a/drivers/media/dvb/ttpci/av7110_ir.c Fri Jun 27 14:19:54 2003 +++ b/drivers/media/dvb/ttpci/av7110_ir.c Fri Jun 27 14:19:54 2003 @@ -1,18 +1,13 @@ -#include <asm/types.h> -#include <asm/bitops.h> +#include <linux/types.h> #include <linux/init.h> #include <linux/module.h> #include <linux/input.h> #include <linux/proc_fs.h> +#include <asm/bitops.h> #include "av7110.h" -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include "input_fake.h" -#endif - - -#define UP_TIMEOUT (HZ/2) +#define UP_TIMEOUT (HZ/4) static int av7110_ir_debug = 0; @@ -21,11 +16,11 @@ static struct input_dev input_dev; +static u32 ir_config; -static -u16 key_map [256] = { +static u16 key_map [256] = { KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, - KEY_8, KEY_9, KEY_MHP, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, + KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -47,8 +42,7 @@ }; -static -void av7110_emit_keyup (unsigned long data) +static void av7110_emit_keyup (unsigned long data) { if (!data || !test_bit (data, input_dev.key)) return; @@ -57,43 +51,69 @@ } -static -struct timer_list keyup_timer = { function: av7110_emit_keyup }; +static struct timer_list keyup_timer = { function: av7110_emit_keyup }; -static -void av7110_emit_key (u32 ircom) +static void av7110_emit_key (u32 ircom) { - int down = ircom & (0x80000000); - u16 keycode = key_map[ircom & 0xff]; + u8 data; + u8 addr; + static u16 old_toggle = 0; + u16 new_toggle; + u16 keycode; + + /* extract device address and data */ + if (ir_config & 0x0001) { + /* TODO RCMM: ? bits device address, 8 bits data */ + data = ircom & 0xff; + addr = (ircom >> 8) & 0xff; + } else { + /* RC5: 5 bits device address, 6 bits data */ + data = ircom & 0x3f; + addr = (ircom >> 6) & 0x1f; + } - dprintk ("#########%08x######### key %02x %s (keycode %i)\n", - ircom, ircom & 0xff, down ? "pressed" : "released", keycode); + keycode = key_map[data]; + + dprintk ("#########%08x######### addr %i data 0x%02x (keycode %i)\n", + ircom, addr, data, keycode); + + /* check device address (if selected) */ + if (ir_config & 0x4000) + if (addr != ((ir_config >> 16) & 0xff)) + return; if (!keycode) { printk ("%s: unknown key 0x%02x!!\n", - __FUNCTION__, ircom & 0xff); + __FUNCTION__, data); return; } + if (ir_config & 0x0001) + new_toggle = 0; /* RCMM */ + else + new_toggle = (ircom & 0x800); /* RC5 */ + if (timer_pending (&keyup_timer)) { del_timer (&keyup_timer); - if (keyup_timer.data != keycode) + if (keyup_timer.data != keycode || new_toggle != old_toggle) { input_event (&input_dev, EV_KEY, keyup_timer.data, !!0); - } - - clear_bit (keycode, input_dev.key); + input_event (&input_dev, EV_KEY, keycode, !0); + } else + input_event (&input_dev, EV_KEY, keycode, 2); + } else input_event (&input_dev, EV_KEY, keycode, !0); keyup_timer.expires = jiffies + UP_TIMEOUT; keyup_timer.data = keycode; add_timer (&keyup_timer); + + old_toggle = new_toggle; } -static -void input_register_keys (void) +static void input_register_keys (void) { int i; @@ -108,17 +128,35 @@ } -static -int av7110_ir_write_proc (struct file *file, const char *buffer, +static void input_repeat_key(unsigned long data) +{ + /* dummy routine to disable autorepeat in the input driver */ +} + + +static int av7110_ir_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - u32 ir_config; + char *page; + int size = 4 + 256 * sizeof(u16); - if (count < 4 + 256 * sizeof(u16)) + if (count < size) return -EINVAL; - memcpy (&ir_config, buffer, 4); - memcpy (&key_map, buffer + 4, 256 * sizeof(u16)); + page = (char *)vmalloc(size); + if( NULL == page ) { + return -ENOMEM; + } + + if (copy_from_user(page, buffer, size)) { + vfree(page); + return -EFAULT; + } + + memcpy (&ir_config, page, 4); + memcpy (&key_map, page + 4, 256 * sizeof(u16)); + + vfree(page); av7110_setup_irc_config (NULL, ir_config); @@ -141,10 +179,12 @@ * enable keys */ set_bit (EV_KEY, input_dev.evbit); + set_bit (EV_REP, input_dev.evbit); input_register_keys (); input_register_device(&input_dev); + input_dev.timer.function = input_repeat_key; av7110_setup_irc_config (NULL, 0x0001); av7110_register_irc_handler (av7110_emit_key); diff -Nru a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c --- a/drivers/media/dvb/ttpci/budget-av.c Fri Jun 27 14:20:00 2003 +++ b/drivers/media/dvb/ttpci/budget-av.c Fri Jun 27 14:20:00 2003 @@ -30,13 +30,10 @@ * the project's page is at http://www.linuxtv.org/dvb/ */ -#include "budget.h" #include <media/saa7146_vv.h> -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME budget_av -#endif - +#include "budget.h" +#include "dvb_functions.h" struct budget_av { struct budget budget; @@ -48,16 +45,8 @@ * INITIALIZATION ****************************************************************************/ -static inline -void ddelay(int i) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout((HZ*i)/100); -} - -static -u8 i2c_readreg (struct dvb_i2c_bus *i2c, u8 id, u8 reg) +static u8 i2c_readreg (struct dvb_i2c_bus *i2c, u8 id, u8 reg) { u8 mm1[] = {0x00}; u8 mm2[] = {0x00}; @@ -76,8 +65,7 @@ } -static -int i2c_writereg (struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 val) +static int i2c_writereg (struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 val) { u8 msg[2]={ reg, val }; struct i2c_msg msgs; @@ -90,8 +78,7 @@ } -static const -u8 saa7113_tab[] = { +static const u8 saa7113_tab[] = { 0x01, 0x08, 0x02, 0xc0, 0x03, 0x33, @@ -121,8 +108,7 @@ }; -static -int saa7113_init (struct budget_av *budget_av) +static int saa7113_init (struct budget_av *budget_av) { struct budget *budget = &budget_av->budget; const u8 *data = saa7113_tab; @@ -146,8 +132,7 @@ } -static -int saa7113_setinput (struct budget_av *budget_av, int input) +static int saa7113_setinput (struct budget_av *budget_av, int input) { struct budget *budget = &budget_av->budget; @@ -165,8 +150,7 @@ } -static -int budget_av_detach (struct saa7146_dev *dev) +static int budget_av_detach (struct saa7146_dev *dev) { struct budget_av *budget_av = (struct budget_av*) dev->ext_priv; int err; @@ -175,7 +159,7 @@ saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); - ddelay(20); + dvb_delay(200); saa7146_unregister_device (&budget_av->vd, dev); @@ -187,8 +171,7 @@ } -static -int budget_av_attach (struct saa7146_dev* dev, +static int budget_av_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { struct budget_av *budget_av; @@ -221,7 +204,7 @@ //test_knc_ci(av7110); saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI); - ddelay(50); + dvb_delay(500); if ((err = saa7113_init (budget_av))) { budget_av_detach(dev); @@ -245,9 +228,11 @@ /* what is this? since we don't support open()/close() notifications, we simply put this into the release handler... */ -// saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); - ddelay(20); - +/* + saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout (20); +*/ /* fixme: find some sane values here... */ saa7146_write(dev, PCI_BT_V1, 0x1c00101f); @@ -263,8 +248,7 @@ }; -static -struct saa7146_extension_ioctls ioctls[] = { +static struct saa7146_extension_ioctls ioctls[] = { { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, @@ -272,8 +256,7 @@ }; -static -int av_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) +static int av_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg) { struct budget_av *budget_av = (struct budget_av*) dev->ext_priv; /* @@ -315,15 +298,13 @@ return 0; } -static -struct saa7146_standard standard[] = { +static struct saa7146_standard standard[] = { { "PAL", V4L2_STD_PAL, SAA7146_PAL_VALUES }, { "NTSC", V4L2_STD_NTSC, SAA7146_NTSC_VALUES }, }; -static -struct saa7146_ext_vv vv_data = { +static struct saa7146_ext_vv vv_data = { .inputs = 2, .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113 .flags = 0, @@ -340,18 +321,16 @@ MAKE_BUDGET_INFO(knc1, "KNC1 DVB-S", BUDGET_KNC1); -static -struct pci_device_id pci_tbl [] = { +static struct pci_device_id pci_tbl [] = { MAKE_EXTENSION_PCI(knc1, 0x1131, 0x4f56), { .vendor = 0, } }; +MODULE_DEVICE_TABLE(pci, pci_tbl); - -static -struct saa7146_extension budget_extension = { +static struct saa7146_extension budget_extension = { .name = "budget dvb /w video in\0", .pci_tbl = pci_tbl, @@ -366,8 +345,7 @@ }; -static -int __init budget_av_init(void) +static int __init budget_av_init(void) { DEB_EE((".\n")); @@ -378,8 +356,7 @@ } -static -void __exit budget_av_exit(void) +static void __exit budget_av_exit(void) { DEB_EE((".\n")); saa7146_unregister_extension(&budget_extension); diff -Nru a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c --- a/drivers/media/dvb/ttpci/budget-ci.c Fri Jun 27 14:19:53 2003 +++ b/drivers/media/dvb/ttpci/budget-ci.c Fri Jun 27 14:19:53 2003 @@ -28,10 +28,6 @@ */ #include "budget.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME budget -#endif - #include <linux/module.h> #include <linux/errno.h> @@ -39,12 +35,6 @@ #include <linux/interrupt.h> #include <linux/input.h> -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include "input_fake.h" -#endif - - - struct budget_ci { struct budget budget; struct input_dev input_dev; @@ -78,8 +68,7 @@ -static -int wait_for_debi_done(struct saa7146_dev *saa) +static int wait_for_debi_done(struct saa7146_dev *saa) { int start = jiffies; @@ -113,8 +102,7 @@ } -static -u32 debiread (struct saa7146_dev *saa, u32 config, int addr, int count) +static u32 debiread (struct saa7146_dev *saa, u32 config, int addr, int count) { u32 result = 0; @@ -141,8 +129,7 @@ /* DEBI during interrupt */ -static inline -u32 irdebi(struct saa7146_dev *saa, u32 config, int addr, u32 val, int count) +static inline u32 irdebi(struct saa7146_dev *saa, u32 config, int addr, u32 val, int count) { u32 res; res = debiread(saa, config, addr, count); @@ -158,8 +145,7 @@ Hauppauge (from NOVA-CI-s box product) i've taken a "middle of the road" approach and note the differences */ -static - u16 key_map[64] = { +static u16 key_map[64] = { /* 0x0X */ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, @@ -209,8 +195,7 @@ }; -static -void msp430_ir_debounce (unsigned long data) +static void msp430_ir_debounce (unsigned long data) { struct input_dev *dev = (struct input_dev *) data; @@ -227,8 +212,7 @@ -static -void msp430_ir_interrupt (unsigned long data) +static void msp430_ir_interrupt (unsigned long data) { struct budget_ci *budget_ci = (struct budget_ci*) data; struct saa7146_dev *saa = budget_ci->budget.dev; @@ -266,8 +250,7 @@ } -static -int msp430_ir_init (struct budget_ci *budget_ci) +static int msp430_ir_init (struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; int i; @@ -294,8 +277,7 @@ } -static -void msp430_ir_deinit (struct budget_ci *budget_ci) +static void msp430_ir_deinit (struct budget_ci *budget_ci) { struct saa7146_dev *saa = budget_ci->budget.dev; struct input_dev *dev = &budget_ci->input_dev; @@ -311,8 +293,7 @@ } -static -void budget_ci_irq (struct saa7146_dev *dev, u32 *isr) +static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr) { struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv; @@ -327,8 +308,7 @@ -static -int budget_ci_attach (struct saa7146_dev* dev, +static int budget_ci_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { struct budget_ci *budget_ci; @@ -356,8 +336,7 @@ -static -int budget_ci_detach (struct saa7146_dev* dev) +static int budget_ci_detach (struct saa7146_dev* dev) { struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv; int err; @@ -379,8 +358,7 @@ MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); -static -struct pci_device_id pci_tbl[] = { +static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), { @@ -388,10 +366,9 @@ } }; +MODULE_DEVICE_TABLE(pci, pci_tbl); - -static -struct saa7146_extension budget_extension = { +static struct saa7146_extension budget_extension = { .name = "budget_ci dvb\0", .flags = 0, .ext_vv_data = NULL, @@ -406,8 +383,7 @@ }; -static -int __init budget_ci_init(void) +static int __init budget_ci_init(void) { if (saa7146_register_extension(&budget_extension)) return -ENODEV; @@ -416,8 +392,7 @@ } -static -void __exit budget_ci_exit(void) +static void __exit budget_ci_exit(void) { DEB_EE((".\n")); saa7146_unregister_extension(&budget_extension); diff -Nru a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c --- a/drivers/media/dvb/ttpci/budget-core.c Fri Jun 27 14:19:55 2003 +++ b/drivers/media/dvb/ttpci/budget-core.c Fri Jun 27 14:19:55 2003 @@ -1,26 +1,12 @@ #include "budget.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME budget -#endif int budget_debug = 0; /**************************************************************************** - * General helper functions - ****************************************************************************/ - -static inline void ddelay(int i) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout((HZ*i)/100); -} - -/**************************************************************************** * TT budget / WinTV Nova ****************************************************************************/ -static -int stop_ts_capture(struct budget *budget) +static int stop_ts_capture(struct budget *budget) { DEB_EE(("budget: %p\n",budget)); @@ -33,8 +19,7 @@ } -static -int start_ts_capture (struct budget *budget) +static int start_ts_capture (struct budget *budget) { struct saa7146_dev *dev=budget->dev; @@ -75,8 +60,7 @@ } -static -void vpeirq (unsigned long data) +static void vpeirq (unsigned long data) { struct budget *budget = (struct budget*) data; u8 *mem = (u8 *)(budget->grabbing); @@ -113,8 +97,7 @@ * DVB API SECTION ****************************************************************************/ -static -int budget_start_feed(struct dvb_demux_feed *feed) +static int budget_start_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct budget *budget = (struct budget*) demux->priv; @@ -127,8 +110,7 @@ return start_ts_capture (budget); } -static -int budget_stop_feed(struct dvb_demux_feed *feed) +static int budget_stop_feed(struct dvb_demux_feed *feed) { struct dvb_demux *demux = feed->demux; struct budget *budget = (struct budget *) demux->priv; @@ -139,17 +121,13 @@ } -static -int budget_register(struct budget *budget) +static int budget_register(struct budget *budget) { - int ret; - dmx_frontend_t *dvbfront=&budget->hw_frontend; struct dvb_demux *dvbdemux=&budget->demux; + int ret; DEB_EE(("budget: %p\n",budget)); - memcpy(budget->demux_id, "demux0_0", 9); - budget->demux_id[5] = budget->dvb_adapter->num + '0'; dvbdemux->priv = (void *) budget; dvbdemux->filternum = 256; @@ -158,33 +136,24 @@ dvbdemux->stop_feed = budget_stop_feed; dvbdemux->write_to_decoder = NULL; - dvbdemux->dmx.vendor = "CIM"; - dvbdemux->dmx.model = "sw"; - dvbdemux->dmx.id = budget->demux_id; dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); dvb_dmx_init(&budget->demux); - dvbfront->id = "hw_frontend"; - dvbfront->vendor = "VLSI"; - dvbfront->model = "DVB Frontend"; - dvbfront->source = DMX_FRONTEND_0; - budget->dmxdev.filternum = 256; budget->dmxdev.demux = &dvbdemux->dmx; budget->dmxdev.capabilities = 0; dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter); - ret=dvbdemux->dmx.add_frontend (&dvbdemux->dmx, - &budget->hw_frontend); + budget->hw_frontend.source = DMX_FRONTEND_0; + + ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend); + if (ret < 0) return ret; - budget->mem_frontend.id = "mem_frontend"; - budget->mem_frontend.vendor = "memory"; - budget->mem_frontend.model = "sw"; budget->mem_frontend.source = DMX_MEMORY_FE; ret=dvbdemux->dmx.add_frontend (&dvbdemux->dmx, &budget->mem_frontend); @@ -203,8 +172,7 @@ } -static -void budget_unregister(struct budget *budget) +static void budget_unregister(struct budget *budget) { struct dvb_demux *dvbdemux=&budget->demux; @@ -221,8 +189,7 @@ } -static -int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) +static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) { struct saa7146_dev *dev = i2c->data; return saa7146_i2c_transfer(dev, msgs, num, 6); @@ -278,9 +245,9 @@ saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); /* frontend power on */ - if (budget_register(budget) == 0) + if (budget_register(budget) == 0) { return 0; - + } err: if (budget->grabbing) vfree(budget->grabbing); @@ -312,7 +279,6 @@ saa7146_pgtable_free (dev->pci, &budget->pt); vfree (budget->grabbing); - kfree (budget); return 0; } diff -Nru a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c --- a/drivers/media/dvb/ttpci/budget-patch.c Fri Jun 27 14:19:53 2003 +++ b/drivers/media/dvb/ttpci/budget-patch.c Fri Jun 27 14:19:53 2003 @@ -31,9 +31,7 @@ */ #include "budget.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME budget_patch -#endif +#include "av7110.h" #define budget_patch budget @@ -41,55 +39,14 @@ MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH); -static -struct pci_device_id pci_tbl[] = { +static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(fs_1_3,0x13c2, 0x0000), { .vendor = 0, } }; - -#define COMMAND (DPRAM_BASE + 0x0FC) -#define DPRAM_BASE 0x4000 -#define DEBINOSWAP 0x000e0000 - - -typedef enum { - AudioDAC, - CabADAC, - ON22K, - OFF22K, - MainSwitch, - ADSwitch, - SendDiSEqC, - SetRegister -} AUDCOM; - - -typedef enum { - COMTYPE_NOCOM, - COMTYPE_PIDFILTER, - COMTYPE_MPEGDECODER, - COMTYPE_OSD, - COMTYPE_BMP, - COMTYPE_ENCODER, - COMTYPE_AUDIODAC, - COMTYPE_REQUEST, - COMTYPE_SYSTEM, - COMTYPE_REC_PLAY, - COMTYPE_COMMON_IF, - COMTYPE_PID_FILTER, - COMTYPE_PES, - COMTYPE_TS, - COMTYPE_VIDEO, - COMTYPE_AUDIO, - COMTYPE_CI_LL, -} COMTYPE; - - -static -int wdebi(struct budget_patch *budget, u32 config, int addr, u32 val, int count) +static int wdebi(struct budget_patch *budget, u32 config, int addr, u32 val, int count) { struct saa7146_dev *dev=budget->dev; @@ -109,8 +66,7 @@ } -static -int SOutCommand(struct budget_patch *budget, u16* buf, int length) +static int SOutCommand(struct budget_patch *budget, u16* buf, int length) { int i; @@ -129,8 +85,7 @@ } -static -void av7110_set22k(struct budget_patch *budget, int state) +static void av7110_set22k(struct budget_patch *budget, int state) { u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0}; @@ -139,8 +94,7 @@ } -static int -av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst) +static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst) { int i; u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC), @@ -207,12 +161,10 @@ } -static -int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) +static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { struct budget_patch *budget; int err; - int cnt; if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL))) return -ENOMEM; @@ -235,31 +187,33 @@ ** (74HCT4040, LVC74) for the generation of this VSYNC signal, ** which seems that can be done perfectly without this :-)). */ - cnt = 0; // Setup RPS1 "program" (p35) + + // Setup RPS1 "program" (p35) + // Wait reset Source Line Counter Threshold (p36) - dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS); + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); // Wait Source Line Counter Threshold (p36) - dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | EVT_HS); + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); // Set GPIO3=1 (p42) - dev->rps1[cnt++]=cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - dev->rps1[cnt++]=cpu_to_le32(GPIO3_MSK); - dev->rps1[cnt++]=cpu_to_le32(SAA7146_GPIO_OUTHI<<24); + WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); + WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); + WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24)); // Wait reset Source Line Counter Threshold (p36) - dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS); + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); // Wait Source Line Counter Threshold - dev->rps1[cnt++]=cpu_to_le32(CMD_PAUSE | EVT_HS); + WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); // Set GPIO3=0 (p42) - dev->rps1[cnt++]=cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - dev->rps1[cnt++]=cpu_to_le32(GPIO3_MSK); - dev->rps1[cnt++]=cpu_to_le32(SAA7146_GPIO_OUTLO<<24); + WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); + WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); + WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); // Jump to begin of RPS program (p37) - dev->rps1[cnt++]=cpu_to_le32(CMD_JUMP); - dev->rps1[cnt++]=cpu_to_le32(virt_to_bus(&dev->rps1[0])); + WRITE_RPS1(cpu_to_le32(CMD_JUMP)); + WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); // Fix VSYNC level saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // Set RPS1 Address register to point to RPS code (r108 p42) - saa7146_write(dev, RPS_ADDR1, virt_to_bus(&dev->rps1[0])); + saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); // Set Source Line Counter Threshold, using BRS (rCC p43) saa7146_write(dev, RPS_THRESH1, ((TS_HEIGHT/2) | MASK_12)); // Enable RPS1 (rFC p33) @@ -274,8 +228,7 @@ } -static -int budget_patch_detach (struct saa7146_dev* dev) +static int budget_patch_detach (struct saa7146_dev* dev) { struct budget_patch *budget = (struct budget_patch*) dev->ext_priv; int err; @@ -291,8 +244,7 @@ } -static -int __init budget_patch_init(void) +static int __init budget_patch_init(void) { if (saa7146_register_extension(&budget_extension)) return -ENODEV; @@ -301,16 +253,14 @@ } -static -void __exit budget_patch_exit(void) +static void __exit budget_patch_exit(void) { DEB_EE((".\n")); saa7146_unregister_extension(&budget_extension); } -static -struct saa7146_extension budget_extension = { +static struct saa7146_extension budget_extension = { .name = "budget_patch dvb\0", .flags = 0, .ext_vv_data = NULL, diff -Nru a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c --- a/drivers/media/dvb/ttpci/budget.c Fri Jun 27 14:19:57 2003 +++ b/drivers/media/dvb/ttpci/budget.c Fri Jun 27 14:19:57 2003 @@ -30,21 +30,9 @@ */ #include "budget.h" -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME budget -#endif +#include "dvb_functions.h" - - -static inline void ddelay(int i) -{ - current->state=TASK_INTERRUPTIBLE; - schedule_timeout((HZ*i)/100); -} - - -static -void Set22K (struct budget *budget, int state) +static void Set22K (struct budget *budget, int state) { struct saa7146_dev *dev=budget->dev; DEB_EE(("budget: %p\n",budget)); @@ -56,8 +44,7 @@ /* taken from the Skyvision DVB driver by Ralph Metzler <rjkm@metzlerbros.de> */ -static -void DiseqcSendBit (struct budget *budget, int data) +static void DiseqcSendBit (struct budget *budget, int data) { struct saa7146_dev *dev=budget->dev; DEB_EE(("budget: %p\n",budget)); @@ -69,8 +56,7 @@ } -static -void DiseqcSendByte (struct budget *budget, int data) +static void DiseqcSendByte (struct budget *budget, int data) { int i, par=1, d; @@ -86,8 +72,7 @@ } -static -int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, int burst) +static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) { struct saa7146_dev *dev=budget->dev; int i; @@ -110,7 +95,7 @@ udelay(12500); saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); } - ddelay(2); + dvb_delay(20); } return 0; @@ -146,7 +131,7 @@ } case FE_DISEQC_SEND_BURST: - SendDiSEqCMsg (budget, 0, NULL, (int) arg); + SendDiSEqCMsg (budget, 0, NULL, (unsigned long)arg); break; default: @@ -157,18 +142,20 @@ } -static -int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) +static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) { - struct budget *budget; + struct budget *budget = NULL; int err; - if (!(budget = kmalloc (sizeof(struct budget), GFP_KERNEL))) + budget = kmalloc(sizeof(struct budget), GFP_KERNEL); + if( NULL == budget ) { return -ENOMEM; + } - DEB_EE(("budget: %p\n",budget)); + DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget)); if ((err = ttpci_budget_init (budget, dev, info))) { + printk("==> failed\n"); kfree (budget); return err; } @@ -182,8 +169,7 @@ } -static -int budget_detach (struct saa7146_dev* dev) +static int budget_detach (struct saa7146_dev* dev) { struct budget *budget = (struct budget*) dev->ext_priv; int err; @@ -194,6 +180,7 @@ err = ttpci_budget_deinit (budget); kfree (budget); + dev->ext_priv = NULL; return err; } @@ -209,8 +196,7 @@ /* Uncomment for Budget Patch */ /*MAKE_BUDGET_INFO(fs_1_3,"Siemens/Technotrend/Hauppauge PCI rev1.3+Budget_Patch", BUDGET_PATCH);*/ -static -struct pci_device_id pci_tbl[] = { +static struct pci_device_id pci_tbl[] = { /* Uncomment for Budget Patch */ /*MAKE_EXTENSION_PCI(fs_1_3,0x13c2, 0x0000),*/ MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), @@ -222,10 +208,9 @@ } }; +MODULE_DEVICE_TABLE(pci, pci_tbl); - -static -struct saa7146_extension budget_extension = { +static struct saa7146_extension budget_extension = { .name = "budget dvb\0", .flags = 0, .ext_vv_data = NULL, @@ -240,8 +225,7 @@ }; -static -int __init budget_init(void) +static int __init budget_init(void) { if (saa7146_register_extension(&budget_extension)) return -ENODEV; @@ -250,8 +234,7 @@ } -static -void __exit budget_exit(void) +static void __exit budget_exit(void) { DEB_EE((".\n")); saa7146_unregister_extension(&budget_extension); diff -Nru a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h --- a/drivers/media/dvb/ttpci/budget.h Fri Jun 27 14:19:58 2003 +++ b/drivers/media/dvb/ttpci/budget.h Fri Jun 27 14:19:58 2003 @@ -1,6 +1,8 @@ #ifndef __BUDGET_DVB__ #define __BUDGET_DVB__ +#include <media/saa7146.h> + #include "dvb_i2c.h" #include "dvb_frontend.h" #include "dvbdev.h" @@ -10,8 +12,6 @@ #include "dvb_filter.h" #include "dvb_net.h" -#include <media/saa7146.h> - extern int budget_debug; struct budget_info { @@ -24,7 +24,7 @@ /* devices */ struct dvb_device dvb_dev; - dvb_net_t dvb_net; + struct dvb_net dvb_net; struct saa7146_dev *dev; @@ -37,12 +37,11 @@ struct tasklet_struct fidb_tasklet; struct tasklet_struct vpe_tasklet; - dmxdev_t dmxdev; + struct dmxdev dmxdev; struct dvb_demux demux; - char demux_id[16]; - dmx_frontend_t hw_frontend; - dmx_frontend_t mem_frontend; + struct dmx_frontend hw_frontend; + struct dmx_frontend mem_frontend; int fe_synced; struct semaphore pid_mutex; diff -Nru a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c --- a/drivers/media/video/dpc7146.c Fri Jun 27 14:19:55 2003 +++ b/drivers/media/video/dpc7146.c Fri Jun 27 14:19:55 2003 @@ -23,10 +23,6 @@ #include <media/saa7146_vv.h> #include <linux/video_decoder.h> /* for saa7111a */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME dpc7146 -#endif - #define I2C_SAA7111A 0x24 /* All unused bytes are reserverd. */ @@ -338,6 +334,8 @@ .vendor = 0, } }; + +MODULE_DEVICE_TABLE(pci, pci_tbl); static struct saa7146_ext_vv vv_data = { diff -Nru a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c --- a/drivers/media/video/mxb.c Fri Jun 27 14:19:53 2003 +++ b/drivers/media/video/mxb.c Fri Jun 27 14:19:53 2003 @@ -26,10 +26,6 @@ #include <media/saa7146_vv.h> #include <linux/video_decoder.h> /* for saa7111a */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #define KBUILD_MODNAME mxb -#endif - #include "mxb.h" #include "tea6415c.h" #include "tea6420.h" diff -Nru a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c --- a/drivers/media/video/saa7111.c Fri Jun 27 14:19:55 2003 +++ b/drivers/media/video/saa7111.c Fri Jun 27 14:19:55 2003 @@ -57,7 +57,7 @@ int sat; }; -static unsigned short normal_i2c[] = { 34>>1, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x24, 0x25, I2C_CLIENT_END }; static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; I2C_CLIENT_INSMOD; diff -Nru a/drivers/mtd/afs.c b/drivers/mtd/afs.c --- a/drivers/mtd/afs.c Fri Jun 27 14:20:04 2003 +++ b/drivers/mtd/afs.c Fri Jun 27 14:20:04 2003 @@ -21,7 +21,7 @@ This is access code for flashes using ARM's flash partitioning standards. - $Id: afs.c,v 1.11 2003/05/16 17:08:24 dwmw2 Exp $ + $Id: afs.c,v 1.12 2003/06/13 15:31:06 rmk Exp $ ======================================================================*/ @@ -76,17 +76,19 @@ return ret; } + ret = 1; + /* * Does it contain the magic number? */ if (fs.signature != 0xa0ffff9f) - ret = 1; + ret = 0; /* * Don't touch the SIB. */ if (fs.type == 2) - ret = 1; + ret = 0; *iis_start = fs.image_info_base & mask; *img_start = fs.image_start & mask; @@ -96,14 +98,14 @@ * be located after the footer structure. */ if (*iis_start >= ptr) - ret = 1; + ret = 0; /* * Check the start of this image. The image * data can not be located after this block. */ if (*img_start > off) - ret = 1; + ret = 0; return ret; } @@ -152,7 +154,7 @@ ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; - if (ret == 1) + if (ret == 0) continue; ret = afs_read_iis(mtd, &iis, iis_ptr); @@ -185,7 +187,7 @@ ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); if (ret < 0) break; - if (ret == 1) + if (ret == 0) continue; /* Read the image info block */ diff -Nru a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c --- a/drivers/mtd/chips/amd_flash.c Fri Jun 27 14:19:54 2003 +++ b/drivers/mtd/chips/amd_flash.c Fri Jun 27 14:19:54 2003 @@ -3,7 +3,7 @@ * * Author: Jonas Holmberg <jonas.holmberg@axis.com> * - * $Id: amd_flash.c,v 1.22 2003/05/28 13:47:19 dwmw2 Exp $ + * $Id: amd_flash.c,v 1.23 2003/06/12 09:24:13 dwmw2 Exp $ * * Copyright (c) 2001 Axis Communications AB * @@ -19,6 +19,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/init.h> #include <linux/mtd/map.h> #include <linux/mtd/mtd.h> #include <linux/mtd/flashchip.h> diff -Nru a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c --- a/drivers/mtd/chips/cfi_cmdset_0001.c Fri Jun 27 14:19:54 2003 +++ b/drivers/mtd/chips/cfi_cmdset_0001.c Fri Jun 27 14:19:54 2003 @@ -4,7 +4,7 @@ * * (C) 2000 Red Hat. GPL'd * - * $Id: cfi_cmdset_0001.c,v 1.123 2003/05/28 12:51:48 dwmw2 Exp $ + * $Id: cfi_cmdset_0001.c,v 1.126 2003/06/23 07:45:48 dwmw2 Exp $ * * * 10/10/2000 Nicolas Pitre <nico@cam.org> @@ -936,7 +936,7 @@ struct cfi_private *cfi = map->fldrv_priv; cfi_word status, status_OK; unsigned long cmd_adr, timeo; - int wbufsize, z, ret=0; + int wbufsize, z, ret=0, bytes, words; wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; adr += chip->start; @@ -995,10 +995,13 @@ } /* Write length of data to come */ - cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr ); + bytes = len & (CFIDEV_BUSWIDTH-1); + words = len / CFIDEV_BUSWIDTH; + cfi_write(map, CMD(words - !bytes), cmd_adr ); /* Write data */ - for (z = 0; z < len; z += CFIDEV_BUSWIDTH) { + z = 0; + while(z < words * CFIDEV_BUSWIDTH) { if (cfi_buswidth_is_1()) { map_write8 (map, *((__u8*)buf)++, adr+z); } else if (cfi_buswidth_is_2()) { @@ -1011,6 +1014,26 @@ ret = -EINVAL; goto out; } + z += CFIDEV_BUSWIDTH; + } + if (bytes) { + int i = 0, n = 0; + u_char tmp_buf[8], *tmp_p = tmp_buf; + + while (bytes--) + tmp_buf[i++] = buf[n++]; + while (i < CFIDEV_BUSWIDTH) + tmp_buf[i++] = 0xff; + if (cfi_buswidth_is_2()) { + map_write16 (map, *((__u16*)tmp_p)++, adr+z); + } else if (cfi_buswidth_is_4()) { + map_write32 (map, *((__u32*)tmp_p)++, adr+z); + } else if (cfi_buswidth_is_8()) { + map_write64 (map, *((__u64*)tmp_p)++, adr+z); + } else { + ret = -EINVAL; + goto out; + } } /* GO GO GO */ cfi_write(map, CMD(0xd0), cmd_adr); @@ -1119,12 +1142,12 @@ } /* Write buffer is worth it only if more than one word to write... */ - while(len > CFIDEV_BUSWIDTH) { + while(len) { /* We must not cross write block boundaries */ int size = wbufsize - (ofs & (wbufsize-1)); if (size > len) - size = len & ~(CFIDEV_BUSWIDTH-1); + size = len; ret = do_write_buffer(map, &cfi->chips[chipnum], ofs, buf, size); if (ret) @@ -1142,17 +1165,6 @@ return 0; } } - - /* ... and write the remaining bytes */ - if (len > 0) { - size_t local_retlen; - ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift), - len, &local_retlen, buf); - if (ret) - return ret; - (*retlen) += local_retlen; - } - return 0; } @@ -1423,6 +1435,7 @@ * with the chip now anyway. */ } + spin_unlock(chip->mutex); } /* Unlock the chips again */ diff -Nru a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c --- a/drivers/mtd/chips/gen_probe.c Fri Jun 27 14:20:03 2003 +++ b/drivers/mtd/chips/gen_probe.c Fri Jun 27 14:20:03 2003 @@ -1,8 +1,8 @@ /* * Routines common to all CFI-type probes. - * (C) 2001, 2001 Red Hat, Inc. + * (C) 2001-2003 Red Hat, Inc. * GPL'd - * $Id: gen_probe.c,v 1.11 2003/05/21 15:15:05 dwmw2 Exp $ + * $Id: gen_probe.c,v 1.13 2003/06/25 11:50:37 dwmw2 Exp $ */ #include <linux/kernel.h> @@ -281,6 +281,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001; extern cfi_cmdset_fn_t cfi_cmdset_0002; +extern cfi_cmdset_fn_t cfi_cmdset_0020; static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, int primary) diff -Nru a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c --- a/drivers/mtd/devices/doc2000.c Fri Jun 27 14:19:30 2003 +++ b/drivers/mtd/devices/doc2000.c Fri Jun 27 14:19:30 2003 @@ -4,7 +4,7 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * - * $Id: doc2000.c,v 1.52 2003/05/20 21:03:07 dwmw2 Exp $ + * $Id: doc2000.c,v 1.53 2003/06/11 09:45:19 dwmw2 Exp $ */ #include <linux/kernel.h> @@ -553,6 +553,7 @@ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; + mtd->ecctype = MTD_ECC_RS_DiskOnChip; mtd->size = 0; mtd->erasesize = 0; mtd->oobblock = 512; diff -Nru a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c --- a/drivers/mtd/devices/doc2001.c Fri Jun 27 14:19:54 2003 +++ b/drivers/mtd/devices/doc2001.c Fri Jun 27 14:19:54 2003 @@ -4,7 +4,7 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * - * $Id: doc2001.c,v 1.40 2003/05/20 21:03:07 dwmw2 Exp $ + * $Id: doc2001.c,v 1.41 2003/06/11 09:45:19 dwmw2 Exp $ */ #include <linux/kernel.h> @@ -359,9 +359,10 @@ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; + mtd->ecctype = MTD_ECC_RS_DiskOnChip; mtd->size = 0; - /* FIXME: erase size is not always 8kB */ + /* FIXME: erase size is not always 8KiB */ mtd->erasesize = 0x2000; mtd->oobblock = 512; diff -Nru a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c --- a/drivers/mtd/devices/doc2001plus.c Fri Jun 27 14:19:30 2003 +++ b/drivers/mtd/devices/doc2001plus.c Fri Jun 27 14:19:30 2003 @@ -6,7 +6,7 @@ * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * - * $Id: doc2001plus.c,v 1.4 2003/05/23 11:28:46 dwmw2 Exp $ + * $Id: doc2001plus.c,v 1.5 2003/06/11 09:45:19 dwmw2 Exp $ */ #include <linux/kernel.h> @@ -458,6 +458,7 @@ mtd->type = MTD_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH; + mtd->ecctype = MTD_ECC_RS_DiskOnChip; mtd->size = 0; mtd->erasesize = 0; diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c --- a/drivers/mtd/ftl.c Fri Jun 27 14:20:00 2003 +++ b/drivers/mtd/ftl.c Fri Jun 27 14:20:00 2003 @@ -1,5 +1,5 @@ /* This version ported to the Linux-MTD system by dwmw2@infradead.org - * $Id: ftl.c,v 1.50 2003/05/21 10:49:47 dwmw2 Exp $ + * $Id: ftl.c,v 1.51 2003/06/23 12:00:08 dwmw2 Exp $ * * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups @@ -984,37 +984,20 @@ return 0; } /* ftl_write */ -/*====================================================================== - - IOCTL calls for getting device parameters. - -======================================================================*/ - -static int ftl_ioctl(struct mtd_blktrans_dev *dev, struct inode *inode, - struct file *file, u_int cmd, u_long arg) +static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) { - struct hd_geometry *geo = (struct hd_geometry *)arg; - partition_t *part = (void *)dev; - u_long sect; - - switch (cmd) { - case HDIO_GETGEO: - /* Sort of arbitrary: round size down to 4K boundary */ - sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; - if (put_user(1, (char *)&geo->heads) || - put_user(8, (char *)&geo->sectors) || - put_user((sect>>3), (short *)&geo->cylinders) || - put_user(0, (u_long *)&geo->start)) - return -EFAULT; + partition_t *part = (void *)dev; + u_long sect; - case BLKFLSBUF: - return 0; - } - return -ENOTTY; -} /* ftl_ioctl */ + /* Sort of arbitrary: round size down to 4KiB boundary */ + sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; + geo->heads = 1; + geo->sectors = 8; + geo->cylinders = sect >> 3; -/*======================================================================*/ + return 0; +} static int ftl_readsect(struct mtd_blktrans_dev *dev, unsigned long block, char *buf) @@ -1102,7 +1085,7 @@ .part_bits = PART_BITS, .readsect = ftl_readsect, .writesect = ftl_writesect, - .ioctl = ftl_ioctl, + .getgeo = ftl_getgeo, .add_mtd = ftl_add_mtd, .remove_dev = ftl_remove_dev, .owner = THIS_MODULE, @@ -1110,7 +1093,7 @@ int init_ftl(void) { - DEBUG(0, "$Id: ftl.c,v 1.50 2003/05/21 10:49:47 dwmw2 Exp $\n"); + DEBUG(0, "$Id: ftl.c,v 1.51 2003/06/23 12:00:08 dwmw2 Exp $\n"); return register_mtd_blktrans(&ftl_tr); } diff -Nru a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c --- a/drivers/mtd/inftlcore.c Fri Jun 27 14:19:53 2003 +++ b/drivers/mtd/inftlcore.c Fri Jun 27 14:19:53 2003 @@ -7,7 +7,7 @@ * (c) 1999 Machine Vision Holdings, Inc. * Author: David Woodhouse <dwmw2@infradead.org> * - * $Id: inftlcore.c,v 1.9 2003/05/23 11:41:47 dwmw2 Exp $ + * $Id: inftlcore.c,v 1.14 2003/06/26 08:28:26 dwmw2 Exp $ * * 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 @@ -113,7 +113,7 @@ (long)inftl->sectors ); } - if (add_mtd_blktrans_dev) { + if (add_mtd_blktrans_dev(&inftl->mbd)) { if (inftl->PUtable) kfree(inftl->PUtable); if (inftl->VUtable) @@ -573,7 +573,7 @@ { unsigned char BlockUsed[MAX_SECTORS_PER_UNIT]; unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT]; - unsigned int thisEUN, prevEUN, status; + unsigned int thisEUN, status; int block, silly; struct inftl_bci bci; size_t retlen; @@ -645,26 +645,45 @@ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC); for (;;) { + u16 *prevEUN = &inftl->VUtable[thisVUC]; + thisEUN = *prevEUN; + + /* If the chain is all gone already, we're done */ + if (thisEUN == BLOCK_NIL) { + DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN); + return; + } + /* Find oldest unit in chain. */ - thisEUN = inftl->VUtable[thisVUC]; - prevEUN = BLOCK_NIL; while (inftl->PUtable[thisEUN] != BLOCK_NIL) { - prevEUN = thisEUN; - thisEUN = inftl->PUtable[thisEUN]; + BUG_ON(thisEUN >= inftl->nb_blocks); + + prevEUN = &inftl->PUtable[thisEUN]; + thisEUN = *prevEUN; } + DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n", + thisEUN, thisVUC); + if (INFTL_formatblock(inftl, thisEUN) < 0) { /* * Could not erase : mark block as reserved. - * FixMe: Update Bad Unit Table on disk. + * FixMe: Update Bad Unit Table on medium. */ inftl->PUtable[thisEUN] = BLOCK_RESERVED; } else { /* Correctly erased : mark it as free */ inftl->PUtable[thisEUN] = BLOCK_FREE; - inftl->PUtable[prevEUN] = BLOCK_NIL; inftl->numfreeEUNs++; - } + } + + /* Now sort out whatever was pointing to it... */ + *prevEUN = BLOCK_NIL; + + /* Ideally we'd actually be responsive to new + requests while we're doing this -- if there's + free space why should others be made to wait? */ + cond_resched(); } inftl->VUtable[thisVUC] = BLOCK_NIL; @@ -835,35 +854,22 @@ return 0; } - -static int inftl_ioctl(struct mtd_blktrans_dev *dev, - struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int inftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) { - struct NFTLrecord *nftl = (void *)dev; - - switch (cmd) { - case HDIO_GETGEO: { - struct hd_geometry g; + struct INFTLrecord *inftl = (void *)dev; - g.heads = nftl->heads; - g.sectors = nftl->sectors; - g.cylinders = nftl->cylinders; - g.start = 0; - return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; - } + geo->heads = inftl->heads; + geo->sectors = inftl->sectors; + geo->cylinders = inftl->cylinders; - default: - return -ENOTTY; - } + return 0; } - struct mtd_blktrans_ops inftl_tr = { .name = "inftl", .major = INFTL_MAJOR, .part_bits = INFTL_PARTN_BITS, - .ioctl = inftl_ioctl, + .getgeo = inftl_getgeo, .readsect = inftl_readblock, .writesect = inftl_writeblock, .add_mtd = inftl_add_mtd, @@ -875,7 +881,7 @@ int __init init_inftl(void) { - printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.9 $, " + printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.14 $, " "inftlmount.c %s\n", inftlmountrev); return register_mtd_blktrans(&inftl_tr); diff -Nru a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c --- a/drivers/mtd/inftlmount.c Fri Jun 27 14:19:52 2003 +++ b/drivers/mtd/inftlmount.c Fri Jun 27 14:19:52 2003 @@ -8,7 +8,7 @@ * Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Copyright (C) 2000 Netgem S.A. * - * $Id: inftlmount.c,v 1.9 2003/05/23 11:35:07 dwmw2 Exp $ + * $Id: inftlmount.c,v 1.11 2003/06/23 07:39:21 dwmw2 Exp $ * * 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 @@ -25,7 +25,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define __NO_VERSION__ #include <linux/kernel.h> #include <linux/module.h> #include <asm/errno.h> @@ -42,7 +41,7 @@ #include <linux/mtd/inftl.h> #include <linux/mtd/compatmac.h> -char inftlmountrev[]="$Revision: 1.9 $"; +char inftlmountrev[]="$Revision: 1.11 $"; /* * find_boot_record: Find the INFTL Media Header and its Spare copy which @@ -242,7 +241,7 @@ } if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) { printk(KERN_WARNING "INFTL: Media Header " - "Parition %d sanity check failed\n" + "Partition %d sanity check failed\n" " firstUnit %d : lastUnit %d > " "virtualUnits %d\n", i, ip->lastUnit, ip->firstUnit, ip->Reserved0); @@ -250,7 +249,7 @@ } if (ip->Reserved1 != 0) { printk(KERN_WARNING "INFTL: Media Header " - "Parition %d sanity check failed: " + "Partition %d sanity check failed: " "Reserved1 %d != 0\n", i, ip->Reserved1); return -1; @@ -261,7 +260,7 @@ } if (i >= 4) { - printk(KERN_WARNING "INFTL: Media Header Parition " + printk(KERN_WARNING "INFTL: Media Header Partition " "sanity check failed:\n No partition " "marked as Disk Partition\n"); return -1; @@ -630,7 +629,7 @@ if (prev_block < s->nb_blocks) prev_block += s->firstEUN; - /* Already explored paritial chain? */ + /* Already explored partial chain? */ if (s->PUtable[block] != BLOCK_NOTEXPLORED) { /* Check if chain for this logical */ if (logical_block == first_logical_block) { diff -Nru a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig --- a/drivers/mtd/maps/Kconfig Fri Jun 27 14:20:05 2003 +++ b/drivers/mtd/maps/Kconfig Fri Jun 27 14:20:05 2003 @@ -1,5 +1,5 @@ # drivers/mtd/maps/Kconfig -# $Id: Kconfig,v 1.11 2003/05/28 15:16:56 dwmw2 Exp $ +# $Id: Kconfig,v 1.12 2003/06/23 07:38:11 dwmw2 Exp $ menu "Mapping drivers for chip access" depends on MTD!=n @@ -476,7 +476,7 @@ config MTD_UCLINUX tristate "Generic uClinux RAM/ROM filesystem support" - depends on MTD_PARTITIONS + depends on MTD_PARTITIONS && !MMU help Map driver to support image based filesystems for uClinux. diff -Nru a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c --- a/drivers/mtd/maps/arctic-mtd.c Fri Jun 27 14:19:55 2003 +++ b/drivers/mtd/maps/arctic-mtd.c Fri Jun 27 14:19:55 2003 @@ -1,5 +1,5 @@ /* - * $Id: arctic-mtd.c,v 1.8 2003/05/21 12:45:17 dwmw2 Exp $ + * $Id: arctic-mtd.c,v 1.10 2003/06/02 16:37:59 trini Exp $ * * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for * IBM 405LP Arctic boards. @@ -45,18 +45,23 @@ #include <asm/ibm4xx.h> /* - * fe000000 -- ff9fffff Arctic FFS (26MB) - * ffa00000 -- fff5ffff kernel (5.504MB) - * fff60000 -- ffffffff firmware (640KB) + * 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB) + * 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB) + * 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP) + * 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB) */ -#define ARCTIC_FFS_SIZE 0x01a00000 /* 26 M */ -#define ARCTIC_FIRMWARE_SIZE 0x000a0000 /* 640K */ +#define FFS1_SIZE 0x01000000 /* 16MiB */ +#define KERNEL_SIZE 0x00500000 /* 5.12MiB */ +#define FFS2_SIZE 0x00a60000 /* 10.624MiB */ +#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */ -#define NAME "Arctic Linux Flash" -#define PADDR SUBZERO_BOOTFLASH_PADDR -#define SIZE SUBZERO_BOOTFLASH_SIZE -#define BUSWIDTH 2 + +#define NAME "Arctic Linux Flash" +#define PADDR SUBZERO_BOOTFLASH_PADDR +#define BUSWIDTH 2 +#define SIZE SUBZERO_BOOTFLASH_SIZE +#define PARTITIONS 4 /* Flash memories on these boards are memory resources, accessed big-endian. */ @@ -73,17 +78,19 @@ static struct mtd_info *arctic_mtd; -static struct mtd_partition arctic_partitions[3] = { - { .name = "Arctic FFS", - .size = ARCTIC_FFS_SIZE, +static struct mtd_partition arctic_partitions[PARTITIONS] = { + { .name = "Filesystem", + .size = FFS1_SIZE, .offset = 0,}, - { .name = "Kernel", - .size = SUBZERO_BOOTFLASH_SIZE - ARCTIC_FFS_SIZE - - ARCTIC_FIRMWARE_SIZE, - .offset = ARCTIC_FFS_SIZE,}, + { .name = "Kernel", + .size = KERNEL_SIZE, + .offset = FFS1_SIZE,}, + { .name = "Filesystem", + .size = FFS2_SIZE, + .offset = FFS1_SIZE + KERNEL_SIZE,}, { .name = "Firmware", - .size = ARCTIC_FIRMWARE_SIZE, - .offset = SUBZERO_BOOTFLASH_SIZE - ARCTIC_FIRMWARE_SIZE,}, + .size = FIRMWARE_SIZE, + .offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,}, }; static int __init @@ -107,7 +114,7 @@ arctic_mtd->owner = THIS_MODULE; - return add_mtd_partitions(arctic_mtd, arctic_partitions, 3); + return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS); } static void __exit diff -Nru a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c --- a/drivers/mtd/maps/ebony.c Fri Jun 27 14:20:00 2003 +++ b/drivers/mtd/maps/ebony.c Fri Jun 27 14:20:00 2003 @@ -1,5 +1,5 @@ /* - * $Id: ebony.c,v 1.7 2003/05/21 12:45:18 dwmw2 Exp $ + * $Id: ebony.c,v 1.8 2003/06/23 11:48:18 dwmw2 Exp $ * * Mapping for Ebony user flash * @@ -60,8 +60,6 @@ } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_ebony(void) { u8 fpga0_reg; @@ -109,7 +107,7 @@ if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ebony_small_partitions, - NB_OF(ebony_small_partitions)); + ARRAY_SIZE(ebony_small_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; @@ -131,7 +129,7 @@ if (flash) { flash->owner = THIS_MODULE; add_mtd_partitions(flash, ebony_large_partitions, - NB_OF(ebony_large_partitions)); + ARRAY_SIZE(ebony_large_partitions)); } else { printk("map probe failed for flash\n"); return -ENXIO; diff -Nru a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c --- a/drivers/mtd/maps/edb7312.c Fri Jun 27 14:20:06 2003 +++ b/drivers/mtd/maps/edb7312.c Fri Jun 27 14:20:06 2003 @@ -1,5 +1,5 @@ /* - * $Id: edb7312.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $ + * $Id: edb7312.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ * * Handle mapping of the NOR flash on Cogent EDB7312 boards * @@ -67,7 +67,6 @@ }, }; -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; #endif @@ -109,7 +108,7 @@ if (mtd_parts_nb == 0) { mtd_parts = static_partitions; - mtd_parts_nb = NB_OF(static_partitions); + mtd_parts_nb = ARRAY_SIZE(static_partitions); part_type = "static"; } #endif diff -Nru a/drivers/mtd/maps/elan-104nc.c b/drivers/mtd/maps/elan-104nc.c --- a/drivers/mtd/maps/elan-104nc.c Fri Jun 27 14:19:56 2003 +++ b/drivers/mtd/maps/elan-104nc.c Fri Jun 27 14:19:56 2003 @@ -16,7 +16,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - $Id: elan-104nc.c,v 1.17 2003/05/21 15:15:07 dwmw2 Exp $ + $Id: elan-104nc.c,v 1.18 2003/06/23 07:37:02 dwmw2 Exp $ The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16 mode. This drivers uses the CFI probe and Intel Extended Command Set drivers. @@ -223,30 +223,19 @@ } iounmap((void *)iomapadr); - release_region(PAGE_IO,PAGE_IO_SIZE); } int __init init_elan_104nc(void) { - /* Urg! We use I/O port 0x22 without request_region()ing it */ - /* - if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) { - printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", - elan_104nc_map.name, - PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 ); - return -EAGAIN; - } - */ + /* Urg! We use I/O port 0x22 without request_region()ing it, + because it's already allocated to the PIC. */ + iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH); if (!iomapadr) { printk( KERN_ERR"%s: failed to ioremap memory region\n", elan_104nc_map.name ); return -EIO; } - - /* - request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" ); - */ printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", elan_104nc_map.name, diff -Nru a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c --- a/drivers/mtd/maps/impa7.c Fri Jun 27 14:19:54 2003 +++ b/drivers/mtd/maps/impa7.c Fri Jun 27 14:19:54 2003 @@ -1,5 +1,5 @@ /* - * $Id: impa7.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $ + * $Id: impa7.c,v 1.9 2003/06/23 11:47:43 dwmw2 Exp $ * * Handle mapping of the NOR flash on implementa A7 boards * @@ -66,12 +66,11 @@ }, }; -#define NB_OF(x) (sizeof (x) / sizeof (x[0])) +static int mtd_parts_nb[NUM_FLASHBANKS]; +static struct mtd_partition *mtd_parts[NUM_FLASHBANKS]; #endif -static int mtd_parts_nb = 0; -static struct mtd_partition *mtd_parts = 0; static const char *probes[] = { "cmdlinepart", NULL }; int __init init_impa7(void) @@ -84,7 +83,6 @@ { WINDOW_ADDR0, WINDOW_SIZE0 }, { WINDOW_ADDR1, WINDOW_SIZE1 }, }; - char mtdid[10]; int devicesfound = 0; for(i=0; i<NUM_FLASHBANKS; i++) @@ -107,42 +105,34 @@ impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]); } - if (impa7_mtd[i]) - { + if (impa7_mtd[i]) { impa7_mtd[i]->owner = THIS_MODULE; - add_mtd_device(impa7_mtd[i]); devicesfound++; #ifdef CONFIG_MTD_PARTITIONS - mtd_parts_nb = parse_mtd_partitions(impa7_mtd[i], - probes, - &mtd_parts, - 0); - if (mtd_parts_nb > 0) - part_type = "command line"; -#endif - if (mtd_parts_nb <= 0) - { - mtd_parts = static_partitions; - mtd_parts_nb = NB_OF(static_partitions); + mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], + probes, + &mtd_parts[i], + 0); + if (mtd_parts_nb[i] > 0) { + part_type = "command line"; + } else { + mtd_parts[i] = static_partitions; + mtd_parts_nb[i] = ARRAY_SIZE(static_partitions); part_type = "static"; } - if (mtd_parts_nb <= 0) - { - printk(KERN_NOTICE MSG_PREFIX - "no partition info available\n"); - } - else - { - printk(KERN_NOTICE MSG_PREFIX - "using %s partition definition\n", - part_type); - add_mtd_partitions(impa7_mtd[i], - mtd_parts, mtd_parts_nb); - } + + printk(KERN_NOTICE MSG_PREFIX + "using %s partition definition\n", + part_type); + add_mtd_partitions(impa7_mtd[i], + mtd_parts[i], mtd_parts_nb[i]); +#else + add_mtd_device(impa7_mtd[i]); + #endif } else - iounmap((void *)impa7_map[i].virt); + iounmap((void *)impa7_map[i].virt); } return devicesfound == 0 ? -ENXIO : 0; } @@ -150,15 +140,14 @@ static void __exit cleanup_impa7(void) { int i; - for (i=0; i<NUM_FLASHBANKS; i++) - { - if (impa7_mtd[i]) - { + for (i=0; i<NUM_FLASHBANKS; i++) { + if (impa7_mtd[i]) { +#ifdef CONFIG_MTD_PARTITIONS + del_mtd_partitions(impa7_mtd[i]); +#else del_mtd_device(impa7_mtd[i]); +#endif map_destroy(impa7_mtd[i]); - } - if (impa7_map[i].virt) - { iounmap((void *)impa7_map[i].virt); impa7_map[i].virt = 0; } diff -Nru a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c --- a/drivers/mtd/maps/iq80310.c Fri Jun 27 14:20:03 2003 +++ b/drivers/mtd/maps/iq80310.c Fri Jun 27 14:20:03 2003 @@ -1,5 +1,5 @@ /* - * $Id: iq80310.c,v 1.16 2003/05/21 15:15:07 dwmw2 Exp $ + * $Id: iq80310.c,v 1.17 2003/06/23 11:48:18 dwmw2 Exp $ * * Mapping for the Intel XScale IQ80310 evaluation board * @@ -57,8 +57,6 @@ } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - static struct mtd_info *mymtd; static struct mtd_partition *parsed_parts; static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; @@ -94,7 +92,7 @@ nb_parts = parsed_nr_parts; } else { parts = iq80310_partitions; - nb_parts = NB_OF(iq80310_partitions); + nb_parts = ARRAY_SIZE(iq80310_partitions); } add_mtd_partitions(mymtd, parts, nb_parts); return 0; diff -Nru a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c --- a/drivers/mtd/maps/lubbock-flash.c Fri Jun 27 14:19:59 2003 +++ b/drivers/mtd/maps/lubbock-flash.c Fri Jun 27 14:19:59 2003 @@ -1,5 +1,5 @@ /* - * $Id: lubbock-flash.c,v 1.8 2003/05/21 12:45:19 dwmw2 Exp $ + * $Id: lubbock-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ * * Map driver for the Lubbock developer platform. * @@ -52,8 +52,6 @@ } }; -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - static struct mtd_info *mymtds[2]; static struct mtd_partition *parsed_parts[2]; static int nr_parsed_parts[2]; @@ -116,7 +114,7 @@ add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]); } else if (!i) { printk("Using static partitions on %s\n", lubbock_maps[i].name); - add_mtd_partitions(mymtds[i], lubbock_partitions, NB_OF(lubbock_partitions)); + add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions)); } else { printk("Registering %s as whole device\n", lubbock_maps[i].name); add_mtd_device(mymtds[i]); diff -Nru a/drivers/mtd/maps/pb1xxx-flash.c b/drivers/mtd/maps/pb1xxx-flash.c --- a/drivers/mtd/maps/pb1xxx-flash.c Fri Jun 27 14:20:06 2003 +++ b/drivers/mtd/maps/pb1xxx-flash.c Fri Jun 27 14:20:06 2003 @@ -3,7 +3,7 @@ * * (C) 2001 Pete Popov <ppopov@mvista.com> * - * $Id: pb1xxx-flash.c,v 1.8 2003/05/21 12:45:19 dwmw2 Exp $ + * $Id: pb1xxx-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ */ #include <linux/config.h> @@ -131,9 +131,6 @@ #error Unsupported board #endif - -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - static struct mtd_partition *parsed_parts; static struct mtd_info *mymtd; @@ -151,7 +148,7 @@ */ part_type = "static"; parts = pb1xxx_partitions; - nb_parts = NB_OF(pb1xxx_partitions); + nb_parts = ARRAY_SIZE(pb1xxx_partitions); pb1xxx_map.size = flash_size; /* diff -Nru a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c --- a/drivers/mtd/maps/tqm8xxl.c Fri Jun 27 14:19:54 2003 +++ b/drivers/mtd/maps/tqm8xxl.c Fri Jun 27 14:19:54 2003 @@ -2,7 +2,7 @@ * Handle mapping of the flash memory access routines * on TQM8xxL based devices. * - * $Id: tqm8xxl.c,v 1.8 2003/05/21 12:45:20 dwmw2 Exp $ + * $Id: tqm8xxl.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $ * * based on rpxlite.c * @@ -110,8 +110,6 @@ }; #endif -#define NB_OF(x) (sizeof(x)/sizeof(x[0])) - int __init init_tqm_mtd(void) { int idx = 0, ret = 0; @@ -198,11 +196,11 @@ */ part_banks[0].mtd_part = tqm8xxl_partitions; part_banks[0].type = "Static image"; - part_banks[0].nums = NB_OF(tqm8xxl_partitions); + part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions); part_banks[1].mtd_part = tqm8xxl_fs_partitions; part_banks[1].type = "Static file system"; - part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions); + part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions); for(idx = 0; idx < num_banks ; idx++) { if (part_banks[idx].nums == 0) { diff -Nru a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c --- a/drivers/mtd/mtd_blkdevs.c Fri Jun 27 14:19:52 2003 +++ b/drivers/mtd/mtd_blkdevs.c Fri Jun 27 14:19:52 2003 @@ -1,5 +1,5 @@ /* - * $Id: mtd_blkdevs.c,v 1.12 2003/05/21 01:00:59 dwmw2 Exp $ + * $Id: mtd_blkdevs.c,v 1.16 2003/06/23 13:34:43 dwmw2 Exp $ * * (C) 2003 David Woodhouse <dwmw2@infradead.org> * @@ -18,8 +18,10 @@ #include <linux/blk.h> #include <linux/blkpg.h> #include <linux/spinlock.h> +#include <linux/hdreg.h> #include <linux/init.h> #include <asm/semaphore.h> +#include <asm/uaccess.h> #include <linux/devfs_fs_kernel.h> static LIST_HEAD(blktrans_majors); @@ -46,7 +48,7 @@ nsect = req->current_nr_sectors; buf = req->buffer; - if (!req->flags & REQ_CMD) + if (!(req->flags & REQ_CMD)) return 0; if (block + nsect > get_capacity(req->rq_disk)) @@ -93,14 +95,14 @@ recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + spin_lock_irq(rq->queue_lock); + while (!tr->blkcore_priv->exiting) { struct request *req; struct mtd_blktrans_dev *dev; int res = 0; DECLARE_WAITQUEUE(wait, current); - spin_lock_irq(rq->queue_lock); - req = elv_next_request(rq); if (!req) { @@ -112,6 +114,8 @@ schedule(); remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait); + spin_lock_irq(rq->queue_lock); + continue; } @@ -159,7 +163,7 @@ dev->mtd->usecount++; ret = 0; - if (tr->open && (ret = tr->open(dev, i, f))) { + if (tr->open && (ret = tr->open(dev))) { dev->mtd->usecount--; module_put(dev->mtd->owner); out_tr: @@ -179,7 +183,7 @@ tr = dev->tr; if (tr->release) - ret = tr->release(dev, i, f); + ret = tr->release(dev); if (!ret) { dev->mtd->usecount--; @@ -194,21 +198,33 @@ static int blktrans_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct mtd_blktrans_dev *dev; - struct mtd_blktrans_ops *tr; - int ret = -ENOTTY; - - dev = inode->i_bdev->bd_disk->private_data; - tr = dev->tr; + struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data; + struct mtd_blktrans_ops *tr = dev->tr; - if (tr->ioctl) - ret = tr->ioctl(dev, inode, file, cmd, arg); - - if (ret == -ENOTTY && (cmd == BLKROSET || cmd == BLKFLSBUF)) { + switch (cmd) { + case BLKFLSBUF: + if (tr->flush) + return tr->flush(dev); /* The core code did the work, we had nothing to do. */ - ret = 0; + return 0; + + case HDIO_GETGEO: + if (tr->getgeo) { + struct hd_geometry g; + + memset(&g, 0, sizeof(g)); + int ret = tr->getgeo(dev, &g); + if (ret) + return ret; + + g.start = get_start_sect(inode->i_bdev); + if (copy_to_user((void *)arg, &g, sizeof(g))) + return -EFAULT; + return 0; + } /* else */ + default: + return -ENOTTY; } - return ret; } struct block_device_operations mtd_blktrans_ops = { @@ -328,8 +344,6 @@ if (mtd->type == MTD_ABSENT) return; - printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count)); - list_for_each(this, &blktrans_majors) { struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); @@ -391,8 +405,6 @@ INIT_LIST_HEAD(&tr->devs); list_add(&tr->list, &blktrans_majors); - - printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count)); for (i=0; i<MAX_MTD_DEVICES; i++) { if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT) diff -Nru a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c --- a/drivers/mtd/mtdblock.c Fri Jun 27 14:19:55 2003 +++ b/drivers/mtd/mtdblock.c Fri Jun 27 14:19:55 2003 @@ -1,7 +1,7 @@ /* * Direct MTD block device access * - * $Id: mtdblock.c,v 1.61 2003/05/21 10:49:38 dwmw2 Exp $ + * $Id: mtdblock.c,v 1.63 2003/06/23 12:00:08 dwmw2 Exp $ * * (C) 2000-2003 Nicolas Pitre <nico@cam.org> * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> @@ -248,11 +248,19 @@ unsigned long block, char *buf) { struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; + if (unlikely(!mtdblk->cache_data)) { + mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); + if (!mtdblk->cache_data) + return -EINTR; + /* -EINTR is not really correct, but it is the best match + * documented in man 2 write for all cases. We could also + * return -EAGAIN sometimes, but why bother? + */ + } return do_cached_write(mtdblk, block<<9, 512, buf); } -static int mtdblock_open(struct mtd_blktrans_dev *mbd, - struct inode *inode, struct file *file) +static int mtdblock_open(struct mtd_blktrans_dev *mbd) { struct mtdblk_dev *mtdblk; struct mtd_info *mtd = mbd->mtd; @@ -279,11 +287,7 @@ if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && mtdblk->mtd->erasesize) { mtdblk->cache_size = mtdblk->mtd->erasesize; - mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); - if (!mtdblk->cache_data) { - kfree(mtdblk); - return -ENOMEM; - } + mtdblk->cache_data = NULL; } mtdblks[dev] = mtdblk; @@ -293,17 +297,13 @@ return 0; } -static int mtdblock_release(struct mtd_blktrans_dev *mbd, - struct inode *inode, struct file *file) +static int mtdblock_release(struct mtd_blktrans_dev *mbd) { - int dev; - struct mtdblk_dev *mtdblk; + int dev = mbd->devnum; + struct mtdblk_dev *mtdblk = mtdblks[dev]; DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); - dev = minor(inode->i_rdev); - mtdblk = mtdblks[dev]; - down(&mtdblk->cache_sem); write_cached_data(mtdblk); up(&mtdblk->cache_sem); @@ -321,27 +321,17 @@ return 0; } - -static int mtdblock_ioctl(struct mtd_blktrans_dev *dev, - struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) +static int mtdblock_flush(struct mtd_blktrans_dev *dev) { - struct mtdblk_dev *mtdblk; - - mtdblk = mtdblks[minor(inode->i_rdev)]; + struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; - switch (cmd) { - case BLKFLSBUF: - down(&mtdblk->cache_sem); - write_cached_data(mtdblk); - up(&mtdblk->cache_sem); - if (mtdblk->mtd->sync) - mtdblk->mtd->sync(mtdblk->mtd); - return 0; + down(&mtdblk->cache_sem); + write_cached_data(mtdblk); + up(&mtdblk->cache_sem); - default: - return -ENOTTY; - } + if (mtdblk->mtd->sync) + mtdblk->mtd->sync(mtdblk->mtd); + return 0; } static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) @@ -376,7 +366,7 @@ .major = 31, .part_bits = 0, .open = mtdblock_open, - .ioctl = mtdblock_ioctl, + .flush = mtdblock_flush, .release = mtdblock_release, .readsect = mtdblock_readsect, .writesect = mtdblock_writesect, diff -Nru a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c --- a/drivers/mtd/mtdblock_ro.c Fri Jun 27 14:19:56 2003 +++ b/drivers/mtd/mtdblock_ro.c Fri Jun 27 14:19:56 2003 @@ -1,11 +1,12 @@ /* - * $Id: mtdblock_ro.c,v 1.17 2003/05/18 19:27:27 dwmw2 Exp $ + * $Id: mtdblock_ro.c,v 1.18 2003/06/23 12:00:08 dwmw2 Exp $ * * (C) 2003 David Woodhouse <dwmw2@infradead.org> * * Simple read-only (writable only for RAM) mtdblock driver */ +#include <linux/init.h> #include <linux/slab.h> #include <linux/mtd/mtd.h> #include <linux/mtd/blktrans.h> diff -Nru a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c --- a/drivers/mtd/mtdpart.c Fri Jun 27 14:19:59 2003 +++ b/drivers/mtd/mtdpart.c Fri Jun 27 14:19:59 2003 @@ -5,7 +5,7 @@ * * This code is GPL * - * $Id: mtdpart.c,v 1.39 2003/05/21 15:15:03 dwmw2 Exp $ + * $Id: mtdpart.c,v 1.41 2003/06/18 14:53:02 dwmw2 Exp $ * * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> * added support for read_oob, write_oob @@ -120,7 +120,7 @@ size_t *retlen, u_char *buf) { struct mtd_part *part = PART(mtd); - return part->master->read_user_prot_reg (part->master, from, + return part->master->read_fact_prot_reg (part->master, from, len, retlen, buf); } diff -Nru a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c --- a/drivers/mtd/nand/autcpu12.c Fri Jun 27 14:19:54 2003 +++ b/drivers/mtd/nand/autcpu12.c Fri Jun 27 14:19:54 2003 @@ -6,7 +6,7 @@ * Derived from drivers/mtd/spia.c * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * - * $Id: autcpu12.c,v 1.10 2003/04/20 07:24:40 gleixner Exp $ + * $Id: autcpu12.c,v 1.11 2003/06/04 17:04:09 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -28,6 +28,7 @@ */ #include <linux/slab.h> +#include <linux/init.h> #include <linux/module.h> #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> diff -Nru a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c --- a/drivers/mtd/nand/nand.c Fri Jun 27 14:20:06 2003 +++ b/drivers/mtd/nand/nand.c Fri Jun 27 14:20:06 2003 @@ -124,9 +124,15 @@ + a structure, which will be supplied by a filesystem driver * If NULL is given, then the defaults (none or defaults * supplied by ioctl (MEMSETOOBSEL) are used. - * For partitions the partition defaults are used (mtdpart.c) + * For partitions the partition defaults are used (mtdpart.c) + * + * 06-04-2003 tglx: fix compile errors and fix write verify problem for + * some chips, which need either a delay between the readback + * and the next write command or have the CE removed. The + * CE disable/enable is much faster than a 20us delay and + * it should work on all available chips. * - * $Id: nand.c,v 1.45 2003/05/20 21:01:30 dwmw2 Exp $ + * $Id: nand.c,v 1.46 2003/06/04 17:10:36 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -141,6 +147,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/nand_ecc.h> +#include <linux/mtd/compatmac.h> #include <linux/interrupt.h> #include <asm/io.h> @@ -510,6 +517,13 @@ } } } + /* + * Terminate the read command. This is faster than sending a reset command or + * applying a 20us delay before issuing the next programm sequence. + * This is not a problem for all chips, but I have found a bunch of them. + */ + nand_deselect(); + nand_select(); #endif return 0; } diff -Nru a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c --- a/drivers/mtd/nftlcore.c Fri Jun 27 14:19:52 2003 +++ b/drivers/mtd/nftlcore.c Fri Jun 27 14:19:52 2003 @@ -1,7 +1,7 @@ /* Linux driver for NAND Flash Translation Layer */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse <dwmw2@infradead.org> */ -/* $Id: nftlcore.c,v 1.92 2003/05/23 11:41:47 dwmw2 Exp $ */ +/* $Id: nftlcore.c,v 1.94 2003/06/23 12:00:08 dwmw2 Exp $ */ /* The contents of this file are distributed under the GNU General @@ -101,7 +101,7 @@ (long)nftl->sectors ); } - if (add_mtd_blktrans_dev) { + if (add_mtd_blktrans_dev(&nftl->mbd)) { if (nftl->ReplUnitTable) kfree(nftl->ReplUnitTable); if (nftl->EUNtable) @@ -699,29 +699,17 @@ return 0; } -static int nftl_ioctl(struct mtd_blktrans_dev *dev, - struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) +static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) { struct NFTLrecord *nftl = (void *)dev; - switch (cmd) { - case HDIO_GETGEO: { - struct hd_geometry g; - - g.heads = nftl->heads; - g.sectors = nftl->sectors; - g.cylinders = nftl->cylinders; - g.start = 0; - return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; - } + geo->heads = nftl->heads; + geo->sectors = nftl->sectors; + geo->cylinders = nftl->cylinders; - default: - return -ENOTTY; - } + return 0; } - /**************************************************************************** * * Module stuff @@ -733,7 +721,7 @@ .name = "nftl", .major = NFTL_MAJOR, .part_bits = NFTL_PARTN_BITS, - .ioctl = nftl_ioctl, + .getgeo = nftl_getgeo, .readsect = nftl_readblock, #ifdef CONFIG_NFTL_RW .writesect = nftl_writeblock, @@ -747,7 +735,7 @@ int __init init_nftl(void) { - printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.92 $, nftlmount.c %s\n", nftlmountrev); + printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.94 $, nftlmount.c %s\n", nftlmountrev); return register_mtd_blktrans(&nftl_tr); } diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig --- a/drivers/net/Kconfig Fri Jun 27 14:20:01 2003 +++ b/drivers/net/Kconfig Fri Jun 27 14:20:01 2003 @@ -492,16 +492,16 @@ help Say Y here to support the Ethernet subsystem on your GT96100 card. -config MIPS_AU1000_ENET +config MIPS_AU1X00_ENET bool "MIPS AU1000 Ethernet support" - depends on NET_ETHERNET && MIPS_AU1000 + depends on NET_ETHERNET && SOC_AU1X00 help - If you have an Alchemy Semi AU1000 ethernet controller - on an SGI MIPS system, say Y. Otherwise, say N. + If you have an Alchemy Semi AU1X00 based system + say Y. Otherwise, say N. config NET_SB1250_MAC tristate "SB1250 Ethernet support" - depends on NET_ETHERNET && SIBYTE_SB1250 + depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC config SGI_IOC3_ETH bool "SGI IOC3 Ethernet" @@ -511,6 +511,10 @@ the Ethernet-HOWTO, available from <http://www.tldp.org/docs.html#howto>. +config SGI_O2MACE_ETH + tristate "SGI O2 MACE Fast Ethernet support" + depends on NET_ETHERNET && SGI_IP32=y + config STNIC tristate "National DP83902AV support" depends on NET_ETHERNET && SUPERH @@ -1391,6 +1395,10 @@ <file:Documentation/networking/net-modules.txt>. The module will be called cs89x. +config TC35815 + tristate "TOSHIBA TC35815 Ethernet support" + depends on NET_PCI && PCI + config DGRS tristate "Digi Intl. RightSwitch SE-X support" depends on NET_PCI && (PCI || EISA) @@ -1839,14 +1847,14 @@ The module will be called de620. config SGISEEQ - bool "SGI Seeq ethernet controller support" + tristate "SGI Seeq ethernet controller support" depends on NET_ETHERNET && SGI_IP22 help Say Y here if you have an Seeq based Ethernet network card. This is used in many Silicon Graphics machines. config DECLANCE - bool "DEC LANCE ethernet controller support" + tristate "DEC LANCE ethernet controller support" depends on NET_ETHERNET && DECSTATION help This driver is for the series of Ethernet controllers produced by diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Fri Jun 27 14:19:54 2003 +++ b/drivers/net/Makefile Fri Jun 27 14:19:54 2003 @@ -117,6 +117,7 @@ obj-$(CONFIG_SUN3LANCE) += sun3lance.o obj-$(CONFIG_DEFXX) += defxx.o obj-$(CONFIG_SGISEEQ) += sgiseeq.o +obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o obj-$(CONFIG_AT1700) += at1700.o obj-$(CONFIG_FMV18X) += fmv18x.o obj-$(CONFIG_EL1) += 3c501.o @@ -156,7 +157,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o -obj-$(CONFIG_MIPS_AU1000_ENET) += au1000_eth.o +obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o obj-$(CONFIG_BAGETLANCE) += bagetlance.o obj-$(CONFIG_DECLANCE) += declance.o diff -Nru a/drivers/net/Makefile.lib b/drivers/net/Makefile.lib --- a/drivers/net/Makefile.lib Fri Jun 27 14:20:00 2003 +++ b/drivers/net/Makefile.lib Fri Jun 27 14:20:00 2003 @@ -24,6 +24,7 @@ obj-$(CONFIG_PCMCIA_SMC91C92) += crc32.o obj-$(CONFIG_PCMCIA_XIRTULIP) += crc32.o obj-$(CONFIG_PCNET32) += crc32.o +obj-$(CONFIG_SGI_IOC3_ETH) += crc32.o obj-$(CONFIG_SIS900) += crc32.o obj-$(CONFIG_SMC9194) += crc32.o obj-$(CONFIG_ADAPTEC_STARFIRE) += crc32.o diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c --- a/drivers/net/Space.c Fri Jun 27 14:19:53 2003 +++ b/drivers/net/Space.c Fri Jun 27 14:19:53 2003 @@ -82,7 +82,6 @@ extern int SK_init(struct net_device *); extern int seeq8005_probe(struct net_device *); extern int smc_init( struct net_device * ); -extern int sgiseeq_probe(struct net_device *); extern int atarilance_probe(struct net_device *); extern int sun3lance_probe(struct net_device *); extern int sun3_82586_probe(struct net_device *); @@ -343,14 +342,6 @@ {NULL, 0}, }; - -static struct devprobe sgi_probes[] __initdata = { -#ifdef CONFIG_SGISEEQ - {sgiseeq_probe, 0}, -#endif - {NULL, 0}, -}; - static struct devprobe mips_probes[] __initdata = { #ifdef CONFIG_MIPS_JAZZ_SONIC {sonic_probe, 0}, @@ -384,8 +375,6 @@ if (probe_list(dev, m68k_probes) == 0) return 0; if (probe_list(dev, mips_probes) == 0) - return 0; - if (probe_list(dev, sgi_probes) == 0) return 0; if (probe_list(dev, eisa_probes) == 0) return 0; diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c --- a/drivers/net/acenic.c Fri Jun 27 14:19:56 2003 +++ b/drivers/net/acenic.c Fri Jun 27 14:19:56 2003 @@ -3026,9 +3026,6 @@ return 0; case ETHTOOL_SSET: - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - link = readl(®s->GigLnkState); if (link & LNK_1000MB) speed = SPEED_1000; diff -Nru a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c --- a/drivers/net/au1000_eth.c Fri Jun 27 14:19:57 2003 +++ b/drivers/net/au1000_eth.c Fri Jun 27 14:19:57 2003 @@ -1,13 +1,10 @@ /* - * * Alchemy Semi Au1000 ethernet driver * * Copyright 2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -20,16 +17,8 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * */ - -#ifndef __mips__ -#error This driver only works with MIPS architectures! -#endif - +#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> @@ -125,7 +114,7 @@ }, au1100_iflist[NUM_INTERFACES] = { {AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, - {NULL, NULL} + {0, 0} }; static char version[] __devinitdata = @@ -152,13 +141,6 @@ * code. */ -static char *phy_link[] = - {"unknown", - "10Base2", "10BaseT", - "AUI", - "100BaseT", "100BaseTX", "100BaseFX" - }; - int bcm_5201_init(struct net_device *dev, int phy_addr) { s16 data; @@ -184,6 +166,11 @@ data &= ~MII_FDX_LED; mdio_write(dev, phy_addr, MII_INT, data); + /* Enable TX LED instead of FDX */ + data = mdio_read(dev, phy_addr, MII_INT); + data &= ~MII_FDX_LED; + mdio_write(dev, phy_addr, MII_INT, data); + if (au1000_debug > 4) dump_mii(dev, phy_addr); return 0; } @@ -640,7 +627,7 @@ int prid; int base_addr, irq; - prid = read_32bit_cp0_register(CP0_PRID); + prid = read_c0_prid(); for (i=0; i<NUM_INTERFACES; i++) { if ( (prid & 0xffff0000) == 0x00030000 ) { base_addr = au1000_iflist[i].port; @@ -657,11 +644,11 @@ } // check for valid entries, au1100 only has one entry if (base_addr && irq) { - if (au1000_probe1(NULL, base_addr, irq, i) != 0) { - return -ENODEV; + if (au1000_probe1(NULL, base_addr, irq, i) != 0) { + return -ENODEV; + } } } - } return 0; } @@ -675,10 +662,11 @@ char *pmac, *argptr; char ethaddr[6]; - if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) + if (!request_region(PHYSADDR(ioaddr), MAC_IOSIZE, "Au1000 ENET")) return -ENODEV; - if (version_printed++ == 0) printk(version); + if (version_printed++ == 0) + printk(version); if (!dev) dev = init_etherdev(NULL, sizeof(struct au1000_private)); @@ -690,7 +678,7 @@ } printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", - dev->name, ioaddr, irq); + dev->name, ioaddr, irq); aup = dev->priv; @@ -816,7 +804,7 @@ return 0; free_region: - release_region(ioaddr, MAC_IOSIZE); + release_region(PHYSADDR(ioaddr), MAC_IOSIZE); unregister_netdev(dev); if (aup->vaddr) dma_free((void *)aup->vaddr, @@ -1047,8 +1035,9 @@ ptxd = aup->tx_dma_ring[aup->tx_tail]; while (ptxd->buff_stat & TX_T_DONE) { - update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); + update_tx_stats(dev, ptxd->status, aup->tx_len[aup->tx_tail] & 0x3ff); ptxd->buff_stat &= ~TX_T_DONE; + aup->tx_len[aup->tx_tail] = 0; ptxd->len = 0; au_sync(); @@ -1088,7 +1077,8 @@ return 1; } else if (buff_stat & TX_T_DONE) { - update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); + update_tx_stats(dev, ptxd->status, aup->tx_len[aup->tx_head] & 0x3ff); + aup->tx_len[aup->tx_head] = 0; ptxd->len = 0; } @@ -1103,11 +1093,13 @@ for (i=skb->len; i<MAC_MIN_PKT_SIZE; i++) { ((char *)pDB->vaddr)[i] = 0; } + aup->tx_len[aup->tx_head] = MAC_MIN_PKT_SIZE; ptxd->len = MAC_MIN_PKT_SIZE; } - else + else { + aup->tx_len[aup->tx_head] = skb->len; ptxd->len = skb->len; - + } ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; au_sync(); dev_kfree_skb(skb); @@ -1244,6 +1236,8 @@ printk(KERN_ERR "%s: au1000_tx_timeout: dev=%p\n", dev->name, dev); reset_mac(dev); au1000_init(dev); + dev->trans_start = jiffies; + netif_wake_queue(dev); } static void set_rx_mode(struct net_device *dev) @@ -1269,7 +1263,8 @@ mc_filter[1] = mc_filter[0] = 0; for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { - set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, mc_filter); + set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr)>>26, + mc_filter); } aup->mac->multi_hash_high = mc_filter[1]; aup->mac->multi_hash_low = mc_filter[0]; @@ -1285,18 +1280,21 @@ /* fixme */ switch(cmd) { - case SIOCGMIIPHY: /* Get the address of the PHY in use. */ + case SIOCGMIIPHY: /* Get the address of the PHY in use. */ data[0] = PHY_ADDRESS; + return 0; - case SIOCGMIIREG: /* Read the specified MII register. */ + case SIOCGMIIREG: /* Read the specified MII register. */ //data[3] = mdio_read(ioaddr, data[0], data[1]); return 0; - case SIOCSMIIREG: /* Write the specified MII register */ + case SIOCSMIIREG: /* Write the specified MII register */ if (!capable(CAP_NET_ADMIN)) return -EPERM; + //mdio_write(ioaddr, data[0], data[1], data[2]); return 0; + default: return -EOPNOTSUPP; } diff -Nru a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h --- a/drivers/net/au1000_eth.h Fri Jun 27 14:19:55 2003 +++ b/drivers/net/au1000_eth.h Fri Jun 27 14:19:55 2003 @@ -1,13 +1,10 @@ /* - * * Alchemy Semi Au1000 ethernet driver include file * * Author: Pete Popov <ppopov@mvista.com> * * Copyright 2001 MontaVista Software Inc. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -20,11 +17,8 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * */ +#include <linux/config.h> #define NUM_INTERFACES 2 @@ -137,7 +131,7 @@ #define MII_AUX_100 0x0002 #define MII_AUX_F100 0x0004 #define MII_AUX_ANEG 0x0008 -#define MII_FDX_LED 0x8000 +#define MII_FDX_LED 0x8000 typedef struct mii_phy { struct mii_phy * next; @@ -203,6 +197,7 @@ db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS]; volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA]; volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA]; + int tx_len[NUM_TX_DMA]; db_dest_t *rx_db_inuse[NUM_RX_DMA]; db_dest_t *tx_db_inuse[NUM_TX_DMA]; u32 rx_head; diff -Nru a/drivers/net/declance.c b/drivers/net/declance.c --- a/drivers/net/declance.c Fri Jun 27 14:19:57 2003 +++ b/drivers/net/declance.c Fri Jun 27 14:19:57 2003 @@ -5,6 +5,8 @@ * * adopted from sunlance.c by Richard van den Berg * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * * additional sources: * - PMAD-AA TURBOchannel Ethernet Module Functional Specification, * Revision 1.2 @@ -16,76 +18,71 @@ * v0.002: Removed most sparc stuff, left only some module and dma stuff. * * v0.003: Enhanced base address calculation from proposals by - * Harald Koerfgen and Thomas Riemer. + * Harald Koerfgen and Thomas Riemer. * * v0.004: lance-regs is pointing at the right addresses, added prom - * check. First start of address mapping and DMA. + * check. First start of address mapping and DMA. * - * v0.005: started to play around with LANCE-DMA. This driver will not work - * for non IOASIC lances. HK + * v0.005: started to play around with LANCE-DMA. This driver will not + * work for non IOASIC lances. HK * - * v0.006: added pointer arrays to lance_private and setup routine for them - * in dec_lance_init. HK + * v0.006: added pointer arrays to lance_private and setup routine for + * them in dec_lance_init. HK * - * v0.007: Big shit. The LANCE seems to use a different DMA mechanism to access - * the init block. This looks like one (short) word at a time, but the smallest - * amount the IOASIC can transfer is a (long) word. So we have a 2-2 padding here. - * Changed lance_init_block accordingly. The 16-16 padding for the buffers - * seems to be correct. HK + * v0.007: Big shit. The LANCE seems to use a different DMA mechanism to + * access the init block. This looks like one (short) word at a + * time, but the smallest amount the IOASIC can transfer is a + * (long) word. So we have a 2-2 padding here. Changed + * lance_init_block accordingly. The 16-16 padding for the buffers + * seems to be correct. HK * - * v0.008 - mods to make PMAX_LANCE work. 01/09/1999 triemer - */ - -#undef DEBUG_DRIVER - -static char *version = -"declance.c: v0.008 by Linux Mips DECstation task force\n"; - -static char *lancestr = "LANCE"; - -/* - * card types + * v0.008: mods to make PMAX_LANCE work. 01/09/1999 triemer + * + * v0.009: Module support fixes, multiple interfaces support, various + * bits. macro */ -#define ASIC_LANCE 1 -#define PMAD_LANCE 2 -#define PMAX_LANCE 3 +#include <linux/config.h> +#include <linux/crc32.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/if_ether.h> #include <linux/init.h> #include <linux/kernel.h> +#include <linux/module.h> #include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/spinlock.h> +#include <linux/stddef.h> +#include <linux/string.h> +#include <asm/addrspace.h> #include <asm/dec/interrupts.h> -#include <asm/dec/ioasic_ints.h> +#include <asm/dec/ioasic.h> #include <asm/dec/ioasic_addrs.h> +#include <asm/dec/kn01.h> #include <asm/dec/machtype.h> #include <asm/dec/tc.h> -#include <asm/dec/kn01.h> -#include <asm/wbflush.h> -#include <asm/addrspace.h> +#include <asm/system.h> -#include <linux/config.h> -#include <linux/errno.h> -#include <linux/hdreg.h> -#include <linux/ioport.h> -#include <linux/mm.h> -#include <linux/stddef.h> -#include <linux/string.h> -#include <linux/unistd.h> -#include <linux/slab.h> -#include <linux/user.h> -#include <linux/utsname.h> -#include <linux/a.out.h> -#include <linux/tty.h> -#include <linux/delay.h> -#include <linux/crc32.h> -#include <asm/io.h> -#include <linux/etherdevice.h> +static char version[] __devinitdata = +"declance.c: v0.009 by Linux MIPS DECstation task force\n"; + +MODULE_AUTHOR("Linux MIPS DECstation task force"); +MODULE_DESCRIPTION("DEC LANCE (DECstation onboard, PMAD-xx) driver"); +MODULE_LICENSE("GPL"); + +/* + * card types + */ +#define ASIC_LANCE 1 +#define PMAD_LANCE 2 +#define PMAX_LANCE 3 #ifndef CONFIG_TC unsigned long system_base; unsigned long dmaptr; #endif -static int type; #define LE_CSR0 0 #define LE_CSR1 1 @@ -160,8 +157,6 @@ #define TX_BUFF_SIZE PKT_BUF_SZ #undef TEST_HITS -#define DEBUG_DRIVER 1 - #define ZERO 0 /* The DS2000/3000 have a linear 64 KB buffer. @@ -179,26 +174,26 @@ */ struct lance_rx_desc { - unsigned short rmd0; /* low address of packet */ + unsigned short rmd0; /* low address of packet */ short gap0; unsigned char rmd1_hadr; /* high address of packet */ unsigned char rmd1_bits; /* descriptor bits */ short gap1; - short length; /* This length is 2s complement (negative)! - * Buffer length - */ + short length; /* 2s complement (negative!) + of buffer length */ short gap2; - unsigned short mblength; /* This is the actual number of bytes received */ + unsigned short mblength; /* actual number of bytes received */ short gap3; }; struct lance_tx_desc { - unsigned short tmd0; /* low address of packet */ + unsigned short tmd0; /* low address of packet */ short gap0; unsigned char tmd1_hadr; /* high address of packet */ unsigned char tmd1_bits; /* descriptor bits */ short gap1; - short length; /* Length is 2s complement (negative)! */ + short length; /* 2s complement (negative!) + of buffer length */ short gap2; unsigned short misc; short gap3; @@ -207,28 +202,26 @@ /* First part of the LANCE initialization block, described in databook. */ struct lance_init_block { - unsigned short mode; /* Pre-set mode (reg. 15) */ + unsigned short mode; /* pre-set mode (reg. 15) */ short gap0; - unsigned char phys_addr[12]; /* Physical ethernet address - * only 0, 1, 4, 5, 8, 9 are valid - * 2, 3, 6, 7, 10, 11 are gaps - */ - unsigned short filter[8]; /* Multicast filter. - * only 0, 2, 4, 6 are valid - * 1, 3, 5, 7 are gaps - */ + unsigned char phys_addr[12]; /* physical ethernet address + only 0, 1, 4, 5, 8, 9 are valid + 2, 3, 6, 7, 10, 11 are gaps */ + unsigned short filter[8]; /* multicast filter + only 0, 2, 4, 6 are valid + 1, 3, 5, 7 are gaps */ /* Receive and transmit ring base, along with extra bits. */ - unsigned short rx_ptr; /* receive descriptor addr */ + unsigned short rx_ptr; /* receive descriptor addr */ short gap1; - unsigned short rx_len; /* receive len and high addr */ + unsigned short rx_len; /* receive len and high addr */ short gap2; - unsigned short tx_ptr; /* transmit descriptor addr */ + unsigned short tx_ptr; /* transmit descriptor addr */ short gap3; - unsigned short tx_len; /* transmit len and high addr */ + unsigned short tx_len; /* transmit len and high addr */ short gap4; - char gap5[16]; + short gap5[8]; /* The buffer descriptors */ struct lance_rx_desc brx_ring[RX_RING_SIZE]; @@ -247,10 +240,12 @@ #define LANCE_ADDR(x) (PHYSADDR(x) >> 1) struct lance_private { - char *name; + struct net_device *next; + int type; + int slot; + int dma_irq; volatile struct lance_regs *ll; volatile struct lance_init_block *init_block; - volatile unsigned long *dma_ptr_reg; spinlock_t lock; @@ -261,8 +256,6 @@ unsigned short busmaster_regval; - struct net_device *dev; /* Backpointer */ - struct lance_private *next_module; struct timer_list multicast_timer; /* Pointers to the ring buffers as seen from the CPU */ @@ -292,16 +285,12 @@ int dec_lance_debug = 2; -/* - #ifdef MODULE - static struct lance_private *root_lance_dev = NULL; - #endif - */ +static struct net_device *root_lance_dev; static inline void writereg(volatile unsigned short *regptr, short value) { *regptr = value; - wbflush(); + iob(); } /* Load the CSR registers */ @@ -330,7 +319,7 @@ * Our specialized copy routines * */ -void cp_to_buf(void *to, const void *from, __kernel_size_t len) +void cp_to_buf(const int type, void *to, const void *from, int len) { unsigned short *tp, *fp, clen; unsigned char *rtp, *rfp; @@ -381,10 +370,10 @@ } } - wbflush(); + iob(); } -void cp_from_buf(void *to, unsigned char *from, int len) +void cp_from_buf(const int type, void *to, const void *from, int len) { unsigned short *tp, *fp, clen; unsigned char *rtp, *rfp; @@ -509,7 +498,7 @@ if (i < 3 && ZERO) printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]); } - wbflush(); + iob(); } static int init_restart_lance(struct lance_private *lp) @@ -551,22 +540,21 @@ #ifdef TEST_HITS { - int i; + int i; - printk("["); - for (i = 0; i < RX_RING_SIZE; i++) { - if (i == lp->rx_new) - printk("%s", - ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "_" : "X"); - else - printk("%s", - ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "." : "1"); - } - printk("]"); + printk("["); + for (i = 0; i < RX_RING_SIZE; i++) { + if (i == lp->rx_new) + printk("%s", ib->brx_ring[i].rmd1_bits & + LE_R1_OWN ? "_" : "X"); + else + printk("%s", ib->brx_ring[i].rmd1_bits & + LE_R1_OWN ? "." : "1"); + } + printk("]"); } #endif - for (rd = &ib->brx_ring[lp->rx_new]; !((bits = rd->rmd1_bits) & LE_R1_OWN); rd = &ib->brx_ring[lp->rx_new]) { @@ -608,8 +596,8 @@ skb_reserve(skb, 2); /* 16 byte align */ skb_put(skb, len); /* make room */ - cp_from_buf(skb->data, - (char *) lp->rx_buf_ptr_cpu[lp->rx_new], + cp_from_buf(lp->type, skb->data, + (char *)lp->rx_buf_ptr_cpu[lp->rx_new], len); skb->protocol = eth_type_trans(skb, dev); @@ -709,6 +697,14 @@ spin_unlock(&lp->lock); } +static void lance_dma_merr_int(const int irq, void *dev_id, + struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) dev_id; + + printk("%s: DMA error\n", dev->name); +} + static irqreturn_t lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs) { @@ -741,19 +737,8 @@ lp->stats.rx_errors++; if (csr0 & LE_C0_MERR) { - volatile unsigned long int_stat = *(unsigned long *) (system_base + IOCTL + SIR); - printk("%s: Memory error, status %04x\n", dev->name, csr0); - if (int_stat & LANCE_DMA_MEMRDERR) { - printk("%s: DMA error\n", dev->name); - int_stat |= LANCE_DMA_MEMRDERR; - /* - * re-enable LANCE DMA - */ - *(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16); - wbflush(); - } writereg(&ll->rdp, LE_C0_STOP); lance_init_ring(dev); @@ -800,10 +785,30 @@ netif_start_queue(dev); /* Associate IRQ with lance_interrupt */ - if (request_irq(dev->irq, &lance_interrupt, 0, lp->name, dev)) { - printk("Lance: Can't get irq %d\n", dev->irq); + if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) { + printk("lance: Can't get IRQ %d\n", dev->irq); return -EAGAIN; } + if (lp->dma_irq >= 0) { + unsigned long flags; + + if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0, + "lance error", dev)) { + free_irq(dev->irq, dev); + printk("lance: Can't get DMA IRQ %d\n", lp->dma_irq); + return -EAGAIN; + } + + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); + /* Enable I/O ASIC LANCE DMA. */ + ioasic_write(IO_REG_SSR, + ioasic_read(IO_REG_SSR) | IO_SSR_LANCE_DMA_EN); + + fast_mb(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); + } status = init_restart_lance(lp); @@ -827,7 +832,22 @@ writereg(&ll->rap, LE_CSR0); writereg(&ll->rdp, LE_C0_STOP); - free_irq(dev->irq, (void *) dev); + if (lp->dma_irq >= 0) { + unsigned long flags; + + spin_lock_irqsave(&ioasic_ssr_lock, flags); + + fast_mb(); + /* Disable I/O ASIC LANCE DMA. */ + ioasic_write(IO_REG_SSR, + ioasic_read(IO_REG_SSR) & ~IO_SSR_LANCE_DMA_EN); + + fast_iob(); + spin_unlock_irqrestore(&ioasic_ssr_lock, flags); + + free_irq(lp->dma_irq, dev); + } + free_irq(dev->irq, dev); /* MOD_DEC_USE_COUNT; */ @@ -886,7 +906,8 @@ ib->btx_ring[entry].length = (-len); ib->btx_ring[entry].misc = 0; - cp_to_buf((char *) lp->tx_buf_ptr_cpu[entry], skb->data, skblen); + cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data, + skblen); /* Clear the slack of the packet, do I need this? */ /* For a firewall it's a good idea - AC */ @@ -926,7 +947,7 @@ volatile u16 *mcast_table = (u16 *) & ib->filter; struct dev_mc_list *dmi = dev->mc_list; char *addrs; - int i, j, bit, byte; + int i; u32 crc; /* set all multicast bits */ @@ -952,7 +973,7 @@ if (!(*addrs & 1)) continue; - crc = ether_crc_le(6, addrs); + crc = ether_crc_le(ETH_ALEN, addrs); crc = crc >> 26; mcast_table[2 * (crc >> 4)] |= 1 << (crc & 0xf); } @@ -1001,7 +1022,7 @@ lance_set_multicast(dev); } -static int __init dec_lance_init(struct net_device *dev, const int type) +static int __init dec_lance_init(const int type, const int slot) { static unsigned version_printed; struct net_device *dev; @@ -1013,25 +1034,29 @@ #ifndef CONFIG_TC system_base = KN01_LANCE_BASE; -#else - int slot; #endif if (dec_lance_debug && version_printed++ == 0) printk(version); - dev = init_etherdev(0, sizeof(struct lance_private)); + dev = init_etherdev(NULL, sizeof(struct lance_private)); if (!dev) return -ENOMEM; + SET_MODULE_OWNER(dev); - /* init_etherdev ensures the data structures used by the LANCE are aligned. */ + /* + * init_etherdev ensures the data structures used by the LANCE + * are aligned. + */ lp = (struct lance_private *) dev->priv; spin_lock_init(&lp->lock); + lp->type = type; + lp->slot = slot; switch (type) { #ifdef CONFIG_TC case ASIC_LANCE: - dev->base_addr = system_base + LANCE; + dev->base_addr = system_base + IOASIC_LANCE; /* buffer space for the on-board LANCE shared memory */ /* @@ -1039,78 +1064,101 @@ */ dev->mem_start = KSEG1ADDR(0x00020000); dev->mem_end = dev->mem_start + 0x00020000; - dev->irq = ETHER; - esar_base = system_base + ESAR; - + dev->irq = dec_interrupt[DEC_IRQ_LANCE]; + esar_base = system_base + IOASIC_ESAR; + /* Workaround crash with booting KN04 2.1k from Disk */ - memset(dev->mem_start, 0, dev->mem_end - dev->mem_start); + memset((void *)dev->mem_start, 0, + dev->mem_end - dev->mem_start); /* * setup the pointer arrays, this sucks [tm] :-( */ for (i = 0; i < RX_RING_SIZE; i++) { - lp->rx_buf_ptr_cpu[i] = (char *) (dev->mem_start + BUF_OFFSET_CPU - + 2 * i * RX_BUFF_SIZE); - lp->rx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC - + i * RX_BUFF_SIZE); + lp->rx_buf_ptr_cpu[i] = + (char *)(dev->mem_start + BUF_OFFSET_CPU + + 2 * i * RX_BUFF_SIZE); + lp->rx_buf_ptr_lnc[i] = + (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE); } for (i = 0; i < TX_RING_SIZE; i++) { - lp->tx_buf_ptr_cpu[i] = (char *) (dev->mem_start + BUF_OFFSET_CPU - + 2 * RX_RING_SIZE * RX_BUFF_SIZE - + 2 * i * TX_BUFF_SIZE); - lp->tx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC - + RX_RING_SIZE * RX_BUFF_SIZE - + i * TX_BUFF_SIZE); + lp->tx_buf_ptr_cpu[i] = + (char *)(dev->mem_start + BUF_OFFSET_CPU + + 2 * RX_RING_SIZE * RX_BUFF_SIZE + + 2 * i * TX_BUFF_SIZE); + lp->tx_buf_ptr_lnc[i] = + (char *)(BUF_OFFSET_LNC + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); } - /* - * setup and enable IOASIC LANCE DMA - */ - lp->dma_ptr_reg = (unsigned long *) (system_base + IOCTL + LANCE_DMA_P); - *(lp->dma_ptr_reg) = PHYSADDR(dev->mem_start) << 3; - *(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16); - wbflush(); + /* Setup I/O ASIC LANCE DMA. */ + lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR]; + ioasic_write(IO_REG_LANCE_DMA_P, + PHYSADDR(dev->mem_start) << 3); break; + case PMAD_LANCE: - slot = search_tc_card("PMAD-AA"); claim_tc_card(slot); dev->mem_start = get_tc_base_addr(slot); dev->base_addr = dev->mem_start + 0x100000; dev->irq = get_tc_irq_nr(slot); esar_base = dev->mem_start + 0x1c0002; + lp->dma_irq = -1; + + for (i = 0; i < RX_RING_SIZE; i++) { + lp->rx_buf_ptr_cpu[i] = + (char *)(dev->mem_start + BUF_OFFSET_CPU + + i * RX_BUFF_SIZE); + lp->rx_buf_ptr_lnc[i] = + (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE); + } + for (i = 0; i < TX_RING_SIZE; i++) { + lp->tx_buf_ptr_cpu[i] = + (char *)(dev->mem_start + BUF_OFFSET_CPU + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); + lp->tx_buf_ptr_lnc[i] = + (char *)(BUF_OFFSET_LNC + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); + } + break; #endif + case PMAX_LANCE: - dev->irq = ETHER; + dev->irq = dec_interrupt[DEC_IRQ_LANCE]; dev->base_addr = KN01_LANCE_BASE; dev->mem_start = KN01_LANCE_BASE + 0x01000000; esar_base = KN01_RTC_BASE + 1; + lp->dma_irq = -1; + /* * setup the pointer arrays, this sucks [tm] :-( */ for (i = 0; i < RX_RING_SIZE; i++) { lp->rx_buf_ptr_cpu[i] = - (char *) (dev->mem_start + BUF_OFFSET_CPU - + 2 * i * RX_BUFF_SIZE); - + (char *)(dev->mem_start + BUF_OFFSET_CPU + + 2 * i * RX_BUFF_SIZE); lp->rx_buf_ptr_lnc[i] = - (char *) (BUF_OFFSET_LNC - + i * RX_BUFF_SIZE); - + (char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE); } for (i = 0; i < TX_RING_SIZE; i++) { lp->tx_buf_ptr_cpu[i] = - (char *) (dev->mem_start + BUF_OFFSET_CPU - + 2 * RX_RING_SIZE * RX_BUFF_SIZE - + 2 * i * TX_BUFF_SIZE); - lp->tx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC - + RX_RING_SIZE * RX_BUFF_SIZE - + i * TX_BUFF_SIZE); - + (char *)(dev->mem_start + BUF_OFFSET_CPU + + 2 * RX_RING_SIZE * RX_BUFF_SIZE + + 2 * i * TX_BUFF_SIZE); + lp->tx_buf_ptr_lnc[i] = + (char *)(BUF_OFFSET_LNC + + RX_RING_SIZE * RX_BUFF_SIZE + + i * TX_BUFF_SIZE); } + break; + default: printk("declance_init called with unknown type\n"); ret = -ENODEV; @@ -1140,6 +1188,9 @@ } } + lp->next = root_lance_dev; + root_lance_dev = dev; + /* Copy the ethernet address to the device structure, later to the * lance initialization block so the lance gets it every time it's * (re)initialized. @@ -1162,7 +1213,6 @@ printk(" irq = %d\n", dev->irq); - lp->dev = dev; dev->open = &lance_open; dev->stop = &lance_close; dev->hard_start_xmit = &lance_start_xmit; @@ -1174,8 +1224,6 @@ /* lp->ll is the location of the registers for lance card */ lp->ll = ll; - lp->name = lancestr; - /* busmaster_regval (CSR3) should be zero according to the PMAD-AA * specification. */ @@ -1183,8 +1231,6 @@ dev->dma = 0; - ether_setup(dev); - /* We cannot sleep if the chip is busy during a * multicast list update event, because such events * can occur from interrupts (ex. IPv6). So we @@ -1194,11 +1240,6 @@ lp->multicast_timer.data = (unsigned long) dev; lp->multicast_timer.function = &lance_set_multicast_retry; -#ifdef MODULE - dev->ifindex = dev_new_index(); - lp->next_module = root_lance_dev; - root_lance_dev = lp; -#endif return 0; err_out: @@ -1211,61 +1252,51 @@ /* Find all the lance cards on the system and initialize them */ static int __init dec_lance_probe(void) { - struct net_device *dev = NULL; - static int called; - -#ifdef MODULE - root_lance_dev = NULL; -#endif - + int count = 0; + /* Scan slots for PMAD-AA cards first. */ #ifdef CONFIG_TC - int slot = -1; - if (TURBOCHANNEL) { - if (IOASIC && !called) { - called = 1; - type = ASIC_LANCE; - } else { - if ((slot = search_tc_card("PMAD-AA")) >= 0) { - type = PMAD_LANCE; - } else { - return -ENODEV; - } - } - } else { - if (!called) { - called = 1; - type = PMAX_LANCE; - } else { - return -ENODEV; + int slot; + + while ((slot = search_tc_card("PMAD-AA")) >= 0) { + if (dec_lance_init(PMAD_LANCE, slot) < 0) + break; + count++; } } -#else - if (!called && !TURBOCHANNEL) { - called = 1; - type = PMAX_LANCE; - } else { - return -ENODEV; - } #endif - return dec_lance_init(dev, type); + /* Then handle onboard devices. */ + if (dec_interrupt[DEC_IRQ_LANCE] >= 0) { + if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) { +#ifdef CONFIG_TC + if (dec_lance_init(ASIC_LANCE, -1) >= 0) + count++; +#endif + } else if (!TURBOCHANNEL) { + if (dec_lance_init(PMAX_LANCE, -1) >= 0) + count++; + } + } + + return (count > 0) ? 0 : -ENODEV; } static void __exit dec_lance_cleanup(void) { -#ifdef MODULE - struct lance_private *lp; - - while (root_lance_dev) { - lp = root_lance_dev->next_module; + while (root_lance_dev) { + struct net_device *dev = root_lance_dev; + struct lance_private *lp = (struct lance_private *)dev->priv; - unregister_netdev(root_lance_dev->dev); - kfree(root_lance_dev->dev); - root_lance_dev = lp; - } -#endif /* MODULE */ +#ifdef CONFIG_TC + if (lp->slot >= 0) + release_tc_card(lp->slot); +#endif + root_lance_dev = lp->next; + unregister_netdev(dev); + kfree(dev); + } } module_init(dec_lance_probe); diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c --- a/drivers/net/e100/e100_main.c Fri Jun 27 14:19:56 2003 +++ b/drivers/net/e100/e100_main.c Fri Jun 27 14:19:56 2003 @@ -3424,10 +3424,6 @@ int ethtool_new_speed_duplex; struct ethtool_cmd ecmd; - if (!capable(CAP_NET_ADMIN)) { - return -EPERM; - } - bdp = dev->priv; if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd))) { return -EFAULT; @@ -3545,8 +3541,6 @@ void *addr = ifr->ifr_data; u16 mdi_reg; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; bdp = dev->priv; if(copy_from_user(®s, addr, sizeof(regs))) @@ -3574,9 +3568,6 @@ { struct e100_private *bdp; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - bdp = dev->priv; if ((bdp->speed_duplex_caps & SUPPORTED_Autoneg) && @@ -3632,9 +3623,6 @@ void *ptr; u8 *eeprom_data_bytes = (u8 *)eeprom_data; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - bdp = dev->priv; if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd))) @@ -3911,9 +3899,6 @@ struct e100_private *bdp; struct ethtool_wolinfo wolinfo; int res = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; bdp = dev->priv; diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c --- a/drivers/net/e1000/e1000_ethtool.c Fri Jun 27 14:19:56 2003 +++ b/drivers/net/e1000/e1000_ethtool.c Fri Jun 27 14:19:56 2003 @@ -1289,8 +1289,6 @@ } case ETHTOOL_SSET: { struct ethtool_cmd ecmd; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(copy_from_user(&ecmd, addr, sizeof(ecmd))) return -EFAULT; return e1000_ethtool_sset(adapter, &ecmd); @@ -1363,8 +1361,6 @@ return 0; } case ETHTOOL_NWAY_RST: { - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(netif_running(netdev)) { e1000_down(adapter); e1000_up(adapter); @@ -1393,8 +1389,6 @@ } case ETHTOOL_SWOL: { struct ethtool_wolinfo wol; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(copy_from_user(&wol, addr, sizeof(wol)) != 0) return -EFAULT; return e1000_ethtool_swol(adapter, &wol); @@ -1436,9 +1430,6 @@ case ETHTOOL_SEEPROM: { struct ethtool_eeprom eeprom; - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if(copy_from_user(&eeprom, addr, sizeof(eeprom))) return -EFAULT; @@ -1469,9 +1460,6 @@ uint64_t data[E1000_TEST_LEN]; } test = { {ETHTOOL_TEST} }; int err; - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; if(copy_from_user(&test.eth_test, addr, sizeof(test.eth_test))) return -EFAULT; diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c --- a/drivers/net/eepro100.c Fri Jun 27 14:19:59 2003 +++ b/drivers/net/eepro100.c Fri Jun 27 14:19:59 2003 @@ -116,6 +116,7 @@ #include <linux/netdevice.h> #include <linux/etherdevice.h> +#include <linux/rtnetlink.h> #include <linux/skbuff.h> #include <linux/ethtool.h> #include <linux/mii.h> @@ -670,7 +671,7 @@ if (tx_ring_space == NULL) return -1; - dev = init_etherdev(NULL, sizeof(struct speedo_private)); + dev = alloc_etherdev(sizeof(struct speedo_private)); if (dev == NULL) { printk(KERN_ERR "eepro100: Could not allocate ethernet device.\n"); pci_free_consistent(pdev, size, tx_ring_space, tx_ring_dma); @@ -687,6 +688,10 @@ else option = 0; + rtnl_lock(); + if (dev_alloc_name(dev, dev->name) < 0) + goto err_free_unlock; + /* Read the station address EEPROM before doing the reset. Nominally his should even be done before accepting the device, but then we wouldn't have a device name with which to report the error. @@ -881,7 +886,16 @@ dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &speedo_ioctl; + if (register_netdevice(dev)) + goto err_free_unlock; + rtnl_unlock(); + return 0; + + err_free_unlock: + rtnl_unlock(); + kfree(dev); + return -1; } static void do_slow_command(struct net_device *dev, int cmd) diff -Nru a/drivers/net/gt96100eth.c b/drivers/net/gt96100eth.c --- a/drivers/net/gt96100eth.c Fri Jun 27 14:20:00 2003 +++ b/drivers/net/gt96100eth.c Fri Jun 27 14:20:00 2003 @@ -3,8 +3,6 @@ * Author: MontaVista Software, Inc. * stevel@mvista.com or source@mvista.com * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -18,8 +16,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Ethernet driver for the MIPS GT96100 Advanced Communication Controller. * * Revision history @@ -32,18 +28,7 @@ * gt96100_cleanup_module(), and other general code cleanups * <stevel@mvista.com>. */ - -#ifndef __OPTIMIZE__ -#error You must compile this file with the correct options! -#error See the last lines of the source file. -#error You must compile this driver with "-O". -#endif - -#ifndef __mips__ -#error This driver only works with MIPS architectures! -#endif - - +#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> diff -Nru a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c --- a/drivers/net/ioc3-eth.c Fri Jun 27 14:19:53 2003 +++ b/drivers/net/ioc3-eth.c Fri Jun 27 14:19:53 2003 @@ -5,7 +5,7 @@ * * Driver for SGI's IOC3 based Ethernet cards as found in the PCI card. * - * Copyright (C) 1999, 2000, 2001 Ralf Baechle + * Copyright (C) 1999, 2000, 2001, 2003 Ralf Baechle * Copyright (C) 1995, 1999, 2000, 2001 by Silicon Graphics, Inc. * * References: @@ -36,7 +36,7 @@ #include <linux/pci.h> #include <linux/crc32.h> -#ifdef CONFIG_SERIAL +#ifdef CONFIG_SERIAL_8250 #include <linux/serial.h> #include <asm/serial.h> #define IOC3_BAUD (22000000 / (3*16)) @@ -377,82 +377,6 @@ ip->dev->dev_addr[i - 2] = nic[i]; } -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2) -/* - * Get the ether-address on SN1 nodes - */ -static void ioc3_get_eaddr_sn(struct ioc3_private *ip) -{ - int ibrick_mac_addr_get(nasid_t, char *); - struct ioc3 *ioc3 = ip->regs; - nasid_t nasid_of_ioc3; - char io7eaddr[20]; - long mac; - int err_val; - - /* - * err_val = ibrick_mac_addr_get(get_nasid(), io7eaddr ); - * - * BAD!! The above call uses get_nasid() and assumes that - * the ioc3 pointed to by struct ioc3 is hooked up to the - * cbrick that we're running on. The proper way to make this call - * is to figure out which nasid the ioc3 is connected to - * and use that to call ibrick_mac_addr_get. Below is - * a hack to do just that. - */ - - /* - * Get the nasid of the ioc3 from the ioc3's base addr. - * FIXME: the 8 at the end assumes we're in memory mode, - * not node mode (for that, we'd change it to a 9). - * Is there a call to extract this info from a physical - * addr somewhere in an sn header file already? If so, - * we should probably use that, or restructure this routine - * to use pci_dev and generic numa nodeid getting stuff. - */ - nasid_of_ioc3 = (((unsigned long)ioc3 >> 33) & ~(-1 << 8)); - err_val = ibrick_mac_addr_get(nasid_of_ioc3, io7eaddr ); - - - if (err_val) { - /* Couldn't read the eeprom; try OSLoadOptions. */ - printk("WARNING: ibrick_mac_addr_get failed: %d\n", err_val); - - /* this is where we hardwire the mac address - * 1st ibrick had 08:00:69:11:34:75 - * 2nd ibrick had 08:00:69:11:35:35 - * - * Eagan Machines: - * mankato1 08:00:69:11:BE:95 - * warroad 08:00:69:11:bd:60 - * duron 08:00:69:11:34:60 - * - * an easy way to get the mac address is to hook - * up an ip35, then from L1 do 'cti serial' - * and then look for MAC line XXX THIS DOESN"T QUITE WORK!! - */ - printk("ioc3_get_eaddr: setting ethernet address to:\n -----> "); - ip->dev->dev_addr[0] = 0x8; - ip->dev->dev_addr[1] = 0x0; - ip->dev->dev_addr[2] = 0x69; - ip->dev->dev_addr[3] = 0x11; - ip->dev->dev_addr[4] = 0x34; - ip->dev->dev_addr[5] = 0x60; - } - else { - long simple_strtol(const char *,char **,unsigned int); - - mac = simple_strtol(io7eaddr, (char **)0, 16); - ip->dev->dev_addr[0] = (mac >> 40) & 0xff; - ip->dev->dev_addr[1] = (mac >> 32) & 0xff; - ip->dev->dev_addr[2] = (mac >> 24) & 0xff; - ip->dev->dev_addr[3] = (mac >> 16) & 0xff; - ip->dev->dev_addr[4] = (mac >> 8) & 0xff; - ip->dev->dev_addr[5] = mac & 0xff; - } -} -#endif - /* * Ok, this is hosed by design. It's necessary to know what machine the * NIC is in in order to know how to read the NIC address. We also have @@ -460,30 +384,15 @@ */ static void ioc3_get_eaddr(struct ioc3_private *ip) { - void (*do_get_eaddr)(struct ioc3_private *ip) = NULL; int i; - /* - * We should also use this code for PCI cards, no matter what host - * machine but how to know that we're a PCI card? - */ -#ifdef CONFIG_SGI_IP27 - do_get_eaddr = ioc3_get_eaddr_nic; -#endif -#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2) - do_get_eaddr = ioc3_get_eaddr_sn; -#endif - if (!do_get_eaddr) { - printk(KERN_ERR "Don't know how to read MAC address of this " - "IOC3 NIC\n"); - return; - } + ioc3_get_eaddr_nic(ip); printk("Ethernet address is "); for (i = 0; i < 6; i++) { printk("%02x", ip->dev->dev_addr[i]); - if (i < 7) + if (i < 5) printk(":"); } printk(".\n"); @@ -588,7 +497,7 @@ ip->stats.rx_frame_errors++; next: ip->rx_skbs[n_entry] = new_skb; - rxr[n_entry] = cpu_to_be32((0xa5UL << 56) | + rxr[n_entry] = cpu_to_be64((0xa5UL << 56) | ((unsigned long) rxb & TO_PHYS_MASK)); rxb->w0 = 0; /* Clear valid flag */ n_entry = (n_entry + 1) & 511; /* Update erpir */ @@ -1550,7 +1459,7 @@ } ip->regs = ioc3; -#ifdef CONFIG_SERIAL +#ifdef CONFIG_SERIAL_8250 ioc3_serial_probe(pdev, ioc3); #endif @@ -1613,6 +1522,7 @@ struct ioc3_private *ip = dev->priv; struct ioc3 *ioc3 = ip->regs; + unregister_netdev(dev); iounmap(ioc3); pci_release_regions(pdev); kfree(dev); @@ -1844,9 +1754,6 @@ return -EFAULT; return 0; } else if (ecmd.cmd == ETHTOOL_SSET) { - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Verify the settings we care about. */ if (ecmd.autoneg != AUTONEG_ENABLE && ecmd.autoneg != AUTONEG_DISABLE) diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig --- a/drivers/net/irda/Kconfig Fri Jun 27 14:19:59 2003 +++ b/drivers/net/irda/Kconfig Fri Jun 27 14:19:59 2003 @@ -289,6 +289,10 @@ <file:Documentation/modules.txt>. The module will be called donauboe. +config AU1000_FIR + tristate "Alchemy Au1000 SIR/FIR" + depends on MIPS_AU1000 && IRDA + config SMC_IRCC_OLD tristate "SMC IrCC (old driver) (EXPERIMENTAL)" depends on EXPERIMENTAL && IRDA diff -Nru a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile --- a/drivers/net/irda/Makefile Fri Jun 27 14:19:56 2003 +++ b/drivers/net/irda/Makefile Fri Jun 27 14:19:56 2003 @@ -28,6 +28,7 @@ obj-$(CONFIG_OLD_BELKIN_DONGLE) += old_belkin.o obj-$(CONFIG_EP7211_IR) += ep7211_ir.o obj-$(CONFIG_MCP2120_DONGLE) += mcp2120.o +obj-$(CONFIG_AU1000_FIR) += au1k_ir.o obj-$(CONFIG_ACT200L_DONGLE) += act200l.o obj-$(CONFIG_MA600_DONGLE) += ma600.o # New SIR drivers diff -Nru a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/irda/au1k_ir.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,868 @@ +/* + * + * Alchemy Semi Au1000 IrDA driver + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ + +#ifndef __mips__ +#error This driver only works with MIPS architectures! +#endif + + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/errno.h> +#include <linux/netdevice.h> +#include <linux/slab.h> +#include <linux/rtnetlink.h> +#include <linux/interrupt.h> +#include <linux/pm.h> + +#include <asm/irq.h> +#include <asm/bitops.h> +#include <asm/io.h> +#include <asm/au1000.h> +#include <asm/pb1000.h> + +#include <net/irda/irda.h> +#include <net/irda/irmod.h> +#include <net/irda/wrapper.h> +#include <net/irda/irda_device.h> +#include "net/irda/au1000_ircc.h" + +static int au1k_irda_net_init(struct net_device *); +static int au1k_irda_start(struct net_device *); +static int au1k_irda_stop(struct net_device *dev); +static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *); +static int au1k_irda_rx(struct net_device *); +static void au1k_irda_interrupt(int, void *, struct pt_regs *); +static void au1k_tx_timeout(struct net_device *); +static struct net_device_stats *au1k_irda_stats(struct net_device *); +static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int); +static int au1k_irda_set_speed(struct net_device *dev, int speed); + +static void *dma_alloc(size_t, dma_addr_t *); +static void dma_free(void *, size_t); + +static int qos_mtt_bits = 0x07; /* 1 ms or more */ +static struct net_device *ir_devs[NUM_IR_IFF]; +static char version[] __devinitdata = + "au1k_ircc:1.0 ppopov@mvista.com\n"; + +#define RUN_AT(x) (jiffies + (x)) + +static spinlock_t ir_lock = SPIN_LOCK_UNLOCKED; + +/* + * IrDA peripheral bug. You have to read the register + * twice to get the right value. + */ +u32 read_ir_reg(u32 addr) +{ + readl(addr); + return readl(addr); +} + + +/* + * Buffer allocation/deallocation routines. The buffer descriptor returned + * has the virtual and dma address of a buffer suitable for + * both, receive and transmit operations. + */ +static db_dest_t *GetFreeDB(struct au1k_private *aup) +{ + db_dest_t *pDB; + pDB = aup->pDBfree; + + if (pDB) { + aup->pDBfree = pDB->pnext; + } + return pDB; +} + +static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB) +{ + db_dest_t *pDBfree = aup->pDBfree; + if (pDBfree) + pDBfree->pnext = pDB; + aup->pDBfree = pDB; +} + + +/* + DMA memory allocation, derived from pci_alloc_consistent. + However, the Au1000 data cache is coherent (when programmed + so), therefore we return KSEG0 address, not KSEG1. +*/ +static void *dma_alloc(size_t size, dma_addr_t * dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC | GFP_DMA; + + ret = (void *) __get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + ret = KSEG0ADDR(ret); + } + return ret; +} + + +static void dma_free(void *vaddr, size_t size) +{ + vaddr = KSEG0ADDR(vaddr); + free_pages((unsigned long) vaddr, get_order(size)); +} + + +static void +setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base) +{ + int i; + for (i=0; i<NUM_IR_DESC; i++) { + aup->rx_ring[i] = (volatile ring_dest_t *) + (rx_base + sizeof(ring_dest_t)*i); + } + for (i=0; i<NUM_IR_DESC; i++) { + aup->tx_ring[i] = (volatile ring_dest_t *) + (tx_base + sizeof(ring_dest_t)*i); + } +} + + +/* + * Device has already been stopped at this point. + */ +static void au1k_irda_net_uninit(struct net_device *dev) +{ + dev->hard_start_xmit = NULL; + dev->open = NULL; + dev->stop = NULL; + dev->do_ioctl = NULL; + dev->get_stats = NULL; + dev->priv = NULL; +} + + +static int au1k_irda_init(void) +{ + static unsigned version_printed = 0; + struct net_device *dev; + int err; + + if (version_printed++ == 0) printk(version); + + rtnl_lock(); + dev = dev_alloc("irda%d", &err); + if (dev) { + dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */ + dev->init = au1k_irda_net_init; + dev->uninit = au1k_irda_net_uninit; + err = register_netdevice(dev); + + if (err) + kfree(dev); + else + ir_devs[0] = dev; + printk(KERN_INFO "IrDA: Registered device %s\n", dev->name); + } + rtnl_unlock(); + return err; +} + +static int au1k_irda_init_iobuf(iobuff_t *io, int size) +{ + io->head = kmalloc(size, GFP_KERNEL); + if (io->head != NULL) { + io->truesize = size; + io->in_frame = FALSE; + io->state = OUTSIDE_FRAME; + io->data = io->head; + } + return io->head ? 0 : -ENOMEM; +} + +static int au1k_irda_net_init(struct net_device *dev) +{ + struct au1k_private *aup = NULL; + int i, retval = 0, err; + db_dest_t *pDB, *pDBfree; + unsigned long temp; + + dev->priv = kmalloc(sizeof(struct au1k_private), GFP_KERNEL); + if (dev->priv == NULL) { + retval = -ENOMEM; + goto out; + } + memset(dev->priv, 0, sizeof(struct au1k_private)); + aup = dev->priv; + + err = au1k_irda_init_iobuf(&aup->rx_buff, 14384); + if (err) + goto out; + + dev->open = au1k_irda_start; + dev->hard_start_xmit = au1k_irda_hard_xmit; + dev->stop = au1k_irda_stop; + dev->get_stats = au1k_irda_stats; + dev->do_ioctl = au1k_irda_ioctl; + dev->tx_timeout = au1k_tx_timeout; + + irda_device_setup(dev); + irda_init_max_qos_capabilies(&aup->qos); + + /* The only value we must override it the baudrate */ + aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| + IR_115200|IR_576000 |(IR_4000000 << 8); + + aup->qos.min_turn_time.bits = qos_mtt_bits; + irda_qos_bits_to_value(&aup->qos); + + + /* Tx ring follows rx ring + 512 bytes */ + /* we need a 1k aligned buffer */ + aup->rx_ring[0] = (ring_dest_t *) + dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp); + + /* allocate the data buffers */ + aup->db[0].vaddr = + (void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp); + if (!aup->db[0].vaddr || !aup->rx_ring[0]) { + retval = -ENOMEM; + goto out; + } + + setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512); + + pDBfree = NULL; + pDB = aup->db; + for (i=0; i<(2*NUM_IR_DESC); i++) { + pDB->pnext = pDBfree; + pDBfree = pDB; + pDB->vaddr = + (u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i); + pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); + pDB++; + } + aup->pDBfree = pDBfree; + + /* attach a data buffer to each descriptor */ + for (i=0; i<NUM_IR_DESC; i++) { + pDB = GetFreeDB(aup); + if (!pDB) goto out; + aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); + aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff); + aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff); + aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff); + aup->rx_db_inuse[i] = pDB; + } + for (i=0; i<NUM_IR_DESC; i++) { + pDB = GetFreeDB(aup); + if (!pDB) goto out; + aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); + aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff); + aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff); + aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff); + aup->tx_ring[i]->count_0 = 0; + aup->tx_ring[i]->count_1 = 0; + aup->tx_ring[i]->flags = 0; + aup->tx_db_inuse[i] = pDB; + } + return 0; + +out: + if (aup->db[0].vaddr) + dma_free((void *)aup->db[0].vaddr, + MAX_BUF_SIZE * 2*NUM_IR_DESC); + if (aup->rx_ring[0]) + kfree((void *)aup->rx_ring[0]); + if (aup->rx_buff.head) + kfree(aup->rx_buff.head); + if (dev->priv != NULL) + kfree(dev->priv); + unregister_netdevice(dev); + printk(KERN_ERR "%s: au1k_init_module failed. Returns %d\n", + dev->name, retval); + return retval; +} + + +static int au1k_init(struct net_device *dev) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + int i; + u32 control; + u32 ring_address; + + /* bring the device out of reset */ + control = 0xe; /* coherent, clock enable, one half system clock */ + +#ifndef CONFIG_CPU_LITTLE_ENDIAN + control |= 1; +#endif + aup->tx_head = 0; + aup->tx_tail = 0; + aup->rx_head = 0; + + for (i=0; i<NUM_IR_DESC; i++) { + aup->rx_ring[i]->flags = AU_OWN; + } + + writel(control, IR_INTERFACE_CONFIG); + au_sync_delay(10); + + writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */ + au_sync_delay(1); + + writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN); + + ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]); + writel(ring_address >> 26, IR_RING_BASE_ADDR_H); + writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L); + + writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE); + + writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */ + writel(0, IR_RING_ADDR_CMPR); + + au1k_irda_set_speed(dev, 9600); + return 0; +} + +static int au1k_irda_start(struct net_device *dev) +{ + int retval; + char hwname[32]; + struct au1k_private *aup = (struct au1k_private *) dev->priv; + + MOD_INC_USE_COUNT; + + if ((retval = au1k_init(dev))) { + printk(KERN_ERR "%s: error in au1k_init\n", dev->name); + MOD_DEC_USE_COUNT; + return retval; + } + + if ((retval = request_irq(AU1000_IRDA_TX_INT, &au1k_irda_interrupt, + 0, dev->name, dev))) { + printk(KERN_ERR "%s: unable to get IRQ %d\n", + dev->name, dev->irq); + MOD_DEC_USE_COUNT; + return retval; + } + if ((retval = request_irq(AU1000_IRDA_RX_INT, &au1k_irda_interrupt, + 0, dev->name, dev))) { + free_irq(AU1000_IRDA_TX_INT, dev); + printk(KERN_ERR "%s: unable to get IRQ %d\n", + dev->name, dev->irq); + MOD_DEC_USE_COUNT; + return retval; + } + + /* Give self a hardware name */ + sprintf(hwname, "Au1000 SIR/FIR"); + aup->irlap = irlap_open(dev, &aup->qos, hwname); + netif_start_queue(dev); + + writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */ + + aup->timer.expires = RUN_AT((3*HZ)); + aup->timer.data = (unsigned long)dev; + return 0; +} + +static int au1k_irda_stop(struct net_device *dev) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + + /* disable interrupts */ + writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2); + writel(0, IR_CONFIG_1); + writel(0, IR_INTERFACE_CONFIG); /* disable clock */ + au_sync(); + + if (aup->irlap) { + irlap_close(aup->irlap); + aup->irlap = NULL; + } + + netif_stop_queue(dev); + del_timer(&aup->timer); + + /* disable the interrupt */ + free_irq(AU1000_IRDA_TX_INT, dev); + free_irq(AU1000_IRDA_RX_INT, dev); + MOD_DEC_USE_COUNT; + return 0; +} + +static void __exit au1k_irda_exit(void) +{ + struct net_device *dev = ir_devs[0]; + struct au1k_private *aup = (struct au1k_private *) dev->priv; + + if (!dev) { + printk(KERN_ERR "au1k_ircc no dev found\n"); + return; + } + if (aup->db[0].vaddr) { + dma_free((void *)aup->db[0].vaddr, + MAX_BUF_SIZE * 2*NUM_IR_DESC); + aup->db[0].vaddr = 0; + } + if (aup->rx_ring[0]) { + dma_free((void *)aup->rx_ring[0], + 2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); + aup->rx_ring[0] = 0; + } + rtnl_lock(); + unregister_netdevice(dev); + rtnl_unlock(); + ir_devs[0] = 0; +} + + +static inline void +update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + struct net_device_stats *ps = &aup->stats; + + ps->tx_packets++; + ps->tx_bytes += pkt_len; + + if (status & IR_TX_ERROR) { + ps->tx_errors++; + ps->tx_aborted_errors++; + } +} + + +static void au1k_tx_ack(struct net_device *dev) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + volatile ring_dest_t *ptxd; + + ptxd = aup->tx_ring[aup->tx_tail]; + while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) { + update_tx_stats(dev, ptxd->flags, + ptxd->count_1<<8 | ptxd->count_0); + ptxd->count_0 = 0; + ptxd->count_1 = 0; + au_sync(); + + aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1); + ptxd = aup->tx_ring[aup->tx_tail]; + + if (aup->tx_full) { + aup->tx_full = 0; + netif_wake_queue(dev); + } + } + + if (aup->tx_tail == aup->tx_head) { + if (aup->newspeed) { + au1k_irda_set_speed(dev, aup->newspeed); + aup->newspeed = 0; + } + else { + writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, + IR_CONFIG_1); + au_sync(); + writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, + IR_CONFIG_1); + writel(0, IR_RING_PROMPT); + au_sync(); + } + } +} + + +/* + * Au1000 transmit routine. + */ +static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + int speed = irda_get_next_speed(skb); + volatile ring_dest_t *ptxd; + u32 len; + + u32 flags; + db_dest_t *pDB; + + if (speed != aup->speed && speed != -1) { + aup->newspeed = speed; + } + + if ((skb->len == 0) && (aup->newspeed)) { + if (aup->tx_tail == aup->tx_head) { + au1k_irda_set_speed(dev, speed); + aup->newspeed = 0; + } + dev_kfree_skb(skb); + return 0; + } + + ptxd = aup->tx_ring[aup->tx_head]; + flags = ptxd->flags; + + if (flags & AU_OWN) { + printk(KERN_INFO "%s: tx_full\n", dev->name); + netif_stop_queue(dev); + aup->tx_full = 1; + return 1; + } + else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { + printk(KERN_INFO "%s: tx_full\n", dev->name); + netif_stop_queue(dev); + aup->tx_full = 1; + return 1; + } + + pDB = aup->tx_db_inuse[aup->tx_head]; + +#if 0 + if (read_ir_reg(IR_RX_BYTE_CNT) != 0) { + printk("tx warning: rx byte cnt %x\n", + read_ir_reg(IR_RX_BYTE_CNT)); + } +#endif + + if (aup->speed == 4000000) { + /* FIR */ + memcpy((void *)pDB->vaddr, skb->data, skb->len); + ptxd->count_0 = skb->len & 0xff; + ptxd->count_1 = (skb->len >> 8) & 0xff; + } + else { + /* SIR */ + len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE); + ptxd->count_0 = len & 0xff; + ptxd->count_1 = (len >> 8) & 0xff; + ptxd->flags |= IR_DIS_CRC; + } + ptxd->flags |= AU_OWN; + au_sync(); + + writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); + writel(0, IR_RING_PROMPT); + au_sync(); + + dev_kfree_skb(skb); + aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1); + dev->trans_start = jiffies; + return 0; +} + + +static inline void +update_rx_stats(struct net_device *dev, u32 status, u32 count) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + struct net_device_stats *ps = &aup->stats; + + ps->rx_packets++; + + if (status & IR_RX_ERROR) { + ps->rx_errors++; + if (status & (IR_PHY_ERROR|IR_FIFO_OVER)) + ps->rx_missed_errors++; + if (status & IR_MAX_LEN) + ps->rx_length_errors++; + if (status & IR_CRC_ERROR) + ps->rx_crc_errors++; + } + else + ps->rx_bytes += count; +} + +/* + * Au1000 receive routine. + */ +static int au1k_irda_rx(struct net_device *dev) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + struct sk_buff *skb; + volatile ring_dest_t *prxd; + u32 flags, count; + db_dest_t *pDB; + + prxd = aup->rx_ring[aup->rx_head]; + flags = prxd->flags; + + while (!(flags & AU_OWN)) { + pDB = aup->rx_db_inuse[aup->rx_head]; + count = prxd->count_1<<8 | prxd->count_0; + if (!(flags & IR_RX_ERROR)) { + /* good frame */ + update_rx_stats(dev, flags, count); + skb=alloc_skb(count+1,GFP_ATOMIC); + if (skb == NULL) { + aup->stats.rx_dropped++; + continue; + } + skb_reserve(skb, 1); + if (aup->speed == 4000000) + skb_put(skb, count); + else + skb_put(skb, count-2); + memcpy(skb->data, (void *)pDB->vaddr, count-2); + skb->dev = dev; + skb->mac.raw = skb->data; + skb->protocol = htons(ETH_P_IRDA); + netif_rx(skb); + prxd->count_0 = 0; + prxd->count_1 = 0; + } + prxd->flags |= AU_OWN; + aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1); + writel(0, IR_RING_PROMPT); + au_sync(); + + /* next descriptor */ + prxd = aup->rx_ring[aup->rx_head]; + flags = prxd->flags; + dev->last_rx = jiffies; + + } + return 0; +} + + +void au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) dev_id; + + if (dev == NULL) { + printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name); + return; + } + + writel(0, IR_INT_CLEAR); /* ack irda interrupts */ + + au1k_irda_rx(dev); + au1k_tx_ack(dev); +} + + +/* + * The Tx ring has been full longer than the watchdog timeout + * value. The transmitter must be hung? + */ +static void au1k_tx_timeout(struct net_device *dev) +{ + u32 speed; + struct au1k_private *aup = (struct au1k_private *) dev->priv; + + printk(KERN_ERR "%s: tx timeout\n", dev->name); + speed = aup->speed; + aup->speed = 0; + au1k_irda_set_speed(dev, speed); + aup->tx_full = 0; + netif_wake_queue(dev); +} + + +/* + * Set the IrDA communications speed. + */ +static int +au1k_irda_set_speed(struct net_device *dev, int speed) +{ + unsigned long flags; + struct au1k_private *aup = (struct au1k_private *) dev->priv; + u32 control; + int ret = 0, timeout = 10, i; + volatile ring_dest_t *ptxd; + + if (speed == aup->speed) + return ret; + + spin_lock_irqsave(&ir_lock, flags); + + /* disable PHY first */ + writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); + + /* disable RX/TX */ + writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), + IR_CONFIG_1); + au_sync_delay(1); + while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) { + mdelay(1); + if (!timeout--) { + printk(KERN_ERR "%s: rx/tx disable timeout\n", + dev->name); + break; + } + } + + /* disable DMA */ + writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1); + au_sync_delay(1); + + /* + * After we disable tx/rx. the index pointers + * go back to zero. + */ + aup->tx_head = aup->tx_tail = aup->rx_head = 0; + for (i=0; i<NUM_IR_DESC; i++) { + ptxd = aup->tx_ring[i]; + ptxd->flags = 0; + ptxd->count_0 = 0; + ptxd->count_1 = 0; + } + + for (i=0; i<NUM_IR_DESC; i++) { + ptxd = aup->rx_ring[i]; + ptxd->count_0 = 0; + ptxd->count_1 = 0; + ptxd->flags = AU_OWN; + } + + if (speed == 4000000) + writel(1<<13, CPLD_AUX1); + else + writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1); + + switch (speed) { + case 9600: + writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); + writel(IR_SIR_MODE, IR_CONFIG_1); + break; + case 19200: + writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); + writel(IR_SIR_MODE, IR_CONFIG_1); + break; + case 38400: + writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); + writel(IR_SIR_MODE, IR_CONFIG_1); + break; + case 57600: + writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); + writel(IR_SIR_MODE, IR_CONFIG_1); + break; + case 115200: + writel(12<<5, IR_WRITE_PHY_CONFIG); + writel(IR_SIR_MODE, IR_CONFIG_1); + break; + case 4000000: + writel(0xF, IR_WRITE_PHY_CONFIG); + writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); + break; + default: + printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed); + ret = -EINVAL; + break; + } + + aup->speed = speed; + writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE); + au_sync(); + + control = read_ir_reg(IR_ENABLE); + writel(0, IR_RING_PROMPT); + au_sync(); + + if (control & (1<<14)) { + printk(KERN_ERR "%s: configuration error\n", dev->name); + } + else { + if (control & (1<<11)) + printk(KERN_INFO "%s Valid SIR config\n", dev->name); + if (control & (1<<12)) + printk(KERN_INFO "%s Valid MIR config\n", dev->name); + if (control & (1<<13)) + printk(KERN_INFO "%s Valid FIR config\n", dev->name); + if (control & (1<<10)) + printk(KERN_INFO "%s TX enabled\n", dev->name); + if (control & (1<<9)) + printk(KERN_INFO "%s RX enabled\n", dev->name); + } + + spin_unlock_irqrestore(&ir_lock, flags); + return ret; +} + +static int +au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) +{ + struct if_irda_req *rq = (struct if_irda_req *)ifreq; + struct au1k_private *aup = dev->priv; + int ret = -EOPNOTSUPP; + + switch (cmd) { + case SIOCSBANDWIDTH: + if (capable(CAP_NET_ADMIN)) { + /* + * We are unable to set the speed if the + * device is not running. + */ + if (aup->open) + ret = au1k_irda_set_speed(dev, + rq->ifr_baudrate); + else { + printk(KERN_ERR "%s ioctl: !netif_running\n", + dev->name); + ret = 0; + } + } + break; + + case SIOCSMEDIABUSY: + ret = -EPERM; + if (capable(CAP_NET_ADMIN)) { + irda_device_set_media_busy(dev, TRUE); + ret = 0; + } + break; + + case SIOCGRECEIVING: + rq->ifr_receiving = 0; + break; + default: + break; + } + return ret; +} + + +static struct net_device_stats *au1k_irda_stats(struct net_device *dev) +{ + struct au1k_private *aup = (struct au1k_private *) dev->priv; + return &aup->stats; +} + +#ifdef MODULE +MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>"); +MODULE_DESCRIPTION("Au1000 IrDA Device Driver"); + +module_init(au1k_irda_init); +module_exit(au1k_irda_exit); +#endif /* MODULE */ diff -Nru a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c --- a/drivers/net/irda/vlsi_ir.c Fri Jun 27 14:19:52 2003 +++ b/drivers/net/irda/vlsi_ir.c Fri Jun 27 14:19:52 2003 @@ -2,7 +2,7 @@ * * vlsi_ir.c: VLSI82C147 PCI IrDA controller driver for Linux * - * Copyright (c) 2001-2002 Martin Diehl + * Copyright (c) 2001-2003 Martin Diehl * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,7 +28,7 @@ MODULE_LICENSE("GPL"); #define DRIVER_NAME "vlsi_ir" -#define DRIVER_VERSION "v0.4" +#define DRIVER_VERSION "v0.4a" /********************************************************/ @@ -149,6 +149,9 @@ /********************************************************/ +/* needed regardless of CONFIG_PROC_FS */ +static struct proc_dir_entry *vlsi_proc_root = NULL; + #ifdef CONFIG_PROC_FS static int vlsi_proc_pdev(struct pci_dev *pdev, char *buf, int len) @@ -394,8 +397,6 @@ return out - buf; } -static struct proc_dir_entry *vlsi_proc_root = NULL; - struct vlsi_proc_data { int size; char *data; @@ -494,11 +495,18 @@ } static struct file_operations vlsi_proc_fops = { + /* protect individual procdir file entry against rmmod */ + .owner = THIS_MODULE, .open = vlsi_proc_open, .llseek = vlsi_proc_lseek, .read = vlsi_proc_read, .release = vlsi_proc_release, }; + +#define VLSI_PROC_FOPS (&vlsi_proc_fops) + +#else /* CONFIG_PROC_FS */ +#define VLSI_PROC_FOPS NULL #endif /********************************************************/ @@ -1800,8 +1808,7 @@ goto out_freedev; } -#ifdef CONFIG_PROC_FS - { + if (vlsi_proc_root != NULL) { struct proc_dir_entry *ent; ent = create_proc_entry(ndev->name, S_IFREG|S_IRUGO, vlsi_proc_root); @@ -1810,11 +1817,11 @@ goto out_unregister; } ent->data = ndev; - ent->proc_fops = &vlsi_proc_fops; + ent->proc_fops = VLSI_PROC_FOPS; ent->size = 0; idev->proc_entry = ent; - } -#endif + } else + idev->proc_entry = NULL; printk(KERN_INFO "%s: registered device %s\n", drivername, ndev->name); @@ -1851,12 +1858,10 @@ down(&idev->sem); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); -#ifdef CONFIG_PROC_FS if (idev->proc_entry) { remove_proc_entry(ndev->name, vlsi_proc_root); idev->proc_entry = NULL; } -#endif up(&idev->sem); unregister_netdev(ndev); @@ -1993,9 +1998,7 @@ #endif }; -#ifdef CONFIG_PROC_FS #define PROC_DIR ("driver/" DRIVER_NAME) -#endif static int __init vlsi_mod_init(void) { @@ -2025,18 +2028,23 @@ sirpulse = !!sirpulse; -#ifdef CONFIG_PROC_FS + /* create_proc_entry returns NULL if !CONFIG_PROC_FS. + * Failure to create the procfs entry is handled like running + * without procfs - it's not required for the driver to work. + */ vlsi_proc_root = create_proc_entry(PROC_DIR, S_IFDIR, 0); - if (!vlsi_proc_root) - return -ENOMEM; -#endif + if (vlsi_proc_root) { + /* protect registered procdir against module removal. + * Because we are in the module init path there's no race + * window after create_proc_entry (and no barrier needed). + */ + vlsi_proc_root->owner = THIS_MODULE; + } ret = pci_module_init(&vlsi_irda_driver); -#ifdef CONFIG_PROC_FS - if (ret) + if (ret && vlsi_proc_root) remove_proc_entry(PROC_DIR, 0); -#endif return ret; } @@ -2044,7 +2052,8 @@ static void __exit vlsi_mod_exit(void) { pci_unregister_driver(&vlsi_irda_driver); - remove_proc_entry(PROC_DIR, 0); + if (vlsi_proc_root) + remove_proc_entry(PROC_DIR, 0); } module_init(vlsi_mod_init); diff -Nru a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c --- a/drivers/net/ixgb/ixgb_ethtool.c Fri Jun 27 14:20:03 2003 +++ b/drivers/net/ixgb/ixgb_ethtool.c Fri Jun 27 14:20:03 2003 @@ -448,8 +448,6 @@ case ETHTOOL_SSET:{ struct ethtool_cmd ecmd; - if (!capable(CAP_NET_ADMIN)) - return -EPERM; if (copy_from_user(&ecmd, addr, sizeof (ecmd))) return -EFAULT; return ixgb_ethtool_sset(adapter, &ecmd); @@ -482,9 +480,6 @@ #endif /* ETHTOOL_GREGS */ case ETHTOOL_NWAY_RST:{ IXGB_DBG("ETHTOOL_NWAY_RST\n"); - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - ixgb_down(adapter); ixgb_up(adapter); @@ -539,9 +534,6 @@ struct ethtool_eeprom eeprom; IXGB_DBG("ETHTOOL_SEEPROM\n"); - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&eeprom, addr, sizeof (eeprom))) return -EFAULT; diff -Nru a/drivers/net/meth.c b/drivers/net/meth.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/meth.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,862 @@ +/* + * meth.c -- O2 Builtin 10/100 Ethernet driver + * + * Copyright (C) 2001 Ilya Volynets + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include <linux/module.h> +#include <linux/init.h> + +#include <linux/sched.h> +#include <linux/kernel.h> /* printk() */ +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/errno.h> /* error codes */ +#include <linux/types.h> /* size_t */ +#include <linux/interrupt.h> /* mark_bh */ +#include <linux/pci.h> + +#include <linux/in.h> +#include <linux/netdevice.h> /* struct device, and other headers */ +#include <linux/etherdevice.h> /* eth_type_trans */ +#include <linux/ip.h> /* struct iphdr */ +#include <linux/tcp.h> /* struct tcphdr */ +#include <linux/skbuff.h> +#include <linux/mii.h> /*MII definitions */ + +#include <asm/ip32/crime.h> +#include <asm/ip32/mace.h> +#include <asm/ip32/ip32_ints.h> + +#include "meth.h" + +#include <linux/in6.h> +#include <asm/checksum.h> + +#ifndef MFE_DEBUG +#define MFE_DEBUG 0 +#endif + +#if MFE_DEBUG>=1 +#define DPRINTK(str,args...) printk (KERN_DEBUG "meth(%ld): %s: " str, jiffies, __FUNCTION__ , ## args) +#define MFE_RX_DEBUG 2 +#else +#define DPRINTK(str,args...) +#define MFE_RX_DEBUG 0 +#endif + + +static const char *version="meth.c: Ilya Volynets (ilya@theIlya.com)"; +static const char *meth_str="SGI O2 Fast Ethernet"; +MODULE_AUTHOR("Ilya Volynets"); +MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver"); + +/* This is a load-time options */ +/*static int eth = 0; +MODULE_PARM(eth, "i");*/ + +#define HAVE_TX_TIMEOUT +/* The maximum time waited (in jiffies) before assuming a Tx failed. (400ms) */ +#define TX_TIMEOUT (400*HZ/1000) + +#ifdef HAVE_TX_TIMEOUT +static int timeout = TX_TIMEOUT; +MODULE_PARM(timeout, "i"); +#endif + +int meth_eth; + +/* + * This structure is private to each device. It is used to pass + * packets in and out, so there is place for a packet + */ + +typedef struct meth_private { + struct net_device_stats stats; + volatile struct meth_regs *regs; + u64 mode; /* in-memory copy of MAC control register */ + int phy_addr; /* address of phy, used by mdio_* functions, initialized in mdio_probe*/ + tx_packet *tx_ring; + dma_addr_t tx_ring_dma; + int free_space; + struct sk_buff *tx_skbs[TX_RING_ENTRIES]; + dma_addr_t tx_skb_dmas[TX_RING_ENTRIES]; + int tx_read,tx_write; + int tx_count; + + rx_packet *rx_ring[RX_RING_ENTRIES]; + dma_addr_t rx_ring_dmas[RX_RING_ENTRIES]; + int rx_write; + + spinlock_t meth_lock; +} meth_private; + +extern struct net_device meth_devs[]; +void meth_tx_timeout (struct net_device *dev); +void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs); + +/* global, initialized in ip32-setup.c */ +char o2meth_eaddr[8]={0,0,0,0,0,0,0,0}; + +static inline void load_eaddr(struct net_device *dev, + volatile struct meth_regs *regs) +{ + int i; + DPRINTK("Loading MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", + (int)o2meth_eaddr[0]&0xFF,(int)o2meth_eaddr[1]&0xFF,(int)o2meth_eaddr[2]&0xFF, + (int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF); + //memcpy(dev->dev_addr,o2meth_eaddr+2,6); + for (i=0; i<6; i++) + dev->dev_addr[i]=o2meth_eaddr[i]; + regs->mac_addr= //dev->dev_addr[0]|(dev->dev_addr[1]<<8)| + //dev->dev_addr[2]<<16|(dev->dev_addr[3]<<24)| + //dev->dev_addr[4]<<32|(dev->dev_addr[5]<<40); + (*(u64*)o2meth_eaddr)>>16; + DPRINTK("MAC, finally is %0lx\n",regs->mac_addr); +} + +/* + *Waits for BUSY status of mdio bus to clear + */ +#define WAIT_FOR_PHY(___regs, ___rval) \ + while((___rval=___regs->phy_data)&MDIO_BUSY){ \ + udelay(25); \ + } +/*read phy register, return value read */ +static int mdio_read(meth_private *priv,int phyreg) +{ + volatile meth_regs* regs=priv->regs; + volatile u32 rval; + WAIT_FOR_PHY(regs,rval) + regs->phy_registers=(priv->phy_addr<<5)|(phyreg&0x1f); + udelay(25); + regs->phy_trans_go=1; + udelay(25); + WAIT_FOR_PHY(regs,rval) + return rval&MDIO_DATA_MASK; +} + +/*write phy register */ +static void mdio_write(meth_private* priv,int pfyreg,int val) +{ + volatile meth_regs* regs=priv->regs; + int rval; +/// DPRINTK("Trying to write value %i to reguster %i\n",val, pfyreg); + spin_lock_irq(&priv->meth_lock); + WAIT_FOR_PHY(regs,rval) + regs->phy_registers=(priv->phy_addr<<5)|(pfyreg&0x1f); + regs->phy_data=val; + udelay(25); + WAIT_FOR_PHY(regs,rval) + spin_unlock_irq(&priv->meth_lock); +} + +/* Modify phy register using given mask and value */ +static void mdio_update(meth_private* priv,int phyreg, int val, int mask) +{ + int rval; + DPRINTK("RMW value %i to PHY register %i with mask %i\n",val,phyreg,mask); + rval=mdio_read(priv,phyreg); + rval=(rval&~mask)|(val&mask); + mdio_write(priv,phyreg,rval); +} + +/* handle errata data on MDIO bus */ +//static void mdio_errata(meth_private *priv) +//{ + /* Hmmm... what the hell is phyerrata? does it come from sys init parameters in IRIX */ +//} +static int mdio_probe(meth_private *priv) +{ + int i, p2, p3; + DPRINTK("Detecting PHY kind\n"); + /* check if phy is detected already */ + if(priv->phy_addr>=0&&priv->phy_addr<32) + return 0; + spin_lock_irq(&priv->meth_lock); + for (i=0;i<32;++i){ + priv->phy_addr=(char)i; + p2=mdio_read(priv,2); +#ifdef MFE_DEBUG + p3=mdio_read(priv,3); + switch ((p2<<12)|(p3>>4)){ + case PHY_QS6612X: + DPRINTK("PHY is QS6612X\n"); + break; + case PHY_ICS1889: + DPRINTK("PHY is ICS1889\n"); + break; + case PHY_ICS1890: + DPRINTK("PHY is ICS1890\n"); + break; + case PHY_DP83840: + DPRINTK("PHY is DP83840\n"); + break; + } +#endif + if(p2!=0xffff&&p2!=0x0000){ + DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4)); + break; + } + } + spin_unlock_irq(&priv->meth_lock); + if(priv->phy_addr<32) { + return 0; + } + DPRINTK("Oopsie! PHY is not known!\n"); + priv->phy_addr=-1; + return -ENODEV; +} + +static void meth_check_link(struct net_device *dev) +{ + struct meth_private *priv = (struct meth_private *) dev->priv; + int mii_partner = mdio_read(priv, 5); + int mii_advertising = mdio_read(priv, 4); + int negotiated = mii_advertising & mii_partner; + int duplex, speed; + + if (mii_partner == 0xffff) + return; + + duplex = ((negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040)?METH_PHY_FDX:0; + speed = (negotiated & 0x0380)?METH_100MBIT:0; + + if ((priv->mode & METH_PHY_FDX) ^ duplex) + { + DPRINTK("Setting %s-duplex\n", duplex ? "full" : "half"); + if (duplex) + priv->mode |= METH_PHY_FDX; + else + priv->mode &= ~METH_PHY_FDX; + priv->regs->mac_ctrl = priv->mode; + } + + if ((priv->mode & METH_100MBIT) ^ speed) + { + DPRINTK("Setting %dMbs mode\n", speed ? 100 : 10); + if (duplex) + priv->mode |= METH_100MBIT; + else + priv->mode &= ~METH_100MBIT; + priv->regs->mac_ctrl = priv->mode; + } +} + + +static int meth_init_tx_ring(meth_private *priv) +{ + /* Init TX ring */ + DPRINTK("Initializing TX ring\n"); + priv->tx_ring = (tx_packet *) pci_alloc_consistent(NULL,TX_RING_BUFFER_SIZE,&(priv->tx_ring_dma)); + if(!priv->tx_ring) + return -ENOMEM; + memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE); + priv->tx_count = priv->tx_read = priv->tx_write = 0; + priv->regs->tx_ring_base = priv->tx_ring_dma; + priv->free_space = TX_RING_ENTRIES; + /* Now init skb save area */ + memset(priv->tx_skbs,0,sizeof(priv->tx_skbs)); + memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas)); + DPRINTK("Done with TX ring init\n"); + return 0; +} + +static int meth_init_rx_ring(meth_private *priv) +{ + int i; + DPRINTK("Initializing RX ring\n"); + for(i=0;i<RX_RING_ENTRIES;i++){ + DPRINTK("\t1:\t%i\t",i); + /*if(!(priv->rx_ring[i]=get_free_page(GFP_KERNEL))) + return -ENOMEM; + DPRINTK("\t2:\t%i\n",i);*/ + priv->rx_ring[i]=(rx_packet*)pci_alloc_consistent(NULL,METH_RX_BUFF_SIZE,&(priv->rx_ring_dmas[i])); + /* I'll need to re-sync it after each RX */ + DPRINTK("\t%p\n",priv->rx_ring[i]); + priv->regs->rx_fifo=priv->rx_ring_dmas[i]; + } + priv->rx_write = 0; + DPRINTK("Done with RX ring\n"); + return 0; +} +static void meth_free_tx_ring(meth_private *priv) +{ + int i; + + /* Remove any pending skb */ + for (i = 0; i < TX_RING_ENTRIES; i++) { + if (priv->tx_skbs[i]) + dev_kfree_skb(priv->tx_skbs[i]); + priv->tx_skbs[i] = NULL; + } + pci_free_consistent(NULL, + TX_RING_BUFFER_SIZE, + priv->tx_ring, + priv->tx_ring_dma); +} +static void meth_free_rx_ring(meth_private *priv) +{ + int i; + + for(i=0;i<RX_RING_ENTRIES;i++) + pci_free_consistent(NULL, + METH_RX_BUFF_SIZE, + priv->rx_ring[i], + priv->rx_ring_dmas[i]); +} + +int meth_reset(struct net_device *dev) +{ + struct meth_private *priv = (struct meth_private *) dev->priv; + + /* Reset card */ + priv->regs->mac_ctrl = SGI_MAC_RESET; + priv->regs->mac_ctrl = 0; + udelay(25); + DPRINTK("MAC control after reset: %016lx\n", priv->regs->mac_ctrl); + + /* Load ethernet address */ + load_eaddr(dev, priv->regs); + /* Should load some "errata", but later */ + + /* Check for device */ + if(mdio_probe(priv) < 0) { + DPRINTK("Unable to find PHY\n"); + return -ENODEV; + } + + /* Initial mode -- 10|Half-duplex|Accept normal packets */ + priv->mode=METH_ACCEPT_MCAST|METH_DEFAULT_IPG; + if(dev->flags | IFF_PROMISC) + priv->mode |= METH_PROMISC; + priv->regs->mac_ctrl = priv->mode; + + /* Autonegociate speed and duplex mode */ + meth_check_link(dev); + + /* Now set dma control, but don't enable DMA, yet */ + priv->regs->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) | + (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT); + + return(0); +} + +/*============End Helper Routines=====================*/ + +/* + * Open and close + */ + +int meth_open(struct net_device *dev) +{ + meth_private *priv=dev->priv; + volatile meth_regs *regs=priv->regs; + + MOD_INC_USE_COUNT; + + /* Start DMA */ + regs->dma_ctrl|= + METH_DMA_TX_EN|/*METH_DMA_TX_INT_EN|*/ + METH_DMA_RX_EN|METH_DMA_RX_INT_EN; + + if(request_irq(dev->irq,meth_interrupt,SA_SHIRQ,meth_str,dev)){ + printk(KERN_ERR "%s: Can't get irq %d\n", dev->name, dev->irq); + return -EAGAIN; + } + netif_start_queue(dev); + DPRINTK("Opened... DMA control=0x%08lx\n", regs->dma_ctrl); + return 0; +} + +int meth_release(struct net_device *dev) +{ + netif_stop_queue(dev); /* can't transmit any more */ + /* shut down dma */ + ((meth_private*)(dev->priv))->regs->dma_ctrl&= + ~(METH_DMA_TX_EN|METH_DMA_TX_INT_EN| + METH_DMA_RX_EN|METH_DMA_RX_INT_EN); + free_irq(dev->irq, dev); + MOD_DEC_USE_COUNT; + return 0; +} + +/* + * Configuration changes (passed on by ifconfig) + */ +int meth_config(struct net_device *dev, struct ifmap *map) +{ + if (dev->flags & IFF_UP) /* can't act on a running interface */ + return -EBUSY; + + /* Don't allow changing the I/O address */ + if (map->base_addr != dev->base_addr) { + printk(KERN_WARNING "meth: Can't change I/O address\n"); + return -EOPNOTSUPP; + } + + /* Allow changing the IRQ */ + if (map->irq != dev->irq) { + printk(KERN_WARNING "meth: Can't change IRQ\n"); + return -EOPNOTSUPP; + } + DPRINTK("Configured\n"); + + /* ignore other fields */ + return 0; +} + +/* + * Receive a packet: retrieve, encapsulate and pass over to upper levels + */ +void meth_rx(struct net_device* dev) +{ + struct sk_buff *skb; + struct meth_private *priv = (struct meth_private *) dev->priv; + rx_packet *rxb; + DPRINTK("RX...\n"); + // TEMP while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){ + while((rxb=priv->rx_ring[priv->rx_write])->status.raw&0x8000000000000000){ + int len=rxb->status.parsed.rx_len - 4; /* omit CRC */ + DPRINTK("(%i)\n",priv->rx_write); + /* length sanity check */ + if(len < 60 || len > 1518) { + printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x.\n", + dev->name, priv->rx_write, rxb->status.raw); + priv->stats.rx_errors++; + priv->stats.rx_length_errors++; + } + if(!(rxb->status.raw&METH_RX_STATUS_ERRORS)){ + skb=alloc_skb(len+2,GFP_ATOMIC);/* Should be atomic -- we are in interrupt */ + if(!skb){ + /* Ouch! No memory! Drop packet on the floor */ + DPRINTK("!!!>>>Ouch! Not enough Memory for RX buffer!\n"); + priv->stats.rx_dropped++; + } else { + skb_reserve(skb, 2); /* align IP on 16B boundary */ + memcpy(skb_put(skb, len), rxb->buf, len); + /* Write metadata, and then pass to the receive level */ + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + //skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */ + + DPRINTK("passing packet\n"); + DPRINTK("len = %d rxb->status = %x\n", + len, rxb->status.raw); + netif_rx(skb); + dev->last_rx = jiffies; + priv->stats.rx_packets++; + priv->stats.rx_bytes+=len; + DPRINTK("There we go... Whew...\n"); + } + } + priv->regs->rx_fifo=priv->rx_ring_dmas[priv->rx_write]; + rxb->status.raw=0; + priv->rx_write=(priv->rx_write+1)&(RX_RING_ENTRIES-1); + } +} + +static int meth_tx_full(struct net_device *dev) +{ + struct meth_private *priv = (struct meth_private *) dev->priv; + + return(priv->tx_count >= TX_RING_ENTRIES-1); +} + +void meth_tx_cleanup(struct net_device* dev, int rptr) +{ + meth_private *priv=dev->priv; + tx_packet* status; + struct sk_buff *skb; + + spin_lock(&priv->meth_lock); + + /* Stop DMA */ + priv->regs->dma_ctrl &= ~(METH_DMA_TX_INT_EN); + + while(priv->tx_read != rptr){ + skb = priv->tx_skbs[priv->tx_read]; + status = &priv->tx_ring[priv->tx_read]; + if(!status->header.res.sent) + break; + if(status->header.raw & METH_TX_STATUS_DONE) { + priv->stats.tx_packets++; + priv->stats.tx_bytes += skb->len; + } + dev_kfree_skb_irq(skb); + priv->tx_skbs[priv->tx_read] = NULL; + status->header.raw = 0; + priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1); + priv->tx_count --; + } + + /* wake up queue if it was stopped */ + if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) { + netif_wake_queue(dev); + } + + spin_unlock(priv->meth_lock); +} + +/* + * The typical interrupt entry point + */ +void meth_interrupt(int irq, void *dev_id, struct pt_regs *pregs) +{ + struct meth_private *priv; + union { + u32 reg; /*Whole status register */ + struct { + u32 : 2, + rx_seq : 5, + tx_read : 9, + + rx_read : 8, + int_mask: 8; + } parsed; + } status; + /* + * As usual, check the "device" pointer for shared handlers. + * Then assign "struct device *dev" + */ + struct net_device *dev = (struct net_device *)dev_id; + /* ... and check with hw if it's really ours */ + + if (!dev /*paranoid*/ ) return; + + /* Lock the device */ + priv = (struct meth_private *) dev->priv; + + status.reg = priv->regs->int_flags; + + DPRINTK("Interrupt, status %08x...\n",status.reg); + if (status.parsed.int_mask & METH_INT_RX_THRESHOLD) { + /* send it to meth_rx for handling */ + meth_rx(dev); + } + + if (status.parsed.int_mask & (METH_INT_TX_EMPTY|METH_INT_TX_PKT)) { + /* a transmission is over: free the skb */ + meth_tx_cleanup(dev, status.parsed.tx_read); + } + /* check for errors too... */ + if (status.parsed.int_mask & (METH_INT_TX_LINK_FAIL)) + printk(KERN_WARNING "meth: link failure\n"); + if (status.parsed.int_mask & (METH_INT_MEM_ERROR)) + printk(KERN_WARNING "meth: memory error\n"); + if (status.parsed.int_mask & (METH_INT_TX_ABORT)) + printk(KERN_WARNING "meth: aborted\n"); + DPRINTK("Interrupt handling done...\n"); + + priv->regs->int_flags=status.reg&0xff; /* clear interrupts */ +} + +/* + * Transmits packets that fit into TX descriptor (are <=120B) + */ +static void meth_tx_short_prepare(meth_private* priv, struct sk_buff* skb) +{ + tx_packet *desc=&priv->tx_ring[priv->tx_write]; + int len = (skb->len<ETH_ZLEN)?ETH_ZLEN:skb->len; + + DPRINTK("preparing short packet\n"); + /* maybe I should set whole thing to 0 first... */ + memcpy(desc->data.dt+(120-len),skb->data,skb->len); + if(skb->len < len) + memset(desc->data.dt+120-len+skb->len,0,len-skb->len); + desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16); + DPRINTK("desc=%016lx\n",desc->header.raw); +} +#define TX_CATBUF1 BIT(25) +static void meth_tx_1page_prepare(meth_private* priv, struct sk_buff* skb) +{ + tx_packet *desc=&priv->tx_ring[priv->tx_write]; + void *buffer_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL)); + int unaligned_len = (int)((u64)buffer_data - (u64)skb->data); + int buffer_len = skb->len - unaligned_len; + dma_addr_t catbuf; + + DPRINTK("preparing 1 page...\n"); + DPRINTK("length=%d data=%p\n", skb->len, skb->data); + DPRINTK("unaligned_len=%d\n", unaligned_len); + DPRINTK("buffer_data=%p buffer_len=%d\n", + buffer_data, + buffer_len); + + desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1); + + /* unaligned part */ + if(unaligned_len){ + memcpy(desc->data.dt+(120-unaligned_len), + skb->data, unaligned_len); + desc->header.raw |= (128-unaligned_len) << 16; + } + + /* first page */ + catbuf = pci_map_single(NULL, + buffer_data, + buffer_len, + PCI_DMA_TODEVICE); + DPRINTK("catbuf=%x\n", catbuf); + desc->data.cat_buf[0].form.start_addr = catbuf >> 3; + desc->data.cat_buf[0].form.len = buffer_len-1; + DPRINTK("desc=%016lx\n",desc->header.raw); + DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw); +} +#define TX_CATBUF2 BIT(26) +static void meth_tx_2page_prepare(meth_private* priv, struct sk_buff* skb) +{ + tx_packet *desc=&priv->tx_ring[priv->tx_write]; + void *buffer1_data = (void *)(((u64)skb->data + 7ULL) & (~7ULL)); + void *buffer2_data = (void *)PAGE_ALIGN((u64)skb->data); + int unaligned_len = (int)((u64)buffer1_data - (u64)skb->data); + int buffer1_len = (int)((u64)buffer2_data - (u64)buffer1_data); + int buffer2_len = skb->len - buffer1_len - unaligned_len; + dma_addr_t catbuf1, catbuf2; + + DPRINTK("preparing 2 pages... \n"); + DPRINTK("length=%d data=%p\n", skb->len, skb->data); + DPRINTK("unaligned_len=%d\n", unaligned_len); + DPRINTK("buffer1_data=%p buffer1_len=%d\n", + buffer1_data, + buffer1_len); + DPRINTK("buffer2_data=%p buffer2_len=%d\n", + buffer2_data, + buffer2_len); + + desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1); + /* unaligned part */ + if(unaligned_len){ + memcpy(desc->data.dt+(120-unaligned_len), + skb->data, unaligned_len); + desc->header.raw |= (128-unaligned_len) << 16; + } + + /* first page */ + catbuf1 = pci_map_single(NULL, + buffer1_data, + buffer1_len, + PCI_DMA_TODEVICE); + DPRINTK("catbuf1=%x\n", catbuf1); + desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3; + desc->data.cat_buf[0].form.len = buffer1_len-1; + /* second page */ + catbuf2 = pci_map_single(NULL, + buffer2_data, + buffer2_len, + PCI_DMA_TODEVICE); + DPRINTK("catbuf2=%x\n", catbuf2); + desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3; + desc->data.cat_buf[1].form.len = buffer2_len-1; + DPRINTK("desc=%016lx\n",desc->header.raw); + DPRINTK("cat_buf[0].raw=%016lx\n",desc->data.cat_buf[0].raw); + DPRINTK("cat_buf[1].raw=%016lx\n",desc->data.cat_buf[1].raw); +} + + +void meth_add_to_tx_ring(meth_private *priv, struct sk_buff* skb) +{ + DPRINTK("Transmitting data...\n"); + if(skb->len <= 120) { + /* Whole packet fits into descriptor */ + meth_tx_short_prepare(priv,skb); + } else if(PAGE_ALIGN((u64)skb->data) != + PAGE_ALIGN((u64)skb->data+skb->len-1)) { + /* Packet crosses page boundary */ + meth_tx_2page_prepare(priv,skb); + } else { + /* Packet is in one page */ + meth_tx_1page_prepare(priv,skb); + } + + /* Remember the skb, so we can free it at interrupt time */ + priv->tx_skbs[priv->tx_write] = skb; + priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1); + priv->regs->tx_info.wptr = priv->tx_write; + priv->tx_count ++; + /* Enable DMA transfer */ + priv->regs->dma_ctrl |= METH_DMA_TX_INT_EN; +} + +/* + * Transmit a packet (called by the kernel) + */ +int meth_tx(struct sk_buff *skb, struct net_device *dev) +{ + struct meth_private *priv = (struct meth_private *) dev->priv; + + spin_lock_irq(&priv->meth_lock); + + meth_add_to_tx_ring(priv, skb); + dev->trans_start = jiffies; /* save the timestamp */ + + /* If TX ring is full, tell the upper layer to stop sending packets */ + if (meth_tx_full(dev)) { + DPRINTK("TX full: stopping\n"); + netif_stop_queue(dev); + } + + spin_unlock_irq(&priv->meth_lock); + + return 0; +} + +/* + * Deal with a transmit timeout. + */ + +void meth_tx_timeout (struct net_device *dev) +{ + struct meth_private *priv = (struct meth_private *) dev->priv; + + printk(KERN_WARNING "%s: transmit timed out\n", dev->name); + + /* Protect against concurrent rx interrupts */ + spin_lock_irq(&priv->meth_lock); + + /* Try to reset the adaptor. */ + meth_reset(dev); + + priv->stats.tx_errors++; + + /* Clear all rings */ + meth_free_tx_ring(priv); + meth_free_rx_ring(priv); + meth_init_tx_ring(priv); + meth_init_rx_ring(priv); + + /* Restart dma */ + priv->regs->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN; + + /* Enable interrupt */ + spin_unlock_irq(&priv->meth_lock); + + dev->trans_start = jiffies; + netif_wake_queue(dev); + + return; +} + +/* + * Ioctl commands + */ +int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + + DPRINTK("ioctl\n"); + return 0; +} + +/* + * Return statistics to the caller + */ +struct net_device_stats *meth_stats(struct net_device *dev) +{ + struct meth_private *priv = (struct meth_private *) dev->priv; + return &priv->stats; +} + +/* + * The init function (sometimes called probe). + * It is invoked by register_netdev() + */ +int meth_init(struct net_device *dev) +{ + meth_private *priv; + int ret; + /* + * Then, assign other fields in dev, using ether_setup() and some + * hand assignments + */ + ether_setup(dev); /* assign some of the fields */ + + dev->open = meth_open; + dev->stop = meth_release; + dev->set_config = meth_config; + dev->hard_start_xmit = meth_tx; + dev->do_ioctl = meth_ioctl; + dev->get_stats = meth_stats; +#ifdef HAVE_TX_TIMEOUT + dev->tx_timeout = meth_tx_timeout; + dev->watchdog_timeo = timeout; +#endif + dev->irq = MACE_ETHERNET_IRQ; + SET_MODULE_OWNER(dev); + + /* + * Then, allocate the priv field. This encloses the statistics + * and a few private fields. + */ + priv = kmalloc(sizeof(struct meth_private), GFP_KERNEL); + if (priv == NULL) + return -ENOMEM; + dev->priv=priv; + memset(priv, 0, sizeof(struct meth_private)); + spin_lock_init(&((struct meth_private *) dev->priv)->meth_lock); + /* + * Make the usual checks: check_region(), probe irq, ... -ENODEV + * should be returned if no device found. No resource should be + * grabbed: this is done on open(). + */ + priv->regs=(meth_regs*)SGI_MFE; + dev->base_addr=SGI_MFE; + priv->phy_addr = -1; /* No phy is known yet... */ + + /* Initialize the hardware */ + if((ret=meth_reset(dev)) < 0) + return ret; + + /* Allocate the ring buffers */ + if((ret=meth_init_tx_ring(priv))<0||(ret=meth_init_rx_ring(priv))<0){ + meth_free_tx_ring(priv); + meth_free_rx_ring(priv); + return ret; + } + + printk("SGI O2 Fast Ethernet rev. %ld\n", priv->regs->mac_ctrl >> 29); + + return 0; +} + +/* + * The devices + */ + +struct net_device meth_devs[1] = { + { init: meth_init, } /* init, nothing more */ +}; + +/* + * Finally, the module stuff + */ + +int meth_init_module(void) +{ + int result, device_present = 0; + + strcpy(meth_devs[0].name, "eth%d"); + + if ( (result = register_netdev(meth_devs)) ) + printk("meth: error %i registering device \"%s\"\n", + result, meth_devs->name); + else device_present++; +#ifndef METH_DEBUG + EXPORT_NO_SYMBOLS; +#endif + + return device_present ? 0 : -ENODEV; +} + +void meth_cleanup(void) +{ + kfree(meth_devs->priv); + unregister_netdev(meth_devs); + return; +} + +module_init(meth_init_module); +module_exit(meth_cleanup); diff -Nru a/drivers/net/meth.h b/drivers/net/meth.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/net/meth.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,273 @@ + +/* + * snull.h -- definitions for the network module + * + * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet + * Copyright (C) 2001 O'Reilly & Associates + * + * The source code in this file can be freely used, adapted, + * and redistributed in source or binary form, so long as an + * acknowledgment appears in derived source files. The citation + * should list that the code comes from the book "Linux Device + * Drivers" by Alessandro Rubini and Jonathan Corbet, published + * by O'Reilly & Associates. No warranty is attached; + * we cannot take responsibility for errors or fitness for use. + */ + +/* version dependencies have been confined to a separate file */ + +#define SGI_MFE (MACE_BASE+MACE_ENET) +/* (0xBF280000)*/ + +/* Tunable parameters */ +#define TX_RING_ENTRIES 64 /* 64-512?*/ + +#define RX_RING_ENTRIES 16 /* Do not change */ +/* Internal constants */ +#define TX_RING_BUFFER_SIZE (TX_RING_ENTRIES*sizeof(tx_packet)) +#define RX_BUFFER_SIZE 1546 /* ethenet packet size */ +#define METH_RX_BUFF_SIZE 4096 +#define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */ +#define RX_BUCKET_SIZE 256 + + + +/* For more detailed explanations of what each field menas, + see Nick's great comments to #defines below (or docs, if + you are lucky enough toget hold of them :)*/ + +/* tx status vector is written over tx command header upon + dma completion. */ + +typedef struct tx_status_vector { + u64 sent:1; /* always set to 1...*/ + u64 pad0:34;/* always set to 0 */ + u64 flags:9; /*I'm too lazy to specify each one separately at the moment*/ + u64 col_retry_cnt:4; /*collision retry count*/ + u64 len:16; /*Transmit length in bytes*/ +} tx_status_vector; + +/* + * Each packet is 128 bytes long. + * It consists of header, 0-3 concatination + * buffer pointers and up to 120 data bytes. + */ +typedef struct tx_packet_hdr { + u64 pad1:36; /*should be filled with 0 */ + u64 cat_ptr3_valid:1, /*Concatination pointer valid flags*/ + cat_ptr2_valid:1, + cat_ptr1_valid:1; + u64 tx_int_flag:1; /*Generate TX intrrupt when packet has been sent*/ + u64 term_dma_flag:1; /*Terminate transmit DMA on transmit abort conditions*/ + u64 data_offset:7; /*Starting byte offset in ring data block*/ + u64 data_len:16; /*Length of valid data in bytes-1*/ +} tx_packet_hdr; +typedef union tx_cat_ptr { + struct { + u64 pad2:16; /* should be 0 */ + u64 len:16; /*length of buffer data - 1*/ + u64 start_addr:29; /*Physical starting address*/ + u64 pad1:3; /* should be zero */ + } form; + u64 raw; +} tx_cat_ptr; + +typedef struct tx_packet { + union { + tx_packet_hdr header; + tx_status_vector res; + u64 raw; + }header; + union { + tx_cat_ptr cat_buf[3]; + char dt[120]; + } data; +} tx_packet; + +typedef union rx_status_vector { + struct { + u64 pad1:1;/*fill it with ones*/ + u64 pad2:15;/*fill with 0*/ + u64 ip_chk_sum:16; + u64 seq_num:5; + u64 mac_addr_match:1; + u64 mcast_addr_match:1; + u64 carrier_event_seen:1; + u64 bad_packet:1; + u64 long_event_seen:1; + u64 invalid_preamble:1; + u64 broadcast:1; + u64 multicast:1; + u64 crc_error:1; + u64 huh:1;/*???*/ + u64 rx_code_violation:1; + u64 rx_len:16; + } parsed; + u64 raw; +} rx_status_vector; + +typedef struct rx_packet { + rx_status_vector status; + u64 pad[3]; /* For whatever reason, there needs to be 4 double-word offset */ + u16 pad2; + char buf[METH_RX_BUFF_SIZE-sizeof(rx_status_vector)-3*sizeof(u64)-sizeof(u16)];/* data */ +} rx_packet; + +typedef struct meth_regs { + u64 mac_ctrl; /*0x00,rw,31:0*/ + u64 int_flags; /*0x08,rw,30:0*/ + u64 dma_ctrl; /*0x10,rw,15:0*/ + u64 timer; /*0x18,rw,5:0*/ + u64 int_tx; /*0x20,wo,0:0*/ + u64 int_rx; /*0x28,wo,9:4*/ + struct { + u32 tx_info_pad; + u32 rptr:16,wptr:16; + } tx_info; /*0x30,rw,31:0*/ + u64 tx_info_al; /*0x38,rw,31:0*/ + struct { + u32 rx_buff_pad1; + u32 rx_buff_pad2:8, + wptr:8, + rptr:8, + depth:8; + } rx_buff; /*0x40,ro,23:0*/ + u64 rx_buff_al1; /*0x48,ro,23:0*/ + u64 rx_buff_al2; /*0x50,ro,23:0*/ + u64 int_update; /*0x58,wo,31:0*/ + u32 phy_data_pad; + u32 phy_data; /*0x60,rw,16:0*/ + u32 phy_reg_pad; + u32 phy_registers; /*0x68,rw,9:0*/ + u64 phy_trans_go; /*0x70,wo,0:0*/ + u64 backoff_seed; /*0x78,wo,10:0*/ + u64 imq_reserved[4];/*0x80,ro,64:0(x4)*/ + /*===================================*/ + u64 mac_addr; /*0xA0,rw,47:0, I think it's MAC address, but I'm not sure*/ + u64 mcast_addr; /*0xA8,rw,47:0, This seems like secondary MAC address*/ + u64 mcast_filter; /*0xB0,rw,63:0*/ + u64 tx_ring_base; /*0xB8,rw,31:13*/ + /* Following are read-only debugging info register */ + u64 tx_pkt1_hdr; /*0xC0,ro,63:0*/ + u64 tx_pkt1_ptr[3]; /*0xC8,ro,63:0(x3)*/ + u64 tx_pkt2_hdr; /*0xE0,ro,63:0*/ + u64 tx_pkt2_ptr[3]; /*0xE8,ro,63:0(x3)*/ + /*===================================*/ + u32 rx_pad; + u32 rx_fifo; + u64 reserved[31]; +}meth_regs; + + /* Bits in METH_MAC */ + +#define SGI_MAC_RESET BIT(0) /* 0: MAC110 active in run mode, 1: Global reset signal to MAC110 core is active */ +#define METH_PHY_FDX BIT(1) /* 0: Disable full duplex, 1: Enable full duplex */ +#define METH_PHY_LOOP BIT(2) /* 0: Normal operation, follows 10/100mbit and M10T/MII select, 1: loops internal MII bus */ + /* selects ignored */ +#define METH_100MBIT BIT(3) /* 0: 10meg mode, 1: 100meg mode */ +#define METH_PHY_MII BIT(4) /* 0: MII selected, 1: SIA selected */ + /* Note: when loopback is set this bit becomes collision control. Setting this bit will */ + /* cause a collision to be reported. */ + + /* Bits 5 and 6 are used to determine the the Destination address filter mode */ +#define METH_ACCEPT_MY 0 /* 00: Accept PHY address only */ +#define METH_ACCEPT_MCAST 0x20 /* 01: Accept physical, broadcast, and multicast filter matches only */ +#define METH_ACCEPT_AMCAST 0x40 /* 10: Accept physical, broadcast, and all multicast packets */ +#define METH_PROMISC 0x60 /* 11: Promiscious mode */ + +#define METH_PHY_LINK_FAIL BIT(7) /* 0: Link failure detection disabled, 1: Hardware scans for link failure in PHY */ + +#define METH_MAC_IPG 0x1ffff00 + +#define METH_DEFAULT_IPG ((17<<15) | (11<<22) | (21<<8)) + /* 0x172e5c00 */ /* 23, 23, 23 */ /*0x54A9500 *//*21,21,21*/ + /* Bits 8 through 14 are used to determine Inter-Packet Gap between "Back to Back" packets */ + /* The gap depends on the clock speed of the link, 80ns per increment for 100baseT, 800ns */ + /* per increment for 10BaseT */ + + /* Bits 15 through 21 are used to determine IPGR1 */ + + /* Bits 22 through 28 are used to determine IPGR2 */ + +#define METH_REV_SHIFT 29 /* Bits 29 through 31 are used to determine the revision */ + /* 000: Inital revision */ + /* 001: First revision, Improved TX concatenation */ + + +/* DMA control bits */ +#define METH_RX_OFFSET_SHIFT 12 /* Bits 12:14 of DMA control register indicate starting offset of packet data for RX operation */ +#define METH_RX_DEPTH_SHIFT 4 /* Bits 8:4 define RX fifo depth -- when # of RX fifo entries != depth, interrupt is generted */ + +#define METH_DMA_TX_EN BIT(1) /* enable TX DMA */ +#define METH_DMA_TX_INT_EN BIT(0) /* enable TX Buffer Empty interrupt */ +#define METH_DMA_RX_EN BIT(15) /* Enable RX */ +#define METH_DMA_RX_INT_EN BIT(9) /* Enable interrupt on RX packet */ + + +/* RX status bits */ + +#define METH_RX_ST_RCV_CODE_VIOLATION BIT(16) +#define METH_RX_ST_DRBL_NBL BIT(17) +#define METH_RX_ST_CRC_ERR BIT(18) +#define METH_RX_ST_MCAST_PKT BIT(19) +#define METH_RX_ST_BCAST_PKT BIT(20) +#define METH_RX_ST_INV_PREAMBLE_CTX BIT(21) +#define METH_RX_ST_LONG_EVT_SEEN BIT(22) +#define METH_RX_ST_BAD_PACKET BIT(23) +#define METH_RX_ST_CARRIER_EVT_SEEN BIT(24) +#define METH_RX_ST_MCAST_FILTER_MATCH BIT(25) +#define METH_RX_ST_PHYS_ADDR_MATCH BIT(26) + +#define METH_RX_STATUS_ERRORS \ + ( \ + METH_RX_ST_RCV_CODE_VIOLATION| \ + METH_RX_ST_CRC_ERR| \ + METH_RX_ST_INV_PREAMBLE_CTX| \ + METH_RX_ST_LONG_EVT_SEEN| \ + METH_RX_ST_BAD_PACKET| \ + METH_RX_ST_CARRIER_EVT_SEEN \ + ) + /* Bits in METH_INT */ + /* Write _1_ to corresponding bit to clear */ +#define METH_INT_TX_EMPTY BIT(0) /* 0: No interrupt pending, 1: The TX ring buffer is empty */ +#define METH_INT_TX_PKT BIT(1) /* 0: No interrupt pending */ + /* 1: A TX message had the INT request bit set, the packet has been sent. */ +#define METH_INT_TX_LINK_FAIL BIT(2) /* 0: No interrupt pending, 1: PHY has reported a link failure */ +#define METH_INT_MEM_ERROR BIT(3) /* 0: No interrupt pending */ + /* 1: A memory error occurred durring DMA, DMA stopped, Fatal */ +#define METH_INT_TX_ABORT BIT(4) /* 0: No interrupt pending, 1: The TX aborted operation, DMA stopped, FATAL */ +#define METH_INT_RX_THRESHOLD BIT(5) /* 0: No interrupt pending, 1: Selected receive threshold condition Valid */ +#define METH_INT_RX_UNDERFLOW BIT(6) /* 0: No interrupt pending, 1: FIFO was empty, packet could not be queued */ +#define METH_INT_RX_OVERFLOW BIT(7) /* 0: No interrupt pending, 1: DMA FIFO Overflow, DMA stopped, FATAL */ + +#define METH_INT_RX_RPTR_MASK 0x0001F00 /* Bits 8 through 12 alias of RX read-pointer */ + + /* Bits 13 through 15 are always 0. */ + +#define METH_INT_TX_RPTR_MASK 0x1FF0000 /* Bits 16 through 24 alias of TX read-pointer */ + +#define METH_INT_SEQ_MASK 0x2E000000 /* Bits 25 through 29 are the starting seq number for the message at the */ + /* top of the queue */ + +#define METH_ERRORS ( \ + METH_INT_RX_OVERFLOW| \ + METH_INT_RX_UNDERFLOW| \ + METH_INT_MEM_ERROR| \ + METH_INT_TX_ABORT) + +#define METH_INT_MCAST_HASH BIT(30) /* If RX DMA is enabled the hash select logic output is latched here */ + +/* TX status bits */ +#define METH_TX_STATUS_DONE BIT(23) /* Packet was transmitted successfully */ + +/* Tx command header bits */ +#define METH_TX_CMD_INT_EN BIT(24) /* Generate TX interrupt when packet is sent */ + +/* Phy MDIO interface busy flag */ +#define MDIO_BUSY BIT(16) +#define MDIO_DATA_MASK 0xFFFF +/* PHY defines */ +#define PHY_QS6612X 0x0181441 /* Quality TX */ +#define PHY_ICS1889 0x0015F41 /* ICS FX */ +#define PHY_ICS1890 0x0015F42 /* ICS TX */ +#define PHY_DP83840 0x20005C0 /* National TX */ diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c --- a/drivers/net/pcmcia/3c574_cs.c Fri Jun 27 14:19:54 2003 +++ b/drivers/net/pcmcia/3c574_cs.c Fri Jun 27 14:19:54 2003 @@ -211,7 +211,6 @@ struct el3_private { dev_link_t link; - struct net_device dev; dev_node_t node; struct net_device_stats stats; u16 advertising, partner; /* NWay media advertisement */ @@ -291,13 +290,12 @@ flush_stale_links(); /* Create the PC card device object. */ - lp = kmalloc(sizeof(*lp), GFP_KERNEL); - if (!lp) + dev = alloc_etherdev(sizeof(struct el3_private)); + if (!dev) return NULL; - - memset(lp, 0, sizeof(*lp)); - link = &lp->link; dev = &lp->dev; - link->priv = dev->priv = link->irq.Instance = lp; + lp = dev->priv; + link = &lp->link; + link->priv = dev; init_timer(&link->release); link->release.function = &tc574_release; @@ -312,6 +310,7 @@ for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = &el3_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; @@ -323,7 +322,6 @@ dev->get_stats = &el3_get_stats; dev->do_ioctl = &el3_ioctl; dev->set_multicast_list = &set_rx_mode; - ether_setup(dev); dev->open = &el3_open; dev->stop = &el3_close; #ifdef HAVE_TX_TIMEOUT @@ -364,7 +362,7 @@ static void tc574_detach(dev_link_t *link) { - struct el3_private *lp = link->priv; + struct net_device *dev = link->priv; dev_link_t **linkp; DEBUG(0, "3c574_detach(0x%p)\n", link); @@ -390,8 +388,8 @@ /* Unlink device structure, free bits */ *linkp = link->next; if (link->dev) - unregister_netdev(&lp->dev); - kfree(lp); + unregister_netdev(dev); + kfree(dev); } /* tc574_detach */ @@ -407,8 +405,8 @@ static void tc574_config(dev_link_t *link) { client_handle_t handle = link->handle; - struct el3_private *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; + struct el3_private *lp = dev->priv; tuple_t tuple; cisparse_t parse; unsigned short buf[32]; @@ -599,8 +597,7 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct el3_private *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; DEBUG(1, "3c574_event(0x%06x)\n", event); @@ -856,7 +853,7 @@ tc574_reset(dev); lp->media.function = &media_check; - lp->media.data = (unsigned long)lp; + lp->media.data = (unsigned long) dev; lp->media.expires = jiffies + HZ; add_timer(&lp->media); @@ -939,8 +936,8 @@ /* The EL3 interrupt handler. */ static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct el3_private *lp = dev_id; - struct net_device *dev = &lp->dev; + struct net_device *dev = (struct net_device *) dev_id; + struct el3_private *lp = dev->priv; ioaddr_t ioaddr, status; int work_budget = max_interrupt_work; int handled = 0; @@ -1032,8 +1029,8 @@ */ static void media_check(unsigned long arg) { - struct el3_private *lp = (struct el3_private *)arg; - struct net_device *dev = &lp->dev; + struct net_device *dev = (struct net_device *) arg; + struct el3_private *lp = dev->priv; ioaddr_t ioaddr = dev->base_addr; unsigned long flags; unsigned short /* cable, */ media, partner; diff -Nru a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c --- a/drivers/net/pcmcia/3c589_cs.c Fri Jun 27 14:20:04 2003 +++ b/drivers/net/pcmcia/3c589_cs.c Fri Jun 27 14:20:04 2003 @@ -106,7 +106,6 @@ struct el3_private { dev_link_t link; - struct net_device dev; dev_node_t node; struct net_device_stats stats; /* For transceiver monitoring */ @@ -213,14 +212,14 @@ flush_stale_links(); /* Create new ethernet device */ - lp = kmalloc(sizeof(*lp), GFP_KERNEL); - if (!lp) return NULL; - memset(lp, 0, sizeof(*lp)); + dev = alloc_etherdev(sizeof(struct el3_private)); + if (!dev) + return NULL; + lp = dev->priv; + link = &lp->link; + link->priv = dev; + spin_lock_init(&lp->lock); - - link = &lp->link; dev = &lp->dev; - link->priv = dev->priv = link->irq.Instance = lp; - init_timer(&link->release); link->release.function = &tc589_release; link->release.data = (unsigned long)link; @@ -234,6 +233,7 @@ for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = &el3_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; @@ -246,7 +246,6 @@ dev->set_config = &el3_config; dev->get_stats = &el3_get_stats; dev->set_multicast_list = &set_multicast_list; - ether_setup(dev); dev->open = &el3_open; dev->stop = &el3_close; #ifdef HAVE_TX_TIMEOUT @@ -288,7 +287,7 @@ static void tc589_detach(dev_link_t *link) { - struct el3_private *lp = link->priv; + struct net_device *dev = link->priv; dev_link_t **linkp; DEBUG(0, "3c589_detach(0x%p)\n", link); @@ -314,8 +313,8 @@ /* Unlink device structure, free bits */ *linkp = link->next; if (link->dev) - unregister_netdev(&lp->dev); - kfree(lp); + unregister_netdev(dev); + kfree(dev); } /* tc589_detach */ @@ -333,8 +332,8 @@ static void tc589_config(dev_link_t *link) { client_handle_t handle = link->handle; - struct el3_private *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; + struct el3_private *lp = dev->priv; tuple_t tuple; cisparse_t parse; u16 buf[32], *phys_addr; @@ -487,8 +486,7 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct el3_private *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; DEBUG(1, "3c589_event(0x%06x)\n", event); @@ -738,7 +736,7 @@ tc589_reset(dev); init_timer(&lp->media); lp->media.function = &media_check; - lp->media.data = (unsigned long)lp; + lp->media.data = (unsigned long) dev; lp->media.expires = jiffies + HZ; add_timer(&lp->media); @@ -818,8 +816,8 @@ /* The EL3 interrupt handler. */ static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct el3_private *lp = dev_id; - struct net_device *dev = &lp->dev; + struct net_device *dev = (struct net_device *) dev_id; + struct el3_private *lp = dev->priv; ioaddr_t ioaddr, status; int i = 0, handled = 1; @@ -903,8 +901,8 @@ static void media_check(unsigned long arg) { - struct el3_private *lp = (struct el3_private *)(arg); - struct net_device *dev = &lp->dev; + struct net_device *dev = (struct net_device *)(arg); + struct el3_private *lp = dev->priv; ioaddr_t ioaddr = dev->base_addr; u16 media, errs; unsigned long flags; diff -Nru a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c --- a/drivers/net/pcmcia/fmvj18x_cs.c Fri Jun 27 14:19:59 2003 +++ b/drivers/net/pcmcia/fmvj18x_cs.c Fri Jun 27 14:19:59 2003 @@ -130,7 +130,6 @@ */ typedef struct local_info_t { dev_link_t link; - struct net_device dev; dev_node_t node; struct net_device_stats stats; long open_time; @@ -273,11 +272,12 @@ flush_stale_links(); /* Make up a FMVJ18x specific data structure */ - lp = kmalloc(sizeof(*lp), GFP_KERNEL); - if (!lp) return NULL; - memset(lp, 0, sizeof(*lp)); - link = &lp->link; dev = &lp->dev; - link->priv = dev->priv = link->irq.Instance = lp; + dev = alloc_etherdev(sizeof(local_info_t)); + if (!dev) + return NULL; + lp = dev->priv; + link = &lp->link; + link->priv = dev; init_timer(&link->release); link->release.function = &fmvj18x_release; @@ -297,6 +297,7 @@ for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = &fjn_interrupt; + link->irq.Instance = dev; /* General socket configuration */ link->conf.Attributes = CONF_ENABLE_IRQ; @@ -309,7 +310,6 @@ dev->set_config = &fjn_config; dev->get_stats = &fjn_get_stats; dev->set_multicast_list = &set_rx_mode; - ether_setup(dev); dev->open = &fjn_open; dev->stop = &fjn_close; #ifdef HAVE_TX_TIMEOUT @@ -344,7 +344,7 @@ static void fmvj18x_detach(dev_link_t *link) { - local_info_t *lp = link->priv; + struct net_device *dev = link->priv; dev_link_t **linkp; DEBUG(0, "fmvj18x_detach(0x%p)\n", link); @@ -371,8 +371,8 @@ /* Unlink device structure, free pieces */ *linkp = link->next; if (link->dev) - unregister_netdev(&lp->dev); - kfree(lp); + unregister_netdev(dev); + kfree(dev); } /* fmvj18x_detach */ @@ -423,8 +423,8 @@ static void fmvj18x_config(dev_link_t *link) { client_handle_t handle = link->handle; - local_info_t *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; + local_info_t *lp = dev->priv; tuple_t tuple; cisparse_t parse; u_short buf[32]; @@ -704,8 +704,7 @@ memreq_t mem; u_char *base; int i, j; - local_info_t *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; ioaddr_t ioaddr; /* Allocate a small memory window */ @@ -776,8 +775,7 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; - local_info_t *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; DEBUG(1, "fmvj18x_event(0x%06x)\n", event); @@ -847,8 +845,8 @@ static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - local_info_t *lp = dev_id; - struct net_device *dev = &lp->dev; + struct net_device *dev = dev_id; + local_info_t *lp = dev->priv; ioaddr_t ioaddr; unsigned short tx_stat, rx_stat; diff -Nru a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c --- a/drivers/net/pcmcia/nmclan_cs.c Fri Jun 27 14:19:53 2003 +++ b/drivers/net/pcmcia/nmclan_cs.c Fri Jun 27 14:19:53 2003 @@ -359,7 +359,6 @@ typedef struct _mace_private { dev_link_t link; - struct net_device dev; dev_node_t node; struct net_device_stats linux_stats; /* Linux statistics counters */ mace_statistics mace_stats; /* MACE chip statistics counters */ @@ -476,12 +475,13 @@ flush_stale_links(); /* Create new ethernet device */ - lp = kmalloc(sizeof(*lp), GFP_KERNEL); - if (!lp) return NULL; - memset(lp, 0, sizeof(*lp)); - link = &lp->link; dev = &lp->dev; - link->priv = dev->priv = link->irq.Instance = lp; - + dev = alloc_etherdev(sizeof(mace_private)); + if (!dev) + return NULL; + lp = dev->priv; + link = &lp->link; + link->priv = dev; + init_timer(&link->release); link->release.function = &nmclan_release; link->release.data = (u_long)link; @@ -496,6 +496,7 @@ for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = &mace_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; @@ -510,7 +511,6 @@ dev->get_stats = &mace_get_stats; dev->set_multicast_list = &set_multicast_list; dev->do_ioctl = &mace_ioctl; - ether_setup(dev); dev->open = &mace_open; dev->stop = &mace_close; #ifdef HAVE_TX_TIMEOUT @@ -550,7 +550,7 @@ static void nmclan_detach(dev_link_t *link) { - mace_private *lp = link->priv; + struct net_device *dev = link->priv; dev_link_t **linkp; DEBUG(0, "nmclan_detach(0x%p)\n", link); @@ -576,8 +576,8 @@ /* Unlink device structure, free bits */ *linkp = link->next; if (link->dev) - unregister_netdev(&lp->dev); - kfree(lp); + unregister_netdev(dev); + kfree(dev); } /* nmclan_detach */ @@ -710,8 +710,8 @@ static void nmclan_config(dev_link_t *link) { client_handle_t handle = link->handle; - mace_private *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv;; + mace_private *lp = dev->priv; tuple_t tuple; cisparse_t parse; u_char buf[64]; @@ -836,8 +836,7 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; - mace_private *lp = link->priv; - struct net_device *dev = &lp->dev; + struct net_device *dev = link->priv; DEBUG(1, "nmclan_event(0x%06x)\n", event); @@ -1145,8 +1144,8 @@ ---------------------------------------------------------------------------- */ static irqreturn_t mace_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - mace_private *lp = (mace_private *)dev_id; - struct net_device *dev = &lp->dev; + struct net_device *dev = (struct net_device *) dev_id; + mace_private *lp = dev->priv; ioaddr_t ioaddr = dev->base_addr; int status; int IntrCnt = MACE_MAX_IR_ITERATIONS; diff -Nru a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c --- a/drivers/net/pcmcia/smc91c92_cs.c Fri Jun 27 14:19:59 2003 +++ b/drivers/net/pcmcia/smc91c92_cs.c Fri Jun 27 14:19:59 2003 @@ -113,7 +113,6 @@ struct smc_private { dev_link_t link; - struct net_device dev; spinlock_t lock; u_short manfid; u_short cardid; @@ -344,10 +343,13 @@ flush_stale_links(); /* Create new ethernet device */ - smc = kmalloc(sizeof(struct smc_private), GFP_KERNEL); - if (!smc) return NULL; - memset(smc, 0, sizeof(struct smc_private)); - link = &smc->link; dev = &smc->dev; + dev = alloc_etherdev(sizeof(struct smc_private)); + if (!dev) + return NULL; + smc = dev->priv; + link = &smc->link; + link->priv = dev; + spin_lock_init(&smc->lock); init_timer(&link->release); link->release.function = &smc91c92_release; @@ -363,6 +365,7 @@ for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->irq.Handler = &smc_interrupt; + link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; @@ -373,7 +376,6 @@ dev->get_stats = &smc_get_stats; dev->set_config = &s9k_config; dev->set_multicast_list = &set_rx_mode; - ether_setup(dev); dev->open = &smc_open; dev->stop = &smc_close; dev->do_ioctl = &smc_ioctl; @@ -381,7 +383,6 @@ dev->tx_timeout = smc_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; #endif - dev->priv = link->priv = link->irq.Instance = smc; smc->mii_if.dev = dev; smc->mii_if.mdio_read = mdio_read; @@ -421,7 +422,7 @@ static void smc91c92_detach(dev_link_t *link) { - struct smc_private *smc = link->priv; + struct net_device *dev = link->priv; dev_link_t **linkp; DEBUG(0, "smc91c92_detach(0x%p)\n", link); @@ -447,8 +448,8 @@ /* Unlink device structure, free bits */ *linkp = link->next; if (link->dev) - unregister_netdev(&smc->dev); - kfree(smc); + unregister_netdev(dev); + kfree(dev); } /* smc91c92_detach */ @@ -502,7 +503,8 @@ static int mhz_3288_power(dev_link_t *link) { - struct smc_private *smc = link->priv; + struct net_device *dev = link->priv; + struct smc_private *smc = dev->priv; u_char tmp; /* Read the ISR twice... */ @@ -523,8 +525,8 @@ static int mhz_mfc_config(dev_link_t *link) { - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; + struct smc_private *smc = dev->priv; tuple_t tuple; cisparse_t parse; u_char buf[255]; @@ -590,8 +592,7 @@ static int mhz_setup(dev_link_t *link) { client_handle_t handle = link->handle; - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; tuple_t tuple; cisparse_t parse; u_char buf[255], *station_addr; @@ -638,8 +639,8 @@ static void mot_config(dev_link_t *link) { - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; + struct smc_private *smc = dev->priv; ioaddr_t ioaddr = dev->base_addr; ioaddr_t iouart = link->io.BasePort2; @@ -659,8 +660,7 @@ static int mot_setup(dev_link_t *link) { - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; ioaddr_t ioaddr = dev->base_addr; int i, wait, loop; u_int addr; @@ -694,8 +694,7 @@ static int smc_config(dev_link_t *link) { - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; tuple_t tuple; cisparse_t parse; u_char buf[255]; @@ -727,8 +726,7 @@ static int smc_setup(dev_link_t *link) { client_handle_t handle = link->handle; - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; tuple_t tuple; cisparse_t parse; cistpl_lan_node_id_t *node_id; @@ -755,7 +753,6 @@ return 0; } } - /* Try the third string in the Version 1 Version/ID tuple. */ tuple.DesiredTuple = CISTPL_VERS_1; if (first_tuple(handle, &tuple, &parse) != CS_SUCCESS) @@ -771,8 +768,7 @@ static int osi_config(dev_link_t *link) { - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; static ioaddr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; int i, j; @@ -806,8 +802,7 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) { client_handle_t handle = link->handle; - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; tuple_t tuple; u_char buf[255]; int i; @@ -862,8 +857,7 @@ static int check_sig(dev_link_t *link) { - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; ioaddr_t ioaddr = dev->base_addr; int width; u_short s; @@ -921,8 +915,8 @@ static void smc91c92_config(dev_link_t *link) { client_handle_t handle = link->handle; - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; + struct smc_private *smc = dev->priv; tuple_t tuple; cisparse_t parse; u_short buf[32]; @@ -1090,7 +1084,6 @@ static void smc91c92_release(u_long arg) { dev_link_t *link = (dev_link_t *)arg; - struct smc_private *smc = link->priv; DEBUG(0, "smc91c92_release(0x%p)\n", link); @@ -1105,6 +1098,8 @@ CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseIRQ, link->handle, &link->irq); if (link->win) { + struct net_device *dev = link->priv; + struct smc_private *smc = dev->priv; iounmap(smc->base); CardServices(ReleaseWindow, link->win); } @@ -1126,8 +1121,8 @@ event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct smc_private *smc = link->priv; - struct net_device *dev = &smc->dev; + struct net_device *dev = link->priv; + struct smc_private *smc = dev->priv; int i; DEBUG(1, "smc91c92_event(0x%06x)\n", event); @@ -1302,7 +1297,7 @@ smc_reset(dev); init_timer(&smc->media); smc->media.function = &media_check; - smc->media.data = (u_long)smc; + smc->media.data = (u_long) dev; smc->media.expires = jiffies + HZ; add_timer(&smc->media); @@ -1576,8 +1571,8 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - struct smc_private *smc = dev_id; - struct net_device *dev = &smc->dev; + struct net_device *dev = dev_id; + struct smc_private *smc = dev->priv; ioaddr_t ioaddr; u_short saved_bank, saved_pointer, mask, status; unsigned int handled = 1; @@ -1967,8 +1962,8 @@ static void media_check(u_long arg) { - struct smc_private *smc = (struct smc_private *)(arg); - struct net_device *dev = &smc->dev; + struct net_device *dev = (struct net_device *) arg; + struct smc_private *smc = dev->priv; ioaddr_t ioaddr = dev->base_addr; u_short i, media, saved_bank; u_short link; diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c --- a/drivers/net/ppp_generic.c Fri Jun 27 14:20:04 2003 +++ b/drivers/net/ppp_generic.c Fri Jun 27 14:20:04 2003 @@ -1348,11 +1348,18 @@ struct channel *pch = chan->ppp; int proto; - if (pch == 0 || skb->len == 0) { - kfree_skb(skb); - return; - } + if (pch == 0) + goto drop; + /* need to have PPP header */ + if (!pskb_may_pull(skb, 2)) { + if (pch->ppp) { + ++pch->ppp->stats.rx_length_errors; + ppp_receive_error(pch->ppp); + } + goto drop; + } + proto = PPP_PROTO(skb); read_lock_bh(&pch->upl); if (pch->ppp == 0 || proto >= 0xc000 || proto == PPP_CCPFRAG) { @@ -1367,6 +1374,10 @@ ppp_do_recv(pch->ppp, skb, pch); } read_unlock_bh(&pch->upl); + return; + drop: + kfree_skb(skb); + return; } /* Put a 0-length skb in the receive queue as an error indication */ @@ -1398,23 +1409,13 @@ static void ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) { - if (skb->len >= 2) { #ifdef CONFIG_PPP_MULTILINK - /* XXX do channel-level decompression here */ - if (PPP_PROTO(skb) == PPP_MP) - ppp_receive_mp_frame(ppp, skb, pch); - else + /* XXX do channel-level decompression here */ + if (PPP_PROTO(skb) == PPP_MP) + ppp_receive_mp_frame(ppp, skb, pch); + else #endif /* CONFIG_PPP_MULTILINK */ - ppp_receive_nonmp_frame(ppp, skb); - return; - } - - if (skb->len > 0) - /* note: a 0-length skb is used as an error indication */ - ++ppp->stats.rx_length_errors; - - kfree_skb(skb); - ppp_receive_error(ppp); + ppp_receive_nonmp_frame(ppp, skb); } static void @@ -1446,7 +1447,8 @@ /* decompress VJ compressed packets */ if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP)) goto err; - if (skb_tailroom(skb) < 124) { + + if (skb_tailroom(skb) < 124 || skb_is_nonlinear(skb) ) { /* copy to a new sk_buff with more tailroom */ ns = dev_alloc_skb(skb->len + 128); if (ns == 0) { @@ -1474,6 +1476,13 @@ case PPP_VJC_UNCOMP: if (ppp->vj == 0 || (ppp->flags & SC_REJ_COMP_TCP)) goto err; + + /* Until we fix the decompressor need to make sure + * data portion is linear. + */ + if (!pskb_may_pull(skb, skb->len)) + goto err; + if (slhc_remember(ppp->vj, skb->data + 2, skb->len - 2) <= 0) { printk(KERN_ERR "PPP: VJ uncompressed error\n"); goto err; @@ -1551,6 +1560,12 @@ struct sk_buff *ns; int len; + /* Until we fix all the decompressor's need to make sure + * data portion is linear. + */ + if (!pskb_may_pull(skb, skb->len)) + goto err; + if (proto == PPP_COMP) { ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN); if (ns == 0) { @@ -1603,7 +1618,7 @@ struct list_head *l; int mphdrlen = (ppp->flags & SC_MP_SHORTSEQ)? MPHDRLEN_SSN: MPHDRLEN; - if (skb->len < mphdrlen + 1 || ppp->mrru == 0) + if (!pskb_may_pull(skb, mphdrlen + 1) || ppp->mrru == 0) goto err; /* no good, throw it away */ /* Decode sequence number and begin/end bits */ @@ -2021,7 +2036,7 @@ unsigned char *dp = skb->data + 2; int len; - if (skb->len < CCP_HDRLEN + 2 + if (!pskb_may_pull(skb, CCP_HDRLEN + 2) || skb->len < (len = CCP_LENGTH(dp)) + 2) return; /* too short */ @@ -2056,6 +2071,10 @@ case CCP_CONFACK: if ((ppp->flags & (SC_CCP_OPEN | SC_CCP_UP)) != SC_CCP_OPEN) break; + + if (!pskb_may_pull(skb, len)) + break; + dp += CCP_HDRLEN; len -= CCP_HDRLEN; if (len < CCP_OPT_MINLEN || len < CCP_OPT_LENGTH(dp)) diff -Nru a/drivers/net/pppoe.c b/drivers/net/pppoe.c --- a/drivers/net/pppoe.c Fri Jun 27 14:19:58 2003 +++ b/drivers/net/pppoe.c Fri Jun 27 14:19:58 2003 @@ -77,27 +77,14 @@ #include <asm/uaccess.h> -static int __attribute__((unused)) pppoe_debug = 7; #define PPPOE_HASH_BITS 4 #define PPPOE_HASH_SIZE (1<<PPPOE_HASH_BITS) -int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); -int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb); -int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); - -struct proto_ops pppoe_ops; - - -#if 0 -#define CHECKPTR(x,y) do { if (!(x) && pppoe_debug &7 ){ printk(KERN_CRIT "PPPoE Invalid pointer : %s , %p\n",#x,(x)); error=-EINVAL; goto y; }} while (0) -#define DEBUG(s,args...) do { if( pppoe_debug & (s) ) printk(KERN_CRIT args ); } while (0) -#else -#define CHECKPTR(x,y) do { } while (0) -#define DEBUG(s,args...) do { } while (0) -#endif - - +static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); +static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb); +static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); +static struct proto_ops pppoe_ops; static rwlock_t pppoe_hash_lock = RW_LOCK_UNLOCKED; @@ -255,8 +242,7 @@ { int hash; - if (dev == NULL) - BUG(); + BUG_ON(dev == NULL); read_lock_bh(&pppoe_hash_lock); for (hash = 0; hash < PPPOE_HASH_SIZE; hash++) { @@ -336,20 +322,22 @@ }; - - /************************************************************************ * * Do the real work of receiving a PPPoE Session frame. * ***********************************************************************/ -int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) +static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) { struct pppox_opt *po = pppox_sk(sk); struct pppox_opt *relay_po = NULL; if (sk->sk_state & PPPOX_BOUND) { + struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw; + int len = ntohs(ph->length); skb_pull(skb, sizeof(struct pppoe_hdr)); + skb_trim(skb, len); + ppp_input(&po->chan, skb); } else if (sk->sk_state & PPPOX_RELAY) { relay_po = get_item_by_addr(&po->pppoe_relay); @@ -361,7 +349,7 @@ goto abort_put; skb_pull(skb, sizeof(struct pppoe_hdr)); - if (!__pppoe_xmit( relay_po->sk , skb)) + if (!__pppoe_xmit( relay_po->sk, skb)) goto abort_put; } else { sock_queue_rcv_skb(sk, skb); @@ -387,17 +375,22 @@ struct packet_type *pt) { - struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw; + struct pppoe_hdr *ph; struct pppox_opt *po; - struct sock *sk ; + struct sock *sk; int ret; - po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source); + if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) + goto drop; - if (!po) { - kfree_skb(skb); - return NET_RX_DROP; - } + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + goto out; + + ph = (struct pppoe_hdr *) skb->nh.raw; + + po = get_item((unsigned long) ph->sid, skb->mac.ethernet->h_source); + if (!po) + goto drop; sk = po->sk; bh_lock_sock(sk); @@ -414,6 +407,10 @@ sock_put(sk); return ret; +drop: + kfree_skb(skb); +out: + return NET_RX_DROP; } /************************************************************************ @@ -427,9 +424,16 @@ struct packet_type *pt) { - struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw; + struct pppoe_hdr *ph; struct pppox_opt *po; + if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) + goto abort; + + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + goto out; + + ph = (struct pppoe_hdr *) skb->nh.raw; if (ph->code != PADT_CODE) goto abort; @@ -457,17 +461,20 @@ abort: kfree_skb(skb); +out: return NET_RX_SUCCESS; /* Lies... :-) */ } -struct packet_type pppoes_ptype = { +static struct packet_type pppoes_ptype = { .type = __constant_htons(ETH_P_PPP_SES), .func = pppoe_rcv, + .data = (void *)1, }; -struct packet_type pppoed_ptype = { +static struct packet_type pppoed_ptype = { .type = __constant_htons(ETH_P_PPP_DISC), .func = pppoe_disc_rcv, + .data = (void *)1, }; /*********************************************************************** @@ -522,7 +529,7 @@ goto out; } -int pppoe_release(struct socket *sock) +static int pppoe_release(struct socket *sock) { struct sock *sk = sock->sk; struct pppox_opt *po; @@ -559,7 +566,7 @@ } -int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, +static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, int sockaddr_len, int flags) { struct sock *sk = sock->sk; @@ -648,7 +655,7 @@ } -int pppoe_getname(struct socket *sock, struct sockaddr *uaddr, +static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr, int *usockaddr_len, int peer) { int len = sizeof(struct sockaddr_pppox); @@ -667,7 +674,7 @@ } -int pppoe_ioctl(struct socket *sock, unsigned int cmd, +static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; @@ -769,7 +776,7 @@ } -int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, +static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int total_len) { struct sk_buff *skb = NULL; @@ -847,7 +854,7 @@ * xmit function for internal use. * ***********************************************************************/ -int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) +static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) { struct pppox_opt *po = pppox_sk(sk); struct net_device *dev = po->pppoe_dev; @@ -921,16 +928,18 @@ * sends PPP frame over PPPoE socket * ***********************************************************************/ -int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb) +static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb) { struct sock *sk = (struct sock *) chan->private; return __pppoe_xmit(sk, skb); } -struct ppp_channel_ops pppoe_chan_ops = { pppoe_xmit , NULL }; +static struct ppp_channel_ops pppoe_chan_ops = { + .start_xmit = pppoe_xmit, +}; -int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, +static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, int total_len, int flags) { struct sock *sk = sock->sk; @@ -1029,8 +1038,9 @@ goto out; } po = v; - po = po->next; - if (!po) { + if (po->next) + po = po->next; + else { int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote); while (++hash < PPPOE_HASH_SIZE) { @@ -1071,7 +1081,7 @@ /* ->ioctl are set at pppox_create */ -struct proto_ops pppoe_ops = { +static struct proto_ops pppoe_ops = { .family = AF_PPPOX, .owner = THIS_MODULE, .release = pppoe_release, @@ -1090,14 +1100,14 @@ .mmap = sock_no_mmap }; -struct pppox_proto pppoe_proto = { +static struct pppox_proto pppoe_proto = { .create = pppoe_create, .ioctl = pppoe_ioctl, .owner = THIS_MODULE, }; -int __init pppoe_init(void) +static int __init pppoe_init(void) { int err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto); @@ -1125,7 +1135,7 @@ goto out; } -void __exit pppoe_exit(void) +static void __exit pppoe_exit(void) { unregister_pppox_proto(PX_PROTO_OE); dev_remove_pack(&pppoes_ptype); diff -Nru a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c --- a/drivers/net/sb1250-mac.c Fri Jun 27 14:20:04 2003 +++ b/drivers/net/sb1250-mac.c Fri Jun 27 14:20:04 2003 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Broadcom Corporation + * Copyright (C) 2001,2002,2003 Broadcom Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,17 +17,21 @@ */ /* - This driver is designed for the Broadcom BCM12500 SOC chip's built-in + This driver is designed for the Broadcom SiByte SOC built-in Ethernet controllers. - The author may be reached as mpl@broadcom.com + Written by Mitch Lichtenberg at Broadcom Corp. */ + +#define CONFIG_SBMAC_COALESCE + /* A few user-configurable values. These may be modified when a driver module is loaded. */ static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ +static int noisy_mii = 1; /* mii status msgs */ /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' should exist for driver @@ -41,6 +45,10 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1}; #endif +#ifdef CONFIG_SBMAC_COALESCE +static int int_pktcnt = 0; +static int int_timeout = 0; +#endif /* Operational parameters that usually are not changed. */ @@ -59,22 +67,21 @@ #include <linux/timer.h> #include <linux/errno.h> #include <linux/ioport.h> +#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> -#include <linux/slab.h> #include <linux/init.h> #include <linux/config.h> #include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/bitops.h> #include <asm/io.h> -#include <asm/sibyte/sb1250.h> -#include <asm/sibyte/64bit.h> +#include <asm/cache.h> /* This is only here until the firmware is ready. In that case, the firmware leaves the ethernet address in the register for us. */ -#ifdef CONFIG_SWARM_STANDALONE +#ifdef CONFIG_SIBYTE_STANDALONE #define SBMAC_ETH0_HWADDR "40:00:00:00:01:00" #define SBMAC_ETH1_HWADDR "40:00:00:00:01:01" #define SBMAC_ETH2_HWADDR "40:00:00:00:01:02" @@ -84,23 +91,29 @@ /* These identify the driver base version and may not be removed. */ #if 0 static char version1[] __devinitdata = -"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg (mpl@broadcom.com)\n"; +"sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg\n"; #endif -MODULE_AUTHOR("Mitch Lichtenberg (mpl@broadcom.com)"); -MODULE_DESCRIPTION("Broadcom BCM12500 SOC GB Ethernet driver"); +MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)"); +MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver"); MODULE_PARM(debug, "i"); +MODULE_PARM(noisy_mii, "i"); MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); +MODULE_PARM(int_pktcnt, "i"); +MODULE_PARM(int_timeout, "i"); +#include <asm/sibyte/sb1250.h> #include <asm/sibyte/sb1250_defs.h> #include <asm/sibyte/sb1250_regs.h> #include <asm/sibyte/sb1250_mac.h> #include <asm/sibyte/sb1250_dma.h> #include <asm/sibyte/sb1250_int.h> +#include <asm/sibyte/sb1250_scd.h> +#include <asm/sibyte/64bit.h> /********************************************************************** @@ -109,8 +122,6 @@ typedef unsigned long sbmac_port_t; -typedef uint64_t sbmac_physaddr_t; -typedef uint64_t sbmac_enetaddr_t; typedef enum { sbmac_speed_auto, sbmac_speed_10, sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t; @@ -134,24 +145,19 @@ (d)->sbdma_dscrtable : (d)->f+1) -#define CACHELINESIZE 32 -#define NUMCACHEBLKS(x) (((x)+CACHELINESIZE-1)/CACHELINESIZE) -#define KMALLOC(x) kmalloc((x),GFP_KERNEL) -#define KFREE(x) kfree(x) -#define KVTOPHYS(x) virt_to_bus((void *)(x)) +#define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES) +#define SBMAC_READCSR(t) in64((unsigned long)t) +#define SBMAC_WRITECSR(t,v) out64(v, (unsigned long)t) -#define SBMAC_READCSR(t) (in64((unsigned long)(t))) -#define SBMAC_WRITECSR(t,v) (out64(v, (unsigned long)(t))) - -#define PKSEG1(x) ((sbmac_port_t) KSEG1ADDR(x)) #define SBMAC_MAX_TXDESCR 32 #define SBMAC_MAX_RXDESCR 32 #define ETHER_ALIGN 2 #define ETHER_ADDR_LEN 6 -#define ENET_PACKET_SIZE 1518 +#define ENET_PACKET_SIZE 1518 +/*#define ENET_PACKET_SIZE 9216 */ /********************************************************************** * DMA Descriptor structure @@ -163,7 +169,6 @@ } sbdmadscr_t; typedef unsigned long paddr_t; -typedef unsigned long vaddr_t; /********************************************************************** * DMA Controller structure @@ -178,8 +183,13 @@ struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */ int sbdma_channel; /* channel number */ - int sbdma_txdir; /* direction (1=transmit) */ - int sbdma_maxdescr; /* total # of descriptors in ring */ + int sbdma_txdir; /* direction (1=transmit) */ + int sbdma_maxdescr; /* total # of descriptors in ring */ +#ifdef CONFIG_SBMAC_COALESCE + int sbdma_int_pktcnt; /* # descriptors rx/tx before interrupt*/ + int sbdma_int_timeout; /* # usec rx/tx interrupt */ +#endif + sbmac_port_t sbdma_config0; /* DMA config register 0 */ sbmac_port_t sbdma_config1; /* DMA config register 1 */ sbmac_port_t sbdma_dscrbase; /* Descriptor base address */ @@ -198,7 +208,6 @@ paddr_t sbdma_dscrtable_phys; /* and also the phys addr */ sbdmadscr_t *sbdma_addptr; /* next dscr for sw to add */ sbdmadscr_t *sbdma_remptr; /* next dscr for sw to remove */ - } sbmacdma_t; @@ -218,10 +227,10 @@ struct net_device_stats sbm_stats; int sbm_devflags; /* current device flags */ - int sbm_phy_oldbmsr; - int sbm_phy_oldanlpar; - int sbm_phy_oldk1stsr; - int sbm_phy_oldlinkstat; + int sbm_phy_oldbmsr; + int sbm_phy_oldanlpar; + int sbm_phy_oldk1stsr; + int sbm_phy_oldlinkstat; int sbm_buffersize; unsigned char sbm_phys[2]; @@ -230,7 +239,7 @@ * Controller-specific things */ - sbmac_port_t sbm_base; /* MAC's base address */ + unsigned long sbm_base; /* MAC's base address */ sbmac_state_t sbm_state; /* current state */ sbmac_port_t sbm_macenable; /* MAC Enable Register */ @@ -246,11 +255,12 @@ sbmac_duplex_t sbm_duplex; /* current duplex */ sbmac_fc_t sbm_fc; /* current flow control setting */ - u_char sbm_hwaddr[ETHER_ADDR_LEN]; + unsigned char sbm_hwaddr[ETHER_ADDR_LEN]; sbmacdma_t sbm_txdma; /* for now, only use channel 0 */ sbmacdma_t sbm_rxdma; - + int rx_hw_checksum; + int sbe_idx; }; @@ -267,7 +277,7 @@ int chan, int txrx, int maxdescr); -static void sbdma_channel_start(sbmacdma_t *d); +static void sbdma_channel_start(sbmacdma_t *d, int rxtx); static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *m); static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *m); static void sbdma_emptyring(sbmacdma_t *d); @@ -279,12 +289,11 @@ static void sbmac_channel_stop(struct sbmac_softc *s); static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t); static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff); -/*static void sbmac_init_and_start(struct sbmac_softc *sc);*/ static uint64_t sbmac_addr2reg(unsigned char *ptr); static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs); static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev); static void sbmac_setmulti(struct sbmac_softc *sc); -static int sbmac_init(struct net_device *dev); +static int sbmac_init(struct net_device *dev, int idx); static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed); static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc); @@ -308,6 +317,8 @@ * Globals ********************************************************************* */ +static uint64_t sbmac_orig_hwaddr[MAX_UNITS]; + /********************************************************************** * MDIO constants @@ -328,8 +339,8 @@ #define BMCR_DUPLEX 0x0100 #define BMCR_COLTEST 0x0080 #define BMCR_SPEED1 0x0040 -#define BMCR_SPEED1000 (BMCR_SPEED1|BMCR_SPEED0) -#define BMCR_SPEED100 (BMCR_SPEED0) +#define BMCR_SPEED1000 BMCR_SPEED1 +#define BMCR_SPEED100 BMCR_SPEED0 #define BMCR_SPEED10 0 #define BMSR_100BT4 0x8000 @@ -437,6 +448,8 @@ #define M_MAC_MDIO_DIR_OUTPUT 0 /* for clarity */ +#define ENABLE 1 +#define DISABLE 0 /********************************************************************** * SBMAC_MII_SYNC(s) @@ -490,7 +503,8 @@ curmask = 1 << (bitcnt - 1); for (i = 0; i < bitcnt; i++) { - if (data & curmask) bits |= M_MAC_MDIO_OUT; + if (data & curmask) + bits |= M_MAC_MDIO_OUT; else bits &= ~M_MAC_MDIO_OUT; SBMAC_WRITECSR(s->sbm_mdio,bits); SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC); @@ -571,7 +585,8 @@ regval <<= 1; if (error == 0) { - if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) regval |= 1; + if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN) + regval |= 1; } SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | M_MAC_MDC); @@ -581,7 +596,8 @@ /* Switch back to output */ SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT); - if (error == 0) return regval; + if (error == 0) + return regval; return 0; } @@ -651,20 +667,68 @@ d->sbdma_channel = chan; d->sbdma_txdir = txrx; +#if 0 + /* RMON clearing */ + s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING; +#endif + + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0); + SBMAC_WRITECSR(KSEG1ADDR( + A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0); + /* * initialize register pointers */ d->sbdma_config0 = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0); d->sbdma_config1 = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1); d->sbdma_dscrbase = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE); d->sbdma_dscrcnt = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); d->sbdma_curdscr = - PKSEG1(s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR)); + s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); /* * Allocate memory for the ring @@ -673,23 +737,41 @@ d->sbdma_maxdescr = maxdescr; d->sbdma_dscrtable = (sbdmadscr_t *) - KMALLOC(d->sbdma_maxdescr*sizeof(sbdmadscr_t)); + kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL); memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t)); d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr; - d->sbdma_dscrtable_phys = KVTOPHYS(d->sbdma_dscrtable); + d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable); /* * And context table */ d->sbdma_ctxtable = (struct sk_buff **) - KMALLOC(d->sbdma_maxdescr*sizeof(struct sk_buff *)); + kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL); memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *)); +#ifdef CONFIG_SBMAC_COALESCE + /* + * Setup Rx/Tx DMA coalescing defaults + */ + + if ( int_pktcnt ) { + d->sbdma_int_pktcnt = int_pktcnt; + } else { + d->sbdma_int_pktcnt = 1; + } + + if ( int_timeout ) { + d->sbdma_int_timeout = int_timeout; + } else { + d->sbdma_int_timeout = 0; + } +#endif + } /********************************************************************** @@ -699,33 +781,75 @@ * * Input parameters: * d - DMA channel to init (context must be previously init'd + * rxtx - DMA_RX or DMA_TX depending on what type of channel * * Return value: * nothing ********************************************************************* */ -static void sbdma_channel_start(sbmacdma_t *d) +static void sbdma_channel_start(sbmacdma_t *d, int rxtx ) { /* * Turn on the DMA channel */ +#ifdef CONFIG_SBMAC_COALESCE + SBMAC_WRITECSR(d->sbdma_config1, + V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) | + 0); + SBMAC_WRITECSR(d->sbdma_config0, + M_DMA_EOP_INT_EN | + V_DMA_RINGSZ(d->sbdma_maxdescr) | + V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | + 0); +#else SBMAC_WRITECSR(d->sbdma_config1,0); - - SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys); - SBMAC_WRITECSR(d->sbdma_config0, V_DMA_RINGSZ(d->sbdma_maxdescr) | 0); - +#endif + + SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys); + /* * Initialize ring pointers */ - + d->sbdma_addptr = d->sbdma_dscrtable; d->sbdma_remptr = d->sbdma_dscrtable; } +/********************************************************************** + * SBDMA_CHANNEL_STOP(d) + * + * Initialize the hardware registers for a DMA channel. + * + * Input parameters: + * d - DMA channel to init (context must be previously init'd + * + * Return value: + * nothing + ********************************************************************* */ + +static void sbdma_channel_stop(sbmacdma_t *d) +{ + /* + * Turn off the DMA channel + */ + + SBMAC_WRITECSR(d->sbdma_config1,0); + + SBMAC_WRITECSR(d->sbdma_dscrbase,0); + + SBMAC_WRITECSR(d->sbdma_config0,0); + + /* + * Zero ring pointers + */ + + d->sbdma_addptr = 0; + d->sbdma_remptr = 0; +} static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset) { @@ -777,7 +901,7 @@ if (nextdsc == d->sbdma_remptr) { return -ENOSPC; } - + /* * Allocate a sk_buff if we don't already have one. * If we do have an sk_buff, reset it so that it's empty. @@ -788,25 +912,25 @@ * * 1. the data does not start in the middle of a cache line. * 2. The data does not end in the middle of a cache line - * 3. The buffer can be aligned such that the IP addresses are + * 3. The buffer can be aligned such that the IP addresses are * naturally aligned. * - * Remember, the SB1250's MAC writes whole cache lines at a time, + * Remember, the SOCs MAC writes whole cache lines at a time, * without reading the old contents first. So, if the sk_buff's - * data portion starts in the middle of a cache line, the SB1250 + * data portion starts in the middle of a cache line, the SOC * DMA will trash the beginning (and ending) portions. */ if (sb == NULL) { - sb_new = dev_alloc_skb(ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN); + sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN); if (sb_new == NULL) { printk(KERN_INFO "%s: sk_buff allocation failed\n", d->sbdma_eth->sbm_dev->name); return -ENOBUFS; } - - sbdma_align_skb(sb_new,CACHELINESIZE,ETHER_ALIGN); - + + sbdma_align_skb(sb_new, SMP_CACHE_BYTES, ETHER_ALIGN); + /* mark skbuff owned by our device */ sb_new->dev = d->sbdma_eth->sbm_dev; } @@ -814,7 +938,7 @@ sb_new = sb; /* * nothing special to reinit buffer, it's already aligned - * and sb->tail already points to a good place. + * and sb->data already points to a good place. */ } @@ -822,10 +946,19 @@ * fill in the descriptor */ - dsc->dscr_a = KVTOPHYS(sb_new->tail) | +#ifdef CONFIG_SBMAC_COALESCE + /* + * Do not interrupt per DMA transfer. + */ + dsc->dscr_a = virt_to_phys(sb_new->tail) | + V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | + 0; +#else + dsc->dscr_a = virt_to_phys(sb_new->tail) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | M_DMA_DSCRA_INTERRUPT; - +#endif + /* receiving: no options */ dsc->dscr_b = 0; @@ -904,12 +1037,14 @@ * while doing the calculation. */ - phys = KVTOPHYS(sb->data); - ncb = NUMCACHEBLKS(length+(phys & (CACHELINESIZE-1))); - + phys = virt_to_phys(sb->data); + ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1))); + dsc->dscr_a = phys | V_DMA_DSCRA_A_SIZE(ncb) | +#ifndef CONFIG_SBMAC_COALESCE M_DMA_DSCRA_INTERRUPT | +#endif M_DMA_ETHTX_SOP; /* transmitting: set outbound options and length */ @@ -986,7 +1121,8 @@ int idx; for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) { - if (sbdma_add_rcvbuffer(d,NULL) != 0) break; + if (sbdma_add_rcvbuffer(d,NULL) != 0) + break; } } @@ -1037,7 +1173,8 @@ * the hardware is working on right now. */ - if (curidx == hwidx) break; + if (curidx == hwidx) + break; /* * Otherwise, get the packet's sk_buff ptr back @@ -1058,35 +1195,51 @@ if (!(dsc->dscr_a & M_DMA_ETHRX_BAD)) { /* - * Set length into the packet - */ - skb_put(sb,len); - - /* * Add a new buffer to replace the old one. If we fail * to allocate a buffer, we're going to drop this * packet and put it right back on the receive ring. */ if (sbdma_add_rcvbuffer(d,NULL) == -ENOBUFS) { - sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ - } - else { - /* - * Buffer has been replaced on the receive ring. - * Pass the buffer to the kernel - */ - sc->sbm_stats.rx_bytes += len; - sc->sbm_stats.rx_packets++; - sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); - netif_rx(sb); - } - } - else { + sc->sbm_stats.rx_dropped++; + sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */ + } else { + /* + * Set length into the packet + */ + skb_put(sb,len); + + /* + * Buffer has been replaced on the + * receive ring. Pass the buffer to + * the kernel */ + sc->sbm_stats.rx_bytes += len; + sc->sbm_stats.rx_packets++; + sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); + if (sc->rx_hw_checksum == ENABLE) { + /* if the ip checksum is good + indicate in skb. else set + CHECKSUM_NONE as device + failed to checksum the + packet */ + + if (((dsc->dscr_b) |M_DMA_ETHRX_BADTCPCS) || + ((dsc->dscr_a)| M_DMA_ETHRX_BADIP4CS)) { + sb->ip_summed = CHECKSUM_NONE; + } else { + printk(KERN_DEBUG "hw checksum fail .\n"); + sb->ip_summed = CHECKSUM_UNNECESSARY; + } + } /* rx_hw_checksum */ + + netif_rx(sb); + } + } else { /* * Packet was mangled somehow. Just drop it and * put it back on the receive ring. */ + sc->sbm_stats.rx_errors++; sbdma_add_rcvbuffer(d,sb); } @@ -1143,21 +1296,27 @@ curidx = d->sbdma_remptr - d->sbdma_dscrtable; { - /* XXX This is gross, ugly, and only here because justin hacked it - in to fix a problem without really understanding it. - - It seems that, for whatever reason, this routine is invoked immediately upon the enabling of interrupts. - So then the Read below returns zero, making hwidx a negative number, and anti-hilarity - ensues. - - I'm guessing there's a proper fix involving clearing out interrupt state from old packets - before enabling interrupts, but I'm not sure. - - Anyways, this hack seems to work, and is Good Enough for 11 PM. :) - - -Justin - */ - + /* XXX This is gross, ugly, and only here + * because justin hacked it in to fix a + * problem without really understanding it. + * + * It seems that, for whatever reason, this + * routine is invoked immediately upon the + * enabling of interrupts. So then the Read + * below returns zero, making hwidx a negative + * number, and anti-hilarity ensues. + * + * I'm guessing there's a proper fix involving + * clearing out interrupt state from old + * packets before enabling interrupts, but I'm + * not sure. + * + * Anyways, this hack seems to work, and is + * Good Enough for 11 PM. :) + * + * -Justin + */ + uint64_t tmp = SBMAC_READCSR(d->sbdma_curdscr); if (!tmp) { break; @@ -1171,7 +1330,8 @@ * the hardware is working on right now. */ - if (curidx == hwidx) break; + if (curidx == hwidx) + break; /* * Otherwise, get the packet's sk_buff ptr back @@ -1238,14 +1398,14 @@ * figure out the addresses of some ports */ - s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE); - s->sbm_maccfg = PKSEG1(s->sbm_base + R_MAC_CFG); - s->sbm_fifocfg = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG); - s->sbm_framecfg = PKSEG1(s->sbm_base + R_MAC_FRAMECFG); - s->sbm_rxfilter = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG); - s->sbm_isr = PKSEG1(s->sbm_base + R_MAC_STATUS); - s->sbm_imr = PKSEG1(s->sbm_base + R_MAC_INT_MASK); - s->sbm_mdio = PKSEG1(s->sbm_base + R_MAC_MDIO); + s->sbm_macenable = s->sbm_base + R_MAC_ENABLE; + s->sbm_maccfg = s->sbm_base + R_MAC_CFG; + s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG; + s->sbm_framecfg = s->sbm_base + R_MAC_FRAMECFG; + s->sbm_rxfilter = s->sbm_base + R_MAC_ADFILTER_CFG; + s->sbm_isr = s->sbm_base + R_MAC_STATUS; + s->sbm_imr = s->sbm_base + R_MAC_INT_MASK; + s->sbm_mdio = s->sbm_base + R_MAC_MDIO; s->sbm_phys[0] = 1; s->sbm_phys[1] = 0; @@ -1284,12 +1444,12 @@ static void sbdma_uninitctx(struct sbmacdma_s *d) { if (d->sbdma_dscrtable) { - KFREE(d->sbdma_dscrtable); + kfree(d->sbdma_dscrtable); d->sbdma_dscrtable = NULL; } if (d->sbdma_ctxtable) { - KFREE(d->sbdma_ctxtable); + kfree(d->sbdma_ctxtable); d->sbdma_ctxtable = NULL; } } @@ -1319,13 +1479,14 @@ uint64_t reg; sbmac_port_t port; uint64_t cfg,fifo,framecfg; - int idx; + int idx, th_value; /* * Don't do this if running */ - if (s->sbm_state == sbmac_state_on) return; + if (s->sbm_state == sbmac_state_on) + return; /* * Bring the controller out of reset, but leave it off. @@ -1351,26 +1512,36 @@ M_MAC_SS_EN | 0; + /* + * Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars + * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above + * Use a larger RD_THRSH for gigabit + */ + if (periph_rev >= 2) + th_value = 64; + else + th_value = 28; + fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ - V_MAC_TX_RD_THRSH(4) | + ((s->sbm_speed == sbmac_speed_1000) + ? V_MAC_TX_RD_THRSH(th_value) : V_MAC_TX_RD_THRSH(4)) | V_MAC_TX_RL_THRSH(4) | V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RL_THRSH(8) | 0; - + framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | V_MAC_MAX_FRAMESZ_DEFAULT | V_MAC_BACKOFF_SEL(1); - - + /* * Clear out the hash address map */ - port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE); - for (idx = 0; idx < MAC_HASH_COUNT; idx++) { + port = s->sbm_base + R_MAC_HASH_BASE; + for (idx = 0; idx < MAC_HASH_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); } @@ -1379,7 +1550,7 @@ * Clear out the exact-match table */ - port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); + port = s->sbm_base + R_MAC_ADDR_BASE; for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); @@ -1389,14 +1560,14 @@ * Clear out the DMA Channel mapping table registers */ - port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE); + port = s->sbm_base + R_MAC_CHUP0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); } - port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE); + port = s->sbm_base + R_MAC_CHLO0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { SBMAC_WRITECSR(port,0); port += sizeof(uint64_t); @@ -1409,13 +1580,13 @@ reg = sbmac_addr2reg(s->sbm_hwaddr); - port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); + port = s->sbm_base + R_MAC_ADDR_BASE; SBMAC_WRITECSR(port,reg); - port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR); + port = s->sbm_base + R_MAC_ETHERNET_ADDR; #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* - * Pass1 SB1250s do not receive packets addressed to the + * Pass1 SOCs do not receive packets addressed to the * destination address in the R_MAC_ETHERNET_ADDR register. * Set the value to zero. */ @@ -1439,8 +1610,8 @@ * Initialize DMA channels (rings should be ok now) */ - sbdma_channel_start(&(s->sbm_rxdma)); - sbdma_channel_start(&(s->sbm_txdma)); + sbdma_channel_start(&(s->sbm_rxdma), DMA_RX); + sbdma_channel_start(&(s->sbm_txdma), DMA_TX); /* * Configure the speed, duplex, and flow control @@ -1467,12 +1638,22 @@ + +#ifdef CONFIG_SBMAC_COALESCE + /* + * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0 + */ + SBMAC_WRITECSR(s->sbm_imr, + ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | + ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0)); +#else /* * Accept any kind of interrupt on TX and RX DMA channel 0 */ SBMAC_WRITECSR(s->sbm_imr, (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)); +#endif /* * Enable receiving unicasts and broadcasts @@ -1517,11 +1698,10 @@ static void sbmac_channel_stop(struct sbmac_softc *s) { - uint64_t ctl; - /* don't do this if already stopped */ - if (s->sbm_state == sbmac_state_off) return; + if (s->sbm_state == sbmac_state_off) + return; /* don't accept any packets, disable all interrupts */ @@ -1534,14 +1714,18 @@ /* turn off receiver and transmitter */ - ctl = SBMAC_READCSR(s->sbm_macenable); - ctl &= ~(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0); - SBMAC_WRITECSR(s->sbm_macenable,ctl); + SBMAC_WRITECSR(s->sbm_macenable,0); /* We're stopped now. */ s->sbm_state = sbmac_state_off; + /* + * Stop DMA channels (rings should be ok now) + */ + + sbdma_channel_stop(&(s->sbm_rxdma)); + sbdma_channel_stop(&(s->sbm_txdma)); /* Empty the receive and transmit rings */ @@ -1610,7 +1794,8 @@ { uint64_t reg; - if (sc->sbm_state != sbmac_state_on) return; + if (sc->sbm_state != sbmac_state_on) + return; if (onoff) { reg = SBMAC_READCSR(sc->sbm_rxfilter); @@ -1624,31 +1809,36 @@ } } - - -#if 0 /********************************************************************** - * SBMAC_INIT_AND_START(sc) + * SBMAC_SETIPHDR_OFFSET(sc,onoff) * - * Stop the channel and restart it. This is generally used - * when we have to do something to the channel that requires - * a swift kick. + * Set the iphdr offset as 15 assuming ethernet encapsulation * * Input parameters: * sc - softc + * + * Return value: + * nothing ********************************************************************* */ -static void sbmac_init_and_start(struct sbmac_softc *sc) +static void sbmac_set_iphdr_offset(struct sbmac_softc *sc) { - unsigned long flags; - - spin_lock_irqsave(&(sc->sbm_lock),flags); + uint64_t reg; - sbmac_set_channel_state(sc,sbmac_state_on); + /* Hard code the off set to 15 for now */ + reg = SBMAC_READCSR(sc->sbm_rxfilter); + reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); + SBMAC_WRITECSR(sc->sbm_rxfilter,reg); - spin_unlock_irqrestore(&(sc->sbm_lock),flags); + /* read system identification to determine revision */ + if (periph_rev >= 2) { + printk(KERN_INFO "%s: enabling TCP rcv checksum\n", + sc->sbm_dev->name); + sc->rx_hw_checksum = ENABLE; + } else { + sc->rx_hw_checksum = DISABLE; + } } -#endif /********************************************************************** @@ -1712,7 +1902,8 @@ s->sbm_speed = speed; - if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ + if (s->sbm_state == sbmac_state_on) + return 0; /* save for next restart */ /* * Read current register values @@ -1772,7 +1963,6 @@ SBMAC_WRITECSR(s->sbm_maccfg,cfg); return 1; - } /********************************************************************** @@ -1802,7 +1992,8 @@ s->sbm_duplex = duplex; s->sbm_fc = fc; - if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ + if (s->sbm_state == sbmac_state_on) + return 0; /* save for next restart */ /* * Read current register values @@ -1886,7 +2077,7 @@ * Return value: * nothing ********************************************************************* */ -static void sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs) +static irqreturn_t sbmac_intr(int irq,void *dev_instance,struct pt_regs *rgs) { struct net_device *dev = (struct net_device *) dev_instance; struct sbmac_softc *sc = (struct sbmac_softc *) (dev->priv); @@ -1896,14 +2087,17 @@ for (;;) { /* - * Read the ISR (this clears the bits in the real register) + * Read the ISR (this clears the bits in the real + * register, except for counter addr) */ - isr = SBMAC_READCSR(sc->sbm_isr); + isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; if (isr == 0) break; + handled = 1; + /* * Transmits on channel 0 */ @@ -1915,6 +2109,23 @@ /* * Receives on channel 0 */ + + /* + * It's important to test all the bits (or at least the + * EOP_SEEN bit) when deciding to do the RX process + * particularly when coalescing, to make sure we + * take care of the following: + * + * If you have some packets waiting (have been received + * but no interrupt) and get a TX interrupt before + * the RX timer or counter expires, reading the ISR + * above will clear the timer and counter, and you + * won't get another interrupt until a packet shows + * up to start the timer again. Testing + * EOP_SEEN here takes care of this case. + * (EOP_SEEN is part of M_MAC_INT_CHANNEL << S_MAC_RX_CH0) + */ + if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) { sbdma_rx_process(sc,&(sc->sbm_rxdma)); @@ -1952,6 +2163,9 @@ if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) { /* XXX save skb that we could not send */ netif_stop_queue(dev); + spin_unlock_irq(&sc->sbm_lock); + + return 1; } dev->trans_start = jiffies; @@ -1990,12 +2204,12 @@ */ for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { - port = PKSEG1(sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)); SBMAC_WRITECSR(port,0); } for (idx = 0; idx < MAC_HASH_COUNT; idx++) { - port = PKSEG1(sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)); SBMAC_WRITECSR(port,0); } @@ -2032,8 +2246,7 @@ mclist = dev->mc_list; while (mclist && (idx < MAC_ADDR_COUNT)) { reg = sbmac_addr2reg(mclist->dmi_addr); - port = PKSEG1(sc->sbm_base + - R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); + port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); SBMAC_WRITECSR(port,reg); idx++; mclist = mclist->next; @@ -2070,10 +2283,14 @@ { int digit; - if ((str >= '0') && (str <= '9')) digit = str - '0'; - else if ((str >= 'a') && (str <= 'f')) digit = str - 'a' + 10; - else if ((str >= 'A') && (str <= 'F')) digit = str - 'A' + 10; - else return -1; + if ((str >= '0') && (str <= '9')) + digit = str - '0'; + else if ((str >= 'a') && (str <= 'f')) + digit = str - 'a' + 10; + else if ((str >= 'A') && (str <= 'F')) + digit = str - 'A' + 10; + else + return -1; return digit; } @@ -2092,16 +2309,18 @@ * 0 if ok, else -1 ********************************************************************* */ -static int sbmac_parse_hwaddr(char *str,u_char *hwaddr) +static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr) { int digit1,digit2; int idx = 6; while (*str && (idx > 0)) { digit1 = sbmac_parse_xdigit(*str); - if (digit1 < 0) return -1; + if (digit1 < 0) + return -1; str++; - if (!*str) return -1; + if (!*str) + return -1; if ((*str == ':') || (*str == '-')) { digit2 = digit1; @@ -2109,20 +2328,32 @@ } else { digit2 = sbmac_parse_xdigit(*str); - if (digit2 < 0) return -1; + if (digit2 < 0) + return -1; str++; } *hwaddr++ = (digit1 << 4) | digit2; idx--; - if (*str == '-') str++; - if (*str == ':') str++; + if (*str == '-') + str++; + if (*str == ':') + str++; } return 0; } #endif +static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) +{ + if (new_mtu > ENET_PACKET_SIZE) + return -EINVAL; + _dev->mtu = new_mtu; + printk(KERN_INFO "changing the mtu to %d\n", new_mtu); + return 0; +} + /********************************************************************** * SBMAC_INIT(dev) * @@ -2135,19 +2366,20 @@ * status ********************************************************************* */ -static int sbmac_init(struct net_device *dev) +static int sbmac_init(struct net_device *dev, int idx) { struct sbmac_softc *sc; - u_char *eaddr; + unsigned char *eaddr; uint64_t ea_reg; - int idx; + int i; sc = (struct sbmac_softc *)dev->priv; /* Determine controller base address */ - sc->sbm_base = (sbmac_port_t) dev->base_addr; + sc->sbm_base = KSEG1ADDR(dev->base_addr); sc->sbm_dev = dev; + sc->sbe_idx = idx; eaddr = sc->sbm_hwaddr; @@ -2156,16 +2388,15 @@ * for us in the ethernet address register for each mac. */ - ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR)); - SBMAC_WRITECSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR), 0); - for (idx = 0; idx < 6; idx++) { - eaddr[idx] = (uint8_t) (ea_reg & 0xFF); + ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR); + SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0); + for (i = 0; i < 6; i++) { + eaddr[i] = (uint8_t) (ea_reg & 0xFF); ea_reg >>= 8; } - - for (idx = 0; idx < 6; idx++) { - dev->dev_addr[idx] = eaddr[idx]; + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = eaddr[i]; } @@ -2173,8 +2404,8 @@ * Init packet size */ - sc->sbm_buffersize = ENET_PACKET_SIZE + CACHELINESIZE*2 + ETHER_ALIGN; - + sc->sbm_buffersize = ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN; + /* * Initialize context (get pointers to registers and stuff), then * allocate the memory for the descriptor tables. @@ -2184,13 +2415,13 @@ /* - * Display Ethernet address (this is called during the config process - * so we need to finish off the config message that was being displayed) + * Display Ethernet address (this is called during the config + * process so we need to finish off the config message that + * was being displayed) */ printk(KERN_INFO - "%s: SB1250 Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", - dev->name, - (unsigned long) sc->sbm_base, + "%s: SiByte Ethernet at 0x%08lX, address: %02X-%02X-%02X-%02X-%02X-%02X\n", + dev->name, dev->base_addr, eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]); /* @@ -2208,9 +2439,13 @@ dev->do_ioctl = sbmac_mii_ioctl; dev->tx_timeout = sbmac_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; + + dev->change_mtu = sb1250_change_mtu; + + /* This is needed for PASS2 for Rx H/W checksum feature */ + sbmac_set_iphdr_offset(sc); return 0; - } @@ -2237,7 +2472,7 @@ * Configure default speed */ - sbmac_mii_poll(sc,1); + sbmac_mii_poll(sc,noisy_mii); /* * Turn on the channel @@ -2319,7 +2554,8 @@ chg = 1; } - if (chg == 0) return 0; + if (chg == 0) + return 0; p += sprintf(p,"Link speed: "); @@ -2371,8 +2607,6 @@ } - - static void sbmac_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; @@ -2399,19 +2633,19 @@ * Poll the PHY to see what speed we should be running at */ - if (sbmac_mii_poll(sc,1)) { - if (sc->sbm_state != sbmac_state_off) { - /* - * something changed, restart the channel - */ - if (debug > 1) { - printk("%s: restarting channel because speed changed\n", - sc->sbm_dev->name); - } - sbmac_channel_stop(sc); - sbmac_channel_start(sc); + if (sbmac_mii_poll(sc,noisy_mii)) { + if (sc->sbm_state != sbmac_state_off) { + /* + * something changed, restart the channel + */ + if (debug > 1) { + printk("%s: restarting channel because speed changed\n", + sc->sbm_dev->name); + } + sbmac_channel_stop(sc); + sbmac_channel_start(sc); } - } + } spin_unlock_irq (&sc->sbm_lock); @@ -2479,7 +2713,8 @@ spin_unlock_irqrestore(&sc->sbm_lock, flags); if (msg_flag) { - printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", dev->name,(msg_flag==1)?"en":"dis"); + printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n", + dev->name,(msg_flag==1)?"en":"dis"); } /* @@ -2530,31 +2765,31 @@ { struct sbmac_softc *sc = (struct sbmac_softc *)dev->priv; unsigned long flags; - + int irq; + sbmac_set_channel_state(sc,sbmac_state_off); - + del_timer_sync(&sc->sbm_timer); - + spin_lock_irqsave(&sc->sbm_lock, flags); - + netif_stop_queue(dev); - + if (debug > 1) { printk(KERN_DEBUG "%s: Shutting down ethercard\n",dev->name); } - + spin_unlock_irqrestore(&sc->sbm_lock, flags); - - /* Make sure there is no irq-handler running on a different CPU. */ - synchronize_irq(dev->irq); - - free_irq(dev->irq, dev); - + + irq = dev->irq; + synchronize_irq(irq); + free_irq(irq, dev); + sbdma_emptyring(&(sc->sbm_txdma)); sbdma_emptyring(&(sc->sbm_rxdma)); MOD_DEC_USE_COUNT; - + return 0; } @@ -2571,8 +2806,8 @@ port = A_MAC_CHANNEL_BASE(chan); sbmac_parse_hwaddr(addr,eaddr); val = sbmac_addr2reg(eaddr); - SBMAC_WRITECSR(PKSEG1(port+R_MAC_ETHERNET_ADDR),val); - val = SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)); + SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),val); + val = SBMAC_READCSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR)); } #endif @@ -2585,6 +2820,7 @@ int macidx = 0; struct net_device *dev; sbmac_port_t port; + int chip_max_units; /* * For bringup when not using the firmware, we can pre-fill @@ -2605,8 +2841,25 @@ * Walk through the Ethernet controllers and find * those who have their MAC addresses set. */ - - for (idx = 0; idx < MAX_UNITS; idx++) { + switch (soc_type) { + case K_SYS_SOC_TYPE_BCM1250: + case K_SYS_SOC_TYPE_BCM1250_ALT: + chip_max_units = 3; + break; + case K_SYS_SOC_TYPE_BCM1120: + case K_SYS_SOC_TYPE_BCM1125: + case K_SYS_SOC_TYPE_BCM1125H: + case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ + chip_max_units = 2; + break; + default: + chip_max_units = 0; + break; + } + if (chip_max_units > MAX_UNITS) + chip_max_units = MAX_UNITS; + + for (idx = 0; idx < chip_max_units; idx++) { /* * This is the base address of the MAC. @@ -2620,25 +2873,31 @@ * If we find a zero, skip this MAC. */ - if (SBMAC_READCSR(PKSEG1(port+R_MAC_ETHERNET_ADDR)) == 0) { + sbmac_orig_hwaddr[idx] = SBMAC_READCSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR)); + if (sbmac_orig_hwaddr[idx] == 0) { + printk(KERN_DEBUG "sbmac: not configuring MAC at " + "%lx\n", port); continue; - } + } /* * Okay, cool. Initialize this MAC. */ dev = init_etherdev(NULL,sizeof(struct sbmac_softc)); - if (!dev) break; /* problems, get out now. */ + if (!dev) + return -ENOMEM; /* return ENOMEM */ + + printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); + dev->irq = K_INT_MAC_0 + idx; dev->base_addr = port; dev->mem_end = 0; /*dev->init = sbmac_init;*/ - sbmac_init(dev); + sbmac_init(dev, macidx); dev_sbmac[macidx] = dev; macidx++; - } /* @@ -2654,9 +2913,11 @@ { int idx; struct net_device *dev; + sbmac_port_t port; for (idx = 0; idx < MAX_UNITS; idx++) { dev = dev_sbmac[idx]; - if (dev == NULL) continue; + if (dev == NULL) + continue; if (dev->priv != NULL) { struct sbmac_softc *sc = (struct sbmac_softc *) dev->priv; @@ -2664,9 +2925,11 @@ sbmac_uninitctx(sc); - KFREE(sc); } - KFREE(dev); + + port = A_MAC_CHANNEL_BASE(idx); + SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR), sbmac_orig_hwaddr[idx] ); + kfree(dev); dev_sbmac[idx] = NULL; } } diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c --- a/drivers/net/sgiseeq.c Fri Jun 27 14:20:04 2003 +++ b/drivers/net/sgiseeq.c Fri Jun 27 14:20:04 2003 @@ -5,6 +5,7 @@ */ #include <linux/kernel.h> #include <linux/module.h> +#include <linux/init.h> #include <linux/types.h> #include <linux/interrupt.h> #include <linux/ioport.h> @@ -25,8 +26,8 @@ #include <asm/bitops.h> #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/ip22.h> #include <asm/sgialib.h> #include "sgiseeq.h" @@ -90,8 +91,8 @@ struct sgiseeq_private { volatile struct sgiseeq_init_block srings; char *name; - volatile struct hpc3_ethregs *hregs; - volatile struct sgiseeq_regs *sregs; + struct hpc3_ethregs *hregs; + struct sgiseeq_regs *sregs; /* Ring entry counters. */ unsigned int rx_new, tx_new; @@ -102,17 +103,22 @@ unsigned char mode; struct net_device_stats stats; + + struct net_device *next_module; }; -static inline void hpc3_eth_reset(volatile struct hpc3_ethregs *hregs) +/* A list of all installed seeq devices, for removing the driver module. */ +static struct net_device *root_sgiseeq_dev; + +static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) { hregs->rx_reset = (HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ); udelay(20); hregs->rx_reset = 0; } -static inline void reset_hpc3_and_seeq(volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) +static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { hregs->rx_ctrl = hregs->tx_ctrl = 0; hpc3_eth_reset(hregs); @@ -122,15 +128,15 @@ SEEQ_RCMD_IDRIB | SEEQ_RCMD_ICRC) static inline void seeq_go(struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { sregs->rstat = sp->mode | RSTAT_GO_BITS; hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE; } static inline void seeq_load_eaddr(struct net_device *dev, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { int i; @@ -171,7 +177,6 @@ return -ENOMEM; ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer); -// flush_cache_all(); } ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT); } @@ -186,7 +191,6 @@ return -ENOMEM; ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer); ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer); -// flush_cache_all(); } ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT); } @@ -203,7 +207,7 @@ static int once; struct sgiseeq_rx_desc *r = gpriv->srings.rx_desc; struct sgiseeq_tx_desc *t = gpriv->srings.tx_desc; - volatile struct hpc3_ethregs *hregs = gpriv->hregs; + struct hpc3_ethregs *hregs = gpriv->hregs; int i; if(once) @@ -242,9 +246,9 @@ #define RDMACFG_INIT (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ) static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { - volatile struct hpc3_ethregs *hregs = sp->hregs; + struct hpc3_ethregs *hregs = sp->hregs; int err; reset_hpc3_and_seeq(hregs, sregs); @@ -285,8 +289,8 @@ } static inline void rx_maybe_restart(struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { hregs->rx_ndptr = PHYSADDR(&sp->srings.rx_desc[sp->rx_new]); @@ -299,8 +303,8 @@ (rd) = &(sp)->srings.rx_desc[(sp)->rx_new]) static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { struct sgiseeq_rx_desc *rd; struct sk_buff *skb = 0; @@ -332,7 +336,7 @@ sp->stats.rx_packets++; sp->stats.rx_bytes += len; } else { - printk ("%s: Memory squeeze, deferring packet.\n", + printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", dev->name); sp->stats.rx_dropped++; } @@ -350,7 +354,7 @@ } static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp, - volatile struct sgiseeq_regs *sregs) + struct sgiseeq_regs *sregs) { if (sp->is_edlc) { sregs->rw.wregs.control = sp->control & ~(SEEQ_CTRL_XCNT); @@ -359,7 +363,7 @@ } static inline void kick_tx(struct sgiseeq_tx_desc *td, - volatile struct hpc3_ethregs *hregs) + struct hpc3_ethregs *hregs) { /* If the HPC aint doin nothin, and there are more packets * with ETXD cleared and XIU set we must make very certain @@ -377,8 +381,8 @@ } static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp, - volatile struct hpc3_ethregs *hregs, - volatile struct sgiseeq_regs *sregs) + struct hpc3_ethregs *hregs, + struct sgiseeq_regs *sregs) { struct sgiseeq_tx_desc *td; unsigned long status = hregs->tx_ctrl; @@ -420,8 +424,8 @@ { struct net_device *dev = (struct net_device *) dev_id; struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct hpc3_ethregs *hregs = sp->hregs; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct hpc3_ethregs *hregs = sp->hregs; + struct sgiseeq_regs *sregs = sp->sregs; /* Ack the IRQ and set software state. */ hregs->rx_reset = HPC3_ERXRST_CLRIRQ; @@ -429,7 +433,7 @@ /* Always check for received packets. */ sgiseeq_rx(dev, sp, hregs, sregs); - /* Only check for tx acks iff we have something queued. */ + /* Only check for tx acks if we have something queued. */ if (sp->tx_old != sp->tx_new) sgiseeq_tx(dev, sp, hregs, sregs); @@ -442,47 +446,34 @@ static int sgiseeq_open(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *)dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; - unsigned long flags; - int err; - - local_irq_save(flags); + struct sgiseeq_regs *sregs = sp->sregs; - err = -EAGAIN; - if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { - printk("Seeq8003: Can't get irq %d\n", dev->irq); - goto out; - } - err = init_seeq(dev, sp, sregs); + int err = init_seeq(dev, sp, sregs); if (err) - goto out; + return err; netif_start_queue(dev); -out: - local_irq_restore(flags); - return err; + return 0; } static int sgiseeq_close(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct sgiseeq_regs *sregs = sp->sregs; netif_stop_queue(dev); /* Shutdown the Seeq. */ reset_hpc3_and_seeq(sp->hregs, sregs); - free_irq(dev->irq, dev); - return 0; } static inline int sgiseeq_reset(struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct sgiseeq_regs *sregs = sp->sregs; + struct sgiseeq_regs *sregs = sp->sregs; int err; err = init_seeq(dev, sp, sregs); @@ -504,12 +495,12 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv; - volatile struct hpc3_ethregs *hregs = sp->hregs; + struct hpc3_ethregs *hregs = sp->hregs; unsigned long flags; struct sgiseeq_tx_desc *td; int skblen, len, entry; - save_and_cli(flags); + local_irq_save(flags); /* Setup... */ skblen = skb->len; @@ -553,14 +544,14 @@ if (!TX_BUFFS_AVAIL(sp)) netif_stop_queue(dev); - restore_flags(flags); + local_irq_restore(flags); return 0; } static void timeout(struct net_device *dev) { - printk("%s: transmit timed out, resetting\n", dev->name); + printk(KERN_NOTICE "%s: transmit timed out, resetting\n", dev->name); sgiseeq_reset(dev); dev->trans_start = jiffies; @@ -603,41 +594,56 @@ buf[i].rdma.pnext = PHYSADDR(&buf[0]); } -static char onboard_eth_addr[6]; - #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -int sgiseeq_init(struct net_device *dev, struct sgiseeq_regs *sregs, - struct hpc3_ethregs *hregs, int irq) +int sgiseeq_init(struct hpc3_regs* regs, int irq) { - static unsigned version_printed; - int i; + struct net_device *dev; struct sgiseeq_private *sp; - - dev->priv = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); - if (dev->priv == NULL) + int i; + + sp = (struct sgiseeq_private *) get_zeroed_page(GFP_KERNEL); + if (!sp) { + printk (KERN_ERR + "Seeq8003: Could not allocate private data.\n"); return -ENOMEM; + } - if (!version_printed++) - printk(version); - - printk("%s: SGI Seeq8003 ", dev->name); - - for (i = 0; i < 6; i++) - printk("%2.2x%c", - dev->dev_addr[i] = onboard_eth_addr[i], - i == 5 ? ' ': ':'); + dev = init_etherdev(NULL, 0); + if (!dev) { + printk (KERN_ERR + "Seeq8003: Could not allocate memory for device.\n"); + free_page((unsigned long) sp); + return -ENOMEM; + } + if (request_irq(irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) { + printk(KERN_ERR "Seeq8003: Can't get irq %d\n", dev->irq); + free_page((unsigned long) sp); + unregister_netdev(dev); + return -EAGAIN; + } + + printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name); + +#define EADDR_NVOFS 250 + for (i = 0; i < 3; i++) { + unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); + + printk("%2.2x:%2.2x%c", + dev->dev_addr[2 * i] = tmp >> 8, + dev->dev_addr[2 * i + 1] = tmp & 0xff, + i == 2 ? ' ' : ':'); + } printk("\n"); - sp = (struct sgiseeq_private *) dev->priv; + dev->priv = sp; #ifdef DEBUG gpriv = sp; gdev = dev; #endif - memset((char *)dev->priv, 0, sizeof(struct sgiseeq_private)); - sp->sregs = sregs; - sp->hregs = hregs; + sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0]; + sp->hregs = &hpc3c0->ethregs; sp->name = sgiseeqstr; sp->srings.rx_desc = (struct sgiseeq_rx_desc *) @@ -654,14 +660,13 @@ setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS); /* Reset the chip. */ - hpc3_eth_reset((volatile struct hpc3_ethregs *) hregs); + hpc3_eth_reset(sp->hregs); - sp->is_edlc = !(sregs->rw.rregs.collision_tx[0] & 0xff); - if (sp->is_edlc) { + sp->is_edlc = !(sp->sregs->rw.rregs.collision_tx[0] & 0xff); + if (sp->is_edlc) sp->control = (SEEQ_CTRL_XCNT | SEEQ_CTRL_ACCNT | SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT | SEEQ_CTRL_ENCARR); - } dev->open = sgiseeq_open; dev->stop = sgiseeq_close; @@ -674,51 +679,37 @@ dev->dma = 0; ether_setup(dev); + sp->next_module = root_sgiseeq_dev; + root_sgiseeq_dev = dev; + return 0; } -static inline unsigned char str2hexnum(unsigned char c) +static int __init sgiseeq_probe(void) { - if (c >= '0' && c <= '9') - return c - '0'; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0; /* foo */ + printk(version); + + /* On board adapter on 1st HPC is always present */ + return sgiseeq_init(hpc3c0, SGI_ENET_IRQ); } -static inline void str2eaddr(unsigned char *ea, unsigned char *str) +static void __exit sgiseeq_exit(void) { - int i; - - for (i = 0; i < 6; i++) { - unsigned char num; + struct sgiseeq_private *sp; + struct net_device *next, *dev = root_sgiseeq_dev; - if(*str == ':') - str++; - num = str2hexnum(*str++) << 4; - num |= (str2hexnum(*str++)); - ea[i] = num; + while (dev) { + sp = (struct sgiseeq_private *) dev->priv; + next = sp->next_module; + free_irq(dev->irq, dev); + free_page((unsigned long) sp); + unregister_netdev(dev); + kfree(dev); + dev = next; } } -int sgiseeq_probe(struct net_device *dev) -{ - static int initialized; - char *ep; - - if (initialized) /* Already initialized? */ - return 1; - initialized++; - - /* First get the ethernet address of the onboard interface from ARCS. - * This is fragile; PROM doesn't like running from cache. - * On MIPS64 it crashes for some other, yet unknown reason ... - */ - ep = ArcGetEnvironmentVariable("eaddr"); - str2eaddr(onboard_eth_addr, ep); - return sgiseeq_init(dev, - (struct sgiseeq_regs *) (KSEG1ADDR(0x1fbd4000)), - &hpc3c0->ethregs, SGI_ENET_IRQ); -} +module_init(sgiseeq_probe); +module_exit(sgiseeq_exit); MODULE_LICENSE("GPL"); diff -Nru a/drivers/net/sgiseeq.h b/drivers/net/sgiseeq.h --- a/drivers/net/sgiseeq.h Fri Jun 27 14:19:56 2003 +++ b/drivers/net/sgiseeq.h Fri Jun 27 14:19:56 2003 @@ -1,4 +1,4 @@ -/* $Id: sgiseeq.h,v 1.4 1999/10/09 00:01:24 ralf Exp $ +/* * sgiseeq.h: Defines for the Seeq8003 ethernet controller. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c --- a/drivers/net/sk98lin/skge.c Fri Jun 27 14:19:53 2003 +++ b/drivers/net/sk98lin/skge.c Fri Jun 27 14:19:53 2003 @@ -48,6 +48,9 @@ * History: * * $Log: skge.c,v $ + * Revision x.xx.x.x 2003/06/07 02:31:17 romieu@fr.zoreil.com + * pci api style init. + * * Revision 1.29.2.6 2001/05/21 07:59:29 mlindner * fix: MTU init problems * @@ -275,6 +278,10 @@ #include "h/skdrv2nd.h" /* defines ******************************************************************/ + +#define DRV_MODULE_NAME "sk98lin" +#define PFX DRV_MODULE_NAME ": " + /* for debuging on x86 only */ /* #define BREAKPOINT() asm(" int $3"); */ @@ -361,9 +368,7 @@ /* global variables *********************************************************/ -static const char *BootString = BOOT_STRING; -struct net_device *sk98lin_root_dev = NULL; -static int probed __initdata = 0; +static int boards_found; struct inode_operations SkInodeOps; //static struct file_operations SkFileOps; /* with open/relase */ @@ -371,236 +376,219 @@ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; +spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED; + +static int SkGeDevInit(struct net_device *dev) +{ + DEV_NET *pNet = dev->priv; + int ret = 0; + + dev->open = &SkGeOpen; + dev->stop = &SkGeClose; + dev->hard_start_xmit = &SkGeXmit; + dev->get_stats = &SkGeStats; + dev->set_multicast_list = &SkGeSetRxMode; + dev->set_mac_address = &SkGeSetMacAddr; + dev->do_ioctl = &SkGeIoctl; + dev->change_mtu = &SkGeChangeMtu; + + if (register_netdev(dev) != 0) { + printk(KERN_ERR "Unable to register etherdev\n"); + ret = -ENOMEM; + goto out; + } + pNet->proc = create_proc_entry(dev->name, S_IFREG | 0444, pSkRootDir); + if (pNet->proc) { + pNet->proc->data = dev; + pNet->proc->owner = THIS_MODULE; + pNet->proc->proc_fops = &sk_proc_fops; + } +out: + return ret; +} + +static void SkGeDevCleanUp(struct net_device *dev) +{ + DEV_NET *pNet = dev->priv; + + if (pNet->proc) { + spin_lock(&sk_devs_lock); + pNet->proc->data = NULL; + spin_unlock(&sk_devs_lock); + remove_proc_entry(dev->name, pSkRootDir); + } + unregister_netdev(dev); +} /***************************************************************************** * - * skge_probe - find all SK-98xx adapters + * skge_init_one - init a single instance of a SK-98xx adapter * * Description: - * This function scans the PCI bus for SK-98xx adapters. Resources for - * each adapter are allocated and the adapter is brought into Init 1 - * state. + * This function allocates resources for an SK-98xx adapter and brings + * it into Init 1 state. * * Returns: * 0, if everything is ok - * !=0, on error + * <0, on error */ -static int __init skge_probe (void) +static int __devinit skge_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { - int proc_root_initialized = 0; - int boards_found = 0; - int version_disp = 0; SK_AC *pAC; - DEV_NET *pNet = NULL; - struct pci_dev *pdev = NULL; - unsigned long base_address; - struct net_device *dev = NULL; - - if (probed) - return -ENODEV; - probed++; - - /* display driver info */ - if (!version_disp) - { - /* set display flag to TRUE so that */ - /* we only display this string ONCE */ - version_disp = 1; - printk("%s\n", BootString); - } + DEV_NET *pNet; + unsigned long base_address; + struct net_device *dev; + int ret; - while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT, - PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) { - - pNet = NULL; +#ifndef MODULE + static int version_disp = 0; - if (pci_enable_device(pdev)) - continue; +if (!version_disp++) + printk(KERN_INFO "%s\n", BOOT_STRING); +#endif + ret = pci_enable_device(pdev); + if (ret) + goto out; - /* Configure DMA attributes. */ - if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) && - pci_set_dma_mask(pdev, (u64) 0xffffffff)) - continue; - - dev = alloc_etherdev(sizeof(DEV_NET)); - if (!dev) { - printk(KERN_ERR "Unable to allocate etherdev " - "structure!\n"); - break; + /* Configure DMA attributes. */ + if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) { + ret = pci_set_dma_mask(pdev, (u64) 0xffffffff); + if (ret) { + printk(KERN_ERR PFX "No usable DMA configuration\n"); + goto out_disable; } + } - pNet = dev->priv; - pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); - if (pNet->pAC == NULL){ - kfree(dev); - printk(KERN_ERR "Unable to allocate adapter " - "structure!\n"); - break; - } + ret = -ENOMEM; - memset(pNet->pAC, 0, sizeof(SK_AC)); - pAC = pNet->pAC; - pAC->PciDev = *pdev; - pAC->PciDevId = pdev->device; - pAC->dev[0] = dev; - pAC->dev[1] = dev; - sprintf(pAC->Name, "SysKonnect SK-98xx"); - pAC->CheckQueue = SK_FALSE; + dev = alloc_etherdev(sizeof(DEV_NET)); + if (!dev) { + printk(KERN_ERR "Unable to allocate etherdev structure!\n"); + goto out_disable; + } + + pNet = dev->priv; + + pAC = kmalloc(sizeof(*pAC), GFP_KERNEL); + if (pAC == NULL){ + printk(KERN_ERR "Unable to allocate adapter structure!\n"); + goto out_free_dev; + } + + memset(pAC, 0, sizeof(SK_AC)); + pNet->pAC = pAC; + pAC->PciDev = *pdev; + pAC->PciDevId = pdev->device; + pAC->dev[0] = dev; + pAC->dev[1] = dev; + sprintf(pAC->Name, "SysKonnect SK-98xx"); + pAC->CheckQueue = SK_FALSE; - pNet->Mtu = 1500; - pNet->Up = 0; - dev->irq = pdev->irq; + pNet->Mtu = 1500; + pNet->Up = 0; + dev->irq = pdev->irq; - SET_MODULE_OWNER(dev); - SET_NETDEV_DEV(dev, &pdev->dev); - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; - dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - - if(!proc_root_initialized) { - pSkRootDir = create_proc_entry(SK_Root_Dir_entry, - S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); - pSkRootDir->owner = THIS_MODULE; - proc_root_initialized = 1; - } + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + ret = SkGeDevInit(dev); + if (ret < 0) + goto out_free_priv; - /* - * Dummy value. - */ - dev->base_addr = 42; - pci_set_master(pdev); - base_address = pci_resource_start (pdev, 0); + /* + * Dummy value. + */ + dev->base_addr = 42; + pci_set_master(pdev); + base_address = pci_resource_start(pdev, 0); #ifdef SK_BIG_ENDIAN - /* - * On big endian machines, we use the adapter's aibility of - * reading the descriptors as big endian. - */ - { + /* + * On big endian machines, we use the adapter's ability of + * reading the descriptors as big endian. + */ + { SK_U32 our2; - SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); - our2 |= PCI_REV_DESC; - SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); - } + SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); + our2 |= PCI_REV_DESC; + SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); + } #endif /* BIG ENDIAN */ - /* - * Remap the regs into kernel space. - */ + /* + * Remap the regs into kernel space. + */ - pAC->IoBase = (char*)ioremap(base_address, 0x4000); - if (!pAC->IoBase){ - printk(KERN_ERR "%s: Unable to map I/O register, " - "SK 98xx No. %i will be disabled.\n", - dev->name, boards_found); - kfree(dev); - break; - } - pAC->Index = boards_found; + pAC->IoBase = (char*)ioremap(base_address, 0x4000); + if (!pAC->IoBase) { + printk(KERN_ERR PFX "unable to map I/O register. " + "SK 98xx device disabled.\n"); + ret = -EIO; + goto out_dev_uninit; + } + pAC->Index = boards_found++; + + ret = SkGeBoardInit(dev, pAC); + if (ret < 0) + goto out_free_resources; + + memcpy((caddr_t) &dev->dev_addr, + (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); + + pNet->PortNr = 0; + pNet->NetNr = 0; + + /* More then one port found */ + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + struct net_device *sec_dev; + + sec_dev = alloc_etherdev(sizeof(DEV_NET)); + if (!sec_dev) { + printk(KERN_ERR PFX + "Unable to allocate etherdev structure!\n"); + ret = -ENOMEM; + goto out_free_resources; + } + + pAC->dev[1] = sec_dev; + pNet = sec_dev->priv; + pNet->PortNr = 1; + pNet->NetNr = 1; + pNet->pAC = pAC; + pNet->Mtu = 1500; + pNet->Up = 0; - if (SkGeBoardInit(dev, pAC)) { - FreeResources(dev); - kfree(dev); - continue; - } + ret = SkGeDevInit(sec_dev); + if (ret < 0) + goto out_free_secondary_dev; - memcpy((caddr_t) &dev->dev_addr, + memcpy((caddr_t) &sec_dev->dev_addr, (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); - pNet->PortNr = 0; - pNet->NetNr = 0; - - if (register_netdev(dev) != 0) { - printk(KERN_ERR "Unable to register etherdev\n"); - sk98lin_root_dev = pAC->Next; - remove_proc_entry(dev->name, pSkRootDir); - FreeResources(dev); - kfree(dev); - continue; - } - - pNet->proc = create_proc_entry(dev->name, - S_IFREG | 0444, pSkRootDir); - if (pNet->proc) { - pNet->proc->data = dev; - pNet->proc->owner = THIS_MODULE; - pNet->proc->proc_fops = &sk_proc_fops; - } - - boards_found++; - - /* More then one port found */ - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - dev = alloc_etherdev(sizeof(DEV_NET)); - if (!dev) { - printk(KERN_ERR "Unable to allocate etherdev " - "structure!\n"); - break; - } - - pAC->dev[1] = dev; - pNet = dev->priv; - pNet->PortNr = 1; - pNet->NetNr = 1; - pNet->pAC = pAC; - pNet->Mtu = 1500; - pNet->Up = 0; - - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; - dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - - memcpy((caddr_t) &dev->dev_addr, - (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); - - printk("%s: %s\n", dev->name, pAC->DeviceStr); - printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); - - if (register_netdev(dev) != 0) { - printk(KERN_ERR "Unable to register etherdev\n"); - kfree(dev); - break; - } - - pNet->proc = create_proc_entry(dev->name, - S_IFREG | 0444, pSkRootDir); - if (pNet->proc) { - pNet->proc->data = dev; - pNet->proc->owner = THIS_MODULE; - pNet->proc->proc_fops = &sk_proc_fops; - } - - } - - - /* - * This is bollocks, but we need to tell the net-init - * code that it shall go for the next device. - */ -#ifndef MODULE - dev->base_addr = 0; -#endif + printk("%s: %s\n", sec_dev->name, pAC->DeviceStr); + printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); } + pci_set_drvdata(pdev, dev); - /* - * If we're at this point we're going through skge_probe() for - * the first time. Return success (0) if we've initialized 1 - * or more boards. Otherwise, return failure (-ENODEV). - */ - - return boards_found; -} /* skge_probe */ + ret = 0; +out: + return ret; + +out_free_secondary_dev: + kfree(pAC->dev[1]); +out_free_resources: + FreeResources(dev); +out_dev_uninit: + SkGeDevCleanUp(dev); +out_free_priv: + kfree(pAC); +out_free_dev: + kfree(dev); +out_disable: + pci_disable_device(pdev); + goto out; +} /* skge_init_one */ /***************************************************************************** * @@ -718,39 +706,9 @@ static int debug = 0; /* not used */ static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ - -/***************************************************************************** - * - * skge_init_module - module initialization function - * - * Description: - * Very simple, only call skge_probe and return approriate result. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int __init skge_init_module(void) -{ - int cards; - sk98lin_root_dev = NULL; - - /* just to avoid warnings ... */ - debug = 0; - options[0] = 0; - - cards = skge_probe(); - if (cards == 0) { - printk("No adapter found\n"); - } - return cards ? 0 : -ENODEV; -} /* skge_init_module */ - -spinlock_t sk_devs_lock = SPIN_LOCK_UNLOCKED; - /***************************************************************************** * - * skge_cleanup_module - module unload function + * skge_remove_one - remove a single instance of a SK-98xx adapter * * Description: * Disable adapter if it is still running, free resources, @@ -758,82 +716,65 @@ * * Returns: N/A */ -static void __exit skge_cleanup_module(void) +static void __devexit skge_remove_one(struct pci_dev *pdev) { -DEV_NET *pNet; -SK_AC *pAC; -struct net_device *next; -unsigned long Flags; -SK_EVPARA EvPara; + struct net_device *dev = pci_get_drvdata(pdev); + DEV_NET *pNet = dev->priv; + SK_AC *pAC = pNet->pAC; + unsigned long Flags; + SK_EVPARA EvPara; - while (sk98lin_root_dev) { - pNet = (DEV_NET*) sk98lin_root_dev->priv; - pAC = pNet->pAC; - next = pAC->Next; - netif_stop_queue(sk98lin_root_dev); - SkGeYellowLED(pAC, pAC->IoBase, 0); - if (pNet->proc) { - spin_lock(&sk_devs_lock); - pNet->proc->data = NULL; - spin_unlock(&sk_devs_lock); - } - - if(pAC->BoardLevel == 2) { - /* board is still alive */ - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - EvPara.Para32[0] = 0; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - EvPara.Para32[0] = 1; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - /* disable interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - SkGeDeInit(pAC, pAC->IoBase); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - pAC->BoardLevel = 0; - /* We do NOT check here, if IRQ was pending, of course*/ - } - - if(pAC->BoardLevel == 1) { - /* board is still alive */ - SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = 0; - } - - if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ - pNet = (DEV_NET*) pAC->dev[1]->priv; - if (pNet->proc) { - spin_lock(&sk_devs_lock); - pNet->proc->data = NULL; - spin_unlock(&sk_devs_lock); - } - unregister_netdev(pAC->dev[1]); - kfree(pAC->dev[1]); - } + netif_stop_queue(dev); + SkGeYellowLED(pAC, pAC->IoBase, 0); + if (pNet->proc) { + spin_lock(&sk_devs_lock); + pNet->proc->data = NULL; + spin_unlock(&sk_devs_lock); + remove_proc_entry(dev->name, pSkRootDir); + } - FreeResources(sk98lin_root_dev); + if (pAC->BoardLevel == 2) { + /* board is still alive */ + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + EvPara.Para32[0] = 0; + EvPara.Para32[1] = -1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + EvPara.Para32[0] = 1; + EvPara.Para32[1] = -1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); + SkEventDispatcher(pAC, pAC->IoBase); + /* disable interrupts */ + SK_OUT32(pAC->IoBase, B0_IMSK, 0); + SkGeDeInit(pAC, pAC->IoBase); + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + pAC->BoardLevel = 0; + /* We do NOT check here, if IRQ was pending, of course*/ + } - sk98lin_root_dev->get_stats = NULL; - /* - * otherwise unregister_netdev calls get_stats with - * invalid IO ... :-( - */ - unregister_netdev(sk98lin_root_dev); - kfree(sk98lin_root_dev); - kfree(pAC); - sk98lin_root_dev = next; + if (pAC->BoardLevel == 1) { + /* board is still alive */ + SkGeDeInit(pAC, pAC->IoBase); + pAC->BoardLevel = 0; } - /* clear proc-dir */ - remove_proc_entry(pSkRootDir->name, proc_net); + if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2) { + SkGeDevCleanUp(pAC->dev[1]); + kfree(pAC->dev[1]); + } -} /* skge_cleanup_module */ + FreeResources(dev); -module_init(skge_init_module); -module_exit(skge_cleanup_module); + dev->get_stats = NULL; + /* + * otherwise unregister_netdev calls get_stats with + * invalid IO ... :-( + */ + unregister_netdev(dev); + kfree(dev); + kfree(pAC); + boards_found--; +} /* skge_remove_one */ /***************************************************************************** * @@ -968,12 +909,6 @@ SkGeYellowLED(pAC, pAC->IoBase, 1); - /* - * Register the device here - */ - pAC->Next = sk98lin_root_dev; - sk98lin_root_dev = dev; - return (0); } /* SkGeBoardInit */ @@ -4097,9 +4032,62 @@ #endif /* DEBUG */ +static struct pci_device_id skge_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE, + PCI_ANY_ID, PCI_ANY_ID, }, + { 0,} +}; +MODULE_DEVICE_TABLE(pci, skge_pci_tbl); + +static struct pci_driver skge_driver = { + .name = DRV_MODULE_NAME, + .id_table = skge_pci_tbl, + .probe = skge_init_one, + .remove = __devexit_p(skge_remove_one), +}; + +/***************************************************************************** + * + * skge_init - module initialization function + * + * Description: + * root /proc directory allocation and pci driver invocation. + * + * Returns: + * 0, if everything is ok + * !=0, on error + */ +static int __init skge_init(void) +{ + int ret = -ENOMEM; + + /* just to avoid warnings ... */ + debug = 0; + options[0] = 0; + + pSkRootDir = create_proc_entry(DRV_MODULE_NAME, + S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); + if (pSkRootDir) { + pSkRootDir->owner = THIS_MODULE; + ret = pci_module_init(&skge_driver); + if (ret) + remove_proc_entry(pSkRootDir->name, proc_net); + } + return ret; +} /* skge_init */ + + +static void __exit skge_cleanup(void) +{ + remove_proc_entry(pSkRootDir->name, proc_net); + pci_unregister_driver(&skge_driver); +} + +module_init(skge_init); +module_exit(skge_cleanup); + /* * Local variables: * compile-command: "make" * End: */ - diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c --- a/drivers/net/sungem.c Fri Jun 27 14:20:05 2003 +++ b/drivers/net/sungem.c Fri Jun 27 14:20:05 2003 @@ -2384,9 +2384,6 @@ return 0; case ETHTOOL_SSET: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Verify the settings we care about. */ if (ecmd.autoneg != AUTONEG_ENABLE && ecmd.autoneg != AUTONEG_DISABLE) diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c --- a/drivers/net/sunhme.c Fri Jun 27 14:19:55 2003 +++ b/drivers/net/sunhme.c Fri Jun 27 14:19:55 2003 @@ -2481,9 +2481,6 @@ return -EFAULT; return 0; } else if (ecmd.cmd == ETHTOOL_SSET) { - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - /* Verify the settings we care about. */ if (ecmd.autoneg != AUTONEG_ENABLE && ecmd.autoneg != AUTONEG_DISABLE) diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c --- a/drivers/net/tulip/tulip_core.c Fri Jun 27 14:19:58 2003 +++ b/drivers/net/tulip/tulip_core.c Fri Jun 27 14:19:58 2003 @@ -94,6 +94,8 @@ static int csr0 = 0x01A00000 | 0x9000; #elif defined(__arm__) || defined(__sh__) static int csr0 = 0x01A00000 | 0x4800; +#elif defined(__mips__) +static int csr0 = 0x00200000 | 0x4000; #else #warning Processor architecture undefined! static int csr0 = 0x00A00000 | 0x4800; @@ -1486,6 +1488,16 @@ #ifdef CONFIG_DDB5477 if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 4)) { /* DDB5477 MAC address in first EEPROM locations. */ + sa_offset = 0; + /* No media table either */ + tp->flags &= ~HAS_MEDIA_TABLE; + } +#endif +#ifdef CONFIG_MIPS_COBALT + if ((pdev->bus->number == 0) && + ((PCI_SLOT(pdev->devfn) == 7) || + (PCI_SLOT(pdev->devfn) == 12))) { + /* Cobalt MAC address in first EEPROM locations. */ sa_offset = 0; /* No media table either */ tp->flags &= ~HAS_MEDIA_TABLE; diff -Nru a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c --- a/drivers/net/wan/sdla_chdlc.c Fri Jun 27 14:19:56 2003 +++ b/drivers/net/wan/sdla_chdlc.c Fri Jun 27 14:19:56 2003 @@ -996,13 +996,11 @@ set_bit(0,&chdlc_priv_area->config_chdlc); chdlc_priv_area->config_chdlc_timeout=jiffies; - del_timer(&chdlc_priv_area->poll_delay_timer); /* Start the CHDLC configuration after 1sec delay. * This will give the interface initilization time * to finish its configuration */ - chdlc_priv_area->poll_delay_timer.expires=jiffies+HZ; - add_timer(&chdlc_priv_area->poll_delay_timer); + mod_timer(&chdlc_priv_area->poll_delay_timer, jiffies + HZ); return err; } diff -Nru a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c --- a/drivers/net/wan/sdla_fr.c Fri Jun 27 14:20:05 2003 +++ b/drivers/net/wan/sdla_fr.c Fri Jun 27 14:20:05 2003 @@ -4163,9 +4163,7 @@ { fr_channel_t* chan = dev->priv; - del_timer(&chan->fr_arp_timer); - chan->fr_arp_timer.expires = jiffies + (chan->inarp_interval * HZ); - add_timer(&chan->fr_arp_timer); + mod_timer(&chan->fr_arp_timer, jiffies + chan->inarp_interval * HZ); return; } diff -Nru a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c --- a/drivers/net/wan/sdla_ppp.c Fri Jun 27 14:19:54 2003 +++ b/drivers/net/wan/sdla_ppp.c Fri Jun 27 14:19:54 2003 @@ -762,9 +762,7 @@ /* Start the PPP configuration after 1sec delay. * This will give the interface initilization time * to finish its configuration */ - del_timer(&ppp_priv_area->poll_delay_timer); - ppp_priv_area->poll_delay_timer.expires = jiffies+HZ; - add_timer(&ppp_priv_area->poll_delay_timer); + mod_timer(&ppp_priv_area->poll_delay_timer, jiffies + HZ); return 0; } diff -Nru a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c --- a/drivers/net/wan/sdla_x25.c Fri Jun 27 14:19:59 2003 +++ b/drivers/net/wan/sdla_x25.c Fri Jun 27 14:19:59 2003 @@ -1235,9 +1235,7 @@ connect(card); S508_S514_unlock(card, &smp_flags); - del_timer(&card->u.x.x25_timer); - card->u.x.x25_timer.expires=jiffies+HZ; - add_timer(&card->u.x.x25_timer); + mod_timer(&card->u.x.x25_timer, jiffies + HZ); } } /* Device is not up until the we are in connected state */ diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile --- a/drivers/pci/Makefile Fri Jun 27 14:20:03 2003 +++ b/drivers/pci/Makefile Fri Jun 27 14:20:03 2003 @@ -3,15 +3,16 @@ # obj-y += access.o bus.o probe.o pci.o pool.o quirks.o \ - names.o pci-driver.o search.o hotplug.o \ - pci-sysfs.o + names.o pci-driver.o search.o pci-sysfs.o obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PROC_FS) += proc.o ifndef CONFIG_SPARC64 -obj-$(CONFIG_PCI) += setup-res.o +obj-y += setup-res.o endif +obj-$(CONFIG_HOTPLUG) += hotplug.o + # Build the PCI Hotplug drivers if we were asked to obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ @@ -24,16 +25,11 @@ obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC32) += setup-irq.o obj-$(CONFIG_PPC64) += setup-bus.o -obj-$(CONFIG_DDB5476) += setup-bus.o obj-$(CONFIG_SGI_IP27) += setup-irq.o +obj-$(CONFIG_SGI_IP32) += setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o -# CompactPCI hotplug requires the pbus_* functions -ifdef CONFIG_HOTPLUG_PCI_CPCI -obj-y += setup-bus.o -endif - -# Hotplug (eg, cardbus) now requires setup-bus +# Cardbus & CompactPCI use setup-bus obj-$(CONFIG_HOTPLUG) += setup-bus.o ifndef CONFIG_X86 diff -Nru a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig --- a/drivers/pci/hotplug/Kconfig Fri Jun 27 14:19:55 2003 +++ b/drivers/pci/hotplug/Kconfig Fri Jun 27 14:19:55 2003 @@ -21,6 +21,31 @@ When in doubt, say N. +config HOTPLUG_PCI_FAKE + tristate "Fake PCI Hotplug driver" + depends on HOTPLUG_PCI + help + Say Y here if you want to use the fake PCI hotplug driver. It can + be used to simulate PCI hotplug events if even if your system is + not PCI hotplug capable. + + This driver will "emulate" removing PCI devices from the system. + If the "power" file is written to with "0" then the specified PCI + device will be completely removed from the kernel. + + WARNING, this does NOT turn off the power to the PCI device. + This is a "logical" removal, not a physical or electrical + removal. + + Use this module at your own risk. You have been warned! + + This code is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called fakephp. If you want to compile it + as a module, say M here and read <file:Documentation/modules.txt>. + + When in doubt, say N. + config HOTPLUG_PCI_COMPAQ tristate "Compaq PCI Hotplug driver" depends on HOTPLUG_PCI && X86 diff -Nru a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile --- a/drivers/pci/hotplug/Makefile Fri Jun 27 14:19:59 2003 +++ b/drivers/pci/hotplug/Makefile Fri Jun 27 14:19:59 2003 @@ -3,6 +3,7 @@ # obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o +obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o diff -Nru a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c --- a/drivers/pci/hotplug/acpiphp_core.c Fri Jun 27 14:19:58 2003 +++ b/drivers/pci/hotplug/acpiphp_core.c Fri Jun 27 14:19:58 2003 @@ -380,6 +380,25 @@ } /** + * release_slot - free up the memory used by a slot + * @hotplug_slot: slot to free + */ +static void release_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + + if (slot == NULL) + return; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); +} + +/** * init_slots - initialize 'struct slot' structures for each slot * */ @@ -422,6 +441,7 @@ slot->number = i; slot->hotplug_slot->private = slot; + slot->hotplug_slot->release = &release_slot; slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; slot->acpi_slot = get_slot_from_id(i); @@ -435,10 +455,7 @@ retval = pci_hp_register(slot->hotplug_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); - kfree(slot->hotplug_slot->info); - kfree(slot->hotplug_slot->name); - kfree(slot->hotplug_slot); - kfree(slot); + release_slot(slot->hotplug_slot); return retval; } @@ -457,13 +474,10 @@ struct slot *slot; list_for_each_safe (tmp, n, &slot_list) { + /* memory will be freed in release_slot callback */ slot = list_entry(tmp, struct slot, slot_list); list_del(&slot->slot_list); pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot->info); - kfree(slot->hotplug_slot->name); - kfree(slot->hotplug_slot); - kfree(slot); } return; diff -Nru a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c --- a/drivers/pci/hotplug/cpci_hotplug_core.c Fri Jun 27 14:19:56 2003 +++ b/drivers/pci/hotplug/cpci_hotplug_core.c Fri Jun 27 14:19:56 2003 @@ -278,6 +278,19 @@ return 0; } +static void release_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + + if(slot == NULL) + return; + + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); +} + #define SLOT_NAME_SIZE 6 static void make_slot_name(struct slot *slot) @@ -346,6 +359,7 @@ slot->devfn = PCI_DEVFN(i, 0); hotplug_slot->private = slot; + hotplug_slot->release = &release_slot; make_slot_name(slot); hotplug_slot->ops = &cpci_hotplug_slot_ops; @@ -382,6 +396,7 @@ { struct slot *slot; struct list_head *tmp; + struct list_head *next; int status; if(!bus) { @@ -393,7 +408,7 @@ spin_unlock(&list_lock); return -1; } - list_for_each(tmp, &slot_list) { + list_for_each_safe(tmp, next, &slot_list) { slot = list_entry(tmp, struct slot, slot_list); if(slot->bus == bus) { dbg("deregistering slot %s", slot->hotplug_slot->name); @@ -405,11 +420,6 @@ } list_del(&slot->slot_list); - kfree(slot->hotplug_slot->info); - kfree(slot->hotplug_slot->name); - kfree(slot->hotplug_slot); - kfree(slot); - slots--; } } diff -Nru a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c --- a/drivers/pci/hotplug/cpqphp_core.c Fri Jun 27 14:19:30 2003 +++ b/drivers/pci/hotplug/cpqphp_core.c Fri Jun 27 14:19:30 2003 @@ -312,6 +312,20 @@ return previous; } +static void release_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); + + if (slot == NULL) + return; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); +} static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *smbios_table) { @@ -401,6 +415,7 @@ new_slot->capabilities |= ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; /* register this slot with the hotplug pci core */ + new_slot->hotplug_slot->release = &release_slot; new_slot->hotplug_slot->private = new_slot; make_slot_name (new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot); new_slot->hotplug_slot->ops = &cpqphp_hotplug_slot_ops; @@ -415,10 +430,7 @@ result = pci_hp_register (new_slot->hotplug_slot); if (result) { err ("pci_hp_register failed with error %d\n", result); - kfree (new_slot->hotplug_slot->info); - kfree (new_slot->hotplug_slot->name); - kfree (new_slot->hotplug_slot); - kfree (new_slot); + release_slot(new_slot->hotplug_slot); return result; } @@ -430,10 +442,9 @@ slot_number++; } - return(0); + return 0; } - static int ctrl_slot_cleanup (struct controller * ctrl) { struct slot *old_slot, *next_slot; @@ -442,12 +453,9 @@ ctrl->slot = NULL; while (old_slot) { + /* memory will be freed by the release_slot callback */ next_slot = old_slot->next; pci_hp_deregister (old_slot->hotplug_slot); - kfree(old_slot->hotplug_slot->info); - kfree(old_slot->hotplug_slot->name); - kfree(old_slot->hotplug_slot); - kfree(old_slot); old_slot = next_slot; } @@ -498,7 +506,7 @@ sizeof(struct irq_routing_table)) / sizeof(struct irq_info); // Make sure I got at least one entry if (len == 0) { - if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength ); + kfree(PCIIRQRoutingInfoLength); return -1; } @@ -509,9 +517,7 @@ if ((tbus == bus_num) && (tdevice == dev_num)) { *slot = tslot; - - if (PCIIRQRoutingInfoLength != NULL) - kfree(PCIIRQRoutingInfoLength); + kfree(PCIIRQRoutingInfoLength); return 0; } else { // Didn't get a match on the target PCI device. Check if the @@ -540,10 +546,10 @@ // slot number for the bridge. if (bridgeSlot != 0xFF) { *slot = bridgeSlot; - if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength ); + kfree(PCIIRQRoutingInfoLength); return 0; } - if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength ); + kfree(PCIIRQRoutingInfoLength); // Couldn't find an entry in the routing table for this PCI device return -1; } diff -Nru a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c --- a/drivers/pci/hotplug/cpqphp_pci.c Fri Jun 27 14:20:04 2003 +++ b/drivers/pci/hotplug/cpqphp_pci.c Fri Jun 27 14:20:04 2003 @@ -198,7 +198,7 @@ ctrl->pci_bus->number = bus_num; - for (tdevice = 0; tdevice < 0x100; tdevice++) { + for (tdevice = 0; tdevice < 0xFF; tdevice++) { //Scan for access first if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) continue; @@ -210,7 +210,7 @@ return 0; } } - for (tdevice = 0; tdevice < 0x100; tdevice++) { + for (tdevice = 0; tdevice < 0xFF; tdevice++) { //Scan for access first if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) continue; diff -Nru a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/pci/hotplug/fakephp.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,232 @@ +/* + * Fake PCI Hot Plug Controller Driver + * + * Copyright (c) 2003 Greg Kroah-Hartman <greg@kroah.com> + * Copyright (c) 2003 IBM Corp. + * Copyright (c) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de> + * + * Based on ideas and code from: + * Vladimir Kondratiev <vladimir.kondratiev@intel.com> + * Rolf Eike Beer <eike-kernel@sf-tec.de> + * + * All rights reserved. + * + * 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, version 2 of the License. + * + * Send feedback to <greg@kroah.com> + */ + +/* + * + * This driver will "emulate" removing PCI devices from the system. If + * the "power" file is written to with "0" then the specified PCI device + * will be completely removed from the kernel. + * + * WARNING, this does NOT turn off the power to the PCI device. This is + * a "logical" removal, not a physical or electrical removal. + * + * Use this module at your own risk, you have been warned! + * + * Enabling PCI devices is left as an exercise for the reader... + * + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/init.h> +#include "pci_hotplug.h" +#include "../pci.h" + +#if !defined(CONFIG_HOTPLUG_PCI_FAKE_MODULE) + #define MY_NAME "fakephp" +#else + #define MY_NAME THIS_MODULE->name +#endif + +#define dbg(format, arg...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG "%s: " format, \ + MY_NAME , ## arg); \ + } while (0) +#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) +#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) + +#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" +#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver" + +struct dummy_slot { + struct list_head node; + struct hotplug_slot *slot; + struct pci_dev *dev; +}; + +static int debug; +static LIST_HEAD(slot_list); + +static int enable_slot (struct hotplug_slot *slot); +static int disable_slot (struct hotplug_slot *slot); + +static struct hotplug_slot_ops dummy_hotplug_slot_ops = { + .owner = THIS_MODULE, + .enable_slot = enable_slot, + .disable_slot = disable_slot, +}; + +static void dummy_release(struct hotplug_slot *slot) +{ + struct dummy_slot *dslot = slot->private; + + list_del(&dslot->node); + kfree(dslot->slot->info); + kfree(dslot->slot); + pci_dev_put(dslot->dev); + kfree(dslot); +} + +static int add_slot(struct pci_dev *dev) +{ + struct dummy_slot *dslot; + struct hotplug_slot *slot; + int retval = -ENOMEM; + + slot = kmalloc(sizeof(struct hotplug_slot), GFP_KERNEL); + if (!slot) + goto error; + memset(slot, 0, sizeof(*slot)); + + slot->info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + if (!slot->info) + goto error_slot; + memset(slot->info, 0, sizeof(struct hotplug_slot_info)); + + slot->info->power_status = 1; + slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; + slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; + + slot->name = &dev->dev.bus_id[0]; + dbg("slot->name = %s\n", slot->name); + + dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL); + if (!dslot) + goto error_info; + + slot->ops = &dummy_hotplug_slot_ops; + slot->release = &dummy_release; + slot->private = dslot; + + retval = pci_hp_register(slot); + if (retval) { + err("pci_hp_register failed with error %d\n", retval); + goto error_dslot; + } + + dslot->slot = slot; + dslot->dev = pci_dev_get(dev); + list_add (&dslot->node, &slot_list); + return retval; + +error_dslot: + kfree(dslot); +error_info: + kfree(slot->info); +error_slot: + kfree(slot); +error: + return retval; +} + +static int __init pci_scan_buses(void) +{ + struct pci_dev *dev = NULL; + int retval = 0; + + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + retval = add_slot(dev); + if (retval) { + pci_dev_put(dev); + break; + } + } + + return retval; +} + +static void remove_slot(struct dummy_slot *dslot) +{ + int retval; + + dbg("removing slot %s\n", dslot->slot->name); + retval = pci_hp_deregister(dslot->slot); + if (retval) + err("Problem unregistering a slot %s\n", dslot->slot->name); +} + +static int enable_slot(struct hotplug_slot *hotplug_slot) +{ + return -ENODEV; +} + +static int disable_slot(struct hotplug_slot *slot) +{ + struct dummy_slot *dslot; + + if (!slot) + return -ENODEV; + dslot = slot->private; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, slot->name); + + /* don't disable bridged devices just yet, we can't handle them easily... */ + if (dslot->dev->subordinate) { + err("Can't remove PCI devices with other PCI devices behind it yet.\n"); + return -ENODEV; + } + + /* remove the device from the pci core */ + pci_remove_bus_device(dslot->dev); + + /* blow away this sysfs entry and other parts. */ + remove_slot(dslot); + + return 0; +} + +static void cleanup_slots (void) +{ + struct list_head *tmp; + struct list_head *next; + struct dummy_slot *dslot; + + list_for_each_safe (tmp, next, &slot_list) { + dslot = list_entry (tmp, struct dummy_slot, node); + remove_slot(dslot); + } + +} + +static int __init dummyphp_init(void) +{ + info(DRIVER_DESC "\n"); + + return pci_scan_buses(); +} + + +static void __exit dummyphp_exit(void) +{ + cleanup_slots(); +} + +module_init(dummyphp_init); +module_exit(dummyphp_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); +MODULE_PARM(debug, "i"); +MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); + diff -Nru a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h --- a/drivers/pci/hotplug/ibmphp.h Fri Jun 27 14:19:53 2003 +++ b/drivers/pci/hotplug/ibmphp.h Fri Jun 27 14:19:53 2003 @@ -7,7 +7,7 @@ * Written By: Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation * * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (c) 2001-2003 IBM Corp. * * All rights reserved. * @@ -398,7 +398,6 @@ extern int ibmphp_hpc_writeslot (struct slot *, u8); extern void ibmphp_lock_operations (void); extern void ibmphp_unlock_operations (void); -extern int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *); extern int ibmphp_hpc_start_poll_thread (void); extern void ibmphp_hpc_stop_poll_thread (void); diff -Nru a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c --- a/drivers/pci/hotplug/ibmphp_core.c Fri Jun 27 14:20:06 2003 +++ b/drivers/pci/hotplug/ibmphp_core.c Fri Jun 27 14:20:06 2003 @@ -3,8 +3,8 @@ * * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (c) 2001-2003 IBM Corp. * * All rights reserved. * @@ -739,26 +739,8 @@ debug ("%s -- enter\n", __FUNCTION__); list_for_each_safe (tmp, next, &ibmphp_slot_head) { - slot_cur = list_entry (tmp, struct slot, ibm_slot_list); - pci_hp_deregister (slot_cur->hotplug_slot); - - if (slot_cur->hotplug_slot) { - kfree (slot_cur->hotplug_slot); - slot_cur->hotplug_slot = NULL; - } - - if (slot_cur->ctrl) - slot_cur->ctrl = NULL; - - if (slot_cur->bus_on) - slot_cur->bus_on = NULL; - - ibmphp_unconfigure_card (&slot_cur, -1); /* we don't want to actually remove the resources, since free_resources will do just that */ - - kfree (slot_cur); - slot_cur = NULL; } debug ("%s -- exit\n", __FUNCTION__); } @@ -1221,7 +1203,6 @@ { int rc; u8 flag; - int parm = 0; debug ("DISABLING SLOT... \n"); @@ -1270,7 +1251,7 @@ return 0; } - rc = ibmphp_unconfigure_card (&slot_cur, parm); + rc = ibmphp_unconfigure_card (&slot_cur, 0); slot_cur->func = NULL; debug ("in disable_slot. after unconfigure_card\n"); if (rc) { diff -Nru a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c --- a/drivers/pci/hotplug/ibmphp_ebda.c Fri Jun 27 14:19:54 2003 +++ b/drivers/pci/hotplug/ibmphp_ebda.c Fri Jun 27 14:19:54 2003 @@ -3,8 +3,8 @@ * * Written By: Tong Yu, IBM Corporation * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001,2002 IBM Corp. + * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (c) 2001-2003 IBM Corp. * * All rights reserved. * @@ -727,6 +727,64 @@ return str; } +static int fillslotinfo(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot; + int rc = 0; + + if (!hotplug_slot || !hotplug_slot->private) + return -EINVAL; + + slot = hotplug_slot->private; + rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL); + if (rc) + return rc; + + // power - enabled:1 not:0 + hotplug_slot->info->power_status = SLOT_POWER(slot->status); + + // attention - off:0, on:1, blinking:2 + hotplug_slot->info->attention_status = SLOT_ATTN(slot->status, slot->ext_status); + + // latch - open:1 closed:0 + hotplug_slot->info->latch_status = SLOT_LATCH(slot->status); + + // pci board - present:1 not:0 + if (SLOT_PRESENT (slot->status)) + hotplug_slot->info->adapter_status = 1; + else + hotplug_slot->info->adapter_status = 0; +/* + if (slot->bus_on->supported_bus_mode + && (slot->bus_on->supported_speed == BUS_SPEED_66)) + hotplug_slot->info->max_bus_speed_status = BUS_SPEED_66PCIX; + else + hotplug_slot->info->max_bus_speed_status = slot->bus_on->supported_speed; +*/ + + return rc; +} + +static void release_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot; + + if (!hotplug_slot || !hotplug_slot->private) + return; + + slot = hotplug_slot->private; + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + slot->ctrl = NULL; + slot->bus_on = NULL; + + /* we don't want to actually remove the resources, since free_resources will do just that */ + ibmphp_unconfigure_card(&slot, -1); + + kfree (slot); +} + static struct pci_driver ibmphp_driver; /* @@ -900,32 +958,32 @@ // register slots with hpc core as well as create linked list of ibm slot for (index = 0; index < hpc_ptr->slot_count; index++) { - hp_slot_ptr = (struct hotplug_slot *) kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL); + hp_slot_ptr = kmalloc(sizeof(*hp_slot_ptr), GFP_KERNEL); if (!hp_slot_ptr) { rc = -ENOMEM; goto error_no_hp_slot; } - memset (hp_slot_ptr, 0, sizeof (struct hotplug_slot)); + memset(hp_slot_ptr, 0, sizeof(*hp_slot_ptr)); - hp_slot_ptr->info = (struct hotplug_slot_info *) kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL); + hp_slot_ptr->info = kmalloc (sizeof(struct hotplug_slot_info), GFP_KERNEL); if (!hp_slot_ptr->info) { rc = -ENOMEM; goto error_no_hp_info; } - memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info)); + memset(hp_slot_ptr->info, 0, sizeof(struct hotplug_slot_info)); - hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL); + hp_slot_ptr->name = kmalloc(30, GFP_KERNEL); if (!hp_slot_ptr->name) { rc = -ENOMEM; goto error_no_hp_name; } - tmp_slot = kmalloc (sizeof (struct slot), GFP_KERNEL); + tmp_slot = kmalloc(sizeof(*tmp_slot), GFP_KERNEL); if (!tmp_slot) { rc = -ENOMEM; goto error_no_slot; } - memset (tmp_slot, 0, sizeof (*tmp_slot)); + memset(tmp_slot, 0, sizeof(*tmp_slot)); tmp_slot->flag = TRUE; @@ -959,8 +1017,9 @@ tmp_slot->hotplug_slot = hp_slot_ptr; hp_slot_ptr->private = tmp_slot; + hp_slot_ptr->release = release_slot; - rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr); + rc = fillslotinfo(hp_slot_ptr); if (rc) goto error; diff -Nru a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c --- a/drivers/pci/hotplug/ibmphp_hpc.c Fri Jun 27 14:19:54 2003 +++ b/drivers/pci/hotplug/ibmphp_hpc.c Fri Jun 27 14:19:54 2003 @@ -3,7 +3,7 @@ * * Written By: Jyoti Shah, IBM Corporation * - * Copyright (c) 2001-2002 IBM Corp. + * Copyright (c) 2001-2003 IBM Corp. * * All rights reserved. * @@ -114,7 +114,6 @@ static void get_hpc_access (void); static void free_hpc_access (void); static void poll_hpc (void); -static int update_slot (struct slot *, u8); static int process_changeinstatus (struct slot *, struct slot *); static int process_changeinlatch (u8, u8, struct controller *); static int hpc_poll_thread (void *); @@ -152,11 +151,11 @@ u8 status; int i; void *wpg_addr; // base addr + offset - ulong wpg_data, // data to/from WPG LOHI format - ultemp, data; // actual data HILO format + unsigned long wpg_data; // data to/from WPG LOHI format + unsigned long ultemp; + unsigned long data; // actual data HILO format - - debug_polling ("%s - Entry WPGBbar[%lx] index[%x] \n", __FUNCTION__, (ulong) WPGBbar, index); + debug_polling ("%s - Entry WPGBbar[%p] index[%x] \n", __FUNCTION__, WPGBbar, index); //-------------------------------------------------------------------- // READ - step 1 @@ -165,17 +164,17 @@ if (ctlr_ptr->ctlr_type == 0x02) { data = WPG_READATADDR_MASK; // fill in I2C address - ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr; + ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr; ultemp = ultemp >> 1; data |= (ultemp << 8); // fill in index - data |= (ulong) index; + data |= (unsigned long)index; } else if (ctlr_ptr->ctlr_type == 0x04) { data = WPG_READDIRECT_MASK; // fill in index - ultemp = (ulong) index; + ultemp = (unsigned long)index; ultemp = ultemp << 8; data |= ultemp; } else { @@ -184,14 +183,14 @@ } wpg_data = swab32 (data); // swap data before writing - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // READ - step 2 : clear the message buffer data = 0x00000000; wpg_data = swab32 (data); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- @@ -199,7 +198,7 @@ // 2020 : [20] OR operation at [20] offset 0x20 data = WPG_I2CMCNTL_STARTOP_MASK; wpg_data = swab32 (data); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR; + wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- @@ -207,7 +206,7 @@ i = CMD_COMPLETE_TOUT_SEC; while (i) { long_delay (1 * HZ / 100); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (!(data & WPG_I2CMCNTL_STARTOP_MASK)) @@ -223,7 +222,7 @@ i = CMD_COMPLETE_TOUT_SEC; while (i) { long_delay (1 * HZ / 100); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET; + wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (HPC_I2CSTATUS_CHECK (data)) @@ -237,7 +236,7 @@ //-------------------------------------------------------------------- // READ - step 6 : get DATA - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); @@ -259,12 +258,12 @@ { u8 rc; void *wpg_addr; // base addr + offset - ulong wpg_data, // data to/from WPG LOHI format - ultemp, data; // actual data HILO format + unsigned long wpg_data; // data to/from WPG LOHI format + unsigned long ultemp; + unsigned long data; // actual data HILO format int i; - - debug_polling ("%s - Entry WPGBbar[%lx] index[%x] cmd[%x]\n", __FUNCTION__, (ulong) WPGBbar, index, cmd); + debug_polling ("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __FUNCTION__, WPGBbar, index, cmd); rc = 0; //-------------------------------------------------------------------- @@ -276,17 +275,17 @@ if (ctlr_ptr->ctlr_type == 0x02) { data = WPG_WRITEATADDR_MASK; // fill in I2C address - ultemp = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr; + ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr; ultemp = ultemp >> 1; data |= (ultemp << 8); // fill in index - data |= (ulong) index; + data |= (unsigned long)index; } else if (ctlr_ptr->ctlr_type == 0x04) { data = WPG_WRITEDIRECT_MASK; // fill in index - ultemp = (ulong) index; + ultemp = (unsigned long)index; ultemp = ultemp << 8; data |= ultemp; } else { @@ -295,14 +294,14 @@ } wpg_data = swab32 (data); // swap data before writing - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- // WRITE - step 2 : clear the message buffer - data = 0x00000000 | (ulong) cmd; + data = 0x00000000 | (unsigned long)cmd; wpg_data = swab32 (data); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMBUFL_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- @@ -310,7 +309,7 @@ // 2020 : [20] OR operation at [20] offset 0x20 data = WPG_I2CMCNTL_STARTOP_MASK; wpg_data = swab32 (data); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) WPG_I2C_OR; + wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR; writel (wpg_data, wpg_addr); //-------------------------------------------------------------------- @@ -318,7 +317,7 @@ i = CMD_COMPLETE_TOUT_SEC; while (i) { long_delay (1 * HZ / 100); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET; + wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (!(data & WPG_I2CMCNTL_STARTOP_MASK)) @@ -335,7 +334,7 @@ i = CMD_COMPLETE_TOUT_SEC; while (i) { long_delay (1 * HZ / 100); - (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CSTAT_OFFSET; + wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET; wpg_data = readl (wpg_addr); data = swab32 (wpg_data); if (HPC_I2CSTATUS_CHECK (data)) @@ -543,7 +542,7 @@ int rc = 0; int busindex; - debug_polling ("%s - Entry pslot[%lx] cmd[%x] pstatus[%lx]\n", __FUNCTION__, (ulong) pslot, cmd, (ulong) pstatus); + debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __FUNCTION__, pslot, cmd, pstatus); if ((pslot == NULL) || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) { @@ -683,7 +682,7 @@ int rc = 0; int timeout; - debug_polling ("%s - Entry pslot[%lx] cmd[%x]\n", __FUNCTION__, (ulong) pslot, cmd); + debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __FUNCTION__, pslot, cmd); if (pslot == NULL) { rc = -EINVAL; err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc); @@ -917,71 +916,6 @@ } -/* ---------------------------------------------------------------------- - * Name: ibmphp_hpc_fillhpslotinfo(hotplug_slot * phpslot) - * - * Action: fill out the hotplug_slot info - * - * Input: pointer to hotplug_slot - * - * Return - * Value: 0 or error codes - *-----------------------------------------------------------------------*/ -int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *phpslot) -{ - int rc = 0; - struct slot *pslot; - - if (phpslot && phpslot->private) { - pslot = (struct slot *) phpslot->private; - rc = update_slot (pslot, (u8) TRUE); - if (!rc) { - - // power - enabled:1 not:0 - phpslot->info->power_status = SLOT_POWER (pslot->status); - - // attention - off:0, on:1, blinking:2 - phpslot->info->attention_status = SLOT_ATTN (pslot->status, pslot->ext_status); - - // latch - open:1 closed:0 - phpslot->info->latch_status = SLOT_LATCH (pslot->status); - - // pci board - present:1 not:0 - if (SLOT_PRESENT (pslot->status)) - phpslot->info->adapter_status = 1; - else - phpslot->info->adapter_status = 0; -/* - if (pslot->bus_on->supported_bus_mode - && (pslot->bus_on->supported_speed == BUS_SPEED_66)) - phpslot->info->max_bus_speed_status = BUS_SPEED_66PCIX; - else - phpslot->info->max_bus_speed_status = pslot->bus_on->supported_speed; -*/ } else - rc = -EINVAL; - } else - rc = -EINVAL; - - return rc; -} - -/*---------------------------------------------------------------------- -* Name: update_slot -* -* Action: fill out slot status and extended status, controller status -* -* Input: pointer to slot struct -*---------------------------------------------------------------------*/ -static int update_slot (struct slot *pslot, u8 update) -{ - int rc = 0; - - debug ("%s - Entry pslot[%lx]\n", __FUNCTION__, (ulong) pslot); - rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL); - debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc); - return rc; -} - /*---------------------------------------------------------------------- * Name: process_changeinstatus * @@ -1004,8 +938,7 @@ u8 disable = FALSE; u8 update = FALSE; - debug ("process_changeinstatus - Entry pslot[%lx], poldslot[%lx]\n", (ulong) pslot, - (ulong) poldslot); + debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot); // bit 0 - HPC_SLOT_POWER if ((pslot->status & 0x01) != (poldslot->status & 0x01)) diff -Nru a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c --- a/drivers/pci/hotplug/ibmphp_res.c Fri Jun 27 14:20:01 2003 +++ b/drivers/pci/hotplug/ibmphp_res.c Fri Jun 27 14:20:01 2003 @@ -42,7 +42,7 @@ static int update_bridge_ranges (struct bus_node **); static int add_range (int type, struct range_node *, struct bus_node *); static void fix_resources (struct bus_node *); -static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); +static struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); static LIST_HEAD(gbuses); LIST_HEAD(ibmphp_res_head); @@ -1757,7 +1757,7 @@ return find_bus_wprev (bus_number, NULL, 0); } -static inline struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag) +static struct bus_node *find_bus_wprev (u8 bus_number, struct bus_node **prev, u8 flag) { struct bus_node *bus_cur; struct list_head *tmp; diff -Nru a/drivers/pci/hotplug/pci_hotplug.h b/drivers/pci/hotplug/pci_hotplug.h --- a/drivers/pci/hotplug/pci_hotplug.h Fri Jun 27 14:19:55 2003 +++ b/drivers/pci/hotplug/pci_hotplug.h Fri Jun 27 14:19:55 2003 @@ -51,6 +51,8 @@ ssize_t (*show)(struct hotplug_slot *, char *); ssize_t (*store)(struct hotplug_slot *, const char *, size_t); }; +#define to_hotplug_attr(n) container_of(n, struct hotplug_slot_attribute, attr); + /** * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use * @owner: The module owner of this structure @@ -130,12 +132,14 @@ char *name; struct hotplug_slot_ops *ops; struct hotplug_slot_info *info; + void (*release) (struct hotplug_slot *slot); void *private; /* Variables below this are for use only by the hotplug pci core. */ struct list_head slot_list; struct kobject kobj; }; +#define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj) extern int pci_hp_register (struct hotplug_slot *slot); extern int pci_hp_deregister (struct hotplug_slot *slot); diff -Nru a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c --- a/drivers/pci/hotplug/pci_hotplug_core.c Fri Jun 27 14:20:00 2003 +++ b/drivers/pci/hotplug/pci_hotplug_core.c Fri Jun 27 14:20:00 2003 @@ -74,20 +74,16 @@ static ssize_t hotplug_slot_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { - struct hotplug_slot *slot=container_of(kobj, - struct hotplug_slot,kobj); - struct hotplug_slot_attribute *attribute = - container_of(attr, struct hotplug_slot_attribute, attr); + struct hotplug_slot *slot = to_hotplug_slot(kobj); + struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr); return attribute->show ? attribute->show(slot, buf) : 0; } static ssize_t hotplug_slot_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len) { - struct hotplug_slot *slot=container_of(kobj, - struct hotplug_slot,kobj); - struct hotplug_slot_attribute *attribute = - container_of(attr, struct hotplug_slot_attribute, attr); + struct hotplug_slot *slot = to_hotplug_slot(kobj); + struct hotplug_slot_attribute *attribute = to_hotplug_attr(attr); return attribute->store ? attribute->store(slot, buf, len) : 0; } @@ -96,8 +92,16 @@ .store = hotplug_slot_attr_store, }; +static void hotplug_slot_release(struct kobject *kobj) +{ + struct hotplug_slot *slot = to_hotplug_slot(kobj); + if (slot->release) + slot->release(slot); +} + static struct kobj_type hotplug_slot_ktype = { - .sysfs_ops = &hotplug_slot_sysfs_ops + .sysfs_ops = &hotplug_slot_sysfs_ops, + .release = &hotplug_slot_release, }; static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL); diff -Nru a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c --- a/drivers/pci/hotplug/pcihp_skeleton.c Fri Jun 27 14:19:57 2003 +++ b/drivers/pci/hotplug/pcihp_skeleton.c Fri Jun 27 14:19:57 2003 @@ -1,8 +1,8 @@ /* - * PCI Hot Plug Controller Skeleton Driver - 0.1 + * PCI Hot Plug Controller Skeleton Driver - 0.2 * - * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (c) 2001 IBM Corp. + * Copyright (c) 2001,2003 Greg Kroah-Hartman (greg@kroah.com) + * Copyright (c) 2001,2003 IBM Corp. * * All rights reserved. * @@ -69,7 +69,7 @@ static int debug; static int num_slots; -#define DRIVER_VERSION "0.1" +#define DRIVER_VERSION "0.2" #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>" #define DRIVER_DESC "Hot Plug PCI Controller Skeleton Driver" @@ -288,6 +288,21 @@ return retval; } +static void release_slots(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval = 0; + + if (slot == NULL) + return -ENODEV; + + dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); + kfree(slot->hotplug_slot->info); + kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); +} + #define SLOT_NAME_SIZE 10 static void make_slot_name (struct slot *slot) { @@ -347,6 +362,7 @@ slot->number = i; hotplug_slot->private = slot; + hotplug_slot->release = &release_slot; make_slot_name (slot); hotplug_slot->ops = &skel_hotplug_slot_ops; @@ -376,27 +392,23 @@ return retval; } - -static void cleanup_slots (void) + +static void cleanup_slots(void) { struct list_head *tmp; + struct list_head *next; struct slot *slot; /* - * Unregister all of our slots with the pci_hotplug subsystem, - * and free up all memory that we had allocated. + * Unregister all of our slots with the pci_hotplug subsystem. + * Memory will be freed in release_slot() callback after slot's + * lifespan is finished. */ - list_for_each (tmp, &slot_list) { + list_for_each_safe (tmp, next, &slot_list) { slot = list_entry (tmp, struct slot, slot_list); list_del (&slot->slot_list); pci_hp_deregister (slot->hotplug_slot); - kfree (slot->hotplug_slot->info); - kfree (slot->hotplug_slot->name); - kfree (slot->hotplug_slot); - kfree (slot); } - - return; } static int __init pcihp_skel_init(void) diff -Nru a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c --- a/drivers/pci/hotplug.c Fri Jun 27 14:20:04 2003 +++ b/drivers/pci/hotplug.c Fri Jun 27 14:20:04 2003 @@ -12,7 +12,6 @@ static void pci_free_resources(struct pci_dev *dev); -#ifdef CONFIG_HOTPLUG int pci_hotplug (struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { @@ -209,16 +208,6 @@ } EXPORT_SYMBOL(pci_remove_device_safe); -#else /* CONFIG_HOTPLUG */ - -int pci_hotplug (struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) -{ - return -ENODEV; -} - -#endif /* CONFIG_HOTPLUG */ - static void pci_free_resources(struct pci_dev *dev) { @@ -283,7 +272,5 @@ } } -#ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_remove_bus_device); EXPORT_SYMBOL(pci_remove_behind_bridge); -#endif diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c --- a/drivers/pci/pci-driver.c Fri Jun 27 14:19:59 2003 +++ b/drivers/pci/pci-driver.c Fri Jun 27 14:19:59 2003 @@ -486,6 +486,14 @@ put_device(&dev->dev); } +#ifndef CONFIG_HOTPLUG +int pci_hotplug (struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + return -ENODEV; +} +#endif + struct bus_type pci_bus_type = { .name = "pci", .match = pci_bus_match, diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Fri Jun 27 14:19:54 2003 +++ b/drivers/pci/pci.c Fri Jun 27 14:19:54 2003 @@ -747,6 +747,7 @@ EXPORT_SYMBOL(isa_bridge); #endif +EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_disable_device); EXPORT_SYMBOL(pci_max_busnr); diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c --- a/drivers/pci/probe.c Fri Jun 27 14:19:59 2003 +++ b/drivers/pci/probe.c Fri Jun 27 14:19:59 2003 @@ -18,7 +18,10 @@ #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ #define CARDBUS_RESERVE_BUSNR 3 +/* Ugh. Need to stop exporting this to modules. */ LIST_HEAD(pci_root_buses); +EXPORT_SYMBOL(pci_root_buses); + LIST_HEAD(pci_devices); /* @@ -106,7 +109,7 @@ (((unsigned long) ~sz) << 32); #else if (l) { - printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", dev->slot_name); + printk(KERN_ERR "PCI: Unable to handle 64-bit address for device %s\n", pci_name(dev)); res->start = 0; res->flags = 0; continue; @@ -301,7 +304,7 @@ pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); DBG("Scanning behind PCI bridge %s, config %06x, pass %d\n", - dev->slot_name, buses & 0xffffff, pass); + pci_name(dev), buses & 0xffffff, pass); if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus) { unsigned int cmax; @@ -400,8 +403,9 @@ { u32 class; - sprintf(dev->slot_name, "%02x:%02x.%d", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + dev->slot_name = dev->dev.bus_id; + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus), + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); sprintf(dev->dev.name, "PCI device %04x:%04x", dev->vendor, dev->device); @@ -449,12 +453,12 @@ default: /* unknown header */ printk(KERN_ERR "PCI: device %s has unknown header type %02x, ignoring.\n", - dev->slot_name, dev->hdr_type); + pci_name(dev), dev->hdr_type); return -1; bad: printk(KERN_ERR "PCI: %s: class %x doesn't match header type %02x. Ignoring class.\n", - dev->slot_name, class, dev->hdr_type); + pci_name(dev), class, dev->hdr_type); dev->class = PCI_CLASS_NOT_DEFINED; } @@ -528,9 +532,6 @@ pci_name_device(dev); - /* now put in global tree */ - sprintf(dev->dev.bus_id, "%04x:%s", pci_domain_nr(bus), - dev->slot_name); dev->dev.dma_mask = &dev->dma_mask; return dev; @@ -643,7 +644,7 @@ return 0; } -static struct pci_bus * __devinit pci_alloc_primary_bus_parented(struct device *parent, int bus) +struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { struct pci_bus *b; @@ -656,46 +657,39 @@ b = pci_alloc_bus(); if (!b) return NULL; - + b->dev = kmalloc(sizeof(*(b->dev)),GFP_KERNEL); if (!b->dev){ kfree(b); return NULL; } - + + b->sysdata = sysdata; + b->ops = ops; + list_add_tail(&b->node, &pci_root_buses); memset(b->dev,0,sizeof(*(b->dev))); - sprintf(b->dev->bus_id,"pci%d",bus); - strcpy(b->dev->name,"Host/PCI Bridge"); b->dev->parent = parent; + sprintf(b->dev->bus_id,"pci%04x:%02x", pci_domain_nr(b), bus); + strcpy(b->dev->name,"Host/PCI Bridge"); device_register(b->dev); b->number = b->secondary = bus; b->resource[0] = &ioport_resource; b->resource[1] = &iomem_resource; - return b; -} -struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) -{ - struct pci_bus *b = pci_alloc_primary_bus_parented(parent, bus); - if (b) { - b->sysdata = sysdata; - b->ops = ops; - b->subordinate = pci_scan_child_bus(b); - pci_bus_add_devices(b); - } + b->subordinate = pci_scan_child_bus(b); + + pci_bus_add_devices(b); + return b; } EXPORT_SYMBOL(pci_scan_bus_parented); -EXPORT_SYMBOL(pci_root_buses); - #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pci_add_new_bus); EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_scan_slot); -EXPORT_SYMBOL(pci_scan_bus); EXPORT_SYMBOL(pci_scan_bridge); #endif diff -Nru a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/pcmcia/au1000_generic.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,702 @@ +/* + * + * Alchemy Semi Au1000 pcmcia driver + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/config.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/tqueue.h> +#include <linux/timer.h> +#include <linux/mm.h> +#include <linux/proc_fs.h> +#include <linux/version.h> +#include <linux/types.h> +#include <linux/vmalloc.h> + +#include <pcmcia/version.h> +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/ss.h> +#include <pcmcia/bulkmem.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/bus_ops.h> +#include "cs_internal.h" + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> + +#include <asm/au1000.h> +#include <asm/au1000_pcmcia.h> + +#ifdef PCMCIA_DEBUG +static int pc_debug; +#endif + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>"); +MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller"); + +#define MAP_SIZE 0x1000000 + +/* This structure maintains housekeeping state for each socket, such + * as the last known values of the card detect pins, or the Card Services + * callback value associated with the socket: + */ +static struct au1000_pcmcia_socket *pcmcia_socket; +static int socket_count; + + +/* Returned by the low-level PCMCIA interface: */ +static struct pcmcia_low_level *pcmcia_low_level; + +/* Event poll timer structure */ +static struct timer_list poll_timer; + + +/* Prototypes for routines which are used internally: */ + +static int au1000_pcmcia_driver_init(void); +static void au1000_pcmcia_driver_shutdown(void); +static void au1000_pcmcia_task_handler(void *data); +static void au1000_pcmcia_poll_event(unsigned long data); +static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs); +static struct tq_struct au1000_pcmcia_task; + +#ifdef CONFIG_PROC_FS +static int au1000_pcmcia_proc_status(char *buf, char **start, + off_t pos, int count, int *eof, void *data); +#endif + + +/* Prototypes for operations which are exported to the + * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core: + */ + +static int au1000_pcmcia_init(u32 sock); +static int au1000_pcmcia_suspend(u32 sock); +static int au1000_pcmcia_register_callback(u32 sock, + void (*handler)(void *, u32), void *info); +static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap); +static int au1000_pcmcia_get_status(u32 sock, u_int *value); +static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state); +static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state); +static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io); +static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io); +static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem); +static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem); +#ifdef CONFIG_PROC_FS +static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base); +#endif + +static struct pccard_operations au1000_pcmcia_operations = { + au1000_pcmcia_init, + au1000_pcmcia_suspend, + au1000_pcmcia_register_callback, + au1000_pcmcia_inquire_socket, + au1000_pcmcia_get_status, + au1000_pcmcia_get_socket, + au1000_pcmcia_set_socket, + au1000_pcmcia_get_io_map, + au1000_pcmcia_set_io_map, + au1000_pcmcia_get_mem_map, + au1000_pcmcia_set_mem_map, +#ifdef CONFIG_PROC_FS + au1000_pcmcia_proc_setup +#endif +}; + +static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED; + +static int __init au1000_pcmcia_driver_init(void) +{ + servinfo_t info; + struct pcmcia_init pcmcia_init; + struct pcmcia_state state; + unsigned int i; + + printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE); + +#ifndef CONFIG_64BIT_PHYS_ADDR + printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n"); + return -1; +#endif + + CardServices(GetCardServicesInfo, &info); + + if(info.Revision!=CS_RELEASE_CODE){ + printk(KERN_ERR "Card Services release codes do not match\n"); + return -1; + } + +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) + pcmcia_low_level=&pb1x00_pcmcia_ops; +#else +#error Unsupported AU1000 board. +#endif + + pcmcia_init.handler=au1000_pcmcia_interrupt; + if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) { + printk(KERN_ERR "Unable to initialize PCMCIA service.\n"); + return -EIO; + } + + /* NOTE: the chip select must already be setup */ + + pcmcia_socket = + kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, + GFP_KERNEL); + if (!pcmcia_socket) { + printk(KERN_ERR "Card Services can't get memory \n"); + return -1; + } + memset(pcmcia_socket, 0, + sizeof(struct au1000_pcmcia_socket) * socket_count); + + /* + * Assuming max of 2 sockets, which the Au1000 supports. + * WARNING: the Pb1000 has two sockets, and both work, but you + * can't use them both at the same time due to glue logic conflicts. + */ + for(i=0; i < socket_count; i++) { + + if(pcmcia_low_level->socket_state(i, &state)<0){ + printk(KERN_ERR "Unable to get PCMCIA status\n"); + return -EIO; + } + pcmcia_socket[i].k_state=state; + pcmcia_socket[i].cs_state.csc_mask=SS_DETECT; + + if (i == 0) { + pcmcia_socket[i].virt_io = + (u32)ioremap((ioaddr_t)0xF00000000, 0x1000); + pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000; + pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000; + } + else { + pcmcia_socket[i].virt_io = + (u32)ioremap((ioaddr_t)0xF08000000, 0x1000); + pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000; + pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000; + } + } + + /* Only advertise as many sockets as we can detect: */ + if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){ + printk(KERN_ERR "Unable to register socket service routine\n"); + return -ENXIO; + } + + /* Start the event poll timer. + * It will reschedule by itself afterwards. + */ + au1000_pcmcia_poll_event(0); + + DEBUG(1, "au1000: initialization complete\n"); + return 0; + +} /* au1000_pcmcia_driver_init() */ + +module_init(au1000_pcmcia_driver_init); + +static void __exit au1000_pcmcia_driver_shutdown(void) +{ + int i; + + del_timer_sync(&poll_timer); + unregister_ss_entry(&au1000_pcmcia_operations); + pcmcia_low_level->shutdown(); + flush_scheduled_tasks(); + for(i=0; i < socket_count; i++) { + if (pcmcia_socket[i].virt_io) + iounmap((void *)pcmcia_socket[i].virt_io); + } + DEBUG(1, "au1000: shutdown complete\n"); +} + +module_exit(au1000_pcmcia_driver_shutdown); + +static int au1000_pcmcia_init(unsigned int sock) { return 0; } + +static int au1000_pcmcia_suspend(unsigned int sock) +{ + return 0; +} + + +static inline unsigned +au1000_pcmcia_events(struct pcmcia_state *state, + struct pcmcia_state *prev_state, + unsigned int mask, unsigned int flags) +{ + unsigned int events=0; + + if(state->detect!=prev_state->detect){ + DEBUG(2, "%s(): card detect value %u\n", + __FUNCTION__, state->detect); + events |= mask&SS_DETECT; + } + + + if(state->ready!=prev_state->ready){ + DEBUG(2, "%s(): card ready value %u\n", + __FUNCTION__, state->ready); + events |= mask&((flags&SS_IOCARD)?0:SS_READY); + } + + *prev_state=*state; + return events; + +} /* au1000_pcmcia_events() */ + + +/* + * Au1000_pcmcia_task_handler() + * Processes socket events. + */ +static void au1000_pcmcia_task_handler(void *data) +{ + struct pcmcia_state state; + int i, events, irq_status; + + for(i=0; i<socket_count; i++) { + if((irq_status = pcmcia_low_level->socket_state(i, &state))<0) + printk(KERN_ERR "low-level PCMCIA error\n"); + + events = au1000_pcmcia_events(&state, + &pcmcia_socket[i].k_state, + pcmcia_socket[i].cs_state.csc_mask, + pcmcia_socket[i].cs_state.flags); + if(pcmcia_socket[i].handler!=NULL) { + pcmcia_socket[i].handler(pcmcia_socket[i].handler_info, + events); + } + } + +} /* au1000_pcmcia_task_handler() */ + +static struct tq_struct au1000_pcmcia_task = { + routine: au1000_pcmcia_task_handler +}; + + +static void au1000_pcmcia_poll_event(unsigned long dummy) +{ + poll_timer.function = au1000_pcmcia_poll_event; + poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD; + add_timer(&poll_timer); + schedule_task(&au1000_pcmcia_task); +} + + +/* + * au1000_pcmcia_interrupt() + * The actual interrupt work is performed by au1000_pcmcia_task(), + * because the Card Services event handling code performs scheduling + * operations which cannot be executed from within an interrupt context. + */ +static void +au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs) +{ + schedule_task(&au1000_pcmcia_task); +} + + +static int +au1000_pcmcia_register_callback(unsigned int sock, + void (*handler)(void *, unsigned int), void *info) +{ + if(handler==NULL){ + pcmcia_socket[sock].handler=NULL; + MOD_DEC_USE_COUNT; + } else { + MOD_INC_USE_COUNT; + pcmcia_socket[sock].handler=handler; + pcmcia_socket[sock].handler_info=info; + } + return 0; +} + + +/* au1000_pcmcia_inquire_socket() + * + * From the sa1100 socket driver : + * + * Implements the inquire_socket() operation for the in-kernel PCMCIA + * service (formerly SS_InquireSocket in Card Services). We set + * SS_CAP_STATIC_MAP, which disables the memory resource database check. + * (Mapped memory is set up within the socket driver itself.) + * + * In conjunction with the STATIC_MAP capability is a new field, + * `io_offset', recommended by David Hinds. Rather than go through + * the SetIOMap interface (which is not quite suited for communicating + * window locations up from the socket driver), we just pass up + * an offset which is applied to client-requested base I/O addresses + * in alloc_io_space(). + * + * Returns: 0 on success, -1 if no pin has been configured for `sock' + */ +static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap) +{ + struct pcmcia_irq_info irq_info; + + if(sock > socket_count){ + printk(KERN_ERR "au1000: socket %u not configured\n", sock); + return -1; + } + + /* from the sa1100_generic driver: */ + + /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the + * force_low argument to validate_mem() in rsrc_mgr.c -- since in + * general, the mapped * addresses of the PCMCIA memory regions + * will not be within 0xffff, setting force_low would be + * undesirable. + * + * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory + * resource database; we instead pass up physical address ranges + * and allow other parts of Card Services to deal with remapping. + * + * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but + * not 32-bit CardBus devices. + */ + cap->features=(SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD); + + irq_info.sock=sock; + irq_info.irq=-1; + + if(pcmcia_low_level->get_irq_info(&irq_info)<0){ + printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock); + return -1; + } + + cap->irq_mask=0; + cap->map_size=MAP_SIZE; + cap->pci_irq=irq_info.irq; + cap->io_offset=pcmcia_socket[sock].virt_io; + + return 0; + +} /* au1000_pcmcia_inquire_socket() */ + + +static int +au1000_pcmcia_get_status(unsigned int sock, unsigned int *status) +{ + struct pcmcia_state state; + + + if((pcmcia_low_level->socket_state(sock, &state))<0){ + printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n"); + return -1; + } + + pcmcia_socket[sock].k_state = state; + + *status = state.detect?SS_DETECT:0; + + *status |= state.ready?SS_READY:0; + + *status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0; + + if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD) + *status |= state.bvd1?SS_STSCHG:0; + else { + if(state.bvd1==0) + *status |= SS_BATDEAD; + else if(state.bvd2 == 0) + *status |= SS_BATWARN; + } + + *status|=state.vs_3v?SS_3VCARD:0; + + *status|=state.vs_Xv?SS_XVCARD:0; + + DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n", + (*status&SS_DETECT)?"DETECT ":"", + (*status&SS_READY)?"READY ":"", + (*status&SS_BATDEAD)?"BATDEAD ":"", + (*status&SS_BATWARN)?"BATWARN ":"", + (*status&SS_POWERON)?"POWERON ":"", + (*status&SS_STSCHG)?"STSCHG ":"", + (*status&SS_3VCARD)?"3VCARD ":"", + (*status&SS_XVCARD)?"XVCARD ":""); + + return 0; + +} /* au1000_pcmcia_get_status() */ + + +static int +au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state) +{ + *state = pcmcia_socket[sock].cs_state; + return 0; +} + + +static int +au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state) +{ + struct pcmcia_configure configure; + + DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n" + "\tVcc %d Vpp %d irq %d\n", + (state->csc_mask==0)?"<NONE>":"", + (state->csc_mask&SS_DETECT)?"DETECT ":"", + (state->csc_mask&SS_READY)?"READY ":"", + (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", + (state->csc_mask&SS_BATWARN)?"BATWARN ":"", + (state->csc_mask&SS_STSCHG)?"STSCHG ":"", + (state->flags==0)?"<NONE>":"", + (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", + (state->flags&SS_IOCARD)?"IOCARD ":"", + (state->flags&SS_RESET)?"RESET ":"", + (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", + (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"", + state->Vcc, state->Vpp, state->io_irq); + + configure.sock=sock; + configure.vcc=state->Vcc; + configure.vpp=state->Vpp; + configure.output=(state->flags&SS_OUTPUT_ENA)?1:0; + configure.speaker=(state->flags&SS_SPKR_ENA)?1:0; + configure.reset=(state->flags&SS_RESET)?1:0; + + if(pcmcia_low_level->configure_socket(&configure)<0){ + printk(KERN_ERR "Unable to configure socket %u\n", sock); + return -1; + } + + pcmcia_socket[sock].cs_state = *state; + return 0; + +} /* au1000_pcmcia_set_socket() */ + + +static int +au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map) +{ + DEBUG(1, "au1000_pcmcia_get_io_map: sock %d\n", sock); + if(map->map>=MAX_IO_WIN){ + printk(KERN_ERR "%s(): map (%d) out of range\n", + __FUNCTION__, map->map); + return -1; + } + *map=pcmcia_socket[sock].io_map[map->map]; + return 0; +} + + +int +au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) +{ + unsigned int speed; + unsigned long start; + + if(map->map>=MAX_IO_WIN){ + printk(KERN_ERR "%s(): map (%d) out of range\n", + __FUNCTION__, map->map); + return -1; + } + + if(map->flags&MAP_ACTIVE){ + speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED; + pcmcia_socket[sock].speed_io=speed; + } + + start=map->start; + + if(map->stop==1) { + map->stop=PAGE_SIZE-1; + } + + map->start=pcmcia_socket[sock].virt_io; + map->stop=map->start+(map->stop-start); + pcmcia_socket[sock].io_map[map->map]=*map; + DEBUG(3, "set_io_map %d start %x stop %x\n", + map->map, map->start, map->stop); + return 0; + +} /* au1000_pcmcia_set_io_map() */ + + +static int +au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map) +{ + + if(map->map>=MAX_WIN) { + printk(KERN_ERR "%s(): map (%d) out of range\n", + __FUNCTION__, map->map); + return -1; + } + *map=pcmcia_socket[sock].mem_map[map->map]; + return 0; +} + + +static int +au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map) +{ + unsigned int speed; + unsigned long start; + u_long flags; + + if(map->map>=MAX_WIN){ + printk(KERN_ERR "%s(): map (%d) out of range\n", + __FUNCTION__, map->map); + return -1; + } + + if(map->flags&MAP_ACTIVE){ + speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED; + + /* TBD */ + if(map->flags&MAP_ATTRIB){ + pcmcia_socket[sock].speed_attr=speed; + } + else { + pcmcia_socket[sock].speed_mem=speed; + } + } + + spin_lock_irqsave(&pcmcia_lock, flags); + start=map->sys_start; + + if(map->sys_stop==0) + map->sys_stop=MAP_SIZE-1; + + if (map->flags & MAP_ATTRIB) { + map->sys_start = pcmcia_socket[sock].phys_attr + + map->card_start; + } + else { + map->sys_start = pcmcia_socket[sock].phys_mem + + map->card_start; + } + + map->sys_stop=map->sys_start+(map->sys_stop-start); + pcmcia_socket[sock].mem_map[map->map]=*map; + spin_unlock_irqrestore(&pcmcia_lock, flags); + DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n", + map->map, map->sys_start, map->sys_stop, + map->card_start); + return 0; + +} /* au1000_pcmcia_set_mem_map() */ + + +#if defined(CONFIG_PROC_FS) + +static void +au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) +{ + struct proc_dir_entry *entry; + + if((entry=create_proc_entry("status", 0, base))==NULL){ + printk(KERN_ERR "Unable to install \"status\" procfs entry\n"); + return; + } + + entry->read_proc=au1000_pcmcia_proc_status; + entry->data=(void *)sock; +} + + +/* au1000_pcmcia_proc_status() + * Implements the /proc/bus/pccard/??/status file. + * + * Returns: the number of characters added to the buffer + */ +static int +au1000_pcmcia_proc_status(char *buf, char **start, off_t pos, + int count, int *eof, void *data) +{ + char *p=buf; + unsigned int sock=(unsigned int)data; + + p+=sprintf(p, "k_flags : %s%s%s%s%s%s%s\n", + pcmcia_socket[sock].k_state.detect?"detect ":"", + pcmcia_socket[sock].k_state.ready?"ready ":"", + pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"", + pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"", + pcmcia_socket[sock].k_state.wrprot?"wrprot ":"", + pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"", + pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":""); + + p+=sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n", + pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"", + pcmcia_socket[sock].k_state.ready?"SS_READY ":"", + pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"", + pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\ + "SS_IOCARD ":"", + (pcmcia_socket[sock].cs_state.flags&SS_IOCARD && + pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"", + ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 && + (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"", + ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 && + (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"", + pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"", + pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":""); + + p+=sprintf(p, "mask : %s%s%s%s%s\n", + pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\ + "SS_DETECT ":"", + pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\ + "SS_READY ":"", + pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\ + "SS_BATDEAD ":"", + pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\ + "SS_BATWARN ":"", + pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\ + "SS_STSCHG ":""); + + p+=sprintf(p, "cs_flags : %s%s%s%s%s\n", + pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\ + "SS_PWR_AUTO ":"", + pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\ + "SS_IOCARD ":"", + pcmcia_socket[sock].cs_state.flags&SS_RESET?\ + "SS_RESET ":"", + pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\ + "SS_SPKR_ENA ":"", + pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\ + "SS_OUTPUT_ENA ":""); + + p+=sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc); + p+=sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp); + p+=sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq); + p+=sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io); + p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr); + p+=sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem); + return p-buf; +} + + +#endif /* defined(CONFIG_PROC_FS) */ diff -Nru a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/pcmcia/au1000_pb1x00.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,411 @@ +/* + * + * Alchemy Semi Pb1x00 boards specific pcmcia routines. + * + * Copyright 2002 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/kernel.h> +#include <linux/tqueue.h> +#include <linux/timer.h> +#include <linux/mm.h> +#include <linux/proc_fs.h> +#include <linux/version.h> +#include <linux/types.h> + +#include <pcmcia/version.h> +#include <pcmcia/cs_types.h> +#include <pcmcia/cs.h> +#include <pcmcia/ss.h> +#include <pcmcia/bulkmem.h> +#include <pcmcia/cistpl.h> +#include <pcmcia/bus_ops.h> +#include "cs_internal.h" + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> + +#include <asm/au1000.h> +#include <asm/au1000_pcmcia.h> + +#ifdef CONFIG_MIPS_PB1000 +#include <asm/pb1000.h> +#define PCMCIA_IRQ AU1000_GPIO_15 +#elif defined (CONFIG_MIPS_PB1500) +#include <asm/pb1500.h> +#define PCMCIA_IRQ AU1000_GPIO_11 /* fixme */ +#elif defined (CONFIG_MIPS_PB1100) +#include <asm/pb1100.h> +#define PCMCIA_IRQ AU1000_GPIO_11 +#endif + +static int pb1x00_pcmcia_init(struct pcmcia_init *init) +{ +#ifdef CONFIG_MIPS_PB1000 + u16 pcr; + pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; + + au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */ + au_sync_delay(100); + au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */ + au_sync(); + + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); + au_writel(pcr, PB1000_PCR); + au_sync_delay(20); + + return PCMCIA_NUM_SOCKS; + +#else /* fixme -- take care of the Pb1500 at some point */ + + u16 pcr; + pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */ + pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); + au_writew(pcr, PB1100_MEM_PCMCIA); + au_sync_delay(500); + return PCMCIA_NUM_SOCKS; +#endif +} + +static int pb1x00_pcmcia_shutdown(void) +{ +#ifdef CONFIG_MIPS_PB1000 + u16 pcr; + pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); + au_writel(pcr, PB1000_PCR); + au_sync_delay(20); + return 0; +#else + u16 pcr; + pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */ + pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); + au_writew(pcr, PB1100_MEM_PCMCIA); + au_sync_delay(2); + return 0; +#endif +} + +static int +pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) +{ + u32 inserted0, inserted1; + u16 vs0, vs1; + +#ifdef CONFIG_MIPS_PB1000 + vs0 = vs1 = (u16)au_readl(PB1000_ACR1); + inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2)); + inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2)); + vs0 = (vs0 >> 4) & 0x3; + vs1 = (vs1 >> 12) & 0x3; +#else + vs0 = (au_readw(PB1100_BOARD_STATUS) >> 4) & 0x3; + inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */ +#endif + + state->ready = 0; + state->vs_Xv = 0; + state->vs_3v = 0; + state->detect = 0; + + if (sock == 0) { + if (inserted0) { + switch (vs0) { + case 0: + case 2: + state->vs_3v=1; + break; + case 3: /* 5V */ + break; + default: + /* return without setting 'detect' */ + printk(KERN_ERR "pb1x00 bad VS (%d)\n", + vs0); + return; + } + state->detect = 1; + } + } + else { + if (inserted1) { + switch (vs1) { + case 0: + case 2: + state->vs_3v=1; + break; + case 3: /* 5V */ + break; + default: + /* return without setting 'detect' */ + printk(KERN_ERR "pb1x00 bad VS (%d)\n", + vs1); + return; + } + state->detect = 1; + } + } + + if (state->detect) { + state->ready = 1; + } + + state->bvd1=1; + state->bvd2=1; + state->wrprot=0; + return 1; +} + + +static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info) +{ + + if(info->sock > PCMCIA_MAX_SOCK) return -1; + + /* + * Even in the case of the Pb1000, both sockets are connected + * to the same irq line. + */ + info->irq = PCMCIA_IRQ; + + return 0; +} + + +static int +pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) +{ + u16 pcr; + + if(configure->sock > PCMCIA_MAX_SOCK) return -1; + +#ifdef CONFIG_MIPS_PB1000 + pcr = au_readl(PB1000_PCR); + + if (configure->sock == 0) { + pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 | + PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1); + } + else { + pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 | + PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1); + } + + pcr &= ~PCR_SLOT_0_RST; + DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x\n", + configure->vcc, configure->vpp, pcr); + switch(configure->vcc){ + case 0: /* Vcc 0 */ + switch(configure->vpp) { + case 0: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND, + configure->sock); + break; + case 12: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V, + configure->sock); + break; + case 50: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V, + configure->sock); + break; + case 33: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V, + configure->sock); + break; + default: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, + configure->sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + case 50: /* Vcc 5V */ + switch(configure->vpp) { + case 0: + pcr |= SET_VCC_VPP(VCC_5V,VPP_GND, + configure->sock); + break; + case 50: + pcr |= SET_VCC_VPP(VCC_5V,VPP_5V, + configure->sock); + break; + case 12: + pcr |= SET_VCC_VPP(VCC_5V,VPP_12V, + configure->sock); + break; + case 33: + pcr |= SET_VCC_VPP(VCC_5V,VPP_3V, + configure->sock); + break; + default: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, + configure->sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + case 33: /* Vcc 3.3V */ + switch(configure->vpp) { + case 0: + pcr |= SET_VCC_VPP(VCC_3V,VPP_GND, + configure->sock); + break; + case 50: + pcr |= SET_VCC_VPP(VCC_3V,VPP_5V, + configure->sock); + break; + case 12: + pcr |= SET_VCC_VPP(VCC_3V,VPP_12V, + configure->sock); + break; + case 33: + pcr |= SET_VCC_VPP(VCC_3V,VPP_3V, + configure->sock); + break; + default: + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, + configure->sock); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + default: /* what's this ? */ + pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock); + printk(KERN_ERR "%s: bad Vcc %d\n", + __FUNCTION__, configure->vcc); + break; + } + + if (configure->sock == 0) { + pcr &= ~(PCR_SLOT_0_RST); + if (configure->reset) + pcr |= PCR_SLOT_0_RST; + } + else { + pcr &= ~(PCR_SLOT_1_RST); + if (configure->reset) + pcr |= PCR_SLOT_1_RST; + } + au_writel(pcr, PB1000_PCR); + au_sync_delay(300); + +#else + + pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; + + DEBUG(KERN_INFO "Vcc %dV Vpp %dV, pcr %x, reset %d\n", + configure->vcc, configure->vpp, pcr, configure->reset); + + + switch(configure->vcc){ + case 0: /* Vcc 0 */ + pcr |= SET_VCC_VPP(0,0); + break; + case 50: /* Vcc 5V */ + switch(configure->vpp) { + case 0: + pcr |= SET_VCC_VPP(2,0); + break; + case 50: + pcr |= SET_VCC_VPP(2,1); + break; + case 12: + pcr |= SET_VCC_VPP(2,2); + break; + case 33: + default: + pcr |= SET_VCC_VPP(0,0); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + case 33: /* Vcc 3.3V */ + switch(configure->vpp) { + case 0: + pcr |= SET_VCC_VPP(1,0); + break; + case 12: + pcr |= SET_VCC_VPP(1,2); + break; + case 33: + pcr |= SET_VCC_VPP(1,1); + break; + case 50: + default: + pcr |= SET_VCC_VPP(0,0); + printk("%s: bad Vcc/Vpp (%d:%d)\n", + __FUNCTION__, + configure->vcc, + configure->vpp); + break; + } + break; + default: /* what's this ? */ + pcr |= SET_VCC_VPP(0,0); + printk(KERN_ERR "%s: bad Vcc %d\n", + __FUNCTION__, configure->vcc); + break; + } + + au_writew(pcr, PB1100_MEM_PCMCIA); + au_sync_delay(300); + + if (!configure->reset) { + pcr |= PB1100_PC_DRV_EN; + au_writew(pcr, PB1100_MEM_PCMCIA); + au_sync_delay(100); + pcr |= PB1100_PC_DEASSERT_RST; + au_writew(pcr, PB1100_MEM_PCMCIA); + au_sync_delay(100); + } + else { + pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN); + au_writew(pcr, PB1100_MEM_PCMCIA); + au_sync_delay(100); + } +#endif + return 0; +} + +struct pcmcia_low_level pb1x00_pcmcia_ops = { + pb1x00_pcmcia_init, + pb1x00_pcmcia_shutdown, + pb1x00_pcmcia_socket_state, + pb1x00_pcmcia_get_irq_info, + pb1x00_pcmcia_configure_socket +}; diff -Nru a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h --- a/drivers/pcmcia/ti113x.h Fri Jun 27 14:19:55 2003 +++ b/drivers/pcmcia/ti113x.h Fri Jun 27 14:19:55 2003 @@ -175,6 +175,27 @@ new = reg & ~I365_INTR_ENA; if (new != reg) exca_writeb(socket, I365_INTCTL, new); + + /* + * If ISA interrupts don't work, then fall back to routing card + * interrupts to the PCI interrupt of the socket. + */ + if (!socket->socket.irq_mask) { + int irqmux, devctl; + + printk (KERN_INFO "ti113x: Routing card interrupts to PCI\n"); + + devctl = config_readb(socket, TI113X_DEVICE_CONTROL); + devctl &= ~TI113X_DCR_IMODE_MASK; + + irqmux = config_readl(socket, TI122X_IRQMUX); + irqmux = (irqmux & ~0x0f) | 0x02; /* route INTA */ + irqmux = (irqmux & ~0xf0) | 0x20; /* route INTB */ + + config_writel(socket, TI122X_IRQMUX, irqmux); + config_writeb(socket, TI113X_DEVICE_CONTROL, devctl); + } + socket->socket.ss_entry->init = ti_init; return 0; } @@ -239,6 +260,17 @@ ti113x_override(socket); socket->socket.ss_entry->init = ti1250_init; return 0; +} + + +static int ti12xx_override(struct yenta_socket *socket) +{ + /* make sure that memory burst is active */ + ti_sysctl(socket) = config_readl(socket, TI113X_SYSTEM_CONTROL); + ti_sysctl(socket) |= TI122X_SCR_MRBURSTUP; + config_writel(socket, TI113X_SYSTEM_CONTROL, ti_sysctl(socket)); + + return ti113x_override(socket); } #endif /* CONFIG_CARDBUS */ diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c --- a/drivers/pcmcia/yenta_socket.c Fri Jun 27 14:19:58 2003 +++ b/drivers/pcmcia/yenta_socket.c Fri Jun 27 14:19:58 2003 @@ -807,22 +807,29 @@ unsigned short device; int (*override) (struct yenta_socket *socket); } cardbus_override[] = { - { PD(TI,1130), &ti113x_override }, { PD(TI,1031), &ti_override }, - { PD(TI,1131), &ti113x_override }, - { PD(TI,1250), &ti1250_override }, - { PD(TI,1220), &ti_override }, - { PD(TI,1221), &ti_override }, + + /* TBD: Check if these TI variants can use more + * advanced overrides instead */ { PD(TI,1210), &ti_override }, - { PD(TI,1450), &ti_override }, - { PD(TI,1225), &ti_override }, - { PD(TI,1251A), &ti_override }, { PD(TI,1211), &ti_override }, + { PD(TI,1251A), &ti_override }, { PD(TI,1251B), &ti_override }, - { PD(TI,1410), ti1250_override }, { PD(TI,1420), &ti_override }, + { PD(TI,1450), &ti_override }, { PD(TI,4410), &ti_override }, { PD(TI,4451), &ti_override }, + + { PD(TI,1130), &ti113x_override }, + { PD(TI,1131), &ti113x_override }, + + { PD(TI,1220), &ti12xx_override }, + { PD(TI,1221), &ti12xx_override }, + { PD(TI,1225), &ti12xx_override }, + { PD(TI,1520), &ti12xx_override }, + + { PD(TI,1250), &ti1250_override }, + { PD(TI,1410), &ti1250_override }, { PD(RICOH,RL5C465), &ricoh_override }, { PD(RICOH,RL5C466), &ricoh_override }, diff -Nru a/drivers/pnp/interface.c b/drivers/pnp/interface.c --- a/drivers/pnp/interface.c Fri Jun 27 14:19:53 2003 +++ b/drivers/pnp/interface.c Fri Jun 27 14:19:53 2003 @@ -323,14 +323,14 @@ if (!strnicmp(buf,"auto",4)) { if (dev->active) goto done; - pnp_init_resources(&dev->res); + pnp_init_resource_table(&dev->res); retval = pnp_auto_config_dev(dev); goto done; } if (!strnicmp(buf,"clear",5)) { if (dev->active) goto done; - pnp_init_resources(&dev->res); + pnp_init_resource_table(&dev->res); goto done; } if (!strnicmp(buf,"get",3)) { @@ -345,7 +345,7 @@ if (dev->active) goto done; buf += 3; - pnp_init_resources(&dev->res); + pnp_init_resource_table(&dev->res); down(&pnp_res_mutex); while (1) { while (isspace(*buf)) diff -Nru a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c --- a/drivers/pnp/isapnp/core.c Fri Jun 27 14:19:57 2003 +++ b/drivers/pnp/isapnp/core.c Fri Jun 27 14:19:57 2003 @@ -458,7 +458,7 @@ dev->capabilities |= PNP_READ; dev->capabilities |= PNP_WRITE; dev->capabilities |= PNP_DISABLE; - pnp_init_resources(&dev->res); + pnp_init_resource_table(&dev->res); return dev; } @@ -1020,7 +1020,7 @@ static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table * res) { int ret; - pnp_init_resources(res); + pnp_init_resource_table(res); isapnp_cfg_begin(dev->card->number, dev->number); ret = isapnp_read_resources(dev, res); isapnp_cfg_end(); diff -Nru a/drivers/pnp/manager.c b/drivers/pnp/manager.c --- a/drivers/pnp/manager.c Fri Jun 27 14:20:04 2003 +++ b/drivers/pnp/manager.c Fri Jun 27 14:20:04 2003 @@ -190,10 +190,9 @@ * @table: pointer to the desired resource table * */ -void pnp_init_resources(struct pnp_resource_table *table) +void pnp_init_resource_table(struct pnp_resource_table *table) { int idx; - down(&pnp_res_mutex); for (idx = 0; idx < PNP_MAX_IRQ; idx++) { table->irq_resource[idx].name = NULL; table->irq_resource[idx].start = -1; @@ -218,7 +217,6 @@ table->mem_resource[idx].end = 0; table->mem_resource[idx].flags = IORESOURCE_AUTO; } - up(&pnp_res_mutex); } /** @@ -226,7 +224,7 @@ * @res - the resources to clean * */ -static void pnp_clean_resources(struct pnp_resource_table * res) +static void pnp_clean_resource_table(struct pnp_resource_table * res) { int idx; for (idx = 0; idx < PNP_MAX_IRQ; idx++) { @@ -278,7 +276,7 @@ return -ENODEV; down(&pnp_res_mutex); - pnp_clean_resources(&dev->res); /* start with a fresh slate */ + pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ if (dev->independent) { port = dev->independent->port; mem = dev->independent->mem; @@ -351,7 +349,7 @@ return 1; fail: - pnp_clean_resources(&dev->res); + pnp_clean_resource_table(&dev->res); up(&pnp_res_mutex); return 0; } @@ -510,7 +508,7 @@ /* release the resources so that other devices can use them */ down(&pnp_res_mutex); - pnp_clean_resources(&dev->res); + pnp_clean_resource_table(&dev->res); up(&pnp_res_mutex); return 1; @@ -539,4 +537,4 @@ EXPORT_SYMBOL(pnp_activate_dev); EXPORT_SYMBOL(pnp_disable_dev); EXPORT_SYMBOL(pnp_resource_change); -EXPORT_SYMBOL(pnp_init_resources); +EXPORT_SYMBOL(pnp_init_resource_table); diff -Nru a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c --- a/drivers/pnp/pnpbios/core.c Fri Jun 27 14:19:52 2003 +++ b/drivers/pnp/pnpbios/core.c Fri Jun 27 14:19:52 2003 @@ -937,7 +937,7 @@ /* clear out the damaged flags */ if (!dev->active) - pnp_init_resources(&dev->res); + pnp_init_resource_table(&dev->res); pnp_add_device(dev); pnpbios_interface_attach_device(node); diff -Nru a/drivers/pnp/resource.c b/drivers/pnp/resource.c --- a/drivers/pnp/resource.c Fri Jun 27 14:19:57 2003 +++ b/drivers/pnp/resource.c Fri Jun 27 14:19:57 2003 @@ -85,7 +85,6 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { - int i; struct pnp_irq *ptr; if (!option) return -EINVAL; @@ -101,9 +100,13 @@ option->irq = data; #ifdef CONFIG_PCI - for (i=0; i<16; i++) - if (data->map & (1<<i)) - pcibios_penalize_isa_irq(i); + { + int i; + + for (i=0; i<16; i++) + if (data->map & (1<<i)) + pcibios_penalize_isa_irq(i); + } #endif return 0; } diff -Nru a/drivers/pnp/support.c b/drivers/pnp/support.c --- a/drivers/pnp/support.c Fri Jun 27 14:19:54 2003 +++ b/drivers/pnp/support.c Fri Jun 27 14:19:54 2003 @@ -123,7 +123,7 @@ return NULL; /* Blank the resource table values */ - pnp_init_resources(res); + pnp_init_resource_table(res); while ((char *)p < (char *)end) { diff -Nru a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c --- a/drivers/s390/block/dasd.c Fri Jun 27 14:19:56 2003 +++ b/drivers/s390/block/dasd.c Fri Jun 27 14:19:56 2003 @@ -7,7 +7,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * - * $Revision: 1.99 $ + * $Revision: 1.101 $ */ #include <linux/config.h> @@ -32,7 +32,7 @@ /* * SECTION: Constant definitions to be used within this file */ -#define DASD_CHANQ_MAX_SIZE 5 +#define DASD_CHANQ_MAX_SIZE 4 /* * SECTION: exported variables of dasd.c @@ -803,24 +803,18 @@ * 2) delayed start of request where start_IO failed with -EBUSY * 3) timeout for missing state change interrupts * The head of the ccw queue will have status DASD_CQR_IN_IO for 1), - * DASD_CQR_QUEUED for 2) and DASD_CQR_PENDING for 3). + * DASD_CQR_QUEUED for 2) and 3). */ static void dasd_timeout_device(unsigned long ptr) { unsigned long flags; struct dasd_device *device; - struct dasd_ccw_req *cqr; device = (struct dasd_device *) ptr; spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); /* re-activate first request in queue */ - if (!list_empty(&device->ccw_queue)) { - cqr = list_entry(device->ccw_queue.next, - struct dasd_ccw_req, list); - if (cqr->status == DASD_CQR_PENDING) - cqr->status = DASD_CQR_QUEUED; - } + device->stopped &= ~DASD_STOPPED_PENDING; spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); dasd_schedule_bh(device); } @@ -861,10 +855,6 @@ /* * Handles the state change pending interrupt. - * Search for the device related request queue and check if the first - * cqr in queue in in status 'DASD_CQR_PENDING'. - * If so the status is set to 'DASD_CQR_QUEUED' to reactivate - * the device. */ static void do_state_change_pending(void *data) @@ -874,29 +864,12 @@ struct dasd_device *device; } *p; struct dasd_device *device; - struct dasd_ccw_req *cqr; p = data; device = p->device; DBF_EVENT(DBF_NOTICE, "State change Interrupt for bus_id %s", device->cdev->dev.bus_id); - - spin_lock_irq(get_ccwdev_lock(device->cdev)); - /* re-activate first request in queue */ - if (!list_empty(&device->ccw_queue)) { - cqr = list_entry(device->ccw_queue.next, - struct dasd_ccw_req, list); - if (cqr == NULL) { - MESSAGE (KERN_DEBUG, - "got state change pending interrupt on" - "an idle device: bus_id %s", - device->cdev->dev.bus_id); - return; - } - if (cqr->status == DASD_CQR_PENDING) - cqr->status = DASD_CQR_QUEUED; - } - spin_unlock_irq(get_ccwdev_lock(device->cdev)); + device->stopped &= ~DASD_STOPPED_PENDING; dasd_schedule_bh(device); dasd_put_device(device); kfree(p); @@ -1036,7 +1009,8 @@ if (cqr->list.next != &device->ccw_queue) { next = list_entry(cqr->list.next, struct dasd_ccw_req, list); - if (next->status == DASD_CQR_QUEUED) { + if ((next->status == DASD_CQR_QUEUED) && + (!device->stopped)) { if (device->discipline->start_IO(next) == 0) expires = next->expires; else @@ -1264,7 +1238,8 @@ if (list_empty(&device->ccw_queue)) return; cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); - if (cqr->status == DASD_CQR_QUEUED) { + if ((cqr->status == DASD_CQR_QUEUED) && + (!device->stopped)) { /* try to start the first I/O that can be started */ rc = device->discipline->start_IO(cqr); if (rc == 0) diff -Nru a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c --- a/drivers/s390/block/dasd_3990_erp.c Fri Jun 27 14:20:00 2003 +++ b/drivers/s390/block/dasd_3990_erp.c Fri Jun 27 14:20:01 2003 @@ -5,7 +5,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 * - * $Revision: 1.24 $ + * $Revision: 1.25 $ */ #include <linux/timer.h> @@ -221,13 +221,6 @@ * Block the given device request queue to prevent from further * processing until the started timer has expired or an related * interrupt was received. - * - * PARAMETER - * erp request to be blocked - * expires time to wait until restart (in jiffies) - * - * RETURN VALUES - * void */ static void dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) @@ -238,7 +231,9 @@ DEV_MESSAGE(KERN_INFO, device, "blocking request queue for %is", expires); - erp->status = DASD_CQR_PENDING; + device->stopped |= DASD_STOPPED_PENDING; + erp->status = DASD_CQR_QUEUED; + dasd_set_timer(device, expires); } @@ -453,9 +448,11 @@ if (sense[25] == 0x1D) { /* state change pending */ - DEV_MESSAGE(KERN_INFO, device, "%s", - "waiting for state change pending " "int"); - + DEV_MESSAGE(KERN_INFO, device, + "waiting for state change pending " + "interrupt, %d retries left", + erp->retries); + dasd_3990_erp_block_queue(erp, 30*HZ); } else { diff -Nru a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c --- a/drivers/s390/block/dasd_eckd.c Fri Jun 27 14:19:30 2003 +++ b/drivers/s390/block/dasd_eckd.c Fri Jun 27 14:19:30 2003 @@ -7,7 +7,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.42 $ + * $Revision: 1.46 $ */ #include <linux/config.h> @@ -80,7 +80,13 @@ static int dasd_eckd_probe (struct ccw_device *cdev) { - return dasd_generic_probe (cdev, &dasd_eckd_discipline); + int ret; + + ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); + if (ret) + return ret; + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + return 0; } static int @@ -204,7 +210,7 @@ data->ep_sys_time = get_clock (); de_ccw->count = sizeof (struct DE_eckd_data); - de_ccw->flags = CCW_FLAG_SLI; + de_ccw->flags |= CCW_FLAG_SLI; } return; @@ -281,19 +287,11 @@ /* check for sequential prestage - enhance cylinder range */ if (data->attributes.operation == DASD_SEQ_PRESTAGE || data->attributes.operation == DASD_SEQ_ACCESS) { - - if (end.cyl + private->attrib.nr_cyl < geo.cyl) { + + if (end.cyl + private->attrib.nr_cyl < geo.cyl) end.cyl += private->attrib.nr_cyl; - DBF_DEV_EVENT(DBF_NOTICE, device, - "Enhanced DE Cylinder from %x to %x", - (totrk / geo.head), end.cyl); - } else { + else end.cyl = (geo.cyl - 1); - DBF_DEV_EVENT(DBF_NOTICE, device, - "Enhanced DE Cylinder from %x to " - "End of device %x", - (totrk / geo.head), end.cyl); - } } data->beg_ext.cyl = beg.cyl; @@ -512,12 +510,6 @@ private->rdc_data.cu_type, private->rdc_data.cu_model.model); return 0; - - /* get characteristis via diag to determine the kind of - * minidisk under VM needed beacause XRC is not support - * by VM (jet). Can be removed as soon as VM supports XRC - * FIXME: TBD ??? HUM - */ } static struct dasd_ccw_req * @@ -1130,13 +1122,16 @@ return -ENODEV; cqr = dasd_smalloc_request(dasd_eckd_discipline.name, - 1, 0, device); + 1, 32, device); if (cqr == NULL) { MESSAGE(KERN_WARNING, "%s", "No memory to allocate initialization request"); return -ENOMEM; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE; + cqr->cpaddr->flags |= CCW_FLAG_SLI; + cqr->cpaddr->count = 32; + cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->device = device; cqr->retries = 0; cqr->expires = 10 * HZ; @@ -1145,14 +1140,14 @@ rc = dasd_sleep_on_immediatly(cqr); - dasd_kfree_request(cqr, cqr->device); + dasd_sfree_request(cqr, cqr->device); return rc; } /* * Reserve device ioctl. * Options are set to 'synchronous wait for interrupt' and - * 'timeout the request'. This leads to an terminate IO if + * 'timeout the request'. This leads to a terminate IO if * the interrupt is outstanding for a certain time. */ static int @@ -1170,14 +1165,16 @@ return -ENODEV; cqr = dasd_smalloc_request(dasd_eckd_discipline.name, - 1, 0, device); - + 1, 32, device); if (cqr == NULL) { MESSAGE(KERN_WARNING, "%s", "No memory to allocate initialization request"); return -ENOMEM; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE; + cqr->cpaddr->flags |= CCW_FLAG_SLI; + cqr->cpaddr->count = 32; + cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->device = device; cqr->retries = 0; cqr->expires = 10 * HZ; @@ -1186,11 +1183,7 @@ rc = dasd_sleep_on_immediatly(cqr); - if (rc == -EIO) { - /* Request got an error or has been timed out. */ - dasd_eckd_release(bdev, no, args); - } - dasd_kfree_request(cqr, cqr->device); + dasd_sfree_request(cqr, cqr->device); return rc; } @@ -1214,13 +1207,16 @@ return -ENODEV; cqr = dasd_smalloc_request(dasd_eckd_discipline.name, - 1, 0, device); + 1, 32, device); if (cqr == NULL) { MESSAGE(KERN_WARNING, "%s", "No memory to allocate initialization request"); return -ENOMEM; } cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK; + cqr->cpaddr->flags |= CCW_FLAG_SLI; + cqr->cpaddr->count = 32; + cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; cqr->device = device; cqr->retries = 0; cqr->expires = 10 * HZ; @@ -1229,11 +1225,7 @@ rc = dasd_sleep_on_immediatly(cqr); - if (rc == -EIO) { - /* Request got an error or has been timed out. */ - dasd_eckd_release(bdev, no, args); - } - dasd_kfree_request(cqr, cqr->device); + dasd_sfree_request(cqr, cqr->device); return rc; } @@ -1330,17 +1322,13 @@ private = (struct dasd_eckd_private *) device->private; - DBF_DEV_EVENT(DBF_ERR, device, - "cache operation mode got " - "%x (%i cylinder prestage)", - attrib.operation, attrib.nr_cyl); - private->attrib = attrib; DBF_DEV_EVENT(DBF_ERR, device, "cache operation mode set to " "%x (%i cylinder prestage)", private->attrib.operation, private->attrib.nr_cyl); + return 0; } diff -Nru a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c --- a/drivers/s390/block/dasd_erp.c Fri Jun 27 14:19:53 2003 +++ b/drivers/s390/block/dasd_erp.c Fri Jun 27 14:19:53 2003 @@ -7,7 +7,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 * - * $Revision: 1.9 $ + * $Revision: 1.10 $ */ #include <linux/config.h> @@ -86,48 +86,31 @@ atomic_dec(&device->ref_count); } + /* - * DESCRIPTION - * sets up the default-ERP struct dasd_ccw_req, namely one, which performs - * a TIC to the original channel program with a retry counter of 16 - * - * PARAMETER - * cqr failed CQR - * - * RETURN VALUES - * erp CQR performing the ERP + * dasd_default_erp_action just retries the current cqr */ struct dasd_ccw_req * dasd_default_erp_action(struct dasd_ccw_req * cqr) { struct dasd_device *device; - struct dasd_ccw_req *erp; - MESSAGE(KERN_DEBUG, "%s", "Default ERP called... "); device = cqr->device; - erp = dasd_alloc_erp_request((char *) &cqr->magic, 1, 0, device); - if (IS_ERR(erp)) { - DEV_MESSAGE(KERN_ERR, device, "%s", - "Unable to allocate request for default ERP"); - cqr->status = DASD_CQR_FAILED; - cqr->stopclk = get_clock(); - return cqr; - } - - erp->cpaddr->cmd_code = CCW_CMD_TIC; - erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr; - erp->function = dasd_default_erp_action; - erp->refers = cqr; - erp->device = device; - erp->magic = cqr->magic; - erp->retries = 16; - erp->status = DASD_CQR_FILLED; - - list_add(&erp->list, &device->ccw_queue); - erp->status = DASD_CQR_QUEUED; - - return erp; + /* just retry - there is nothing to save ... I got no sense data.... */ + if (cqr->retries > 0) { + DEV_MESSAGE (KERN_DEBUG, device, + "default ERP called (%i retries left)", + cqr->retries); + cqr->status = DASD_CQR_QUEUED; + } else { + DEV_MESSAGE (KERN_WARNING, device, "%s", + "default ERP called (NO retry left)"); + + cqr->status = DASD_CQR_FAILED; + cqr->stopclk = get_clock (); + } + return cqr; } /* end dasd_default_erp_action */ /* diff -Nru a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c --- a/drivers/s390/block/dasd_fba.c Fri Jun 27 14:19:59 2003 +++ b/drivers/s390/block/dasd_fba.c Fri Jun 27 14:19:59 2003 @@ -4,7 +4,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.29 $ + * $Revision: 1.30 $ */ #include <linux/config.h> @@ -57,7 +57,13 @@ static int dasd_fba_probe(struct ccw_device *cdev) { - return dasd_generic_probe (cdev, &dasd_fba_discipline); + int ret; + + ret = dasd_generic_probe (cdev, &dasd_fba_discipline); + if (ret) + return ret; + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + return 0; } static int diff -Nru a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h --- a/drivers/s390/block/dasd_int.h Fri Jun 27 14:19:59 2003 +++ b/drivers/s390/block/dasd_int.h Fri Jun 27 14:19:59 2003 @@ -6,7 +6,7 @@ * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * - * $Revision: 1.40 $ + * $Revision: 1.42 $ */ #ifndef DASD_INT_H @@ -188,7 +188,6 @@ #define DASD_CQR_DONE 0x03 /* request is completed successfully */ #define DASD_CQR_ERROR 0x04 /* request is completed with error */ #define DASD_CQR_FAILED 0x05 /* request is finally failed */ -#define DASD_CQR_PENDING 0x06 /* request is waiting for interrupt - ERP only */ /* Signature for error recovery functions. */ typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); @@ -279,6 +278,7 @@ /* Device state and target state. */ int state, target; + int stopped; /* device (ccw_device_start) was stopped */ /* Open and reference count. */ atomic_t ref_count; @@ -305,6 +305,12 @@ struct dasd_profile_info_t profile; #endif }; + +/* reasons why device (ccw_device_start) was stopped */ +#define DASD_STOPPED_NOT_ACC 1 /* not accessible */ +#define DASD_STOPPED_QUIESCE 2 /* Quiesced */ +#define DASD_STOPPED_PENDING 4 /* long busy */ + void dasd_put_device_wake(struct dasd_device *); diff -Nru a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c --- a/drivers/s390/block/dasd_ioctl.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/block/dasd_ioctl.c Fri Jun 27 14:19:57 2003 @@ -169,6 +169,58 @@ } /* + * Quiesce device. + */ +static int +dasd_ioctl_quiesce(struct block_device *bdev, int no, long args) +{ + struct dasd_device *device; + unsigned long flags; + + if (!capable (CAP_SYS_ADMIN)) + return -EACCES; + + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "Quiesce IO on device"); + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); + device->stopped |= DASD_STOPPED_QUIESCE; + spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); + return 0; +} + + +/* + * Quiesce device. + */ +static int +dasd_ioctl_resume(struct block_device *bdev, int no, long args) +{ + struct dasd_device *device; + unsigned long flags; + + if (!capable (CAP_SYS_ADMIN)) + return -EACCES; + + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + + DEV_MESSAGE (KERN_DEBUG, device, "%s", + "resume IO on device"); + + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); + device->stopped &= ~DASD_STOPPED_QUIESCE; + spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); + + dasd_schedule_bh (device); + return 0; +} + +/* * performs formatting of _device_ according to _fdata_ * Note: The discipline's format_function is assumed to deliver formatting * commands to format a single unit of the device. In terms of the ECKD @@ -438,6 +490,8 @@ { { BIODASDDISABLE, dasd_ioctl_disable }, { BIODASDENABLE, dasd_ioctl_enable }, + { BIODASDQUIESCE, dasd_ioctl_quiesce }, + { BIODASDRESUME, dasd_ioctl_resume }, { BIODASDFMT, dasd_ioctl_format }, { BIODASDINFO, dasd_ioctl_information }, { BIODASDINFO2, dasd_ioctl_information }, diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c --- a/drivers/s390/block/xpram.c Fri Jun 27 14:19:59 2003 +++ b/drivers/s390/block/xpram.c Fri Jun 27 14:19:59 2003 @@ -487,7 +487,7 @@ unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); devfs_remove("slram"); sys_device_unregister(&xpram_sys_device); - sysdev_class_unregister(&xpram_sys_class); + sysdev_class_unregister(&xpram_sysclass); } static int __init xpram_init(void) @@ -511,7 +511,7 @@ rc = sys_device_register(&xpram_sys_device); if (rc) { - sysdev_class_unregister(&xpram_syclass); + sysdev_class_unregister(&xpram_sysclass); return rc; } rc = xpram_setup_blkdev(); diff -Nru a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c --- a/drivers/s390/char/con3215.c Fri Jun 27 14:19:59 2003 +++ b/drivers/s390/char/con3215.c Fri Jun 27 14:19:59 2003 @@ -1215,6 +1215,7 @@ return ret; } tty3215_driver = driver; + return 0; } static void __exit diff -Nru a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c --- a/drivers/s390/char/tape_core.c Fri Jun 27 14:19:54 2003 +++ b/drivers/s390/char/tape_core.c Fri Jun 27 14:19:54 2003 @@ -372,6 +372,8 @@ device->cdev = cdev; cdev->handler = tape_do_irq; + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + return 0; } @@ -903,7 +905,7 @@ { tape_dbf_area = debug_register ( "tape", 1, 2, 3*sizeof(long)); debug_register_view(tape_dbf_area, &debug_sprintf_view); - DBF_EVENT(3, "tape init: ($Revision: 1.25 $)\n"); + DBF_EVENT(3, "tape init: ($Revision: 1.26 $)\n"); tape_proc_init(); tapechar_init (); tapeblock_init (); @@ -928,7 +930,7 @@ MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and " "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)"); MODULE_DESCRIPTION("Linux on zSeries channel attached " - "tape device driver ($Revision: 1.25 $)"); + "tape device driver ($Revision: 1.26 $)"); module_init(tape_init); module_exit(tape_exit); diff -Nru a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c --- a/drivers/s390/cio/ccwgroup.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/cio/ccwgroup.c Fri Jun 27 14:19:57 2003 @@ -1,7 +1,7 @@ /* * drivers/s390/cio/ccwgroup.c * bus driver for ccwgroup - * $Revision: 1.6 $ + * $Revision: 1.7 $ * * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -196,10 +196,12 @@ value = simple_strtoul(buf, 0, 0); - if (value) + if (value == 1) ccwgroup_set_online(gdev); - else + else if (value == 0) ccwgroup_set_offline(gdev); + else + return -EINVAL; return count; } @@ -211,7 +213,7 @@ online = (to_ccwgroupdev(dev)->state == CCWGROUP_ONLINE); - return sprintf(buf, online ? "1\n" : "0\n"); + return sprintf(buf, online ? "yes\n" : "no\n"); } static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store); diff -Nru a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c --- a/drivers/s390/cio/chsc.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/cio/chsc.c Fri Jun 27 14:19:57 2003 @@ -1,7 +1,7 @@ /* * drivers/s390/cio/chsc.c * S/390 common I/O routines -- channel subsystem call - * $Revision: 1.69 $ + * $Revision: 1.73 $ * * Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -322,10 +322,6 @@ sprintf(dbf_txt, "chpr%x", chpid); CIO_TRACE_EVENT(2, dbf_txt); - /* - * TODO: the chpid may be not the chpid with the link incident, - * but the chpid the report came in through. How to handle??? - */ clear_bit(chpid, chpids); if (!test_and_clear_bit(chpid, chpids_known)) return; /* we didn't know the chpid anyway */ @@ -469,9 +465,40 @@ free_page((unsigned long)page); } +static int +__get_chpid_from_lir(void *data) +{ + struct lir { + u8 iq; + u8 ic; + u16 sci; + /* incident-node descriptor */ + u32 indesc[28]; + /* attached-node descriptor */ + u32 andesc[28]; + /* incident-specific information */ + u32 isinfo[28]; + } *lir; + + lir = (struct lir*) data; + if (!(lir->iq&0x80)) + /* NULL link incident record */ + return -EINVAL; + if (!(lir->indesc[0]&0xc0000000)) + /* node descriptor not valid */ + return -EINVAL; + if (!(lir->indesc[0]&0x10000000)) + /* don't handle device-type nodes - FIXME */ + return -EINVAL; + /* Byte 3 contains the chpid. Could also be CTCA, but we don't care */ + + return (u16) (lir->indesc[0]&0x000000ff); +} + static void do_process_crw(void *ignore) { + int chpid; struct { struct chsc_header request; u32 reserved1; @@ -487,10 +514,8 @@ u16 rsid; /* reporting source id */ u32 reserved5; u32 reserved6; - u32 ccdf; /* content-code dependent field */ - u32 reserved7; - u32 reserved8; - u32 reserved9; + u32 ccdf[96]; /* content-code dependent field */ + /* ccdf has to be big enough for a link-incident record */ } *sei_area; /* @@ -560,9 +585,14 @@ case 1: /* link incident*/ CIO_CRW_EVENT(4, "chsc_process_crw: " "channel subsystem reports link incident," - " source is chpid %x\n", sei_area->rsid); - - s390_set_chpid_offline(sei_area->rsid); + " reporting source is chpid %x\n", + sei_area->rsid); + chpid = __get_chpid_from_lir(sei_area->ccdf); + if (chpid < 0) + CIO_CRW_EVENT(4, "%s: Invalid LIR, skipping\n", + __FUNCTION__); + else + s390_set_chpid_offline(chpid); break; case 2: /* i/o resource accessibiliy */ diff -Nru a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h --- a/drivers/s390/cio/css.h Fri Jun 27 14:20:06 2003 +++ b/drivers/s390/cio/css.h Fri Jun 27 14:20:06 2003 @@ -72,9 +72,9 @@ struct { unsigned int fast:1; /* post with "channel end" */ unsigned int repall:1; /* report every interrupt status */ + unsigned int pgroup:1; /* do path grouping */ } __attribute__ ((packed)) options; struct { - unsigned int pgid_supp:1; /* "path group ID" supported */ unsigned int pgid_single:1; /* use single path for Set PGID */ unsigned int esid:1; /* Ext. SenseID supported by HW */ unsigned int dosense:1; /* delayed SENSE required */ diff -Nru a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c --- a/drivers/s390/cio/device.c Fri Jun 27 14:19:59 2003 +++ b/drivers/s390/cio/device.c Fri Jun 27 14:19:59 2003 @@ -1,7 +1,7 @@ /* * drivers/s390/cio/device.c * bus driver for ccw devices - * $Revision: 1.54 $ + * $Revision: 1.57 $ * * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation @@ -298,20 +298,19 @@ online_store (struct device *dev, const char *buf, size_t count) { struct ccw_device *cdev = to_ccwdev(dev); - unsigned int value; + int i; + char *tmp; if (!cdev->drv) return count; - sscanf(buf, "%u", &value); - - if (value) { - if (cdev->drv->set_online) - ccw_device_set_online(cdev); - } else { - if (cdev->drv->set_offline) - ccw_device_set_offline(cdev); - } + i = simple_strtoul(buf, &tmp, 16); + if (i == 0 && cdev->drv->set_online) + ccw_device_set_online(cdev); + else if (i == 1 && cdev->drv->set_offline) + ccw_device_set_offline(cdev); + else + return -EINVAL; return count; } @@ -405,11 +404,14 @@ * This allows to trigger an unconditional reserve ccw to eckd dasds * (if the device is something else, there should be no problems more than * a command reject; we don't have any means of finding out the device's - * type if it was boxed at ipl/attach). + * type if it was boxed at ipl/attach for older devices and under VM). */ void -ccw_device_add_stlck(struct ccw_device *cdev) +ccw_device_add_stlck(void *data) { + struct ccw_device *cdev; + + cdev = (struct ccw_device *)data; device_create_file(&cdev->dev, &dev_attr_steal_lock); } @@ -470,6 +472,8 @@ if (ret) printk(KERN_WARNING "%s: could not add attributes to %04x\n", __func__, sch->irq); + if (cdev->private->state == DEV_STATE_BOXED) + device_create_file(&cdev->dev, &dev_attr_steal_lock); out: put_device(&sch->dev); } @@ -493,6 +497,8 @@ if (cdev->dev.release) cdev->dev.release(&cdev->dev); break; + case DEV_STATE_BOXED: + /* Device did not respond in time. */ case DEV_STATE_OFFLINE: /* * We can't register the device in interrupt context so @@ -501,9 +507,6 @@ INIT_WORK(&cdev->private->kick_work, io_subchannel_register, (void *) cdev); queue_work(ccw_device_work, &cdev->private->kick_work); - break; - case DEV_STATE_BOXED: - /* Device did not respond in time. */ break; } if (atomic_dec_and_test(&ccw_device_init_count)) diff -Nru a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h --- a/drivers/s390/cio/device.h Fri Jun 27 14:20:00 2003 +++ b/drivers/s390/cio/device.h Fri Jun 27 14:20:00 2003 @@ -95,7 +95,7 @@ void ccw_device_call_handler(struct ccw_device *); -void ccw_device_add_stlck(struct ccw_device *); +void ccw_device_add_stlck(void *); int ccw_device_stlck(struct ccw_device *); /* qdio needs this. */ diff -Nru a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c --- a/drivers/s390/cio/device_fsm.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/cio/device_fsm.c Fri Jun 27 14:19:57 2003 @@ -132,11 +132,11 @@ CIO_DEBUG(KERN_WARNING, 2, "SenseID : boxed device %04X on subchannel %04X\n", sch->schib.pmcw.dev, sch->irq); - ccw_device_add_stlck(cdev); break; } io_subchannel_recog_done(cdev); - wake_up(&cdev->private->wait_q); + if (state != DEV_STATE_NOT_OPER) + wake_up(&cdev->private->wait_q); } /* @@ -159,22 +159,65 @@ } /* + * Finished with online/offline processing. + */ +static void +ccw_device_done(struct ccw_device *cdev, int state) +{ + struct subchannel *sch; + + sch = to_subchannel(cdev->dev.parent); + + if (state != DEV_STATE_ONLINE) + cio_disable_subchannel(sch); + + /* Reset device status. */ + memset(&cdev->private->irb, 0, sizeof(struct irb)); + + cdev->private->state = state; + + + if (state == DEV_STATE_BOXED) { + CIO_DEBUG(KERN_WARNING, 2, + "Boxed device %04X on subchannel %04X\n", + sch->schib.pmcw.dev, sch->irq); + INIT_WORK(&cdev->private->kick_work, + ccw_device_add_stlck, (void *) cdev); + queue_work(ccw_device_work, &cdev->private->kick_work); + } + + wake_up(&cdev->private->wait_q); + + if (state != DEV_STATE_ONLINE) + put_device (&cdev->dev); +} + +/* * Function called from device_pgid.c after sense path ground has completed. */ void ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) { + struct subchannel *sch; + + sch = to_subchannel(cdev->dev.parent); switch (err) { case 0: - cdev->private->state = DEV_STATE_SENSE_ID; - ccw_device_sense_id_start(cdev); + /* Start Path Group verification. */ + sch->vpm = 0; /* Start with no path groups set. */ + cdev->private->state = DEV_STATE_VERIFY; + ccw_device_verify_start(cdev); break; case -ETIME: /* Sense path group id stopped by timeout. */ case -EUSERS: /* device is reserved for someone else. */ - ccw_device_recog_done(cdev, DEV_STATE_BOXED); + ccw_device_done(cdev, DEV_STATE_BOXED); + break; + case -EOPNOTSUPP: /* path grouping not supported, just set online. */ + cdev->private->options.pgroup = 0; + ccw_device_done(cdev, DEV_STATE_ONLINE); break; default: - ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); + ccw_device_done(cdev, DEV_STATE_NOT_OPER); break; } } @@ -198,11 +241,15 @@ ccw_device_set_timeout(cdev, 60*HZ); /* - * First thing we should do is a sensePGID in order to find out how - * we can proceed with the recognition process. + * We used to start here with a sense pgid to find out whether a device + * is locked by someone else. Unfortunately, the sense pgid command + * code has other meanings on devices predating the path grouping + * algorithm, so we start with sense id and box the device after an + * timeout (or if sense pgid during path verification detects the device + * is locked, as may happen on newer devices). */ - cdev->private->state = DEV_STATE_SENSE_PGID; - ccw_device_sense_pgid_start(cdev); + cdev->private->state = DEV_STATE_SENSE_ID; + ccw_device_sense_id_start(cdev); return 0; } @@ -218,29 +265,6 @@ ccw_device_set_timeout(cdev, 3*HZ); } -/* - * Finished with online/offline processing. - */ -static void -ccw_device_done(struct ccw_device *cdev, int state) -{ - struct subchannel *sch; - - sch = to_subchannel(cdev->dev.parent); - - if (state != DEV_STATE_ONLINE) - cio_disable_subchannel(sch); - - /* Reset device status. */ - memset(&cdev->private->irb, 0, sizeof(struct irb)); - - cdev->private->state = state; - - wake_up(&cdev->private->wait_q); - - if (state != DEV_STATE_ONLINE) - put_device (&cdev->dev); -} void ccw_device_verify_done(struct ccw_device *cdev, int err) @@ -276,16 +300,15 @@ dev_fsm_event(cdev, DEV_EVENT_NOTOPER); return -ENODEV; } - /* Is Set Path Group supported? */ - if (!cdev->private->flags.pgid_supp) { + /* Do we want to do path grouping? */ + if (!cdev->private->options.pgroup) { /* No, set state online immediately. */ ccw_device_done(cdev, DEV_STATE_ONLINE); return 0; } - /* Start Path Group verification. */ - sch->vpm = 0; /* Start with no path groups set. */ - cdev->private->state = DEV_STATE_VERIFY; - ccw_device_verify_start(cdev); + /* Do a SensePGID first. */ + cdev->private->state = DEV_STATE_SENSE_PGID; + ccw_device_sense_pgid_start(cdev); return 0; } @@ -321,8 +344,8 @@ } if (sch->schib.scsw.actl != 0) return -EBUSY; - /* Is Set Path Group supported? */ - if (!cdev->private->flags.pgid_supp) { + /* Are we doing path grouping? */ + if (!cdev->private->options.pgroup) { /* No, set state offline immediately. */ ccw_device_done(cdev, DEV_STATE_OFFLINE); return 0; @@ -643,9 +666,9 @@ [DEV_EVENT_VERIFY] ccw_device_nop, }, [DEV_STATE_SENSE_PGID] { - [DEV_EVENT_NOTOPER] ccw_device_recog_notoper, + [DEV_EVENT_NOTOPER] ccw_device_online_notoper, [DEV_EVENT_INTERRUPT] ccw_device_sense_pgid_irq, - [DEV_EVENT_TIMEOUT] ccw_device_recog_timeout, + [DEV_EVENT_TIMEOUT] ccw_device_onoff_timeout, [DEV_EVENT_VERIFY] ccw_device_nop, }, [DEV_STATE_SENSE_ID] { diff -Nru a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c --- a/drivers/s390/cio/device_ops.c Fri Jun 27 14:19:59 2003 +++ b/drivers/s390/cio/device_ops.c Fri Jun 27 14:19:59 2003 @@ -37,6 +37,7 @@ return -EINVAL; cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0; cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0; + cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0; return 0; } diff -Nru a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c --- a/drivers/s390/cio/device_pgid.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/cio/device_pgid.c Fri Jun 27 14:19:57 2003 @@ -84,7 +84,6 @@ cdev->private->state = DEV_STATE_SENSE_PGID; cdev->private->imask = 0x80; cdev->private->iretry = 5; - cdev->private->flags.pgid_supp = 0; memset (&cdev->private->pgid, 0, sizeof (struct pgid)); ret = __ccw_device_sense_pgid_start(cdev); if (ret) @@ -165,14 +164,13 @@ switch (__ccw_device_check_sense_pgid(cdev)) { /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */ case 0: /* Sense Path Group ID successful. */ - cdev->private->flags.pgid_supp = 1; opm = sch->schib.pmcw.pim & sch->schib.pmcw.pam & sch->schib.pmcw.pom; for (i=0;i<8;i++) { if (opm == (0x80 << i)) { /* Don't group single path devices. */ - cdev->private->flags.pgid_supp = 0; + cdev->private->options.pgroup = 0; break; } } @@ -181,7 +179,7 @@ sizeof(struct pgid)); /* fall through. */ case -EOPNOTSUPP: /* Sense Path Group ID not supported */ - ccw_device_sense_pgid_done(cdev, 0); + ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP); break; case -ETIME: /* Sense path group id stopped by timeout. */ ccw_device_sense_pgid_done(cdev, -ETIME); diff -Nru a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h --- a/drivers/s390/cio/qdio.h Fri Jun 27 14:19:54 2003 +++ b/drivers/s390/cio/qdio.h Fri Jun 27 14:19:54 2003 @@ -1,7 +1,7 @@ #ifndef _CIO_QDIO_H #define _CIO_QDIO_H -#define VERSION_CIO_QDIO_H "$Revision: 1.16 $" +#define VERSION_CIO_QDIO_H "$Revision: 1.17 $" //#define QDIO_DBF_LIKE_HELL @@ -21,7 +21,15 @@ #define QDIO_TIMER_POLL_VALUE 1 #define IQDIO_TIMER_POLL_VALUE 1 -#define IQDIO_FILL_LEVEL_TO_POLL (QDIO_MAX_BUFFERS_PER_Q*4/3) +/* + * unfortunately this can't be (QDIO_MAX_BUFFERS_PER_Q*4/3) or so -- as + * we never know, whether we'll get initiative again, e.g. to give the + * transmit skb's back to the stack, however the stack may be waiting for + * them... therefore we define 4 as threshold to start polling (which + * will stop as soon as the asynchronous queue catches up) + * btw, this only applies to the asynchronous HiperSockets queue + */ +#define IQDIO_FILL_LEVEL_TO_POLL 4 #define IQDIO_THININT_ISC 3 #define IQDIO_DELAY_TARGET 0 diff -Nru a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c --- a/drivers/s390/net/ctcmain.c Fri Jun 27 14:19:55 2003 +++ b/drivers/s390/net/ctcmain.c Fri Jun 27 14:19:55 2003 @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.42 2003/05/23 17:45:57 felfert Exp $ + * $Id: ctcmain.c,v 1.43 2003/05/27 11:34:23 mschwide Exp $ * * CTC / ESCON network driver * @@ -36,7 +36,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.42 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.43 $ * */ @@ -272,7 +272,7 @@ print_banner(void) { static int printed = 0; - char vbuf[] = "$Revision: 1.42 $"; + char vbuf[] = "$Revision: 1.43 $"; char *version = vbuf; if (printed) @@ -2752,7 +2752,7 @@ dev->type = ARPHRD_SLIP; dev->tx_queue_len = 100; dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(&tun->dev); + SET_MODULE_OWNER(dev); return dev; } diff -Nru a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c --- a/drivers/s390/net/ctctty.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/net/ctctty.c Fri Jun 27 14:19:57 2003 @@ -1,5 +1,5 @@ /* - * $Id: ctctty.c,v 1.11 2003/05/06 09:40:55 mschwide Exp $ + * $Id: ctctty.c,v 1.12 2003/06/17 11:36:44 mschwide Exp $ * * CTC / ESCON network driver, tty interface. * diff -Nru a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c --- a/drivers/s390/net/lcs.c Fri Jun 27 14:19:53 2003 +++ b/drivers/s390/net/lcs.c Fri Jun 27 14:19:53 2003 @@ -11,7 +11,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Martin Schwidefsky <schwidefsky@de.ibm.com> * - * $Revision: 1.51 $ $Date: 2003/03/28 08:54:40 $ + * $Revision: 1.53 $ $Date: 2003/06/17 11:36:45 $ * * 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 @@ -58,7 +58,7 @@ /** * initialization string for output */ -#define VERSION_LCS_C "$Revision: 1.51 $" +#define VERSION_LCS_C "$Revision: 1.53 $" static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; @@ -1785,7 +1785,7 @@ dev->set_multicast_list = lcs_set_multicast_list; #endif dev->get_stats = lcs_getstats; - SET_MODULE_OWNER(&tun->dev); + SET_MODULE_OWNER(dev); if (register_netdev(dev) != 0) goto out; netif_stop_queue(dev); diff -Nru a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c --- a/drivers/s390/net/netiucv.c Fri Jun 27 14:19:57 2003 +++ b/drivers/s390/net/netiucv.c Fri Jun 27 14:19:57 2003 @@ -1,5 +1,5 @@ /* - * $Id: netiucv.c,v 1.19 2003/04/08 16:00:17 mschwide Exp $ + * $Id: netiucv.c,v 1.20 2003/05/27 11:34:24 mschwide Exp $ * * IUCV network driver * @@ -30,7 +30,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: IUCV network driver $Revision: 1.19 $ + * RELEASE-TAG: IUCV network driver $Revision: 1.20 $ * */ @@ -1631,7 +1631,7 @@ dev->type = ARPHRD_SLIP; dev->tx_queue_len = NETIUCV_QUEUELEN_DEFAULT; dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(&tun->dev); + SET_MODULE_OWNER(dev); return dev; } @@ -1717,7 +1717,7 @@ static void netiucv_banner(void) { - char vbuf[] = "$Revision: 1.19 $"; + char vbuf[] = "$Revision: 1.20 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Fri Jun 27 14:20:03 2003 +++ b/drivers/scsi/Kconfig Fri Jun 27 14:20:03 2003 @@ -1,3 +1,27 @@ +menu "SCSI device support" + +config SCSI + tristate "SCSI device support" + ---help--- + If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or + any other SCSI device under Linux, say Y and make sure that you know + the name of your SCSI host adapter (the card inside your computer + that "speaks" the SCSI protocol, also called SCSI controller), + because you will be asked for it. + + You also need to say Y here if you have a device which speaks + the SCSI protocol. Examples of this include the parallel port + version of the IOMEGA ZIP drive, USB storage devices, Fibre + Channel, FireWire storage and the IDE-SCSI emulation driver. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called scsi_mod. If you want to compile it as + a module, say M here and read <file:Documentation/modules.txt> and + <file:Documentation/scsi/scsi.txt>. However, do not compile this as a + module if your root file system (the one containing the directory /) + is located on a SCSI device. + comment "SCSI support type (disk, tape, CD-ROM)" depends on SCSI @@ -5,9 +29,10 @@ tristate "SCSI disk support" depends on SCSI ---help--- - If you want to use a SCSI hard disk or the SCSI or parallel port - version of the IOMEGA ZIP drive under Linux, say Y and read the - SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from + If you want to use SCSI hard disks, Fibre Channel disks, + USB storage or the SCSI or parallel port version of + the IOMEGA ZIP drive, say Y and read the SCSI-HOWTO, + the Disk-HOWTO and the Multi-Disk-HOWTO, available from <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI CD-ROMs. @@ -65,10 +90,10 @@ tristate "SCSI CDROM support" depends on SCSI ---help--- - If you want to use a SCSI CD-ROM under Linux, say Y and read the - SCSI-HOWTO and the CD-ROM-HOWTO at - <http://www.tldp.org/docs.html#howto>. Also make sure to say Y - or M to "ISO 9660 CD-ROM file system support" later. + If you want to use a SCSI or FireWire CD-ROM under Linux, + say Y and read the SCSI-HOWTO and the CDROM-HOWTO at + <http://www.tldp.org/docs.html#howto>. Also make sure to say + Y or M to "ISO 9660 CD-ROM file system support" later. This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). @@ -1823,3 +1848,4 @@ source "drivers/scsi/pcmcia/Kconfig" +endmenu diff -Nru a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c --- a/drivers/scsi/NCR53C9x.c Fri Jun 27 14:19:54 2003 +++ b/drivers/scsi/NCR53C9x.c Fri Jun 27 14:19:54 2003 @@ -893,7 +893,7 @@ int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int inout) { - struct NCR_ESP *esp = (struct NCR_ESP *) SCpnt->device->host->hostdata; + struct NCR_ESP *esp = (struct NCR_ESP *)shost->hostdata; if(inout) return -EINVAL; /* not yet */ diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c --- a/drivers/scsi/fd_mcs.c Fri Jun 27 14:19:55 2003 +++ b/drivers/scsi/fd_mcs.c Fri Jun 27 14:19:55 2003 @@ -589,7 +589,6 @@ static int fd_mcs_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout) { int len = 0; - int i; if (inout) return (-ENOSYS); diff -Nru a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c --- a/drivers/scsi/gdth.c Fri Jun 27 14:19:58 2003 +++ b/drivers/scsi/gdth.c Fri Jun 27 14:19:58 2003 @@ -3662,7 +3662,7 @@ pci_unmap_single(ha->pdev,scp->SCp.dma_handle, scp->request_bufflen,scp->SCp.Message); if (scp->SCp.buffer) - pci_unmap_single(ha->pdev,(dma_addr_t)(u32)scp->SCp.buffer, + pci_unmap_single(ha->pdev,(dma_addr_t)scp->SCp.buffer, 16,PCI_DMA_FROMDEVICE); #endif if (ha->status == S_OK) { diff -Nru a/drivers/serial/8250.c b/drivers/serial/8250.c --- a/drivers/serial/8250.c Fri Jun 27 14:19:52 2003 +++ b/drivers/serial/8250.c Fri Jun 27 14:19:52 2003 @@ -122,13 +122,13 @@ struct uart_port port; struct timer_list timer; /* "no irq" timer */ struct list_head list; /* ports on this IRQ */ + unsigned short rev; unsigned char acr; unsigned char ier; - unsigned char rev; unsigned char lcr; unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ - unsigned int lsr_break_flag; + unsigned char lsr_break_flag; /* * We provide a per-port pm hook. diff -Nru a/drivers/serial/8250_cs.c b/drivers/serial/8250_cs.c --- a/drivers/serial/8250_cs.c Fri Jun 27 14:19:56 2003 +++ b/drivers/serial/8250_cs.c Fri Jun 27 14:19:56 2003 @@ -2,7 +2,7 @@ A driver for PCMCIA serial devices - serial_cs.c 1.123 2000/08/24 18:46:38 + serial_cs.c 1.134 2002/05/04 05:48:53 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file @@ -43,7 +43,6 @@ #include <linux/serial.h> #include <linux/serial_core.h> #include <linux/major.h> -#include <linux/workqueue.h> #include <asm/io.h> #include <asm/system.h> @@ -59,7 +58,7 @@ static int pc_debug = PCMCIA_DEBUG; MODULE_PARM(pc_debug, "i"); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) -static char *version = "serial_cs.c 1.123 2000/08/24 18:46:38 (David Hinds)"; +static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)"; #else #define DEBUG(n, args...) #endif @@ -74,10 +73,13 @@ /* Enable the speaker? */ static int do_sound = 1; +/* Skip strict UART tests? */ +static int buggy_uart; MODULE_PARM(irq_mask, "i"); MODULE_PARM(irq_list, "1-4i"); MODULE_PARM(do_sound, "i"); +MODULE_PARM(buggy_uart, "i"); /*====================================================================*/ @@ -100,7 +102,7 @@ }; #define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id)) -typedef struct serial_info { +struct serial_info { dev_link_t link; int ndev; int multi; @@ -108,8 +110,7 @@ int manfid; dev_node_t node[4]; int line[4]; - struct work_struct remove; -} serial_info_t; +}; static void serial_config(dev_link_t * link); static int serial_event(event_t event, int priority, @@ -124,20 +125,19 @@ /*====================================================================== - After a card is removed, do_serial_release() will unregister + After a card is removed, serial_remove() will unregister the serial device(s), and release the PCMCIA configuration. ======================================================================*/ -/* - * This always runs in process context. - */ -static void do_serial_release(void *arg) +static void serial_remove(dev_link_t *link) { - struct serial_info *info = arg; - int i; + struct serial_info *info = link->priv; + int i, ret; - DEBUG(0, "serial_release(0x%p)\n", &info->link); + link->state &= ~DEV_PRESENT; + + DEBUG(0, "serial_release(0x%p)\n", link); /* * Recheck to see if the device is still configured. @@ -158,25 +158,6 @@ } } -/* - * This may be called from IRQ context. - */ -static void serial_remove(dev_link_t *link) -{ - struct serial_info *info = link->priv; - - link->state &= ~DEV_PRESENT; - - /* - * FIXME: Since the card has probably been removed, - * we should call into the serial layer and hang up - * the ports on the card immediately. - */ - - if (link->state & DEV_CONFIG) - schedule_work(&info->remove); -} - /*====================================================================== serial_attach() creates an "instance" of the driver, allocating @@ -187,7 +168,7 @@ static dev_link_t *serial_attach(void) { - serial_info_t *info; + struct serial_info *info; client_reg_t client_reg; dev_link_t *link; int i, ret; @@ -202,8 +183,6 @@ link = &info->link; link->priv = info; - INIT_WORK(&info->remove, do_serial_release, info); - link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts1 = 8; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; @@ -214,7 +193,6 @@ for (i = 0; i < 4; i++) link->irq.IRQInfo2 |= 1 << irq_list[i]; link->conf.Attributes = CONF_ENABLE_IRQ; - link->conf.Vcc = 50; if (do_sound) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; @@ -254,7 +232,7 @@ static void serial_detach(dev_link_t * link) { - serial_info_t *info = link->priv; + struct serial_info *info = link->priv; dev_link_t **linkp; int ret; @@ -275,7 +253,7 @@ /* * Ensure that the ports have been released. */ - do_serial_release(info); + serial_remove(link); if (link->handle) { ret = CardServices(DeregisterClient, link->handle); @@ -290,7 +268,7 @@ /*====================================================================*/ -static int setup_serial(serial_info_t * info, ioaddr_t port, int irq) +static int setup_serial(struct serial_info * info, ioaddr_t port, int irq) { struct serial_struct serial; int line; @@ -299,11 +277,13 @@ serial.port = port; serial.irq = irq; serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ; + if (buggy_uart) + serial.flags |= UPF_BUGGY_UART; line = register_serial(&serial); if (line < 0) { printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx," " irq %d failed\n", (u_long) serial.port, serial.irq); - return -1; + return -EINVAL; } info->line[info->ndev] = line; @@ -341,7 +321,7 @@ { static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; client_handle_t handle = link->handle; - serial_info_t *info = link->priv; + struct serial_info *info = link->priv; tuple_t tuple; u_char buf[256]; cisparse_t parse; @@ -445,13 +425,21 @@ static int multi_config(dev_link_t * link) { client_handle_t handle = link->handle; - serial_info_t *info = link->priv; + struct serial_info *info = link->priv; tuple_t tuple; u_char buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; + config_info_t config; int i, base2 = 0; + i = CardServices(GetConfigurationInfo, handle, &config); + if (i != CS_SUCCESS) { + cs_error(handle, GetConfigurationInfo, i); + return -1; + } + link->conf.Vcc = config.Vcc; + tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; @@ -524,6 +512,19 @@ return -1; } + /* The Oxford Semiconductor OXCF950 cards are in fact single-port: + 8 registers are for the UART, the others are extra registers */ + if (info->manfid == MANFID_OXSEMI) { + if (cf->index == 1 || cf->index == 3) { + setup_serial(info, base2, link->irq.AssignedIRQ); + outb(12, link->io.BasePort1 + 1); + } else { + setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); + outb(12, base2 + 1); + } + return 0; + } + setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) @@ -548,7 +549,7 @@ void serial_config(dev_link_t * link) { client_handle_t handle = link->handle; - serial_info_t *info = link->priv; + struct serial_info *info = link->priv; tuple_t tuple; u_short buf[128]; cisparse_t parse; @@ -631,7 +632,8 @@ cs_failed: cs_error(link->handle, last_fn, last_ret); failed: - do_serial_release(info); + serial_remove(link); + link->state &= ~DEV_CONFIG_PENDING; } /*====================================================================== @@ -647,7 +649,7 @@ serial_event(event_t event, int priority, event_callback_args_t * args) { dev_link_t *link = args->client_data; - serial_info_t *info = link->priv; + struct serial_info *info = link->priv; DEBUG(1, "serial_event(0x%06x)\n", event); diff -Nru a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c --- a/drivers/serial/8250_pci.c Fri Jun 27 14:20:00 2003 +++ b/drivers/serial/8250_pci.c Fri Jun 27 14:20:00 2003 @@ -322,7 +322,7 @@ * hope) because it doesn't touch EEPROM settings to prevent conflicts * with other OSes (like M$ DOS). * - * SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999 + * SIIG support added by Andrey Panin <pazke@donpac.ru>, 10/1999 * * There is two family of SIIG serial cards with different PCI * interface chip and different configuration methods: diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig --- a/drivers/serial/Kconfig Fri Jun 27 14:20:04 2003 +++ b/drivers/serial/Kconfig Fri Jun 27 14:20:04 2003 @@ -80,14 +80,14 @@ config SERIAL_8250_ACPI bool "8250/16550 device discovery via ACPI namespace" default y if IA64 - depends on ACPI_BUS + depends on ACPI_BUS && SERIAL_8250 ---help--- If you wish to enable serial port discovery via the ACPI namespace, say Y here. If unsure, say N. config SERIAL_8250_HCDP bool "8250/16550 device discovery support via EFI HCDP table" - depends on IA64 + depends on IA64 && SERIAL_8250 ---help--- If you wish to make the serial console port described by the EFI HCDP table available for use as serial console or general @@ -326,6 +326,14 @@ This driver supports the Zilog8530 serial ports found on many Sparc systems. Say Y or M if you want to be able to these serial ports. +config SERIAL_SUNZILOG_CONSOLE + bool "Console on Sun Zilog8530 serial port" + depends on SERIAL_SUNZILOG=y + help + If you would like to be able to use the Zilog8530 serial port + on your Sparc system as the console, you can do so by answering + Y to this option. + config SERIAL_SUNSU tristate "Sun SU serial support" depends on (SPARC32 || SPARC64) && PCI @@ -334,6 +342,14 @@ mouse on (PCI) UltraSPARC systems. Say Y or M if you want to be able to these serial ports. +config SERIAL_SUNSU_CONSOLE + bool "Console on Sun SU serial port" + depends on SERIAL_SUNSU=y + help + If you would like to be able to use the SU serial port + on your Sparc system as the console, you can do so by answering + Y to this option. + config SERIAL_MUX tristate "Serial MUX support" depends on PARISC @@ -380,6 +396,14 @@ (PCI) UltraSPARC systems. Say Y or M if you want to be able to these serial ports. +config SERIAL_SUNSAB_CONSOLE + bool "Console on Sun Siemens SAB82532 serial port" + depends on SERIAL_SUNSAB=y + help + If you would like to be able to use the SAB82532 serial port + on your Sparc system as the console, you can do so by answering + Y to this option. + config V850E_NB85E_UART bool "NEC V850E on-chip UART support" depends on V850E_NB85E || V850E2_ANNA || V850E_AS85EP1 @@ -407,7 +431,7 @@ config SERIAL_CORE_CONSOLE bool - depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNCORE || V850E_NB85E_UART_CONSOLE || SERIAL98_CONSOLE + depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_NB85E_UART_CONSOLE || SERIAL98_CONSOLE default y config SERIAL_68328 diff -Nru a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c --- a/drivers/serial/sunsab.c Fri Jun 27 14:19:55 2003 +++ b/drivers/serial/sunsab.c Fri Jun 27 14:19:55 2003 @@ -28,6 +28,7 @@ #include <linux/ioport.h> #include <linux/circ_buf.h> #include <linux/serial.h> +#include <linux/sysrq.h> #include <linux/console.h> #include <linux/spinlock.h> #include <linux/slab.h> @@ -38,6 +39,10 @@ #include <asm/oplib.h> #include <asm/ebus.h> +#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include <linux/serial_core.h> #include "suncore.h" @@ -838,6 +843,8 @@ static struct uart_sunsab_port *sunsab_ports; static int num_channels; +#ifdef CONFIG_SERIAL_SUNSAB_CONSOLE + static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char c) { unsigned long flags; @@ -929,6 +936,7 @@ .index = -1, .data = &sunsab_reg, }; +#define SUNSAB_CONSOLE (&sunsab_console) static void __init sunsab_console_init(void) { @@ -949,6 +957,10 @@ sunsab_console.index = i; register_console(&sunsab_console); } +#else +#define SUNSAB_CONSOLE (NULL) +#define sunsab_console_init() do { } while (0) +#endif static void __init for_each_sab_edev(void (*callback)(struct linux_ebus_device *, void *), void *arg) { @@ -1091,7 +1103,7 @@ sunsab_reg.minor = sunserial_current_minor; sunsab_reg.nr = num_channels; - sunsab_reg.cons = &sunsab_console; + sunsab_reg.cons = SUNSAB_CONSOLE; ret = uart_register_driver(&sunsab_reg); if (ret < 0) { diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c --- a/drivers/serial/sunsu.c Fri Jun 27 14:19:54 2003 +++ b/drivers/serial/sunsu.c Fri Jun 27 14:19:54 2003 @@ -46,8 +46,7 @@ #include <asm/isa.h> #endif -/* #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) */ -#if defined(CONFIG_MAGIC_SYSRQ) +#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ #endif @@ -1347,6 +1346,8 @@ * ------------------------------------------------------------ */ +#ifdef CONFIG_SERIAL_SUNSU_CONSOLE + #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) /* @@ -1465,6 +1466,7 @@ .index = -1, .data = &sunsu_reg, }; +#define SUNSU_CONSOLE (&sunsu_cons) /* * Register console. @@ -1492,6 +1494,10 @@ register_console(&sunsu_cons); return 0; } +#else +#define SUNSU_CONSOLE (NULL) +#define sunsu_serial_console_init() do { } while (0) +#endif static int __init sunsu_serial_init(void) { @@ -1522,7 +1528,7 @@ sunserial_current_minor += instance; sunsu_reg.nr = instance; - sunsu_reg.cons = &sunsu_cons; + sunsu_reg.cons = SUNSU_CONSOLE; ret = uart_register_driver(&sunsu_reg); if (ret < 0) diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c --- a/drivers/serial/sunzilog.c Fri Jun 27 14:20:05 2003 +++ b/drivers/serial/sunzilog.c Fri Jun 27 14:20:05 2003 @@ -28,6 +28,7 @@ #include <linux/slab.h> #include <linux/circ_buf.h> #include <linux/serial.h> +#include <linux/sysrq.h> #include <linux/console.h> #include <linux/spinlock.h> #ifdef CONFIG_SERIO @@ -42,6 +43,10 @@ #endif #include <asm/sbus.h> +#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include <linux/serial_core.h> #include "suncore.h" @@ -1331,6 +1336,7 @@ #endif /* CONFIG_SERIO */ +#ifdef CONFIG_SERIAL_SUNZILOG_CONSOLE static void sunzilog_console_write(struct console *con, const char *s, unsigned int count) { @@ -1400,6 +1406,7 @@ .index = -1, .data = &sunzilog_reg, }; +#define SUNZILOG_CONSOLE (&sunzilog_console) static int __init sunzilog_console_init(void) { @@ -1422,6 +1429,10 @@ register_console(&sunzilog_console); return 0; } +#else +#define SUNZILOG_CONSOLE (NULL) +#define sunzilog_console_init() do { } while (0) +#endif /* * We scan the PROM tree recursively. This is the most reliable way @@ -1639,7 +1650,7 @@ * in the system. */ sunzilog_reg.nr = NUM_CHANNELS; - sunzilog_reg.cons = &sunzilog_console; + sunzilog_reg.cons = SUNZILOG_CONSOLE; sunzilog_reg.minor = sunserial_current_minor; sunserial_current_minor += NUM_CHANNELS; diff -Nru a/drivers/sgi/Kconfig b/drivers/sgi/Kconfig --- a/drivers/sgi/Kconfig Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,57 +0,0 @@ -# -# Character device configuration -# - -menu "SGI devices" - depends on SGI_IP22 - -config SGI_SERIAL - bool "SGI Zilog85C30 serial support" - help - If you want to use your SGI's built-in serial ports under Linux, - answer Y. - -config SERIAL_CONSOLE - bool "Support for console on serial port" - depends on SGI_SERIAL - ---help--- - If you say Y here, it will be possible to use a serial port as the - system console (the system console is the device which receives all - kernel messages and warnings and which allows logins in single user - mode). This could be useful if some terminal or printer is connected - to that serial port. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttyS1". (Try "man bootparam" or see the documentation of - your boot loader (lilo or loadlin) about how to pass options to the - kernel at boot time.) - - If you don't have a VGA card installed and you say Y here, the - kernel will automatically use the first serial line, /dev/ttyS0, as - system console. - - If unsure, say N. - -config SGI_DS1286 - bool "SGI DS1286 RTC support" - help - If you say Y here and create a character special file /dev/rtc with - major number 10 and minor number 135 using mknod ("man mknod"), you - will get access to the real time clock built into your computer. - Every SGI has such a clock built in. It reports status information - via the file /proc/rtc and its behaviour is set by various ioctls on - /dev/rtc. - -config SGI_NEWPORT_GFX - tristate "SGI Newport Graphics support (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - If you have an SGI machine and you want to compile the graphics - drivers, say Y here. This will include the code for the - /dev/graphics and /dev/gfx drivers into the kernel for supporting - virtualized access to your graphics hardware. - -endmenu - diff -Nru a/drivers/sgi/Makefile b/drivers/sgi/Makefile --- a/drivers/sgi/Makefile Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,10 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# -# Character and Audio devices for SGI machines. -# -subdir-m += char - -obj-y += char/ diff -Nru a/drivers/sgi/char/Makefile b/drivers/sgi/char/Makefile --- a/drivers/sgi/char/Makefile Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,9 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-y := newport.o shmiq.o sgicons.o usema.o streamable.o - -obj-$(CONFIG_SGI_SERIAL) += sgiserial.o -obj-$(CONFIG_SGI_DS1286) += ds1286.o -obj-$(CONFIG_SGI_NEWPORT_GFX) += graphics.o rrm.o diff -Nru a/drivers/sgi/char/ds1286.c b/drivers/sgi/char/ds1286.c --- a/drivers/sgi/char/ds1286.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,521 +0,0 @@ -/* - * DS1286 Real Time Clock interface for Linux - * - * Copyright (C) 1998, 1999, 2000 Ralf Baechle - * - * Based on code written by Paul Gortmaker. - * - * This driver allows use of the real time clock (built into nearly all - * computers) from user space. It exports the /dev/rtc interface supporting - * various ioctl() and also the /proc/rtc pseudo-file for status - * information. - * - * The ioctls can be used to set the interrupt behaviour and generation rate - * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make - * use of these timer interrupts, be they interval or alarm based. - * - * The /dev/rtc interface will block on reads until an interrupt has been - * received. If a RTC interrupt has already happened, it will output an - * unsigned long and then block. The output value contains the interrupt - * status in the low byte and the number of interrupts since the last read - * in the remaining high bytes. The /dev/rtc interface can also be used with - * the select(2) call. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/miscdevice.h> -#include <linux/slab.h> -#include <linux/ioport.h> -#include <linux/fcntl.h> -#include <linux/init.h> -#include <linux/poll.h> -#include <linux/rtc.h> -#include <linux/spinlock.h> -#include <linux/bcd.h> - -#include <asm/ds1286.h> -#include <asm/io.h> -#include <asm/uaccess.h> -#include <asm/system.h> - -#define DS1286_VERSION "1.0" - -/* - * We sponge a minor off of the misc major. No need slurping - * up another valuable major dev number for this. If you add - * an ioctl, make sure you don't conflict with SPARC's RTC - * ioctls. - */ - -static DECLARE_WAIT_QUEUE_HEAD(ds1286_wait); - -static ssize_t ds1286_read(struct file *file, char *buf, - size_t count, loff_t *ppos); - -static int ds1286_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -static unsigned int ds1286_poll(struct file *file, poll_table *wait); - -void get_rtc_time (struct rtc_time *rtc_tm); -void get_rtc_alm_time (struct rtc_time *alm_tm); - -void set_rtc_irq_bit(unsigned char bit); -void clear_rtc_irq_bit(unsigned char bit); - -static inline unsigned char ds1286_is_updating(void); - -static spinlock_t ds1286_lock = SPIN_LOCK_UNLOCKED; - -/* - * Bits in rtc_status. (7 bits of room for future expansion) - */ - -#define RTC_IS_OPEN 0x01 /* means /dev/rtc is in use */ -#define RTC_TIMER_ON 0x02 /* missed irq timer active */ - -unsigned char ds1286_status; /* bitmapped status byte. */ -unsigned long ds1286_freq; /* Current periodic IRQ rate */ - -unsigned char days_in_mo[] = -{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - -/* - * Now all the various file operations that we export. - */ - -static ssize_t ds1286_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - return -EIO; -} - -static int ds1286_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - - struct rtc_time wtime; - - switch (cmd) { - case RTC_AIE_OFF: /* Mask alarm int. enab. bit */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val |= RTC_TDM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_AIE_ON: /* Allow alarm interrupts. */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val &= ~RTC_TDM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_WIE_OFF: /* Mask watchdog int. enab. bit */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val |= RTC_WAM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_WIE_ON: /* Allow watchdog interrupts. */ - { - unsigned int flags; - unsigned char val; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - spin_lock_irqsave(&ds1286_lock, flags); - val = CMOS_READ(RTC_CMD); - val &= ~RTC_WAM; - CMOS_WRITE(val, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - case RTC_ALM_READ: /* Read the present alarm time */ - { - /* - * This returns a struct rtc_time. Reading >= 0xc0 - * means "don't care" or "match all". Only the tm_hour, - * tm_min, and tm_sec values are filled in. - */ - - get_rtc_alm_time(&wtime); - break; - } - case RTC_ALM_SET: /* Store a time into the alarm */ - { - /* - * This expects a struct rtc_time. Writing 0xff means - * "don't care" or "match all". Only the tm_hour, - * tm_min and tm_sec are used. - */ - unsigned char hrs, min, sec; - struct rtc_time alm_tm; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&alm_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - hrs = alm_tm.tm_hour; - min = alm_tm.tm_min; - - if (hrs >= 24) - hrs = 0xff; - - if (min >= 60) - min = 0xff; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - - spin_lock(&ds1286_lock); - CMOS_WRITE(hrs, RTC_HOURS_ALARM); - CMOS_WRITE(min, RTC_MINUTES_ALARM); - spin_unlock(&ds1286_lock); - - return 0; - } - case RTC_RD_TIME: /* Read the time/date from RTC */ - { - get_rtc_time(&wtime); - break; - } - case RTC_SET_TIME: /* Set the RTC */ - { - struct rtc_time rtc_tm; - unsigned char mon, day, hrs, min, sec, leap_yr; - unsigned char save_control; - unsigned int yrs, flags; - - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, - sizeof(struct rtc_time))) - return -EFAULT; - - yrs = rtc_tm.tm_year + 1900; - mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ - day = rtc_tm.tm_mday; - hrs = rtc_tm.tm_hour; - min = rtc_tm.tm_min; - sec = rtc_tm.tm_sec; - - if (yrs < 1970) - return -EINVAL; - - leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); - - if ((mon > 12) || (day == 0)) - return -EINVAL; - - if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) - return -EINVAL; - - if ((hrs >= 24) || (min >= 60) || (sec >= 60)) - return -EINVAL; - - if ((yrs -= 1940) > 255) /* They are unsigned */ - return -EINVAL; - - if (yrs >= 100) - yrs -= 100; - - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); - BIN_TO_BCD(day); - BIN_TO_BCD(mon); - BIN_TO_BCD(yrs); - - spin_lock_irqsave(&ds1286_lock, flags); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); - - CMOS_WRITE(yrs, RTC_YEAR); - CMOS_WRITE(mon, RTC_MONTH); - CMOS_WRITE(day, RTC_DATE); - CMOS_WRITE(hrs, RTC_HOURS); - CMOS_WRITE(min, RTC_MINUTES); - CMOS_WRITE(sec, RTC_SECONDS); - CMOS_WRITE(0, RTC_HUNDREDTH_SECOND); - - CMOS_WRITE(save_control, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - return 0; - } - default: - return -EINVAL; - } - return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; -} - -/* - * We enforce only one user at a time here with the open/close. - * Also clear the previous interrupt data on an open, and clean - * up things on a close. - */ - -static int ds1286_open(struct inode *inode, struct file *file) -{ - spin_lock_irq(&ds1286_lock); - - if (ds1286_status & RTC_IS_OPEN) - goto out_busy; - - ds1286_status |= RTC_IS_OPEN; - - spin_lock_irq(&ds1286_lock); - return 0; - -out_busy: - spin_lock_irq(&ds1286_lock); - return -EBUSY; -} - -static int ds1286_release(struct inode *inode, struct file *file) -{ - ds1286_status &= ~RTC_IS_OPEN; - - return 0; -} - -static unsigned int ds1286_poll(struct file *file, poll_table *wait) -{ - poll_wait(file, &ds1286_wait, wait); - - return 0; -} - -/* - * The various file operations we support. - */ - -static struct file_operations ds1286_fops = { - .llseek = no_llseek, - .read = ds1286_read, - .poll = ds1286_poll, - .ioctl = ds1286_ioctl, - .open = ds1286_open, - .release = ds1286_release, -}; - -static struct miscdevice ds1286_dev= -{ - RTC_MINOR, - "rtc", - &ds1286_fops -}; - -int __init ds1286_init(void) -{ - printk(KERN_INFO "DS1286 Real Time Clock Driver v%s\n", DS1286_VERSION); - return misc_register(&ds1286_dev); -} - -static char *days[] = { - "***", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - -/* - * Info exported via "/proc/rtc". - */ -int get_ds1286_status(char *buf) -{ - char *p, *s; - struct rtc_time tm; - unsigned char hundredth, month, cmd, amode; - - p = buf; - - get_rtc_time(&tm); - hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND); - BCD_TO_BIN(hundredth); - - p += sprintf(p, - "rtc_time\t: %02d:%02d:%02d.%02d\n" - "rtc_date\t: %04d-%02d-%02d\n", - tm.tm_hour, tm.tm_min, tm.tm_sec, hundredth, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); - - /* - * We implicitly assume 24hr mode here. Alarm values >= 0xc0 will - * match any value for that particular field. Values that are - * greater than a valid time, but less than 0xc0 shouldn't appear. - */ - get_rtc_alm_time(&tm); - p += sprintf(p, "alarm\t\t: %s ", days[tm.tm_wday]); - if (tm.tm_hour <= 24) - p += sprintf(p, "%02d:", tm.tm_hour); - else - p += sprintf(p, "**:"); - - if (tm.tm_min <= 59) - p += sprintf(p, "%02d\n", tm.tm_min); - else - p += sprintf(p, "**\n"); - - month = CMOS_READ(RTC_MONTH); - p += sprintf(p, - "oscillator\t: %s\n" - "square_wave\t: %s\n", - (month & RTC_EOSC) ? "disabled" : "enabled", - (month & RTC_ESQW) ? "disabled" : "enabled"); - - amode = ((CMOS_READ(RTC_MINUTES_ALARM) & 0x80) >> 5) | - ((CMOS_READ(RTC_HOURS_ALARM) & 0x80) >> 6) | - ((CMOS_READ(RTC_DAY_ALARM) & 0x80) >> 7); - if (amode == 7) s = "each minute"; - else if (amode == 3) s = "minutes match"; - else if (amode == 1) s = "hours and minutes match"; - else if (amode == 0) s = "days, hours and minutes match"; - else s = "invalid"; - p += sprintf(p, "alarm_mode\t: %s\n", s); - - cmd = CMOS_READ(RTC_CMD); - p += sprintf(p, - "alarm_enable\t: %s\n" - "wdog_alarm\t: %s\n" - "alarm_mask\t: %s\n" - "wdog_alarm_mask\t: %s\n" - "interrupt_mode\t: %s\n" - "INTB_mode\t: %s_active\n" - "interrupt_pins\t: %s\n", - (cmd & RTC_TDF) ? "yes" : "no", - (cmd & RTC_WAF) ? "yes" : "no", - (cmd & RTC_TDM) ? "disabled" : "enabled", - (cmd & RTC_WAM) ? "disabled" : "enabled", - (cmd & RTC_PU_LVL) ? "pulse" : "level", - (cmd & RTC_IBH_LO) ? "low" : "high", - (cmd & RTC_IPSW) ? "unswapped" : "swapped"); - - return p - buf; -} - -/* - * Returns true if a clock update is in progress - */ -static inline unsigned char ds1286_is_updating(void) -{ - return CMOS_READ(RTC_CMD) & RTC_TE; -} - -void get_rtc_time(struct rtc_time *rtc_tm) -{ - unsigned long uip_watchdog = jiffies; - unsigned char save_control; - unsigned int flags; - - /* - * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to - * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. - * If you need to know *exactly* when a second has started, enable - * periodic update complete interrupts, (via ioctl) and then - * immediately read /dev/rtc which will block until you get the IRQ. - * Once the read clears, read the RTC time (again via ioctl). Easy. - */ - - if (ds1286_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) - barrier(); - - /* - * Only the values that we read from the RTC are set. We leave - * tm_wday, tm_yday and tm_isdst untouched. Even though the - * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated - * by the RTC when initially set to a non-zero value. - */ - spin_lock_irqsave(&ds1286_lock, flags); - save_control = CMOS_READ(RTC_CMD); - CMOS_WRITE((save_control|RTC_TE), RTC_CMD); - - rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); - rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); - rtc_tm->tm_hour = CMOS_READ(RTC_HOURS) & 0x1f; - rtc_tm->tm_mday = CMOS_READ(RTC_DATE); - rtc_tm->tm_mon = CMOS_READ(RTC_MONTH) & 0x1f; - rtc_tm->tm_year = CMOS_READ(RTC_YEAR); - - CMOS_WRITE(save_control, RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - BCD_TO_BIN(rtc_tm->tm_sec); - BCD_TO_BIN(rtc_tm->tm_min); - BCD_TO_BIN(rtc_tm->tm_hour); - BCD_TO_BIN(rtc_tm->tm_mday); - BCD_TO_BIN(rtc_tm->tm_mon); - BCD_TO_BIN(rtc_tm->tm_year); - - /* - * Account for differences between how the RTC uses the values - * and how they are defined in a struct rtc_time; - */ - if (rtc_tm->tm_year < 45) - rtc_tm->tm_year += 30; - if ((rtc_tm->tm_year += 40) < 70) - rtc_tm->tm_year += 100; - - rtc_tm->tm_mon--; -} - -void get_rtc_alm_time(struct rtc_time *alm_tm) -{ - unsigned char cmd; - unsigned int flags; - - /* - * Only the values that we read from the RTC are set. That - * means only tm_wday, tm_hour, tm_min. - */ - spin_lock_irqsave(&ds1286_lock, flags); - alm_tm->tm_min = CMOS_READ(RTC_MINUTES_ALARM) & 0x7f; - alm_tm->tm_hour = CMOS_READ(RTC_HOURS_ALARM) & 0x1f; - alm_tm->tm_wday = CMOS_READ(RTC_DAY_ALARM) & 0x07; - cmd = CMOS_READ(RTC_CMD); - spin_unlock_irqrestore(&ds1286_lock, flags); - - BCD_TO_BIN(alm_tm->tm_min); - BCD_TO_BIN(alm_tm->tm_hour); - alm_tm->tm_sec = 0; -} diff -Nru a/drivers/sgi/char/gconsole.h b/drivers/sgi/char/gconsole.h --- a/drivers/sgi/char/gconsole.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,33 +0,0 @@ -/* - * This is a temporary measure, we should eventually migrate to - * Gert's generic graphic console code. - */ - -#define cmapsz 8192 -#define CHAR_HEIGHT 16 - -struct console_ops { - void (*set_origin)(unsigned short offset); - void (*hide_cursor)(void); - void (*set_cursor)(int currcons); - void (*get_scrmem)(int currcons); - void (*set_scrmem)(int currcons, long offset); - int (*set_get_cmap)(unsigned char *arg, int set); - void (*blitc)(unsigned short charattr, unsigned long addr); - void (*memsetw)(void *s, unsigned short c, unsigned int count); - void (*memcpyw)(unsigned short *to, unsigned short *from, unsigned int count); -}; - -void register_gconsole (struct console_ops *); - -/* This points to the system console */ -extern struct console_ops *gconsole; - -extern void gfx_init (const char **name); - -extern void __set_origin (unsigned short offset); -extern void hide_cursor (void); -extern unsigned char vga_font[]; - -extern void disable_gconsole (void); -extern void enable_gconsole (void); diff -Nru a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c --- a/drivers/sgi/char/graphics.c Fri Jun 27 14:19:57 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,377 +0,0 @@ -/* - * gfx.c: support for SGI's /dev/graphics, /dev/opengl - * - * Author: Miguel de Icaza (miguel@nuclecu.unam.mx) - * Ralf Baechle (ralf@gnu.org) - * Ulf Carlsson (ulfc@bun.falkenberg.se) - * - * On IRIX, /dev/graphics is [10, 146] - * /dev/opengl is [10, 147] - * - * From a mail with Mark J. Kilgard, /dev/opengl and /dev/graphics are - * the same thing, the use of /dev/graphics seems deprecated though. - * - * The reason that the original SGI programmer had to use only one - * device for all the graphic cards on the system will remain a - * mistery for the rest of our lives. Why some ioctls take a board - * number and some others not? Mistery. Why do they map the hardware - * registers into the user address space with an ioctl instead of - * mmap? Mistery too. Why they did not use the standard way of - * making ioctl constants and instead sticked a random constant? - * Mistery too. - * - * We implement those misterious things, and tried not to think about - * the reasons behind them. - */ -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/miscdevice.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/mman.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/smp_lock.h> -#include <asm/uaccess.h> -#include "gconsole.h" -#include "graphics.h" -#include "usema.h" -#include <asm/gfx.h> -#include <asm/rrm.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <video/newport.h> - -#define DEBUG - -/* The boards */ -extern struct graphics_ops *newport_probe (int, const char **); - -static struct graphics_ops cards [MAXCARDS]; -static int boards; - -#define GRAPHICS_CARD(inode) 0 - -/* -void enable_gconsole(void) {}; -void disable_gconsole(void) {}; -*/ - - -int -sgi_graphics_open (struct inode *inode, struct file *file) -{ - struct newport_regs *nregs = - (struct newport_regs *) KSEG1ADDR(cards[0].g_regs); - - newport_wait(); - nregs->set.wrmask = 0xffffffff; - nregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK | - NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX | - NPORT_DMODE0_STOPY); - nregs->set.colori = 1; - nregs->set.xystarti = (0 << 16) | 0; - nregs->go.xyendi = (1280 << 16) | 1024; - - return 0; -} - -int -sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - unsigned int board; - unsigned int devnum = GRAPHICS_CARD (inode->i_rdev); - int i; - - if ((cmd >= RRM_BASE) && (cmd <= RRM_CMD_LIMIT)) - return rrm_command (cmd-RRM_BASE, (void *) arg); - - switch (cmd){ - case GFX_GETNUM_BOARDS: - return boards; - - case GFX_GETBOARD_INFO: { - struct gfx_getboardinfo_args *bia = (void *) arg; - void *dest_buf; - int max_len; - - i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct gfx_getboardinfo_args)); - if (i) return i; - - if (__get_user (board, &bia->board) || - __get_user (dest_buf, &bia->buf) || - __get_user (max_len, &bia->len)) - return -EFAULT; - - if (board >= boards) - return -EINVAL; - if (max_len < sizeof (struct gfx_getboardinfo_args)) - return -EINVAL; - if (max_len > cards [board].g_board_info_len) - max_len = cards [boards].g_board_info_len; - i = verify_area (VERIFY_WRITE, dest_buf, max_len); - if (i) return i; - if (copy_to_user (dest_buf, cards [board].g_board_info, max_len)) - return -EFAULT; - return max_len; - } - - case GFX_ATTACH_BOARD: { - struct gfx_attach_board_args *att = (void *) arg; - void *vaddr; - int r; - - i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct gfx_attach_board_args)); - if (i) return i; - - if (__get_user (board, &att->board) || - __get_user (vaddr, &att->vaddr)) - return -EFAULT; - - /* Ok for now we are assuming /dev/graphicsN -> head N even - * if the ioctl api suggests that this is not quite the case. - * - * Otherwise we fail, we use this assumption in the mmap code - * below to find our board information. - */ - if (board != devnum){ - printk ("Parameter board does not match the current board\n"); - return -EINVAL; - } - - if (board >= boards) - return -EINVAL; - - /* If it is the first opening it, then make it the board owner */ - if (!cards [board].g_owner) - cards [board].g_owner = current; - - /* - * Ok, we now call mmap on this file, which will end up calling - * sgi_graphics_mmap - */ - disable_gconsole (); - down_write(¤t->mm->mmap_sem); - r = do_mmap (file, (unsigned long)vaddr, - cards[board].g_regs_size, PROT_READ|PROT_WRITE, - MAP_FIXED|MAP_PRIVATE, 0); - up_write(¤t->mm->mmap_sem); - if (r) - return r; - } - - /* Strange, the real mapping seems to be done at GFX_ATTACH_BOARD, - * GFX_MAPALL is not even used by IRIX X server - */ - case GFX_MAPALL: - return 0; - - case GFX_LABEL: - return 0; - - /* Version check - * for my IRIX 6.2 X server, this is what the kernel returns - */ - case 1: - return 3; - - /* Xsgi does not use this one, I assume minor is the board being queried */ - case GFX_IS_MANAGED: - if (devnum > boards) - return -EINVAL; - return (cards [devnum].g_owner != 0); - - default: - if (cards [devnum].g_ioctl) - return (*cards [devnum].g_ioctl)(devnum, cmd, arg); - - } - return -EINVAL; -} - -int -sgi_graphics_close (struct inode *inode, struct file *file) -{ - int board = GRAPHICS_CARD (inode->i_rdev); - - /* Tell the rendering manager that one client is going away */ - rrm_close (inode, file); - - /* Was this file handle from the board owner?, clear it */ - if (current == cards [board].g_owner){ - cards [board].g_owner = 0; - if (cards [board].g_reset_console) - (*cards [board].g_reset_console)(); - enable_gconsole (); - } - return 0; -} - -/* - * This is the core of the direct rendering engine. - */ -struct page * -sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int - no_share) -{ - pgd_t *pgd; pmd_t *pmd; pte_t *pte; - int board = GRAPHICS_CARD (vma->vm_dentry->d_inode->i_rdev); - - unsigned long virt_add, phys_add; - struct page * page; - -#ifdef DEBUG - printk ("Got a page fault for board %d address=%lx guser=%lx\n", board, - address, (unsigned long) cards[board].g_user); -#endif - - /* Figure out if another process has this mapped, and revoke the mapping - * in that case. */ - if (cards[board].g_user && cards[board].g_user != current) { - /* FIXME: save graphics context here, dump it to rendering - * node? */ - - remove_mapping(vma, cards[board].g_user, vma->vm_start, vma->vm_end); - } - - cards [board].g_user = current; - - /* Map the physical address of the newport registers into the address - * space of this process */ - - virt_add = address & PAGE_MASK; - phys_add = cards[board].g_regs + virt_add - vma->vm_start; - remap_page_range(vma, virt_add, phys_add, PAGE_SIZE, vma->vm_page_prot); - - pgd = pgd_offset(current->mm, address); - pmd = pmd_offset(pgd, address); - pte = pte_kmap_offset(pmd, address); - page = pte_page(*pte); - pte_kunmap(pte); - return page; -} - -/* - * We convert a GFX ioctl for mapping hardware registers, in a nice sys_mmap - * call, which takes care of everything that must be taken care of. - * - */ - -static struct vm_operations_struct graphics_mmap = { - .nopage = sgi_graphics_nopage, /* our magic no-page fault handler */ -}; - -int -sgi_graphics_mmap (struct file *file, struct vm_area_struct *vma) -{ - uint size; - - size = vma->vm_end - vma->vm_start; - - /* 1. Set our special graphic virtualizer */ - vma->vm_ops = &graphics_mmap; - - /* 2. Set the special tlb permission bits */ - vma->vm_page_prot = PAGE_USERIO; - - /* final setup */ - vma->vm_file = file; - return 0; -} - -#if 0 -/* Do any post card-detection setup on graphics_ops */ -static void -graphics_ops_post_init (int slot) -{ - /* There is no owner for the card initially */ - cards [slot].g_owner = (struct task_struct *) 0; - cards [slot].g_user = (struct task_struct *) 0; -} -#endif - -struct file_operations sgi_graphics_fops = { - .ioctl = sgi_graphics_ioctl, - .mmap = sgi_graphics_mmap, - .open = sgi_graphics_open, - .release = sgi_graphics_close, -}; - -/* /dev/graphics */ -static struct miscdevice dev_graphics = { - SGI_GRAPHICS_MINOR, "sgi-graphics", &sgi_graphics_fops -}; - -/* /dev/opengl */ -static struct miscdevice dev_opengl = { - SGI_OPENGL_MINOR, "sgi-opengl", &sgi_graphics_fops -}; - -/* This is called later from the misc-init routine */ -void __init gfx_register (void) -{ - misc_register (&dev_graphics); - misc_register (&dev_opengl); -} - -void __init gfx_init (const char **name) -{ -#if 0 - struct console_ops *console; - struct graphics_ops *g; -#endif - - printk ("GFX INIT: "); - shmiq_init (); - usema_init (); - - boards++; - -#if 0 - if ((g = newport_probe (boards, name)) != 0) { - cards [boards] = *g; - graphics_ops_post_init (boards); - boards++; - console = 0; - } - /* Add more graphic drivers here */ - /* Keep passing console around */ -#endif - - if (boards > MAXCARDS) - printk (KERN_WARNING "Too many cards found on the system\n"); -} - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -int init_module(void) { - static int initiated = 0; - - printk("SGI Newport Graphics version %i.%i.%i\n",42,54,69); - - if (!initiated++) { - shmiq_init(); - usema_init(); - printk("Adding first board\n"); - boards++; - cards[0].g_regs = 0x1f0f0000; - cards[0].g_regs_size = sizeof (struct newport_regs); - } - - printk("Boards: %d\n", boards); - - misc_register (&dev_graphics); - misc_register (&dev_opengl); - - return 0; -} - -void cleanup_module(void) { - printk("Shutting down SGI Newport Graphics\n"); - - misc_deregister (&dev_graphics); - misc_deregister (&dev_opengl); -} -#endif diff -Nru a/drivers/sgi/char/graphics.h b/drivers/sgi/char/graphics.h --- a/drivers/sgi/char/graphics.h Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,27 +0,0 @@ -#define MAXCARDS 4 - -struct graphics_ops { - /* SGIism: Board owner, gets the shmiq requests from the kernel */ - struct task_struct *g_owner; - - /* Last process that got the graphics registers mapped */ - struct task_struct *g_user; - - /* Board info */ - void *g_board_info; - int g_board_info_len; - - /* These point to hardware registers that should be mapped with - * GFX_ATTACH_BOARD and the size of the information pointed to - */ - unsigned long g_regs; - int g_regs_size; - - void (*g_save_context)(void *); - void (*g_restore_context)(void *); - void (*g_reset_console)(void); - int (*g_ioctl)(int device, int cmd, unsigned long arg); -}; - -void shmiq_init (void); -void streamable_init (void); diff -Nru a/drivers/sgi/char/newport.c b/drivers/sgi/char/newport.c --- a/drivers/sgi/char/newport.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,222 +0,0 @@ -/* - * newport.c: context switching the newport graphics card and - * newport graphics support. - * - * Author: Miguel de Icaza - */ - -#include <linux/errno.h> -#include <linux/sched.h> -#include <asm/types.h> -#include <asm/gfx.h> -#include <asm/ng1.h> -#include <asm/uaccess.h> -#include <video/newport.h> -#include <linux/module.h> - -struct newport_regs *npregs; - -EXPORT_SYMBOL(npregs); - -/* Kernel routines for supporting graphics context switching */ - -void newport_save (void *y) -{ - newport_ctx *x = y; - newport_wait (); - -#define LOAD(val) x->val = npregs->set.val; -#define LOADI(val) x->val = npregs->set.val.word; -#define LOADC(val) x->val = npregs->cset.val; - - LOAD(drawmode1); - LOAD(drawmode0); - LOAD(lsmode); - LOAD(lspattern); - LOAD(lspatsave); - LOAD(zpattern); - LOAD(colorback); - LOAD(colorvram); - LOAD(alpharef); - LOAD(smask0x); - LOAD(smask0y); - LOADI(_xstart); - LOADI(_ystart); - LOADI(_xend); - LOADI(_yend); - LOAD(xsave); - LOAD(xymove); - LOADI(bresd); - LOADI(bress1); - LOAD(bresoctinc1); - LOAD(bresrndinc2); - LOAD(brese1); - LOAD(bress2); - LOAD(aweight0); - LOAD(aweight1); - LOADI(colorred); - LOADI(coloralpha); - LOADI(colorgrn); - LOADI(colorblue); - LOADI(slopered); - LOADI(slopealpha); - LOADI(slopegrn); - LOADI(slopeblue); - LOAD(wrmask); - LOAD(hostrw0); - LOAD(hostrw1); - - /* configregs */ - - LOADC(smask1x); - LOADC(smask1y); - LOADC(smask2x); - LOADC(smask2y); - LOADC(smask3x); - LOADC(smask3y); - LOADC(smask4x); - LOADC(smask4y); - LOADC(topscan); - LOADC(xywin); - LOADC(clipmode); - LOADC(config); - - /* Mhm, maybe I am missing something, but it seems that - * saving/restoring the DCB is only a matter of saving these - * registers - */ - - newport_bfwait (); - LOAD (dcbmode); - newport_bfwait (); - x->dcbdata0 = npregs->set.dcbdata0.byword; - newport_bfwait (); - LOAD(dcbdata1); -} - -/* - * Importat things to keep in mind when restoring the newport context: - * - * 1. slopered register is stored as a 2's complete (s12.11); - * needs to be converted to a signed magnitude (s(8)12.11). - * - * 2. xsave should be stored after xstart. - * - * 3. None of the registers should be written with the GO address. - * (read the docs for more details on this). - */ -void newport_restore (void *y) -{ - newport_ctx *x = y; -#define STORE(val) npregs->set.val = x->val -#define STOREI(val) npregs->set.val.word = x->val -#define STOREC(val) npregs->cset.val = x->val - newport_wait (); - - STORE(drawmode1); - STORE(drawmode0); - STORE(lsmode); - STORE(lspattern); - STORE(lspatsave); - STORE(zpattern); - STORE(colorback); - STORE(colorvram); - STORE(alpharef); - STORE(smask0x); - STORE(smask0y); - STOREI(_xstart); - STOREI(_ystart); - STOREI(_xend); - STOREI(_yend); - STORE(xsave); - STORE(xymove); - STOREI(bresd); - STOREI(bress1); - STORE(bresoctinc1); - STORE(bresrndinc2); - STORE(brese1); - STORE(bress2); - STORE(aweight0); - STORE(aweight1); - STOREI(colorred); - STOREI(coloralpha); - STOREI(colorgrn); - STOREI(colorblue); - STOREI(slopered); - STOREI(slopealpha); - STOREI(slopegrn); - STOREI(slopeblue); - STORE(wrmask); - STORE(hostrw0); - STORE(hostrw1); - - /* configregs */ - - STOREC(smask1x); - STOREC(smask1y); - STOREC(smask2x); - STOREC(smask2y); - STOREC(smask3x); - STOREC(smask3y); - STOREC(smask4x); - STOREC(smask4y); - STOREC(topscan); - STOREC(xywin); - STOREC(clipmode); - STOREC(config); - - /* FIXME: restore dcb thingies */ -} - -int -newport_ioctl (int card, int cmd, unsigned long arg) -{ - switch (cmd){ - case NG1_SETDISPLAYMODE: { - struct ng1_setdisplaymode_args request; - - if (copy_from_user (&request, (void *) arg, sizeof (request))) - return -EFAULT; - - newport_wait (); - newport_bfwait (); - npregs->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL | - DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL; - xmap9FIFOWait (npregs); - - /* FIXME: timing is wrong, just be extracted from - * the per-board timing table. I still have to figure - * out where this comes from - * - * This is used to select the protocol used to talk to - * the xmap9. For now I am using 60, selecting the - * WSLOW_DCB_XMAP9_PROTOCOL. - * - * Robert Tray comments on this issue: - * - * cfreq refers to the frequency of the monitor - * (ie. the refresh rate). Our monitors run typically - * between 60 Hz and 76 Hz. But it will be as low as - * 50 Hz if you're displaying NTSC/PAL and as high as - * 120 Hz if you are runining in stereo mode. You - * might want to try the WSLOW values. - */ - xmap9SetModeReg (npregs, request.wid, request.mode, 60); - return 0; - } - case NG1_SET_CURSOR_HOTSPOT: { - struct ng1_set_cursor_hotspot request; - - if (copy_from_user (&request, (void *) arg, sizeof (request))) - return -EFAULT; - /* FIXME: make request.xhot, request.yhot the hot spot */ - return 0; - } - - case NG1_SETGAMMARAMP0: - /* FIXME: load the gamma ramps :-) */ - return 0; - - } - return -EINVAL; -} diff -Nru a/drivers/sgi/char/rrm.c b/drivers/sgi/char/rrm.c --- a/drivers/sgi/char/rrm.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,75 +0,0 @@ -/* - * Linux Rendering Resource Manager - * - * Implements the SGI-compatible rendering resource manager. - * This takes care of implementing the virtualized video hardware - * access required for OpenGL direct rendering. - * - * Author: Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * Fixes: - */ -#include <linux/module.h> - -#include <asm/uaccess.h> -#include <asm/rrm.h> - - -int -rrm_open_rn (int rnid, void *arg) -{ - return 0; -} - -int -rrm_close_rn (int rnid, void *arg) -{ - return 0; -} - -int -rrm_bind_proc_to_rn (int rnid, void *arg) -{ - return 0; -} - -typedef int (*rrm_function )(void *arg); - -struct { - int (*r_fn)(int rnid, void *arg); - int arg_size; -} rrm_functions [] = { - { rrm_open_rn, sizeof (struct RRM_OpenRN) }, - { rrm_close_rn, sizeof (struct RRM_CloseRN) }, - { rrm_bind_proc_to_rn, sizeof (struct RRM_BindProcToRN) } -}; - -#define RRM_FUNCTIONS (sizeof (rrm_functions)/sizeof (rrm_functions [0])) - -/* cmd is a number in the range [0..RRM_CMD_LIMIT-RRM_BASE] */ -int -rrm_command (unsigned int cmd, void *arg) -{ - int i, rnid; - - if (cmd > RRM_FUNCTIONS){ - printk ("Called unimplemented rrm ioctl: %d\n", cmd + RRM_BASE); - return -EINVAL; - } - i = verify_area (VERIFY_READ, arg, rrm_functions [cmd].arg_size); - if (i) return i; - - if (__get_user (rnid, (int *) arg)) - return -EFAULT; - return (*(rrm_functions [cmd].r_fn))(rnid, arg); -} - -int -rrm_close (struct inode *inode, struct file *file) -{ - /* This routine is invoked when the device is closed */ - return 0; -} - -EXPORT_SYMBOL(rrm_command); -EXPORT_SYMBOL(rrm_close); diff -Nru a/drivers/sgi/char/sgicons.c b/drivers/sgi/char/sgicons.c --- a/drivers/sgi/char/sgicons.c Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,45 +0,0 @@ -/* - * sgicons.c: Setting up and registering console I/O on the SGI. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * This implement a virtual console interface. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/module.h> -#include <asm/uaccess.h> -#include "gconsole.h" - -/* This is the system graphics console (the first adapter found) */ -struct console_ops *gconsole = 0; -struct console_ops *real_gconsole = 0; - -void -enable_gconsole (void) -{ - if (!gconsole) - gconsole = real_gconsole; -} - -void -disable_gconsole (void) -{ - if (gconsole){ - real_gconsole = gconsole; - gconsole = 0; - } -} - -EXPORT_SYMBOL(disable_gconsole); -EXPORT_SYMBOL(enable_gconsole); - -void -register_gconsole (struct console_ops *gc) -{ - if (gconsole) - return; - gconsole = gc; -} diff -Nru a/drivers/sgi/char/sgiserial.c b/drivers/sgi/char/sgiserial.c --- a/drivers/sgi/char/sgiserial.c Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2210 +0,0 @@ -/* sgiserial.c: Serial port driver for SGI machines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ - -/* - * Note: This driver seems to have been derived from some - * version of the sbus/char/zs.c driver. A lot of clean-up - * and bug fixes seem to have happened to the Sun driver in - * the intervening time. As of 21.09.1999, I have merged in - * ONLY the changes necessary to fix observed functional - * problems on the Indy. Someone really ought to do a - * thorough pass to merge in the rest of the updates. - * Better still, someone really ought to make it a common - * code module for both platforms. kevink@mips.com - * - * 20010616 - Klaus Naumann <spock@mgnet.de> : Make serial console work with - * any speed - not only 9600 - */ - -#include <linux/config.h> /* for CONFIG_REMOTE_DEBUG */ -#include <linux/errno.h> -#include <linux/signal.h> -#include <linux/sched.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/tty.h> -#include <linux/tty_flip.h> -#include <linux/major.h> -#include <linux/string.h> -#include <linux/fcntl.h> -#include <linux/mm.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/console.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/sgialib.h> -#include <asm/system.h> -#include <asm/bitops.h> -#include <asm/sgi/sgihpc.h> -#include <asm/sgi/sgint23.h> -#include <asm/uaccess.h> - -#include "sgiserial.h" - -#define NUM_SERIAL 1 /* One chip on board. */ -#define NUM_CHANNELS (NUM_SERIAL * 2) - -struct sgi_zslayout *zs_chips[NUM_SERIAL] = { 0, }; -struct sgi_zschannel *zs_channels[NUM_CHANNELS] = { 0, 0, }; -struct sgi_zschannel *zs_conschan; -struct sgi_zschannel *zs_kgdbchan; - -struct sgi_serial zs_soft[NUM_CHANNELS]; -struct sgi_serial *zs_chain; /* IRQ servicing chain */ -static int zilog_irq = SGI_SERIAL_IRQ; - -/* Console hooks... */ -static int zs_cons_chanout; -static int zs_cons_chanin; -struct sgi_serial *zs_consinfo; - -static unsigned char kgdb_regs[16] = { - 0, 0, 0, /* write 0, 1, 2 */ - (Rx8 | RxENABLE), /* write 3 */ - (X16CLK | SB1 | PAR_EVEN), /* write 4 */ - (Tx8 | TxENAB), /* write 5 */ - 0, 0, 0, /* write 6, 7, 8 */ - (NV), /* write 9 */ - (NRZ), /* write 10 */ - (TCBR | RCBR), /* write 11 */ - 0, 0, /* BRG time constant, write 12 + 13 */ - (BRENABL), /* write 14 */ - (DCDIE) /* write 15 */ -}; - -static unsigned char zscons_regs[16] = { - 0, /* write 0 */ - (EXT_INT_ENAB | INT_ALL_Rx), /* write 1 */ - 0, /* write 2 */ - (Rx8 | RxENABLE), /* write 3 */ - (X16CLK), /* write 4 */ - (DTR | Tx8 | TxENAB), /* write 5 */ - 0, 0, 0, /* write 6, 7, 8 */ - (NV | MIE), /* write 9 */ - (NRZ), /* write 10 */ - (TCBR | RCBR), /* write 11 */ - 0, 0, /* BRG time constant, write 12 + 13 */ - (BRENABL), /* write 14 */ - (DCDIE | CTSIE | TxUIE | BRKIE) /* write 15 */ -}; - -#define ZS_CLOCK 3672000 /* Zilog input clock rate */ - -DECLARE_TASK_QUEUE(tq_serial); - -static struct tty_driver *serial_driver; -struct console *sgisercon; - -/* serial subtype definitions */ -#define SERIAL_TYPE_NORMAL 1 - -/* number of characters left in xmit buffer before we ask for more */ -#define WAKEUP_CHARS 256 - -/* Debugging... DEBUG_INTR is bad to use when one of the zs - * lines is your console ;( - */ -#undef SERIAL_DEBUG_INTR -#undef SERIAL_DEBUG_OPEN -#undef SERIAL_DEBUG_FLOW - -#define RS_STROBE_TIME 10 -#define RS_ISR_PASS_LIMIT 256 - -#define _INLINE_ inline - -static void change_speed(struct sgi_serial *info); - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the memcpy_fromfs blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char tmp_buf[4096]; /* This is cheating */ -static DECLARE_MUTEX(tmp_buf_sem); - -static inline int serial_paranoia_check(struct sgi_serial *info, - char *name, const char *routine) -{ -#ifdef SERIAL_PARANOIA_CHECK - static const char *badmagic = KERN_WARNING - "Warning: bad magic number for serial struct %s in %s\n"; - static const char *badinfo = KERN_WARNING - "Warning: null sgi_serial for %s in %s\n"; - - if (!info) { - printk(badinfo, name, routine); - return 1; - } - if (info->magic != SERIAL_MAGIC) { - printk(badmagic, name, routine); - return 1; - } -#endif - return 0; -} - -/* - * This is used to figure out the divisor speeds and the timeouts - */ -static int baud_table[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 0 }; - -/* - * Reading and writing Zilog8530 registers. The delays are to make this - * driver work on the Sun4 which needs a settling delay after each chip - * register access, other machines handle this in hardware via auxiliary - * flip-flops which implement the settle time we do in software. - * - * read_zsreg() and write_zsreg() may get called from rs_kgdb_hook() before - * interrupts are enabled. Therefore we have to check ioc_iocontrol before we - * access it. - */ -static inline unsigned char read_zsreg(struct sgi_zschannel *channel, - unsigned char reg) -{ - unsigned char retval; - volatile unsigned char junk; - - udelay(2); - channel->control = reg; - if (ioc_icontrol) - junk = ioc_icontrol->istat0; - udelay(1); - retval = channel->control; - return retval; -} - -static inline void write_zsreg(struct sgi_zschannel *channel, - unsigned char reg, unsigned char value) -{ - volatile unsigned char junk; - - udelay(2); - channel->control = reg; - if (ioc_icontrol) - junk = ioc_icontrol->istat0; - udelay(1); - channel->control = value; - if (ioc_icontrol) - junk = ioc_icontrol->istat0; - return; -} - -static inline void load_zsregs(struct sgi_zschannel *channel, unsigned char *regs) -{ - ZS_CLEARERR(channel); - ZS_CLEARFIFO(channel); - /* Load 'em up */ - write_zsreg(channel, R4, regs[R4]); - write_zsreg(channel, R10, regs[R10]); - write_zsreg(channel, R3, regs[R3] & ~RxENABLE); - write_zsreg(channel, R5, regs[R5] & ~TxENAB); - write_zsreg(channel, R1, regs[R1]); - write_zsreg(channel, R9, regs[R9]); - write_zsreg(channel, R11, regs[R11]); - write_zsreg(channel, R12, regs[R12]); - write_zsreg(channel, R13, regs[R13]); - write_zsreg(channel, R14, regs[R14]); - write_zsreg(channel, R15, regs[R15]); - write_zsreg(channel, R3, regs[R3]); - write_zsreg(channel, R5, regs[R5]); - return; -} - -/* Sets or clears DTR/RTS on the requested line */ -static inline void zs_rtsdtr(struct sgi_serial *ss, int set) -{ - if(set) { - ss->curregs[5] |= (RTS | DTR); - ss->pendregs[5] = ss->curregs[5]; - write_zsreg(ss->zs_channel, 5, ss->curregs[5]); - } else { - ss->curregs[5] &= ~(RTS | DTR); - ss->pendregs[5] = ss->curregs[5]; - write_zsreg(ss->zs_channel, 5, ss->curregs[5]); - } - return; -} - -static inline void kgdb_chaninit(struct sgi_serial *ss, int intson, int bps) -{ - int brg; - - if(intson) { - kgdb_regs[R1] = INT_ALL_Rx; - kgdb_regs[R9] |= MIE; - } else { - kgdb_regs[R1] = 0; - kgdb_regs[R9] &= ~MIE; - } - brg = BPS_TO_BRG(bps, ZS_CLOCK/ss->clk_divisor); - kgdb_regs[R12] = (brg & 255); - kgdb_regs[R13] = ((brg >> 8) & 255); - load_zsregs(ss->zs_channel, kgdb_regs); -} - -/* Utility routines for the Zilog */ -static inline int get_zsbaud(struct sgi_serial *ss) -{ - struct sgi_zschannel *channel = ss->zs_channel; - int brg; - - /* The baud rate is split up between two 8-bit registers in - * what is termed 'BRG time constant' format in my docs for - * the chip, it is a function of the clk rate the chip is - * receiving which happens to be constant. - */ - brg = ((read_zsreg(channel, 13)&0xff) << 8); - brg |= (read_zsreg(channel, 12)&0xff); - return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor))); -} - -/* - * ------------------------------------------------------------ - * rs_stop() and rs_start() - * - * This routines are called before setting or resetting tty->stopped. - * They enable or disable transmitter interrupts, as necessary. - * ------------------------------------------------------------ - */ -static void rs_stop(struct tty_struct *tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_stop")) - return; - - save_flags(flags); cli(); - if (info->curregs[5] & TxENAB) { - info->curregs[5] &= ~TxENAB; - info->pendregs[5] &= ~TxENAB; - write_zsreg(info->zs_channel, 5, info->curregs[5]); - } - restore_flags(flags); -} - -static void rs_start(struct tty_struct *tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_start")) - return; - - save_flags(flags); cli(); - if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) { - info->curregs[5] |= TxENAB; - info->pendregs[5] = info->curregs[5]; - write_zsreg(info->zs_channel, 5, info->curregs[5]); - } - restore_flags(flags); -} - -/* Drop into either the boot monitor or kadb upon receiving a break - * from keyboard/console input. - */ -static void batten_down_hatches(void) -{ - ArcEnterInteractiveMode(); -#if 0 - /* If we are doing kadb, we call the debugger - * else we just drop into the boot monitor. - * Note that we must flush the user windows - * first before giving up control. - */ - printk("\n"); - if((((unsigned long)linux_dbvec)>=DEBUG_FIRSTVADDR) && - (((unsigned long)linux_dbvec)<=DEBUG_LASTVADDR)) - sp_enter_debugger(); - else - prom_halt(); - - /* XXX We want to notify the keyboard driver that all - * XXX keys are in the up state or else weird things - * XXX happen... - */ -#endif - return; -} - -/* On receive, this clears errors and the receiver interrupts */ -static inline void rs_recv_clear(struct sgi_zschannel *zsc) -{ - volatile unsigned char junk; - - udelay(2); - zsc->control = ERR_RES; - junk = ioc_icontrol->istat0; - udelay(2); - zsc->control = RES_H_IUS; - junk = ioc_icontrol->istat0; -} - -/* - * ---------------------------------------------------------------------- - * - * Here starts the interrupt handling routines. All of the following - * subroutines are declared as inline and are folded into - * rs_interrupt(). They were separated out for readability's sake. - * - * Note: rs_interrupt() is a "fast" interrupt, which means that it - * runs with interrupts turned off. People who may want to modify - * rs_interrupt() should try to keep the interrupt handler as fast as - * possible. After you are done making modifications, it is not a bad - * idea to do: - * - * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c - * - * and look at the resulting assemble code in serial.s. - * - * - Ted Ts'o (tytso@mit.edu), 7-Mar-93 - * ----------------------------------------------------------------------- - */ - -/* - * This routine is used by the interrupt handler to schedule - * processing in the software interrupt portion of the driver. - */ -static _INLINE_ void rs_sched_event(struct sgi_serial *info, - int event) -{ - info->event |= 1 << event; - queue_task(&info->tqueue, &tq_serial); - mark_bh(SERIAL_BH); -} - -#ifdef CONFIG_REMOTE_DEBUG -extern void set_async_breakpoint(unsigned int epc); -#endif - -static _INLINE_ void receive_chars(struct sgi_serial *info, struct pt_regs *regs) -{ - struct tty_struct *tty = info->tty; - volatile unsigned char junk; - unsigned char ch, stat; - - udelay(2); - ch = info->zs_channel->data; - junk = ioc_icontrol->istat0; - udelay(2); - stat = read_zsreg(info->zs_channel, R1); - - /* If this is the console keyboard, we need to handle - * L1-A's here. - */ - if(info->is_cons) { - if(ch==0) { /* whee, break received */ - batten_down_hatches(); - rs_recv_clear(info->zs_channel); - return; - } else if (ch == 1) { - show_state(); - return; - } - } - /* Look for kgdb 'stop' character, consult the gdb documentation - * for remote target debugging and arch/sparc/kernel/sparc-stub.c - * to see how all this works. - */ -#ifdef CONFIG_REMOTE_DEBUG - if((info->kgdb_channel) && (ch =='\003')) { - set_async_breakpoint(read_32bit_cp0_register(CP0_EPC)); - goto clear_and_exit; - } -#endif - if(!tty) - goto clear_and_exit; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - queue_task(&tty->flip.tqueue, &tq_timer); - tty->flip.count++; - if(stat & PAR_ERR) - *tty->flip.flag_buf_ptr++ = TTY_PARITY; - else if(stat & Rx_OVR) - *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; - else if(stat & CRC_ERR) - *tty->flip.flag_buf_ptr++ = TTY_FRAME; - else - *tty->flip.flag_buf_ptr++ = 0; /* XXX */ - *tty->flip.char_buf_ptr++ = ch; - - queue_task(&tty->flip.tqueue, &tq_timer); - -clear_and_exit: - rs_recv_clear(info->zs_channel); - return; -} - -static _INLINE_ void transmit_chars(struct sgi_serial *info) -{ - volatile unsigned char junk; - - /* P3: In theory we have to test readiness here because a - * serial console can clog the chip through zs_cons_put_char(). - * David did not do this. I think he relies on 3-chars FIFO in 8530. - * Let's watch for lost _output_ characters. XXX - */ - - /* SGI ADDENDUM: On most SGI machines, the Zilog does possess - * a 16 or 17 byte fifo, so no worries. -dm - */ - - if (info->x_char) { - /* Send next char */ - udelay(2); - info->zs_channel->data = info->x_char; - junk = ioc_icontrol->istat0; - - info->x_char = 0; - goto clear_and_return; - } - - if((info->xmit_cnt <= 0) || info->tty->stopped) { - /* That's peculiar... */ - udelay(2); - info->zs_channel->control = RES_Tx_P; - junk = ioc_icontrol->istat0; - goto clear_and_return; - } - - /* Send char */ - udelay(2); - info->zs_channel->data = info->xmit_buf[info->xmit_tail++]; - junk = ioc_icontrol->istat0; - - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt--; - - if (info->xmit_cnt < WAKEUP_CHARS) - rs_sched_event(info, RS_EVENT_WRITE_WAKEUP); - - if(info->xmit_cnt <= 0) { - udelay(2); - info->zs_channel->control = RES_Tx_P; - junk = ioc_icontrol->istat0; - goto clear_and_return; - } - -clear_and_return: - /* Clear interrupt */ - udelay(2); - info->zs_channel->control = RES_H_IUS; - junk = ioc_icontrol->istat0; - return; -} - -static _INLINE_ void status_handle(struct sgi_serial *info) -{ - volatile unsigned char junk; - unsigned char status; - - /* Get status from Read Register 0 */ - udelay(2); - status = info->zs_channel->control; - junk = ioc_icontrol->istat0; - /* Clear status condition... */ - udelay(2); - info->zs_channel->control = RES_EXT_INT; - junk = ioc_icontrol->istat0; - /* Clear the interrupt */ - udelay(2); - info->zs_channel->control = RES_H_IUS; - junk = ioc_icontrol->istat0; - -#if 0 - if(status & DCD) { - if((info->tty->termios->c_cflag & CRTSCTS) && - ((info->curregs[3] & AUTO_ENAB)==0)) { - info->curregs[3] |= AUTO_ENAB; - info->pendregs[3] |= AUTO_ENAB; - write_zsreg(info->zs_channel, 3, info->curregs[3]); - } - } else { - if((info->curregs[3] & AUTO_ENAB)) { - info->curregs[3] &= ~AUTO_ENAB; - info->pendregs[3] &= ~AUTO_ENAB; - write_zsreg(info->zs_channel, 3, info->curregs[3]); - } - } -#endif - /* Whee, if this is console input and this is a - * 'break asserted' status change interrupt, call - * the boot prom. - */ - if((status & BRK_ABRT) && info->break_abort) - batten_down_hatches(); - - /* XXX Whee, put in a buffer somewhere, the status information - * XXX whee whee whee... Where does the information go... - */ - return; -} - -/* - * This is the serial driver's generic interrupt routine - */ -void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - struct sgi_serial * info = (struct sgi_serial *) dev_id; - unsigned char zs_intreg; - - zs_intreg = read_zsreg(info->zs_next->zs_channel, 3); - - /* NOTE: The read register 3, which holds the irq status, - * does so for both channels on each chip. Although - * the status value itself must be read from the A - * channel and is only valid when read from channel A. - * Yes... broken hardware... - */ -#define CHAN_A_IRQMASK (CHARxIP | CHATxIP | CHAEXT) -#define CHAN_B_IRQMASK (CHBRxIP | CHBTxIP | CHBEXT) - - /* *** Chip 1 *** */ - /* Channel B -- /dev/ttyb, could be the console */ - if(zs_intreg & CHAN_B_IRQMASK) { - if (zs_intreg & CHBRxIP) - receive_chars(info, regs); - if (zs_intreg & CHBTxIP) - transmit_chars(info); - if (zs_intreg & CHBEXT) - status_handle(info); - } - - info=info->zs_next; - - /* Channel A -- /dev/ttya, could be the console */ - if(zs_intreg & CHAN_A_IRQMASK) { - if (zs_intreg & CHARxIP) - receive_chars(info, regs); - if (zs_intreg & CHATxIP) - transmit_chars(info); - if (zs_intreg & CHAEXT) - status_handle(info); - } -} - -/* - * ------------------------------------------------------------------- - * Here ends the serial interrupt routines. - * ------------------------------------------------------------------- - */ - -/* - * This routine is used to handle the "bottom half" processing for the - * serial driver, known also the "software interrupt" processing. - * This processing is done at the kernel interrupt level, after the - * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This - * is where time-consuming activities which can not be done in the - * interrupt driver proper are done; the interrupt driver schedules - * them using rs_sched_event(), and they get done here. - */ -static void do_serial_bh(void) -{ - run_task_queue(&tq_serial); -} - -static void do_softint(void *private_) -{ - struct sgi_serial *info = (struct sgi_serial *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); - wake_up_interruptible(&tty->write_wait); - } -} - -/* - * This routine is called from the scheduler tqueue when the interrupt - * routine has signalled that a hangup has occurred. The path of - * hangup processing is: - * - * serial interrupt routine -> (scheduler tqueue) -> - * do_serial_hangup() -> tty->hangup() -> rs_hangup() - * - */ -static void do_serial_hangup(void *private_) -{ - struct sgi_serial *info = (struct sgi_serial *) private_; - struct tty_struct *tty; - - tty = info->tty; - if (!tty) - return; - - tty_hangup(tty); -} - - -static int startup(struct sgi_serial * info) -{ - volatile unsigned char junk; - unsigned long flags; - - if (info->flags & ZILOG_INITIALIZED) - return 0; - - if (!info->xmit_buf) { - info->xmit_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL); - if (!info->xmit_buf) - return -ENOMEM; - } - - save_flags(flags); cli(); - -#ifdef SERIAL_DEBUG_OPEN - printk("starting up ttys%d (irq %d)...\n", info->line, info->irq); -#endif - - /* - * Clear the FIFO buffers and disable them - * (they will be reenabled in change_speed()) - */ - ZS_CLEARFIFO(info->zs_channel); - info->xmit_fifo_size = 1; - - /* - * Clear the interrupt registers. - */ - udelay(2); - info->zs_channel->control = ERR_RES; - junk = ioc_icontrol->istat0; - udelay(2); - info->zs_channel->control = RES_H_IUS; - junk = ioc_icontrol->istat0; - - /* - * Now, initialize the Zilog - */ - zs_rtsdtr(info, 1); - - /* - * Finally, enable sequencing and interrupts - */ - info->curregs[1] |= (info->curregs[1] & ~0x18) | (EXT_INT_ENAB|INT_ALL_Rx); - info->pendregs[1] = info->curregs[1]; - info->curregs[3] |= (RxENABLE | Rx8); - info->pendregs[3] = info->curregs[3]; - /* We enable Tx interrupts as needed. */ - info->curregs[5] |= (TxENAB | Tx8); - info->pendregs[5] = info->curregs[5]; - info->curregs[9] |= (NV | MIE); - info->pendregs[9] = info->curregs[9]; - write_zsreg(info->zs_channel, 3, info->curregs[3]); - write_zsreg(info->zs_channel, 5, info->curregs[5]); - write_zsreg(info->zs_channel, 9, info->curregs[9]); - - /* - * And clear the interrupt registers again for luck. - */ - udelay(2); - info->zs_channel->control = ERR_RES; - junk = ioc_icontrol->istat0; - udelay(2); - info->zs_channel->control = RES_H_IUS; - junk = ioc_icontrol->istat0; - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - - /* - * and set the speed of the serial port - */ - change_speed(info); - - info->flags |= ZILOG_INITIALIZED; - restore_flags(flags); - return 0; -} - -/* - * This routine will shutdown a serial port; interrupts are disabled, and - * DTR is dropped if the hangup on close termio flag is on. - */ -static void shutdown(struct sgi_serial * info) -{ - unsigned long flags; - - if (!(info->flags & ZILOG_INITIALIZED)) - return; - -#ifdef SERIAL_DEBUG_OPEN - printk("Shutting down serial port %d (irq %d)....", info->line, - info->irq); -#endif - - save_flags(flags); cli(); /* Disable interrupts */ - - if (info->xmit_buf) { - free_page((unsigned long) info->xmit_buf); - info->xmit_buf = 0; - } - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ZILOG_INITIALIZED; - restore_flags(flags); -} - -/* - * This routine is called to set the UART divisor registers to match - * the specified baud rate for a serial port. - */ -static void change_speed(struct sgi_serial *info) -{ - unsigned short port; - unsigned cflag; - int i; - int brg; - - if (!info->tty || !info->tty->termios) - return; - cflag = info->tty->termios->c_cflag; - if (!(port = info->port)) - return; - i = cflag & CBAUD; - if (i & CBAUDEX) { - /* XXX CBAUDEX is not obeyed. - * It is impossible at a 32bits SPARC. - * But we have to report this to user ... someday. - */ - i = B9600; - } - if (i == 0) { - /* XXX B0, hangup the line. */ - do_serial_hangup(info); - } else if (baud_table[i]) { - info->zs_baud = baud_table[i]; - info->clk_divisor = 16; - - info->curregs[4] = X16CLK; - info->curregs[11] = TCBR | RCBR; - brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor); - info->curregs[12] = (brg & 255); - info->curregs[13] = ((brg >> 8) & 255); - info->curregs[14] = BRENABL; - } - - /* byte size and parity */ - switch (cflag & CSIZE) { - case CS5: - info->curregs[3] &= ~(0xc0); - info->curregs[3] |= Rx5; - info->pendregs[3] = info->curregs[3]; - info->curregs[5] &= ~(0xe0); - info->curregs[5] |= Tx5; - info->pendregs[5] = info->curregs[5]; - break; - case CS6: - info->curregs[3] &= ~(0xc0); - info->curregs[3] |= Rx6; - info->pendregs[3] = info->curregs[3]; - info->curregs[5] &= ~(0xe0); - info->curregs[5] |= Tx6; - info->pendregs[5] = info->curregs[5]; - break; - case CS7: - info->curregs[3] &= ~(0xc0); - info->curregs[3] |= Rx7; - info->pendregs[3] = info->curregs[3]; - info->curregs[5] &= ~(0xe0); - info->curregs[5] |= Tx7; - info->pendregs[5] = info->curregs[5]; - break; - case CS8: - default: /* defaults to 8 bits */ - info->curregs[3] &= ~(0xc0); - info->curregs[3] |= Rx8; - info->pendregs[3] = info->curregs[3]; - info->curregs[5] &= ~(0xe0); - info->curregs[5] |= Tx8; - info->pendregs[5] = info->curregs[5]; - break; - } - info->curregs[4] &= ~(0x0c); - if (cflag & CSTOPB) { - info->curregs[4] |= SB2; - } else { - info->curregs[4] |= SB1; - } - info->pendregs[4] = info->curregs[4]; - if (cflag & PARENB) { - info->curregs[4] |= PAR_ENA; - info->pendregs[4] |= PAR_ENA; - } else { - info->curregs[4] &= ~PAR_ENA; - info->pendregs[4] &= ~PAR_ENA; - } - if (!(cflag & PARODD)) { - info->curregs[4] |= PAR_EVEN; - info->pendregs[4] |= PAR_EVEN; - } else { - info->curregs[4] &= ~PAR_EVEN; - info->pendregs[4] &= ~PAR_EVEN; - } - - /* Load up the new values */ - load_zsregs(info->zs_channel, info->curregs); - - return; -} - -/* This is for console output over ttya/ttyb */ -static void zs_cons_put_char(char ch) -{ - struct sgi_zschannel *chan = zs_conschan; - volatile unsigned char junk; - int flags, loops = 0; - - save_flags(flags); cli(); - while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) { - loops++; - udelay(2); - } - - udelay(2); - chan->data = ch; - junk = ioc_icontrol->istat0; - restore_flags(flags); -} - -/* - * This is the more generic put_char function for the driver. - * In earlier versions of this driver, "rs_put_char" was the - * name of the console-specific fucntion, now called zs_cons_put_char - */ - -static void rs_put_char(struct tty_struct *tty, char ch) -{ - struct sgi_zschannel *chan = - ((struct sgi_serial *)tty->driver_data)->zs_channel; - volatile unsigned char junk; - int flags, loops = 0; - - save_flags(flags); cli(); - while(((junk = chan->control) & Tx_BUF_EMP)==0 && loops < 10000) { - loops++; - udelay(2); - } - - udelay(2); - chan->data = ch; - junk = ioc_icontrol->istat0; - restore_flags(flags); -} - -/* These are for receiving and sending characters under the kgdb - * source level kernel debugger. - */ -int putDebugChar(char kgdb_char) -{ - struct sgi_zschannel *chan = zs_kgdbchan; - volatile unsigned char junk; - unsigned long flags; - - save_flags(flags); cli(); - udelay(2); - while((chan->control & Tx_BUF_EMP)==0) - udelay(2); - - udelay(2); - chan->data = kgdb_char; - junk = ioc_icontrol->istat0; - restore_flags(flags); - - return 1; -} - -char getDebugChar(void) -{ - struct sgi_zschannel *chan = zs_kgdbchan; - unsigned char junk; - - while((chan->control & Rx_CH_AV)==0) - udelay(2); - - junk = ioc_icontrol->istat0; - udelay(2); - return chan->data; -} - -/* - * Fair output driver allows a process to speak. - */ -static void rs_fair_output(void) -{ - int left; /* Output no more than that */ - unsigned long flags; - struct sgi_serial *info = zs_consinfo; - volatile unsigned char junk; - char c; - - if (info == 0) return; - if (info->xmit_buf == 0) return; - - save_flags(flags); cli(); - left = info->xmit_cnt; - while (left != 0) { - c = info->xmit_buf[info->xmit_tail]; - info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt--; - restore_flags(flags); - - zs_cons_put_char(c); - - save_flags(flags); cli(); - left = MIN(info->xmit_cnt, left-1); - } - - /* Last character is being transmitted now (hopefully). */ - udelay(2); - zs_conschan->control = RES_Tx_P; - junk = ioc_icontrol->istat0; - - restore_flags(flags); - return; -} - - -static int rs_write(struct tty_struct * tty, int from_user, - const unsigned char *buf, int count) -{ - int c, total = 0; - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_write")) - return 0; - - if (!tty || !info->xmit_buf) - return 0; - - save_flags(flags); - while (1) { - cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - if (c <= 0) - break; - - if (from_user) { - down(&tmp_buf_sem); - copy_from_user(tmp_buf, buf, c); - c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, - SERIAL_XMIT_SIZE - info->xmit_head)); - memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c); - up(&tmp_buf_sem); - } else - memcpy(info->xmit_buf + info->xmit_head, buf, c); - info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt += c; - restore_flags(flags); - buf += c; - count -= c; - total += c; - } - - if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { - /* - * The above test used to include the condition - * "&& !(info->curregs[5] & TxENAB)", but there - * is reason to suspect that it is never statisfied - * when the port is running. The problem may in fact - * have been masked by the fact that, if O_POST is set, - * there is always a rs_flush_xx operation following the - * rs_write, and the flush ignores that condition when - * it kicks off the transmit. - */ - /* Enable transmitter */ - info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB; - info->pendregs[1] |= TxINT_ENAB|EXT_INT_ENAB; - write_zsreg(info->zs_channel, 1, info->curregs[1]); - info->curregs[5] |= TxENAB; - info->pendregs[5] |= TxENAB; - write_zsreg(info->zs_channel, 5, info->curregs[5]); - - /* - * The following code is imported from the 2.3.6 Sun sbus zs.c - * driver, of which an earlier version served as the basis - * for sgiserial.c. Perhaps due to changes over time in - * the line discipline code, ns_write()s with from_user - * set would not otherwise actually kick-off output in - * Linux 2.2.x or later. Maybe it never really worked. - */ - - rs_put_char(tty, info->xmit_buf[info->xmit_tail++]); - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt--; - } - - restore_flags(flags); - return total; -} - -static int rs_write_room(struct tty_struct *tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - int ret; - - if (serial_paranoia_check(info, tty->name, "rs_write_room")) - return 0; - ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; - if (ret < 0) - ret = 0; - return ret; -} - -static int rs_chars_in_buffer(struct tty_struct *tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer")) - return 0; - return info->xmit_cnt; -} - -static void rs_flush_buffer(struct tty_struct *tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) - return; - cli(); - info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); -} - -static void rs_flush_chars(struct tty_struct *tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - unsigned long flags; - - if (serial_paranoia_check(info, tty->name, "rs_flush_chars")) - return; - - if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || - !info->xmit_buf) - return; - - /* Enable transmitter */ - save_flags(flags); cli(); - info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB; - info->pendregs[1] |= TxINT_ENAB|EXT_INT_ENAB; - write_zsreg(info->zs_channel, 1, info->curregs[1]); - info->curregs[5] |= TxENAB; - info->pendregs[5] |= TxENAB; - write_zsreg(info->zs_channel, 5, info->curregs[5]); - - /* - * Send a first (bootstrapping) character. A best solution is - * to call transmit_chars() here which handles output in a - * generic way. Current transmit_chars() not only transmits, - * but resets interrupts also what we do not desire here. - * XXX Discuss with David. - */ - if (info->zs_channel->control & Tx_BUF_EMP) { - volatile unsigned char junk; - - /* Send char */ - udelay(2); - info->zs_channel->data = info->xmit_buf[info->xmit_tail++]; - junk = ioc_icontrol->istat0; - info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); - info->xmit_cnt--; - } - restore_flags(flags); -} - -/* - * ------------------------------------------------------------ - * rs_throttle() - * - * This routine is called by the upper-layer tty layer to signal that - * incoming characters should be throttled. - * ------------------------------------------------------------ - */ -static void rs_throttle(struct tty_struct * tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("throttle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_throttle")) - return; - - if (I_IXOFF(tty)) - info->x_char = STOP_CHAR(tty); - - /* Turn off RTS line */ - cli(); - info->curregs[5] &= ~RTS; - info->pendregs[5] &= ~RTS; - write_zsreg(info->zs_channel, 5, info->curregs[5]); - sti(); -} - -static void rs_unthrottle(struct tty_struct * tty) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; -#ifdef SERIAL_DEBUG_THROTTLE - char buf[64]; - - printk("unthrottle %s: %d....\n", _tty_name(tty, buf), - tty->ldisc.chars_in_buffer(tty)); -#endif - - if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) - return; - - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - info->x_char = START_CHAR(tty); - } - - /* Assert RTS line */ - cli(); - info->curregs[5] |= RTS; - info->pendregs[5] |= RTS; - write_zsreg(info->zs_channel, 5, info->curregs[5]); - sti(); -} - -/* - * ------------------------------------------------------------ - * rs_ioctl() and friends - * ------------------------------------------------------------ - */ - -static int get_serial_info(struct sgi_serial * info, - struct serial_struct * retinfo) -{ - struct serial_struct tmp; - - if (!retinfo) - return -EFAULT; - memset(&tmp, 0, sizeof(tmp)); - tmp.type = info->type; - tmp.line = info->line; - tmp.port = info->port; - tmp.irq = info->irq; - tmp.flags = info->flags; - tmp.baud_base = info->baud_base; - tmp.close_delay = info->close_delay; - tmp.closing_wait = info->closing_wait; - tmp.custom_divisor = info->custom_divisor; - return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0; -} - -static int set_serial_info(struct sgi_serial * info, - struct serial_struct * new_info) -{ - struct serial_struct new_serial; - struct sgi_serial old_info; - int retval = 0; - - if (!new_info) - return -EFAULT; - copy_from_user(&new_serial,new_info,sizeof(new_serial)); - old_info = *info; - - if (!capable(CAP_SYS_ADMIN)) { - if ((new_serial.baud_base != info->baud_base) || - (new_serial.type != info->type) || - (new_serial.close_delay != info->close_delay) || - ((new_serial.flags & ~ZILOG_USR_MASK) != - (info->flags & ~ZILOG_USR_MASK))) - return -EPERM; - info->flags = ((info->flags & ~ZILOG_USR_MASK) | - (new_serial.flags & ZILOG_USR_MASK)); - info->custom_divisor = new_serial.custom_divisor; - goto check_and_exit; - } - - if (info->count > 1) - return -EBUSY; - - /* - * OK, past this point, all the error checking has been done. - * At this point, we start making changes..... - */ - - info->baud_base = new_serial.baud_base; - info->flags = ((info->flags & ~ZILOG_FLAGS) | - (new_serial.flags & ZILOG_FLAGS)); - info->type = new_serial.type; - info->close_delay = new_serial.close_delay; - info->closing_wait = new_serial.closing_wait; - -check_and_exit: - retval = startup(info); - return retval; -} - -/* - * get_lsr_info - get line status register info - * - * Purpose: Let user call ioctl() to get info when the UART physically - * is emptied. On bus types like RS485, the transmitter must - * release the bus after transmitting. This must be done when - * the transmit shift register is empty, not be done when the - * transmit holding register is empty. This functionality - * allows an RS485 driver to be written in user space. - */ -static int get_lsr_info(struct sgi_serial * info, unsigned int *value) -{ - volatile unsigned char junk; - unsigned char status; - - cli(); - udelay(2); - status = info->zs_channel->control; - junk = ioc_icontrol->istat0; - sti(); - return put_user(status,value); -} - -static int get_modem_info(struct sgi_serial * info, unsigned int *value) -{ - unsigned char status; - unsigned int result; - - cli(); - status = info->zs_channel->control; - udelay(2); - sti(); - result = ((info->curregs[5] & RTS) ? TIOCM_RTS : 0) - | ((info->curregs[5] & DTR) ? TIOCM_DTR : 0) - | ((status & DCD) ? TIOCM_CAR : 0) - | ((status & SYNC) ? TIOCM_DSR : 0) - | ((status & CTS) ? TIOCM_CTS : 0); - if (put_user(result, value)) - return -EFAULT; - return 0; -} - -static int set_modem_info(struct sgi_serial * info, unsigned int cmd, - unsigned int *value) -{ - unsigned int arg; - - if (get_user(arg, value)) - return -EFAULT; - switch (cmd) { - case TIOCMBIS: - if (arg & TIOCM_RTS) - info->curregs[5] |= RTS; - if (arg & TIOCM_DTR) - info->curregs[5] |= DTR; - break; - case TIOCMBIC: - if (arg & TIOCM_RTS) - info->curregs[5] &= ~RTS; - if (arg & TIOCM_DTR) - info->curregs[5] &= ~DTR; - break; - case TIOCMSET: - info->curregs[5] = ((info->curregs[5] & ~(RTS | DTR)) - | ((arg & TIOCM_RTS) ? RTS : 0) - | ((arg & TIOCM_DTR) ? DTR : 0)); - break; - default: - return -EINVAL; - } - cli(); - write_zsreg(info->zs_channel, 5, info->curregs[5]); - sti(); - return 0; -} - -/* - * This routine sends a break character out the serial port. - */ -static void send_break( struct sgi_serial * info, int duration) -{ - if (!info->port) - return; - current->state = TASK_INTERRUPTIBLE; - cli(); - write_zsreg(info->zs_channel, 5, (info->curregs[5] | SND_BRK)); - schedule_timeout(duration); - write_zsreg(info->zs_channel, 5, info->curregs[5]); - sti(); -} - -static int rs_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg) -{ - struct sgi_serial * info = (struct sgi_serial *) tty->driver_data; - int retval; - - if (serial_paranoia_check(info, tty->name, "zs_ioctl")) - return -ENODEV; - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && - (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case TCSBRK: /* SVID version: non-zero arg --> no break */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - if (!arg) - send_break(info, HZ/4); /* 1/4 second */ - return 0; - case TCSBRKP: /* support for POSIX tcsendbreak() */ - retval = tty_check_change(tty); - if (retval) - return retval; - tty_wait_until_sent(tty, 0); - send_break(info, arg ? arg*(HZ/10) : HZ/4); - return 0; - case TIOCGSOFTCAR: - if (put_user(C_CLOCAL(tty) ? 1 : 0, - (unsigned long *) arg)) - return -EFAULT; - return 0; - case TIOCSSOFTCAR: - if (get_user(arg, (unsigned long *) arg)) - return -EFAULT; - tty->termios->c_cflag = - ((tty->termios->c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); - return 0; - case TIOCMGET: - return get_modem_info(info, (unsigned int *) arg); - case TIOCMBIS: - case TIOCMBIC: - case TIOCMSET: - return set_modem_info(info, cmd, (unsigned int *) arg); - case TIOCGSERIAL: - return get_serial_info(info, - (struct serial_struct *) arg); - case TIOCSSERIAL: - return set_serial_info(info, - (struct serial_struct *) arg); - case TIOCSERGETLSR: /* Get line status register */ - return get_lsr_info(info, (unsigned int *) arg); - - case TIOCSERGSTRUCT: - if (copy_to_user((struct sgi_serial *) arg, - info, sizeof(struct sgi_serial))) - return -EFAULT; - return 0; - - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct sgi_serial *info = (struct sgi_serial *)tty->driver_data; - - if (tty->termios->c_cflag == old_termios->c_cflag) - return; - - change_speed(info); - - if ((old_termios->c_cflag & CRTSCTS) && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - rs_start(tty); - } -} - -/* - * ------------------------------------------------------------ - * rs_close() - * - * This routine is called when the serial port gets closed. First, we - * wait for the last remaining data to be sent. Then, we unlink its - * ZILOG structure from the interrupt chain if necessary, and we free - * that IRQ if nothing is left in the chain. - * ------------------------------------------------------------ - */ -static void rs_close(struct tty_struct *tty, struct file * filp) -{ - struct sgi_serial * info = (struct sgi_serial *)tty->driver_data; - unsigned long flags; - - if (!info || serial_paranoia_check(info, tty->name, "rs_close")) - return; - - save_flags(flags); cli(); - - if (tty_hung_up_p(filp)) { - restore_flags(flags); - return; - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_close ttys%d, count = %d\n", info->line, info->count); -#endif - if ((tty->count == 1) && (info->count != 1)) { - /* - * Uh, oh. tty->count is 1, which means that the tty - * structure will be freed. Info->count should always - * be one in these conditions. If it's greater than - * one, we've got real problems, since it means the - * serial port won't be shutdown. - */ - printk("rs_close: bad serial port count; tty->count is 1, " - "info->count is %d\n", info->count); - info->count = 1; - } - if (--info->count < 0) { - printk("rs_close: bad serial port count for ttys%d: %d\n", - info->line, info->count); - info->count = 0; - } - if (info->count) { - restore_flags(flags); - return; - } - info->flags |= ZILOG_CLOSING; - /* - * Now we wait for the transmit buffer to clear; and we notify - * the line discipline to only process XON/XOFF characters. - */ - tty->closing = 1; - if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) - tty_wait_until_sent(tty, info->closing_wait); - /* - * At this point we stop accepting input. To do this, we - * disable the receive line status interrupts, and tell the - * interrupt driver to stop checking the data ready bit in the - * line status register. - */ - /** if (!info->iscons) ... **/ - info->curregs[3] &= ~RxENABLE; - info->pendregs[3] = info->curregs[3]; - write_zsreg(info->zs_channel, 3, info->curregs[3]); - info->curregs[1] &= ~(0x18); - info->pendregs[1] = info->curregs[1]; - write_zsreg(info->zs_channel, 1, info->curregs[1]); - ZS_CLEARFIFO(info->zs_channel); - - shutdown(info); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - if (tty->ldisc.flush_buffer) - tty->ldisc.flush_buffer(tty); - tty->closing = 0; - info->event = 0; - info->tty = 0; - if (tty->ldisc.num != ldiscs[N_TTY].num) { - if (tty->ldisc.close) - (tty->ldisc.close)(tty); - tty->ldisc = ldiscs[N_TTY]; - tty->termios->c_line = N_TTY; - if (tty->ldisc.open) - (tty->ldisc.open)(tty); - } - if (info->blocked_open) { - if (info->close_delay) { - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(info->close_delay); - } - wake_up_interruptible(&info->open_wait); - } - info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CLOSING); - wake_up_interruptible(&info->close_wait); - restore_flags(flags); -} - -/* - * rs_hangup() --- called by tty_hangup() when a hangup is signaled. - */ -void rs_hangup(struct tty_struct *tty) -{ - struct sgi_serial * info = (struct sgi_serial *)tty->driver_data; - - if (serial_paranoia_check(info, tty->name, "rs_hangup")) - return; - - rs_flush_buffer(tty); - shutdown(info); - info->event = 0; - info->count = 0; - info->flags &= ~ZILOG_NORMAL_ACTIVE; - info->tty = 0; - wake_up_interruptible(&info->open_wait); -} - -/* - * ------------------------------------------------------------ - * rs_open() and friends - * ------------------------------------------------------------ - */ -static int block_til_ready(struct tty_struct *tty, struct file * filp, - struct sgi_serial *info) -{ - DECLARE_WAITQUEUE(wait, current); - int retval; - int do_clocal = 0; - - /* - * If the device is in the middle of being closed, then block - * until it's done, and then try again. - */ - if (info->flags & ZILOG_CLOSING) { - interruptible_sleep_on(&info->close_wait); -#ifdef SERIAL_DO_RESTART - if (info->flags & ZILOG_HUP_NOTIFY) - return -EAGAIN; - else - return -ERESTARTSYS; -#else - return -EAGAIN; -#endif - } - - /* - * If non-blocking mode is set, or the port is not enabled, - * then make the check up front and then exit. - */ - if ((filp->f_flags & O_NONBLOCK) || - (tty->flags & (1 << TTY_IO_ERROR))) { - info->flags |= ZILOG_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* - * Block waiting for the carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * rs_close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - retval = 0; - add_wait_queue(&info->open_wait, &wait); -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready before block: ttys%d, count = %d\n", - info->line, info->count); -#endif - info->count--; - info->blocked_open++; - while (1) { - cli(); - zs_rtsdtr(info, 1); - sti(); - set_current_state(TASK_INTERRUPTIBLE); - if (tty_hung_up_p(filp) || - !(info->flags & ZILOG_INITIALIZED)) { -#ifdef SERIAL_DO_RESTART - if (info->flags & ZILOG_HUP_NOTIFY) - retval = -EAGAIN; - else - retval = -ERESTARTSYS; -#else - retval = -EAGAIN; -#endif - break; - } - if (!(info->flags & ZILOG_CLOSING) && do_clocal) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready blocking: ttys%d, count = %d\n", - info->line, info->count); -#endif - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(&info->open_wait, &wait); - if (!tty_hung_up_p(filp)) - info->count++; - info->blocked_open--; -#ifdef SERIAL_DEBUG_OPEN - printk("block_til_ready after blocking: ttys%d, count = %d\n", - info->line, info->count); -#endif - if (retval) - return retval; - info->flags |= ZILOG_NORMAL_ACTIVE; - return 0; -} - -/* - * This routine is called whenever a serial port is opened. It - * enables interrupts for a serial port, linking in its ZILOG structure into - * the IRQ chain. It also performs the serial-specific - * initialization for the tty structure. - */ -int rs_open(struct tty_struct *tty, struct file * filp) -{ - struct sgi_serial *info; - int retval, line; - - line = tty->index; - /* The zilog lines for the mouse/keyboard must be - * opened using their respective drivers. - */ - if ((line < 0) || (line >= NUM_CHANNELS)) - return -ENODEV; - info = zs_soft + line; - /* Is the kgdb running over this line? */ - if (info->kgdb_channel) - return -ENODEV; - if (serial_paranoia_check(info, tty->name, "rs_open")) - return -ENODEV; -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s, count = %d\n", tty->name, info->count); -#endif - info->count++; - tty->driver_data = info; - info->tty = tty; - - /* - * Start up serial port - */ - retval = startup(info); - if (retval) - return retval; - - retval = block_til_ready(tty, filp, info); - if (retval) { -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open returning after block_til_ready with %d\n", - retval); -#endif - return retval; - } - - /* If this is the serial console change the speed to - * the right value - */ - if (info->is_cons) { - info->tty->termios->c_cflag = sgisercon->cflag; - change_speed(info); - } - -#ifdef SERIAL_DEBUG_OPEN - printk("rs_open %s successful...\n", tty->name); -#endif - return 0; -} - -/* Finally, routines used to initialize the serial driver. */ - -static void show_serial_version(void) -{ - printk("SGI Zilog8530 serial driver version 1.00\n"); -} - -/* Return layout for the requested zs chip number. */ -static inline struct sgi_zslayout *get_zs(int chip) -{ - extern struct hpc3_miscregs *hpc3mregs; - - if (chip > 0) - panic("Wheee, bogus zs chip number requested."); - - return (struct sgi_zslayout *) (&hpc3mregs->ser1cmd); -} - - -static inline void -rs_cons_check(struct sgi_serial *ss, int channel) -{ - int i, o, io; - static int msg_printed = 0; - - i = o = io = 0; - - /* Is this one of the serial console lines? */ - if((zs_cons_chanout != channel) && - (zs_cons_chanin != channel)) - return; - zs_conschan = ss->zs_channel; - zs_consinfo = ss; - - - - /* If this is console input, we handle the break received - * status interrupt on this line to mean prom_halt(). - */ - if(zs_cons_chanin == channel) { - ss->break_abort = 1; - i = 1; - } - if(o && i) - io = 1; - - /* Set flag variable for this port so that it cannot be - * opened for other uses by accident. - */ - ss->is_cons = 1; - - if(io) { - if (!msg_printed) { - printk("zs%d: console I/O\n", ((channel>>1)&1)); - msg_printed = 1; - } - - } else { - printk("zs%d: console %s\n", ((channel>>1)&1), - (i==1 ? "input" : (o==1 ? "output" : "WEIRD"))); - } -} - -static struct tty_operations serial_ops = { - .open = rs_open, - .close = rs_close, - .write = rs_write, - .flush_chars = rs_flush_chars, - .write_room = rs_write_room, - .chars_in_buffer = rs_chars_in_buffer, - .flush_buffer = rs_flush_buffer, - .ioctl = rs_ioctl, - .throttle = rs_throttle, - .unthrottle = rs_unthrottle, - .set_termios = rs_set_termios, - .stop = rs_stop, - .start = rs_start, - .hangup = rs_hangup, -}; - -/* rs_init inits the driver */ -int rs_init(void) -{ - int chip, channel, i, flags; - struct sgi_serial *info; - - serial_driver = tty_alloc_serial(NUM_CHANNELS); - if (!serial_driver) - return -ENOMEM; - - /* Setup base handler, and timer table. */ - init_bh(SERIAL_BH, do_serial_bh); - - show_serial_version(); - - /* Initialize the tty_driver structure */ - /* SGI: Not all of this is exactly right for us. */ - - serial_driver->owner = THIS_MODULE; - serial_driver->name = "ttyS"; - serial_driver->major = TTY_MAJOR; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - - tty_set_operations(serial_driver, &serial_ops); - - if (tty_register_driver(serial_driver)) - panic("Couldn't register serial driver\n"); - - save_flags(flags); cli(); - - /* Set up our interrupt linked list */ - zs_chain = &zs_soft[0]; - zs_soft[0].zs_next = &zs_soft[1]; - zs_soft[1].zs_next = 0; - - for(chip = 0; chip < NUM_SERIAL; chip++) { - /* If we are doing kgdb over one of the channels on - * chip zero, kgdb_channel will be set to 1 by the - * rs_kgdb_hook() routine below. - */ - if(!zs_chips[chip]) { - zs_chips[chip] = get_zs(chip); - /* Two channels per chip */ - zs_channels[(chip*2)] = &zs_chips[chip]->channelB; - zs_channels[(chip*2)+1] = &zs_chips[chip]->channelA; - zs_soft[(chip*2)].kgdb_channel = 0; - zs_soft[(chip*2)+1].kgdb_channel = 0; - } - /* First, set up channel A on this chip. */ - channel = chip * 2; - zs_soft[channel].zs_channel = zs_channels[channel]; - zs_soft[channel].change_needed = 0; - zs_soft[channel].clk_divisor = 16; - zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); - zs_soft[channel].cons_mouse = 0; - /* If not keyboard/mouse and is console serial - * line, then enable receiver interrupts. - */ - if(zs_soft[channel].is_cons) { - write_zsreg(zs_soft[channel].zs_channel, R1, - (EXT_INT_ENAB | INT_ALL_Rx)); - write_zsreg(zs_soft[channel].zs_channel, R9, (NV | MIE)); - write_zsreg(zs_soft[channel].zs_channel, R10, (NRZ)); - write_zsreg(zs_soft[channel].zs_channel, R3, (Rx8|RxENABLE)); - write_zsreg(zs_soft[channel].zs_channel, R5, (Tx8 | TxENAB)); - } - /* If this is the kgdb line, enable interrupts because we - * now want to receive the 'control-c' character from the - * client attached to us asynchronously. - */ - if(zs_soft[channel].kgdb_channel) - kgdb_chaninit(&zs_soft[channel], 1, - zs_soft[channel].zs_baud); - - /* Now, channel B */ - channel++; - zs_soft[channel].zs_channel = zs_channels[channel]; - zs_soft[channel].change_needed = 0; - zs_soft[channel].clk_divisor = 16; - zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); - zs_soft[channel].cons_keyb = 0; - /* If console serial line, then enable receiver interrupts. */ - if(zs_soft[channel].is_cons) { - write_zsreg(zs_soft[channel].zs_channel, R1, - (EXT_INT_ENAB | INT_ALL_Rx)); - write_zsreg(zs_soft[channel].zs_channel, R9, - (NV | MIE)); - write_zsreg(zs_soft[channel].zs_channel, R10, - (NRZ)); - write_zsreg(zs_soft[channel].zs_channel, R3, - (Rx8|RxENABLE)); - write_zsreg(zs_soft[channel].zs_channel, R5, - (Tx8 | TxENAB | RTS | DTR)); - } - } - - for(info=zs_chain, i=0; info; info = info->zs_next, i++) - { - info->magic = SERIAL_MAGIC; - info->port = (int) info->zs_channel; - info->line = i; - info->tty = 0; - info->irq = zilog_irq; - info->custom_divisor = 16; - info->close_delay = 50; - info->closing_wait = 3000; - info->x_char = 0; - info->event = 0; - info->count = 0; - info->blocked_open = 0; - info->tqueue.routine = do_softint; - info->tqueue.data = info; - info->tqueue_hangup.routine = do_serial_hangup; - info->tqueue_hangup.data = info; - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - printk("tty%02d at 0x%04x (irq = %d)", info->line, - info->port, info->irq); - printk(" is a Zilog8530\n"); - } - - if (request_irq(zilog_irq, rs_interrupt, (SA_INTERRUPT), - "Zilog8530", zs_chain)) - panic("Unable to attach zs intr\n"); - restore_flags(flags); - - return 0; -} - -/* - * register_serial and unregister_serial allows for serial ports to be - * configured at run-time, to support PCMCIA modems. - */ -/* SGI: Unused at this time, just here to make things link. */ -int register_serial(struct serial_struct *req) -{ - return -1; -} - -void unregister_serial(int line) -{ - return; -} - -/* Hooks for running a serial console. con_init() calls this if the - * console is being run over one of the ttya/ttyb serial ports. - * 'chip' should be zero, as chip 1 drives the mouse/keyboard. - * 'channel' is decoded as 0=TTYA 1=TTYB, note that the channels - * are addressed backwards, channel B is first, then channel A. - */ -void -rs_cons_hook(int chip, int out, int line) -{ - int channel; - - if(chip) - panic("rs_cons_hook called with chip not zero"); - if(line != 0 && line != 1) - panic("rs_cons_hook called with line not ttya or ttyb"); - channel = line; - if(!zs_chips[chip]) { - zs_chips[chip] = get_zs(chip); - /* Two channels per chip */ - zs_channels[(chip*2)] = &zs_chips[chip]->channelB; - zs_channels[(chip*2)+1] = &zs_chips[chip]->channelA; - } - zs_soft[channel].zs_channel = zs_channels[channel]; - zs_soft[channel].change_needed = 0; - zs_soft[channel].clk_divisor = 16; - zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]); - if(out) - zs_cons_chanout = ((chip * 2) + channel); - else - zs_cons_chanin = ((chip * 2) + channel); - - rs_cons_check(&zs_soft[channel], channel); -} - -/* This is called at boot time to prime the kgdb serial debugging - * serial line. The 'tty_num' argument is 0 for /dev/ttyd2 and 1 for - * /dev/ttyd1 (yes they are backwards on purpose) which is determined - * in setup_arch() from the boot command line flags. - */ -void -rs_kgdb_hook(int tty_num) -{ - int chip = 0; - - if(!zs_chips[chip]) { - zs_chips[chip] = get_zs(chip); - /* Two channels per chip */ - zs_channels[(chip*2)] = &zs_chips[chip]->channelA; - zs_channels[(chip*2)+1] = &zs_chips[chip]->channelB; - } - zs_soft[tty_num].zs_channel = zs_channels[tty_num]; - zs_kgdbchan = zs_soft[tty_num].zs_channel; - zs_soft[tty_num].change_needed = 0; - zs_soft[tty_num].clk_divisor = 16; - zs_soft[tty_num].zs_baud = get_zsbaud(&zs_soft[tty_num]); - zs_soft[tty_num].kgdb_channel = 1; /* This runs kgdb */ - zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */ - - /* Turn on transmitter/receiver at 8-bits/char */ - kgdb_chaninit(&zs_soft[tty_num], 0, 9600); - ZS_CLEARERR(zs_kgdbchan); - udelay(5); - ZS_CLEARFIFO(zs_kgdbchan); -} - -static void zs_console_write(struct console *co, const char *str, - unsigned int count) -{ - - while(count--) { - if(*str == '\n') - zs_cons_put_char('\r'); - zs_cons_put_char(*str++); - } - - /* Comment this if you want to have a strict interrupt-driven output */ - rs_fair_output(); -} - -static struct tty_driver *zs_console_device(struct console *con, int *index) -{ - *index = con->index; - return serial_driver; -} - - -static int __init zs_console_setup(struct console *con, char *options) -{ - struct sgi_serial *info; - int baud; - int bits = 8; - int parity = 'n'; - int cflag = CREAD | HUPCL | CLOCAL; - char *s, *dbaud; - int i, brg; - - if (options) { - baud = simple_strtoul(options, NULL, 10); - s = options; - while(*s >= '0' && *s <= '9') - s++; - if (*s) parity = *s++; - if (*s) bits = *s - '0'; - } - else { - /* If the user doesn't set console=... try to read the - * PROM variable - if this fails use 9600 baud and - * inform the user about the problem - */ - dbaud = ArcGetEnvironmentVariable("dbaud"); - if(dbaud) baud = simple_strtoul(dbaud, NULL, 10); - else { - /* Use prom_printf() to make sure that the user - * is getting anything ... - */ - prom_printf("No dbaud set in PROM ?!? Using 9600.\n"); - baud = 9600; - } - } - - /* - * Now construct a cflag setting. - */ - switch(baud) { - case 1200: - cflag |= B1200; - break; - case 2400: - cflag |= B2400; - break; - case 4800: - cflag |= B4800; - break; - case 19200: - cflag |= B19200; - break; - case 38400: - cflag |= B38400; - break; - case 57600: - cflag |= B57600; - break; - case 115200: - cflag |= B115200; - break; - case 9600: - default: - cflag |= B9600; - break; - } - switch(bits) { - case 7: - cflag |= CS7; - break; - default: - case 8: - cflag |= CS8; - break; - } - switch(parity) { - case 'o': case 'O': - cflag |= PARODD; - break; - case 'e': case 'E': - cflag |= PARENB; - break; - } - con->cflag = cflag; - - rs_cons_hook(0, 0, con->index); - info = zs_soft + con->index; - info->is_cons = 1; - - printk("Console: ttyS%d (Zilog8530), %d baud\n", - info->line, baud); - - i = con->cflag & CBAUD; - if (con->cflag & CBAUDEX) { - i &= ~CBAUDEX; - con->cflag &= ~CBAUDEX; - } - info->zs_baud = baud; - - switch (con->cflag & CSIZE) { - case CS5: - zscons_regs[3] = Rx5 | RxENABLE; - zscons_regs[5] = Tx5 | TxENAB; - break; - case CS6: - zscons_regs[3] = Rx6 | RxENABLE; - zscons_regs[5] = Tx6 | TxENAB; - break; - case CS7: - zscons_regs[3] = Rx7 | RxENABLE; - zscons_regs[5] = Tx7 | TxENAB; - break; - default: - case CS8: - zscons_regs[3] = Rx8 | RxENABLE; - zscons_regs[5] = Tx8 | TxENAB; - break; - } - zscons_regs[5] |= DTR; - - if (con->cflag & PARENB) - zscons_regs[4] |= PAR_ENA; - if (!(con->cflag & PARODD)) - zscons_regs[4] |= PAR_EVEN; - - if (con->cflag & CSTOPB) - zscons_regs[4] |= SB2; - else - zscons_regs[4] |= SB1; - - sgisercon = con; - - brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor); - zscons_regs[12] = brg & 0xff; - zscons_regs[13] = (brg >> 8) & 0xff; - memcpy(info->curregs, zscons_regs, sizeof(zscons_regs)); - memcpy(info->pendregs, zscons_regs, sizeof(zscons_regs)); - load_zsregs(info->zs_channel, zscons_regs); - ZS_CLEARERR(info->zs_channel); - ZS_CLEARFIFO(info->zs_channel); - return 0; -} - -static struct console sgi_console_driver = { - .name = "ttyS", - .write = zs_console_write, - .device = zs_console_device, - .setup = zs_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -/* - * Register console. - */ -static void __init sgi_serial_console_init(void) -{ - register_console(&sgi_console_driver); -} -console_initcall(sgi_serial_console_init); - -__initcall(rs_init); diff -Nru a/drivers/sgi/char/sgiserial.h b/drivers/sgi/char/sgiserial.h --- a/drivers/sgi/char/sgiserial.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,447 +0,0 @@ -/* sgiserial.h: Definitions for the SGI Zilog85C30 serial driver. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - */ -#ifndef _SGI_SERIAL_H -#define _SGI_SERIAL_H - -/* Just one channel */ -struct sgi_zschannel { -#ifdef __MIPSEB__ - volatile unsigned char unused0[3]; - volatile unsigned char control; - volatile unsigned char unused1[3]; - volatile unsigned char data; -#else /* __MIPSEL__ */ - volatile unsigned char control; - volatile unsigned char unused0[3]; - volatile unsigned char data; - volatile unsigned char unused1[3]; -#endif -}; - -/* The address space layout for each zs chip. Yes they are - * backwards. - */ -struct sgi_zslayout { - struct sgi_zschannel channelB; - struct sgi_zschannel channelA; -}; - -#define NUM_ZSREGS 16 - -struct serial_struct { - int type; - int line; - int port; - int irq; - int flags; - int xmit_fifo_size; - int custom_divisor; - int baud_base; - unsigned short close_delay; - char reserved_char[2]; - int hub6; - unsigned short closing_wait; /* time to wait before closing */ - unsigned short closing_wait2; /* no longer used... */ - int reserved[4]; -}; - -/* - * For the close wait times, 0 means wait forever for serial port to - * flush its output. 65535 means don't wait at all. - */ -#define ZILOG_CLOSING_WAIT_INF 0 -#define ZILOG_CLOSING_WAIT_NONE 65535 - -/* - * Definitions for ZILOG_struct (and serial_struct) flags field - */ -#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes - on the callout port */ -#define ZILOG_FOURPORT 0x0002 /* Set OU1, OUT2 per AST Fourport settings */ -#define ZILOG_SAK 0x0004 /* Secure Attention Key (Orange book) */ -#define ZILOG_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */ - -#define ZILOG_SPD_MASK 0x0030 -#define ZILOG_SPD_HI 0x0010 /* Use 56000 instead of 38400 bps */ - -#define ZILOG_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */ -#define ZILOG_SPD_CUST 0x0030 /* Use user-specified divisor */ - -#define ZILOG_SKIP_TEST 0x0040 /* Skip UART test during autoconfiguration */ -#define ZILOG_AUTO_IRQ 0x0080 /* Do automatic IRQ during autoconfiguration */ -#define ZILOG_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */ -#define ZILOG_PGRP_LOCKOUT 0x0200 /* Lock out cua opens based on pgrp */ -#define ZILOG_CALLOUT_NOHUP 0x0400 /* Don't do hangups for cua device */ - -#define ZILOG_FLAGS 0x0FFF /* Possible legal ZILOG flags */ -#define ZILOG_USR_MASK 0x0430 /* Legal flags that non-privileged - * users can set or reset */ - -/* Internal flags used only by kernel/chr_drv/serial.c */ -#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */ -#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ -#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ -#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ -#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */ -#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */ -#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */ - -/* Software state per channel */ - -#ifdef __KERNEL__ -/* - * This is our internal structure for each serial port's state. - * - * Many fields are paralleled by the structure used by the serial_struct - * structure. - * - * For definitions of the flags field, see tty.h - */ - -struct sgi_serial { - struct sgi_serial *zs_next; /* For IRQ servicing chain */ - struct sgi_zschannel *zs_channel; /* Channel registers */ - unsigned char read_reg_zero; - - char soft_carrier; /* Use soft carrier on this channel */ - char cons_keyb; /* Channel runs the keyboard */ - char cons_mouse; /* Channel runs the mouse */ - char break_abort; /* Is serial console in, so process brk/abrt */ - char kgdb_channel; /* Kgdb is running on this channel */ - char is_cons; /* Is this our console. */ - - /* We need to know the current clock divisor - * to read the bps rate the chip has currently - * loaded. - */ - unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */ - int zs_baud; - - /* Current write register values */ - unsigned char curregs[NUM_ZSREGS]; - - /* Values we need to set next opportunity */ - unsigned char pendregs[NUM_ZSREGS]; - - char change_needed; - - int magic; - int baud_base; - int port; - int irq; - int flags; /* defined in tty.h */ - int type; /* UART type */ - struct tty_struct *tty; - int read_status_mask; - int ignore_status_mask; - int timeout; - int xmit_fifo_size; - int custom_divisor; - int x_char; /* xon/xoff character */ - int close_delay; - unsigned short closing_wait; - unsigned short closing_wait2; - unsigned long event; - unsigned long last_active; - int line; - int count; /* # of fd on device */ - int blocked_open; /* # of blocked opens */ - unsigned char *xmit_buf; - int xmit_head; - int xmit_tail; - int xmit_cnt; - struct tq_struct tqueue; - struct tq_struct tqueue_hangup; - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; -}; - - -#define SERIAL_MAGIC 0x5301 - -/* - * The size of the serial xmit buffer is 1 page, or 4096 bytes - */ -#define SERIAL_XMIT_SIZE 4096 - -/* - * Events are used to schedule things to happen at timer-interrupt - * time, instead of at rs interrupt time. - */ -#define RS_EVENT_WRITE_WAKEUP 0 - -#endif /* __KERNEL__ */ - -/* Conversion routines to/from brg time constants from/to bits - * per second. - */ -#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) -#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) - -/* The Zilog register set */ - -#define FLAG 0x7e - -/* Write Register 0 */ -#define R0 0 /* Register selects */ -#define R1 1 -#define R2 2 -#define R3 3 -#define R4 4 -#define R5 5 -#define R6 6 -#define R7 7 -#define R8 8 -#define R9 9 -#define R10 10 -#define R11 11 -#define R12 12 -#define R13 13 -#define R14 14 -#define R15 15 - -#define NULLCODE 0 /* Null Code */ -#define POINT_HIGH 0x8 /* Select upper half of registers */ -#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ -#define SEND_ABORT 0x18 /* HDLC Abort */ -#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ -#define RES_Tx_P 0x28 /* Reset TxINT Pending */ -#define ERR_RES 0x30 /* Error Reset */ -#define RES_H_IUS 0x38 /* Reset highest IUS */ - -#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ -#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ -#define RES_EOM_L 0xC0 /* Reset EOM latch */ - -/* Write Register 1 */ - -#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ -#define TxINT_ENAB 0x2 /* Tx Int Enable */ -#define PAR_SPEC 0x4 /* Parity is special condition */ - -#define RxINT_DISAB 0 /* Rx Int Disable */ -#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ -#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ -#define INT_ERR_Rx 0x18 /* Int on error only */ - -#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ -#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ -#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */ - -/* Write Register #2 (Interrupt Vector) */ - -/* Write Register 3 */ - -#define RxENABLE 0x1 /* Rx Enable */ -#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ -#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ -#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ -#define ENT_HM 0x10 /* Enter Hunt Mode */ -#define AUTO_ENAB 0x20 /* Auto Enables */ -#define Rx5 0x0 /* Rx 5 Bits/Character */ -#define Rx7 0x40 /* Rx 7 Bits/Character */ -#define Rx6 0x80 /* Rx 6 Bits/Character */ -#define Rx8 0xc0 /* Rx 8 Bits/Character */ - -/* Write Register 4 */ - -#define PAR_ENA 0x1 /* Parity Enable */ -#define PAR_EVEN 0x2 /* Parity Even/Odd* */ - -#define SYNC_ENAB 0 /* Sync Modes Enable */ -#define SB1 0x4 /* 1 stop bit/char */ -#define SB15 0x8 /* 1.5 stop bits/char */ -#define SB2 0xc /* 2 stop bits/char */ - -#define MONSYNC 0 /* 8 Bit Sync character */ -#define BISYNC 0x10 /* 16 bit sync character */ -#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ -#define EXTSYNC 0x30 /* External Sync Mode */ - -#define X1CLK 0x0 /* x1 clock mode */ -#define X16CLK 0x40 /* x16 clock mode */ -#define X32CLK 0x80 /* x32 clock mode */ -#define X64CLK 0xC0 /* x64 clock mode */ - -/* Write Register 5 */ - -#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ -#define RTS 0x2 /* RTS */ -#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ -#define TxENAB 0x8 /* Tx Enable */ -#define SND_BRK 0x10 /* Send Break */ -#define Tx5 0x0 /* Tx 5 bits (or less)/character */ -#define Tx7 0x20 /* Tx 7 bits/character */ -#define Tx6 0x40 /* Tx 6 bits/character */ -#define Tx8 0x60 /* Tx 8 bits/character */ -#define DTR 0x80 /* DTR */ - -/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ - -/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ - -/* Write Register 8 (transmit buffer) */ - -/* Write Register 9 (Master interrupt control) */ -#define VIS 1 /* Vector Includes Status */ -#define NV 2 /* No Vector */ -#define DLC 4 /* Disable Lower Chain */ -#define MIE 8 /* Master Interrupt Enable */ -#define STATHI 0x10 /* Status high */ -#define NORESET 0 /* No reset on write to R9 */ -#define CHRB 0x40 /* Reset channel B */ -#define CHRA 0x80 /* Reset channel A */ -#define FHWRES 0xc0 /* Force hardware reset */ - -/* Write Register 10 (misc control bits) */ -#define BIT6 1 /* 6 bit/8bit sync */ -#define LOOPMODE 2 /* SDLC Loop mode */ -#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ -#define MARKIDLE 8 /* Mark/flag on idle */ -#define GAOP 0x10 /* Go active on poll */ -#define NRZ 0 /* NRZ mode */ -#define NRZI 0x20 /* NRZI mode */ -#define FM1 0x40 /* FM1 (transition = 1) */ -#define FM0 0x60 /* FM0 (transition = 0) */ -#define CRCPS 0x80 /* CRC Preset I/O */ - -/* Write Register 11 (Clock Mode control) */ -#define TRxCXT 0 /* TRxC = Xtal output */ -#define TRxCTC 1 /* TRxC = Transmit clock */ -#define TRxCBR 2 /* TRxC = BR Generator Output */ -#define TRxCDP 3 /* TRxC = DPLL output */ -#define TRxCOI 4 /* TRxC O/I */ -#define TCRTxCP 0 /* Transmit clock = RTxC pin */ -#define TCTRxCP 8 /* Transmit clock = TRxC pin */ -#define TCBR 0x10 /* Transmit clock = BR Generator output */ -#define TCDPLL 0x18 /* Transmit clock = DPLL output */ -#define RCRTxCP 0 /* Receive clock = RTxC pin */ -#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ -#define RCBR 0x40 /* Receive clock = BR Generator output */ -#define RCDPLL 0x60 /* Receive clock = DPLL output */ -#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ - -/* Write Register 12 (lower byte of baud rate generator time constant) */ - -/* Write Register 13 (upper byte of baud rate generator time constant) */ - -/* Write Register 14 (Misc control bits) */ -#define BRENABL 1 /* Baud rate generator enable */ -#define BRSRC 2 /* Baud rate generator source */ -#define DTRREQ 4 /* DTR/Request function */ -#define AUTOECHO 8 /* Auto Echo */ -#define LOOPBAK 0x10 /* Local loopback */ -#define SEARCH 0x20 /* Enter search mode */ -#define RMC 0x40 /* Reset missing clock */ -#define DISDPLL 0x60 /* Disable DPLL */ -#define SSBR 0x80 /* Set DPLL source = BR generator */ -#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ -#define SFMM 0xc0 /* Set FM mode */ -#define SNRZI 0xe0 /* Set NRZI mode */ - -/* Write Register 15 (external/status interrupt control) */ -#define ZCIE 2 /* Zero count IE */ -#define DCDIE 8 /* DCD IE */ -#define SYNCIE 0x10 /* Sync/hunt IE */ -#define CTSIE 0x20 /* CTS IE */ -#define TxUIE 0x40 /* Tx Underrun/EOM IE */ -#define BRKIE 0x80 /* Break/Abort IE */ - - -/* Read Register 0 */ -#define Rx_CH_AV 0x1 /* Rx Character Available */ -#define ZCOUNT 0x2 /* Zero count */ -#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ -#define DCD 0x8 /* DCD */ -#define SYNC 0x10 /* Sync/hunt */ -#define CTS 0x20 /* CTS */ -#define TxEOM 0x40 /* Tx underrun */ -#define BRK_ABRT 0x80 /* Break/Abort */ - -/* Read Register 1 */ -#define ALL_SNT 0x1 /* All sent */ -/* Residue Data for 8 Rx bits/char programmed */ -#define RES3 0x8 /* 0/3 */ -#define RES4 0x4 /* 0/4 */ -#define RES5 0xc /* 0/5 */ -#define RES6 0x2 /* 0/6 */ -#define RES7 0xa /* 0/7 */ -#define RES8 0x6 /* 0/8 */ -#define RES18 0xe /* 1/8 */ -#define RES28 0x0 /* 2/8 */ -/* Special Rx Condition Interrupts */ -#define PAR_ERR 0x10 /* Parity error */ -#define Rx_OVR 0x20 /* Rx Overrun Error */ -#define CRC_ERR 0x40 /* CRC/Framing Error */ -#define END_FR 0x80 /* End of Frame (SDLC) */ - -/* Read Register 2 (channel b only) - Interrupt vector */ - -/* Read Register 3 (interrupt pending register) ch a only */ -#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ -#define CHBTxIP 0x2 /* Channel B Tx IP */ -#define CHBRxIP 0x4 /* Channel B Rx IP */ -#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ -#define CHATxIP 0x10 /* Channel A Tx IP */ -#define CHARxIP 0x20 /* Channel A Rx IP */ - -/* Read Register 8 (receive data register) */ - -/* Read Register 10 (misc status bits) */ -#define ONLOOP 2 /* On loop */ -#define LOOPSEND 0x10 /* Loop sending */ -#define CLK2MIS 0x40 /* Two clocks missing */ -#define CLK1MIS 0x80 /* One clock missing */ - -/* Read Register 12 (lower byte of baud rate generator constant) */ - -/* Read Register 13 (upper byte of baud rate generator constant) */ - -/* Read Register 15 (value of WR 15) */ - -/* Misc inlines */ -extern inline void ZS_CLEARERR(struct sgi_zschannel *channel) -{ - volatile unsigned char junk; - - udelay(2); - channel->control = ERR_RES; - if (ioc_icontrol) - junk = ioc_icontrol->istat0; -} - -extern inline void ZS_CLEARFIFO(struct sgi_zschannel *channel) -{ - volatile unsigned char junk; - - udelay(2); - junk = channel->data; - udelay(2); - if (ioc_icontrol) - junk = ioc_icontrol->istat0; - junk = channel->data; - udelay(2); - if (ioc_icontrol) - junk = ioc_icontrol->istat0; - junk = channel->data; - udelay(2); - if (ioc_icontrol) - junk = ioc_icontrol->istat0; -} - -#if 0 - -#define ZS_CLEARERR(channel) (channel->control = ERR_RES) -#define ZS_CLEARFIFO(channel) do { volatile unsigned char garbage; \ - garbage = channel->data; \ - udelay(2); \ - garbage = channel->data; \ - udelay(2); \ - garbage = channel->data; \ - udelay(2); } while(0) - -#endif - -#endif /* !(_SPARC_SERIAL_H) */ diff -Nru a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c --- a/drivers/sgi/char/shmiq.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,478 +0,0 @@ -/* - * shmiq.c: shared memory input queue driver - * written 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * We implement /dev/shmiq, /dev/qcntlN here - * this is different from IRIX that has shmiq as a misc - * streams device and the and qcntl devices as a major device. - * - * minor number 0 implements /dev/shmiq, - * any other number implements /dev/qcntl${minor-1} - * - * /dev/shmiq is used by the X server for two things: - * - * 1. for I_LINK()ing trough ioctl the file handle of a - * STREAMS device. - * - * 2. To send STREAMS-commands to the devices with the - * QIO ioctl interface. - * - * I have not yet figured how to make multiple X servers share - * /dev/shmiq for having different servers running. So, for now - * I keep a kernel-global array of inodes that are pushed into - * /dev/shmiq. - * - * /dev/qcntlN is used by the X server for two things: - * - * 1. Issuing the QIOCATTACH for mapping the shared input - * queue into the address space of the X server (yeah, yeah, - * I did not invent this interface). - * - * 2. used by select. I bet it is used for checking for events on - * the queue. - * - * Now the problem is that there does not seem anything that - * establishes a connection between /dev/shmiq and the qcntlN file. I - * need an strace from an X server that runs on a machine with more - * than one keyboard. And this is a problem since the file handles - * are pushed in /dev/shmiq, while the events should be dispatched to - * the /dev/qcntlN device. - * - * Until then, I just allow for 1 qcntl device. - * - */ -#include <linux/fs.h> -#include <linux/miscdevice.h> -#include <linux/sched.h> -#include <linux/file.h> -#include <linux/interrupt.h> -#include <linux/poll.h> -#include <linux/vmalloc.h> -#include <linux/wait.h> -#include <linux/major.h> -#include <linux/module.h> -#include <linux/smp_lock.h> -#include <linux/devfs_fs_kernel.h> - -#include <asm/shmiq.h> -#include <asm/gfx.h> -#include <asm/mman.h> -#include <asm/uaccess.h> -#include <asm/poll.h> -#include "graphics.h" - -/* we are not really getting any more than a few files in the shmiq */ -#define MAX_SHMIQ_DEVS 10 - -/* - * One per X server running, not going to get very big. - * Even if we have this we now assume just 1 /dev/qcntl can be - * active, I need to find how this works on multi-headed machines. - */ -#define MAX_SHMI_QUEUES 4 - -static struct { - int used; - struct file *filp; - struct shmiqsetcpos cpos; -} shmiq_pushed_devices [MAX_SHMIQ_DEVS]; - -/* /dev/qcntlN attached memory regions, location and size of the event queue */ -static struct { - int opened; - void *shmiq_vaddr; /* mapping in kernel-land */ - spinlock_t shmiq_lock:SPIN_LOCK_UNLOCKED; - /* protects vaddr and opened */ - int tail; /* our copy of the shmiq->tail */ - int events; - int mapped; - - wait_queue_head_t proc_list; - struct fasync_struct *fasync; -} shmiqs [MAX_SHMI_QUEUES]; - -void -shmiq_push_event (struct shmqevent *e) -{ - struct sharedMemoryInputQueue *s; - int device = 0; /* FIXME: here is the assumption /dev/shmiq == /dev/qcntl0 */ - int tail_next; - - if (!shmiqs [device].mapped) - return; - s = shmiqs [device].shmiq_vaddr; - - s->flags = 0; - if (s->tail != shmiqs [device].tail){ - s->flags |= SHMIQ_CORRUPTED; - return; - } - tail_next = (s->tail + 1) % (shmiqs [device].events); - - if (tail_next == s->head){ - s->flags |= SHMIQ_OVERFLOW; - return; - } - - e->un.time = jiffies; - s->events [s->tail] = *e; - printk ("KERNEL: dev=%d which=%d type=%d flags=%d\n", - e->data.device, e->data.which, e->data.type, e->data.flags); - s->tail = tail_next; - shmiqs [device].tail = tail_next; - kill_fasync (&shmiqs [device].fasync, SIGIO, POLL_IN); - wake_up_interruptible (&shmiqs [device].proc_list); -} - -static int -shmiq_manage_file (struct file *filp) -{ - int i; - - if (!filp->f_op || !filp->f_op->ioctl) - return -ENOSR; - - for (i = 0; i < MAX_SHMIQ_DEVS; i++){ - if (shmiq_pushed_devices [i].used) - continue; - if ((*filp->f_op->ioctl)(filp->f_dentry->d_inode, filp, SHMIQ_ON, i) != 0) - return -ENOSR; - shmiq_pushed_devices [i].used = 1; - shmiq_pushed_devices [i].filp = filp; - shmiq_pushed_devices [i].cpos.x = 0; - shmiq_pushed_devices [i].cpos.y = 0; - return i; - } - return -ENOSR; -} - -static int -shmiq_forget_file (unsigned long fdes) -{ - struct file *filp; - - if (fdes > MAX_SHMIQ_DEVS) - return -EINVAL; - - if (!shmiq_pushed_devices [fdes].used) - return -EINVAL; - - filp = shmiq_pushed_devices [fdes].filp; - if (filp){ - (*filp->f_op->ioctl)(filp->f_dentry->d_inode, filp, SHMIQ_OFF, 0); - shmiq_pushed_devices [fdes].filp = 0; - fput (filp); - } - shmiq_pushed_devices [fdes].used = 0; - - return 0; -} - -static int -shmiq_sioc (int device, int cmd, struct strioctl *s) -{ - switch (cmd){ - case QIOCGETINDX: - /* - * Ok, we just return the index they are providing us - */ - printk ("QIOCGETINDX: returning %d\n", *(int *)s->ic_dp); - return 0; - - case QIOCIISTR: { - struct muxioctl *mux = (struct muxioctl *) s->ic_dp; - - printk ("Double indirect ioctl: [%d, %x\n", mux->index, mux->realcmd); - return -EINVAL; - } - - case QIOCSETCPOS: { - if (copy_from_user (&shmiq_pushed_devices [device].cpos, s->ic_dp, - sizeof (struct shmiqsetcpos))) - return -EFAULT; - return 0; - } - } - printk ("Unknown I_STR request for shmiq device: 0x%x\n", cmd); - return -EINVAL; -} - -static int -shmiq_ioctl (struct inode *inode, struct file *f, unsigned int cmd, unsigned long arg) -{ - struct file *file; - struct strioctl sioc; - int v; - - switch (cmd){ - /* - * They are giving us the file descriptor for one - * of their streams devices - */ - - case I_LINK: - file = fget (arg); - if (!file) - goto bad_file; - - v = shmiq_manage_file (file); - if (v<0) - fput(file); - return v; - - /* - * Remove a device from our list of managed - * stream devices - */ - case I_UNLINK: - v = shmiq_forget_file (arg); - return v; - - case I_STR: - v = get_sioc (&sioc, arg); - if (v) - return v; - - /* FIXME: This forces device = 0 */ - return shmiq_sioc (0, sioc.ic_cmd, &sioc); - } - - return -EINVAL; - -bad_file: - return -EBADF; -} - -extern long sys_munmap(unsigned long addr, size_t len); - -static int -qcntl_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg, int minor) -{ - struct shmiqreq req; - struct vm_area_struct *vma; - int v; - - switch (cmd) { - /* - * The address space is already mapped as a /dev/zero - * mapping. FIXME: check that /dev/zero is what the user - * had mapped before :-) - */ - case QIOCATTACH: { - unsigned long vaddr; - int s; - - v = verify_area (VERIFY_READ, (void *) arg, - sizeof (struct shmiqreq)); - if (v) - return v; - if (copy_from_user(&req, (void *) arg, sizeof (req))) - return -EFAULT; - /* - * Do not allow to attach to another region if it has - * already been attached - */ - if (shmiqs [minor].mapped) { - printk("SHMIQ:The thingie is already mapped\n"); - return -EINVAL; - } - - vaddr = (unsigned long) req.user_vaddr; - vma = find_vma (current->mm, vaddr); - if (!vma) { - printk ("SHMIQ: could not find %lx the vma\n", - vaddr); - return -EINVAL; - } - s = req.arg * sizeof (struct shmqevent) + - sizeof (struct sharedMemoryInputQueue); - v = sys_munmap (vaddr, s); - down_write(¤t->mm->mmap_sem); - do_munmap(current->mm, vaddr, s); - do_mmap(filp, vaddr, s, PROT_READ | PROT_WRITE, - MAP_PRIVATE|MAP_FIXED, 0); - up_write(¤t->mm->mmap_sem); - shmiqs[minor].events = req.arg; - shmiqs[minor].mapped = 1; - - return 0; - } - } - - return -EINVAL; -} - -struct page * -shmiq_nopage (struct vm_area_struct *vma, unsigned long address, - int write_access) -{ - /* Do not allow for mremap to expand us */ - return NULL; -} - -static struct vm_operations_struct qcntl_mmap = { - .nopage = shmiq_nopage, /* our magic no-page fault handler */ -}; - -static int -shmiq_qcntl_mmap (struct file *file, struct vm_area_struct *vma) -{ - int minor = MINOR (file->f_dentry->d_inode->i_rdev), error; - unsigned int size; - unsigned long mem, start; - - /* mmap is only supported on the qcntl devices */ - if (minor-- == 0) - return -EINVAL; - - if (vma->vm_pgoff != 0) - return -EINVAL; - - size = vma->vm_end - vma->vm_start; - start = vma->vm_start; - mem = vmalloc_uncached (size); - if (!mem) - return -EINVAL; - spin_lock( &shmiqs [minor].shmiq_lock ); - hmiqs [minor].shmiq_vaddr = mem; - - /* Prevent the swapper from considering these pages for swap and touching them */ - vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO); - vma->vm_ops = &qcntl_mmap; - - /* Uncache the pages */ - vma->vm_page_prot = PAGE_USERIO; - - - shmiqs [minor].tail = 0; - /* Init the shared memory input queue */ - spin_unlock( &shmiqs [minor].shmiq_lock ); - memset (shmiqs [minor].shmiq_vaddr, 0, size); - error = vmap_page_range (vma, vma->vm_start, size, mem); - return error; -} - -static int -shmiq_qcntl_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) -{ - int minor = MINOR (inode->i_rdev); - - if (minor-- == 0) - return shmiq_ioctl (inode, filp, cmd, arg); - - return qcntl_ioctl (inode, filp, cmd, arg, minor); -} - -static unsigned int -shmiq_qcntl_poll (struct file *filp, poll_table *wait) -{ - struct sharedMemoryInputQueue *s; - int minor = MINOR (filp->f_dentry->d_inode->i_rdev); - - if (minor-- == 0) - return 0; - - if (!shmiqs [minor].mapped) - return 0; - - poll_wait (filp, &shmiqs [minor].proc_list, wait); - s = shmiqs [minor].shmiq_vaddr; - if (s->head != s->tail) - return POLLIN | POLLRDNORM; - return 0; -} - -static int -shmiq_qcntl_open (struct inode *inode, struct file *filp) -{ - int minor = MINOR (inode->i_rdev); - - if (minor == 0) - return 0; - - minor--; - if (minor > MAX_SHMI_QUEUES) - return -EINVAL; - spin_lock( &shmiqs [minor].shmiq_lock ); - if (shmiqs [minor].opened) - { - spin_unlock( &shmiqs [minor].shmiq_lock ); - return -EBUSY; - } - - shmiqs [minor].opened = 1; - shmiqs [minor].shmiq_vaddr = 0; - spin_unlock( &shmiqs [minor].shmiq_lock ); - - return 0; -} - -static int -shmiq_qcntl_fasync (int fd, struct file *file, int on) -{ - int retval; - int minor = MINOR (file->f_dentry->d_inode->i_rdev); - - retval = fasync_helper (fd, file, on, &shmiqs [minor].fasync); - if (retval < 0) - return retval; - return 0; -} - -static int -shmiq_qcntl_close (struct inode *inode, struct file *filp) -{ - int minor = MINOR (inode->i_rdev); - int j; - - if (minor-- == 0){ - for (j = 0; j < MAX_SHMIQ_DEVS; j++) - shmiq_forget_file (j); - } - - if (minor > MAX_SHMI_QUEUES) - return -EINVAL; - - spin_lock( &shmiqs [minor].shmiq_lock ); - if (shmiqs [minor].opened == 0) { - spin_unlock( &shmiqs [minor].shmiq_lock ); - return -EINVAL; - } - - shmiq_qcntl_fasync (-1, filp, 0); - shmiqs [minor].opened = 0; - shmiqs [minor].mapped = 0; - shmiqs [minor].events = 0; - shmiqs [minor].fasync = 0; - vfree (shmiqs [minor].shmiq_vaddr); - shmiqs [minor].shmiq_vaddr = 0; - spin_unlock( &shmiqs [minor].shmiq_lock ); - - return 0; -} - - -static struct file_operations shmiq_fops = -{ - .poll = shmiq_qcntl_poll, - .ioctl = shmiq_qcntl_ioctl, - .mmap = shmiq_qcntl_mmap, - .open = shmiq_qcntl_open, - .release = shmiq_qcntl_close, - .fasync = shmiq_qcntl_fasync, -}; - -void -shmiq_init (void) -{ - static char names[3] = { "shmiq", "qcntl0", "qcntl1" }; - int i; - printk ("SHMIQ setup\n"); - register_chrdev(SHMIQ_MAJOR, "shmiq", &shmiq_fops); - for (i = 0; i < 3; i++) { - devfs_mk_cdev(MKDEV(SHMIQ_MAJOR, i), - S_IFCHR | S_IRUSR | S_IWUSR, names[i]); - } -} - -EXPORT_SYMBOL(shmiq_init); diff -Nru a/drivers/sgi/char/streamable.c b/drivers/sgi/char/streamable.c --- a/drivers/sgi/char/streamable.c Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,335 +0,0 @@ -/* $Id: streamable.c,v 1.10 2000/02/05 06:47:30 ralf Exp $ - * - * streamable.c: streamable devices. /dev/gfx - * (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * Major 10 is the streams clone device. The IRIX Xsgi server just - * opens /dev/gfx and closes it inmediately. - * - */ - -#include <linux/fs.h> -#include <linux/miscdevice.h> -#include <linux/sched.h> -#include <linux/kbd_kern.h> -#include <linux/vt_kern.h> -#include <linux/smp_lock.h> -#include <asm/uaccess.h> -#include <asm/shmiq.h> -#include <asm/keyboard.h> -#include "graphics.h" - - -extern struct kbd_struct kbd_table [MAX_NR_CONSOLES]; - -/* console number where forwarding is enabled */ -int forward_chars; - -/* To which shmiq this keyboard is assigned */ -int kbd_assigned_device; - -/* previous kbd_mode for the forward_chars terminal */ -int kbd_prev_mode; - -/* Fetchs the strioctl information from user space for I_STR ioctls */ -int -get_sioc (struct strioctl *sioc, unsigned long arg) -{ - int v; - - v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl)); - if (v) - return v; - if (copy_from_user (sioc, (void *) arg, sizeof (struct strioctl))) - return -EFAULT; - - v = verify_area (VERIFY_WRITE, (void *) sioc->ic_dp, sioc->ic_len); - if (v) - return v; - return 0; -} - -/* /dev/gfx device */ -static int -sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - printk ("GFX: ioctl 0x%x %ld called\n", cmd, arg); - return 0; - return -EINVAL; -} - -struct file_operations sgi_gfx_fops = { - .ioctl = sgi_gfx_ioctl, -}; - -static struct miscdevice dev_gfx = { - SGI_GFX_MINOR, "sgi-gfx", &sgi_gfx_fops -}; - -/* /dev/input/keyboard streams device */ -static idevDesc sgi_kbd_desc = { - "keyboard", /* devName */ - "KEYBOARD", /* devType */ - 240, /* nButtons */ - 0, /* nValuators */ - 0, /* nLEDs */ - 0, /* nStrDpys */ - 0, /* nIntDpys */ - 0, /* nBells */ - IDEV_HAS_KEYMAP | IDEV_HAS_PCKBD -}; - -static int -sgi_kbd_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found) -{ - *found = 1; - - switch (cmd){ - - case IDEVINITDEVICE: - return 0; - - case IDEVGETDEVICEDESC: - if (size >= sizeof (idevDesc)){ - if (copy_to_user (data, &sgi_kbd_desc, sizeof (sgi_kbd_desc))) - return -EFAULT; - return 0; - } - return -EINVAL; - - case IDEVGETKEYMAPDESC: - if (size >= sizeof (idevKeymapDesc)){ - if (copy_to_user (data, "US", 3)) - return -EFAULT; - return 0; - } - return -EINVAL; - } - *found = 0; - return -EINVAL; -} - -static int -sgi_keyb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - struct strioctl sioc; - int f, v; - - /* IRIX calls I_PUSH on the opened device, go figure */ - if (cmd == I_PUSH) - return 0; - - if (cmd == I_STR){ - v = get_sioc (&sioc, arg); - if (v) - return v; - - /* Why like this? Because this is a sample piece of code - * that can be copied into other drivers and shows how to - * call a stock IRIX xxx_wioctl routine - * - * The NULL is supposed to be a idevInfo, right now we - * do not support this in our kernel. - */ - return sgi_kbd_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f); - } - - if (cmd == SHMIQ_ON){ - kbd_assigned_device = arg; - forward_chars = fg_console + 1; - kbd_prev_mode = kbd_table [fg_console].kbdmode; - - kbd_table [fg_console].kbdmode = VC_RAW; - } else if (cmd == SHMIQ_OFF && forward_chars){ - kbd_table [forward_chars-1].kbdmode = kbd_prev_mode; - forward_chars = 0; - } else - return -EINVAL; - return 0; -} - -void -kbd_forward_char (int ch) -{ - static struct shmqevent ev; - - ev.data.flags = (ch & 0200) ? 0 : 1; - ev.data.which = ch; - ev.data.device = kbd_assigned_device + 0x11; - shmiq_push_event (&ev); -} - -static int -sgi_keyb_open (struct inode *inode, struct file *file) -{ - /* Nothing, but required by the misc driver */ - return 0; -} - -struct file_operations sgi_keyb_fops = { - .ioctl = sgi_keyb_ioctl, - .open = sgi_keyb_open, -}; - -static struct miscdevice dev_input_keyboard = { - SGI_STREAMS_KEYBOARD, "streams-keyboard", &sgi_keyb_fops -}; - -/* /dev/input/mouse streams device */ -#define MOUSE_VALUATORS 2 -static idevDesc sgi_mouse_desc = { - "mouse", /* devName */ - "MOUSE", /* devType */ - 3, /* nButtons */ - MOUSE_VALUATORS, /* nValuators */ - 0, /* nLEDs */ - 0, /* nStrDpys */ - 0, /* nIntDpys */ - 0, /* nBells */ - 0 /* flags */ -}; - -static idevValuatorDesc mouse_default_valuator = { - 200, /* hwMinRes */ - 200, /* hwMaxRes */ - 0, /* hwMinVal */ - 65000, /* hwMaxVal */ - IDEV_EITHER, /* possibleModes */ - IDEV_ABSOLUTE, /* default mode */ - 200, /* resolution */ - 0, /* minVal */ - 65000 /* maxVal */ -}; - -static int mouse_opened; -static idevValuatorDesc mouse_valuators [MOUSE_VALUATORS]; - -int -sgi_mouse_open (struct inode *inode, struct file *file) -{ - int i; - - if (mouse_opened) - return -EBUSY; - - mouse_opened = 1; - for (i = 0; i < MOUSE_VALUATORS; i++) - mouse_valuators [i] = mouse_default_valuator; - return 0; -} - -static int -sgi_mouse_close (struct inode *inode, struct file *filp) -{ - mouse_opened = 0; - return 0; -} - -static int -sgi_mouse_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found) -{ - *found = 1; - - switch (cmd){ - case IDEVINITDEVICE: - return 0; - - case IDEVGETDEVICEDESC: - if (size >= sizeof (idevDesc)){ - if (copy_to_user (data, &sgi_mouse_desc, sizeof (sgi_mouse_desc))) - return -EFAULT; - return 0; - } - return -EINVAL; - - case IDEVGETVALUATORDESC: { - idevGetSetValDesc request, *ureq = (idevGetSetValDesc *) data; - - if (size < sizeof (idevGetSetValDesc)) - return -EINVAL; - - if (copy_from_user (&request, data, sizeof (request))) - return -EFAULT; - if (request.valNum >= MOUSE_VALUATORS) - return -EINVAL; - if (copy_to_user ((void *)&ureq->desc, - (void *)&mouse_valuators [request.valNum], - sizeof (idevValuatorDesc))) - return -EFAULT; - return 0; - } - } - *found = 0; - return -EINVAL; -} - -static int -sgi_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - struct strioctl sioc; - int f, v; - - /* IRIX calls I_PUSH on the opened device, go figure */ - switch (cmd){ - case I_PUSH: - return 0; - - case I_STR: - v = get_sioc (&sioc, arg); - if (v) - return v; - - /* Why like this? Because this is a sample piece of code - * that can be copied into other drivers and shows how to - * call a stock IRIX xxx_wioctl routine - * - * The NULL is supposed to be a idevInfo, right now we - * do not support this in our kernel. - */ - return sgi_mouse_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f); - - case SHMIQ_ON: - case SHMIQ_OFF: - return 0; - } - return 0; -} - -struct file_operations sgi_mouse_fops = { - .ioctl = sgi_mouse_ioctl, - .open = sgi_mouse_open, - .release = sgi_mouse_close, -}; - -/* /dev/input/mouse */ -static struct miscdevice dev_input_mouse = { - SGI_STREAMS_KEYBOARD, "streams-mouse", &sgi_mouse_fops -}; - -void -streamable_init (void) -{ - if (misc_register (&dev_gfx) < 0) { - printk(KERN_ERR - "streamable: cannot register gfx misc device.\n"); - return; - } - - if (misc_register (&dev_input_keyboard) < 0) { - printk(KERN_ERR - "streamable: cannot register keyboard misc device.\n"); - misc_deregister(&dev_gfx); - return; - } - - if (misc_register (&dev_input_mouse) < 0) { - printk(KERN_ERR - "streamable: cannot register mouse misc device.\n"); - misc_deregister(&dev_input_keyboard); - misc_deregister(&dev_gfx); - return; - } - - printk ("streamable: misc devices registered (keyb:%d, gfx:%d)\n", - SGI_STREAMS_KEYBOARD, SGI_GFX_MINOR); -} diff -Nru a/drivers/sgi/char/usema.c b/drivers/sgi/char/usema.c --- a/drivers/sgi/char/usema.c Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,187 +0,0 @@ -/* - * usema.c: software semaphore driver (see IRIX's usema(7M)) - * written 1997 Mike Shaver (shaver@neon.ingenia.ca) - * 1997 Miguel de Icaza (miguel@kernel.org) - * - * This file contains the implementation of /dev/usemaclone, - * the devices used by IRIX's us* semaphore routines. - * - * /dev/usemaclone is used to create a new semaphore device, and then - * the semaphore is manipulated via ioctls. - * - * At least for the zero-contention case, lock set and unset as well - * as semaphore P and V are done in userland, which makes things a - * little bit better. I suspect that the ioctls are used to register - * the process as blocking, etc. - * - * Much inspiration and structure stolen from Miguel's shmiq work. - * - * For more information: - * usema(7m), usinit(3p), usnewsema(3p) - * /usr/include/sys/usioctl.h - * - */ -#include <linux/fs.h> -#include <linux/miscdevice.h> -#include <linux/sched.h> -#include <linux/file.h> -#include <linux/major.h> -#include <linux/poll.h> -#include <linux/string.h> -#include <linux/dcache.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include "usema.h" - -#include <asm/usioctl.h> -#include <asm/mman.h> -#include <asm/uaccess.h> - -struct irix_usema { - struct file *filp; - wait_queue_head_t proc_list; -}; - - -static int -sgi_usema_attach (usattach_t * attach, struct irix_usema *usema) -{ - int newfd; - newfd = get_unused_fd(); - if (newfd < 0) - return newfd; - - get_file(usema->filp); - fd_install(newfd, usema->filp); - /* Is that it? */ - printk("UIOCATTACHSEMA: new usema fd is %d", newfd); - return newfd; -} - -static int -sgi_usemaclone_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct irix_usema *usema = file->private_data; - int retval; - - printk("[%s:%d] wants ioctl 0x%xd (arg 0x%lx)", - current->comm, current->pid, cmd, arg); - - switch(cmd) { - case UIOCATTACHSEMA: { - /* They pass us information about the semaphore to - which they wish to be attached, and we create&return - a new fd corresponding to the appropriate semaphore. - */ - usattach_t *attach = (usattach_t *)arg; - retval = verify_area(VERIFY_READ, attach, sizeof(usattach_t)); - if (retval) { - printk("[%s:%d] sgi_usema_ioctl(UIOCATTACHSEMA): " - "verify_area failure", - current->comm, current->pid); - return retval; - } - if (usema == 0) - return -EINVAL; - - printk("UIOCATTACHSEMA: attaching usema %p to process %d\n", - usema, current->pid); - /* XXX what is attach->us_handle for? */ - return sgi_usema_attach(attach, usema); - break; - } - case UIOCABLOCK: /* XXX make `async' */ - case UIOCNOIBLOCK: /* XXX maybe? */ - case UIOCBLOCK: { - /* Block this process on the semaphore */ - usattach_t *attach = (usattach_t *)arg; - - retval = verify_area(VERIFY_READ, attach, sizeof(usattach_t)); - if (retval) { - printk("[%s:%d] sgi_usema_ioctl(UIOC*BLOCK): " - "verify_area failure", - current->comm, current->pid); - return retval; - } - printk("UIOC*BLOCK: putting process %d to sleep on usema %p", - current->pid, usema); - if (cmd == UIOCNOIBLOCK) - interruptible_sleep_on(&usema->proc_list); - else - sleep_on(&usema->proc_list); - return 0; - } - case UIOCAUNBLOCK: /* XXX make `async' */ - case UIOCUNBLOCK: { - /* Wake up all process waiting on this semaphore */ - usattach_t *attach = (usattach_t *)arg; - - retval = verify_area(VERIFY_READ, attach, sizeof(usattach_t)); - if (retval) { - printk("[%s:%d] sgi_usema_ioctl(UIOC*BLOCK): " - "verify_area failure", - current->comm, current->pid); - return retval; - } - - printk("[%s:%d] releasing usema %p", - current->comm, current->pid, usema); - wake_up(&usema->proc_list); - return 0; - } - } - return -ENOSYS; -} - -static unsigned int -sgi_usemaclone_poll(struct file *filp, poll_table *wait) -{ - struct irix_usema *usema = filp->private_data; - - printk("[%s:%d] wants to poll usema %p", - current->comm, current->pid, usema); - - return 0; -} - -static int -sgi_usemaclone_open(struct inode *inode, struct file *filp) -{ - struct irix_usema *usema; - - usema = kmalloc (sizeof (struct irix_usema), GFP_KERNEL); - if (!usema) - return -ENOMEM; - - usema->filp = filp; - init_waitqueue_head(&usema->proc_list); - filp->private_data = usema; - - return 0; -} - -struct file_operations sgi_usemaclone_fops = { - .poll = sgi_usemaclone_poll, - .ioctl = sgi_usemaclone_ioctl, - .open = sgi_usemaclone_open, -}; - -static struct miscdevice dev_usemaclone = { - SGI_USEMACLONE, "usemaclone", &sgi_usemaclone_fops -}; - -void -usema_init(void) -{ - if (misc_register(&dev_usemaclone) < 0) { - printk(KERN_ERR "usemaclone: cannot register misc device.\n"); - return; - } - printk("usemaclone misc device registered (minor: %d)\n", - SGI_USEMACLONE); -} - -EXPORT_SYMBOL(usema_init); diff -Nru a/drivers/sgi/char/usema.h b/drivers/sgi/char/usema.h --- a/drivers/sgi/char/usema.h Fri Jun 27 14:19:58 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,10 +0,0 @@ -/* usema.h - * - * Copyright (C) 1996 Alex deVries <puffin@redhat.com> - */ -#ifndef _SGI_USEMA_H -#define _SGI_USEMA_H - -void usema_init (void); - -#endif diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c Fri Jun 27 14:19:59 2003 +++ b/drivers/usb/host/ehci-hcd.c Fri Jun 27 14:19:59 2003 @@ -974,7 +974,7 @@ /* EHCI spec says PCI is required. */ /* PCI driver selection metadata; PCI hotplugging uses this */ -static const struct pci_device_id __devinitdata pci_ids [] = { { +static struct pci_device_id __devinitdata pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c --- a/drivers/usb/host/uhci-debug.c Fri Jun 27 14:19:53 2003 +++ b/drivers/usb/host/uhci-debug.c Fri Jun 27 14:19:53 2003 @@ -513,7 +513,7 @@ } #ifdef CONFIG_PROC_FS -#define MAX_OUTPUT (PAGE_SIZE * 16) +#define MAX_OUTPUT (64 * 1024) static struct proc_dir_entry *uhci_proc_root = NULL; diff -Nru a/drivers/usb/net/cdc-ether.c b/drivers/usb/net/cdc-ether.c --- a/drivers/usb/net/cdc-ether.c Fri Jun 27 14:19:52 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1397 +0,0 @@ -// Portions of this file taken from -// Petko Manolov - Petkan (petkan@dce.bg) -// from his driver pegasus.c - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/types.h> -#include <linux/jiffies.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/usb.h> -#include <linux/module.h> -#include "cdc-ether.h" - -static const char *version = __FILE__ ": v0.98.5 22 Sep 2001 Brad Hards and another"; - -/* Take any CDC device, and sort it out in probe() */ -static struct usb_device_id CDCEther_ids[] = { - { USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) }, - { } /* Terminating null entry */ -}; - -/* - * module parameter that provides an alternate upper limit on the - * number of multicast filters we use, with a default to use all - * the filters available to us. Note that the actual number used - * is the lesser of this parameter and the number returned in the - * descriptor for the particular device. See Table 41 of the CDC - * spec for more info on the descriptor limit. - */ -static int multicast_filter_limit = 32767; - - -////////////////////////////////////////////////////////////////////////////// -// Callback routines from USB device ///////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static void read_bulk_callback( struct urb *urb, struct pt_regs *regs ) -{ - ether_dev_t *ether_dev = urb->context; - struct net_device *net; - int count = urb->actual_length, res; - struct sk_buff *skb; - - // Sanity check - if ( !ether_dev || !(ether_dev->flags & CDC_ETHER_RUNNING) ) { - dbg("BULK IN callback but driver is not active!"); - return; - } - - net = ether_dev->net; - if ( !netif_device_present(net) ) { - // Somebody killed our network interface... - return; - } - - if ( ether_dev->flags & CDC_ETHER_RX_BUSY ) { - // Are we already trying to receive a frame??? - ether_dev->stats.rx_errors++; - dbg("ether_dev Rx busy"); - return; - } - - // We are busy, leave us alone! - ether_dev->flags |= CDC_ETHER_RX_BUSY; - - switch ( urb->status ) { - case 0: - break; - case -ETIMEDOUT: - dbg( "no repsonse in BULK IN" ); - ether_dev->flags &= ~CDC_ETHER_RX_BUSY; - break; - default: - dbg( "%s: RX status %d", net->name, urb->status ); - goto goon; - } - - // Check to make sure we got some data... - if ( !count ) { - // We got no data!!! - goto goon; - } - - // Tell the kernel we want some memory - if ( !(skb = dev_alloc_skb(count)) ) { - // We got no receive buffer. - goto goon; - } - - // Here's where it came from - skb->dev = net; - - // Now we copy it over - eth_copy_and_sum(skb, ether_dev->rx_buff, count, 0); - - // Not sure - skb_put(skb, count); - // Not sure here either - skb->protocol = eth_type_trans(skb, net); - - // Ship it off to the kernel - netif_rx(skb); - - // update out statistics - ether_dev->stats.rx_packets++; - ether_dev->stats.rx_bytes += count; - -goon: - // Prep the USB to wait for another frame - usb_fill_bulk_urb( ether_dev->rx_urb, ether_dev->usb, - usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in), - ether_dev->rx_buff, ether_dev->wMaxSegmentSize, - read_bulk_callback, ether_dev ); - - // Give this to the USB subsystem so it can tell us - // when more data arrives. - if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_ATOMIC)) ) { - warn("%s failed submint rx_urb %d", __FUNCTION__, res); - } - - // We are no longer busy, show us the frames!!! - ether_dev->flags &= ~CDC_ETHER_RX_BUSY; -} - -static void write_bulk_callback( struct urb *urb, struct pt_regs *regs ) -{ - ether_dev_t *ether_dev = urb->context; - - // Sanity check - if ( !ether_dev || !(ether_dev->flags & CDC_ETHER_RUNNING) ) { - // We are insane!!! - err( "write_bulk_callback: device not running" ); - return; - } - - // Do we still have a valid kernel network device? - if ( !netif_device_present(ether_dev->net) ) { - // Someone killed our network interface. - err( "write_bulk_callback: net device not present" ); - return; - } - - // Hmm... What on Earth could have happened??? - if ( urb->status ) { - info("%s: TX status %d", ether_dev->net->name, urb->status); - } - - // Update the network interface and tell it we are - // ready for another frame - ether_dev->net->trans_start = jiffies; - netif_wake_queue( ether_dev->net ); -} - -//static void intr_callback( struct urb *urb ) -//{ -// ether_dev_t *ether_dev = urb->context; -// struct net_device *net; -// __u8 *d; -// -// if ( !ether_dev ) -// return; -// -// switch ( urb->status ) { -// case 0: -// break; -// case -ENOENT: -// return; -// default: -// info("intr status %d", urb->status); -// } -// -// d = urb->transfer_buffer; -// net = ether_dev->net; -// if ( d[0] & 0xfc ) { -// ether_dev->stats.tx_errors++; -// if ( d[0] & TX_UNDERRUN ) -// ether_dev->stats.tx_fifo_errors++; -// if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) ) -// ether_dev->stats.tx_aborted_errors++; -// if ( d[0] & LATE_COL ) -// ether_dev->stats.tx_window_errors++; -// if ( d[0] & (NO_CARRIER | LOSS_CARRIER) ) -// ether_dev->stats.tx_carrier_errors++; -// } -//} - -////////////////////////////////////////////////////////////////////////////// -// Routines for turning net traffic on and off on the USB side /////////////// -////////////////////////////////////////////////////////////////////////////// - -static inline int enable_net_traffic( ether_dev_t *ether_dev ) -{ - struct usb_device *usb = ether_dev->usb; - - // Here would be the time to set the data interface to the configuration where - // it has two endpoints that use a protocol we can understand. - - if (usb_set_interface( usb, - ether_dev->data_bInterfaceNumber, - ether_dev->data_bAlternateSetting_with_traffic ) ) { - err("usb_set_interface() failed" ); - err("Attempted to set interface %d", ether_dev->data_bInterfaceNumber); - err("To alternate setting %d", ether_dev->data_bAlternateSetting_with_traffic); - return -1; - } - return 0; -} - -static inline void disable_net_traffic( ether_dev_t *ether_dev ) -{ - // The thing to do is to set the data interface to the alternate setting that has - // no endpoints. This is what the spec suggests. - - if (ether_dev->data_interface_altset_num_without_traffic >= 0 ) { - if (usb_set_interface( ether_dev->usb, - ether_dev->data_bInterfaceNumber, - ether_dev->data_bAlternateSetting_without_traffic ) ) { - err("usb_set_interface() failed"); - } - } else { - // Some devices just may not support this... - warn("No way to disable net traffic"); - } -} - -////////////////////////////////////////////////////////////////////////////// -// Callback routines for kernel Ethernet Device ////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static void CDCEther_tx_timeout( struct net_device *net ) -{ - ether_dev_t *ether_dev = net->priv; - - // Sanity check - if ( !ether_dev ) { - // Seems to be a case of insanity here - return; - } - - // Tell syslog we are hosed. - warn("%s: Tx timed out.", net->name); - - // Tear the waiting frame off the list - ether_dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; - usb_unlink_urb( ether_dev->tx_urb ); - - // Update statistics - ether_dev->stats.tx_errors++; -} - -static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net ) -{ - ether_dev_t *ether_dev = net->priv; - int res; - - // Tell the kernel, "No more frames 'til we are done - // with this one.' - netif_stop_queue( net ); - - // Copy it from kernel memory to OUR memory - memcpy(ether_dev->tx_buff, skb->data, skb->len); - - // Fill in the URB for shipping it out. - usb_fill_bulk_urb( ether_dev->tx_urb, ether_dev->usb, - usb_sndbulkpipe(ether_dev->usb, ether_dev->data_ep_out), - ether_dev->tx_buff, ether_dev->wMaxSegmentSize, - write_bulk_callback, ether_dev ); - - // Tell the URB how much it will be transporting today - ether_dev->tx_urb->transfer_buffer_length = skb->len; - - /* Deal with the zero length problem, I hope */ - ether_dev->tx_urb->transfer_flags |= URB_ZERO_PACKET; - - // Send the URB on its merry way. - if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_ATOMIC))) { - // Hmm... It didn't go. Tell someone... - warn("failed tx_urb %d", res); - // update some stats... - ether_dev->stats.tx_errors++; - // and tell the kernel to give us another. - // Maybe we'll get it right next time. - netif_start_queue( net ); - } else { - // Okay, it went out. - // Update statistics - ether_dev->stats.tx_packets++; - ether_dev->stats.tx_bytes += skb->len; - // And tell the kernel when the last transmit occurred. - net->trans_start = jiffies; - } - - // We are done with the kernel's memory - dev_kfree_skb(skb); - - // We are done here. - return 0; -} - -static struct net_device_stats *CDCEther_netdev_stats( struct net_device *net ) -{ - // Easy enough! - return &((ether_dev_t *)net->priv)->stats; -} - -static int CDCEther_open(struct net_device *net) -{ - ether_dev_t *ether_dev = (ether_dev_t *)net->priv; - int res; - - // Turn on the USB and let the packets flow!!! - if ( (res = enable_net_traffic( ether_dev )) ) { - err("%s can't enable_net_traffic() - %d", __FUNCTION__, res ); - return -EIO; - } - - // Prep a receive URB - usb_fill_bulk_urb( ether_dev->rx_urb, ether_dev->usb, - usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in), - ether_dev->rx_buff, ether_dev->wMaxSegmentSize, - read_bulk_callback, ether_dev ); - - // Put it out there so the device can send us stuff - if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) ) - { - // Hmm... Okay... - warn("%s failed rx_urb %d", __FUNCTION__, res ); - } - - // Tell the kernel we are ready to start receiving from it - netif_start_queue( net ); - - // We are up and running. - ether_dev->flags |= CDC_ETHER_RUNNING; - - // Let's get ready to move frames!!! - return 0; -} - -static int CDCEther_close( struct net_device *net ) -{ - ether_dev_t *ether_dev = net->priv; - - // We are no longer running. - ether_dev->flags &= ~CDC_ETHER_RUNNING; - - // Tell the kernel to stop sending us stuff - netif_stop_queue( net ); - - // If we are not already unplugged, turn off USB - // traffic - if ( !(ether_dev->flags & CDC_ETHER_UNPLUG) ) { - disable_net_traffic( ether_dev ); - } - - // We don't need the URBs anymore. - usb_unlink_urb( ether_dev->rx_urb ); - usb_unlink_urb( ether_dev->tx_urb ); - usb_unlink_urb( ether_dev->intr_urb ); - - // That's it. I'm done. - return 0; -} - -static int CDCEther_ioctl( struct net_device *net, struct ifreq *rq, int cmd ) -{ - //__u16 *data = (__u16 *)&rq->ifr_data; - //ether_dev_t *ether_dev = net->priv; - - // No support here yet. - // Do we need support??? - switch(cmd) { - case SIOCDEVPRIVATE: - return -EOPNOTSUPP; - case SIOCDEVPRIVATE+1: - return -EOPNOTSUPP; - case SIOCDEVPRIVATE+2: - //return 0; - return -EOPNOTSUPP; - default: - return -EOPNOTSUPP; - } -} - -#if 0 -static void CDC_SetEthernetPacketFilter (ether_dev_t *ether_dev) -{ - usb_control_msg(ether_dev->usb, - usb_sndctrlpipe(ether_dev->usb, 0), - SET_ETHERNET_PACKET_FILTER, /* request */ - USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, /* request type */ - cpu_to_le16(ether_dev->mode_flags), /* value */ - cpu_to_le16((u16)ether_dev->comm_interface), /* index */ - NULL, - 0, /* size */ - HZ); /* timeout */ -} -#endif - - -static void CDCEther_set_multicast( struct net_device *net ) -{ - ether_dev_t *ether_dev = net->priv; - int i; - __u8 *buff; - - - // Tell the kernel to stop sending us frames while we get this - // all set up. -// netif_stop_queue(net); - -// FIXME: We hold xmit_lock. If you want to do the queue stuff you need -// to enable it from a completion handler - - /* Note: do not reorder, GCC is clever about common statements. */ - if (net->flags & IFF_PROMISC) { - /* Unconditionally log net taps. */ - info( "%s: Promiscuous mode enabled", net->name); - ether_dev->mode_flags = MODE_FLAG_PROMISCUOUS | - MODE_FLAG_ALL_MULTICAST | - MODE_FLAG_DIRECTED | - MODE_FLAG_BROADCAST | - MODE_FLAG_MULTICAST; - } else if (net->mc_count > ether_dev->wNumberMCFilters) { - /* Too many to filter perfectly -- accept all multicasts. */ - info("%s: set too many MC filters, using allmulti", net->name); - ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST | - MODE_FLAG_DIRECTED | - MODE_FLAG_BROADCAST | - MODE_FLAG_MULTICAST; - } else if (net->flags & IFF_ALLMULTI) { - /* Filter in software */ - info("%s: using allmulti", net->name); - ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST | - MODE_FLAG_DIRECTED | - MODE_FLAG_BROADCAST | - MODE_FLAG_MULTICAST; - } else { - /* do multicast filtering in hardware */ - struct dev_mc_list *mclist; - info("%s: set multicast filters", net->name); - ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST | - MODE_FLAG_DIRECTED | - MODE_FLAG_BROADCAST | - MODE_FLAG_MULTICAST; - buff = kmalloc(6 * net->mc_count, GFP_ATOMIC); - for (i = 0, mclist = net->mc_list; - mclist && i < net->mc_count; - i++, mclist = mclist->next) { - memcpy(&mclist->dmi_addr, &buff[i * 6], 6); - } -#if 0 - usb_control_msg(ether_dev->usb, -// FIXME: We hold a spinlock. You must not use a synchronous API - usb_sndctrlpipe(ether_dev->usb, 0), - SET_ETHERNET_MULTICAST_FILTER, /* request */ - USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, /* request type */ - cpu_to_le16(net->mc_count), /* value */ - cpu_to_le16((u16)ether_dev->comm_interface), /* index */ - buff, - (6* net->mc_count), /* size */ - HZ); /* timeout */ -#endif - kfree(buff); - } - -#if 0 - CDC_SetEthernetPacketFilter(ether_dev); -#endif - // Tell the kernel to start giving frames to us again. -// netif_wake_queue(net); -} - -////////////////////////////////////////////////////////////////////////////// -// Routines used to parse out the Functional Descriptors ///////////////////// -////////////////////////////////////////////////////////////////////////////// - -static int parse_header_functional_descriptor( int *bFunctionLength, - int bDescriptorType, - int bDescriptorSubtype, - unsigned char *data, - ether_dev_t *ether_dev, - int *requirements ) -{ - // Check to make sure we haven't seen one of these already. - if ( (~*requirements) & REQ_HDR_FUNC_DESCR ) { - err( "Multiple Header Functional Descriptors found." ); - return -1; - } - - // Is it the right size??? - if (*bFunctionLength != 5) { - info( "Invalid length in Header Functional Descriptor" ); - // This is a hack to get around a particular device (NO NAMES) - // It has this function length set to the length of the - // whole class-specific descriptor - *bFunctionLength = 5; - } - - // Nothing extremely useful here. - // We'll keep it for posterity - ether_dev->bcdCDC = data[0] + (data[1] << 8); - dbg( "Found Header descriptor, CDC version %x", ether_dev->bcdCDC); - - // We've seen one of these - *requirements &= ~REQ_HDR_FUNC_DESCR; - - // It's all good. - return 0; -} - -static int parse_union_functional_descriptor( int *bFunctionLength, - int bDescriptorType, - int bDescriptorSubtype, - unsigned char *data, - ether_dev_t *ether_dev, - int *requirements ) -{ - // Check to make sure we haven't seen one of these already. - if ( (~*requirements) & REQ_UNION_FUNC_DESCR ) { - err( "Multiple Union Functional Descriptors found." ); - return -1; - } - - // Is it the right size? - if (*bFunctionLength != 5) { - // It is NOT the size we expected. - err( "Unsupported length in Union Functional Descriptor" ); - return -1; - } - - // Sanity check of sorts - if (ether_dev->comm_interface != data[0]) { - // This tells us that we are chasing the wrong comm - // interface or we are crazy or something else weird. - if (ether_dev->comm_interface == data[1]) { - info( "Probably broken Union descriptor, fudging data interface" ); - // We'll need this in a few microseconds, - // so guess here, and hope for the best - ether_dev->data_interface = data[0]; - } else { - err( "Union Functional Descriptor is broken beyond repair" ); - return -1; - } - } else{ // Descriptor is OK - // We'll need this in a few microseconds! - ether_dev->data_interface = data[1]; - } - - // We've seen one of these now. - *requirements &= ~REQ_UNION_FUNC_DESCR; - - // Done - return 0; -} - -static int parse_ethernet_functional_descriptor( int *bFunctionLength, - int bDescriptorType, - int bDescriptorSubtype, - unsigned char *data, - ether_dev_t *ether_dev, - int *requirements ) -{ - // Check to make sure we haven't seen one of these already. - if ( (~*requirements) & REQ_ETH_FUNC_DESCR ) { - err( "Multiple Ethernet Functional Descriptors found." ); - return -1; - } - - // Is it the right size? - if (*bFunctionLength != 13) { - err( "Invalid length in Ethernet Networking Functional Descriptor" ); - return -1; - } - - // Lots of goodies from this one. They are all important. - ether_dev->iMACAddress = data[0]; - ether_dev->bmEthernetStatistics = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24); - ether_dev->wMaxSegmentSize = data[5] + (data[6] << 8); - ether_dev->wNumberMCFilters = (data[7] + (data[8] << 8)) & 0x00007FFF; - if (ether_dev->wNumberMCFilters > multicast_filter_limit) { - ether_dev->wNumberMCFilters = multicast_filter_limit; - } - ether_dev->bNumberPowerFilters = data[9]; - - // We've seen one of these now. - *requirements &= ~REQ_ETH_FUNC_DESCR; - - // That's all she wrote. - return 0; -} - -static int parse_protocol_unit_functional_descriptor( int *bFunctionLength, - int bDescriptorType, - int bDescriptorSubtype, - unsigned char *data, - ether_dev_t *ether_dev, - int *requirements ) -{ - // There should only be one type if we are sane - if (bDescriptorType != CS_INTERFACE) { - info( "Invalid bDescriptorType found." ); - return -1; - } - - // The Subtype tells the tale. - switch (bDescriptorSubtype){ - case 0x00: // Header Functional Descriptor - return parse_header_functional_descriptor( bFunctionLength, - bDescriptorType, - bDescriptorSubtype, - data, - ether_dev, - requirements ); - break; - case 0x06: // Union Functional Descriptor - return parse_union_functional_descriptor( bFunctionLength, - bDescriptorType, - bDescriptorSubtype, - data, - ether_dev, - requirements ); - break; - case 0x0F: // Ethernet Networking Functional Descriptor - return parse_ethernet_functional_descriptor( bFunctionLength, - bDescriptorType, - bDescriptorSubtype, - data, - ether_dev, - requirements ); - break; - default: // We don't support this at this time... - // However that doesn't necessarily indicate an error. - dbg( "Unexpected header type %x:", bDescriptorSubtype ); - return 0; - } - // How did we get here??? - return -1; -} - -static int parse_ethernet_class_information( unsigned char *data, int length, ether_dev_t *ether_dev ) -{ - int loc = 0; - int rc; - int bFunctionLength; - int bDescriptorType; - int bDescriptorSubtype; - int requirements = REQUIREMENTS_TOTAL; - - // As long as there is something here, we will try to parse it - while (loc < length) { - // Length - bFunctionLength = data[loc]; - loc++; - - // Type - bDescriptorType = data[loc]; - loc++; - - // Subtype - bDescriptorSubtype = data[loc]; - loc++; - - // ship this off to be processed elsewhere. - rc = parse_protocol_unit_functional_descriptor( &bFunctionLength, - bDescriptorType, - bDescriptorSubtype, - &data[loc], - ether_dev, - &requirements ); - // Did it process okay? - if (rc) { - // Something was hosed somewhere. - // No need to continue; - err("Bad descriptor parsing: %x", rc ); - return -1; - } - // We have already taken three bytes. - loc += (bFunctionLength - 3); - } - // Check to see if we got everything we need. - if (requirements) { - // We missed some of the requirements... - err( "Not all required functional descriptors present 0x%08X", requirements ); - return -1; - } - // We got everything. - return 0; -} - -////////////////////////////////////////////////////////////////////////////// -// Routine to check for the existence of the Functional Descriptors ////////// -////////////////////////////////////////////////////////////////////////////// - -static int find_and_parse_ethernet_class_information( struct usb_device *device, ether_dev_t *ether_dev ) -{ - struct usb_host_config *conf = NULL; - struct usb_interface *comm_intf_group = NULL; - struct usb_host_interface *comm_intf = NULL; - int rc = -1; - // The assumption here is that find_ethernet_comm_interface - // and find_valid_configuration - // have already filled in the information about where to find - // the a valid commication interface. - - conf = &( device->config[ether_dev->configuration_num] ); - comm_intf_group = &( conf->interface[ether_dev->comm_interface] ); - comm_intf = &( comm_intf_group->altsetting[ether_dev->comm_interface_altset_num] ); - // Let's check and see if it has the extra information we need... - - if (comm_intf->extralen > 0) { - // This is where the information is SUPPOSED to be. - rc = parse_ethernet_class_information( comm_intf->extra, comm_intf->extralen, ether_dev ); - } else if (conf->extralen > 0) { - // This is a hack. The spec says it should be at the interface - // location checked above. However I have seen it here also. - // This is the same device that requires the functional descriptor hack above - warn( "Ethernet information found at device configuration. This is broken." ); - rc = parse_ethernet_class_information( conf->extra, conf->extralen, ether_dev ); - } else { - // I don't know where else to look. - warn( "No ethernet information found." ); - rc = -1; - } - return rc; -} - -////////////////////////////////////////////////////////////////////////////// -// Routines to verify the data interface ///////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static int get_data_interface_endpoints( struct usb_device *device, ether_dev_t *ether_dev ) -{ - struct usb_host_config *conf = NULL; - struct usb_interface *data_intf_group = NULL; - struct usb_host_interface *data_intf = NULL; - - // Walk through and get to the data interface we are checking. - conf = &( device->config[ether_dev->configuration_num] ); - data_intf_group = &( conf->interface[ether_dev->data_interface] ); - data_intf = &( data_intf_group->altsetting[ether_dev->data_interface_altset_num_with_traffic] ); - - // Start out assuming we won't find anything we can use - ether_dev->data_ep_in = 0; - ether_dev->data_ep_out = 0; - - // If these are not BULK endpoints, we don't want them - if ( data_intf->endpoint[0].desc.bmAttributes != 0x02 ) { - return -1; - } if ( data_intf->endpoint[1].desc.bmAttributes != 0x02 ) { - return -1; - } - - // Check the first endpoint to see if it is IN or OUT - if ( data_intf->endpoint[0].desc.bEndpointAddress & 0x80 ) { - // This endpoint is IN - ether_dev->data_ep_in = data_intf->endpoint[0].desc.bEndpointAddress & 0x7F; - } else { - // This endpoint is OUT - ether_dev->data_ep_out = data_intf->endpoint[0].desc.bEndpointAddress & 0x7F; - ether_dev->data_ep_out_size = data_intf->endpoint[0].desc.wMaxPacketSize; - } - - // Check the second endpoint to see if it is IN or OUT - if ( data_intf->endpoint[1].desc.bEndpointAddress & 0x80 ) { - // This endpoint is IN - ether_dev->data_ep_in = data_intf->endpoint[1].desc.bEndpointAddress & 0x7F; - } else { - // This endpoint is OUT - ether_dev->data_ep_out = data_intf->endpoint[1].desc.bEndpointAddress & 0x7F; - ether_dev->data_ep_out_size = data_intf->endpoint[1].desc.wMaxPacketSize; - } - - // Now make sure we got both an IN and an OUT - if (ether_dev->data_ep_in && ether_dev->data_ep_out) { - // We did get both, we are in good shape... - info( "detected BULK OUT packets of size %d", ether_dev->data_ep_out_size ); - return 0; - } - return -1; -} - -static int verify_ethernet_data_interface( struct usb_device *device, ether_dev_t *ether_dev ) -{ - struct usb_host_config *conf = NULL; - struct usb_interface *data_intf_group = NULL; - struct usb_interface_descriptor *data_intf = NULL; - int rc = -1; - int status; - int altset_num; - - // The assumption here is that parse_ethernet_class_information() - // and find_valid_configuration() - // have already filled in the information about where to find - // a data interface - conf = &( device->config[ether_dev->configuration_num] ); - data_intf_group = &( conf->interface[ether_dev->data_interface] ); - - // start out assuming we won't find what we are looking for. - ether_dev->data_interface_altset_num_with_traffic = -1; - ether_dev->data_bAlternateSetting_with_traffic = -1; - ether_dev->data_interface_altset_num_without_traffic = -1; - ether_dev->data_bAlternateSetting_without_traffic = -1; - - // Walk through every possible setting for this interface until - // we find what makes us happy. - for ( altset_num = 0; altset_num < data_intf_group->num_altsetting; altset_num++ ) { - data_intf = &( data_intf_group->altsetting[altset_num].desc ); - - // Is this a data interface we like? - if ( ( data_intf->bInterfaceClass == 0x0A ) - && ( data_intf->bInterfaceSubClass == 0x00 ) - && ( data_intf->bInterfaceProtocol == 0x00 ) ) { - if ( data_intf->bNumEndpoints == 2 ) { - // We are required to have one of these. - // An interface with 2 endpoints to send Ethernet traffic back and forth - // It actually may be possible that the device might only - // communicate in a vendor specific manner. - // That would not be very nice. - // We can add that one later. - ether_dev->data_bInterfaceNumber = data_intf->bInterfaceNumber; - ether_dev->data_interface_altset_num_with_traffic = altset_num; - ether_dev->data_bAlternateSetting_with_traffic = data_intf->bAlternateSetting; - status = get_data_interface_endpoints( device, ether_dev ); - if (!status) { - rc = 0; - } - } - if ( data_intf->bNumEndpoints == 0 ) { - // According to the spec we are SUPPOSED to have one of these - // In fact the device is supposed to come up in this state. - // However, I have seen a device that did not have such an interface. - // So it must be just optional for our driver... - ether_dev->data_bInterfaceNumber = data_intf->bInterfaceNumber; - ether_dev->data_interface_altset_num_without_traffic = altset_num; - ether_dev->data_bAlternateSetting_without_traffic = data_intf->bAlternateSetting; - } - } - } - return rc; -} - -////////////////////////////////////////////////////////////////////////////// -// Routine to find a communication interface ///////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static int find_ethernet_comm_interface( struct usb_device *device, ether_dev_t *ether_dev ) -{ - struct usb_host_config *conf = NULL; - struct usb_interface *comm_intf_group = NULL; - struct usb_interface_descriptor *comm_intf = NULL; - int intf_num; - int altset_num; - int rc; - - conf = &( device->config[ether_dev->configuration_num] ); - - // We need to check and see if any of these interfaces are something we want. - // Walk through each interface one at a time - for ( intf_num = 0; intf_num < conf->desc.bNumInterfaces; intf_num++ ) { - comm_intf_group = &( conf->interface[intf_num] ); - // Now for each of those interfaces, check every possible - // alternate setting. - for ( altset_num = 0; altset_num < comm_intf_group->num_altsetting; altset_num++ ) { - comm_intf = &( comm_intf_group->altsetting[altset_num].desc); - - // Is this a communication class of interface of the - // ethernet subclass variety. - if ( ( comm_intf->bInterfaceClass == 0x02 ) - && ( comm_intf->bInterfaceSubClass == 0x06 ) - && ( comm_intf->bInterfaceProtocol == 0x00 ) ) { - if ( comm_intf->bNumEndpoints == 1 ) { - // Good, we found one, we will try this one - // Fill in the structure... - ether_dev->comm_interface = intf_num; - ether_dev->comm_bInterfaceNumber = comm_intf->bInterfaceNumber; - ether_dev->comm_interface_altset_num = altset_num; - ether_dev->comm_bAlternateSetting = comm_intf->bAlternateSetting; - - // Look for the Ethernet Functional Descriptors - rc = find_and_parse_ethernet_class_information( device, ether_dev ); - if (rc) { - // Nope this was no good after all. - continue; - } - - // Check that we really can talk to the data - // interface - // This includes # of endpoints, protocols, - // etc. - rc = verify_ethernet_data_interface( device, ether_dev ); - if (rc) { - // We got something we didn't like - continue; - } - // This communication interface seems to give us everything - // we require. We have all the ethernet info we need. - // Let's get out of here and go home right now. - return 0; - } else { - // bNumEndPoints != 1 - // We found an interface that had the wrong number of - // endpoints but would have otherwise been okay - } // end bNumEndpoints check. - } // end interface specifics check. - } // end for altset_num - } // end for intf_num - return -1; -} - -////////////////////////////////////////////////////////////////////////////// -// Routine to go through all configurations and find one that //////////////// -// is an Ethernet Networking Device ////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static int find_valid_configuration( struct usb_device *device, ether_dev_t *ether_dev ) -{ - struct usb_host_config *conf = NULL; - int conf_num; - int rc; - - // We will try each and every possible configuration - for ( conf_num = 0; conf_num < device->descriptor.bNumConfigurations; conf_num++ ) { - conf = &( device->config[conf_num] ); - - // Our first requirement : 2 interfaces - if ( conf->desc.bNumInterfaces != 2 ) { - // I currently don't know how to handle devices with any number of interfaces - // other than 2. - continue; - } - - // This one passed our first check, fill in some - // useful data - ether_dev->configuration_num = conf_num; - ether_dev->bConfigurationValue = conf->desc.bConfigurationValue; - - // Now run it through the ringers and see what comes - // out the other side. - rc = find_ethernet_comm_interface( device, ether_dev ); - - // Check if we found an ethernet Communcation Device - if ( !rc ) { - // We found one. - return 0; - } - } - // None of the configurations suited us. - return -1; -} - -////////////////////////////////////////////////////////////////////////////// -// Routine that checks a given configuration to see if any driver //////////// -// has claimed any of the devices interfaces ///////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static int check_for_claimed_interfaces( struct usb_host_config *config ) -{ - struct usb_interface *comm_intf_group; - int intf_num; - - // Go through all the interfaces and make sure none are - // claimed by anybody else. - for ( intf_num = 0; intf_num < config->desc.bNumInterfaces; intf_num++ ) { - comm_intf_group = &( config->interface[intf_num] ); - if ( usb_interface_claimed( comm_intf_group ) ) { - // Somebody has beat us to this guy. - // We can't change the configuration out from underneath of whoever - // is using this device, so we will go ahead and give up. - return -1; - } - } - // We made it all the way through. - // I guess no one has claimed any of these interfaces. - return 0; -} - -////////////////////////////////////////////////////////////////////////////// -// Routines to ask for and set the kernel network interface's MAC address //// -// Used by driver's probe routine //////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static inline unsigned char hex2dec( unsigned char digit ) -{ - // Is there a standard way to do this??? - // I have written this code TOO MANY times. - if ( (digit >= '0') && (digit <= '9') ) { - return (digit - '0'); - } - if ( (digit >= 'a') && (digit <= 'f') ) { - return (digit - 'a' + 10); - } - if ( (digit >= 'A') && (digit <= 'F') ) { - return (digit - 'A' + 10); - } - return 0; -} - -static void set_ethernet_addr( ether_dev_t *ether_dev ) -{ - unsigned char mac_addr[6]; - int i; - int len; - unsigned char buffer[13]; - - // Let's assume we don't get anything... - mac_addr[0] = 0x00; - mac_addr[1] = 0x00; - mac_addr[2] = 0x00; - mac_addr[3] = 0x00; - mac_addr[4] = 0x00; - mac_addr[5] = 0x00; - - // Let's ask the device... - len = usb_string(ether_dev->usb, ether_dev->iMACAddress, buffer, 13); - - // Sanity check! - if (len != 12) { - // You gotta love failing sanity checks - err("Attempting to get MAC address returned %d bytes", len); - return; - } - - // Fill in the mac_addr - for (i = 0; i < 6; i++) { - mac_addr[i] = ( hex2dec( buffer[2 * i] ) << 4 ) + hex2dec( buffer[2 * i + 1] ); - } - - // Now copy it over to the kernel's network driver. - memcpy( ether_dev->net->dev_addr, mac_addr, sizeof(mac_addr) ); -} - -////////////////////////////////////////////////////////////////////////////// -// Routine to print to syslog information about the driver /////////////////// -// Used by driver's probe routine //////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static void log_device_info(ether_dev_t *ether_dev) -{ - int len; - int string_num; - unsigned char *manu = NULL; - unsigned char *prod = NULL; - unsigned char *sern = NULL; - unsigned char *mac_addr; - - manu = kmalloc(256, GFP_KERNEL); - prod = kmalloc(256, GFP_KERNEL); - sern = kmalloc(256, GFP_KERNEL); - if (!manu || !prod || !sern) { - dbg("no mem for log_device_info"); - goto fini; - } - - // Default empty strings in case we don't find a real one - manu[0] = 0x00; - prod[0] = 0x00; - sern[0] = 0x00; - - // Try to get the device Manufacturer - string_num = ether_dev->usb->descriptor.iManufacturer; - if (string_num) { - // Put it into its buffer - len = usb_string(ether_dev->usb, string_num, manu, 255); - // Just to be safe - manu[len] = 0x00; - } - - // Try to get the device Product Name - string_num = ether_dev->usb->descriptor.iProduct; - if (string_num) { - // Put it into its buffer - len = usb_string(ether_dev->usb, string_num, prod, 255); - // Just to be safe - prod[len] = 0x00; - } - - // Try to get the device Serial Number - string_num = ether_dev->usb->descriptor.iSerialNumber; - if (string_num) { - // Put it into its buffer - len = usb_string(ether_dev->usb, string_num, sern, 255); - // Just to be safe - sern[len] = 0x00; - } - - // This makes it easier for us to print - mac_addr = ether_dev->net->dev_addr; - - // Now send everything we found to the syslog - info( "%s: %s %s %s %02X:%02X:%02X:%02X:%02X:%02X", - ether_dev->net->name, manu, prod, sern, mac_addr[0], - mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], - mac_addr[5] ); -fini: - kfree(manu); - kfree(prod); - kfree(sern); -} - -/* Forward declaration */ -static struct usb_driver CDCEther_driver ; - -////////////////////////////////////////////////////////////////////////////// -// Module's probe routine //////////////////////////////////////////////////// -// claims interfaces if they are for an Ethernet CDC ///////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static int CDCEther_probe( struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *usb = interface_to_usbdev(intf); - struct net_device *net; - ether_dev_t *ether_dev; - int rc; - - // First we should check the active configuration to see if - // any other driver has claimed any of the interfaces. - if ( check_for_claimed_interfaces( usb->actconfig ) ) { - // Someone has already put there grubby paws on this device. - // We don't want it now... - return -ENODEV; - } - - // We might be finding a device we can use. - // We all go ahead and allocate our storage space. - // We need to because we have to start filling in the data that - // we are going to need later. - if(!(ether_dev = kmalloc(sizeof(ether_dev_t), GFP_KERNEL))) { - err("out of memory allocating device structure"); - return -ENOMEM; - } - - // Zero everything out. - memset(ether_dev, 0, sizeof(ether_dev_t)); - - ether_dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ether_dev->rx_urb) { - kfree(ether_dev); - return -ENOMEM; - } - ether_dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ether_dev->tx_urb) { - usb_free_urb(ether_dev->rx_urb); - kfree(ether_dev); - return -ENOMEM; - } - ether_dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ether_dev->intr_urb) { - usb_free_urb(ether_dev->tx_urb); - usb_free_urb(ether_dev->rx_urb); - kfree(ether_dev); - return -ENOMEM; - } - - // Let's see if we can find a configuration we can use. - rc = find_valid_configuration( usb, ether_dev ); - if (rc) { - // Nope we couldn't find one we liked. - // This device was not meant for us to control. - goto error_all; - } - - // Now that we FOUND a configuration. let's try to make the - // device go into it. - if ( usb_set_configuration( usb, ether_dev->bConfigurationValue ) ) { - err("usb_set_configuration() failed"); - goto error_all; - } - - // Now set the communication interface up as required. - if (usb_set_interface(usb, ether_dev->comm_bInterfaceNumber, ether_dev->comm_bAlternateSetting)) { - err("usb_set_interface() failed"); - goto error_all; - } - - // Only turn traffic on right now if we must... - if (ether_dev->data_interface_altset_num_without_traffic >= 0) { - // We found an alternate setting for the data - // interface that allows us to turn off traffic. - // We should use it. - if (usb_set_interface( usb, - ether_dev->data_bInterfaceNumber, - ether_dev->data_bAlternateSetting_without_traffic)) { - err("usb_set_interface() failed"); - goto error_all; - } - } else { - // We didn't find an alternate setting for the data - // interface that would let us turn off traffic. - // Oh well, let's go ahead and do what we must... - if (usb_set_interface( usb, - ether_dev->data_bInterfaceNumber, - ether_dev->data_bAlternateSetting_with_traffic)) { - err("usb_set_interface() failed"); - goto error_all; - } - } - - // Now we need to get a kernel Ethernet interface. - net = alloc_etherdev(0); - if ( !net ) { - // Hmm... The kernel is not sharing today... - // Fine, we didn't want it anyway... - err( "Unable to initialize ethernet device" ); - goto error_all; - } - - // Now that we have an ethernet device, let's set it up - // (And I don't mean "set [it] up the bomb".) - net->priv = ether_dev; - SET_MODULE_OWNER(net); - net->open = CDCEther_open; - net->stop = CDCEther_close; - net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT; - net->tx_timeout = CDCEther_tx_timeout; // TX timeout function - net->do_ioctl = CDCEther_ioctl; - net->hard_start_xmit = CDCEther_start_xmit; - net->set_multicast_list = CDCEther_set_multicast; - net->get_stats = CDCEther_netdev_stats; - net->mtu = ether_dev->wMaxSegmentSize - 14; - - // We'll keep track of this information for later... - ether_dev->usb = usb; - ether_dev->net = net; - - // and don't forget the MAC address. - set_ethernet_addr( ether_dev ); - - // Send a message to syslog about what we are handling - log_device_info( ether_dev ); - - // I claim this interface to be a CDC Ethernet Networking device - usb_driver_claim_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]), - ether_dev ); - // I claim this interface to be a CDC Ethernet Networking device - usb_driver_claim_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]), - ether_dev ); - - // Does this REALLY do anything??? - usb_get_dev( usb ); - - // TODO - last minute HACK - ether_dev->comm_ep_in = 5; - - if (register_netdev(net) != 0) { - usb_put_dev(usb); - goto out; - } - -/* FIXME!!! This driver needs to be fixed to work with the new USB interface logic - * this is not the correct thing to be doing here, we need to set the interface - * driver specific data field. - */ - // Okay, we are finally done... - return 0; - - -out: - usb_driver_release_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]) ); - - usb_driver_release_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]) ); - // bailing out with our tail between our knees -error_all: - usb_free_urb(ether_dev->tx_urb); - usb_free_urb(ether_dev->rx_urb); - usb_free_urb(ether_dev->intr_urb); - kfree( ether_dev ); - return -EIO; -} - - -////////////////////////////////////////////////////////////////////////////// -// Module's disconnect routine /////////////////////////////////////////////// -// Called when the driver is unloaded or the device is unplugged ///////////// -// (Whichever happens first assuming the driver suceeded at its probe) /////// -////////////////////////////////////////////////////////////////////////////// - -static void CDCEther_disconnect( struct usb_interface *intf ) -{ - ether_dev_t *ether_dev = usb_get_intfdata(intf); - struct usb_device *usb; - - usb_set_intfdata(intf, NULL); - - // Sanity check!!! - if ( !ether_dev || !ether_dev->usb ) { - // We failed. We are insane!!! - warn("unregistering non-existant device"); - return; - } - - // Make sure we fail the sanity check if we try this again. - ether_dev->usb = NULL; - - usb = interface_to_usbdev(intf); - - // It is possible that this function is called before - // the "close" function. - // This tells the close function we are already disconnected - ether_dev->flags |= CDC_ETHER_UNPLUG; - - // We don't need the network device any more - unregister_netdev( ether_dev->net ); - - // For sanity checks - ether_dev->net = NULL; - - // I ask again, does this do anything??? - usb_put_dev( usb ); - - // We are done with this interface - usb_driver_release_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]) ); - - // We are done with this interface too - usb_driver_release_interface( &CDCEther_driver, - &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]) ); - - // No more tied up kernel memory - usb_free_urb(ether_dev->intr_urb); - usb_free_urb(ether_dev->rx_urb); - usb_free_urb(ether_dev->rx_urb); - kfree( ether_dev ); - - // This does no good, but it looks nice! - ether_dev = NULL; -} - -////////////////////////////////////////////////////////////////////////////// -// Driver info /////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -static struct usb_driver CDCEther_driver = { - .owner = THIS_MODULE, - .name = "CDCEther", - .probe = CDCEther_probe, - .disconnect = CDCEther_disconnect, - .id_table = CDCEther_ids, -}; - -////////////////////////////////////////////////////////////////////////////// -// init and exit routines called when driver is installed and uninstalled //// -////////////////////////////////////////////////////////////////////////////// - -int __init CDCEther_init(void) -{ - info( "%s", version ); - return usb_register( &CDCEther_driver ); -} - -void __exit CDCEther_exit(void) -{ - usb_deregister( &CDCEther_driver ); -} - -////////////////////////////////////////////////////////////////////////////// -// Module info /////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -module_init( CDCEther_init ); -module_exit( CDCEther_exit ); - -MODULE_AUTHOR("Brad Hards and another"); -MODULE_DESCRIPTION("USB CDC Ethernet driver"); -MODULE_LICENSE("GPL"); - -MODULE_PARM (multicast_filter_limit, "i"); -MODULE_PARM_DESC (multicast_filter_limit, "CDCEther maximum number of filtered multicast addresses"); - -MODULE_DEVICE_TABLE (usb, CDCEther_ids); - -////////////////////////////////////////////////////////////////////////////// -// End of file /////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// diff -Nru a/drivers/usb/net/cdc-ether.h b/drivers/usb/net/cdc-ether.h --- a/drivers/usb/net/cdc-ether.h Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,98 +0,0 @@ -// Portions of this file taken from -// Petko Manolov - Petkan (petkan@dce.bg) -// from his driver pegasus.h - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#define CS_INTERFACE 0x24 - -#define CDC_ETHER_MAX_MTU 1536 - -#define CDC_ETHER_PRESENT 0x00000001 -#define CDC_ETHER_RUNNING 0x00000002 -#define CDC_ETHER_TX_BUSY 0x00000004 -#define CDC_ETHER_RX_BUSY 0x00000008 -#define CDC_ETHER_UNPLUG 0x00000040 - -#define CDC_ETHER_TX_TIMEOUT (HZ*10) - -#define TX_UNDERRUN 0x80 -#define EXCESSIVE_COL 0x40 -#define LATE_COL 0x20 -#define NO_CARRIER 0x10 -#define LOSS_CARRIER 0x08 -#define JABBER_TIMEOUT 0x04 - -#define CDC_ETHER_REQT_READ 0xc0 -#define CDC_ETHER_REQT_WRITE 0x40 -#define CDC_ETHER_REQ_GET_REGS 0xf0 -#define CDC_ETHER_REQ_SET_REGS 0xf1 -#define CDC_ETHER_REQ_SET_REG PIPERIDER_REQ_SET_REGS -#define L1_ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES))) - -#define MODE_FLAG_PROMISCUOUS (1<<0) -#define MODE_FLAG_ALL_MULTICAST (1<<1) -#define MODE_FLAG_DIRECTED (1<<2) -#define MODE_FLAG_BROADCAST (1<<3) -#define MODE_FLAG_MULTICAST (1<<4) - -#define SET_ETHERNET_MULTICAST_FILTER 0x40 -#define SET_ETHERNET_PACKET_FILTER 0x43 - -typedef struct _ether_dev_t { - struct usb_device *usb; - struct net_device *net; - struct net_device_stats stats; - unsigned flags; - int configuration_num; - int bConfigurationValue; - int comm_interface; - int comm_bInterfaceNumber; - int comm_interface_altset_num; - int comm_bAlternateSetting; - int comm_ep_in; - int data_interface; - int data_bInterfaceNumber; - int data_interface_altset_num_with_traffic; - int data_bAlternateSetting_with_traffic; - int data_interface_altset_num_without_traffic; - int data_bAlternateSetting_without_traffic; - int data_ep_in; - int data_ep_out; - int data_ep_out_size; - __u16 bcdCDC; - __u8 iMACAddress; - __u32 bmEthernetStatistics; - __u16 wMaxSegmentSize; - __u16 mode_flags; - __u16 wNumberMCFilters; - __u8 bNumberPowerFilters; - int intr_interval; - struct urb *rx_urb, *tx_urb, *intr_urb; - unsigned char L1_ALIGN(rx_buff[CDC_ETHER_MAX_MTU]); - unsigned char L1_ALIGN(tx_buff[CDC_ETHER_MAX_MTU]); - unsigned char L1_ALIGN(intr_buff[8]); -} ether_dev_t; - -#define REQ_HDR_FUNC_DESCR 0x0001 -#define REQ_UNION_FUNC_DESCR 0x0002 -#define REQ_ETH_FUNC_DESCR 0x0004 -#define REQUIREMENTS_TOTAL 0x0007 - - - diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c --- a/drivers/usb/net/kaweth.c Fri Jun 27 14:19:59 2003 +++ b/drivers/usb/net/kaweth.c Fri Jun 27 14:19:59 2003 @@ -56,6 +56,8 @@ #include <linux/usb.h> #include <linux/types.h> #include <linux/ethtool.h> +#include <linux/pci.h> +#include <linux/dma-mapping.h> #include <asm/uaccess.h> #include <asm/semaphore.h> #include <asm/byteorder.h> @@ -215,8 +217,10 @@ __u32 status; int end; int removed; - int suspend_lowmem; + int suspend_lowmem_rx; + int suspend_lowmem_ctrl; int linkstate; + struct work_struct lowmem_work; struct usb_device *dev; struct net_device *net; @@ -475,14 +479,29 @@ /**************************************************************** int_callback *****************************************************************/ + +static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, int mf) +{ + int status; + + status = usb_submit_urb (kaweth->irq_urb, mf); + if (unlikely(status == -ENOMEM)) { + kaweth->suspend_lowmem_ctrl = 1; + schedule_delayed_work(&kaweth->lowmem_work, HZ/4); + } else { + kaweth->suspend_lowmem_ctrl = 0; + } + + if (status) + err ("can't resubmit intr, %s-%s, status %d", + kaweth->dev->bus->bus_name, + kaweth->dev->devpath, status); +} + static void int_callback(struct urb *u, struct pt_regs *regs) { struct kaweth_device *kaweth = u->context; - int act_state, status; - - /* we abuse the interrupt urb for rebsubmitting under low memory saving a timer */ - if (kaweth->suspend_lowmem) - kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC); + int act_state; switch (u->status) { case 0: /* success */ @@ -506,13 +525,24 @@ kaweth->linkstate = act_state; } resubmit: - status = usb_submit_urb (u, SLAB_ATOMIC); - if (status) - err ("can't resubmit intr, %s-%s, status %d", - kaweth->dev->bus->bus_name, - kaweth->dev->devpath, status); + kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC); +} + +static void kaweth_resubmit_tl(void *d) +{ + struct kaweth_device *kaweth = (struct kaweth_device *)d; + + if (kaweth->status | KAWETH_STATUS_CLOSING) + return; + + if (kaweth->suspend_lowmem_rx) + kaweth_resubmit_rx_urb(kaweth, GFP_NOIO); + + if (kaweth->suspend_lowmem_ctrl) + kaweth_resubmit_int_urb(kaweth, GFP_NOIO); } + /**************************************************************** * kaweth_resubmit_rx_urb ****************************************************************/ @@ -532,11 +562,13 @@ kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle; if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) { - if (result == -ENOMEM) - kaweth->suspend_lowmem = 1; + if (result == -ENOMEM) { + kaweth->suspend_lowmem_rx = 1; + schedule_delayed_work(&kaweth->lowmem_work, HZ/4); + } kaweth_err("resubmitting rx_urb %d failed", result); } else { - kaweth->suspend_lowmem = 0; + kaweth->suspend_lowmem_rx = 0; } return result; @@ -665,6 +697,13 @@ usb_unlink_urb(kaweth->irq_urb); usb_unlink_urb(kaweth->rx_urb); + flush_scheduled_work(); + + /* a scheduled work may have resubmitted, + we hit them again */ + usb_unlink_urb(kaweth->irq_urb); + usb_unlink_urb(kaweth->rx_urb); + kaweth->status &= ~KAWETH_STATUS_CLOSING; return 0; @@ -1075,10 +1114,15 @@ memset(&kaweth->stats, 0, sizeof(kaweth->stats)); + INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth); + SET_MODULE_OWNER(netdev); usb_set_intfdata(intf, kaweth); + if (dma_supported (&intf->dev, 0xffffffffffffffffULL)) + kaweth->net->features |= NETIF_F_HIGHDMA; + if (register_netdev(netdev) != 0) { kaweth_err("Error calling init_etherdev."); goto err_intfdata; @@ -1092,7 +1136,6 @@ err_intfdata: usb_set_intfdata(intf, NULL); -err_all: usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle); err_all_but_rxbuf: usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle); diff -Nru a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c --- a/drivers/usb/serial/io_edgeport.c Fri Jun 27 14:19:53 2003 +++ b/drivers/usb/serial/io_edgeport.c Fri Jun 27 14:19:53 2003 @@ -412,6 +412,7 @@ // MCR.7 = 0. // static struct divisor_table_entry divisor_table[] = { + { 50, 4608}, { 75, 3072}, { 110, 2095}, /* 2094.545455 => 230450 => .0217 % over */ { 134, 1713}, /* 1713.011152 => 230398.5 => .00065% under */ @@ -2591,7 +2592,7 @@ // We have tried all of the standard baud rates // lets try to calculate the divisor for this baud rate // Make sure the baud rate is reasonable - if (baudrate > 75 && baudrate < 230400) { + if (baudrate < 230400) { // get divisor custom = (__u16)(230400L / baudrate); diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c --- a/drivers/usb/serial/pl2303.c Fri Jun 27 14:19:56 2003 +++ b/drivers/usb/serial/pl2303.c Fri Jun 27 14:19:56 2003 @@ -537,16 +537,20 @@ struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int mcr; + unsigned int status; unsigned int result; dbg("%s (%d)", __FUNCTION__, port->number); spin_lock_irqsave (&priv->lock, flags); mcr = priv->line_control; + status = priv->line_status; spin_unlock_irqrestore (&priv->lock, flags); result = ((mcr & CONTROL_DTR) ? TIOCM_DTR : 0) - | ((mcr & CONTROL_RTS) ? TIOCM_RTS : 0); + | ((mcr & CONTROL_RTS) ? TIOCM_RTS : 0) + | ((status & UART_CTS) ? TIOCM_CTS : 0) + | ((status & UART_DSR) ? TIOCM_DSR : 0); dbg("%s - result = %x", __FUNCTION__, result); diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c Fri Jun 27 14:19:54 2003 +++ b/drivers/usb/serial/visor.c Fri Jun 27 14:19:54 2003 @@ -12,6 +12,10 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (06/03/2003) Judd Montgomery <judd at jpilot.org> + * Added support for module parameter options for untested/unknown + * devices. + * * (03/09/2003) gkh * Added support for the Sony Clie NZ90V device. Thanks to Martin Brachtl * <brachtl@redgrep.cz> for the information. @@ -188,6 +192,9 @@ static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id); static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id); +/* Parameters that may be passed into the module. */ +static int vendor = -1; +static int product = -1; static struct usb_device_id id_table [] = { { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID), @@ -223,6 +230,7 @@ .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { }, /* optional parameter entry */ { } /* Terminating entry */ }; @@ -250,6 +258,7 @@ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) }, + { }, /* optional parameter entry */ { } /* Terminating entry */ }; @@ -942,6 +951,33 @@ static int __init visor_init (void) { + int i; + /* Only if parameters were passed to us */ + if ((vendor>0) && (product>0)) { + struct usb_device_id usb_dev_temp[]= + {{USB_DEVICE(vendor, product), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }}; + + /* Find the last entry in id_table */ + for (i=0; ; i++) { + if (id_table[i].idVendor==0) { + id_table[i] = usb_dev_temp[0]; + break; + } + } + /* Find the last entry in id_table_combined */ + for (i=0; ; i++) { + if (id_table_combined[i].idVendor==0) { + id_table_combined[i] = usb_dev_temp[0]; + break; + } + } + info("Untested USB device specified at time of module insertion"); + info("Warning: This is not guaranteed to work"); + info("Using a newer kernel is preferred to this method"); + info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x", + vendor, product); + } usb_serial_register (&handspring_device); usb_serial_register (&clie_3_5_device); usb_register (&visor_driver); @@ -969,3 +1005,7 @@ MODULE_PARM(debug, "i"); MODULE_PARM_DESC(debug, "Debug enabled or not"); +MODULE_PARM(vendor, "i"); +MODULE_PARM_DESC(vendor, "User specified vendor ID"); +MODULE_PARM(product, "i"); +MODULE_PARM_DESC(product, "User specified product ID"); diff -Nru a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c --- a/drivers/usb/storage/initializers.c Fri Jun 27 14:19:55 2003 +++ b/drivers/usb/storage/initializers.c Fri Jun 27 14:19:55 2003 @@ -41,6 +41,7 @@ #include <linux/errno.h> #include "initializers.h" #include "debug.h" +#include "transport.h" /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target * mode */ @@ -59,4 +60,50 @@ return 0; } +/* This function is required to activate all four slots on the UCR-61S2B + * flash reader */ +int usb_stor_ucr61s2b_init(struct us_data *us) +{ + struct bulk_cb_wrap *bcb; + struct bulk_cs_wrap *bcs; + int res, partial; + + bcb = kmalloc(sizeof *bcb, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); + if (!bcb) { + return(-1); + } + bcs = kmalloc(sizeof *bcs, in_interrupt() ? GFP_ATOMIC : GFP_NOIO); + if (!bcs) { + kfree(bcb); + return(-1); + } + + US_DEBUGP("Sending UCR-61S2B initialization packet...\n"); + + bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); + bcb->Tag = 0; + bcb->DataTransferLength = cpu_to_le32(0); + bcb->Flags = bcb->Lun = 0; + bcb->Length = sizeof(UCR61S2B_INIT); + memset(bcb->CDB, 0, sizeof(bcb->CDB)); + memcpy(bcb->CDB, UCR61S2B_INIT, sizeof(UCR61S2B_INIT)); + + res = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, + US_BULK_CB_WRAP_LEN, &partial); + US_DEBUGP("-- result is %d\n", res); + kfree(bcb); + + if(res) { + kfree(bcs); + return(res); + } + + res = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, + US_BULK_CS_WRAP_LEN, &partial); + US_DEBUGP("-- result of status read is %d\n", res); + + kfree(bcs); + + return(res ? -1 : 0); +} diff -Nru a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h --- a/drivers/usb/storage/initializers.h Fri Jun 27 14:19:56 2003 +++ b/drivers/usb/storage/initializers.h Fri Jun 27 14:19:56 2003 @@ -48,3 +48,9 @@ #ifdef CONFIG_USB_STORAGE_SDDR09 int sddr09_init(struct us_data *us); #endif + +#define UCR61S2B_INIT "\xec\x0a\x06\x00$PCCHIPS" + +/* This function is required to activate all four slots on the UCR-61S2B + * flash reader */ +int usb_stor_ucr61s2b_init(struct us_data *us); diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h Fri Jun 27 14:20:00 2003 +++ b/drivers/usb/storage/unusual_devs.h Fri Jun 27 14:20:00 2003 @@ -595,6 +595,16 @@ US_SC_SCSI, US_PR_BULK, NULL, US_FL_FIX_INQUIRY ), +/* Pentax Optio S digital camera + * adapted from http://www2.goldfisch.at/knowledge/233 + * (Peter Pilsl <pilsl@goldfisch.at>) + * by Christoph Weidemann <cweidema@indiana.edu> */ +UNUSUAL_DEV( 0x0a17, 0x0006, 0x0000, 0xffff, + "Pentax", + "Optio S", + US_SC_8070, US_PR_CB, NULL, + US_FL_MODE_XLATE|US_FL_FIX_INQUIRY), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", @@ -609,6 +619,16 @@ "EasyDisk EDxxxx", US_SC_SCSI, US_PR_BULK, NULL, US_FL_MODE_XLATE | US_FL_FIX_INQUIRY ), + +/* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> + * Tested on hardware version 1.10. + * Entry is needed only for the initializer function override. + */ +UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x9999, + "Desknote", + "UCR-61S2B", + US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, + 0 ), /* Reported by Dan Pilone <pilone@slac.com> * The device needs the flags only. diff -Nru a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c --- a/drivers/video/i810/i810_main.c Fri Jun 27 14:19:55 2003 +++ b/drivers/video/i810/i810_main.c Fri Jun 27 14:19:55 2003 @@ -1075,8 +1075,6 @@ struct i810fb_par *par = (struct i810fb_par *) info->par; u8 *mmio = par->mmio_start_virtual, temp; - if (regno > 255) return 1; - if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { if ((info->var.green.length == 5 && regno > 31) || (info->var.green.length == 6 && regno > 63)) diff -Nru a/drivers/video/vgastate.c b/drivers/video/vgastate.c --- a/drivers/video/vgastate.c Fri Jun 27 14:19:56 2003 +++ b/drivers/video/vgastate.c Fri Jun 27 14:19:56 2003 @@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/fb.h> +#include <linux/vmalloc.h> #include <video/vga.h> struct regstate { diff -Nru a/fs/binfmt_elf.c b/fs/binfmt_elf.c --- a/fs/binfmt_elf.c Fri Jun 27 14:19:56 2003 +++ b/fs/binfmt_elf.c Fri Jun 27 14:19:56 2003 @@ -35,6 +35,7 @@ #include <linux/compiler.h> #include <linux/highmem.h> #include <linux/pagemap.h> +#include <linux/security.h> #include <asm/uaccess.h> #include <asm/param.h> @@ -191,6 +192,7 @@ NEW_AUX_ENT(AT_EUID, (elf_addr_t) tsk->euid); NEW_AUX_ENT(AT_GID, (elf_addr_t) tsk->gid); NEW_AUX_ENT(AT_EGID, (elf_addr_t) tsk->egid); + NEW_AUX_ENT(AT_SECURE, (elf_addr_t) security_bprm_secureexec(bprm)); if (k_platform) { NEW_AUX_ENT(AT_PLATFORM, (elf_addr_t)(long)u_platform); } diff -Nru a/fs/buffer.c b/fs/buffer.c --- a/fs/buffer.c Fri Jun 27 14:19:57 2003 +++ b/fs/buffer.c Fri Jun 27 14:19:57 2003 @@ -1337,7 +1337,7 @@ check_irqs_on(); bh_lru_lock(); - lru = &per_cpu(bh_lrus, smp_processor_id()); + lru = &__get_cpu_var(bh_lrus); if (lru->bhs[0] != bh) { struct buffer_head *bhs[BH_LRU_SIZE]; int in; @@ -1381,7 +1381,7 @@ check_irqs_on(); bh_lru_lock(); - lru = &per_cpu(bh_lrus, smp_processor_id()); + lru = &__get_cpu_var(bh_lrus); for (i = 0; i < BH_LRU_SIZE; i++) { struct buffer_head *bh = lru->bhs[i]; @@ -1474,15 +1474,14 @@ */ static void invalidate_bh_lru(void *arg) { - const int cpu = get_cpu(); - struct bh_lru *b = &per_cpu(bh_lrus, cpu); + struct bh_lru *b = &get_cpu_var(bh_lrus); int i; for (i = 0; i < BH_LRU_SIZE; i++) { brelse(b->bhs[i]); b->bhs[i] = NULL; } - put_cpu(); + put_cpu_var(bh_lrus); } static void invalidate_bh_lrus(void) diff -Nru a/fs/compat.c b/fs/compat.c --- a/fs/compat.c Fri Jun 27 14:19:56 2003 +++ b/fs/compat.c Fri Jun 27 14:19:56 2003 @@ -451,7 +451,6 @@ break; old_fs = get_fs(); set_fs(KERNEL_DS); - ret = sys_fcntl(fd, F_GETLK, (unsigned long)&f); ret = sys_fcntl(fd, (cmd == F_GETLK64) ? F_GETLK : ((cmd == F_SETLK64) ? F_SETLK : F_SETLKW), (unsigned long)&f); diff -Nru a/fs/compat_ioctl.c b/fs/compat_ioctl.c --- a/fs/compat_ioctl.c Fri Jun 27 14:20:04 2003 +++ b/fs/compat_ioctl.c Fri Jun 27 14:20:04 2003 @@ -1562,6 +1562,8 @@ extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); +#ifdef CONFIG_VT + static int vt_check(struct file *file) { struct tty_struct *tty; @@ -1693,6 +1695,8 @@ return 0; } +#endif /* CONFIG_VT */ + static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, unsigned long arg) { mm_segment_t old_fs = get_fs(); @@ -2398,11 +2402,13 @@ HANDLE_IOCTL(LOOP_GET_STATUS, loop_status) #define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout) +#ifdef CONFIG_VT HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl) HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl) HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl) HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl) +#endif HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl) HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl) HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl) diff -Nru a/fs/dcache.c b/fs/dcache.c --- a/fs/dcache.c Fri Jun 27 14:19:53 2003 +++ b/fs/dcache.c Fri Jun 27 14:19:53 2003 @@ -232,14 +232,17 @@ * we might still populate it if it was a * working directory or similar). */ + spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1) { if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) { + spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); return -EBUSY; } } __d_drop(dentry); + spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); return 0; } diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c --- a/fs/ext3/inode.c Fri Jun 27 14:19:59 2003 +++ b/fs/ext3/inode.c Fri Jun 27 14:19:59 2003 @@ -1662,33 +1662,21 @@ * This required during truncate. We need to physically zero the tail end * of that block so it doesn't yield old data if the file is later grown. */ -static int ext3_block_truncate_page(handle_t *handle, +static int ext3_block_truncate_page(handle_t *handle, struct page *page, struct address_space *mapping, loff_t from) { unsigned long index = from >> PAGE_CACHE_SHIFT; unsigned offset = from & (PAGE_CACHE_SIZE-1); unsigned blocksize, iblock, length, pos; struct inode *inode = mapping->host; - struct page *page; struct buffer_head *bh; int err; void *kaddr; blocksize = inode->i_sb->s_blocksize; - length = offset & (blocksize - 1); - - /* Block boundary? Nothing to do */ - if (!length) - return 0; - - length = blocksize - length; + length = blocksize - (offset & (blocksize - 1)); iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); - page = grab_cache_page(mapping, index); - err = -ENOMEM; - if (!page) - goto out; - if (!page_has_buffers(page)) create_empty_buffers(page, blocksize, 0); @@ -1756,7 +1744,6 @@ unlock: unlock_page(page); page_cache_release(page); -out: return err; } @@ -2137,13 +2124,15 @@ struct ext3_inode_info *ei = EXT3_I(inode); u32 *i_data = ei->i_data; int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb); + struct address_space *mapping = inode->i_mapping; int offsets[4]; Indirect chain[4]; Indirect *partial; int nr = 0; int n; long last_block; - unsigned blocksize; + unsigned blocksize = inode->i_sb->s_blocksize; + struct page *page; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) @@ -2155,16 +2144,36 @@ ext3_discard_prealloc(inode); + /* + * We have to lock the EOF page here, because lock_page() nests + * outside journal_start(). + */ + if ((inode->i_size & (blocksize - 1)) == 0) { + /* Block boundary? Nothing to do */ + page = NULL; + } else { + page = grab_cache_page(mapping, + inode->i_size >> PAGE_CACHE_SHIFT); + if (!page) + return; + } + handle = start_transaction(inode); if (IS_ERR(handle)) { + if (page) { + clear_highpage(page); + flush_dcache_page(page); + unlock_page(page); + page_cache_release(page); + } return; /* AKPM: return what? */ } - blocksize = inode->i_sb->s_blocksize; last_block = (inode->i_size + blocksize-1) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb); - ext3_block_truncate_page(handle, inode->i_mapping, inode->i_size); + if (page) + ext3_block_truncate_page(handle, page, mapping, inode->i_size); n = ext3_block_to_path(inode, last_block, offsets, NULL); if (n == 0) diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c --- a/fs/ext3/namei.c Fri Jun 27 14:19:57 2003 +++ b/fs/ext3/namei.c Fri Jun 27 14:19:57 2003 @@ -1295,12 +1295,12 @@ } root = (struct dx_root *) bh->b_data; - EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; bh2 = ext3_append (handle, dir, &block, &retval); if (!(bh2)) { brelse(bh); return retval; } + EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; data1 = bh2->b_data; /* The 0th block becomes the root, move the dirents out */ diff -Nru a/fs/hpfs/namei.c b/fs/hpfs/namei.c --- a/fs/hpfs/namei.c Fri Jun 27 14:19:55 2003 +++ b/fs/hpfs/namei.c Fri Jun 27 14:19:55 2003 @@ -372,12 +372,15 @@ if (rep) goto ret; d_drop(dentry); + spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1 || permission(inode, MAY_WRITE) || get_write_access(inode)) { + spin_unlock(&dentry->d_lock); d_rehash(dentry); goto ret; } + spin_unlock(&dentry->d_lock); /*printk("HPFS: truncating file before delete.\n");*/ newattrs.ia_size = 0; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; diff -Nru a/fs/jbd/commit.c b/fs/jbd/commit.c --- a/fs/jbd/commit.c Fri Jun 27 14:20:02 2003 +++ b/fs/jbd/commit.c Fri Jun 27 14:20:02 2003 @@ -727,9 +727,8 @@ __journal_unfile_buffer(jh); jh->b_transaction = 0; jbd_unlock_bh_state(bh); - journal_remove_journal_head(bh); - if (buffer_freed(bh)) - release_buffer_page(bh); + journal_remove_journal_head(bh); /* needs a brelse */ + release_buffer_page(bh); } spin_unlock(&journal->j_list_lock); } diff -Nru a/fs/jffs2/dir.c b/fs/jffs2/dir.c --- a/fs/jffs2/dir.c Fri Jun 27 14:20:00 2003 +++ b/fs/jffs2/dir.c Fri Jun 27 14:20:00 2003 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: dir.c,v 1.76 2003/05/26 09:50:38 dwmw2 Exp $ + * $Id: dir.c,v 1.77 2003/06/05 14:42:24 dwmw2 Exp $ * */ @@ -356,7 +356,7 @@ up(&f->sem); /* Work out where to put the dirent node now. */ - writtenlen = (writtenlen+3)&~3; + writtenlen = PAD(writtenlen); phys_ofs += writtenlen; alloclen -= writtenlen; @@ -653,7 +653,7 @@ up(&f->sem); /* Work out where to put the dirent node now. */ - writtenlen = (writtenlen+3)&~3; + writtenlen = PAD(writtenlen); phys_ofs += writtenlen; alloclen -= writtenlen; diff -Nru a/fs/jffs2/fs.c b/fs/jffs2/fs.c --- a/fs/jffs2/fs.c Fri Jun 27 14:19:56 2003 +++ b/fs/jffs2/fs.c Fri Jun 27 14:19:56 2003 @@ -22,7 +22,7 @@ #include <linux/vfs.h> #include "nodelist.h" -int jffs2_statfs(struct super_block *sb, struct statfs *buf) +int jffs2_statfs(struct super_block *sb, struct kstatfs *buf) { struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); unsigned long avail; diff -Nru a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h --- a/fs/jffs2/os-linux.h Fri Jun 27 14:19:53 2003 +++ b/fs/jffs2/os-linux.h Fri Jun 27 14:19:53 2003 @@ -123,7 +123,7 @@ #define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf)) #define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf)) -struct statfs; +struct kstatfs; /* wbuf.c */ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen); @@ -169,7 +169,7 @@ void jffs2_clear_inode (struct inode *); struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri); -int jffs2_statfs (struct super_block *, struct statfs *); +int jffs2_statfs (struct super_block *, struct kstatfs *); void jffs2_write_super (struct super_block *); int jffs2_remount_fs (struct super_block *, int *, char *); int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); diff -Nru a/fs/jffs2/scan.c b/fs/jffs2/scan.c --- a/fs/jffs2/scan.c Fri Jun 27 14:20:04 2003 +++ b/fs/jffs2/scan.c Fri Jun 27 14:20:04 2003 @@ -7,7 +7,7 @@ * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: scan.c,v 1.99 2003/04/28 10:17:17 dwmw2 Exp $ + * $Id: scan.c,v 1.100 2003/06/05 14:42:24 dwmw2 Exp $ * */ #include <linux/kernel.h> @@ -354,7 +354,7 @@ if (ofs & 3) { printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); - ofs = (ofs+3)&~3; + ofs = PAD(ofs); continue; } if (ofs == prevofs) { diff -Nru a/fs/lockd/svc.c b/fs/lockd/svc.c --- a/fs/lockd/svc.c Fri Jun 27 14:19:58 2003 +++ b/fs/lockd/svc.c Fri Jun 27 14:19:58 2003 @@ -34,7 +34,6 @@ #include <linux/sunrpc/svcsock.h> #include <linux/lockd/lockd.h> #include <linux/nfs.h> -#include <linux/suspend.h> #define NLMDBG_FACILITY NLMDBG_SVC #define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE) @@ -122,8 +121,6 @@ while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) { long timeout = MAX_SCHEDULE_TIMEOUT; - if (current->flags & PF_FREEZE) - refrigerator(PF_IOTHREAD); if (signalled()) { flush_signals(current); if (nlmsvc_ops) { diff -Nru a/fs/nfs/dir.c b/fs/nfs/dir.c --- a/fs/nfs/dir.c Fri Jun 27 14:19:56 2003 +++ b/fs/nfs/dir.c Fri Jun 27 14:19:56 2003 @@ -1015,7 +1015,9 @@ lock_kernel(); spin_lock(&dcache_lock); + spin_lock(&dentry->d_lock); if (atomic_read(&dentry->d_count) > 1) { + spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); error = nfs_sillyrename(dir, dentry); unlock_kernel(); @@ -1025,6 +1027,7 @@ __d_drop(dentry); need_rehash = 1; } + spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); error = nfs_safe_remove(dentry); if (!error) diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c --- a/fs/nfsd/export.c Fri Jun 27 14:19:57 2003 +++ b/fs/nfsd/export.c Fri Jun 27 14:19:57 2003 @@ -156,7 +156,7 @@ if (len == 0) { struct svc_expkey *ek; set_bit(CACHE_NEGATIVE, &key.h.flags); - ek = svc_expkey_lookup(&key, 2); + ek = svc_expkey_lookup(&key, 1); if (ek) expkey_put(&ek->h, &svc_expkey_cache); } else { @@ -176,7 +176,7 @@ key.ek_export = exp; dprintk("And found export\n"); - ek = svc_expkey_lookup(&key, 2); + ek = svc_expkey_lookup(&key, 1); if (ek) expkey_put(&ek->h, &svc_expkey_cache); exp_put(exp); @@ -184,7 +184,7 @@ out_nd: path_release(&nd); } - + cache_flush(); out: if (dom) auth_domain_put(dom); @@ -193,6 +193,30 @@ return err; } +static int expkey_show(struct seq_file *m, + struct cache_detail *cd, + struct cache_head *h) +{ + struct svc_expkey *ek ; + + if (h ==NULL) { + seq_puts(m, "#domain fsidtype fsid [path]\n"); + return 0; + } + ek = container_of(h, struct svc_expkey, h); + seq_printf(m, "%s %d 0x%08x", ek->ek_client->name, + ek->ek_fsidtype, ek->ek_fsid[0]); + if (ek->ek_fsid == 0) + seq_printf(m, "%08x", ek->ek_fsid[0]); + if (test_bit(CACHE_VALID, &h->flags) && + !test_bit(CACHE_NEGATIVE, &h->flags)) { + seq_printf(m, " "); + seq_path(m, ek->ek_export->ex_mnt, ek->ek_export->ex_dentry, "\\ \t\n"); + } + seq_printf(m, "\n"); + return 0; +} + struct cache_detail svc_expkey_cache = { .hash_size = EXPKEY_HASHMAX, .hash_table = expkey_table, @@ -200,6 +224,7 @@ .cache_put = expkey_put, .cache_request = expkey_request, .cache_parse = expkey_parse, + .cache_show = expkey_show, }; static inline int svc_expkey_match (struct svc_expkey *a, struct svc_expkey *b) @@ -231,7 +256,7 @@ new->ek_export = item->ek_export; } -static DefineSimpleCacheLookup(svc_expkey) +static DefineSimpleCacheLookup(svc_expkey,0) /* no inplace updates */ #define EXPORT_HASHBITS 8 #define EXPORT_HASHMAX (1<< EXPORT_HASHBITS) @@ -396,7 +421,7 @@ if (expp) exp_put(expp); err = 0; - + cache_flush(); out: if (nd.dentry) path_release(&nd); @@ -407,6 +432,30 @@ return err; } +static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong); + +static int svc_export_show(struct seq_file *m, + struct cache_detail *cd, + struct cache_head *h) +{ + struct svc_export *exp ; + + if (h ==NULL) { + seq_puts(m, "#path domain(flags)\n"); + return 0; + } + exp = container_of(h, struct svc_export, h); + seq_path(m, exp->ex_mnt, exp->ex_dentry, " \t\n\\"); + seq_putc(m, '\t'); + seq_escape(m, exp->ex_client->name, " \t\n\\"); + seq_putc(m, '('); + if (test_bit(CACHE_VALID, &h->flags) && + !test_bit(CACHE_NEGATIVE, &h->flags)) + exp_flags(m, exp->ex_flags, exp->ex_fsid, + exp->ex_anon_uid, exp->ex_anon_gid); + seq_puts(m, ")\n"); + return 0; +} struct cache_detail svc_export_cache = { .hash_size = EXPORT_HASHMAX, .hash_table = export_table, @@ -414,6 +463,7 @@ .cache_put = svc_export_put, .cache_request = svc_export_request, .cache_parse = svc_export_parse, + .cache_show = svc_export_show, }; static inline int svc_export_match(struct svc_export *a, struct svc_export *b) @@ -438,7 +488,7 @@ new->ex_fsid = item->ex_fsid; } -static DefineSimpleCacheLookup(svc_export) +static DefineSimpleCacheLookup(svc_export,1) /* allow inplace updates */ struct svc_expkey * @@ -976,17 +1026,11 @@ seq_printf(m, "%sanongid=%d", first++?",":"", anong); } -static inline void mangle(struct seq_file *m, const char *s) -{ - seq_escape(m, s, " \t\n\\"); -} - static int e_show(struct seq_file *m, void *p) { struct cache_head *cp = p; struct svc_export *exp = container_of(cp, struct svc_export, h); svc_client *clp; - char *pbuf; if (p == (void *)1) { seq_puts(m, "# Version 1.1\n"); @@ -999,17 +1043,7 @@ if (cache_check(&svc_export_cache, &exp->h, NULL)) return 0; if (cache_put(&exp->h, &svc_export_cache)) BUG(); - pbuf = m->private; - mangle(m, d_path(exp->ex_dentry, exp->ex_mnt, - pbuf, PAGE_SIZE)); - - seq_putc(m, '\t'); - mangle(m, clp->name); - seq_putc(m, '('); - exp_flags(m, exp->ex_flags, exp->ex_fsid, - exp->ex_anon_uid, exp->ex_anon_gid); - seq_puts(m, ")\n"); - return 0; + return svc_export_show(m, &svc_export_cache, cp); } struct seq_operations nfs_exports_op = { diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c --- a/fs/nfsd/nfs3xdr.c Fri Jun 27 14:19:30 2003 +++ b/fs/nfsd/nfs3xdr.c Fri Jun 27 14:19:30 2003 @@ -780,7 +780,7 @@ { struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, common); u32 *p = cd->buffer; - int buflen, slen, elen; + int slen, elen; if (cd->offset) xdr_encode_hyper(cd->offset, (u64) offset); @@ -797,7 +797,7 @@ slen = XDR_QUADLEN(namlen); elen = slen + NFS3_ENTRY_BAGGAGE + (plus? NFS3_ENTRYPLUS_BAGGAGE : 0); - if ((buflen = cd->buflen - elen) < 0) { + if (cd->buflen < elen) { cd->common.err = nfserr_readdir_nospc; return -EINVAL; } @@ -836,7 +836,7 @@ } out: - cd->buflen = buflen; + cd->buflen -= p - cd->buffer; cd->buffer = p; cd->common.err = nfs_ok; return 0; diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c --- a/fs/nfsd/nfs4proc.c Fri Jun 27 14:20:06 2003 +++ b/fs/nfsd/nfs4proc.c Fri Jun 27 14:20:06 2003 @@ -55,12 +55,6 @@ #define NFSDDBG_FACILITY NFSDDBG_PROC -static inline int -nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close) -{ - return nfs_ok; -} - /* Note: The organization of the OPEN code seems a little strange; it * has been superfluously split into three routines, one of which is named * nfsd4_process_open2() even though there is no nfsd4_process_open1()! @@ -140,10 +134,6 @@ status = nfsd4_process_open2(rqstp, current_fh, open); if (status) return status; - /* - * To finish the open response, we just need to set the rflags. - */ - open->op_rflags = 0; return 0; } @@ -356,14 +346,51 @@ static inline int nfsd4_read(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_read *read) { + struct nfs4_stateid *stp; + int status; + /* no need to check permission - this will be done in nfsd_read() */ if (read->rd_offset >= OFFSET_MAX) return nfserr_inval; + nfsd4_lock_state(); + status = nfs_ok; + /* For stateid -1, we don't check share reservations. */ + if (ONE_STATEID(&read->rd_stateid)) { + dprintk("NFSD: nfsd4_read: -1 stateid...\n"); + goto out; + } + /* + * For stateid 0, the client doesn't have to have the file open, but + * we still check for share reservation conflicts. + */ + if (ZERO_STATEID(&read->rd_stateid)) { + dprintk("NFSD: nfsd4_read: zero stateid...\n"); + if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_READ))) { + dprintk("NFSD: nfsd4_read: conflicting share reservation!\n"); + goto out; + } + status = nfs_ok; + goto out; + } + /* check stateid */ + if ((status = nfs4_preprocess_stateid_op(current_fh, &read->rd_stateid, + CHECK_FH, &stp))) { + dprintk("NFSD: nfsd4_read: couldn't process stateid!\n"); + goto out; + } + status = nfserr_openmode; + if (!(stp->st_share_access & NFS4_SHARE_ACCESS_READ)) { + dprintk("NFSD: nfsd4_read: file not opened for read!\n"); + goto out; + } + status = nfs_ok; +out: + nfsd4_unlock_state(); read->rd_rqstp = rqstp; read->rd_fhp = current_fh; - return nfs_ok; + return status; } static inline int @@ -425,28 +452,85 @@ static inline int nfsd4_setattr(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_setattr *setattr) { - return nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0); + struct nfs4_stateid *stp; + int status = nfs_ok; + + if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { + + status = nfserr_bad_stateid; + if (ZERO_STATEID(&setattr->sa_stateid) || ONE_STATEID(&setattr->sa_stateid)) { + dprintk("NFSD: nfsd4_setattr: magic stateid!\n"); + return status; + } + + nfsd4_lock_state(); + if ((status = nfs4_preprocess_stateid_op(current_fh, + &setattr->sa_stateid, + CHECK_FH, &stp))) { + dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n"); + goto out; + } + status = nfserr_openmode; + if (!(stp->st_share_access & NFS4_SHARE_ACCESS_WRITE)) { + dprintk("NFSD: nfsd4_setattr: not opened for write!\n"); + goto out; + } + nfsd4_unlock_state(); + } + return (nfsd_setattr(rqstp, current_fh, &setattr->sa_iattr, 0, (time_t)0)); +out: + nfsd4_unlock_state(); + return status; } static inline int nfsd4_write(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_write *write) { + struct nfs4_stateid *stp; + stateid_t *stateid = &write->wr_stateid; u32 *p; + int status = nfs_ok; /* no need to check permission - this will be done in nfsd_write() */ if (write->wr_offset >= OFFSET_MAX) return nfserr_inval; + nfsd4_lock_state(); + if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { + dprintk("NFSD: nfsd4_write: zero stateid...\n"); + if ((status = nfs4_share_conflict(current_fh, NFS4_SHARE_DENY_WRITE))) { + dprintk("NFSD: nfsd4_write: conflicting share reservation!\n"); + goto out; + } + goto zero_stateid; + } + if ((status = nfs4_preprocess_stateid_op(current_fh, stateid, + CHECK_FH, &stp))) { + dprintk("NFSD: nfsd4_write: couldn't process stateid!\n"); + goto out; + } + + status = nfserr_openmode; + if (!(stp->st_share_access & NFS4_SHARE_ACCESS_WRITE)) { + dprintk("NFSD: nfsd4_write: file not open for write!\n"); + goto out; + } + +zero_stateid: + nfsd4_unlock_state(); write->wr_bytes_written = write->wr_buflen; write->wr_how_written = write->wr_stable_how; p = (u32 *)write->wr_verifier; *p++ = nfssvc_boot.tv_sec; *p++ = nfssvc_boot.tv_usec; - return nfsd_write(rqstp, current_fh, write->wr_offset, + return (nfsd_write(rqstp, current_fh, write->wr_offset, write->wr_vec, write->wr_vlen, write->wr_buflen, - &write->wr_how_written); + &write->wr_how_written)); +out: + nfsd4_unlock_state(); + return status; } /* This routine never returns NFS_OK! If there are no other errors, it @@ -608,6 +692,12 @@ break; case OP_OPEN: op->status = nfsd4_open(rqstp, ¤t_fh, &op->u.open); + break; + case OP_OPEN_CONFIRM: + op->status = nfsd4_open_confirm(rqstp, ¤t_fh, &op->u.open_confirm); + break; + case OP_OPEN_DOWNGRADE: + op->status = nfsd4_open_downgrade(rqstp, ¤t_fh, &op->u.open_downgrade); break; case OP_PUTFH: op->status = nfsd4_putfh(rqstp, ¤t_fh, &op->u.putfh); diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c --- a/fs/nfsd/nfs4state.c Fri Jun 27 14:19:59 2003 +++ b/fs/nfsd/nfs4state.c Fri Jun 27 14:19:59 2003 @@ -56,12 +56,20 @@ static u32 current_ownerid = 0; static u32 current_fileid = 0; static u32 nfs4_init = 0; +stateid_t zerostateid; /* bits all 0 */ +stateid_t onestateid; /* bits all 1 */ /* debug counters */ u32 list_add_perfile = 0; u32 list_del_perfile = 0; u32 add_perclient = 0; u32 del_perclient = 0; +u32 alloc_file = 0; +u32 free_file = 0; +u32 alloc_sowner = 0; +u32 free_sowner = 0; +u32 vfsopen = 0; +u32 vfsclose = 0; /* Locking: * @@ -71,6 +79,18 @@ */ static struct semaphore client_sema; +void +nfsd4_lock_state(void) +{ + down(&client_sema); +} + +void +nfsd4_unlock_state(void) +{ + up(&client_sema); +} + static inline u32 opaque_hashval(const void *ptr, int nbytes) { @@ -87,6 +107,8 @@ /* forward declarations */ static void release_stateowner(struct nfs4_stateowner *sop); static void release_stateid(struct nfs4_stateid *stp); +static void release_file(struct nfs4_file *fp); + /* * SETCLIENTID state @@ -136,7 +158,8 @@ { if (clid->cl_boot == boot_time) return 0; - printk("NFSD stale clientid (%08x/%08x)\n", clid->cl_boot, clid->cl_id); + dprintk("NFSD stale clientid (%08x/%08x)\n", + clid->cl_boot, clid->cl_id); return 1; } @@ -294,6 +317,7 @@ { unsigned int strhashval; + dprintk("NFSD: move_to_confirm nfs4_client %p\n", clp); list_del_init(&clp->cl_strhash); list_del_init(&clp->cl_idhash); list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]); @@ -646,20 +670,30 @@ #define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS) #define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1) +#define ownerid_hashval(id) \ + ((id) & OWNER_HASH_MASK) #define ownerstr_hashval(clientid, ownername) \ (((clientid) + opaque_hashval((ownername.data), (ownername.len))) & OWNER_HASH_MASK) +static struct list_head ownerid_hashtbl[OWNER_HASH_SIZE]; static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE]; /* hash table for nfs4_file */ #define FILE_HASH_BITS 8 #define FILE_HASH_SIZE (1 << FILE_HASH_BITS) #define FILE_HASH_MASK (FILE_HASH_SIZE - 1) +/* hash table for (open)nfs4_stateid */ +#define OPENSTATEID_HASH_BITS 10 +#define OPENSTATEID_HASH_SIZE (1 << OPENSTATEID_HASH_BITS) +#define OPENSTATEID_HASH_MASK (OPENSTATEID_HASH_SIZE - 1) #define file_hashval(x) \ ((unsigned int)((x)->dev + (x)->ino + (x)->generation) & FILE_HASH_MASK) +#define openstateid_hashval(owner_id, file_id) \ + (((owner_id) + (file_id)) & OPENSTATEID_HASH_MASK) static struct list_head file_hashtbl[FILE_HASH_SIZE]; +static struct list_head openstateid_hashtbl[OPENSTATEID_HASH_SIZE]; /* OPEN Share state helper functions */ static inline struct nfs4_file * @@ -671,6 +705,7 @@ list_add(&fp->fi_hash, &file_hashtbl[hashval]); memcpy(&fp->fi_ino, ino, sizeof(nfs4_ino_desc_t)); fp->fi_id = current_fileid++; + alloc_file++; return fp; } return (struct nfs4_file *)NULL; @@ -689,8 +724,7 @@ if(!list_empty(&fp->fi_perfile)) { printk("ERROR: release_all_files: file %p is open, creating dangling state !!!\n",fp); } - list_del_init(&fp->fi_hash); - kfree(fp); + release_file(fp); } } } @@ -718,26 +752,31 @@ kfree(sop->so_owner.data); kfree(sop); sop = NULL; + free_sowner++; } } static struct nfs4_stateowner * alloc_init_stateowner(unsigned int strhashval, struct nfs4_client *clp, struct nfsd4_open *open) { struct nfs4_stateowner *sop; + unsigned int idhashval; if (!(sop = alloc_stateowner(&open->op_owner))) return (struct nfs4_stateowner *)NULL; + idhashval = ownerid_hashval(current_ownerid); + INIT_LIST_HEAD(&sop->so_idhash); INIT_LIST_HEAD(&sop->so_strhash); INIT_LIST_HEAD(&sop->so_perclient); INIT_LIST_HEAD(&sop->so_peropenstate); + list_add(&sop->so_idhash, &ownerid_hashtbl[idhashval]); list_add(&sop->so_strhash, &ownerstr_hashtbl[strhashval]); list_add(&sop->so_perclient, &clp->cl_perclient); add_perclient++; sop->so_id = current_ownerid++; sop->so_client = clp; sop->so_seqid = open->op_seqid; - /* until open_confirm is coded, pretend it happened! */ - sop->so_confirmed = 1; + sop->so_confirmed = 0; + alloc_sowner++; return sop; } @@ -746,6 +785,7 @@ { struct nfs4_stateid *stp; + list_del_init(&sop->so_idhash); list_del_init(&sop->so_strhash); list_del_init(&sop->so_perclient); del_perclient++; @@ -759,9 +799,12 @@ static inline void init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfs4_stateowner *sop, struct nfsd4_open *open) { + unsigned int hashval = openstateid_hashval(sop->so_id, fp->fi_id); + INIT_LIST_HEAD(&stp->st_hash); INIT_LIST_HEAD(&stp->st_peropenstate); INIT_LIST_HEAD(&stp->st_perfile); + list_add(&stp->st_hash, &openstateid_hashtbl[hashval]); list_add(&stp->st_peropenstate, &sop->so_peropenstate); list_add_perfile++; list_add(&stp->st_perfile, &fp->fi_perfile); @@ -778,11 +821,13 @@ static void release_stateid(struct nfs4_stateid *stp) { + list_del_init(&stp->st_hash); list_del_perfile++; list_del_init(&stp->st_perfile); list_del_init(&stp->st_peropenstate); if(stp->st_vfs_set) { nfsd_close(&stp->st_vfs_file); + vfsclose++; dput(stp->st_vfs_file.f_dentry); mntput(stp->st_vfs_file.f_vfsmnt); } @@ -791,6 +836,37 @@ stp = NULL; } +static void +release_file(struct nfs4_file *fp) +{ + free_file++; + list_del_init(&fp->fi_hash); + kfree(fp); +} + +void +release_open_state(struct nfs4_stateid *stp) +{ + struct nfs4_stateowner *sop = stp->st_stateowner; + struct nfs4_file *fp = stp->st_file; + + dprintk("NFSD: release_open_state\n"); + release_stateid(stp); + /* + * release unused nfs4_stateowners. + * XXX will need to be placed on an open_stateid_lru list to be + * released by the laundromat service after the lease period + * to enable us to handle CLOSE replay + */ + if (sop->so_confirmed && list_empty(&sop->so_peropenstate)) { + release_stateowner(sop); + } + /* unused nfs4_file's are releseed. XXX slab cache? */ + if (list_empty(&fp->fi_perfile)) { + release_file(fp); + } +} + static int cmp_owner_str(struct nfs4_stateowner *sop, struct nfsd4_open *open) { return ((sop->so_owner.len == open->op_owner.len) && @@ -872,6 +948,30 @@ ino->generation = inode->i_generation; } +int +nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) +{ + nfs4_ino_desc_t ino; + unsigned int fi_hashval; + struct nfs4_file *fp; + struct nfs4_stateid *stp; + struct list_head *pos, *next; + + dprintk("NFSD: nfs4_share_conflict\n"); + + nfs4_init_ino(&ino, current_fh); + fi_hashval = file_hashval(&ino); + if (find_file(fi_hashval, &ino, &fp)) { + /* Search for conflicting share reservations */ + list_for_each_safe(pos, next, &fp->fi_perfile) { + stp = list_entry(pos, struct nfs4_stateid, st_perfile); + if (stp->st_share_deny & deny_type) + return nfserr_share_denied; + } + } + return nfs_ok; +} + static inline int nfs4_file_upgrade(struct file *filp, unsigned int share_access) { @@ -887,6 +987,15 @@ return nfs_ok; } +static inline void +nfs4_file_downgrade(struct file *filp, unsigned int share_access) +{ + if (share_access & NFS4_SHARE_ACCESS_WRITE) { + put_write_access(filp->f_dentry->d_inode); + filp->f_mode = FMODE_READ; + } +} + /* * nfsd4_process_open1() @@ -981,7 +1090,6 @@ struct nfs4_stateid *stq, *stp = NULL; int status; - status = nfserr_resource; if (!sop) goto out; @@ -1026,6 +1134,7 @@ &stp->st_vfs_file)) != 0) goto out_free; + vfsopen++; dget(stp->st_vfs_file.f_dentry); mntget(stp->st_vfs_file.f_vfsmnt); @@ -1063,6 +1172,13 @@ open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE; status = nfs_ok; out: + /* + * To finish the open response, we just need to set the rflags. + */ + open->op_rflags = 0; + if (!open->op_stateowner->so_confirmed) + open->op_rflags |= NFS4_OPEN_RESULT_CONFIRM; + up(&client_sema); /*XXX need finer grained locking */ return status; out_free: @@ -1154,6 +1270,326 @@ schedule_delayed_work(&laundromat_work, t*HZ); } +/* search openstateid_hashtbl[] for stateid */ +struct nfs4_stateid * +find_stateid(stateid_t *stid) +{ + struct list_head *pos, *next; + struct nfs4_stateid *local = NULL; + u32 st_id = stid->si_stateownerid; + u32 f_id = stid->si_fileid; + unsigned int hashval = openstateid_hashval(st_id, f_id); + + list_for_each_safe(pos, next, &openstateid_hashtbl[hashval]) { + local = list_entry(pos, struct nfs4_stateid, st_hash); + if((local->st_stateid.si_stateownerid == st_id) && + (local->st_stateid.si_fileid == f_id)) + return local; + } + return NULL; +} + +/* search ownerid_hashtbl[] for stateid owner (stateid->si_stateownerid) */ +struct nfs4_stateowner * +find_stateowner_id(u32 st_id) { + struct list_head *pos, *next; + struct nfs4_stateowner *local = NULL; + unsigned int hashval = ownerid_hashval(st_id); + + list_for_each_safe(pos, next, &ownerid_hashtbl[hashval]) { + local = list_entry(pos, struct nfs4_stateowner, so_idhash); + if(local->so_id == st_id) + return local; + } + return NULL; +} + +static inline int +nfs4_check_fh(struct svc_fh *fhp, struct nfs4_stateid *stp) +{ + return (fhp->fh_dentry != stp->st_vfs_file.f_dentry); +} + +static int +STALE_STATEID(stateid_t *stateid) +{ + if (stateid->si_boot == boot_time) + return 0; + printk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", + stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, + stateid->si_generation); + return 1; +} + + +/* +* Checks for stateid operations +*/ +int +nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int flags, struct nfs4_stateid **stpp) +{ + struct nfs4_stateid *stp; + int status; + + dprintk("NFSD: preprocess_stateid_op:stateid = (%08x/%08x/%08x/%08x)\n", + stateid->si_boot, stateid->si_stateownerid, + stateid->si_fileid, stateid->si_generation); + + *stpp = NULL; + + /* STALE STATEID */ + status = nfserr_stale_stateid; + if (STALE_STATEID(stateid)) + goto out; + + /* BAD STATEID */ + status = nfserr_bad_stateid; + if (!(stp = find_stateid(stateid))) { + dprintk("NFSD: process stateid: no open stateid!\n"); + goto out; + } + if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) { + dprintk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n"); + goto out; + } + if (!stp->st_stateowner->so_confirmed) { + dprintk("process_stateid: lockowner not confirmed yet!\n"); + goto out; + } + if (stateid->si_generation > stp->st_stateid.si_generation) { + dprintk("process_stateid: future stateid?!\n"); + goto out; + } + + /* OLD STATEID */ + status = nfserr_old_stateid; + if (stateid->si_generation < stp->st_stateid.si_generation) { + dprintk("process_stateid: old stateid!\n"); + goto out; + } + *stpp = stp; + status = nfs_ok; + renew_client(stp->st_stateowner->so_client); +out: + return status; +} + + +/* + * Checks for sequence id mutating operations. + * + * XXX need to code replay cache logic + */ +int +nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp) +{ + int status; + struct nfs4_stateid *stp; + struct nfs4_stateowner *sop; + + dprintk("NFSD: preprocess_seqid_op: seqid=%d " + "stateid = (%08x/%08x/%08x/%08x)\n", seqid, + stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, + stateid->si_generation); + + *stpp = NULL; + *sopp = NULL; + + status = nfserr_bad_stateid; + if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { + printk("NFSD: preprocess_seqid_op: magic stateid!\n"); + goto out; + } + + status = nfserr_stale_stateid; + if (STALE_STATEID(stateid)) + goto out; + /* + * We return BAD_STATEID if filehandle doesn't match stateid, + * the confirmed flag is incorrecly set, or the generation + * number is incorrect. + * If there is no entry in the openfile table for this id, + * we can't always return BAD_STATEID; + * this might be a retransmitted CLOSE which has arrived after + * the openfile has been released. + */ + if (!(stp = find_stateid(stateid))) + goto no_nfs4_stateid; + + status = nfserr_bad_stateid; + + if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) { + printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n"); + goto out; + } + + *stpp = stp; + *sopp = sop = stp->st_stateowner; + + /* + * We now validate the seqid and stateid generation numbers. + * For the moment, we ignore the possibility of + * generation number wraparound. + */ + if (seqid != sop->so_seqid + 1) + goto check_replay; + + if (sop->so_confirmed) { + if (flags & CONFIRM) { + printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n"); + goto out; + } + } + else { + if (!(flags & CONFIRM)) { + printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n"); + goto out; + } + } + if (stateid->si_generation > stp->st_stateid.si_generation) { + printk("NFSD: preprocess_seqid_op: future stateid?!\n"); + goto out; + } + + status = nfserr_old_stateid; + if (stateid->si_generation < stp->st_stateid.si_generation) { + printk("NFSD: preprocess_seqid_op: old stateid!\n"); + goto out; + } + /* XXX renew the client lease here */ + status = nfs_ok; + +out: + return status; + +no_nfs4_stateid: + + /* + * We determine whether this is a bad stateid or a replay, + * starting by trying to look up the stateowner. + * If stateowner is not found - stateid is bad. + */ + if (!(sop = find_stateowner_id(stateid->si_stateownerid))) { + printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n"); + status = nfserr_bad_stateid; + goto out; + } + +check_replay: + status = nfserr_bad_seqid; + if (seqid == sop->so_seqid) { + printk("NFSD: preprocess_seqid_op: retransmission?\n"); + /* XXX will need to indicate replay to calling function here */ + } else + printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid); + + goto out; +} + +int +nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_confirm *oc) +{ + int status; + struct nfs4_stateowner *sop; + struct nfs4_stateid *stp; + + dprintk("NFSD: nfsd4_open_confirm on file %.*s\n", + current_fh->fh_dentry->d_name.len, + current_fh->fh_dentry->d_name.name); + oc->oc_stateowner = NULL; + down(&client_sema); /* XXX need finer grained locking */ + + if ((status = nfs4_preprocess_seqid_op(current_fh, oc->oc_seqid, + &oc->oc_req_stateid, + CHECK_FH | CONFIRM, + &oc->oc_stateowner, &stp))) + goto out; + + sop = oc->oc_stateowner; + sop->so_confirmed = 1; + update_stateid(&stp->st_stateid); + memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); + /* XXX renew the client lease here */ + dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " + "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid, + stp->st_stateid.si_boot, + stp->st_stateid.si_stateownerid, + stp->st_stateid.si_fileid, + stp->st_stateid.si_generation); + status = nfs_ok; +out: + up(&client_sema); + return status; +} +int +nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open_downgrade *od) +{ + int status; + struct nfs4_stateid *stp; + + dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n", + current_fh->fh_dentry->d_name.len, + current_fh->fh_dentry->d_name.name); + + down(&client_sema); /* XXX need finer grained locking */ + if ((status = nfs4_preprocess_seqid_op(current_fh, od->od_seqid, + &od->od_stateid, + CHECK_FH, &od->od_stateowner, &stp))) + goto out; + + status = nfserr_inval; + if (od->od_share_access & ~stp->st_share_access) { + dprintk("NFSD:access not a subset current=%08x, desired=%08x\n", + stp->st_share_access, od->od_share_access); + goto out; + } + if (od->od_share_deny & ~stp->st_share_deny) { + dprintk("NFSD:deny not a subset current=%08x, desired=%08x\n", + stp->st_share_deny, od->od_share_deny); + goto out; + } + nfs4_file_downgrade(&stp->st_vfs_file, + stp->st_share_access & ~od->od_share_access); + stp->st_share_access = od->od_share_access; + stp->st_share_deny = od->od_share_deny; + update_stateid(&stp->st_stateid); + memcpy(&od->od_stateid, &stp->st_stateid, sizeof(stateid_t)); + status = nfs_ok; +out: + up(&client_sema); + return status; +} + +int +nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_close *close) +{ + int status; + struct nfs4_stateid *stp; + + dprintk("NFSD: nfsd4_close on file %.*s\n", + current_fh->fh_dentry->d_name.len, + current_fh->fh_dentry->d_name.name); + + down(&client_sema); /* XXX need finer grained locking */ + if ((status = nfs4_preprocess_seqid_op(current_fh, close->cl_seqid, + &close->cl_stateid, + CHECK_FH, + &close->cl_stateowner, &stp))) + goto out; + /* + * Return success, but first update the stateid. + */ + status = nfs_ok; + update_stateid(&stp->st_stateid); + memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); + + /* release_open_state() calls nfsd_close() if needed */ + release_open_state(stp); +out: + up(&client_sema); + return status; +} + void nfs4_state_init(void) { @@ -1172,7 +1608,14 @@ } for (i = 0; i < OWNER_HASH_SIZE; i++) { INIT_LIST_HEAD(&ownerstr_hashtbl[i]); + INIT_LIST_HEAD(&ownerid_hashtbl[i]); + } + for (i = 0; i < OPENSTATEID_HASH_SIZE; i++) { + INIT_LIST_HEAD(&openstateid_hashtbl[i]); } + memset(&zerostateid, 0, sizeof(stateid_t)); + memset(&onestateid, ~0, sizeof(stateid_t)); + INIT_LIST_HEAD(&client_lru); init_MUTEX(&client_sema); boot_time = get_seconds(); @@ -1206,6 +1649,12 @@ list_add_perfile, list_del_perfile); dprintk("NFSD: add_perclient %d del_perclient %d\n", add_perclient, del_perclient); + dprintk("NFSD: alloc_file %d free_file %d\n", + alloc_file, free_file); + dprintk("NFSD: alloc_sowner %d free_sowner %d\n", + alloc_sowner, free_sowner); + dprintk("NFSD: vfsopen %d vfsclose %d\n", + vfsopen, vfsclose); } void diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c --- a/fs/nfsd/nfs4xdr.c Fri Jun 27 14:20:00 2003 +++ b/fs/nfsd/nfs4xdr.c Fri Jun 27 14:20:00 2003 @@ -660,6 +660,34 @@ } static int +nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf) +{ + DECODE_HEAD; + + READ_BUF(4 + sizeof(stateid_t)); + READ32(open_conf->oc_req_stateid.si_generation); + COPYMEM(&open_conf->oc_req_stateid.si_opaque, sizeof(stateid_opaque_t)); + READ32(open_conf->oc_seqid); + + DECODE_TAIL; +} + +static int +nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down) +{ + DECODE_HEAD; + + READ_BUF(4 + sizeof(stateid_t)); + READ32(open_down->od_stateid.si_generation); + COPYMEM(&open_down->od_stateid.si_opaque, sizeof(stateid_opaque_t)); + READ32(open_down->od_seqid); + READ32(open_down->od_share_access); + READ32(open_down->od_share_deny); + + DECODE_TAIL; +} + +static int nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh) { DECODE_HEAD; @@ -953,6 +981,12 @@ case OP_OPEN: op->status = nfsd4_decode_open(argp, &op->u.open); break; + case OP_OPEN_CONFIRM: + op->status = nfsd4_decode_open_confirm(argp, &op->u.open_confirm); + break; + case OP_OPEN_DOWNGRADE: + op->status = nfsd4_decode_open_downgrade(argp, &op->u.open_downgrade); + break; case OP_PUTFH: op->status = nfsd4_decode_putfh(argp, &op->u.putfh); break; @@ -1057,6 +1091,21 @@ } while (0) #define ADJUST_ARGS() resp->p = p +/* + * Routine for encoding the result of a + * "seqid-mutating" NFSv4 operation. This is + * where seqids are incremented + */ + +#define ENCODE_SEQID_OP_TAIL(stateowner) \ + BUG_ON(!stateowner); \ + if (seqid_mutating_err(nfserr) && stateowner) { \ + if (stateowner->so_confirmed) \ + stateowner->so_seqid++; \ + } \ + return nfserr; + + static u32 nfs4_ftypes[16] = { NF4BAD, NF4FIFO, NF4CHR, NF4BAD, NF4DIR, NF4BAD, NF4BLK, NF4BAD, @@ -1702,6 +1751,36 @@ } static int +nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_confirm *oc) +{ + ENCODE_HEAD; + + if (!nfserr) { + RESERVE_SPACE(sizeof(stateid_t)); + WRITE32(oc->oc_resp_stateid.si_generation); + WRITEMEM(&oc->oc_resp_stateid.si_opaque, sizeof(stateid_opaque_t)); + ADJUST_ARGS(); + } + + ENCODE_SEQID_OP_TAIL(oc->oc_stateowner); +} + +static int +nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_open_downgrade *od) +{ + ENCODE_HEAD; + + if (!nfserr) { + RESERVE_SPACE(sizeof(stateid_t)); + WRITE32(od->od_stateid.si_generation); + WRITEMEM(&od->od_stateid.si_opaque, sizeof(stateid_opaque_t)); + ADJUST_ARGS(); + } + + ENCODE_SEQID_OP_TAIL(od->od_stateowner); +} + +static int nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) { u32 eof; @@ -2012,6 +2091,12 @@ break; case OP_OPEN: nfsd4_encode_open(resp, op->status, &op->u.open); + break; + case OP_OPEN_CONFIRM: + nfsd4_encode_open_confirm(resp, op->status, &op->u.open_confirm); + break; + case OP_OPEN_DOWNGRADE: + nfsd4_encode_open_downgrade(resp, op->status, &op->u.open_downgrade); break; case OP_PUTFH: break; diff -Nru a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c --- a/fs/nfsd/nfsctl.c Fri Jun 27 14:19:54 2003 +++ b/fs/nfsd/nfsctl.c Fri Jun 27 14:19:54 2003 @@ -175,32 +175,14 @@ extern struct seq_operations nfs_exports_op; static int exports_open(struct inode *inode, struct file *file) { - int res; - char *namebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (namebuf == NULL) - return -ENOMEM; - - res = seq_open(file, &nfs_exports_op); - if (res) - kfree(namebuf); - else - ((struct seq_file *)file->private_data)->private = namebuf; - - return res; -} -static int exports_release(struct inode *inode, struct file *file) -{ - struct seq_file *m = (struct seq_file *)file->private_data; - kfree(m->private); - m->private = NULL; - return seq_release(inode, file); + return seq_open(file, &nfs_exports_op); } static struct file_operations exports_operations = { .open = exports_open, .read = seq_read, .llseek = seq_lseek, - .release = exports_release, + .release = seq_release, }; /*----------------------------------------------------------------------------*/ diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c --- a/fs/nfsd/nfssvc.c Fri Jun 27 14:19:57 2003 +++ b/fs/nfsd/nfssvc.c Fri Jun 27 14:19:57 2003 @@ -209,8 +209,8 @@ * recvfrom routine. */ while ((err = svc_recv(serv, rqstp, - 5*60*HZ)) == -EAGAIN) - cache_clean(); + 60*60*HZ)) == -EAGAIN) + ; if (err < 0) break; update_thread_usage(atomic_read(&nfsd_busy)); diff -Nru a/fs/smbfs/inode.c b/fs/smbfs/inode.c --- a/fs/smbfs/inode.c Fri Jun 27 14:19:53 2003 +++ b/fs/smbfs/inode.c Fri Jun 27 14:19:53 2003 @@ -526,6 +526,7 @@ goto out_no_mem; server->ops = mem; + smb_install_null_ops(server->ops); server->mnt = mem + sizeof(struct smb_ops); /* Setup NLS stuff */ diff -Nru a/fs/smbfs/proc.c b/fs/smbfs/proc.c --- a/fs/smbfs/proc.c Fri Jun 27 14:19:53 2003 +++ b/fs/smbfs/proc.c Fri Jun 27 14:19:53 2003 @@ -2802,6 +2802,13 @@ return result; } +static int +smb_proc_getattr_null(struct smb_sb_info *server, struct dentry *dir, + struct smb_fattr *attr) +{ + return -EIO; +} + int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr) { @@ -3429,3 +3436,14 @@ /* .setattr = smb_proc_setattr_unix, */ .truncate = smb_proc_trunc64, }; + +/* Place holder until real ops are in place */ +static struct smb_ops smb_ops_null = +{ + .getattr = smb_proc_getattr_null, +}; + +void smb_install_null_ops(struct smb_ops *ops) +{ + install_ops(ops, &smb_ops_null); +} diff -Nru a/fs/xfs/linux/xfs_globals.c b/fs/xfs/linux/xfs_globals.c --- a/fs/xfs/linux/xfs_globals.c Fri Jun 27 14:19:58 2003 +++ b/fs/xfs/linux/xfs_globals.c Fri Jun 27 14:19:58 2003 @@ -48,7 +48,7 @@ * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n, * other XFS code uses these values. */ -xfs_param_t xfs_params = { 0, 1, 0, 0, 0, 3, 30 * HZ }; +xfs_param_t xfs_params = { 0, 1, 0, 0, 3, 30 * HZ, 0 }; /* * Global system credential structure. diff -Nru a/fs/xfs/linux/xfs_iops.c b/fs/xfs/linux/xfs_iops.c --- a/fs/xfs/linux/xfs_iops.c Fri Jun 27 14:19:55 2003 +++ b/fs/xfs/linux/xfs_iops.c Fri Jun 27 14:19:55 2003 @@ -150,8 +150,10 @@ if (S_ISCHR(mode) || S_ISBLK(mode)) ip->i_rdev = to_kdev_t(rdev); - validate_fields(dir); + else if (S_ISDIR(mode)) + validate_fields(ip); d_instantiate(dentry, ip); + validate_fields(dir); } if (!error && have_default_acl) { @@ -663,8 +665,10 @@ } /* Convert Linux syscall to XFS internal ATTR flags */ - if (!size) + if (!size) { xflags |= ATTR_KERNOVAL; + data = NULL; + } if (strncmp(name, xfs_namespaces[ROOT_NAMES].name, xfs_namespaces[ROOT_NAMES].namelen) == 0) { diff -Nru a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c --- a/fs/xfs/linux/xfs_super.c Fri Jun 27 14:20:04 2003 +++ b/fs/xfs/linux/xfs_super.c Fri Jun 27 14:20:04 2003 @@ -483,7 +483,7 @@ int error; VFS_STATVFS(vfsp, statp, NULL, error); - return error; + return -error; } STATIC int @@ -500,7 +500,7 @@ if (!error) VFS_MNTUPDATE(vfsp, flags, args, error); kmem_free(args, sizeof(*args)); - return error; + return -error; } STATIC void diff -Nru a/fs/xfs/linux/xfs_sysctl.c b/fs/xfs/linux/xfs_sysctl.c --- a/fs/xfs/linux/xfs_sysctl.c Fri Jun 27 14:20:06 2003 +++ b/fs/xfs/linux/xfs_sysctl.c Fri Jun 27 14:20:06 2003 @@ -36,12 +36,13 @@ #include <linux/proc_fs.h> -STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0, 0, HZ }; -STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 1, 127, 3, HZ * 60 }; +STATIC ulong xfs_min[XFS_PARAM] = { 0, 0, 0, 0, 0, HZ, 0 }; +STATIC ulong xfs_max[XFS_PARAM] = { 1, 1, 1, 127, 3, HZ * 60, 1 }; static struct ctl_table_header *xfs_table_header; +#ifdef CONFIG_PROC_FS STATIC int xfs_stats_clear_proc_handler( ctl_table *ctl, @@ -66,35 +67,39 @@ return ret; } +#endif /* CONFIG_PROC_FS */ STATIC ctl_table xfs_table[] = { - {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear, - sizeof(ulong), 0644, NULL, &xfs_stats_clear_proc_handler, - &sysctl_intvec, NULL, &xfs_min[0], &xfs_max[0]}, - {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown, sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax, - &sysctl_intvec, NULL, &xfs_min[1], &xfs_max[1]}, + &sysctl_intvec, NULL, &xfs_min[0], &xfs_max[0]}, {XFS_SGID_INHERIT, "irix_sgid_inherit", &xfs_params.sgid_inherit, sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax, - &sysctl_intvec, NULL, &xfs_min[2], &xfs_max[2]}, + &sysctl_intvec, NULL, &xfs_min[1], &xfs_max[1]}, {XFS_SYMLINK_MODE, "irix_symlink_mode", &xfs_params.symlink_mode, sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax, - &sysctl_intvec, NULL, &xfs_min[3], &xfs_max[3]}, + &sysctl_intvec, NULL, &xfs_min[2], &xfs_max[2]}, {XFS_PANIC_MASK, "panic_mask", &xfs_params.panic_mask, sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax, - &sysctl_intvec, NULL, &xfs_min[4], &xfs_max[4]}, + &sysctl_intvec, NULL, &xfs_min[3], &xfs_max[3]}, {XFS_ERRLEVEL, "error_level", &xfs_params.error_level, sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax, - &sysctl_intvec, NULL, &xfs_min[5], &xfs_max[5]}, + &sysctl_intvec, NULL, &xfs_min[4], &xfs_max[4]}, {XFS_SYNC_INTERVAL, "sync_interval", &xfs_params.sync_interval, sizeof(ulong), 0644, NULL, &proc_doulongvec_minmax, + &sysctl_intvec, NULL, &xfs_min[5], &xfs_max[5]}, + + /* please keep this the last entry */ +#ifdef CONFIG_PROC_FS + {XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear, + sizeof(ulong), 0644, NULL, &xfs_stats_clear_proc_handler, &sysctl_intvec, NULL, &xfs_min[6], &xfs_max[6]}, +#endif /* CONFIG_PROC_FS */ {0} }; diff -Nru a/fs/xfs/linux/xfs_sysctl.h b/fs/xfs/linux/xfs_sysctl.h --- a/fs/xfs/linux/xfs_sysctl.h Fri Jun 27 14:19:30 2003 +++ b/fs/xfs/linux/xfs_sysctl.h Fri Jun 27 14:19:30 2003 @@ -42,7 +42,6 @@ #define XFS_PARAM (sizeof(struct xfs_param) / sizeof(ulong)) typedef struct xfs_param { - ulong stats_clear; /* Reset all XFS statistics to zero. */ ulong restrict_chown; /* Root/non-root can give away files. */ ulong sgid_inherit; /* Inherit ISGID bit if process' GID is */ /* not a member of the parent dir GID. */ @@ -50,6 +49,7 @@ ulong panic_mask; /* bitmask to specify panics on errors. */ ulong error_level; /* Degree of reporting for internal probs*/ ulong sync_interval; /* time between sync calls */ + ulong stats_clear; /* Reset all XFS statistics to zero. */ } xfs_param_t; /* @@ -68,13 +68,13 @@ */ enum { - XFS_STATS_CLEAR = 1, - XFS_RESTRICT_CHOWN = 2, - XFS_SGID_INHERIT = 3, - XFS_SYMLINK_MODE = 4, - XFS_PANIC_MASK = 5, - XFS_ERRLEVEL = 6, - XFS_SYNC_INTERVAL = 7, + XFS_RESTRICT_CHOWN = 1, + XFS_SGID_INHERIT = 2, + XFS_SYMLINK_MODE = 3, + XFS_PANIC_MASK = 4, + XFS_ERRLEVEL = 5, + XFS_SYNC_INTERVAL = 6, + XFS_STATS_CLEAR = 7, }; extern xfs_param_t xfs_params; diff -Nru a/fs/xfs/linux/xfs_vfs.h b/fs/xfs/linux/xfs_vfs.h --- a/fs/xfs/linux/xfs_vfs.h Fri Jun 27 14:19:52 2003 +++ b/fs/xfs/linux/xfs_vfs.h Fri Jun 27 14:19:52 2003 @@ -87,9 +87,10 @@ #define SYNC_CLOSE 0x0002 /* close file system down */ #define SYNC_DELWRI 0x0004 /* look at delayed writes */ #define SYNC_WAIT 0x0008 /* wait for i/o to complete */ -#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ #define SYNC_BDFLUSH 0x0010 /* BDFLUSH is calling -- don't block */ - +#define SYNC_FSDATA 0x0020 /* flush fs data (e.g. superblocks) */ +#define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ +#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ typedef int (*vfs_mount_t)(bhv_desc_t *, struct xfs_mount_args *, struct cred *); diff -Nru a/fs/xfs/pagebuf/page_buf.c b/fs/xfs/pagebuf/page_buf.c --- a/fs/xfs/pagebuf/page_buf.c Fri Jun 27 14:19:52 2003 +++ b/fs/xfs/pagebuf/page_buf.c Fri Jun 27 14:19:52 2003 @@ -1689,10 +1689,10 @@ int pincount = 0; int flush_cnt = 0; + pagebuf_runall_queues(pagebuf_dataio_workqueue); + spin_lock(&pbd_delwrite_lock); INIT_LIST_HEAD(&tmp); - - pagebuf_runall_queues(pagebuf_dataio_workqueue); list_for_each_safe(curr, next, &pbd_delwrite_queue) { pb = list_entry(curr, page_buf_t, pb_list); diff -Nru a/fs/xfs/support/kmem.c b/fs/xfs/support/kmem.c --- a/fs/xfs/support/kmem.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Further, this software is distributed without any warranty that it is - * free of the rightful claim of any third person regarding infringement - * or the like. Any license provided herein, whether implied or - * otherwise, applies only to this software file. Patent licenses, if - * any, provided herein do not apply to combinations of this program with - * other software, or any other product whatsoever. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ - */ - -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/highmem.h> -#include <linux/vmalloc.h> -#include <linux/slab.h> - -#include "time.h" -#include "kmem.h" - -#define DEF_PRIORITY (6) -#define MAX_SLAB_SIZE 0x10000 - -static __inline unsigned int flag_convert(int flags) -{ -#if DEBUG - if (unlikely(flags & ~(KM_SLEEP|KM_NOSLEEP|KM_NOFS))) { - printk(KERN_WARNING - "XFS: memory allocation with wrong flags (%x)\n", flags); - BUG(); - } -#endif - - if (flags & KM_NOSLEEP) - return GFP_ATOMIC; - /* If we're in a transaction, FS activity is not ok */ - else if ((current->flags & PF_FSTRANS) || (flags & KM_NOFS)) - return GFP_NOFS; - else - return GFP_KERNEL; -} - -#define MAX_SHAKE 8 - -static kmem_shake_func_t shake_list[MAX_SHAKE]; -static DECLARE_MUTEX(shake_sem); - -void kmem_shake_register(kmem_shake_func_t sfunc) -{ - int i; - - down(&shake_sem); - for (i = 0; i < MAX_SHAKE; i++) { - if (shake_list[i] == NULL) { - shake_list[i] = sfunc; - break; - } - } - if (i == MAX_SHAKE) - BUG(); - up(&shake_sem); -} - -void kmem_shake_deregister(kmem_shake_func_t sfunc) -{ - int i; - - down(&shake_sem); - for (i = 0; i < MAX_SHAKE; i++) { - if (shake_list[i] == sfunc) - break; - } - if (i == MAX_SHAKE) - BUG(); - for (; i < MAX_SHAKE - 1; i++) { - shake_list[i] = shake_list[i+1]; - } - shake_list[i] = NULL; - up(&shake_sem); -} - -static __inline__ void kmem_shake(void) -{ - int i; - - down(&shake_sem); - for (i = 0; i < MAX_SHAKE && shake_list[i]; i++) - (*shake_list[i])(); - up(&shake_sem); - delay(10); -} - -void * -kmem_alloc(size_t size, int flags) -{ - int shrink = DEF_PRIORITY; /* # times to try to shrink cache */ - void *rval; - -repeat: - if (MAX_SLAB_SIZE < size) { - /* Avoid doing filesystem sensitive stuff to get this */ - rval = __vmalloc(size, flag_convert(flags), PAGE_KERNEL); - } else { - rval = kmalloc(size, flag_convert(flags)); - } - - if (rval || (flags & KM_NOSLEEP)) - return rval; - - /* - * KM_SLEEP callers don't expect a failure - */ - if (shrink) { - kmem_shake(); - - shrink--; - goto repeat; - } - - rval = __vmalloc(size, flag_convert(flags), PAGE_KERNEL); - if (!rval && (flags & KM_SLEEP)) - panic("kmem_alloc: NULL memory on KM_SLEEP request!"); - - return rval; -} - -void * -kmem_zalloc(size_t size, int flags) -{ - void *ptr; - - ptr = kmem_alloc(size, flags); - - if (ptr) - memset((char *)ptr, 0, (int)size); - - return (ptr); -} - -void -kmem_free(void *ptr, size_t size) -{ - if (((unsigned long)ptr < VMALLOC_START) || - ((unsigned long)ptr >= VMALLOC_END)) { - kfree(ptr); - } else { - vfree(ptr); - } -} - -void * -kmem_realloc(void *ptr, size_t newsize, size_t oldsize, int flags) -{ - void *new; - - new = kmem_alloc(newsize, flags); - if (ptr) { - if (new) - memcpy(new, ptr, - ((oldsize < newsize) ? oldsize : newsize)); - kmem_free(ptr, oldsize); - } - - return new; -} - -kmem_zone_t * -kmem_zone_init(int size, char *zone_name) -{ - return kmem_cache_create(zone_name, size, 0, 0, NULL, NULL); -} - -void * -kmem_zone_alloc(kmem_zone_t *zone, int flags) -{ - int shrink = DEF_PRIORITY; /* # times to try to shrink cache */ - void *ptr = NULL; - -repeat: - ptr = kmem_cache_alloc(zone, flag_convert(flags)); - - if (ptr || (flags & KM_NOSLEEP)) - return ptr; - - /* - * KM_SLEEP callers don't expect a failure - */ - if (shrink) { - kmem_shake(); - - shrink--; - goto repeat; - } - - if (flags & KM_SLEEP) - panic("kmem_zone_alloc: NULL memory on KM_SLEEP request!"); - - return NULL; -} - -void * -kmem_zone_zalloc(kmem_zone_t *zone, int flags) -{ - int shrink = DEF_PRIORITY; /* # times to try to shrink cache */ - void *ptr = NULL; - -repeat: - ptr = kmem_cache_alloc(zone, flag_convert(flags)); - - if (ptr) { - memset(ptr, 0, kmem_cache_size(zone)); - return ptr; - } - - if (flags & KM_NOSLEEP) - return ptr; - - /* - * KM_SLEEP callers don't expect a failure - */ - if (shrink) { - kmem_shake(); - - shrink--; - goto repeat; - } - - if (flags & KM_SLEEP) - panic("kmem_zone_zalloc: NULL memory on KM_SLEEP request!"); - - return NULL; -} - -void -kmem_zone_free(kmem_zone_t *zone, void *ptr) -{ - kmem_cache_free(zone, ptr); -} diff -Nru a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c --- a/fs/xfs/xfs_acl.c Fri Jun 27 14:19:55 2003 +++ b/fs/xfs/xfs_acl.c Fri Jun 27 14:19:55 2003 @@ -226,19 +226,23 @@ int kind) { int error; - xfs_acl_t *xfs_acl; + xfs_acl_t *xfs_acl = NULL; posix_acl_xattr_header *ext_acl = acl; + int flags = 0; VN_HOLD(vp); if ((error = _MAC_VACCESS(vp, NULL, VREAD))) goto out; - if (!(_ACL_ALLOC(xfs_acl))) { - error = ENOMEM; - goto out; - } + if(size) { + if (!(_ACL_ALLOC(xfs_acl))) { + error = ENOMEM; + goto out; + } + memset(xfs_acl, 0, sizeof(xfs_acl_t)); + } else + flags = ATTR_KERNOVAL; - memset(xfs_acl, 0, sizeof(xfs_acl_t)); - xfs_acl_get_attr(vp, xfs_acl, kind, size? 0 : ATTR_KERNOVAL, &error); + xfs_acl_get_attr(vp, xfs_acl, kind, flags, &error); if (error) goto out; @@ -262,7 +266,8 @@ } out: VN_RELE(vp); - _ACL_FREE(xfs_acl); + if(xfs_acl) + _ACL_FREE(xfs_acl); return -error; } @@ -657,6 +662,7 @@ { int len = sizeof(xfs_acl_t); + ASSERT((flags & ATTR_KERNOVAL) ? (aclp == NULL) : 1); flags |= ATTR_ROOT; VOP_ATTR_GET(vp, kind == _ACL_TYPE_ACCESS ? SGI_ACL_FILE : SGI_ACL_DEFAULT, diff -Nru a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c --- a/fs/xfs/xfs_attr_leaf.c Fri Jun 27 14:19:56 2003 +++ b/fs/xfs/xfs_attr_leaf.c Fri Jun 27 14:19:56 2003 @@ -486,8 +486,7 @@ i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) { if (unlikely( ((char *)sfe < (char *)sf) || - ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)) || - (sfe->namelen >= MAXNAMELEN))) { + ((char *)sfe >= ((char *)sf + dp->i_afp->if_bytes)))) { XFS_CORRUPTION_ERROR("xfs_attr_shortform_list", XFS_ERRLEVEL_LOW, context->dp->i_mount, sfe); diff -Nru a/fs/xfs/xfs_cap.c b/fs/xfs/xfs_cap.c --- a/fs/xfs/xfs_cap.c Fri Jun 27 14:19:55 2003 +++ b/fs/xfs/xfs_cap.c Fri Jun 27 14:19:55 2003 @@ -115,15 +115,17 @@ int flags = ATTR_ROOT; xfs_cap_set_t xfs_cap = { 0 }; posix_cap_xattr *xattr_cap = cap; + char *data = (char *)&xfs_cap; VN_HOLD(vp); if ((error = _MAC_VACCESS(vp, NULL, VREAD))) goto out; - if (!size) + if (!size) { flags |= ATTR_KERNOVAL; - VOP_ATTR_GET(vp, SGI_CAP_LINUX, (char *)&xfs_cap, - &len, flags, sys_cred, error); + data = NULL; + } + VOP_ATTR_GET(vp, SGI_CAP_LINUX, data, &len, flags, sys_cred, error); if (error) goto out; ASSERT(len == sizeof(xfs_cap_set_t)); diff -Nru a/fs/xfs/xfs_dir_leaf.c b/fs/xfs/xfs_dir_leaf.c --- a/fs/xfs/xfs_dir_leaf.c Fri Jun 27 14:20:03 2003 +++ b/fs/xfs/xfs_dir_leaf.c Fri Jun 27 14:20:03 2003 @@ -483,8 +483,7 @@ if (unlikely( ((char *)sfe < (char *)sf) || - ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)) || - (sfe->namelen >= MAXNAMELEN))) { + ((char *)sfe >= ((char *)sf + dp->i_df.if_bytes)))) { xfs_dir_trace_g_du("sf: corrupted", dp, uio); XFS_CORRUPTION_ERROR("xfs_dir_shortform_getdents", XFS_ERRLEVEL_LOW, mp, sfe); @@ -2001,8 +2000,7 @@ if (unlikely( ((char *)namest < (char *)leaf) || - ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)) || - (entry->namelen >= MAXNAMELEN))) { + ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(1)", XFS_ERRLEVEL_LOW, mp, leaf); xfs_dir_trace_g_du("leaf: corrupted", dp, uio); @@ -2065,8 +2063,7 @@ if (unlikely( ((char *)namest < (char *)leaf) || - ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)) || - (entry->namelen >= MAXNAMELEN))) { + ((char *)namest >= (char *)leaf + XFS_LBSIZE(mp)))) { XFS_CORRUPTION_ERROR("xfs_dir_leaf_getdents_int(2)", XFS_ERRLEVEL_LOW, mp, leaf); xfs_dir_trace_g_du("leaf: corrupted", dp, uio); diff -Nru a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c --- a/fs/xfs/xfs_ialloc.c Fri Jun 27 14:19:57 2003 +++ b/fs/xfs/xfs_ialloc.c Fri Jun 27 14:19:57 2003 @@ -151,7 +151,6 @@ int ninodes; /* num inodes per buf */ xfs_agino_t thisino; /* current inode number, for loop */ int version; /* inode version number to use */ - static xfs_timestamp_t ztime; /* zero xfs timestamp */ int isaligned; /* inode allocation at stripe unit */ /* boundary */ xfs_dinode_core_t dic; /* a dinode_core to copy to new */ @@ -265,6 +264,11 @@ version = XFS_DINODE_VERSION_2; else version = XFS_DINODE_VERSION_1; + + memset(&dic, 0, sizeof(xfs_dinode_core_t)); + INT_SET(dic.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC); + INT_SET(dic.di_version, ARCH_CONVERT, version); + for (j = 0; j < nbufs; j++) { /* * Get the block. @@ -279,36 +283,6 @@ /* * Loop over the inodes in this buffer. */ - INT_SET(dic.di_magic, ARCH_CONVERT, XFS_DINODE_MAGIC); - INT_ZERO(dic.di_mode, ARCH_CONVERT); - INT_SET(dic.di_version, ARCH_CONVERT, version); - INT_ZERO(dic.di_format, ARCH_CONVERT); - INT_ZERO(dic.di_onlink, ARCH_CONVERT); - INT_ZERO(dic.di_uid, ARCH_CONVERT); - INT_ZERO(dic.di_gid, ARCH_CONVERT); - INT_ZERO(dic.di_nlink, ARCH_CONVERT); - INT_ZERO(dic.di_projid, ARCH_CONVERT); - memset(&(dic.di_pad[0]), 0, sizeof(dic.di_pad)); - INT_SET(dic.di_atime.t_sec, ARCH_CONVERT, ztime.t_sec); - INT_SET(dic.di_atime.t_nsec, ARCH_CONVERT, ztime.t_nsec); - - INT_SET(dic.di_mtime.t_sec, ARCH_CONVERT, ztime.t_sec); - INT_SET(dic.di_mtime.t_nsec, ARCH_CONVERT, ztime.t_nsec); - - INT_SET(dic.di_ctime.t_sec, ARCH_CONVERT, ztime.t_sec); - INT_SET(dic.di_ctime.t_nsec, ARCH_CONVERT, ztime.t_nsec); - - INT_ZERO(dic.di_size, ARCH_CONVERT); - INT_ZERO(dic.di_nblocks, ARCH_CONVERT); - INT_ZERO(dic.di_extsize, ARCH_CONVERT); - INT_ZERO(dic.di_nextents, ARCH_CONVERT); - INT_ZERO(dic.di_anextents, ARCH_CONVERT); - INT_ZERO(dic.di_forkoff, ARCH_CONVERT); - INT_ZERO(dic.di_aformat, ARCH_CONVERT); - INT_ZERO(dic.di_dmevmask, ARCH_CONVERT); - INT_ZERO(dic.di_dmstate, ARCH_CONVERT); - INT_ZERO(dic.di_flags, ARCH_CONVERT); - INT_ZERO(dic.di_gen, ARCH_CONVERT); for (i = 0; i < ninodes; i++) { free = XFS_MAKE_IPTR(args.mp, fbuf, i); diff -Nru a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c --- a/fs/xfs/xfs_iget.c Fri Jun 27 14:20:05 2003 +++ b/fs/xfs/xfs_iget.c Fri Jun 27 14:20:05 2003 @@ -214,7 +214,13 @@ XFS_STATS_INC(xfsstats.xs_ig_found); + ip->i_flags &= ~XFS_IRECLAIMABLE; read_unlock(&ih->ih_lock); + + XFS_MOUNT_ILOCK(mp); + list_del_init(&ip->i_reclaim); + XFS_MOUNT_IUNLOCK(mp); + goto finish_inode; } else if (vp != inode_vp) { @@ -252,10 +258,6 @@ if (newnode) { xfs_iocore_inode_reinit(ip); } - - XFS_MOUNT_ILOCK(mp); - list_del_init(&ip->i_reclaim); - XFS_MOUNT_IUNLOCK(mp); vn_trace_exit(vp, "xfs_iget.found", (inst_t *)__return_address); diff -Nru a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c --- a/fs/xfs/xfs_inode.c Fri Jun 27 14:20:05 2003 +++ b/fs/xfs/xfs_inode.c Fri Jun 27 14:20:05 2003 @@ -96,11 +96,12 @@ xfs_exntfmt_t fmt) { xfs_bmbt_irec_t irec; - int i; xfs_bmbt_rec_t rec; + int i; for (i = 0; i < nrecs; i++) { - memcpy(&rec, ep, sizeof(rec)); + rec.l0 = get_unaligned((__uint64_t*)&ep->l0); + rec.l1 = get_unaligned((__uint64_t*)&ep->l1); if (disk) xfs_bmbt_disk_get_all(&rec, &irec); else @@ -411,7 +412,7 @@ mp->m_dev, (unsigned long long)imap.im_blkno, i, INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); #endif - XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_LOW, + XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, mp, dip); xfs_trans_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); @@ -656,9 +657,7 @@ int nex; int real_size; int size; -#if ARCH_CONVERT != ARCH_NOCONVERT int i; -#endif ifp = XFS_IFORK_PTR(ip, whichfork); nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_CONVERT); @@ -691,21 +690,16 @@ ifp->if_bytes = size; ifp->if_real_bytes = real_size; if (size) { - xfs_validate_extents( - (xfs_bmbt_rec_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT), - nex, 1, XFS_EXTFMT_INODE(ip)); - dp = (xfs_bmbt_rec_t *)XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT); + dp = (xfs_bmbt_rec_t *) + XFS_DFORK_PTR_ARCH(dip, whichfork, ARCH_CONVERT); + xfs_validate_extents(dp, nex, 1, XFS_EXTFMT_INODE(ip)); ep = ifp->if_u1.if_extents; -#if ARCH_CONVERT != ARCH_NOCONVERT for (i = 0; i < nex; i++, ep++, dp++) { - ep->l0 = INT_GET(get_unaligned((u64*)&dp->l0), + ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0), ARCH_CONVERT); - ep->l1 = INT_GET(get_unaligned((u64*)&dp->l1), + ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), ARCH_CONVERT); } -#else - memcpy(ep, dp, size); -#endif xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex, whichfork); if (whichfork != XFS_DATA_FORK || @@ -2635,7 +2629,8 @@ if (vp) { struct inode *inode = LINVFS_GET_IP(vp); - mark_inode_dirty_sync(inode); + if (!(inode->i_state & I_NEW)) + mark_inode_dirty_sync(inode); } wake_up(&ip->i_ipin_wait); @@ -2733,15 +2728,11 @@ continue; } -#if ARCH_CONVERT != ARCH_NOCONVERT /* Translate to on disk format */ put_unaligned(INT_GET(ep->l0, ARCH_CONVERT), - (u64*)&dest_ep->l0); + (__uint64_t*)&dest_ep->l0); put_unaligned(INT_GET(ep->l1, ARCH_CONVERT), - (u64*)&dest_ep->l1); -#else - *dest_ep = *ep; -#endif + (__uint64_t*)&dest_ep->l1); dest_ep++; ep++; copied++; @@ -3003,9 +2994,7 @@ * see if other inodes can be gathered into this write */ -#ifdef DEBUG - ip->i_chash->chl_buf = bp; /* inode clustering debug */ -#endif + ip->i_chash->chl_buf = bp; ch = XFS_CHASH(mp, ip->i_blkno); s = mutex_spinlock(&ch->ch_lock); diff -Nru a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h --- a/fs/xfs/xfs_inode.h Fri Jun 27 14:19:59 2003 +++ b/fs/xfs/xfs_inode.h Fri Jun 27 14:19:59 2003 @@ -192,9 +192,7 @@ struct xfs_inode *chl_ip; xfs_daddr_t chl_blkno; /* starting block number of * the cluster */ -#ifdef DEBUG - struct xfs_buf *chl_buf; /* debug: the inode buffer */ -#endif + struct xfs_buf *chl_buf; /* the inode buffer */ } xfs_chashlist_t; typedef struct xfs_chash { @@ -364,6 +362,7 @@ #define XFS_IUIOSZ 0x0002 /* inode i/o sizes have been explicitly set */ #define XFS_IQUIESCE 0x0004 /* we have started quiescing for this inode */ #define XFS_IRECLAIM 0x0008 /* we have started reclaiming this inode */ +#define XFS_IRECLAIMABLE 0x0010 /* inode can be reclaimed */ /* * Flags for inode locking. diff -Nru a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c --- a/fs/xfs/xfs_inode_item.c Fri Jun 27 14:19:59 2003 +++ b/fs/xfs/xfs_inode_item.c Fri Jun 27 14:19:59 2003 @@ -879,7 +879,7 @@ * Write out the inode. The completion routine ('iflush_done') will * pull it from the AIL, mark it clean, unlock the flush lock. */ - (void) xfs_iflush(ip, XFS_IFLUSH_DELWRI); + (void) xfs_iflush(ip, XFS_IFLUSH_ASYNC); xfs_iunlock(ip, XFS_ILOCK_SHARED); return; diff -Nru a/fs/xfs/xfs_iocore.c b/fs/xfs/xfs_iocore.c --- a/fs/xfs/xfs_iocore.c Fri Jun 27 14:20:00 2003 +++ b/fs/xfs/xfs_iocore.c Fri Jun 27 14:20:00 2003 @@ -77,8 +77,7 @@ struct xfs_mount_args *mntargs, int flags) { - return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp), - vfsp->vfs_super->s_bdev->bd_dev, flags); + return xfs_mountfs(vfsp, XFS_VFSTOM(vfsp), flags); } xfs_ioops_t xfs_iocore_xfs = { diff -Nru a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c --- a/fs/xfs/xfs_log.c Fri Jun 27 14:20:06 2003 +++ b/fs/xfs/xfs_log.c Fri Jun 27 14:20:06 2003 @@ -794,8 +794,9 @@ do { ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); - if (free_bytes < tic->t_unit_res) + if (free_bytes < tic->t_unit_res && tail_lsn != 1) break; + tail_lsn = 0; free_bytes -= tic->t_unit_res; sv_signal(&tic->t_sema); tic = tic->t_next; @@ -814,8 +815,9 @@ need_bytes = tic->t_unit_res*tic->t_cnt; else need_bytes = tic->t_unit_res; - if (free_bytes < need_bytes) + if (free_bytes < need_bytes && tail_lsn != 1) break; + tail_lsn = 0; free_bytes -= need_bytes; sv_signal(&tic->t_sema); tic = tic->t_next; @@ -836,8 +838,10 @@ SPLDECL(s); int needed = 0, gen; xlog_t *log = mp->m_log; + vfs_t *vfsp = XFS_MTOVFS(mp); - if (mp->m_frozen || XFS_FORCED_SHUTDOWN(mp)) + if (mp->m_frozen || XFS_FORCED_SHUTDOWN(mp) || + (vfsp->vfs_flag & VFS_RDONLY)) return 0; s = LOG_LOCK(log); @@ -1205,7 +1209,10 @@ if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) { log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); - ASSERT(XFS_SB_VERSION_HASLOGV2(&mp->m_sb)); + /* for larger sector sizes, must have v2 or external log */ + ASSERT(log->l_sectbb_log == 0 || + log->l_logBBstart == 0 || + XFS_SB_VERSION_HASLOGV2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; diff -Nru a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c --- a/fs/xfs/xfs_log_recover.c Fri Jun 27 14:19:57 2003 +++ b/fs/xfs/xfs_log_recover.c Fri Jun 27 14:19:57 2003 @@ -3413,6 +3413,45 @@ xlog_unpack_data_checksum(rhead, dp, log); } +STATIC int +xlog_valid_rec_header( + xlog_t *log, + xlog_rec_header_t *rhead, + xfs_daddr_t blkno) +{ + int bblks; + + if (unlikely( + (INT_GET(rhead->h_magicno, ARCH_CONVERT) != + XLOG_HEADER_MAGIC_NUM))) { + XFS_ERROR_REPORT("xlog_valid_rec_header(1)", + XFS_ERRLEVEL_LOW, log->l_mp); + return XFS_ERROR(EFSCORRUPTED); + } + if (unlikely( + (INT_ISZERO(rhead->h_version, ARCH_CONVERT) || + (INT_GET(rhead->h_version, ARCH_CONVERT) & + (~XLOG_VERSION_OKBITS)) != 0))) { + xlog_warn("XFS: %s: unrecognised log version (%d).", + __FUNCTION__, INT_GET(rhead->h_version, ARCH_CONVERT)); + return XFS_ERROR(EIO); + } + + /* LR body must have data or it wouldn't have been written */ + bblks = INT_GET(rhead->h_len, ARCH_CONVERT); + if (unlikely( bblks <= 0 || bblks > INT_MAX )) { + XFS_ERROR_REPORT("xlog_valid_rec_header(2)", + XFS_ERRLEVEL_LOW, log->l_mp); + return XFS_ERROR(EFSCORRUPTED); + } + if (unlikely( blkno > log->l_logBBsize || blkno > INT_MAX )) { + XFS_ERROR_REPORT("xlog_valid_rec_header(3)", + XFS_ERRLEVEL_LOW, log->l_mp); + return XFS_ERROR(EFSCORRUPTED); + } + return 0; +} + /* * Read the log from tail to head and process the log records found. * Handle the two cases where the tail and head are in the same cycle @@ -3437,6 +3476,8 @@ int hblks, split_hblks, wrapped_hblks; xlog_recover_t *rhash[XLOG_RHASH_SIZE]; + ASSERT(head_blk != tail_blk); + /* * Read the header of the tail block and get the iclog buffer size from * h_size. Use this to tell how many sectors make up the log header. @@ -3454,17 +3495,10 @@ goto bread_err1; offset = xlog_align(log, tail_blk, 1, hbp); rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - if ((INT_GET(rhead->h_version, ARCH_CONVERT) & - (~XLOG_VERSION_OKBITS)) != 0) { - xlog_warn( - "XFS: xlog_do_recovery_pass: unrecognised log version number."); - error = XFS_ERROR(EIO); + error = xlog_valid_rec_header(log, rhead, tail_blk); + if (error) goto bread_err1; - } h_size = INT_GET(rhead->h_size, ARCH_CONVERT); - if ((INT_GET(rhead->h_version, ARCH_CONVERT) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { @@ -3498,47 +3532,21 @@ goto bread_err2; offset = xlog_align(log, blk_no, hblks, hbp); rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= - INT_MAX)); - /* blocks in data section */ - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - - if (unlikely( - (INT_GET(rhead->h_magicno, ARCH_CONVERT) != - XLOG_HEADER_MAGIC_NUM) || - (BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > - INT_MAX)) || - (bblks <= 0) || - (blk_no > log->l_logBBsize))) { - XFS_ERROR_REPORT("xlog_do_recovery_pass(1)", - XFS_ERRLEVEL_LOW, log->l_mp); - error = EFSCORRUPTED; + error = xlog_valid_rec_header(log, rhead, blk_no); + if (error) goto bread_err2; - } - if ((INT_GET(rhead->h_version, ARCH_CONVERT) & - (~XLOG_VERSION_OKBITS)) != 0) { - xlog_warn( - "XFS: xlog_do_recovery_pass: unrecognised log version number."); - error = XFS_ERROR(EIO); - goto bread_err2; - } /* blocks in data section */ bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - if (bblks > 0) { - if ((error = xlog_bread(log, blk_no + hblks, - bblks, dbp))) - goto bread_err2; - offset = xlog_align(log, blk_no + hblks, - bblks, dbp); - xlog_unpack_data(rhead, offset, log); - if ((error = xlog_recover_process_data(log, + error = xlog_bread(log, blk_no + hblks, bblks, dbp); + if (error) + goto bread_err2; + offset = xlog_align(log, blk_no + hblks, bblks, dbp); + xlog_unpack_data(rhead, offset, log); + if ((error = xlog_recover_process_data(log, rhash, rhead, offset, pass))) - goto bread_err2; - } - blk_no += (bblks+hblks); + goto bread_err2; + blk_no += bblks + hblks; } } else { /* @@ -3551,17 +3559,17 @@ /* * Check for header wrapping around physical end-of-log */ + offset = NULL; + split_hblks = 0; wrapped_hblks = 0; - if (blk_no+hblks <= log->l_logBBsize) { + if (blk_no + hblks <= log->l_logBBsize) { /* Read header in one read */ - if ((error = xlog_bread(log, blk_no, - hblks, hbp))) + error = xlog_bread(log, blk_no, hblks, hbp); + if (error) goto bread_err2; offset = xlog_align(log, blk_no, hblks, hbp); } else { /* This LR is split across physical log end */ - offset = NULL; - split_hblks = 0; if (blk_no != log->l_logBBsize) { /* some data before physical log end */ ASSERT(blk_no <= INT_MAX); @@ -3590,8 +3598,8 @@ bufaddr + BBTOB(split_hblks), BBTOB(hblks - split_hblks)); wrapped_hblks = hblks - split_hblks; - if ((error = xlog_bread(log, 0, - wrapped_hblks, hbp))) + error = xlog_bread(log, 0, wrapped_hblks, hbp); + if (error) goto bread_err2; XFS_BUF_SET_PTR(hbp, bufaddr, hblks); if (!offset) @@ -3599,33 +3607,18 @@ wrapped_hblks, hbp); } rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= - INT_MAX)); - bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - - /* LR body must have data or it wouldn't have been - * written */ - ASSERT(bblks > 0); - blk_no += hblks; /* successfully read header */ - - if (unlikely( - (INT_GET(rhead->h_magicno, ARCH_CONVERT) != - XLOG_HEADER_MAGIC_NUM) || - (BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) > - INT_MAX)) || - (bblks <= 0))) { - XFS_ERROR_REPORT("xlog_do_recovery_pass(2)", - XFS_ERRLEVEL_LOW, log->l_mp); - error = EFSCORRUPTED; + error = xlog_valid_rec_header(log, rhead, + split_hblks ? blk_no : 0); + if (error) goto bread_err2; - } + + bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); + blk_no += hblks; /* Read in data for log record */ - if (blk_no+bblks <= log->l_logBBsize) { - if ((error = xlog_bread(log, blk_no, - bblks, dbp))) + if (blk_no + bblks <= log->l_logBBsize) { + error = xlog_bread(log, blk_no, bblks, dbp); + if (error) goto bread_err2; offset = xlog_align(log, blk_no, bblks, dbp); } else { @@ -3674,7 +3667,7 @@ } xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + rhead, offset, pass))) goto bread_err2; blk_no += bblks; } @@ -3688,20 +3681,18 @@ goto bread_err2; offset = xlog_align(log, blk_no, hblks, hbp); rhead = (xlog_rec_header_t *)offset; - ASSERT(INT_GET(rhead->h_magicno, ARCH_CONVERT) == - XLOG_HEADER_MAGIC_NUM); - ASSERT(BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT) <= - INT_MAX)); + error = xlog_valid_rec_header(log, rhead, blk_no); + if (error) + goto bread_err2; bblks = (int)BTOBB(INT_GET(rhead->h_len, ARCH_CONVERT)); - ASSERT(bblks > 0); if ((error = xlog_bread(log, blk_no+hblks, bblks, dbp))) goto bread_err2; offset = xlog_align(log, blk_no+hblks, bblks, dbp); xlog_unpack_data(rhead, offset, log); if ((error = xlog_recover_process_data(log, rhash, - rhead, offset, pass))) + rhead, offset, pass))) goto bread_err2; - blk_no += (bblks+hblks); + blk_no += bblks + hblks; } } @@ -3732,9 +3723,8 @@ xfs_daddr_t tail_blk) { int error; -#ifdef DEBUG - int i; -#endif + + ASSERT(head_blk != tail_blk); /* * First do a pass to find all of the cancelled buf log items. @@ -3758,11 +3748,15 @@ */ error = xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS2); -#ifdef DEBUG - for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) { - ASSERT(log->l_buf_cancel_table[i] == NULL); +#ifdef DEBUG + { + int i; + + for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) + ASSERT(log->l_buf_cancel_table[i] == NULL); } #endif /* DEBUG */ + kmem_free(log->l_buf_cancel_table, XLOG_BC_TABLE_SIZE * sizeof(xfs_buf_cancel_t*)); log->l_buf_cancel_table = NULL; diff -Nru a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c --- a/fs/xfs/xfs_mount.c Fri Jun 27 14:19:55 2003 +++ b/fs/xfs/xfs_mount.c Fri Jun 27 14:19:55 2003 @@ -620,7 +620,6 @@ xfs_mountfs( vfs_t *vfsp, xfs_mount_t *mp, - dev_t dev, int mfsi_flags) { xfs_buf_t *bp; @@ -633,11 +632,10 @@ __uint64_t ret64; __int64_t update_flags; uint quotamount, quotaflags; - int agno, noio; + int agno; int uuid_mounted = 0; int error = 0; - noio = dev == 0 && mp->m_sb_bp != NULL; if (mp->m_sb_bp == NULL) { if ((error = xfs_readsb(mp))) { return (error); @@ -826,22 +824,20 @@ error = XFS_ERROR(E2BIG); goto error1; } - if (!noio) { - error = xfs_read_buf(mp, mp->m_ddev_targp, - d - XFS_FSS_TO_BB(mp, 1), - XFS_FSS_TO_BB(mp, 1), 0, &bp); - if (!error) { - xfs_buf_relse(bp); - } else { - cmn_err(CE_WARN, "XFS: size check 2 failed"); - if (error == ENOSPC) { - error = XFS_ERROR(E2BIG); - } - goto error1; + error = xfs_read_buf(mp, mp->m_ddev_targp, + d - XFS_FSS_TO_BB(mp, 1), + XFS_FSS_TO_BB(mp, 1), 0, &bp); + if (!error) { + xfs_buf_relse(bp); + } else { + cmn_err(CE_WARN, "XFS: size check 2 failed"); + if (error == ENOSPC) { + error = XFS_ERROR(E2BIG); } + goto error1; } - if (!noio && ((mfsi_flags & XFS_MFSI_CLIENT) == 0) && + if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) && mp->m_logdev_targp != mp->m_ddev_targp) { d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { @@ -918,10 +914,6 @@ * Initialize the precomputed transaction reservations values. */ xfs_trans_init(mp); - if (noio) { - ASSERT((mfsi_flags & XFS_MFSI_CLIENT) == 0); - return 0; - } /* * Allocate and initialize the inode hash table for this diff -Nru a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h --- a/fs/xfs/xfs_mount.h Fri Jun 27 14:19:30 2003 +++ b/fs/xfs/xfs_mount.h Fri Jun 27 14:19:30 2003 @@ -539,7 +539,7 @@ extern xfs_mount_t *xfs_mount_init(void); extern void xfs_mod_sb(xfs_trans_t *, __int64_t); extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); -extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, dev_t, int); +extern int xfs_mountfs(struct vfs *, xfs_mount_t *mp, int); extern int xfs_unmountfs(xfs_mount_t *, struct cred *); extern void xfs_unmountfs_close(xfs_mount_t *, struct cred *); diff -Nru a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h --- a/fs/xfs/xfs_sb.h Fri Jun 27 14:19:55 2003 +++ b/fs/xfs/xfs_sb.h Fri Jun 27 14:19:55 2003 @@ -81,7 +81,7 @@ XFS_SB_VERSION_OKREALFBITS | \ XFS_SB_VERSION_OKSASHFBITS) #define XFS_SB_VERSION_MKFS(ia,dia,extflag,dirv2,na,sflag) \ - (((ia) || (dia) || (extflag) || (dirv2) || (na)) ? \ + (((ia) || (dia) || (extflag) || (dirv2) || (na) || (sflag)) ? \ (XFS_SB_VERSION_4 | \ ((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \ ((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \ diff -Nru a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c --- a/fs/xfs/xfs_trans.c Fri Jun 27 14:19:56 2003 +++ b/fs/xfs/xfs_trans.c Fri Jun 27 14:19:56 2003 @@ -850,15 +850,6 @@ * running in simulation mode (the log is explicitly turned * off). */ -#if defined(XLOG_NOLOG) || defined(DEBUG) - if (xlog_debug) { - tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; - tp->t_logcb.cb_arg = tp; - error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); - } else { - xfs_trans_committed(tp, 0); - } -#else tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; tp->t_logcb.cb_arg = tp; @@ -869,7 +860,6 @@ * waiting for an item to unlock. */ error = xfs_log_notify(mp, commit_iclog, &(tp->t_logcb)); -#endif /* * Once all the items of the transaction have been copied diff -Nru a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c --- a/fs/xfs/xfs_vfsops.c Fri Jun 27 14:19:54 2003 +++ b/fs/xfs/xfs_vfsops.c Fri Jun 27 14:19:54 2003 @@ -599,6 +599,8 @@ return XFS_ERROR(error); } +#define REMOUNT_READONLY_FLAGS (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) + STATIC int xfs_mntupdate( bhv_desc_t *bdp, @@ -623,7 +625,7 @@ xfs_finish_reclaim_all(mp, 0); do { - VFS_SYNC(vfsp, SYNC_ATTR|SYNC_WAIT, NULL, error); + VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error); pagebuf_delwri_flush(mp->m_ddev_targp, PBDF_WAIT, &pincount); } while (pincount); @@ -1483,7 +1485,7 @@ /* * Now check to see if the log needs a "dummy" transaction. */ - if (xfs_log_need_covered(mp)) { + if (!(flags & SYNC_REMOUNT) && xfs_log_need_covered(mp)) { xfs_trans_t *tp; xfs_inode_t *ip; @@ -1619,7 +1621,7 @@ if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_LOGBUFS); - return -EINVAL; + return EINVAL; } args->logbufs = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { @@ -1628,7 +1630,7 @@ if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_LOGBSIZE); - return -EINVAL; + return EINVAL; } last = strlen(value) - 1; if (value[last] == 'K' || value[last] == 'k') { @@ -1642,28 +1644,28 @@ if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_LOGDEV); - return -EINVAL; + return EINVAL; } strncpy(args->logname, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_MTPT)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_MTPT); - return -EINVAL; + return EINVAL; } strncpy(args->mtpt, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_RTDEV)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_RTDEV); - return -EINVAL; + return EINVAL; } strncpy(args->rtname, value, MAXNAMELEN); } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_BIOSIZE); - return -EINVAL; + return EINVAL; } iosize = simple_strtoul(value, &eov, 10); args->flags |= XFSMNT_IOSIZE; @@ -1679,7 +1681,7 @@ #ifndef XFS_BIG_FILESYSTEMS printk("XFS: %s option not allowed on this system\n", MNTOPT_INO64); - return -EINVAL; + return EINVAL; #endif } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { args->flags |= XFSMNT_NOALIGN; @@ -1687,14 +1689,14 @@ if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_SUNIT); - return -EINVAL; + return EINVAL; } dsunit = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { if (!value || !*value) { printk("XFS: %s option requires an argument\n", MNTOPT_SWIDTH); - return -EINVAL; + return EINVAL; } dswidth = simple_strtoul(value, &eov, 10); } else if (!strcmp(this_char, MNTOPT_NOUUID)) { @@ -1708,33 +1710,33 @@ printk("XFS: irixsgid is now a sysctl(2) variable, option is deprecated.\n"); } else { printk("XFS: unknown mount option [%s].\n", this_char); - return -EINVAL; + return EINVAL; } } if (args->flags & XFSMNT_NORECOVERY) { if ((vfsp->vfs_flag & VFS_RDONLY) == 0) { printk("XFS: no-recovery mounts must be read-only.\n"); - return -EINVAL; + return EINVAL; } } if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) { printk( "XFS: sunit and swidth options incompatible with the noalign option\n"); - return -EINVAL; + return EINVAL; } if ((dsunit && !dswidth) || (!dsunit && dswidth)) { printk("XFS: sunit and swidth must be specified together\n"); - return -EINVAL; + return EINVAL; } if (dsunit && (dswidth % dsunit != 0)) { printk( "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)\n", dswidth, dsunit); - return -EINVAL; + return EINVAL; } if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { diff -Nru a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c --- a/fs/xfs/xfs_vnodeops.c Fri Jun 27 14:20:06 2003 +++ b/fs/xfs/xfs_vnodeops.c Fri Jun 27 14:20:06 2003 @@ -578,7 +578,8 @@ /* * Can't change extent size if any extents are allocated. */ - if (ip->i_d.di_nextents && (mask & XFS_AT_EXTSIZE) && + if ((ip->i_d.di_nextents || ip->i_delayed_blks) && + (mask & XFS_AT_EXTSIZE) && ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != vap->va_extsize) ) { code = XFS_ERROR(EINVAL); /* EFBIG? */ @@ -3930,6 +3931,7 @@ */ if (!ip->i_update_core && (ip->i_itemp == NULL)) { xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_iflock(ip); return xfs_finish_reclaim(ip, 1, XFS_IFLUSH_DELWRI_ELSE_SYNC); } else { xfs_mount_t *mp = ip->i_mount; @@ -3938,7 +3940,7 @@ XFS_MOUNT_ILOCK(mp); vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); - + ip->i_flags |= XFS_IRECLAIMABLE; XFS_MOUNT_IUNLOCK(mp); } return 0; @@ -3953,19 +3955,20 @@ xfs_ihash_t *ih = ip->i_hash; int error; - if (!locked) - xfs_ilock(ip, XFS_ILOCK_EXCL); - /* The hash lock here protects a thread in xfs_iget_core from * racing with us on linking the inode back with a vnode. * Once we have the XFS_IRECLAIM flag set it will not touch * us. */ write_lock(&ih->ih_lock); - if (ip->i_flags & XFS_IRECLAIM || (!locked && XFS_ITOV_NULL(ip))) { + if ((ip->i_flags & XFS_IRECLAIM) || + (!(ip->i_flags & XFS_IRECLAIMABLE) && + (XFS_ITOV_NULL(ip) == NULL))) { write_unlock(&ih->ih_lock); - if (!locked) + if (locked) { + xfs_ifunlock(ip); xfs_iunlock(ip, XFS_ILOCK_EXCL); + } return(1); } ip->i_flags |= XFS_IRECLAIM; @@ -3984,6 +3987,7 @@ */ if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { if (!locked) { + xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_iflock(ip); } @@ -4007,8 +4011,16 @@ ASSERT(ip->i_update_core == 0); ASSERT(ip->i_itemp == NULL || ip->i_itemp->ili_format.ilf_fields == 0); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + } else if (locked) { + /* + * We are not interested in doing an iflush if we're + * in the process of shutting down the filesystem forcibly. + * So, just reclaim the inode. + */ + xfs_ifunlock(ip); + xfs_iunlock(ip, XFS_ILOCK_EXCL); } - xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_ireclaim(ip); return 0; diff -Nru a/fs/xfs/xfsidbg.c b/fs/xfs/xfsidbg.c --- a/fs/xfs/xfsidbg.c Fri Jun 27 14:20:00 2003 +++ b/fs/xfs/xfsidbg.c Fri Jun 27 14:20:00 2003 @@ -4883,13 +4883,8 @@ xfs_inode_t *ip; while (chl != NULL) { -#ifdef DEBUG - kdb_printf("hashlist inode 0x%p blkno %Ld buf 0x%p", - chl->chl_ip, chl->chl_blkno, chl->chl_buf); -#else - kdb_printf("hashlist inode 0x%p blkno %lld", - chl->chl_ip, (long long) chl->chl_blkno); -#endif + kdb_printf("hashlist inode 0x%p blkno %lld buf 0x%p", + chl->chl_ip, (long long) chl->chl_blkno, chl->chl_buf); kdb_printf("\n"); diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h --- a/include/acpi/acpi_drivers.h Fri Jun 27 14:19:59 2003 +++ b/include/acpi/acpi_drivers.h Fri Jun 27 14:19:59 2003 @@ -73,6 +73,10 @@ int acpi_pci_bind (struct acpi_device *device); int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); +/* Arch-defined function to add a bus to the system */ + +struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain, int bus); + #endif /*CONFIG_ACPI_PCI*/ diff -Nru a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h --- a/include/asm-alpha/pci.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-alpha/pci.h Fri Jun 27 14:19:30 2003 @@ -197,7 +197,8 @@ /* Bus number == domain number until we get above 256 busses */ static inline int pci_name_bus(char *name, struct pci_bus *bus) { - int domain = pci_domain_nr(bus) + int domain = pci_domain_nr(bus); + if (domain < 256) { sprintf(name, "%02x", domain); } else { diff -Nru a/include/asm-arm26/processor.h b/include/asm-arm26/processor.h --- a/include/asm-arm26/processor.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-arm26/processor.h Fri Jun 27 14:19:57 2003 @@ -100,10 +100,6 @@ /* Free all resources held by a thread. */ extern void release_thread(struct task_struct *); -/* Copy and release all segment info associated with a VM */ -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) - unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() diff -Nru a/include/asm-h8300/processor.h b/include/asm-h8300/processor.h --- a/include/asm-h8300/processor.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-h8300/processor.h Fri Jun 27 14:19:53 2003 @@ -89,9 +89,6 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -#define copy_segments(tsk, mm) do { } while (0) -#define release_segments(mm) do { } while (0) -#define forget_segments() do { } while (0) #define prepare_to_copy(tsk) do { } while (0) /* diff -Nru a/include/asm-i386/io_apic.h b/include/asm-i386/io_apic.h --- a/include/asm-i386/io_apic.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-i386/io_apic.h Fri Jun 27 14:19:59 2003 @@ -22,27 +22,44 @@ /* * The structure of the IO-APIC: */ -struct IO_APIC_reg_00 { - __u32 __reserved_2 : 14, - LTS : 1, - delivery_type : 1, - __reserved_1 : 8, - ID : 8; -} __attribute__ ((packed)); +union IO_APIC_reg_00 { + u32 raw; + struct { + u32 __reserved_2 : 14, + LTS : 1, + delivery_type : 1, + __reserved_1 : 8, + ID : 8; + } __attribute__ ((packed)) bits; +}; -struct IO_APIC_reg_01 { - __u32 version : 8, - __reserved_2 : 7, - PRQ : 1, - entries : 8, - __reserved_1 : 8; -} __attribute__ ((packed)); +union IO_APIC_reg_01 { + u32 raw; + struct { + u32 version : 8, + __reserved_2 : 7, + PRQ : 1, + entries : 8, + __reserved_1 : 8; + } __attribute__ ((packed)) bits; +}; -struct IO_APIC_reg_02 { - __u32 __reserved_2 : 24, - arbitration : 4, - __reserved_1 : 4; -} __attribute__ ((packed)); +union IO_APIC_reg_02 { + u32 raw; + struct { + u32 __reserved_2 : 24, + arbitration : 4, + __reserved_1 : 4; + } __attribute__ ((packed)) bits; +}; + +union IO_APIC_reg_03 { + u32 raw; + struct { + u32 boot_DT : 1, + __reserved_1 : 31; + } __attribute__ ((packed)) bits; +}; /* * # of IO-APICs and # of IRQ routing registers diff -Nru a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h --- a/include/asm-ia64/agp.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-ia64/agp.h Fri Jun 27 14:19:57 2003 @@ -4,7 +4,7 @@ /* * IA-64 specific AGP definitions. * - * Copyright (C) 2002 Hewlett-Packard Co + * Copyright (C) 2002-2003 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> */ @@ -17,8 +17,5 @@ #define unmap_page_from_agp(page) /* nothing */ #define flush_agp_mappings() /* nothing */ #define flush_agp_cache() mb() - -/* Page-protection value to be used for AGP memory mapped into kernel space. */ -#define PAGE_AGP PAGE_KERNEL #endif /* _ASM_IA64_AGP_H */ diff -Nru a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h --- a/include/asm-ia64/hw_irq.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-ia64/hw_irq.h Fri Jun 27 14:19:56 2003 @@ -2,7 +2,7 @@ #define _ASM_IA64_HW_IRQ_H /* - * Copyright (C) 2001-2002 Hewlett-Packard Co + * Copyright (C) 2001-2003 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> */ @@ -91,10 +91,10 @@ * Default implementations for the irq-descriptor API: */ -extern struct irq_desc _irq_desc[NR_IRQS]; +extern irq_desc_t _irq_desc[NR_IRQS]; #ifndef CONFIG_IA64_GENERIC -static inline struct irq_desc * +static inline irq_desc_t * __ia64_irq_desc (unsigned int irq) { return _irq_desc + irq; @@ -124,8 +124,8 @@ */ /* Return a pointer to the irq descriptor for IRQ. */ -static inline struct irq_desc * -irq_desc (int irq) +static inline irq_desc_t * +irq_descp (int irq) { return platform_irq_desc(irq); } diff -Nru a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h --- a/include/asm-ia64/pci.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-ia64/pci.h Fri Jun 27 14:20:04 2003 @@ -21,7 +21,6 @@ #define PCIBIOS_MIN_MEM 0x10000000 void pcibios_config_init(void); -struct pci_bus * pcibios_scan_root(void *acpi_handle, int segment, int bus); struct pci_dev; diff -Nru a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h --- a/include/asm-ia64/thread_info.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-ia64/thread_info.h Fri Jun 27 14:20:06 2003 @@ -37,7 +37,6 @@ struct restart_block restart_block; }; -#define INIT_THREAD_SIZE /* tell sched.h not to declare the thread_union */ #define THREAD_SIZE KERNEL_STACK_SIZE #define INIT_THREAD_INFO(tsk) \ diff -Nru a/include/asm-ia64/timex.h b/include/asm-ia64/timex.h --- a/include/asm-ia64/timex.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-ia64/timex.h Fri Jun 27 14:20:01 2003 @@ -15,8 +15,15 @@ typedef unsigned long cycles_t; /* - * Something low processor frequency like 100Mhz but - * yet multiple of HZ to avoid truncation in some formulas. + * For performance reasons, we don't want to define CLOCK_TICK_TRATE as + * local_cpu_data->itc_rate. Fortunately, we don't have to, either: according to George + * Anzinger, 1/CLOCK_TICK_RATE is taken as the resolution of the timer clock. The time + * calculation assumes that you will use enough of these so that your tick size <= 1/HZ. + * If the calculation shows that your CLOCK_TICK_RATE can not supply exactly 1/HZ ticks, + * the actual value is calculated and used to update the wall clock each jiffie. Setting + * the CLOCK_TICK_RATE to x*HZ insures that the calculation will find no errors. Hence we + * pick a multiple of HZ which gives us a (totally virtual) CLOCK_TICK_RATE of about + * 100MHz. */ #define CLOCK_TICK_RATE (HZ * 100000UL) diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h --- a/include/asm-ia64/tlb.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-ia64/tlb.h Fri Jun 27 14:19:55 2003 @@ -39,6 +39,7 @@ */ #include <linux/config.h> #include <linux/mm.h> +#include <linux/swap.h> #include <asm/processor.h> #include <asm/tlbflush.h> diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h --- a/include/asm-ia64/topology.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-ia64/topology.h Fri Jun 27 14:19:52 2003 @@ -28,11 +28,6 @@ */ #define node_to_cpumask(node) (node_to_cpu_mask[node]) -#else -#define cpu_to_node(cpu) (0) -#define node_to_cpumask(node) (phys_cpu_present_map) -#endif - /* * Returns the number of the node containing MemBlk 'memblk' */ @@ -64,5 +59,9 @@ #define NODE_BALANCE_RATE 10 void build_cpu_to_node_map(void); + +#endif /* CONFIG_NUMA */ + +#include <asm-generic/topology.h> #endif /* _ASM_IA64_TOPOLOGY_H */ diff -Nru a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h --- a/include/asm-mips/addrspace.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/addrspace.h Fri Jun 27 14:19:52 2003 @@ -4,67 +4,100 @@ * for more details. * * Copyright (C) 1996 by Ralf Baechle - * Copyright (C) 2000 by Maciej W. Rozycki + * Copyright (C) 2000, 2002 Maciej W. Rozycki * - * Defitions for the address spaces of the MIPS CPUs. + * Definitions for the address spaces of the MIPS CPUs. */ -#ifndef __ASM_MIPS_ADDRSPACE_H -#define __ASM_MIPS_ADDRSPACE_H +#ifndef __ASM_ADDRSPACE_H +#define __ASM_ADDRSPACE_H + +/* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ATYPE_ +#define _ATYPE32_ +#define _ATYPE64_ +#else +#define _ATYPE_ __PTRDIFF_TYPE__ +#define _ATYPE32_ int +#define _ATYPE64_ long long +#endif + +/* + * 32-bit MIPS address spaces + */ +#ifdef __ASSEMBLY__ +#define _ACAST32_ +#define _ACAST64_ +#else +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ +#endif /* * Memory segments (32bit kernel mode addresses) */ -#define KUSEG 0x00000000 -#define KSEG0 0x80000000 -#define KSEG1 0xa0000000 -#define KSEG2 0xc0000000 -#define KSEG3 0xe0000000 +#define KUSEG 0x00000000 +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 +#define KSEG2 0xc0000000 +#define KSEG3 0xe0000000 -#define K0BASE KSEG0 +#define K0BASE KSEG0 /* * Returns the kernel segment base of a given address */ -#ifndef __ASSEMBLY__ -#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000) -#else -#define KSEGX(a) ((a) & 0xe0000000) -#endif +#define KSEGX(a) ((_ACAST32_ (a)) & 0xe0000000) /* * Returns the physical address of a KSEG0/KSEG1 address */ -#ifndef __ASSEMBLY__ -#define PHYSADDR(a) (((unsigned long)(a)) & 0x1fffffff) -#else -#define PHYSADDR(a) ((a) & 0x1fffffff) -#endif +#define CPHYSADDR(a) ((_ACAST32_ (a)) & 0x1fffffff) + +#define PHYSADDR(a) CPHYSADDR(a) /* * Map an address to a certain kernel segment */ -#ifndef __ASSEMBLY__ -#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG0)) -#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG1)) -#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG2)) -#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) | KSEG3)) -#else -#define KSEG0ADDR(a) (((a) & 0x1fffffff) | KSEG0) -#define KSEG1ADDR(a) (((a) & 0x1fffffff) | KSEG1) -#define KSEG2ADDR(a) (((a) & 0x1fffffff) | KSEG2) -#define KSEG3ADDR(a) (((a) & 0x1fffffff) | KSEG3) -#endif +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) /* * Memory segments (64bit kernel mode addresses) */ -#define XKUSEG 0x0000000000000000 -#define XKSSEG 0x4000000000000000 -#define XKPHYS 0x8000000000000000 -#define XKSEG 0xc000000000000000 -#define CKSEG0 0xffffffff80000000 -#define CKSEG1 0xffffffffa0000000 -#define CKSSEG 0xffffffffc0000000 -#define CKSEG3 0xffffffffe0000000 +#define XKUSEG 0x0000000000000000 +#define XKSSEG 0x4000000000000000 +#define XKPHYS 0x8000000000000000 +#define XKSEG 0xc000000000000000 +#define CKSEG0 0xffffffff80000000 +#define CKSEG1 0xffffffffa0000000 +#define CKSSEG 0xffffffffc0000000 +#define CKSEG3 0xffffffffe0000000 + +/* + * Cache modes for XKPHYS address conversion macros + */ +#define K_CALG_COH_EXCL1_NOL2 0 +#define K_CALG_COH_SHRL1_NOL2 1 +#define K_CALG_UNCACHED 2 +#define K_CALG_NONCOHERENT 3 +#define K_CALG_COH_EXCL 4 +#define K_CALG_COH_SHAREABLE 5 +#define K_CALG_NOTUSED 6 +#define K_CALG_UNCACHED_ACCEL 7 + +#define TO_PHYS_MASK 0xfffffffffULL /* 36 bit */ + +/* + * 64-bit address conversions + */ +#define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED,(p)) +#define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE,(p)) +#define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) +#define PHYS_TO_XKPHYS(cm,a) (0x8000000000000000 | ((cm)<<59) | (a)) -#endif /* __ASM_MIPS_ADDRSPACE_H */ +#endif /* __ASM_ADDRSPACE_H */ diff -Nru a/include/asm-mips/asm.h b/include/asm-mips/asm.h --- a/include/asm-mips/asm.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips/asm.h Fri Jun 27 14:19:30 2003 @@ -1,11 +1,10 @@ /* - * include/asm-mips/asm.h - * * 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) 1995, 1996, 1997 by Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki * * Some useful macros for MIPS assembler code * @@ -16,6 +15,7 @@ #ifndef __ASM_ASM_H #define __ASM_ASM_H +#include <linux/config.h> #include <asm/sgidefs.h> #ifndef CAT @@ -28,16 +28,6 @@ #endif /* - * Macros to handle different pointer/register sizes for 32/64-bit code - * - * 64 bit address space isn't used yet, so we may use the R3000 32 bit - * defines for now. - */ -#define PTR .word -#define PTRSIZE 4 -#define PTRLOG 2 - -/* * PIC specific declarations * Not used for the kernel but here seems to be the right place. */ @@ -106,7 +96,7 @@ #define PANIC(msg) \ .set push; \ .set reorder; \ - la a0,8f; \ + PTR_LA a0,8f; \ jal panic; \ 9: b 9b; \ .set pop; \ @@ -118,26 +108,26 @@ #define PRINT(string) \ .set push; \ .set reorder; \ - la a0,8f; \ + PTR_LA a0,8f; \ jal printk; \ .set pop; \ TEXT(string) #define TEXT(msg) \ - .data; \ + .pushsection .data; \ 8: .asciiz msg; \ - .previous; + .popsection; /* * Build text tables */ #define TTABLE(string) \ - .text; \ + .pushsection .text; \ .word 1f; \ - .previous; \ - .data; \ -1: .asciz string; \ - .previous + .popsection \ + .pushsection .data; \ +1: .asciiz string; \ + .popsection /* * MIPS IV pref instruction. @@ -146,16 +136,26 @@ * MIPS IV implementations are free to treat this as a nop. The R5000 * is one of them. So we should have an option not to use this instruction. */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS64) +#if CONFIG_CPU_HAS_PREFETCH + #define PREF(hint,addr) \ - pref hint,addr + .set push; \ + .set mips4; \ + pref hint,addr; \ + .set pop + #define PREFX(hint,addr) \ - prefx hint,addr -#else -#define PREF -#define PREFX -#endif + .set push; \ + .set mips4; \ + prefx hint,addr; \ + .set pop + +#else /* !CONFIG_CPU_HAS_PREFETCH */ + +#define PREF(hint,addr) +#define PREFX(hint,addr) + +#endif /* !CONFIG_CPU_HAS_PREFETCH */ /* * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. @@ -163,16 +163,16 @@ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) #define MOVN(rd,rs,rt) \ .set push; \ - .set noreorder; \ + .set reorder; \ beqz rt,9f; \ move rd,rs; \ .set pop; \ 9: #define MOVZ(rd,rs,rt) \ .set push; \ - .set noreorder; \ + .set reorder; \ bnez rt,9f; \ - move rd,rt; \ + move rd,rs; \ .set pop; \ 9: #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ @@ -181,24 +181,24 @@ .set push; \ .set noreorder; \ bnezl rt,9f; \ - move rd,rs; \ + move rd,rs; \ .set pop; \ 9: #define MOVZ(rd,rs,rt) \ .set push; \ .set noreorder; \ beqzl rt,9f; \ - movz rd,rs; \ + move rd,rs; \ .set pop; \ 9: #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS64) + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) #define MOVN(rd,rs,rt) \ movn rd,rs,rt #define MOVZ(rd,rs,rt) \ movz rd,rs,rt -#endif /* MIPS IV, MIPS V or MIPS64 */ +#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ /* * Stack alignment @@ -215,6 +215,10 @@ #endif /* + * Macros to handle different pointer/register sizes for 32/64-bit code + */ + +/* * Size of a register */ #ifdef __mips64 @@ -229,59 +233,54 @@ */ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ (_MIPS_ISA == _MIPS_ISA_MIPS32) -#define REG_S sw -#define REG_L lw -#define PTR_SUBU subu -#define PTR_ADDU addu +#define REG_S sw +#define REG_L lw +#define REG_SUBU subu +#define REG_ADDU addu #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) -#define REG_S sd -#define REG_L ld -/* We still live in a 32 bit address space ... */ -#define PTR_SUBU subu -#define PTR_ADDU addu +#define REG_S sd +#define REG_L ld +#define REG_SUBU dsubu +#define REG_ADDU daddu #endif /* * How to add/sub/load/store/shift C int variables. */ #if (_MIPS_SZINT == 32) -#define INT_ADD add -#define INT_ADDI addi +#define INT_ADD add #define INT_ADDU addu +#define INT_ADDI addi #define INT_ADDIU addiu -#define INT_SUB add -#define INT_SUBI subi +#define INT_SUB sub #define INT_SUBU subu -#define INT_SUBIU subu #define INT_L lw #define INT_S sw -#define LONG_SLL sll -#define LONG_SLLV sllv -#define LONG_SRL srl -#define LONG_SRLV srlv -#define LONG_SRA sra -#define LONG_SRAV srav +#define INT_SLL sll +#define INT_SLLV sllv +#define INT_SRL srl +#define INT_SRLV srlv +#define INT_SRA sra +#define INT_SRAV srav #endif #if (_MIPS_SZINT == 64) -#define INT_ADD dadd -#define INT_ADDI daddi +#define INT_ADD dadd #define INT_ADDU daddu +#define INT_ADDI daddi #define INT_ADDIU daddiu -#define INT_SUB dadd -#define INT_SUBI dsubi +#define INT_SUB dsub #define INT_SUBU dsubu -#define INT_SUBIU dsubu #define INT_L ld #define INT_S sd -#define LONG_SLL dsll -#define LONG_SLLV dsllv -#define LONG_SRL dsrl -#define LONG_SRLV dsrlv -#define LONG_SRA dsra -#define LONG_SRAV dsrav +#define INT_SLL dsll +#define INT_SLLV dsllv +#define INT_SRL dsrl +#define INT_SRLV dsrlv +#define INT_SRA dsra +#define INT_SRAV dsrav #endif /* @@ -289,13 +288,11 @@ */ #if (_MIPS_SZLONG == 32) #define LONG_ADD add -#define LONG_ADDI addi #define LONG_ADDU addu +#define LONG_ADDI addi #define LONG_ADDIU addiu -#define LONG_SUB add -#define LONG_SUBI subi +#define LONG_SUB sub #define LONG_SUBU subu -#define LONG_SUBIU subu #define LONG_L lw #define LONG_S sw #define LONG_SLL sll @@ -308,13 +305,11 @@ #if (_MIPS_SZLONG == 64) #define LONG_ADD dadd -#define LONG_ADDI daddi #define LONG_ADDU daddu +#define LONG_ADDI daddi #define LONG_ADDIU daddiu -#define LONG_SUB dadd -#define LONG_SUBI dsubi +#define LONG_SUB dsub #define LONG_SUBU dsubu -#define LONG_SUBIU dsubu #define LONG_L ld #define LONG_S sd #define LONG_SLL dsll @@ -328,17 +323,16 @@ /* * How to add/sub/load/store/shift pointers. */ -#if (_MIPS_SZLONG == 32) -#define PTR_ADD add -#define PTR_ADDI addi +#if (_MIPS_SZPTR == 32) +#define PTR_ADD add #define PTR_ADDU addu +#define PTR_ADDI addi #define PTR_ADDIU addiu -#define PTR_SUB add -#define PTR_SUBI subi +#define PTR_SUB sub #define PTR_SUBU subu -#define PTR_SUBIU subu #define PTR_L lw #define PTR_S sw +#define PTR_LA la #define PTR_SLL sll #define PTR_SLLV sllv #define PTR_SRL srl @@ -347,19 +341,22 @@ #define PTR_SRAV srav #define PTR_SCALESHIFT 2 + +#define PTR .word +#define PTRSIZE 4 +#define PTRLOG 2 #endif -#if (_MIPS_SZLONG == 64) -#define PTR_ADD dadd -#define PTR_ADDI daddi +#if (_MIPS_SZPTR == 64) +#define PTR_ADD dadd #define PTR_ADDU daddu +#define PTR_ADDI daddi #define PTR_ADDIU daddiu -#define PTR_SUB dadd -#define PTR_SUBI dsubi +#define PTR_SUB dsub #define PTR_SUBU dsubu -#define PTR_SUBIU dsubu #define PTR_L ld #define PTR_S sd +#define PTR_LA dla #define PTR_SLL dsll #define PTR_SLLV dsllv #define PTR_SRL dsrl @@ -368,6 +365,10 @@ #define PTR_SRAV dsrav #define PTR_SCALESHIFT 3 + +#define PTR .dword +#define PTRSIZE 8 +#define PTRLOG 3 #endif /* @@ -375,13 +376,15 @@ */ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ (_MIPS_ISA == _MIPS_ISA_MIPS32) -#define MFC0 mfc0 -#define MTC0 mtc0 +#define MFC0 mfc0 +#define MTC0 mtc0 #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) -#define MFC0 dmfc0 -#define MTC0 dmtc0 +#define MFC0 dmfc0 +#define MTC0 dmtc0 #endif + +#define SSNOP sll zero,zero,1 #endif /* __ASM_ASM_H */ diff -Nru a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h --- a/include/asm-mips/asmmacro.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips/asmmacro.h Fri Jun 27 14:20:00 2003 @@ -7,8 +7,22 @@ #ifndef _ASM_ASMMACRO_H #define _ASM_ASMMACRO_H +#include <linux/config.h> #include <asm/offset.h> +#ifdef CONFIG_CPU_SB1 +#define FPU_ENABLE_HAZARD \ + .set push; \ + .set noreorder; \ + .set mips2; \ + SSNOP; \ + bnezl $0, .+4; \ + SSNOP; \ + .set pop +#else +#define FPU_ENABLE_HAZARD +#endif + #define FPU_SAVE_DOUBLE(thread, tmp) \ cfc1 tmp, fcr31; \ sdc1 $f0, (THREAD_FPU + 0x000)(thread); \ @@ -29,41 +43,81 @@ sdc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ sw tmp, (THREAD_FPU + 0x100)(thread) +#if defined (__MIPSEL__) #define FPU_SAVE_SINGLE(thread,tmp) \ cfc1 tmp, fcr31; \ swc1 $f0, (THREAD_FPU + 0x000)(thread); \ - swc1 $f1, (THREAD_FPU + 0x008)(thread); \ + swc1 $f1, (THREAD_FPU + 0x004)(thread); \ swc1 $f2, (THREAD_FPU + 0x010)(thread); \ - swc1 $f3, (THREAD_FPU + 0x018)(thread); \ + swc1 $f3, (THREAD_FPU + 0x014)(thread); \ swc1 $f4, (THREAD_FPU + 0x020)(thread); \ - swc1 $f5, (THREAD_FPU + 0x028)(thread); \ + swc1 $f5, (THREAD_FPU + 0x024)(thread); \ swc1 $f6, (THREAD_FPU + 0x030)(thread); \ - swc1 $f7, (THREAD_FPU + 0x038)(thread); \ + swc1 $f7, (THREAD_FPU + 0x034)(thread); \ swc1 $f8, (THREAD_FPU + 0x040)(thread); \ - swc1 $f9, (THREAD_FPU + 0x048)(thread); \ + swc1 $f9, (THREAD_FPU + 0x044)(thread); \ swc1 $f10, (THREAD_FPU + 0x050)(thread); \ - swc1 $f11, (THREAD_FPU + 0x058)(thread); \ + swc1 $f11, (THREAD_FPU + 0x054)(thread); \ swc1 $f12, (THREAD_FPU + 0x060)(thread); \ - swc1 $f13, (THREAD_FPU + 0x068)(thread); \ + swc1 $f13, (THREAD_FPU + 0x064)(thread); \ swc1 $f14, (THREAD_FPU + 0x070)(thread); \ - swc1 $f15, (THREAD_FPU + 0x078)(thread); \ + swc1 $f15, (THREAD_FPU + 0x074)(thread); \ swc1 $f16, (THREAD_FPU + 0x080)(thread); \ - swc1 $f17, (THREAD_FPU + 0x088)(thread); \ + swc1 $f17, (THREAD_FPU + 0x084)(thread); \ swc1 $f18, (THREAD_FPU + 0x090)(thread); \ - swc1 $f19, (THREAD_FPU + 0x098)(thread); \ + swc1 $f19, (THREAD_FPU + 0x094)(thread); \ swc1 $f20, (THREAD_FPU + 0x0a0)(thread); \ - swc1 $f21, (THREAD_FPU + 0x0a8)(thread); \ + swc1 $f21, (THREAD_FPU + 0x0a4)(thread); \ swc1 $f22, (THREAD_FPU + 0x0b0)(thread); \ - swc1 $f23, (THREAD_FPU + 0x0b8)(thread); \ + swc1 $f23, (THREAD_FPU + 0x0b4)(thread); \ swc1 $f24, (THREAD_FPU + 0x0c0)(thread); \ - swc1 $f25, (THREAD_FPU + 0x0c8)(thread); \ + swc1 $f25, (THREAD_FPU + 0x0c4)(thread); \ swc1 $f26, (THREAD_FPU + 0x0d0)(thread); \ - swc1 $f27, (THREAD_FPU + 0x0d8)(thread); \ + swc1 $f27, (THREAD_FPU + 0x0d4)(thread); \ swc1 $f28, (THREAD_FPU + 0x0e0)(thread); \ - swc1 $f29, (THREAD_FPU + 0x0e8)(thread); \ + swc1 $f29, (THREAD_FPU + 0x0e4)(thread); \ swc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ - swc1 $f31, (THREAD_FPU + 0x0f8)(thread); \ + swc1 $f31, (THREAD_FPU + 0x0f4)(thread); \ + sw tmp, (THREAD_FPU + 0x100)(thread) +#elif defined (__MIPSEB__) +#define FPU_SAVE_SINGLE(thread,tmp) \ + cfc1 tmp, fcr31; \ + swc1 $f0, (THREAD_FPU + 0x004)(thread); \ + swc1 $f1, (THREAD_FPU + 0x000)(thread); \ + swc1 $f2, (THREAD_FPU + 0x014)(thread); \ + swc1 $f3, (THREAD_FPU + 0x010)(thread); \ + swc1 $f4, (THREAD_FPU + 0x024)(thread); \ + swc1 $f5, (THREAD_FPU + 0x020)(thread); \ + swc1 $f6, (THREAD_FPU + 0x034)(thread); \ + swc1 $f7, (THREAD_FPU + 0x030)(thread); \ + swc1 $f8, (THREAD_FPU + 0x044)(thread); \ + swc1 $f9, (THREAD_FPU + 0x040)(thread); \ + swc1 $f10, (THREAD_FPU + 0x054)(thread); \ + swc1 $f11, (THREAD_FPU + 0x050)(thread); \ + swc1 $f12, (THREAD_FPU + 0x064)(thread); \ + swc1 $f13, (THREAD_FPU + 0x060)(thread); \ + swc1 $f14, (THREAD_FPU + 0x074)(thread); \ + swc1 $f15, (THREAD_FPU + 0x070)(thread); \ + swc1 $f16, (THREAD_FPU + 0x084)(thread); \ + swc1 $f17, (THREAD_FPU + 0x080)(thread); \ + swc1 $f18, (THREAD_FPU + 0x094)(thread); \ + swc1 $f19, (THREAD_FPU + 0x090)(thread); \ + swc1 $f20, (THREAD_FPU + 0x0a4)(thread); \ + swc1 $f21, (THREAD_FPU + 0x0a0)(thread); \ + swc1 $f22, (THREAD_FPU + 0x0b4)(thread); \ + swc1 $f23, (THREAD_FPU + 0x0b0)(thread); \ + swc1 $f24, (THREAD_FPU + 0x0c4)(thread); \ + swc1 $f25, (THREAD_FPU + 0x0c0)(thread); \ + swc1 $f26, (THREAD_FPU + 0x0d4)(thread); \ + swc1 $f27, (THREAD_FPU + 0x0d0)(thread); \ + swc1 $f28, (THREAD_FPU + 0x0e4)(thread); \ + swc1 $f29, (THREAD_FPU + 0x0e0)(thread); \ + swc1 $f30, (THREAD_FPU + 0x0f4)(thread); \ + swc1 $f31, (THREAD_FPU + 0x0f0)(thread); \ sw tmp, (THREAD_FPU + 0x100)(thread) +#else +#error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" +#endif #define FPU_RESTORE_DOUBLE(thread, tmp) \ lw tmp, (THREAD_FPU + 0x100)(thread); \ @@ -85,41 +139,81 @@ ldc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ ctc1 tmp, fcr31 +#if defined (__MIPSEL__) #define FPU_RESTORE_SINGLE(thread,tmp) \ lw tmp, (THREAD_FPU + 0x100)(thread); \ lwc1 $f0, (THREAD_FPU + 0x000)(thread); \ - lwc1 $f1, (THREAD_FPU + 0x008)(thread); \ + lwc1 $f1, (THREAD_FPU + 0x004)(thread); \ lwc1 $f2, (THREAD_FPU + 0x010)(thread); \ - lwc1 $f3, (THREAD_FPU + 0x018)(thread); \ + lwc1 $f3, (THREAD_FPU + 0x014)(thread); \ lwc1 $f4, (THREAD_FPU + 0x020)(thread); \ - lwc1 $f5, (THREAD_FPU + 0x028)(thread); \ + lwc1 $f5, (THREAD_FPU + 0x024)(thread); \ lwc1 $f6, (THREAD_FPU + 0x030)(thread); \ - lwc1 $f7, (THREAD_FPU + 0x038)(thread); \ + lwc1 $f7, (THREAD_FPU + 0x034)(thread); \ lwc1 $f8, (THREAD_FPU + 0x040)(thread); \ - lwc1 $f9, (THREAD_FPU + 0x048)(thread); \ + lwc1 $f9, (THREAD_FPU + 0x044)(thread); \ lwc1 $f10, (THREAD_FPU + 0x050)(thread); \ - lwc1 $f11, (THREAD_FPU + 0x058)(thread); \ + lwc1 $f11, (THREAD_FPU + 0x054)(thread); \ lwc1 $f12, (THREAD_FPU + 0x060)(thread); \ - lwc1 $f13, (THREAD_FPU + 0x068)(thread); \ + lwc1 $f13, (THREAD_FPU + 0x064)(thread); \ lwc1 $f14, (THREAD_FPU + 0x070)(thread); \ - lwc1 $f15, (THREAD_FPU + 0x078)(thread); \ + lwc1 $f15, (THREAD_FPU + 0x074)(thread); \ lwc1 $f16, (THREAD_FPU + 0x080)(thread); \ - lwc1 $f17, (THREAD_FPU + 0x088)(thread); \ + lwc1 $f17, (THREAD_FPU + 0x084)(thread); \ lwc1 $f18, (THREAD_FPU + 0x090)(thread); \ - lwc1 $f19, (THREAD_FPU + 0x098)(thread); \ + lwc1 $f19, (THREAD_FPU + 0x094)(thread); \ lwc1 $f20, (THREAD_FPU + 0x0a0)(thread); \ - lwc1 $f21, (THREAD_FPU + 0x0a8)(thread); \ + lwc1 $f21, (THREAD_FPU + 0x0a4)(thread); \ lwc1 $f22, (THREAD_FPU + 0x0b0)(thread); \ - lwc1 $f23, (THREAD_FPU + 0x0b8)(thread); \ + lwc1 $f23, (THREAD_FPU + 0x0b4)(thread); \ lwc1 $f24, (THREAD_FPU + 0x0c0)(thread); \ - lwc1 $f25, (THREAD_FPU + 0x0c8)(thread); \ + lwc1 $f25, (THREAD_FPU + 0x0c4)(thread); \ lwc1 $f26, (THREAD_FPU + 0x0d0)(thread); \ - lwc1 $f27, (THREAD_FPU + 0x0d8)(thread); \ + lwc1 $f27, (THREAD_FPU + 0x0d4)(thread); \ lwc1 $f28, (THREAD_FPU + 0x0e0)(thread); \ - lwc1 $f29, (THREAD_FPU + 0x0e8)(thread); \ + lwc1 $f29, (THREAD_FPU + 0x0e4)(thread); \ lwc1 $f30, (THREAD_FPU + 0x0f0)(thread); \ - lwc1 $f31, (THREAD_FPU + 0x0f8)(thread); \ + lwc1 $f31, (THREAD_FPU + 0x0f4)(thread); \ + ctc1 tmp, fcr31 +#elif defined (__MIPSEB__) +#define FPU_RESTORE_SINGLE(thread,tmp) \ + lw tmp, (THREAD_FPU + 0x100)(thread); \ + lwc1 $f0, (THREAD_FPU + 0x004)(thread); \ + lwc1 $f1, (THREAD_FPU + 0x000)(thread); \ + lwc1 $f2, (THREAD_FPU + 0x014)(thread); \ + lwc1 $f3, (THREAD_FPU + 0x010)(thread); \ + lwc1 $f4, (THREAD_FPU + 0x024)(thread); \ + lwc1 $f5, (THREAD_FPU + 0x020)(thread); \ + lwc1 $f6, (THREAD_FPU + 0x034)(thread); \ + lwc1 $f7, (THREAD_FPU + 0x030)(thread); \ + lwc1 $f8, (THREAD_FPU + 0x044)(thread); \ + lwc1 $f9, (THREAD_FPU + 0x040)(thread); \ + lwc1 $f10, (THREAD_FPU + 0x054)(thread); \ + lwc1 $f11, (THREAD_FPU + 0x050)(thread); \ + lwc1 $f12, (THREAD_FPU + 0x064)(thread); \ + lwc1 $f13, (THREAD_FPU + 0x060)(thread); \ + lwc1 $f14, (THREAD_FPU + 0x074)(thread); \ + lwc1 $f15, (THREAD_FPU + 0x070)(thread); \ + lwc1 $f16, (THREAD_FPU + 0x084)(thread); \ + lwc1 $f17, (THREAD_FPU + 0x080)(thread); \ + lwc1 $f18, (THREAD_FPU + 0x094)(thread); \ + lwc1 $f19, (THREAD_FPU + 0x090)(thread); \ + lwc1 $f20, (THREAD_FPU + 0x0a4)(thread); \ + lwc1 $f21, (THREAD_FPU + 0x0a0)(thread); \ + lwc1 $f22, (THREAD_FPU + 0x0b4)(thread); \ + lwc1 $f23, (THREAD_FPU + 0x0b0)(thread); \ + lwc1 $f24, (THREAD_FPU + 0x0c4)(thread); \ + lwc1 $f25, (THREAD_FPU + 0x0c0)(thread); \ + lwc1 $f26, (THREAD_FPU + 0x0d4)(thread); \ + lwc1 $f27, (THREAD_FPU + 0x0d0)(thread); \ + lwc1 $f28, (THREAD_FPU + 0x0e4)(thread); \ + lwc1 $f29, (THREAD_FPU + 0x0e0)(thread); \ + lwc1 $f30, (THREAD_FPU + 0x0f4)(thread); \ + lwc1 $f31, (THREAD_FPU + 0x0f0)(thread); \ ctc1 tmp, fcr31 +#else +#error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" +#endif #define CPU_SAVE_NONSCRATCH(thread) \ sw s0, THREAD_REG16(thread); \ diff -Nru a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h --- a/include/asm-mips/atomic.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips/atomic.h Fri Jun 27 14:19:30 2003 @@ -57,12 +57,11 @@ */ extern __inline__ void atomic_add(int i, atomic_t * v) { - int flags; + unsigned long flags; - save_flags(flags); - cli(); + local_irq_save(flags); v->counter += i; - restore_flags(flags); + local_irq_restore(flags); } /* @@ -75,38 +74,37 @@ */ extern __inline__ void atomic_sub(int i, atomic_t * v) { - int flags; + unsigned long flags; - save_flags(flags); - cli(); + local_irq_save(flags); v->counter -= i; - restore_flags(flags); + local_irq_restore(flags); } extern __inline__ int atomic_add_return(int i, atomic_t * v) { - int temp, flags; + unsigned long flags; + int temp; - save_flags(flags); - cli(); + local_irq_save(flags); temp = v->counter; temp += i; v->counter = temp; - restore_flags(flags); + local_irq_restore(flags); return temp; } extern __inline__ int atomic_sub_return(int i, atomic_t * v) { - int temp, flags; + unsigned long flags; + int temp; - save_flags(flags); - cli(); + local_irq_save(flags); temp = v->counter; temp -= i; v->counter = temp; - restore_flags(flags); + local_irq_restore(flags); return temp; } @@ -175,6 +173,7 @@ " sc %0, %2 \n" " beqz %0, 1b \n" " addu %0, %1, %3 \n" + " sync \n" ".set pop \n" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -195,6 +194,7 @@ " sc %0, %2 \n" " beqz %0, 1b \n" " subu %0, %1, %3 \n" + " sync \n" ".set pop \n" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -228,7 +228,7 @@ * other cases. Note that the guaranteed * useful range of an atomic_t is only 24 bits. */ -#define atomic_inc_and_test(v) (atomic_inc_return(1, (v)) == 0) +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) /* * atomic_dec_and_test - decrement by 1 and test @@ -268,15 +268,14 @@ * if the result is negative, or false when * result is greater than or equal to zero. Note that the guaranteed * useful range of an atomic_t is only 24 bits. - * - * Currently not implemented for MIPS. */ +#define atomic_add_negative(i,v) (atomic_add_return(i, (v)) < 0) /* Atomic operations are already serializing */ -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() +#define smp_mb__before_atomic_dec() smp_mb() +#define smp_mb__after_atomic_dec() smp_mb() +#define smp_mb__before_atomic_inc() smp_mb() +#define smp_mb__after_atomic_inc() smp_mb() #endif /* defined(__KERNEL__) */ diff -Nru a/include/asm-mips/au1000.h b/include/asm-mips/au1000.h --- a/include/asm-mips/au1000.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/au1000.h Fri Jun 27 14:19:52 2003 @@ -1,9 +1,9 @@ /* * * BRIEF MODULE DESCRIPTION - * Include file for Alchemy Semiconductor's Au1000 CPU. + * Include file for Alchemy Semiconductor's Au1k CPU. * - * Copyright 2000 MontaVista Software Inc. + * Copyright 2000,2001 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -28,191 +28,191 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ + /* + * some definitions add by takuzo@sm.sony.co.jp and sato@sm.sony.co.jp + */ + #ifndef _AU1000_H_ #define _AU1000_H_ +#include <linux/delay.h> +#include <asm/io.h> + +/* cpu pipeline flush */ +void static inline au_sync(void) +{ + __asm__ volatile ("sync"); +} + +void static inline au_sync_udelay(int us) +{ + __asm__ volatile ("sync"); + udelay(us); +} + +void static inline au_sync_delay(int ms) +{ + __asm__ volatile ("sync"); + mdelay(ms); +} + +void static inline au_writeb(u8 val, int reg) +{ + *(volatile u8 *)(reg) = val; +} + +void static inline au_writew(u16 val, int reg) +{ + *(volatile u16 *)(reg) = val; +} + +void static inline au_writel(u32 val, int reg) +{ + *(volatile u32 *)(reg) = val; +} + +static inline u8 au_readb(unsigned long port) +{ + return (*(volatile u8 *)port); +} + +static inline u16 au_readw(unsigned long port) +{ + return (*(volatile u16 *)port); +} + +static inline u32 au_readl(unsigned long port) +{ + return (*(volatile u32 *)port); +} + +/* arch/mips/au1000/common/clocks.c */ +extern void set_au1x00_speed(unsigned int new_freq); +extern unsigned int get_au1x00_speed(void); +extern void set_au1x00_uart_baud_base(unsigned long new_baud_base); +extern unsigned long get_au1x00_uart_baud_base(void); +extern void set_au1x00_lcd_clock(void); +extern unsigned int get_au1x00_lcd_clock(void); + +#ifdef CONFIG_PM +/* no CP0 timer irq */ +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) +#else +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) +#endif + /* SDRAM Controller */ -#define CS_MODE_0 0x14000000 -#define CS_MODE_1 0x14000004 -#define CS_MODE_2 0x14000008 - -#define CS_CONFIG_0 0x1400000C -#define CS_CONFIG_1 0x14000010 -#define CS_CONFIG_2 0x14000014 - -#define REFRESH_CONFIG 0x14000018 -#define PRECHARGE_CMD 0x1400001C -#define AUTO_REFRESH_CMD 0x14000020 - -#define WRITE_EXTERN_0 0x14000024 -#define WRITE_EXTERN_1 0x14000028 -#define WRITE_EXTERN_2 0x1400002C +#define MEM_SDMODE0 0xB4000000 +#define MEM_SDMODE1 0xB4000004 +#define MEM_SDMODE2 0xB4000008 + +#define MEM_SDADDR0 0xB400000C +#define MEM_SDADDR1 0xB4000010 +#define MEM_SDADDR2 0xB4000014 + +#define MEM_SDREFCFG 0xB4000018 +#define MEM_SDPRECMD 0xB400001C +#define MEM_SDAUTOREF 0xB4000020 + +#define MEM_SDWRMD0 0xB4000024 +#define MEM_SDWRMD1 0xB4000028 +#define MEM_SDWRMD2 0xB400002C -#define SDRAM_SLEEP 0x14000030 -#define TOGGLE_CKE 0x14000034 +#define MEM_SDSLEEP 0xB4000030 +#define MEM_SDSMCKE 0xB4000034 /* Static Bus Controller */ -#define STATIC_CONFIG_0 0x14001000 -#define STATIC_TIMING_0 0x14001004 -#define STATIC_ADDRESS_0 0x14001008 - -#define STATIC_CONFIG_1 0x14001010 -#define STATIC_TIMING_1 0x14001014 -#define STATIC_ADDRESS_1 0x14001018 - -#define STATIC_CONFIG_2 0x14001020 -#define STATIC_TIMING_2 0x14001024 -#define STATIC_ADDRESS_2 0x14001028 - -#define STATIC_CONFIG_3 0x14001030 -#define STATIC_TIMING_3 0x14001034 -#define STATIC_ADDRESS_3 0x14001038 - -/* DMA Controller 0 */ -#define DMA0_MODE_SET 0x14002000 -#define DMA0_MODE_CLEAR 0x14002004 -#define DMA0_PERIPHERAL_ADDR 0x14002008 -#define DMA0_BUFFER0_START 0x1400200C -#define DMA0_BUFFER0_COUNT 0x14002010 -#define DMA0_BUFFER1_START 0x14002014 -#define DMA0_BUFFER1_COUNT 0x14002018 - -/* DMA Controller 1 */ -#define DMA1_MODE_SET 0x14002100 -#define DMA1_MODE_CLEAR 0x14002104 -#define DMA1_PERIPHERAL_ADDR 0x14002108 -#define DMA1_BUFFER0_START 0x1400210C -#define DMA1_BUFFER0_COUNT 0x14002110 -#define DMA1_BUFFER1_START 0x14002114 -#define DMA1_BUFFER1_COUNT 0x14002118 - -/* DMA Controller 2 */ -#define DMA2_MODE_SET 0x14002200 -#define DMA2_MODE_CLEAR 0x14002204 -#define DMA2_PERIPHERAL_ADDR 0x14002208 -#define DMA2_BUFFER0_START 0x1400220C -#define DMA2_BUFFER0_COUNT 0x14002210 -#define DMA2_BUFFER1_START 0x14002214 -#define DMA2_BUFFER1_COUNT 0x14002218 - -/* DMA Controller 3 */ -#define DMA3_MODE_SET 0x14002300 -#define DMA3_MODE_CLEAR 0x14002304 -#define DMA3_PERIPHERAL_ADDR 0x14002308 -#define DMA3_BUFFER0_START 0x1400230C -#define DMA3_BUFFER0_COUNT 0x14002310 -#define DMA3_BUFFER1_START 0x14002314 -#define DMA3_BUFFER1_COUNT 0x14002318 - -/* DMA Controller 4 */ -#define DMA4_MODE_SET 0x14002400 -#define DMA4_MODE_CLEAR 0x14002404 -#define DMA4_PERIPHERAL_ADDR 0x14002408 -#define DMA4_BUFFER0_START 0x1400240C -#define DMA4_BUFFER0_COUNT 0x14002410 -#define DMA4_BUFFER1_START 0x14002414 -#define DMA4_BUFFER1_COUNT 0x14002418 - -/* DMA Controller 5 */ -#define DMA5_MODE_SET 0x14002500 -#define DMA5_MODE_CLEAR 0x14002504 -#define DMA5_PERIPHERAL_ADDR 0x14002508 -#define DMA5_BUFFER0_START 0x1400250C -#define DMA5_BUFFER0_COUNT 0x14002510 -#define DMA5_BUFFER1_START 0x14002514 -#define DMA5_BUFFER1_COUNT 0x14002518 - -/* DMA Controller 6 */ -#define DMA6_MODE_SET 0x14002600 -#define DMA6_MODE_CLEAR 0x14002604 -#define DMA6_PERIPHERAL_ADDR 0x14002608 -#define DMA6_BUFFER0_START 0x1400260C -#define DMA6_BUFFER0_COUNT 0x14002610 -#define DMA6_BUFFER1_START 0x14002614 -#define DMA6_BUFFER1_COUNT 0x14002618 - -/* DMA Controller 7 */ -#define DMA7_MODE_SET 0x14002700 -#define DMA7_MODE_CLEAR 0x14002704 -#define DMA7_PERIPHERAL_ADDR 0x14002708 -#define DMA7_BUFFER0_START 0x1400270C -#define DMA7_BUFFER0_COUNT 0x14002710 -#define DMA7_BUFFER1_START 0x14002714 -#define DMA7_BUFFER1_COUNT 0x14002718 +#define MEM_STCFG0 0xB4001000 +#define MEM_STTIME0 0xB4001004 +#define MEM_STADDR0 0xB4001008 + +#define MEM_STCFG1 0xB4001010 +#define MEM_STTIME1 0xB4001014 +#define MEM_STADDR1 0xB4001018 + +#define MEM_STCFG2 0xB4001020 +#define MEM_STTIME2 0xB4001024 +#define MEM_STADDR2 0xB4001028 + +#define MEM_STCFG3 0xB4001030 +#define MEM_STTIME3 0xB4001034 +#define MEM_STADDR3 0xB4001038 /* Interrupt Controller 0 */ -#define INTC0_CONFIG0_READ 0x10400040 -#define INTC0_CONFIG0_SET 0x10400040 -#define INTC0_CONFIG0_CLEAR 0x10400044 - -#define INTC0_CONFIG1_READ 0x10400048 -#define INTC0_CONFIG1_SET 0x10400048 -#define INTC0_CONFIG1_CLEAR 0x1040004C - -#define INTC0_CONFIG2_READ 0x10400050 -#define INTC0_CONFIG2_SET 0x10400050 -#define INTC0_CONFIG2_CLEAR 0x10400054 - -#define INTC0_REQ0_INT 0x10400054 -#define INTC0_SOURCE_READ 0x10400058 -#define INTC0_SOURCE_SET 0x10400058 -#define INTC0_SOURCE_CLEAR 0x1040005C -#define INTC0_REQ1_INT 0x1040005C - -#define INTC0_ASSIGN_REQ_READ 0x10400060 -#define INTC0_ASSIGN_REQ_SET 0x10400060 -#define INTC0_ASSIGN_REQ_CLEAR 0x10400064 - -#define INTC0_WAKEUP_READ 0x10400068 -#define INTC0_WAKEUP_SET 0x10400068 -#define INTC0_WAKEUP_CLEAR 0x1040006C - -#define INTC0_MASK_READ 0x10400070 -#define INTC0_MASK_SET 0x10400070 -#define INTC0_MASK_CLEAR 0x10400074 - -#define INTC0_R_EDGE_DETECT 0x10400078 -#define INTC0_R_EDGE_DETECT_CLEAR 0x10400078 -#define INTC0_F_EDGE_DETECT_CLEAR 0x1040007C +#define IC0_CFG0RD 0xB0400040 +#define IC0_CFG0SET 0xB0400040 +#define IC0_CFG0CLR 0xB0400044 + +#define IC0_CFG1RD 0xB0400048 +#define IC0_CFG1SET 0xB0400048 +#define IC0_CFG1CLR 0xB040004C + +#define IC0_CFG2RD 0xB0400050 +#define IC0_CFG2SET 0xB0400050 +#define IC0_CFG2CLR 0xB0400054 + +#define IC0_REQ0INT 0xB0400054 +#define IC0_SRCRD 0xB0400058 +#define IC0_SRCSET 0xB0400058 +#define IC0_SRCCLR 0xB040005C +#define IC0_REQ1INT 0xB040005C + +#define IC0_ASSIGNRD 0xB0400060 +#define IC0_ASSIGNSET 0xB0400060 +#define IC0_ASSIGNCLR 0xB0400064 + +#define IC0_WAKERD 0xB0400068 +#define IC0_WAKESET 0xB0400068 +#define IC0_WAKECLR 0xB040006C + +#define IC0_MASKRD 0xB0400070 +#define IC0_MASKSET 0xB0400070 +#define IC0_MASKCLR 0xB0400074 + +#define IC0_RISINGRD 0xB0400078 +#define IC0_RISINGCLR 0xB0400078 +#define IC0_FALLINGRD 0xB040007C +#define IC0_FALLINGCLR 0xB040007C -#define INTC0_TEST_BIT 0x10400080 +#define IC0_TESTBIT 0xB0400080 /* Interrupt Controller 1 */ -#define INTC1_CONFIG0_READ 0x11800040 -#define INTC1_CONFIG0_SET 0x11800040 -#define INTC1_CONFIG0_CLEAR 0x11800044 - -#define INTC1_CONFIG1_READ 0x11800048 -#define INTC1_CONFIG1_SET 0x11800048 -#define INTC1_CONFIG1_CLEAR 0x1180004C - -#define INTC1_CONFIG2_READ 0x11800050 -#define INTC1_CONFIG2_SET 0x11800050 -#define INTC1_CONFIG2_CLEAR 0x11800054 - -#define INTC1_REQ0_INT 0x11800054 -#define INTC1_SOURCE_READ 0x11800058 -#define INTC1_SOURCE_SET 0x11800058 -#define INTC1_SOURCE_CLEAR 0x1180005C -#define INTC1_REQ1_INT 0x1180005C - -#define INTC1_ASSIGN_REQ_READ 0x11800060 -#define INTC1_ASSIGN_REQ_SET 0x11800060 -#define INTC1_ASSIGN_REQ_CLEAR 0x11800064 - -#define INTC1_WAKEUP_READ 0x11800068 -#define INTC1_WAKEUP_SET 0x11800068 -#define INTC1_WAKEUP_CLEAR 0x1180006C - -#define INTC1_MASK_READ 0x11800070 -#define INTC1_MASK_SET 0x11800070 -#define INTC1_MASK_CLEAR 0x11800074 - -#define INTC1_R_EDGE_DETECT 0x11800078 -#define INTC1_R_EDGE_DETECT_CLEAR 0x11800078 -#define INTC1_F_EDGE_DETECT_CLEAR 0x1180007C +#define IC1_CFG0RD 0xB1800040 +#define IC1_CFG0SET 0xB1800040 +#define IC1_CFG0CLR 0xB1800044 + +#define IC1_CFG1RD 0xB1800048 +#define IC1_CFG1SET 0xB1800048 +#define IC1_CFG1CLR 0xB180004C + +#define IC1_CFG2RD 0xB1800050 +#define IC1_CFG2SET 0xB1800050 +#define IC1_CFG2CLR 0xB1800054 + +#define IC1_REQ0INT 0xB1800054 +#define IC1_SRCRD 0xB1800058 +#define IC1_SRCSET 0xB1800058 +#define IC1_SRCCLR 0xB180005C +#define IC1_REQ1INT 0xB180005C + +#define IC1_ASSIGNRD 0xB1800060 +#define IC1_ASSIGNSET 0xB1800060 +#define IC1_ASSIGNCLR 0xB1800064 + +#define IC1_WAKERD 0xB1800068 +#define IC1_WAKESET 0xB1800068 +#define IC1_WAKECLR 0xB180006C + +#define IC1_MASKRD 0xB1800070 +#define IC1_MASKSET 0xB1800070 +#define IC1_MASKCLR 0xB1800074 + +#define IC1_RISINGRD 0xB1800078 +#define IC1_RISINGCLR 0xB1800078 +#define IC1_FALLINGRD 0xB180007C +#define IC1_FALLINGCLR 0xB180007C -#define INTC1_TEST_BIT 0x11800080 +#define IC1_TESTBIT 0xB1800080 /* Interrupt Configuration Modes */ #define INTC_INT_DISABLED 0 @@ -225,29 +225,31 @@ /* Interrupt Numbers */ #define AU1000_UART0_INT 0 -#define AU1000_UART1_INT 1 -#define AU1000_UART2_INT 2 +#define AU1000_UART1_INT 1 /* au1000 */ +#define AU1000_UART2_INT 2 /* au1000 */ + +#define AU1000_PCI_INTA 1 /* au1500 */ +#define AU1000_PCI_INTB 2 /* au1500 */ + #define AU1000_UART3_INT 3 -#define AU1000_SSI0_INT 4 -#define AU1000_SSI1_INT 5 -#define AU1000_DMA0_INT 6 -#define AU1000_DMA1_INT 7 -#define AU1000_DMA2_INT 8 -#define AU1000_DMA3_INT 9 -#define AU1000_DMA4_INT 10 -#define AU1000_DMA5_INT 11 -#define AU1000_DMA6_INT 12 -#define AU1000_DMA7_INT 13 -#define AU1000_PC0_INT 14 -#define AU1000_PC0_MATCH0_INT 15 -#define AU1000_PC0_MATCH1_INT 16 -#define AU1000_PC0_MATCH2_INT 17 -#define AU1000_PC1_INT 18 -#define AU1000_PC1_MATCH0_INT 19 -#define AU1000_PC1_MATCH1_INT 20 -#define AU1000_PC1_MATCH2_INT 21 -#define AU1000_IRDA_TX_INT 22 -#define AU1000_IRDA_RX_INT 23 + +#define AU1000_SSI0_INT 4 /* au1000 */ +#define AU1000_SSI1_INT 5 /* au1000 */ + +#define AU1000_PCI_INTC 4 /* au1500 */ +#define AU1000_PCI_INTD 5 /* au1500 */ + +#define AU1000_DMA_INT_BASE 6 +#define AU1000_TOY_INT 14 +#define AU1000_TOY_MATCH0_INT 15 +#define AU1000_TOY_MATCH1_INT 16 +#define AU1000_TOY_MATCH2_INT 17 +#define AU1000_RTC_INT 18 +#define AU1000_RTC_MATCH0_INT 19 +#define AU1000_RTC_MATCH1_INT 20 +#define AU1000_RTC_MATCH2_INT 21 +#define AU1000_IRDA_TX_INT 22 /* au1000 */ +#define AU1000_IRDA_RX_INT 23 /* au1000 */ #define AU1000_USB_DEV_REQ_INT 24 #define AU1000_USB_DEV_SUS_INT 25 #define AU1000_USB_HOST_INT 26 @@ -256,9 +258,9 @@ #define AU1000_MAC1_DMA_INT 29 #define AU1000_ETH0_IRQ AU1000_MAC0_DMA_INT #define AU1000_ETH1_IRQ AU1000_MAC1_DMA_INT -#define AU1000_I2S_UO_INT 30 -#define AU1000_AC97_INT 31 -#define AU1000_LAST_INTC0_INT AU1000_AC97_INT +#define AU1000_I2S_UO_INT 30 /* au1000 */ +#define AU1000_AC97C_INT 31 +#define AU1000_LAST_INTC0_INT AU1000_AC97C_INT #define AU1000_GPIO_0 32 #define AU1000_GPIO_1 33 #define AU1000_GPIO_2 34 @@ -275,6 +277,8 @@ #define AU1000_GPIO_13 45 #define AU1000_GPIO_14 46 #define AU1000_GPIO_15 47 + +/* Au1000 only */ #define AU1000_GPIO_16 48 #define AU1000_GPIO_17 49 #define AU1000_GPIO_18 50 @@ -292,60 +296,162 @@ #define AU1000_GPIO_30 62 #define AU1000_GPIO_31 63 +/* Au1500 only */ +#define AU1500_GPIO_200 48 +#define AU1500_GPIO_201 49 +#define AU1500_GPIO_202 50 +#define AU1500_GPIO_203 51 +#define AU1500_GPIO_20 52 +#define AU1500_GPIO_204 53 +#define AU1500_GPIO_205 54 +#define AU1500_GPIO_23 55 +#define AU1500_GPIO_24 56 +#define AU1500_GPIO_25 57 +#define AU1500_GPIO_26 58 +#define AU1500_GPIO_27 59 +#define AU1500_GPIO_28 60 +#define AU1500_GPIO_206 61 +#define AU1500_GPIO_207 62 +#define AU1500_GPIO_208_215 63 + +#define AU1000_MAX_INTR 63 + +#define AU1100_SD 2 +#define AU1100_GPIO_208_215 29 +// REDEFINE SECONDARY GPIO BLOCK INTO IC1 CONTROLLER HERE + + + /* Programmable Counters 0 and 1 */ -#define PC_BASE 0x11900000 -#define PC_COUNTER_CNTRL (PC_BASE + 0x14) - #define PC_CNTRL_E1S (1<<23) - #define PC_CNTRL_T1S (1<<20) - #define PC_CNTRL_M21 (1<<19) - #define PC_CNTRL_M11 (1<<18) - #define PC_CNTRL_M01 (1<<17) - #define PC_CNTRL_C1S (1<<16) - #define PC_CNTRL_BP (1<<14) - #define PC_CNTRL_EN1 (1<<13) - #define PC_CNTRL_BT1 (1<<12) - #define PC_CNTRL_EN0 (1<<11) - #define PC_CNTRL_BT0 (1<<10) - #define PC_CNTRL_E0 (1<<8) - #define PC_CNTRL_E0S (1<<7) - #define PC_CNTRL_32S (1<<5) - #define PC_CNTRL_T0S (1<<4) - #define PC_CNTRL_M20 (1<<3) - #define PC_CNTRL_M10 (1<<2) - #define PC_CNTRL_M00 (1<<1) - #define PC_CNTRL_C0S (1<<0) +#define SYS_BASE 0xB1900000 +#define SYS_COUNTER_CNTRL (SYS_BASE + 0x14) + #define SYS_CNTRL_E1S (1<<23) + #define SYS_CNTRL_T1S (1<<20) + #define SYS_CNTRL_M21 (1<<19) + #define SYS_CNTRL_M11 (1<<18) + #define SYS_CNTRL_M01 (1<<17) + #define SYS_CNTRL_C1S (1<<16) + #define SYS_CNTRL_BP (1<<14) + #define SYS_CNTRL_EN1 (1<<13) + #define SYS_CNTRL_BT1 (1<<12) + #define SYS_CNTRL_EN0 (1<<11) + #define SYS_CNTRL_BT0 (1<<10) + #define SYS_CNTRL_E0 (1<<8) + #define SYS_CNTRL_E0S (1<<7) + #define SYS_CNTRL_32S (1<<5) + #define SYS_CNTRL_T0S (1<<4) + #define SYS_CNTRL_M20 (1<<3) + #define SYS_CNTRL_M10 (1<<2) + #define SYS_CNTRL_M00 (1<<1) + #define SYS_CNTRL_C0S (1<<0) /* Programmable Counter 0 Registers */ -#define PC0_TRIM (PC_BASE + 0) -#define PC0_COUNTER_WRITE (PC_BASE + 4) -#define PC0_MATCH0 (PC_BASE + 8) -#define PC0_MATCH1 (PC_BASE + 0xC) -#define PC0_MATCH2 (PC_BASE + 0x10) -#define PC0_COUNTER_READ (PC_BASE + 0x40) +#define SYS_TOYTRIM (SYS_BASE + 0) +#define SYS_TOYWRITE (SYS_BASE + 4) +#define SYS_TOYMATCH0 (SYS_BASE + 8) +#define SYS_TOYMATCH1 (SYS_BASE + 0xC) +#define SYS_TOYMATCH2 (SYS_BASE + 0x10) +#define SYS_TOYREAD (SYS_BASE + 0x40) /* Programmable Counter 1 Registers */ -#define PC1_TRIM (PC_BASE + 0x44) -#define PC1_COUNTER_WRITE (PC_BASE + 0x48) -#define PC1_MATCH0 (PC_BASE + 0x4C) -#define PC1_MATCH1 (PC_BASE + 0x50) -#define PC1_MATCH2 (PC_BASE + 0x54) -#define PC1_COUNTER_READ (PC_BASE + 0x58) - +#define SYS_RTCTRIM (SYS_BASE + 0x44) +#define SYS_RTCWRITE (SYS_BASE + 0x48) +#define SYS_RTCMATCH0 (SYS_BASE + 0x4C) +#define SYS_RTCMATCH1 (SYS_BASE + 0x50) +#define SYS_RTCMATCH2 (SYS_BASE + 0x54) +#define SYS_RTCREAD (SYS_BASE + 0x58) /* I2S Controller */ -#define I2S_DATA 0x11000000 -#define I2S_CONFIG_STATUS 0x11000001 -#define I2S_CONTROL 0x11000002 +#define I2S_DATA 0xB1000000 + #define I2S_DATA_MASK (0xffffff) +#define I2S_CONFIG 0xB1000004 + #define I2S_CONFIG_XU (1<<25) + #define I2S_CONFIG_XO (1<<24) + #define I2S_CONFIG_RU (1<<23) + #define I2S_CONFIG_RO (1<<22) + #define I2S_CONFIG_TR (1<<21) + #define I2S_CONFIG_TE (1<<20) + #define I2S_CONFIG_TF (1<<19) + #define I2S_CONFIG_RR (1<<18) + #define I2S_CONFIG_RE (1<<17) + #define I2S_CONFIG_RF (1<<16) + #define I2S_CONFIG_PD (1<<11) + #define I2S_CONFIG_LB (1<<10) + #define I2S_CONFIG_IC (1<<9) + #define I2S_CONFIG_FM_BIT 7 + #define I2S_CONFIG_FM_MASK (0x3 << I2S_CONFIG_FM_BIT) + #define I2S_CONFIG_FM_I2S (0x0 << I2S_CONFIG_FM_BIT) + #define I2S_CONFIG_FM_LJ (0x1 << I2S_CONFIG_FM_BIT) + #define I2S_CONFIG_FM_RJ (0x2 << I2S_CONFIG_FM_BIT) + #define I2S_CONFIG_TN (1<<6) + #define I2S_CONFIG_RN (1<<5) + #define I2S_CONFIG_SZ_BIT 0 + #define I2S_CONFIG_SZ_MASK (0x1F << I2S_CONFIG_SZ_BIT) + +#define I2S_CONTROL 0xB1000008 + #define I2S_CONTROL_D (1<<1) + #define I2S_CONTROL_CE (1<<0) + +/* USB Host Controller */ +// We pass USB_OHCI_BASE to ioremap, so it needs to be a physical address +#define USB_OHCI_BASE 0x10100000 +#define USB_OHCI_LEN 0x00100000 +#define USB_HOST_CONFIG 0xB017fffc + +/* USB Device Controller */ +#define USBD_EP0RD 0xB0200000 +#define USBD_EP0WR 0xB0200004 +#define USBD_EP2WR 0xB0200008 +#define USBD_EP3WR 0xB020000C +#define USBD_EP4RD 0xB0200010 +#define USBD_EP5RD 0xB0200014 +#define USBD_INTEN 0xB0200018 +#define USBD_INTSTAT 0xB020001C + #define USBDEV_INT_SOF (1<<12) + #define USBDEV_INT_HF_BIT 6 + #define USBDEV_INT_HF_MASK (0x3f << USBDEV_INT_HF_BIT) + #define USBDEV_INT_CMPLT_BIT 0 + #define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT) +#define USBD_CONFIG 0xB0200020 +#define USBD_EP0CS 0xB0200024 +#define USBD_EP2CS 0xB0200028 +#define USBD_EP3CS 0xB020002C +#define USBD_EP4CS 0xB0200030 +#define USBD_EP5CS 0xB0200034 + #define USBDEV_CS_SU (1<<14) + #define USBDEV_CS_NAK (1<<13) + #define USBDEV_CS_ACK (1<<12) + #define USBDEV_CS_BUSY (1<<11) + #define USBDEV_CS_TSIZE_BIT 1 + #define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT) + #define USBDEV_CS_STALL (1<<0) +#define USBD_EP0RDSTAT 0xB0200040 +#define USBD_EP0WRSTAT 0xB0200044 +#define USBD_EP2WRSTAT 0xB0200048 +#define USBD_EP3WRSTAT 0xB020004C +#define USBD_EP4RDSTAT 0xB0200050 +#define USBD_EP5RDSTAT 0xB0200054 + #define USBDEV_FSTAT_FLUSH (1<<6) + #define USBDEV_FSTAT_UF (1<<5) + #define USBDEV_FSTAT_OF (1<<4) + #define USBDEV_FSTAT_FCNT_BIT 0 + #define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT) +#define USBD_ENABLE 0xB0200058 + #define USBDEV_ENABLE (1<<1) + #define USBDEV_CE (1<<0) /* Ethernet Controllers */ -#define AU1000_ETH0_BASE 0x10500000 -#define AU1000_ETH1_BASE 0x10510000 +#define AU1000_ETH0_BASE 0xB0500000 +#define AU1000_ETH1_BASE 0xB0510000 +#define AU1500_ETH0_BASE 0xB1500000 +#define AU1500_ETH1_BASE 0xB1510000 +#define AU1100_ETH0_BASE 0xB0500000 /* 4 byte offsets from AU1000_ETH_BASE */ #define MAC_CONTROL 0x0 - #define MAC_RX_ENABLE (1<<2) + #define MAC_RX_ENABLE (1<<2) #define MAC_TX_ENABLE (1<<3) - #define MAC_DEF_CHECK (1<<5) + #define MAC_DEF_CHECK (1<<5) #define MAC_SET_BL(X) (((X)&0x3)<<6) #define MAC_AUTO_PAD (1<<8) #define MAC_DISABLE_RETRY (1<<10) @@ -370,7 +476,7 @@ #define MAC_MCAST_LOW 0x10 #define MAC_MII_CNTRL 0x14 #define MAC_MII_BUSY (1<<0) - #define MAC_MII_READ 0 + #define MAC_MII_READ 0 #define MAC_MII_WRITE (1<<1) #define MAC_SET_MII_SELECT_REG(X) (((X)&0x1f)<<6) #define MAC_SET_MII_SELECT_PHY(X) (((X)&0x1f)<<11) @@ -384,11 +490,15 @@ #define MAC_VLAN2_TAG 0x24 /* Ethernet Controller Enable */ -#define MAC0_ENABLE 0x10520000 -#define MAC1_ENABLE 0x10520004 +#define AU1000_MAC0_ENABLE 0xB0520000 +#define AU1000_MAC1_ENABLE 0xB0520004 +#define AU1500_MAC0_ENABLE 0xB1520000 +#define AU1500_MAC1_ENABLE 0xB1520004 +#define AU1100_MAC0_ENABLE 0xB0520000 + #define MAC_EN_CLOCK_ENABLE (1<<0) #define MAC_EN_RESET0 (1<<1) - #define MAC_EN_TOSS (1<<2) + #define MAC_EN_TOSS (0<<2) #define MAC_EN_CACHEABLE (1<<3) #define MAC_EN_RESET1 (1<<4) #define MAC_EN_RESET2 (1<<5) @@ -396,8 +506,8 @@ /* Ethernet Controller DMA Channels */ -#define MAC0_TX_DMA_ADDR 0x14004000 -#define MAC1_TX_DMA_ADDR 0x14004200 +#define MAC0_TX_DMA_ADDR 0xB4004000 +#define MAC1_TX_DMA_ADDR 0xB4004200 /* offsets from MAC_TX_RING_ADDR address */ #define MAC_TX_BUFF0_STATUS 0x0 #define TX_FRAME_ABORTED (1<<0) @@ -427,8 +537,8 @@ #define MAC_TX_BUFF3_ADDR 0x34 #define MAC_TX_BUFF3_LEN 0x38 -#define MAC0_RX_DMA_ADDR 0x14004100 -#define MAC1_RX_DMA_ADDR 0x14004300 +#define MAC0_RX_DMA_ADDR 0xB4004100 +#define MAC1_RX_DMA_ADDR 0xB4004300 /* offsets from MAC_RX_RING_ADDR */ #define MAC_RX_BUFF0_STATUS 0x0 #define RX_FRAME_LEN_MASK 0x3fff @@ -450,7 +560,7 @@ #define RX_FILTER_FAIL (1<<29) #define RX_PACKET_FILTER (1<<30) #define RX_MISSED_FRAME (1<<31) - + #define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \ RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) @@ -468,10 +578,12 @@ /* UARTS 0-3 */ -#define UART0_ADDR 0x11100000 -#define UART1_ADDR 0x11200000 -#define UART2_ADDR 0x11300000 -#define UART3_ADDR 0x11400000 +#define UART0_ADDR 0xB1100000 +#define UART1_ADDR 0xB1200000 +#define UART2_ADDR 0xB1300000 +#define UART3_ADDR 0xB1400000 +#define UART_BASE UART0_ADDR +#define UART_DEBUG_BASE UART2_ADDR #define UART_RX 0 /* Receive buffer */ #define UART_TX 4 /* Transmit buffer */ @@ -482,7 +594,7 @@ #define UART_MCR 0x18 /* Modem Control Register */ #define UART_LSR 0x1C /* Line Status Register */ #define UART_MSR 0x20 /* Modem Status Register */ -#define UART_CLK 0x28 /* Baud Rat4e Clock Divider */ +#define UART_CLK 0x28 /* Baud Rate Clock Divider */ #define UART_MOD_CNTRL 0x100 /* Module Control */ #define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ @@ -566,70 +678,330 @@ /* SSIO */ -#define SSI0_STATUS 0x11600000 -#define SSI0_INT 0x11600004 -#define SSI0_INT_ENABLE 0x11600008 -#define SSI0_CONFIG 0x11600020 -#define SSI0_ADATA 0x11600024 -#define SSI0_CLKDIV 0x11600028 -#define SSI0_CONTROL 0x11600100 +#define SSI0_STATUS 0xB1600000 + #define SSI_STATUS_BF (1<<4) + #define SSI_STATUS_OF (1<<3) + #define SSI_STATUS_UF (1<<2) + #define SSI_STATUS_D (1<<1) + #define SSI_STATUS_B (1<<0) +#define SSI0_INT 0xB1600004 + #define SSI_INT_OI (1<<3) + #define SSI_INT_UI (1<<2) + #define SSI_INT_DI (1<<1) +#define SSI0_INT_ENABLE 0xB1600008 + #define SSI_INTE_OIE (1<<3) + #define SSI_INTE_UIE (1<<2) + #define SSI_INTE_DIE (1<<1) +#define SSI0_CONFIG 0xB1600020 + #define SSI_CONFIG_AO (1<<24) + #define SSI_CONFIG_DO (1<<23) + #define SSI_CONFIG_ALEN_BIT 20 + #define SSI_CONFIG_ALEN_MASK (0x7<<20) + #define SSI_CONFIG_DLEN_BIT 16 + #define SSI_CONFIG_DLEN_MASK (0x7<<16) + #define SSI_CONFIG_DD (1<<11) + #define SSI_CONFIG_AD (1<<10) + #define SSI_CONFIG_BM_BIT 8 + #define SSI_CONFIG_BM_MASK (0x3<<8) + #define SSI_CONFIG_CE (1<<7) + #define SSI_CONFIG_DP (1<<6) + #define SSI_CONFIG_DL (1<<5) + #define SSI_CONFIG_EP (1<<4) +#define SSI0_ADATA 0xB1600024 + #define SSI_AD_D (1<<24) + #define SSI_AD_ADDR_BIT 16 + #define SSI_AD_ADDR_MASK (0xff<<16) + #define SSI_AD_DATA_BIT 0 + #define SSI_AD_DATA_MASK (0xfff<<0) +#define SSI0_CLKDIV 0xB1600028 +#define SSI0_CONTROL 0xB1600100 + #define SSI_CONTROL_CD (1<<1) + #define SSI_CONTROL_E (1<<0) /* SSI1 */ -#define SSI1_STATUS 0x11680000 -#define SSI1_INT 0x11680004 -#define SSI1_INT_ENABLE 0x11680008 -#define SSI1_CONFIG 0x11680020 -#define SSI1_ADATA 0x11680024 -#define SSI1_CLKDIV 0x11680028 -#define SSI1_CONTROL 0x11680100 +#define SSI1_STATUS 0xB1680000 +#define SSI1_INT 0xB1680004 +#define SSI1_INT_ENABLE 0xB1680008 +#define SSI1_CONFIG 0xB1680020 +#define SSI1_ADATA 0xB1680024 +#define SSI1_CLKDIV 0xB1680028 +#define SSI1_ENABLE 0xB1680100 + +/* + * Register content definitions + */ +#define SSI_STATUS_BF (1<<4) +#define SSI_STATUS_OF (1<<3) +#define SSI_STATUS_UF (1<<2) +#define SSI_STATUS_D (1<<1) +#define SSI_STATUS_B (1<<0) + +/* SSI_INT */ +#define SSI_INT_OI (1<<3) +#define SSI_INT_UI (1<<2) +#define SSI_INT_DI (1<<1) + +/* SSI_INTEN */ +#define SSI_INTEN_OIE (1<<3) +#define SSI_INTEN_UIE (1<<2) +#define SSI_INTEN_DIE (1<<1) + +#define SSI_CONFIG_AO (1<<24) +#define SSI_CONFIG_DO (1<<23) +#define SSI_CONFIG_ALEN (7<<20) +#define SSI_CONFIG_DLEN (15<<16) +#define SSI_CONFIG_DD (1<<11) +#define SSI_CONFIG_AD (1<<10) +#define SSI_CONFIG_BM (3<<8) +#define SSI_CONFIG_CE (1<<7) +#define SSI_CONFIG_DP (1<<6) +#define SSI_CONFIG_DL (1<<5) +#define SSI_CONFIG_EP (1<<4) +#define SSI_CONFIG_ALEN_N(N) ((N-1)<<20) +#define SSI_CONFIG_DLEN_N(N) ((N-1)<<16) +#define SSI_CONFIG_BM_HI (0<<8) +#define SSI_CONFIG_BM_LO (1<<8) +#define SSI_CONFIG_BM_CY (2<<8) + +#define SSI_ADATA_D (1<<24) +#define SSI_ADATA_ADDR (0xFF<<16) +#define SSI_ADATA_DATA (0x0FFF) +#define SSI_ADATA_ADDR_N(N) (N<<16) + +#define SSI_ENABLE_CD (1<<1) +#define SSI_ENABLE_E (1<<0) + /* IrDA Controller */ -#define IR_RING_PTR_STATUS 0x11500000 -#define IR_RING_BASE_ADDR_H 0x11500004 -#define IR_RING_BASE_ADDR_L 0x11500008 -#define IR_RING_SIZE 0x1150000C -#define IR_RING_PROMPT 0x11500010 -#define IR_RING_ADDR_CMPR 0x11500014 -#define IR_CONFIG_1 0x11500020 -#define IR_SIR_FLAGS 0x11500024 -#define IR_ENABLE 0x11500028 -#define IR_READ_PHY_CONFIG 0x1150002C -#define IR_WRITE_PHY_CONFIG 0x11500030 -#define IR_MAX_PKT_LEN 0x11500034 -#define IR_RX_BYTE_CNT 0x11500038 -#define IR_CONFIG_2 0x1150003C -#define IR_INTERFACE_CONFIG 0x11500040 +#define IRDA_BASE 0xB0300000 +#define IR_RING_PTR_STATUS (IRDA_BASE+0x00) +#define IR_RING_BASE_ADDR_H (IRDA_BASE+0x04) +#define IR_RING_BASE_ADDR_L (IRDA_BASE+0x08) +#define IR_RING_SIZE (IRDA_BASE+0x0C) +#define IR_RING_PROMPT (IRDA_BASE+0x10) +#define IR_RING_ADDR_CMPR (IRDA_BASE+0x14) +#define IR_INT_CLEAR (IRDA_BASE+0x18) +#define IR_CONFIG_1 (IRDA_BASE+0x20) + #define IR_RX_INVERT_LED (1<<0) + #define IR_TX_INVERT_LED (1<<1) + #define IR_ST (1<<2) + #define IR_SF (1<<3) + #define IR_SIR (1<<4) + #define IR_MIR (1<<5) + #define IR_FIR (1<<6) + #define IR_16CRC (1<<7) + #define IR_TD (1<<8) + #define IR_RX_ALL (1<<9) + #define IR_DMA_ENABLE (1<<10) + #define IR_RX_ENABLE (1<<11) + #define IR_TX_ENABLE (1<<12) + #define IR_LOOPBACK (1<<14) + #define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \ + IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC) +#define IR_SIR_FLAGS (IRDA_BASE+0x24) +#define IR_ENABLE (IRDA_BASE+0x28) + #define IR_RX_STATUS (1<<9) + #define IR_TX_STATUS (1<<10) +#define IR_READ_PHY_CONFIG (IRDA_BASE+0x2C) +#define IR_WRITE_PHY_CONFIG (IRDA_BASE+0x30) +#define IR_MAX_PKT_LEN (IRDA_BASE+0x34) +#define IR_RX_BYTE_CNT (IRDA_BASE+0x38) +#define IR_CONFIG_2 (IRDA_BASE+0x3C) + #define IR_MODE_INV (1<<0) + #define IR_ONE_PIN (1<<1) +#define IR_INTERFACE_CONFIG (IRDA_BASE+0x40) /* GPIO */ -#define TSTATE_STATE_READ 0x11900100 -#define TSTATE_STATE_SET 0x11900100 -#define OUTPUT_STATE_READ 0x11900108 -#define OUTPUT_STATE_SET 0x11900108 -#define OUTPUT_STATE_CLEAR 0x1190010C -#define PIN_STATE 0x11900110 +#define SYS_PINFUNC 0xB190002C + #define SYS_PF_USB (1<<15) /* 2nd USB device/host */ + #define SYS_PF_U3 (1<<14) /* GPIO23/U3TXD */ + #define SYS_PF_U2 (1<<13) /* GPIO22/U2TXD */ + #define SYS_PF_U1 (1<<12) /* GPIO21/U1TXD */ + #define SYS_PF_SRC (1<<11) /* GPIO6/SROMCKE */ + #define SYS_PF_CK5 (1<<10) /* GPIO3/CLK5 */ + #define SYS_PF_CK4 (1<<9) /* GPIO2/CLK4 */ + #define SYS_PF_IRF (1<<8) /* GPIO15/IRFIRSEL */ + #define SYS_PF_UR3 (1<<7) /* GPIO[14:9]/UART3 */ + #define SYS_PF_I2D (1<<6) /* GPIO8/I2SDI */ + #define SYS_PF_I2S (1<<5) /* I2S/GPIO[29:31] */ + #define SYS_PF_NI2 (1<<4) /* NI2/GPIO[24:28] */ + #define SYS_PF_U0 (1<<3) /* U0TXD/GPIO20 */ + #define SYS_PF_RD (1<<2) /* IRTXD/GPIO19 */ + #define SYS_PF_A97 (1<<1) /* AC97/SSL1 */ + #define SYS_PF_S0 (1<<0) /* SSI_0/GPIO[16:18] */ +#define SYS_TRIOUTRD 0xB1900100 +#define SYS_TRIOUTCLR 0xB1900100 +#define SYS_OUTPUTRD 0xB1900108 +#define SYS_OUTPUTSET 0xB1900108 +#define SYS_OUTPUTCLR 0xB190010C +#define SYS_PINSTATERD 0xB1900110 +#define SYS_PININPUTEN 0xB1900110 + +/* GPIO2, Au1500 only */ +#define GPIO2_BASE 0xB1700000 +#define GPIO2_DIR (GPIO2_BASE + 0) +#define GPIO2_DATA_EN (GPIO2_BASE + 8) +#define GPIO2_PIN_STATE (GPIO2_BASE + 0xC) +#define GPIO2_INT_ENABLE (GPIO2_BASE + 0x10) +#define GPIO2_ENABLE (GPIO2_BASE + 0x14) /* Power Management */ -#define PM_SCRATCH_0 0x11900018 -#define PM_SCRATCH_1 0x1190001C -#define PM_WAKEUP_SOURCE_MASK 0x11900034 -#define PM_ENDIANESS 0x11900038 -#define PM_POWERUP_CONTROL 0x1190003C -#define PM_WAKEUP_CAUSE 0x1190005C -#define PM_SLEEP_POWER 0x11900078 -#define PM_SLEEP 0x1190007C +#define SYS_SCRATCH0 0xB1900018 +#define SYS_SCRATCH1 0xB190001C +#define SYS_WAKEMSK 0xB1900034 +#define SYS_ENDIAN 0xB1900038 +#define SYS_POWERCTRL 0xB190003C +#define SYS_WAKESRC 0xB190005C +#define SYS_SLPPWR 0xB1900078 +#define SYS_SLEEP 0xB190007C /* Clock Controller */ -#define FQ_CNTRL_1 0x11900020 -#define FQ_CNTRL_2 0x11900024 -#define CLOCK_SOURCE_CNTRL 0x11900028 -#define CPU_PLL_CNTRL 0x11900060 -#define AUX_PLL_CNTRL 0x11900064 +#define SYS_FREQCTRL0 0xB1900020 + #define SYS_FC_FRDIV2_BIT 22 + #define SYS_FC_FRDIV2_MASK (0xff << FQC2_FRDIV2_BIT) + #define SYS_FC_FE2 (1<<21) + #define SYS_FC_FS2 (1<<20) + #define SYS_FC_FRDIV1_BIT 12 + #define SYS_FC_FRDIV1_MASK (0xff << FQC2_FRDIV1_BIT) + #define SYS_FC_FE1 (1<<11) + #define SYS_FC_FS1 (1<<10) + #define SYS_FC_FRDIV0_BIT 2 + #define SYS_FC_FRDIV0_MASK (0xff << FQC2_FRDIV0_BIT) + #define SYS_FC_FE0 (1<<1) + #define SYS_FC_FS0 (1<<0) +#define SYS_FREQCTRL1 0xB1900024 + #define SYS_FC_FRDIV5_BIT 22 + #define SYS_FC_FRDIV5_MASK (0xff << FQC2_FRDIV5_BIT) + #define SYS_FC_FE5 (1<<21) + #define SYS_FC_FS5 (1<<20) + #define SYS_FC_FRDIV4_BIT 12 + #define SYS_FC_FRDIV4_MASK (0xff << FQC2_FRDIV4_BIT) + #define SYS_FC_FE4 (1<<11) + #define SYS_FC_FS4 (1<<10) + #define SYS_FC_FRDIV3_BIT 2 + #define SYS_FC_FRDIV3_MASK (0xff << FQC2_FRDIV3_BIT) + #define SYS_FC_FE3 (1<<1) + #define SYS_FC_FS3 (1<<0) +#define SYS_CLKSRC 0xB1900028 + #define SYS_CS_ME1_BIT 27 + #define SYS_CS_ME1_MASK (0x7<<CSC_ME1_BIT) + #define SYS_CS_DE1 (1<<26) + #define SYS_CS_CE1 (1<<25) + #define SYS_CS_ME0_BIT 22 + #define SYS_CS_ME0_MASK (0x7<<CSC_ME0_BIT) + #define SYS_CS_DE0 (1<<21) + #define SYS_CS_CE0 (1<<20) + #define SYS_CS_MI2_BIT 17 + #define SYS_CS_MI2_MASK (0x7<<CSC_MI2_BIT) + #define SYS_CS_DI2 (1<<16) + #define SYS_CS_CI2 (1<<15) + #define SYS_CS_MUH_BIT 12 + #define SYS_CS_MUH_MASK (0x7<<CSC_MUH_BIT) + #define SYS_CS_DUH (1<<11) + #define SYS_CS_CUH (1<<10) + #define SYS_CS_MUD_BIT 7 + #define SYS_CS_MUD_MASK (0x7<<CSC_MUD_BIT) + #define SYS_CS_DUD (1<<6) + #define SYS_CS_CUD (1<<5) + #define SYS_CS_MIR_BIT 2 + #define SYS_CS_MIR_MASK (0x7<<CSC_MIR_BIT) + #define SYS_CS_DIR (1<<1) + #define SYS_CS_CIR (1<<0) + + #define SYS_CS_MUX_AUX 0x1 + #define SYS_CS_MUX_FQ0 0x2 + #define SYS_CS_MUX_FQ1 0x3 + #define SYS_CS_MUX_FQ2 0x4 + #define SYS_CS_MUX_FQ3 0x5 + #define SYS_CS_MUX_FQ4 0x6 + #define SYS_CS_MUX_FQ5 0x7 +#define SYS_CPUPLL 0xB1900060 +#define SYS_AUXPLL 0xB1900064 /* AC97 Controller */ -#define AC97_CONFIG 0x10000000 -#define AC97_STATUS 0x10000004 -#define AC97_DATA 0x10000008 -#define AC97_CMD 0x1000000C -#define AC97_CNTRL 0x10000010 +#define AC97C_CONFIG 0xB0000000 + #define AC97C_RECV_SLOTS_BIT 13 + #define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT) + #define AC97C_XMIT_SLOTS_BIT 3 + #define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT) + #define AC97C_SG (1<<2) + #define AC97C_SYNC (1<<1) + #define AC97C_RESET (1<<0) +#define AC97C_STATUS 0xB0000004 + #define AC97C_XU (1<<11) + #define AC97C_XO (1<<10) + #define AC97C_RU (1<<9) + #define AC97C_RO (1<<8) + #define AC97C_READY (1<<7) + #define AC97C_CP (1<<6) + #define AC97C_TR (1<<5) + #define AC97C_TE (1<<4) + #define AC97C_TF (1<<3) + #define AC97C_RR (1<<2) + #define AC97C_RE (1<<1) + #define AC97C_RF (1<<0) +#define AC97C_DATA 0xB0000008 +#define AC97C_CMD 0xB000000C + #define AC97C_WD_BIT 16 + #define AC97C_READ (1<<7) + #define AC97C_INDEX_MASK 0x7f +#define AC97C_CNTRL 0xB0000010 + #define AC97C_RS (1<<1) + #define AC97C_CE (1<<0) + +#ifdef CONFIG_SOC_AU1500 +/* Au1500 PCI Controller */ +#define Au1500_CFG_BASE 0xB4005000 // virtual, kseg0 addr +#define Au1500_PCI_CMEM (Au1500_CFG_BASE + 0) +#define Au1500_PCI_CFG (Au1500_CFG_BASE + 4) + #define PCI_ERROR ((1<<22) | (1<<23) | (1<<24) | (1<<25) | (1<<26) | (1<<27)) +#define Au1500_PCI_B2BMASK_CCH (Au1500_CFG_BASE + 8) +#define Au1500_PCI_B2B0_VID (Au1500_CFG_BASE + 0xC) +#define Au1500_PCI_B2B1_ID (Au1500_CFG_BASE + 0x10) +#define Au1500_PCI_MWMASK_DEV (Au1500_CFG_BASE + 0x14) +#define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18) +#define Au1500_PCI_ERR_ADDR (Au1500_CFG_BASE + 0x1C) +#define Au1500_PCI_SPEC_INTACK (Au1500_CFG_BASE + 0x20) +#define Au1500_PCI_ID (Au1500_CFG_BASE + 0x100) +#define Au1500_PCI_STATCMD (Au1500_CFG_BASE + 0x104) +#define Au1500_PCI_CLASSREV (Au1500_CFG_BASE + 0x108) +#define Au1500_PCI_HDRTYPE (Au1500_CFG_BASE + 0x10C) +#define Au1500_PCI_MBAR (Au1500_CFG_BASE + 0x110) + +#define Au1500_PCI_HDR 0xB4005100 // virtual, kseg0 addr + +/* All of our structures, like pci resource, have 32 bit members. + * Drivers are expected to do an ioremap on the PCI MEM resource, but it's + * hard to store 0x4 0000 0000 in a 32 bit type. We require a small patch + * to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and + * (u32)Au1500_PCI_MEM_END and change those to the full 36 bit PCI MEM + * addresses. For PCI IO, it's simpler because we get to do the ioremap + * ourselves and then adjust the device's resources. + */ +#define Au1500_EXT_CFG 0x600000000 +#define Au1500_EXT_CFG_TYPE1 0x680000000 +#define Au1500_PCI_IO_START 0x500000000 +#define Au1500_PCI_IO_END 0x5000FFFFF +#define Au1500_PCI_MEM_START 0x440000000 +#define Au1500_PCI_MEM_END 0x443FFFFFF + +#define PCI_IO_START (Au1500_PCI_IO_START + 0x300) +#define PCI_IO_END (Au1500_PCI_IO_END) +#define PCI_MEM_START (Au1500_PCI_MEM_START) +#define PCI_MEM_END (Au1500_PCI_MEM_END) +#define PCI_FIRST_DEVFN (0<<3) +#define PCI_LAST_DEVFN (19<<3) + +#endif + +#if defined(CONFIG_SOC_AU1100) || (defined(CONFIG_SOC_AU1000) && !defined(CONFIG_MIPS_PB1000)) +/* no PCI bus controller */ +#define PCI_IO_START 0 +#define PCI_IO_END 0 +#define PCI_MEM_START 0 +#define PCI_MEM_END 0 +#define PCI_FIRST_DEVFN 0 +#define PCI_LAST_DEVFN 0 +#endif #endif diff -Nru a/include/asm-mips/au1000_dma.h b/include/asm-mips/au1000_dma.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/au1000_dma.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,433 @@ +/* + * BRIEF MODULE DESCRIPTION + * Defines for using and allocating dma channels on the Alchemy + * Au1000 mips processor. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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. + * + */ +#ifndef __ASM_AU1000_DMA_H +#define __ASM_AU1000_DMA_H + +#include <linux/config.h> +#include <asm/io.h> /* need byte IO */ +#include <linux/spinlock.h> /* And spinlocks */ +#include <linux/delay.h> +#include <asm/system.h> + +#define NUM_AU1000_DMA_CHANNELS 8 + +/* DMA Channel Base Addresses */ +#define DMA_CHANNEL_BASE 0xB4002000 +#define DMA_CHANNEL_LEN 0x00000100 + +/* DMA Channel Register Offsets */ +#define DMA_MODE_SET 0x00000000 +#define DMA_MODE_READ DMA_MODE_SET +#define DMA_MODE_CLEAR 0x00000004 +/* DMA Mode register bits follow */ +#define DMA_DAH_MASK (0x0f << 20) +#define DMA_DID_BIT 16 +#define DMA_DID_MASK (0x0f << DMA_DID_BIT) +#define DMA_BE (1<<13) +#define DMA_DR (1<<12) +#define DMA_TS8 (1<<11) +#define DMA_DW_BIT 9 +#define DMA_DW_MASK (0x03 << DMA_DW_BIT) +#define DMA_DW8 (0 << DMA_DW_BIT) +#define DMA_DW16 (1 << DMA_DW_BIT) +#define DMA_DW32 (2 << DMA_DW_BIT) +#define DMA_NC (1<<8) +#define DMA_IE (1<<7) +#define DMA_HALT (1<<6) +#define DMA_GO (1<<5) +#define DMA_AB (1<<4) +#define DMA_D1 (1<<3) +#define DMA_BE1 (1<<2) +#define DMA_D0 (1<<1) +#define DMA_BE0 (1<<0) + +#define DMA_PERIPHERAL_ADDR 0x00000008 +#define DMA_BUFFER0_START 0x0000000C +#define DMA_BUFFER1_START 0x00000014 +#define DMA_BUFFER0_COUNT 0x00000010 +#define DMA_BUFFER1_COUNT 0x00000018 +#define DMA_BAH_BIT 16 +#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT) +#define DMA_COUNT_BIT 0 +#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT) + +/* DMA Device ID's follow */ +enum { + DMA_ID_UART0_TX = 0, + DMA_ID_UART0_RX, + DMA_ID_GP04, + DMA_ID_GP05, + DMA_ID_AC97C_TX, + DMA_ID_AC97C_RX, + DMA_ID_UART3_TX, + DMA_ID_UART3_RX, + DMA_ID_USBDEV_EP0_RX, + DMA_ID_USBDEV_EP0_TX, + DMA_ID_USBDEV_EP2_TX, + DMA_ID_USBDEV_EP3_TX, + DMA_ID_USBDEV_EP4_RX, + DMA_ID_USBDEV_EP5_RX, + DMA_ID_I2S_TX, + DMA_ID_I2S_RX, + DMA_NUM_DEV +}; + +struct dma_chan { + int dev_id; // this channel is allocated if >=0, free otherwise + unsigned int io; + const char *dev_str; + int irq; + void *irq_dev; + unsigned int fifo_addr; + unsigned int mode; +}; + +/* These are in arch/mips/au1000/common/dma.c */ +extern struct dma_chan au1000_dma_table[]; +extern int request_au1000_dma(int dev_id, + const char *dev_str, + void (*irqhandler)(int, void *, + struct pt_regs *), + unsigned long irqflags, + void *irq_dev_id); +extern void free_au1000_dma(unsigned int dmanr); +extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos, + int length, int *eof, void *data); +extern void dump_au1000_dma_channel(unsigned int dmanr); +extern spinlock_t au1000_dma_spin_lock; + + +static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr) +{ + if (dmanr > NUM_AU1000_DMA_CHANNELS + || au1000_dma_table[dmanr].dev_id < 0) + return NULL; + return &au1000_dma_table[dmanr]; +} + +static __inline__ unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&au1000_dma_spin_lock, flags); + return flags; +} + +static __inline__ void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&au1000_dma_spin_lock, flags); +} + +/* + * Set the DMA buffer enable bits in the mode register. + */ +static __inline__ void enable_dma_buffer0(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(DMA_BE0, chan->io + DMA_MODE_SET); +} +static __inline__ void enable_dma_buffer1(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(DMA_BE1, chan->io + DMA_MODE_SET); +} +static __inline__ void enable_dma_buffers(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); +} + +static __inline__ void start_dma(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + + au_writel(DMA_GO, chan->io + DMA_MODE_SET); +} + +#define DMA_HALT_POLL 0x5000 + +static __inline__ void halt_dma(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + int i; + if (!chan) + return; + + au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); + // poll the halt bit + for (i = 0; i < DMA_HALT_POLL; i++) + if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) + break; + if (i == DMA_HALT_POLL) + printk(KERN_INFO "halt_dma: HALT poll expired!\n"); +} + + +static __inline__ void disable_dma(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + + halt_dma(dmanr); + + // now we can disable the buffers + au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); +} + +static __inline__ int dma_halted(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 1; + return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; +} + +/* initialize a DMA channel */ +static __inline__ void init_dma(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + u32 mode; + if (!chan) + return; + + disable_dma(dmanr); + + // set device FIFO address + au_writel(PHYSADDR(chan->fifo_addr), + chan->io + DMA_PERIPHERAL_ADDR); + + mode = chan->mode | (chan->dev_id << DMA_DID_BIT); + if (chan->irq) + mode |= DMA_IE; + + au_writel(~mode, chan->io + DMA_MODE_CLEAR); + au_writel(mode, chan->io + DMA_MODE_SET); +} + +/* + * set mode for a specific DMA channel + */ +static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + /* + * set_dma_mode is only allowed to change endianess, direction, + * transfer size, device FIFO width, and coherency settings. + * Make sure anything else is masked off. + */ + mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC); + chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC); + chan->mode |= mode; +} + +static __inline__ unsigned int get_dma_mode(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + return chan->mode; +} + +static __inline__ int get_dma_active_buffer(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return -1; + return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; +} + + +/* + * set the device FIFO address for a specific DMA channel - only + * applicable to GPO4 and GPO5. All the other devices have fixed + * FIFO addresses. + */ +static __inline__ void set_dma_fifo_addr(unsigned int dmanr, + unsigned int a) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + + if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) + return; + + au_writel(PHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); +} + +/* + * Clear the DMA buffer done bits in the mode register. + */ +static __inline__ void clear_dma_done0(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); +} +static __inline__ void clear_dma_done1(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); +} + +/* + * This does nothing - not applicable to Au1000 DMA. + */ +static __inline__ void set_dma_page(unsigned int dmanr, char pagenr) +{ +} + +/* + * Set Buffer 0 transfer address for specific DMA channel. + */ +static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(a, chan->io + DMA_BUFFER0_START); +} + +/* + * Set Buffer 1 transfer address for specific DMA channel. + */ +static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + au_writel(a, chan->io + DMA_BUFFER1_START); +} + + +/* + * Set Buffer 0 transfer size (max 64k) for a specific DMA channel. + */ +static __inline__ void set_dma_count0(unsigned int dmanr, + unsigned int count) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + count &= DMA_COUNT_MASK; + au_writel(count, chan->io + DMA_BUFFER0_COUNT); +} + +/* + * Set Buffer 1 transfer size (max 64k) for a specific DMA channel. + */ +static __inline__ void set_dma_count1(unsigned int dmanr, + unsigned int count) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + count &= DMA_COUNT_MASK; + au_writel(count, chan->io + DMA_BUFFER1_COUNT); +} + +/* + * Set both buffer transfer sizes (max 64k) for a specific DMA channel. + */ +static __inline__ void set_dma_count(unsigned int dmanr, + unsigned int count) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return; + count &= DMA_COUNT_MASK; + au_writel(count, chan->io + DMA_BUFFER0_COUNT); + au_writel(count, chan->io + DMA_BUFFER1_COUNT); +} + +/* + * Returns which buffer has its done bit set in the mode register. + * Returns -1 if neither or both done bits set. + */ +static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); +} + + +/* + * Returns the DMA channel's Buffer Done IRQ number. + */ +static __inline__ int get_dma_done_irq(unsigned int dmanr) +{ + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return -1; + + return chan->irq; +} + +/* + * Get DMA residue count. Returns the number of _bytes_ left to transfer. + */ +static __inline__ int get_dma_residue(unsigned int dmanr) +{ + int curBufCntReg, count; + struct dma_chan *chan = get_dma_chan(dmanr); + if (!chan) + return 0; + + curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? + DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT; + + count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; + + if ((chan->mode & DMA_DW_MASK) == DMA_DW16) + count <<= 1; + else if ((chan->mode & DMA_DW_MASK) == DMA_DW32) + count <<= 2; + + return count; +} + +#endif /* __ASM_AU1000_DMA_H */ diff -Nru a/include/asm-mips/au1000_gpio.h b/include/asm-mips/au1000_gpio.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/au1000_gpio.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,56 @@ +/* + * FILE NAME au1000_gpio.h + * + * BRIEF MODULE DESCRIPTION + * API to Alchemy Au1000 GPIO device. + * + * Author: MontaVista Software, Inc. <source@mvista.com> + * Steve Longerbeam <stevel@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 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. + */ + +#ifndef __AU1000_GPIO_H +#define __AU1000_GPIO_H + +#include <linux/ioctl.h> + +#define AU1000GPIO_IOC_MAGIC 'A' + +#define AU1000GPIO_IN _IOR (AU1000GPIO_IOC_MAGIC, 0, int) +#define AU1000GPIO_SET _IOW (AU1000GPIO_IOC_MAGIC, 1, int) +#define AU1000GPIO_CLEAR _IOW (AU1000GPIO_IOC_MAGIC, 2, int) +#define AU1000GPIO_OUT _IOW (AU1000GPIO_IOC_MAGIC, 3, int) +#define AU1000GPIO_TRISTATE _IOW (AU1000GPIO_IOC_MAGIC, 4, int) +#define AU1000GPIO_AVAIL_MASK _IOR (AU1000GPIO_IOC_MAGIC, 5, int) + +#ifdef __KERNEL__ +extern u32 get_au1000_avail_gpio_mask(void); +extern int au1000gpio_tristate(u32 data); +extern int au1000gpio_in(u32 *data); +extern int au1000gpio_set(u32 data); +extern int au1000gpio_clear(u32 data); +extern int au1000gpio_out(u32 data); +#endif + +#endif diff -Nru a/include/asm-mips/au1000_pcmcia.h b/include/asm-mips/au1000_pcmcia.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/au1000_pcmcia.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,111 @@ +/* + * + * Alchemy Semi Au1000 pcmcia driver include file + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#ifndef __ASM_AU1000_PCMCIA_H +#define __ASM_AU1000_PCMCIA_H + + +#define AU1000_PCMCIA_POLL_PERIOD (2*HZ) +#define AU1000_PCMCIA_IO_SPEED (255) +#define AU1000_PCMCIA_MEM_SPEED (300) + +#define AU1X_SOCK0_IO 0xF00000000 +#define AU1X_SOCK0_PHYS_ATTR 0xF40000000 +#define AU1X_SOCK0_PHYS_MEM 0xF80000000 + +/* pcmcia socket 1 needs external glue logic so the memory map + * differs from board to board. + */ +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) +#define AU1X_SOCK1_IO 0xF08000000 +#define AU1X_SOCK1_PHYS_ATTR 0xF48000000 +#define AU1X_SOCK1_PHYS_MEM 0xF88000000 +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) +#define AU1X_SOCK1_IO 0xF04000000 +#define AU1X_SOCK1_PHYS_ATTR 0xF44000000 +#define AU1X_SOCK1_PHYS_MEM 0xF84000000 +#endif + +struct pcmcia_state { + unsigned detect: 1, + ready: 1, + wrprot: 1, + bvd1: 1, + bvd2: 1, + vs_3v: 1, + vs_Xv: 1; +}; + +struct pcmcia_configure { + unsigned sock: 8, + vcc: 8, + vpp: 8, + output: 1, + speaker: 1, + reset: 1; +}; + +struct pcmcia_irq_info { + unsigned int sock; + unsigned int irq; +}; + + +struct au1000_pcmcia_socket { + socket_state_t cs_state; + struct pcmcia_state k_state; + unsigned int irq; + void (*handler)(void *, unsigned int); + void *handler_info; + pccard_io_map io_map[MAX_IO_WIN]; + pccard_mem_map mem_map[MAX_WIN]; + u32 virt_io; + ioaddr_t phys_attr, phys_mem; + unsigned short speed_io, speed_attr, speed_mem; +}; + +struct pcmcia_init { + void (*handler)(int irq, void *dev, struct pt_regs *regs); +}; + +struct pcmcia_low_level { + int (*init)(struct pcmcia_init *); + int (*shutdown)(void); + int (*socket_state)(unsigned sock, struct pcmcia_state *); + int (*get_irq_info)(struct pcmcia_irq_info *); + int (*configure_socket)(const struct pcmcia_configure *); +}; + +#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) +extern struct pcmcia_low_level pb1x00_pcmcia_ops; +#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) +extern struct pcmcia_low_level db1x00_pcmcia_ops; +#else +error unknown Au1000 board +#endif + +#endif /* __ASM_AU1000_PCMCIA_H */ diff -Nru a/include/asm-mips/au1000_usbdev.h b/include/asm-mips/au1000_usbdev.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/au1000_usbdev.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,73 @@ +/* + * BRIEF MODULE DESCRIPTION + * Au1000 USB Device-Side Driver + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * 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. + */ + +#define USBDEV_REV 0x0110 // BCD +#define USBDEV_EP0_MAX_PACKET_SIZE 64 + +typedef enum { + ATTACHED = 0, + POWERED, + DEFAULT, + ADDRESS, + CONFIGURED +} usbdev_state_t; + +typedef enum { + CB_NEW_STATE = 0, + CB_PKT_COMPLETE +} usbdev_cb_type_t; + + +typedef struct usbdev_pkt { + int ep_addr; // ep addr this packet routed to + int size; // size of payload in bytes + unsigned status; // packet status + struct usbdev_pkt* next; // function layer can't touch this + u8 payload[0]; // the payload +} usbdev_pkt_t; + +#define PKT_STATUS_ACK (1<<0) +#define PKT_STATUS_NAK (1<<1) +#define PKT_STATUS_SU (1<<2) + +extern int usbdev_init(struct usb_device_descriptor* dev_desc, + struct usb_config_descriptor* config_desc, + struct usb_interface_descriptor* if_desc, + struct usb_endpoint_descriptor* ep_desc, + struct usb_string_descriptor* str_desc[], + void (*cb)(usbdev_cb_type_t, unsigned long, void *), + void* cb_data); + +extern void usbdev_exit(void); + +extern int usbdev_alloc_packet (int ep_addr, int data_size, + usbdev_pkt_t** pkt); +extern int usbdev_send_packet (int ep_addr, usbdev_pkt_t* pkt); +extern int usbdev_receive_packet(int ep_addr, usbdev_pkt_t** pkt); +extern int usbdev_get_byte_count(int ep_addr); diff -Nru a/include/asm-mips/baget/baget.h b/include/asm-mips/baget/baget.h --- a/include/asm-mips/baget/baget.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/baget/baget.h Fri Jun 27 14:19:57 2003 @@ -1,4 +1,4 @@ -/* $Id$ +/* * baget.h: Definitions specific to Baget/MIPS machines. * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov @@ -9,13 +9,13 @@ #include "vic.h" #include "vac.h" -#define VIC_BASE 0xBFFC0000 +#define VIC_BASE 0xBFFC0000 #define VAC_BASE 0xBFFD0000 /* Baget interrupt registers and their sizes */ -struct baget_int_reg { +struct baget_int_reg { unsigned long address; int size; /* in bytes */ }; @@ -43,8 +43,8 @@ #define BAGET_IRQ_MASK(x) ((NR_IRQS-1) & (x)) #define BAGET_FPU_IRQ 0x26 -#define BAGET_VIC_TIMER_IRQ 0x32 -#define BAGET_VAC_TIMER_IRQ 0x36 +#define BAGET_VIC_TIMER_IRQ 0x32 +#define BAGET_VAC_TIMER_IRQ 0x36 #define BAGET_BSM_IRQ 0x3C #define BAGET_LANCE_MEM_BASE 0xfcf10000 diff -Nru a/include/asm-mips/baget/vac.h b/include/asm-mips/baget/vac.h --- a/include/asm-mips/baget/vac.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/baget/vac.h Fri Jun 27 14:19:55 2003 @@ -1,12 +1,11 @@ -/* $Id$ - * +/* * vac.h: Various VIC controller defines. The VIC is a VME controller * used in Baget/MIPS series. * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ -#ifndef _MIPS_VAC_H -#define _MIPS_VAC_H +#ifndef _ASM_VAC_H +#define _ASM_VAC_H #define VAC_SLSEL1_MASK 0x000 #define VAC_SLSEL1_BASE 0x100 @@ -22,8 +21,8 @@ #define VAC_A24_MASK (0x3f<<9) #define VAC_A24_D32_ENABLE (1<<8) #define VAC_A24_A24_CACHINH (1<<7) -#define VAC_A24_A16D32_ENABLE (1<<6) -#define VAC_A24_A16D32 (1<<5) +#define VAC_A24_A16D32_ENABLE (1<<6) +#define VAC_A24_A16D32 (1<<5) #define VAC_A24_DATAPATH (1<<4) #define VAC_A24_IO_CACHINH (1<<3) #define VAC_REG1 0x900 @@ -197,13 +196,13 @@ #define VAC_ID 0x2900 -#ifndef __LANGUAGE_ASSEMBLY__ +#ifndef __ASSEMBLY__ #define vac_inb(p) (*(volatile unsigned char *)(VAC_BASE + (p))) #define vac_outb(v,p) (*((volatile unsigned char *)(VAC_BASE + (p))) = v) #define vac_inw(p) (*(volatile unsigned short*)(VAC_BASE + (p))) #define vac_outw(v,p) (*((volatile unsigned short*)(VAC_BASE + (p))) = v) -#endif /* __LANGUAGE_ASSEMBLY__ */ +#endif /* !__ASSEMBLY__ */ -#endif /* !(_MIPS_VAC_H) */ +#endif /* _ASM_VAC_H */ diff -Nru a/include/asm-mips/baget/vic.h b/include/asm-mips/baget/vic.h --- a/include/asm-mips/baget/vic.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/baget/vic.h Fri Jun 27 14:19:53 2003 @@ -1,12 +1,11 @@ -/* $Id$ - * +/* * vic.h: Various VIC controller defines. The VIC is an interrupt controller * used in Baget/MIPS series. * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov */ -#ifndef _MIPS_VIC_H -#define _MIPS_VIC_H +#ifndef _ASM_BAGET_VIC_H +#define _ASM_BAGET_VIC_H #define VIC_VME_II 0x3 #define VIC_VME_INT1 0x7 @@ -168,10 +167,10 @@ #define VIC_SSxCR1_TF1(x) ((x)&0xf) #define VIC_RELEASE 0xD3 #define VIC_RELEASE_BLKXFER_BLEN(x) ((x)&0x1f) -#define VIC_RELEASE_ROR (0<<6) -#define VIC_RELEASE_RWD (1<<6) -#define VIC_RELEASE_ROC (2<<6) -#define VIC_RELEASE_BCAP (3<<6) +#define VIC_RELEASE_ROR (0<<6) +#define VIC_RELEASE_RWD (1<<6) +#define VIC_RELEASE_ROC (2<<6) +#define VIC_RELEASE_BCAP (3<<6) #define VIC_BXFER_CTRL 0xD7 #define VIC_BXFER_CTRL_MODULE (1<<7) #define VIC_BXFER_CTRL_LOCAL (1<<6) @@ -183,11 +182,11 @@ #define VIC_BXFER_LEN_HI 0xDF #define VIC_SYS_RESET 0xE3 -#ifndef __LANGUAGE_ASSEMBLY__ +#ifndef __ASSEMBLY__ #define vic_inb(p) (*(volatile unsigned char *)(VIC_BASE + (p))) #define vic_outb(v,p) (*((volatile unsigned char *)(VIC_BASE + (p))) = v) -#endif /* __LANGUAGE_ASSEMBLY__ */ +#endif /* !__ASSEMBLY__ */ -#endif /* !(_MIPS_VIC_H) */ +#endif /* _ASM_BAGET_VIC_H */ diff -Nru a/include/asm-mips/bcache.h b/include/asm-mips/bcache.h --- a/include/asm-mips/bcache.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-mips/bcache.h Fri Jun 27 14:20:01 2003 @@ -3,8 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 1997, 1999, 2000 by Ralf Baechle - * Copyright (c) 2000 by Silicon Graphics, Inc. + * Copyright (c) 1997, 1999 by Ralf Baechle + * Copyright (c) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_BCACHE_H #define _ASM_BCACHE_H @@ -28,22 +28,22 @@ extern struct bcache_ops *bcops; -extern inline void bc_enable(void) +static inline void bc_enable(void) { bcops->bc_enable(); } -extern inline void bc_disable(void) +static inline void bc_disable(void) { bcops->bc_disable(); } -extern inline void bc_wback_inv(unsigned long page, unsigned long size) +static inline void bc_wback_inv(unsigned long page, unsigned long size) { bcops->bc_wback_inv(page, size); } -extern inline void bc_inv(unsigned long page, unsigned long size) +static inline void bc_inv(unsigned long page, unsigned long size) { bcops->bc_inv(page, size); } diff -Nru a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h --- a/include/asm-mips/bitops.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/bitops.h Fri Jun 27 14:19:53 2003 @@ -9,42 +9,49 @@ #ifndef _ASM_BITOPS_H #define _ASM_BITOPS_H +#include <linux/config.h> +#include <linux/compiler.h> #include <linux/types.h> #include <asm/byteorder.h> /* sigh ... */ +#if (_MIPS_SZLONG == 32) +#define SZLONG_LOG 5 +#define SZLONG_MASK 31UL +#elif (_MIPS_SZLONG == 64) +#define SZLONG_LOG 6 +#define SZLONG_MASK 63UL +#endif + #ifdef __KERNEL__ #include <asm/sgidefs.h> #include <asm/system.h> -#include <linux/config.h> /* * clear_bit() doesn't provide any barrier for the compiler. */ -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() /* * Only disable interrupt for kernel mode stuff to keep usermode stuff * that dares to use kernel include files alive. */ -#define __bi_flags unsigned long flags -#define __bi_cli() local_irq_disable() -#define __bi_save_flags(x) local_save_flags(x) -#define __bi_save_and_cli(x) local_irq_save(x) -#define __bi_restore_flags(x) local_irq_restore(x) +#define __bi_flags unsigned long flags +#define __bi_cli() local_irq_disable() +#define __bi_save_flags(x) local_save_flags(x) +#define __bi_local_irq_save(x) local_irq_save(x) +#define __bi_local_irq_restore(x) local_irq_restore(x) #else #define __bi_flags #define __bi_cli() #define __bi_save_flags(x) -#define __bi_save_and_cli(x) -#define __bi_restore_flags(x) +#define __bi_local_irq_save(x) +#define __bi_local_irq_restore(x) #endif /* __KERNEL__ */ #ifdef CONFIG_CPU_HAS_LLSC -#include <asm/mipsregs.h> - /* * These functions for MIPS ISA > 1 are interrupt and SMP proof and * interrupt friendly @@ -60,8 +67,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void -set_bit(int nr, volatile void *addr) +static __inline__ void set_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp; @@ -84,7 +90,7 @@ * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __set_bit(int nr, volatile void * addr) +static __inline__ void __set_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 5); @@ -101,8 +107,7 @@ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -extern __inline__ void -clear_bit(int nr, volatile void *addr) +static __inline__ void clear_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp; @@ -117,6 +122,22 @@ } /* + * __clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * Unlike clear_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __clear_bit(int nr, volatile unsigned long * addr) +{ + unsigned long * m = ((unsigned long *) addr) + (nr >> 5); + + *m &= ~(1UL << (nr & 31)); +} + +/* * change_bit - Toggle a bit in memory * @nr: Bit to clear * @addr: Address to start counting from @@ -125,8 +146,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void -change_bit(int nr, volatile void *addr) +static __inline__ void change_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp; @@ -142,14 +162,14 @@ /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __change_bit(int nr, volatile void * addr) +static __inline__ void __change_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 5); @@ -161,14 +181,14 @@ * @nr: Bit to set * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int -test_and_set_bit(int nr, volatile void *addr) +static __inline__ int test_and_set_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); - unsigned long temp, res; + unsigned long temp; + int res; __asm__ __volatile__( ".set\tnoreorder\t\t# test_and_set_bit\n" @@ -177,6 +197,9 @@ "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x1f)), "m" (*m) @@ -190,14 +213,15 @@ * @nr: Bit to set * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -209,14 +233,13 @@ /* * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int -test_and_clear_bit(int nr, volatile void *addr) +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp, res; @@ -229,6 +252,9 @@ "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x1f)), "m" (*m) @@ -239,17 +265,18 @@ /* * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +static __inline__ int __test_and_clear_bit(int nr, + volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask, retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -261,14 +288,13 @@ /* * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int -test_and_change_bit(int nr, volatile void *addr) +static __inline__ int test_and_change_bit(int nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 5); unsigned long temp, res; @@ -280,6 +306,9 @@ "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x1f)), "m" (*m) @@ -290,17 +319,19 @@ /* * __test_and_change_bit - Change a bit and return its old value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) +static __inline__ int __test_and_change_bit(int nr, + volatile unsigned long *addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -322,17 +353,17 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void set_bit(int nr, volatile void * addr) +static __inline__ void set_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); *a |= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); } /* @@ -344,10 +375,10 @@ * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __set_bit(int nr, volatile void * addr) +static __inline__ void __set_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -364,51 +395,61 @@ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -extern __inline__ void clear_bit(int nr, volatile void * addr) +static __inline__ void clear_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); + *a &= ~mask; + __bi_local_irq_restore(flags); +} + +static __inline__ void __clear_bit(int nr, volatile unsigned long * addr) +{ + volatile unsigned long *a = addr; + unsigned long mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); *a &= ~mask; - __bi_restore_flags(flags); } /* * change_bit - Toggle a bit in memory - * @nr: Bit to clear + * @nr: Bit to change * @addr: Address to start counting from * * change_bit() is atomic and may not be reordered. * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void change_bit(int nr, volatile void * addr) +static __inline__ void change_bit(int nr, volatile unsigned long * addr) { - int mask; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); *a ^= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); } /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __change_bit(int nr, volatile void * addr) +static __inline__ void __change_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 5); @@ -420,21 +461,22 @@ * @nr: Bit to set * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int test_and_set_bit(int nr, volatile void * addr) +static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a |= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); return retval; } @@ -444,14 +486,15 @@ * @nr: Bit to set * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_set_bit(int nr, volatile void * addr) +static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -463,41 +506,44 @@ /* * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int test_and_clear_bit(int nr, volatile void * addr) +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a &= ~mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); return retval; } /* * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +static __inline__ int __test_and_clear_bit(int nr, + volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -509,41 +555,43 @@ /* * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ int test_and_change_bit(int nr, volatile void * addr) +static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask, retval; __bi_flags; a += nr >> 5; mask = 1 << (nr & 0x1f); - __bi_save_and_cli(flags); + __bi_local_irq_save(flags); retval = (mask & *a) != 0; *a ^= mask; - __bi_restore_flags(flags); + __bi_local_irq_restore(flags); return retval; } /* * __test_and_change_bit - Change a bit and return its old value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int __test_and_change_bit(int nr, volatile void * addr) +static __inline__ int __test_and_change_bit(int nr, + volatile unsigned long * addr) { - int mask, retval; - volatile int *a = addr; + volatile unsigned long *a = addr; + unsigned long mask; + int retval; a += nr >> 5; mask = 1 << (nr & 0x1f); @@ -556,7 +604,7 @@ #undef __bi_flags #undef __bi_cli #undef __bi_save_flags -#undef __bi_restore_flags +#undef __bi_local_irq_restore #endif /* MIPS I */ @@ -565,202 +613,80 @@ * @nr: bit number to test * @addr: Address to start counting from */ -extern __inline__ int test_bit(int nr, volatile void *addr) +static inline int test_bit(int nr, const volatile unsigned long *addr) { - return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0; + return 1UL & (((const volatile unsigned long *) addr)[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK)); } -#ifndef __MIPSEB__ - -/* Little endian versions. */ - /* - * find_first_zero_bit - find the first zero bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search + * ffz - find first zero in word. + * @word: The word to search * - * Returns the bit-number of the first zero bit, not the number of the byte - * containing a bit. + * Undefined if no zero exists, so code should check against ~0UL first. */ -extern __inline__ int find_first_zero_bit (void *addr, unsigned size) +static __inline__ unsigned long ffz(unsigned long word) { - unsigned long dummy; - int res; - - if (!size) - return 0; + int b = 0, s; - __asm__ (".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tsubu\t$1,%6,%0\n\t" - "blez\t$1,2f\n\t" - "lw\t$1,(%5)\n\t" - "addiu\t%5,4\n\t" -#if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) - "beql\t%1,$1,1b\n\t" - "addiu\t%0,32\n\t" -#else - "addiu\t%0,32\n\t" - "beq\t%1,$1,1b\n\t" - "nop\n\t" - "subu\t%0,32\n\t" -#endif -#ifdef __MIPSEB__ -#error "Fix this for big endian" -#endif /* __MIPSEB__ */ - "li\t%1,1\n" - "1:\tand\t%2,$1,%1\n\t" - "beqz\t%2,2f\n\t" - "sll\t%1,%1,1\n\t" - "bnez\t%1,1b\n\t" - "add\t%0,%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "2:" - : "=r" (res), "=r" (dummy), "=r" (addr) - : "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff), - "2" (addr), "r" (size) - : "$1"); + word = ~word; + s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; + s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; + s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; + s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; + s = 1; if (word << 31 != 0) s = 0; b += s; - return res; + return b; } /* - * find_next_zero_bit - find the first zero bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -extern __inline__ int find_next_zero_bit (void * addr, int size, int offset) -{ - unsigned int *p = ((unsigned int *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; - unsigned long dummy; - - if (bit) { - /* - * Look for zero in first byte - */ -#ifdef __MIPSEB__ -#error "Fix this for big endian byte order" -#endif - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tand\t$1,%4,%1\n\t" - "beqz\t$1,1f\n\t" - "sll\t%1,%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "1:" - : "=r" (set), "=r" (dummy) - : "0" (0), "1" (1 << bit), "r" (*p) - : "$1"); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No zero yet, search remaining full bytes for a zero - */ - res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr)); - return offset + set + res; -} - -#endif /* !(__MIPSEB__) */ - -/* - * ffz - find first zero in word. + * __ffs - find first bit in word. * @word: The word to search * - * Undefined if no zero exists, so code should check against ~0UL first. + * Undefined if no bit exists, so code should check against 0 first. */ -extern __inline__ unsigned long ffz(unsigned long word) +static __inline__ unsigned long __ffs(unsigned long word) { - unsigned int __res; - unsigned int mask = 1; - - __asm__ ( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "move\t%0,$0\n" - "1:\tand\t$1,%2,%1\n\t" - "beqz\t$1,2f\n\t" - "sll\t%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "2:\n\t" - : "=&r" (__res), "=r" (mask) - : "r" (word), "1" (mask) - : "$1"); - - return __res; + return ffz(~word); } -#ifdef __KERNEL__ - -/** - * ffs - find first bit set - * @x: the word to search - * - * This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). - */ - -#define ffs(x) generic_ffs(x) - /* - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * - * The Hamming Weight of a number is the total number of bits set in it. + * fls: find last bit set. */ -#define hweight32(x) generic_hweight32(x) -#define hweight16(x) generic_hweight16(x) -#define hweight8(x) generic_hweight8(x) +#define fls(x) generic_fls(x) -#endif /* __KERNEL__ */ - -#ifdef __MIPSEB__ /* * find_next_zero_bit - find the first zero bit in a memory region * @addr: The address to base the search on * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -extern __inline__ int find_next_zero_bit(void *addr, int size, int offset) +static inline unsigned long find_next_zero_bit(unsigned long *addr, + unsigned long size, unsigned long offset) { - unsigned long *p = ((unsigned long *) addr) + (offset >> 5); - unsigned long result = offset & ~31UL; + unsigned long *p = ((unsigned long *) addr) + (offset >> SZLONG_LOG); + unsigned long result = offset & ~SZLONG_MASK; unsigned long tmp; if (offset >= size) return size; size -= result; - offset &= 31UL; + offset &= SZLONG_MASK; if (offset) { tmp = *(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) + tmp |= ~0UL >> (_MIPS_SZLONG-offset); + if (size < _MIPS_SZLONG) goto found_first; if (~tmp) goto found_middle; - size -= 32; - result += 32; + size -= _MIPS_SZLONG; + result += _MIPS_SZLONG; } - while (size & ~31UL) { + while (size & ~SZLONG_MASK) { if (~(tmp = *(p++))) goto found_middle; - result += 32; - size -= 32; + result += _MIPS_SZLONG; + size -= _MIPS_SZLONG; } if (!size) return result; @@ -768,158 +694,241 @@ found_first: tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ found_middle: return result + ffz(tmp); } -/* Linus sez that gcc can optimize the following correctly, we'll see if this - * holds on the Sparc as it does for the ALPHA. +#define find_first_zero_bit(addr, size) \ + find_next_zero_bit((addr), (size), 0) + +/* + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search */ +static inline unsigned long find_next_bit(unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned long *p = addr + (offset >> SZLONG_LOG); + unsigned long result = offset & ~SZLONG_MASK; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= SZLONG_MASK; + if (offset) { + tmp = *(p++); + tmp &= ~0UL << offset; + if (size < _MIPS_SZLONG) + goto found_first; + if (tmp) + goto found_middle; + size -= _MIPS_SZLONG; + result += _MIPS_SZLONG; + } + while (size & ~SZLONG_MASK) { + if ((tmp = *(p++))) + goto found_middle; + result += _MIPS_SZLONG; + size -= _MIPS_SZLONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= ~0UL >> (_MIPS_SZLONG - size); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} -#if 0 /* Fool kernel-doc since it doesn't do macros yet */ /* - * find_first_zero_bit - find the first zero bit in a memory region + * find_first_bit - find the first set bit in a memory region * @addr: The address to start the search at * @size: The maximum size to search * - * Returns the bit-number of the first zero bit, not the number of the byte + * Returns the bit-number of the first set bit, not the number of the byte * containing a bit. */ -extern int find_first_zero_bit (void *addr, unsigned size); -#endif +#define find_first_bit(addr, size) \ + find_next_bit((addr), (size), 0) -#define find_first_zero_bit(addr, size) \ - find_next_zero_bit((addr), (size), 0) +#ifdef __KERNEL__ -#endif /* (__MIPSEB__) */ +/* + * Every architecture must define this function. It's the fastest + * way of searching a 168-bit bitmap where the first 128 bits are + * unlikely to be set. It's guaranteed that at least one of the 168 + * bits is cleared. + */ +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 32; + if (unlikely(b[2])) + return __ffs(b[2]) + 64; + if (unlikely(b[3])) + return __ffs(b[3]) + 96; + if (b[4]) + return __ffs(b[4]) + 128; + return __ffs(b[5]) + 32 + 128; +} -/* Now for the ext2 filesystem bit operations and helper routines. */ +/* + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + +#define ffs(x) generic_ffs(x) + +/* + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ -#ifdef __MIPSEB__ -extern __inline__ int ext2_set_bit(int nr, void * addr) +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +static inline int __test_and_set_le_bit(unsigned long nr, unsigned long *addr) { - int mask, retval, flags; unsigned char *ADDR = (unsigned char *) addr; + int mask, retval; ADDR += nr >> 3; mask = 1 << (nr & 0x07); - save_and_cli(flags); retval = (mask & *ADDR) != 0; *ADDR |= mask; - restore_flags(flags); + return retval; } -extern __inline__ int ext2_clear_bit(int nr, void * addr) +static inline int __test_and_clear_le_bit(unsigned long nr, unsigned long *addr) { - int mask, retval, flags; unsigned char *ADDR = (unsigned char *) addr; + int mask, retval; ADDR += nr >> 3; mask = 1 << (nr & 0x07); - save_and_cli(flags); retval = (mask & *ADDR) != 0; *ADDR &= ~mask; - restore_flags(flags); + return retval; } -#define ext2_set_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_set_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_clear_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_clear_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -extern __inline__ int ext2_test_bit(int nr, const void * addr) +static inline int test_le_bit(unsigned long nr, const unsigned long * addr) { - int mask; const unsigned char *ADDR = (const unsigned char *) addr; + int mask; ADDR += nr >> 3; mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); } -#define ext2_find_first_zero_bit(addr, size) \ - ext2_find_next_zero_bit((addr), (size), 0) +static inline unsigned long ext2_ffz(unsigned int word) +{ + int b = 0, s; + + word = ~word; + s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; + s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; + s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; + s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; + s = 1; if (word << 31 != 0) s = 0; b += s; + + return b; +} -extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +static inline unsigned long find_next_zero_le_bit(unsigned long *addr, + unsigned long size, unsigned long offset) { - unsigned long *p = ((unsigned long *) addr) + (offset >> 5); - unsigned long result = offset & ~31UL; - unsigned long tmp; + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31; + unsigned int tmp; if (offset >= size) return size; + size -= result; - offset &= 31UL; - if(offset) { - /* We hold the little endian value in tmp, but then the - * shift is illegal. So we could keep a big endian value - * in tmp, like this: - * - * tmp = __swab32(*(p++)); - * tmp |= ~0UL >> (32-offset); - * - * but this would decrease preformance, so we change the - * shift: - */ - tmp = *(p++); - tmp |= __swab32(~0UL >> (32-offset)); - if(size < 32) + offset &= 31; + if (offset) { + tmp = cpu_to_le32p(p++); + tmp |= ~0U >> (32-offset); /* bug or feature ? */ + if (size < 32) goto found_first; - if(~tmp) + if (tmp != ~0U) goto found_middle; size -= 32; result += 32; } - while(size & ~31UL) { - if(~(tmp = *(p++))) + while (size >= 32) { + if ((tmp = cpu_to_le32p(p++)) != ~0U) goto found_middle; result += 32; size -= 32; } - if(!size) + if (!size) return result; - tmp = *p; + tmp = cpu_to_le32p(p); found_first: - /* tmp is little endian, so we would have to swab the shift, - * see above. But then we have to swab tmp below for ffz, so - * we might as well do this here. - */ - return result + ffz(__swab32(tmp) | (~0UL << size)); + tmp |= ~0 << size; + if (tmp == ~0U) /* Are any bits zero? */ + return result + size; /* Nope. */ + found_middle: - return result + ffz(__swab32(tmp)); + return result + ext2_ffz(tmp); } -#else /* !(__MIPSEB__) */ -/* Native ext2 byte ordering, just collapse using defines. */ -#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr)) -#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr), (addr)) -#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr), (addr)) -#define ext2_test_bit(nr, addr) test_bit((nr), (addr)) -#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size)) -#define ext2_find_next_zero_bit(addr, size, offset) \ - find_next_zero_bit((addr), (size), (offset)) - -#endif /* !(__MIPSEB__) */ +#define find_first_zero_le_bit(addr, size) \ + find_next_zero_le_bit((addr), (size), 0) + +#define ext2_set_bit(nr,addr) \ + __test_and_set_le_bit((nr),(unsigned long*)addr) +#define ext2_clear_bit(nr, addr) \ + __test_and_clear_le_bit((nr),(unsigned long*)addr) + #define ext2_set_bit_atomic(lock, nr, addr) \ +({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_set_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ +}) + +#define ext2_clear_bit_atomic(lock, nr, addr) \ +({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_clear_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ +}) +#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr) +#define ext2_find_first_zero_bit(addr, size) \ + find_first_zero_le_bit((unsigned long*)addr, size) +#define ext2_find_next_zero_bit(addr, size, off) \ + find_next_zero_le_bit((unsigned long*)addr, size, off) /* * Bitmap functions for the minix filesystem. + * * FIXME: These assume that Minix uses the native byte/bitorder. * This limits the Minix filesystem's value for data exchange very much. */ @@ -928,5 +937,7 @@ #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr) #define minix_test_bit(nr,addr) test_bit(nr,addr) #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ #endif /* _ASM_BITOPS_H */ diff -Nru a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h --- a/include/asm-mips/bootinfo.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/bootinfo.h Fri Jun 27 14:19:54 2003 @@ -9,40 +9,39 @@ #ifndef _ASM_BOOTINFO_H #define _ASM_BOOTINFO_H +#include <linux/types.h> + /* * Values for machgroup */ -#define MACH_GROUP_UNKNOWN 0 /* whatever... */ -#define MACH_GROUP_JAZZ 1 /* Jazz */ -#define MACH_GROUP_DEC 2 /* Digital Equipment */ +#define MACH_GROUP_UNKNOWN 0 /* whatever... */ +#define MACH_GROUP_JAZZ 1 /* Jazz */ +#define MACH_GROUP_DEC 2 /* Digital Equipment */ #define MACH_GROUP_ARC 3 /* Wreckstation Tyne, rPC44, possibly other */ -#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ #define MACH_GROUP_ACN 5 -#define MACH_GROUP_SGI 6 /* Silicon Graphics */ -#define MACH_GROUP_COBALT 7 /* Cobalt servers */ -#define MACH_GROUP_NEC_DDB 8 /* NEC DDB */ -#define MACH_GROUP_BAGET 9 /* Baget */ -#define MACH_GROUP_COSINE 10 /* CoSine Orion */ -#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ -#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ -#define MACH_GROUP_ITE 13 /* ITE Semi Eval Boards */ +#define MACH_GROUP_SGI 6 /* Silicon Graphics */ +#define MACH_GROUP_COBALT 7 /* Cobalt servers */ +#define MACH_GROUP_NEC_DDB 8 /* NEC DDB */ +#define MACH_GROUP_BAGET 9 /* Baget */ +#define MACH_GROUP_COSINE 10 /* CoSine Orion */ +#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ +#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ +#define MACH_GROUP_ITE 13 /* ITE Semi Eval Boards */ #define MACH_GROUP_PHILIPS 14 -#define MACH_GROUP_GLOBESPAN 15 /* Globespan PVR Referrence Board */ -#define MACH_GROUP_SIBYTE 16 /* Sibyte Eval Boards */ -#define MACH_GROUP_TOSHIBA 17 /* Toshiba Reference Systems TSBREF */ -#define MACH_GROUP_ALCHEMY 18 /* Alchemy Semi Eval Boards*/ - -#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", "SNI", "ACN", \ - "SGI", "Cobalt", "NEC DDB", "Baget", "Cosine", "Galileo", "Momentum", \ - "ITE", "Philips", "Globepspan", "SiByte", "Toshiba", "Alchemy" } +#define MACH_GROUP_GLOBESPAN 15 /* Globespan PVR Referrence Board */ +#define MACH_GROUP_SIBYTE 16 /* Sibyte Eval Boards */ +#define MACH_GROUP_TOSHIBA 17 /* Toshiba Reference Systems TSBREF */ +#define MACH_GROUP_ALCHEMY 18 /* Alchemy Semi Eval Boards */ +#define MACH_GROUP_NEC_VR41XX 19 /* NEC Vr41xx based boards/gadgets */ +#define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ +#define MACH_GROUP_LASAT 21 /* * Valid machtype values for group unknown (low order halfword of mips_machtype) */ #define MACH_UNKNOWN 0 /* whatever... */ -#define GROUP_UNKNOWN_NAMES { "unknown" } - /* * Valid machtype values for group JAZZ */ @@ -50,26 +49,20 @@ #define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ #define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ -#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" } - /* - * Valid machtype for group DEC + * Valid machtype for group DEC */ #define MACH_DSUNKNOWN 0 #define MACH_DS23100 1 /* DECstation 2100 or 3100 */ -#define MACH_DS5100 2 /* DECstation 5100 */ +#define MACH_DS5100 2 /* DECsystem 5100 */ #define MACH_DS5000_200 3 /* DECstation 5000/200 */ #define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */ #define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */ #define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */ -#define MACH_DS5400 7 /* DECstation 5400 */ -#define MACH_DS5500 8 /* DECstation 5500 */ -#define MACH_DS5800 9 /* DECstation 5800 */ - -#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \ - "DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \ - "DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \ - "DECstation 5800" } +#define MACH_DS5400 7 /* DECsystem 5400 */ +#define MACH_DS5500 8 /* DECsystem 5500 */ +#define MACH_DS5800 9 /* DECsystem 5800 */ +#define MACH_DS5900 10 /* DECsystem 5900 */ /* * Valid machtype for group ARC @@ -77,46 +70,37 @@ #define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */ #define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ -#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } - /* * Valid machtype for group SNI_RM */ #define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ -#define GROUP_SNI_RM_NAMES { "RM200 PCI" } - /* * Valid machtype for group ACN */ #define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ -#define GROUP_ACN_NAMES { "ACN" } - /* * Valid machtype for group SGI */ -#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstations */ -#define MACH_SGI_CHALLENGE_S 1 /* The Challenge S server */ -#define MACH_SGI_INDIGO2 2 /* The Indigo2 system */ - -#define GROUP_SGI_NAMES { "Indy", "Challenge S", "Indigo2" } +#define MACH_SGI_IP22 0 /* Indy, Indigo2, Challenge S */ +#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */ +#define MACH_SGI_IP28 2 /* Indigo2 Impact */ +#define MACH_SGI_IP32 3 /* O2 */ /* * Valid machtype for group COBALT */ -#define MACH_COBALT_27 0 /* Proto "27" hardware */ - -#define GROUP_COBALT_NAMES { "Microserver 27" } +#define MACH_COBALT_27 0 /* Proto "27" hardware */ /* * Valid machtype for group NEC DDB */ -#define MACH_NEC_DDB5074 0 /* NEC DDB Vrc-5074 */ -#define MACH_NEC_DDB5476 1 /* NEC DDB Vrc-5476 */ -#define MACH_NEC_DDB5477 2 /* NEC DDB Vrc-5477 */ - -#define GROUP_NEC_DDB_NAMES { "Vrc-5074", "Vrc-5476", "Vrc-5477"} +#define MACH_NEC_DDB5074 0 /* NEC DDB Vrc-5074 */ +#define MACH_NEC_DDB5476 1 /* NEC DDB Vrc-5476 */ +#define MACH_NEC_DDB5477 2 /* NEC DDB Vrc-5477 */ +#define MACH_NEC_ROCKHOPPER 3 /* Rockhopper base board */ +#define MACH_NEC_ROCKHOPPERII 4 /* Rockhopper II base board */ /* * Valid machtype for group BAGET @@ -124,44 +108,33 @@ #define MACH_BAGET201 0 /* BT23-201 */ #define MACH_BAGET202 1 /* BT23-202 */ -#define GROUP_BAGET_NAMES { "BT23-201", "BT23-202" } - /* * Cosine boards. */ #define MACH_COSINE_ORION 0 -#define GROUP_COSINE_NAMES { "Orion" } - /* * Valid machtype for group GALILEO */ #define MACH_EV96100 0 /* EV96100 */ #define MACH_EV64120A 1 /* EV64120A */ -#define GROUP_GALILEO_NAMES { "EV96100" , "EV64120A" } - /* * Valid machtype for group MOMENCO */ #define MACH_MOMENCO_OCELOT 0 +#define MACH_MOMENCO_OCELOT_G 1 +#define MACH_MOMENCO_OCELOT_C 2 -#define GROUP_MOMENCO_NAMES { "Ocelot" } - - /* * Valid machtype for group ITE */ #define MACH_QED_4N_S01B 0 /* ITE8172 based eval board */ - -#define GROUP_ITE_NAMES { "QED-4N-S01B" } /* the actual board name */ - + /* * Valid machtype for group Globespan */ -#define MACH_IVR 0 /* IVR eval board */ - -#define GROUP_GLOBESPAN_NAMES { "IVR" } /* the actual board name */ +#define MACH_IVR 0 /* IVR eval board */ /* * Valid machtype for group PHILIPS @@ -169,126 +142,63 @@ #define MACH_PHILIPS_NINO 0 /* Nino */ #define MACH_PHILIPS_VELO 1 /* Velo */ -#define GROUP_PHILIPS_NAMES { "Nino" , "Velo" } - /* * Valid machtype for group SIBYTE */ #define MACH_SWARM 0 -#define GROUP_SIBYTE_NAMES {"SWARM" } - /* * Valid machtypes for group Toshiba */ #define MACH_PALLAS 0 #define MACH_TOPAS 1 #define MACH_JMR 2 +#define MACH_TOSHIBA_JMR3927 3 /* JMR-TX3927 CPU/IO board */ +#define MACH_TOSHIBA_RBTX4927 4 +#define MACH_TOSHIBA_RBTX4937 5 +#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR", "JMR TX3927", \ + "RBTX4927", "RBTX4937" } -#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR" } +/* + * Valid machtype for group LASAT + */ +#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ +#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ /* * Valid machtype for group Alchemy */ -#define MACH_PB1000 0 /* Au1000-based eval board */ - -#define GROUP_ALCHEMY_NAMES { "PB1000" } /* the actual board name */ - -/* - * Valid cputype values - */ -#define CPU_UNKNOWN 0 -#define CPU_R2000 1 -#define CPU_R3000 2 -#define CPU_R3000A 3 -#define CPU_R3041 4 -#define CPU_R3051 5 -#define CPU_R3052 6 -#define CPU_R3081 7 -#define CPU_R3081E 8 -#define CPU_R4000PC 9 -#define CPU_R4000SC 10 -#define CPU_R4000MC 11 -#define CPU_R4200 12 -#define CPU_R4400PC 13 -#define CPU_R4400SC 14 -#define CPU_R4400MC 15 -#define CPU_R4600 16 -#define CPU_R6000 17 -#define CPU_R6000A 18 -#define CPU_R8000 19 -#define CPU_R10000 20 -#define CPU_R4300 21 -#define CPU_R4650 22 -#define CPU_R4700 23 -#define CPU_R5000 24 -#define CPU_R5000A 25 -#define CPU_R4640 26 -#define CPU_NEVADA 27 /* RM5230, RM5260 */ -#define CPU_RM7000 28 -#define CPU_R5432 29 -#define CPU_4KC 30 -#define CPU_5KC 31 -#define CPU_R4310 32 -#define CPU_SB1 33 -#define CPU_TX3912 34 -#define CPU_TX3922 35 -#define CPU_TX3927 36 -#define CPU_AU1000 37 -#define CPU_4KEC 38 -#define CPU_4KSC 39 -#define CPU_VR41XX 40 -#define CPU_LAST 40 - - -#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ - "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ - "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ - "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \ - "R5000A", "R4640", "Nevada", "RM7000", "R5432", "MIPS 4Kc", \ - "MIPS 5Kc", "R4310", "SiByte SB1", "TX3912", "TX3922", "TX3927", \ - "Au1000", "MIPS 4KEc", "MIPS 4KSc", "NEC Vr41xx" } +#define MACH_PB1000 0 /* Au1000-based eval board */ +#define MACH_PB1100 1 /* Au1100-based eval board */ +#define MACH_PB1500 2 /* Au1500-based eval board */ +#define MACH_DB1000 3 /* Au1000-based eval board */ +#define MACH_DB1100 4 /* Au1100-based eval board */ +#define MACH_DB1500 5 /* Au1500-based eval board */ + +/* + * Valid machtype for group NEC_VR41XX + */ +#define MACH_NEC_OSPREY 0 /* Osprey eval board */ +#define MACH_NEC_EAGLE 1 /* NEC Eagle/Hawk board */ +#define MACH_ZAO_CAPCELLA 2 /* ZAO Networks Capcella */ +#define MACH_VICTOR_MPC30X 3 /* Victor MP-C303/304 */ +#define MACH_IBM_WORKPAD 4 /* IBM WorkPad z50 */ +#define MACH_CASIO_E55 5 /* CASIO CASSIOPEIA E-10/15/55/65 */ +#define MACH_TANBAC_TB0226 6 /* TANBAC TB0226 (Mbase) */ +#define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ + +#define CL_SIZE (256) -#define COMMAND_LINE_SIZE 256 +const char *get_system_type(void); + +extern unsigned long mips_machtype; +extern unsigned long mips_machgroup; #define BOOT_MEM_MAP_MAX 32 #define BOOT_MEM_RAM 1 #define BOOT_MEM_ROM_DATA 2 #define BOOT_MEM_RESERVED 3 -#ifndef __ASSEMBLY__ - -/* - * Some machine parameters passed by the bootloaders. - */ - -struct drive_info_struct { - char dummy[32]; -}; - -/* This is the same as in Milo but renamed for the sake of kernel's */ -/* namespace */ -typedef struct mips_arc_DisplayInfo { /* video adapter information */ - unsigned short cursor_x; - unsigned short cursor_y; - unsigned short columns; - unsigned short lines; -} mips_arc_DisplayInfo; - -/* default values for drive info */ -#define DEFAULT_DRIVE_INFO { {0,}} - -/* - * These are the kernel variables initialized from - * the tag. And they have to be initialized to dummy/default - * values in setup.c (or whereever suitable) so they are in - * .data section - */ -extern struct mips_cpu mips_cpu; -extern unsigned long mips_machtype; -extern unsigned long mips_machgroup; -extern unsigned long mips_tlb_entries; - /* * A memory map that's built upon what was determined * or specified on the command line. @@ -296,17 +206,14 @@ struct boot_mem_map { int nr_map; struct { - unsigned long addr; /* start of memory segment */ - unsigned long size; /* size of memory segment */ + phys_t addr; /* start of memory segment */ + phys_t size; /* size of memory segment */ long type; /* type of memory segment */ } map[BOOT_MEM_MAP_MAX]; }; extern struct boot_mem_map boot_mem_map; -extern void add_memory_region(unsigned long start, unsigned long size, - long type); - -#endif /* !__ASSEMBLY__ */ +extern void add_memory_region(phys_t start, phys_t size, long type); #endif /* _ASM_BOOTINFO_H */ diff -Nru a/include/asm-mips/branch.h b/include/asm-mips/branch.h --- a/include/asm-mips/branch.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/branch.h Fri Jun 27 14:19:55 2003 @@ -1,24 +1,31 @@ /* - * Branch and jump emulation. - * * 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) 1996, 1997, 1998 by Ralf Baechle - * - * $Id: branch.h,v 1.2 1998/04/28 19:37:46 ralf Exp $ + * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle */ +#ifndef _ASM_BRANCH_H +#define _ASM_BRANCH_H + #include <asm/ptrace.h> -extern inline int delay_slot(struct pt_regs *regs) +static inline int delay_slot(struct pt_regs *regs) { return regs->cp0_cause & CAUSEF_BD; } +static inline unsigned long exception_epc(struct pt_regs *regs) +{ + if (!delay_slot(regs)) + return regs->cp0_epc; + + return regs->cp0_epc + 4; +} + extern int __compute_return_epc(struct pt_regs *regs); -extern inline int compute_return_epc(struct pt_regs *regs) +static inline int compute_return_epc(struct pt_regs *regs) { if (!delay_slot(regs)) { regs->cp0_epc += 4; @@ -27,3 +34,5 @@ return __compute_return_epc(regs); } + +#endif /* _ASM_BRANCH_H */ diff -Nru a/include/asm-mips/break.h b/include/asm-mips/break.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/break.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,33 @@ +/* + * 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) 1995, 2003 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_BREAK_H +#define __ASM_BREAK_H + +/* + * The following break codes are or were in use for specific purposes in + * other MIPS operating systems. Linux/MIPS doesn't use all of them. The + * unused ones are here as placeholders; we might encounter them in + * non-Linux/MIPS object files or make use of them in the future. + */ +#define BRK_USERBP 0 /* User bp (used by debuggers) */ +#define BRK_KERNELBP 1 /* Break in the kernel */ +#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */ +#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */ +#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */ +#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */ +#define BRK_OVERFLOW 6 /* Overflow check */ +#define BRK_DIVZERO 7 /* Divide by zero check */ +#define BRK_RANGE 8 /* Range error check */ +#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */ +#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ +#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ +#define BRK_MULOVF 1023 /* Multiply overflow */ +#define BRK_BUG 512 /* Used by BUG() */ + +#endif /* __ASM_BREAK_H */ diff -Nru a/include/asm-mips/bug.h b/include/asm-mips/bug.h --- a/include/asm-mips/bug.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/bug.h Fri Jun 27 14:19:59 2003 @@ -1,15 +1,20 @@ -/* $Id$ */ #ifndef __ASM_BUG_H #define __ASM_BUG_H -#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) +#include <asm/break.h> + +#define BUG() \ +do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \ +} while (0) #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) #define PAGE_BUG(page) do { BUG(); } while (0) #define WARN_ON(condition) do { \ if (unlikely((condition)!=0)) { \ printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ + dump_stack(); \ } \ } while (0) diff -Nru a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h --- a/include/asm-mips/bugs.h Fri Jun 27 14:19:58 2003 +++ b/include/asm-mips/bugs.h Fri Jun 27 14:19:58 2003 @@ -1,47 +1,12 @@ /* - * Copyright (C) 1995 Waldorf Electronics - * Copyright (C) 1997, 1999 Ralf Baechle - */ -#include <asm/bootinfo.h> -#include <asm/cpu.h> - -/* * This is included by init/main.c to check for architecture-dependent bugs. * * Needs: * void check_bugs(void); */ +#ifndef __ASM_BUGS_H +#define __ASM_BUGS_H +extern void check_bugs(void); -static inline void check_wait(void) -{ - printk("Checking for 'wait' instruction... "); - switch(mips_cpu.cputype) { - case CPU_R3081: - case CPU_R3081E: - cpu_wait = r3081_wait; - printk(" available.\n"); - break; - case CPU_R4200: - case CPU_R4300: - case CPU_R4600: - case CPU_R4640: - case CPU_R4650: - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - case CPU_RM7000: - cpu_wait = r4k_wait; - printk(" available.\n"); - break; - default: - printk(" unavailable.\n"); - break; - } -} - -static void __init -check_bugs(void) -{ - check_wait(); -} +#endif /* __ASM_BUGS_H */ diff -Nru a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h --- a/include/asm-mips/byteorder.h Fri Jun 27 14:19:58 2003 +++ b/include/asm-mips/byteorder.h Fri Jun 27 14:19:58 2003 @@ -1,5 +1,4 @@ -/* $Id: byteorder.h,v 1.8 1998/11/02 09:29:32 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff -Nru a/include/asm-mips/cache.h b/include/asm-mips/cache.h --- a/include/asm-mips/cache.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/cache.h Fri Jun 27 14:19:54 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 98, 99, 2000 Ralf Baechle + * Copyright (C) 1997, 98, 99, 2000, 2003 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CACHE_H @@ -11,30 +11,15 @@ #include <linux/config.h> -#ifndef _LANGUAGE_ASSEMBLY -/* - * Descriptor for a cache - */ -struct cache_desc { - int linesz; - int sets; - int ways; - int flags; /* Details like write thru/back, coherent, etc. */ -}; -#endif - -/* - * Flag definitions - */ -#define MIPS_CACHE_NOT_PRESENT 0x00000001 - -#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) || \ + defined(CONFIG_CPU_TX39XX) #define L1_CACHE_BYTES 16 +#define L1_CACHE_SHIFT_MAX 4 /* largest L1 which this arch supports */ #else #define L1_CACHE_BYTES 32 /* A guess */ +#define L1_CACHE_SHIFT_MAX 6 /* largest L1 which this arch supports */ #endif #define SMP_CACHE_BYTES L1_CACHE_BYTES -#define L1_CACHE_SHIFT_MAX 5 /* largest L1 which this arch supports */ #endif /* _ASM_CACHE_H */ diff -Nru a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/cacheflush.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,65 @@ +/* + * 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, 95, 96, 97, 98, 99, 2000, 01, 02, 03 by Ralf Baechle + * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEFLUSH_H +#define __ASM_CACHEFLUSH_H + +#include <linux/config.h> + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* Cache flushing: + * + * - flush_cache_all() flushes entire cache + * - flush_cache_mm(mm) flushes the specified mm context's cache lines + * - flush_cache_page(mm, vmaddr) flushes a single page + * - flush_cache_range(vma, start, end) flushes a range of pages + * - flush_icache_range(start, end) flush a range of instructions + * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache + * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache + * + * MIPS specific flush operations: + * + * - flush_cache_sigtramp() flush signal trampoline + * - flush_icache_all() flush the entire instruction cache + * - flush_data_cache_page() flushes a page from the data cache + */ +extern void (*flush_cache_all)(void); +extern void (*__flush_cache_all)(void); +extern void (*flush_cache_mm)(struct mm_struct *mm); +extern void (*flush_cache_range)(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void (*flush_cache_page)(struct vm_area_struct *vma, + unsigned long page); +extern void flush_dcache_page(struct page *page); +extern void (*flush_icache_page)(struct vm_area_struct *vma, + struct page *page); +extern void (*flush_icache_range)(unsigned long start, unsigned long end); +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page(vma, page) + + +extern void (*flush_cache_sigtramp)(unsigned long addr); +extern void (*flush_icache_all)(void); +extern void (*flush_data_cache_page)(unsigned long addr); + +/* + * This flag is used to indicate that the page pointed to by a pte + * is dirty and requires cleaning before returning it to the user. + */ +#define PG_dcache_dirty PG_arch_1 + +#define Page_dcache_dirty(page) \ + test_bit(PG_dcache_dirty, &(page)->flags) +#define SetPageDcacheDirty(page) \ + set_bit(PG_dcache_dirty, &(page)->flags) +#define ClearPageDcacheDirty(page) \ + clear_bit(PG_dcache_dirty, &(page)->flags) + +#endif /* __ASM_CACHEFLUSH_H */ diff -Nru a/include/asm-mips/cacheops.h b/include/asm-mips/cacheops.h --- a/include/asm-mips/cacheops.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/cacheops.h Fri Jun 27 14:19:54 2003 @@ -5,43 +5,77 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * (C) Copyright 1996, 1997 by Ralf Baechle + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. */ -#ifndef __ASM_MIPS_CACHEOPS_H -#define __ASM_MIPS_CACHEOPS_H +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H /* - * Cache Operations + * Cache Operations available on all MIPS processors with R4000-style caches */ #define Index_Invalidate_I 0x00 #define Index_Writeback_Inv_D 0x01 -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 #define Index_Load_Tag_I 0x04 #define Index_Load_Tag_D 0x05 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 #define Index_Store_Tag_I 0x08 #define Index_Store_Tag_D 0x09 +#define Hit_Invalidate_I 0x10 +#define Hit_Invalidate_D 0x11 +#define Hit_Writeback_Inv_D 0x15 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 + +/* + * R4000-specific cacheops + */ +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 + +/* + * R4000SC and R4400SC-specific cacheops + */ +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 #define Index_Store_Tag_SI 0x0A #define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_D 0x0d #define Create_Dirty_Excl_SD 0x0f -#define Hit_Invalidate_I 0x10 -#define Hit_Invalidate_D 0x11 #define Hit_Invalidate_SI 0x12 #define Hit_Invalidate_SD 0x13 -#define Fill 0x14 -#define Hit_Writeback_Inv_D 0x15 - /* 0x16 is unused */ #define Hit_Writeback_Inv_SD 0x17 -#define Hit_Writeback_I 0x18 -#define Hit_Writeback_D 0x19 - /* 0x1a is unused */ #define Hit_Writeback_SD 0x1b - /* 0x1c is unused */ - /* 0x1e is unused */ #define Hit_Set_Virtual_SI 0x1e #define Hit_Set_Virtual_SD 0x1f -#endif /* __ASM_MIPS_CACHEOPS_H */ +/* + * R5000-specific cacheops + */ +#define R5K_Page_Invalidate_S 0x17 + +/* + * RM7000-specific cacheops + */ +#define Page_Invalidate_T 0x16 + +/* + * R1000-specific cacheops + * + * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. + * Most of the _S cacheops are identical to the R4000SC _SD cacheops. + */ +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +#endif /* __ASM_CACHEOPS_H */ diff -Nru a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h --- a/include/asm-mips/checksum.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/checksum.h Fri Jun 27 14:19:53 2003 @@ -9,6 +9,7 @@ #define _ASM_CHECKSUM_H #include <asm/uaccess.h> +#include <linux/in6.h> /* * computes the checksum of a memory block at buff, length len, @@ -35,7 +36,7 @@ * Copy and checksum to user */ #define HAVE_CSUM_COPY_USER -extern inline unsigned int csum_and_copy_to_user (const char *src, char *dst, +static inline unsigned int csum_and_copy_to_user (const char *src, char *dst, int len, int sum, int *err_ptr) { @@ -71,12 +72,11 @@ "xori\t%0,0xffff\n\t" ".set\tat" : "=r" (sum) - : "0" (sum) - : "$1"); + : "0" (sum)); - return sum; + return sum; } - + /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -124,8 +124,7 @@ "2:\t.set\tat\n\t" ".set\treorder" : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy) - : "1" (iph), "2" (ihl) - : "$1"); + : "1" (iph), "2" (ihl)); return csum_fold(sum); } @@ -161,8 +160,7 @@ #else "r" (((proto)<<16)+len), #endif - "r" (sum) - : "$1"); + "r" (sum)); return sum; } @@ -194,10 +192,11 @@ struct in6_addr *daddr, __u32 len, unsigned short proto, - unsigned int sum) + unsigned int sum) { __asm__( - ".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t" + ".set\tpush\t\t\t# csum_ipv6_magic\n\t" + ".set\tnoreorder\n\t" ".set\tnoat\n\t" "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t" "sltu\t$1, %0, %5\n\t" @@ -208,48 +207,48 @@ "lw\t%1, 0(%2)\t\t\t# four words source address\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 4(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 8(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 12(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 0(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 4(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 8(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 12(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" - ".set\tnoat\n\t" - ".set\tnoreorder" + "sltu\t$1, %0, %1\n\t" + + "addu\t%0, $1\t\t\t# Add final carry\n\t" + ".set\tpop" : "=r" (sum), "=r" (proto) : "r" (saddr), "r" (daddr), - "0" (htonl(len)), "1" (htonl(proto)), "r" (sum) - : "$1"); + "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); return csum_fold(sum); } diff -Nru a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/cobalt/cobalt.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/cobalt/cobalt.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,98 @@ +/* + * Lowlevel hardware stuff for the MIPS based Cobalt microservers. + * + * 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) 1997 Cobalt Microserver + * Copyright (C) 1997 Ralf Baechle + * Copyright (C) 2001, 2002, 2003 Liam Davies (ldavies@agile.tv) + * + */ +#ifndef __ASM_MIPS_COBALT_H +#define __ASM_MIPS_COBALT_H + +/* + * COBALT interrupt enable bits + */ +#define COBALT_IE_PCI (1 << 0) +#define COBALT_IE_FLOPPY (1 << 1) +#define COBALT_IE_KEYBOARD (1 << 2) +#define COBALT_IE_SERIAL1 (1 << 3) +#define COBALT_IE_SERIAL2 (1 << 4) +#define COBALT_IE_PARALLEL (1 << 5) +#define COBALT_IE_GPIO (1 << 6) +#define COBALT_IE_RTC (1 << 7) + +/* + * PCI defines + */ +#define COBALT_IE_ETHERNET (1 << 7) +#define COBALT_IE_SCSI (1 << 7) + +/* + * COBALT Interrupt Level definitions. + * These should match the request IRQ id's. + */ +#define COBALT_TIMER_IRQ 0 +#define COBALT_KEYBOARD_IRQ 1 +#define COBALT_QUBE_SLOT_IRQ 9 +#define COBALT_ETH0_IRQ 4 +#define COBALT_ETH1_IRQ 13 +#define COBALT_SCC_IRQ 4 +#define COBALT_SERIAL2_IRQ 4 +#define COBALT_PARALLEL_IRQ 5 +#define COBALT_FLOPPY_IRQ 6 /* needs to be consistent with floppy driver! */ +#define COBALT_SCSI_IRQ 7 +#define COBALT_SERIAL_IRQ 7 +#define COBALT_RAQ_SCSI_IRQ 4 + +/* + * PCI configuration space manifest constants. These are wired into + * the board layout according to the PCI spec to enable the software + * to probe the hardware configuration space in a well defined manner. + * + * The PCI_DEVSHFT() macro transforms these values into numbers + * suitable for passing as the dev parameter to the various + * pcibios_read/write_config routines. + */ +#define COBALT_PCICONF_CPU 0x06 +#define COBALT_PCICONF_ETH0 0x07 +#define COBALT_PCICONF_RAQSCSI 0x08 +#define COBALT_PCICONF_VIA 0x09 +#define COBALT_PCICONF_PCISLOT 0x0A +#define COBALT_PCICONF_ETH1 0x0C + + +/* + * The Cobalt board id information. The boards have an ID number wired + * into the VIA that is available in the high nibble of register 94. + * This register is available in the VIA configuration space through the + * interface routines qube_pcibios_read/write_config. See cobalt/pci.c + */ +#define VIA_COBALT_BRD_ID_REG 0x94 +#define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char) (reg) >> 4) +#define COBALT_BRD_ID_QUBE1 0x3 +#define COBALT_BRD_ID_RAQ1 0x4 +#define COBALT_BRD_ID_QUBE2 0x5 +#define COBALT_BRD_ID_RAQ2 0x6 + + +/* + * Galileo chipset access macros for the Cobalt. The base address for + * the GT64111 chip is 0x14000000 + */ +#define GT64111_BASE 0x04000000 +#define GALILEO_REG(ofs) (GT64111_BASE + (ofs)) + +#define GALILEO_INL(port) (inl(GALILEO_REG(port))) +#define GALILEO_OUTL(val, port) outl(val, GALILEO_REG(port)) + +#define GALILEO_T0EXP 0x0100 +#define GALILEO_ENTC0 0x01 +#define GALILEO_SELTC0 0x02 + + +#endif /* __ASM_MIPS_COBALT_H */ + diff -Nru a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h --- a/include/asm-mips/cpu.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/cpu.h Fri Jun 27 14:19:53 2003 @@ -7,10 +7,10 @@ #ifndef _ASM_CPU_H #define _ASM_CPU_H -#include <asm/cache.h> +#include <linux/cpu.h> -/* Assigned Company values for bits 23:16 of the PRId Register - (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from +/* Assigned Company values for bits 23:16 of the PRId Register + (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from MTI, the PRId register is defined in this (backwards compatible) way: @@ -21,16 +21,15 @@ I don't have docs for all the previous processors, but my impression is that bits 16-23 have been 0 for all MIPS processors before the MIPS32/64 - spec. + spec. */ #define PRID_COMP_LEGACY 0x000000 #define PRID_COMP_MIPS 0x010000 +#define PRID_COMP_BROADCOM 0x020000 #define PRID_COMP_ALCHEMY 0x030000 -/* - * Don't know who should be here...QED and Sandcraft, maybe? - */ #define PRID_COMP_SIBYTE 0x040000 +#define PRID_COMP_SANDCRAFT 0x050000 /* * Assigned values for the product ID register. In order to detect a @@ -38,7 +37,8 @@ * be examined. These are valid when 23:16 == PRID_COMP_LEGACY */ #define PRID_IMP_R2000 0x0100 -#define PRID_IMP_AU1000 0x0100 +#define PRID_IMP_AU1_REV1 0x0100 +#define PRID_IMP_AU1_REV2 0x0200 #define PRID_IMP_R3000 0x0200 /* Same as R2000A */ #define PRID_IMP_R6000 0x0300 /* Same as R3000A */ #define PRID_IMP_R4000 0x0400 @@ -54,13 +54,16 @@ #define PRID_IMP_R4640 0x2200 #define PRID_IMP_R4650 0x2200 /* Same as R4640 */ #define PRID_IMP_R5000 0x2300 +#define PRID_IMP_TX49 0x2d00 #define PRID_IMP_SONIC 0x2400 #define PRID_IMP_MAGIC 0x2500 #define PRID_IMP_RM7000 0x2700 #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ #define PRID_IMP_R5432 0x5400 +#define PRID_IMP_R5500 0x5500 #define PRID_IMP_4KC 0x8000 #define PRID_IMP_5KC 0x8100 +#define PRID_IMP_20KC 0x8200 #define PRID_IMP_4KEC 0x8400 #define PRID_IMP_4KSC 0x8600 @@ -74,10 +77,18 @@ #define PRID_IMP_SB1 0x0100 /* + * These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT + */ + +#define PRID_IMP_SR71000 0x0400 + +/* * Definitions for 7:0 on legacy processors */ +#define PRID_REV_TX4927 0x0022 +#define PRID_REV_TX4937 0x0030 #define PRID_REV_R4400 0x0040 #define PRID_REV_R3000A 0x0030 #define PRID_REV_R3000 0x0020 @@ -85,50 +96,116 @@ #define PRID_REV_TX3912 0x0010 #define PRID_REV_TX3922 0x0030 #define PRID_REV_TX3927 0x0040 - -#ifndef _LANGUAGE_ASSEMBLY -/* - * Capability and feature descriptor structure for MIPS CPU - */ -struct mips_cpu { - unsigned int processor_id; - unsigned int cputype; /* Old "mips_cputype" code */ - int isa_level; - int options; - int tlbsize; - struct cache_desc icache; /* Primary I-cache */ - struct cache_desc dcache; /* Primary D or combined I/D cache */ - struct cache_desc scache; /* Secondary cache */ - struct cache_desc tcache; /* Tertiary/split secondary cache */ -}; - -#endif +#define PRID_REV_VR4111 0x0050 +#define PRID_REV_VR4181 0x0050 /* Same as VR4111 */ +#define PRID_REV_VR4121 0x0060 +#define PRID_REV_VR4122 0x0070 +#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ +#define PRID_REV_VR4131 0x0080 + +/* + * FPU implementation/revision register (CP1 control register 0). + * + * +---------------------------------+----------------+----------------+ + * | 0 | Implementation | Revision | + * +---------------------------------+----------------+----------------+ + * 31 16 15 8 7 0 + */ + +#define FPIR_IMP_NONE 0x0000 + +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 +#define CPU_R12000 21 +#define CPU_R4300 22 +#define CPU_R4650 23 +#define CPU_R4700 24 +#define CPU_R5000 25 +#define CPU_R5000A 26 +#define CPU_R4640 27 +#define CPU_NEVADA 28 +#define CPU_RM7000 29 +#define CPU_R5432 30 +#define CPU_4KC 31 +#define CPU_5KC 32 +#define CPU_R4310 33 +#define CPU_SB1 34 +#define CPU_TX3912 35 +#define CPU_TX3922 36 +#define CPU_TX3927 37 +#define CPU_AU1000 38 +#define CPU_4KEC 39 +#define CPU_4KSC 40 +#define CPU_VR41XX 41 +#define CPU_R5500 42 +#define CPU_TX49XX 43 +#define CPU_AU1500 44 +#define CPU_20KC 45 +#define CPU_VR4111 46 +#define CPU_VR4121 47 +#define CPU_VR4122 48 +#define CPU_VR4131 49 +#define CPU_VR4181 50 +#define CPU_VR4181A 51 +#define CPU_AU1100 52 +#define CPU_SR71000 53 +#define CPU_LAST 53 /* * ISA Level encodings + * */ #define MIPS_CPU_ISA_I 0x00000001 #define MIPS_CPU_ISA_II 0x00000002 -#define MIPS_CPU_ISA_III 0x00000003 -#define MIPS_CPU_ISA_IV 0x00000004 -#define MIPS_CPU_ISA_V 0x00000005 +#define MIPS_CPU_ISA_III 0x00008003 +#define MIPS_CPU_ISA_IV 0x00008004 +#define MIPS_CPU_ISA_V 0x00008005 #define MIPS_CPU_ISA_M32 0x00000020 -#define MIPS_CPU_ISA_M64 0x00000040 +#define MIPS_CPU_ISA_M64 0x00008040 + +/* + * Bit 15 encodes if an ISA level supports 64-bit operations. + */ +#define MIPS_CPU_ISA_64BIT 0x00008000 /* * CPU Option encodings */ -#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ +#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ /* Leave a spare bit for variant MMU types... */ -#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */ -#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */ -#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */ -#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ -#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ -#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ -#define MIPS_CPU_MIPS16 0x00000100 /* code compression */ -#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ -#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ +#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */ +#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */ +#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */ +#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ +#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ +#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ +#define MIPS_CPU_MIPS16 0x00000100 /* code compression */ +#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ +#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ #define MIPS_CPU_CACHE_CDEX 0x00000800 /* Create_Dirty_Exclusive CACHE op */ +#define MIPS_CPU_MCHECK 0x00001000 /* Machine check exception */ +#define MIPS_CPU_EJTAG 0x00002000 /* EJTAG exception */ +#define MIPS_CPU_NOFPUEX 0x00004000 /* no FPU exception */ +#define MIPS_CPU_LLSC 0x00008000 /* CPU has ll/sc instructions */ +#define MIPS_CPU_SUBSET_CACHES 0x00010000 /* P-cache subset enforced */ #endif /* _ASM_CPU_H */ diff -Nru a/include/asm-mips/current.h b/include/asm-mips/current.h --- a/include/asm-mips/current.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/current.h Fri Jun 27 14:19:53 2003 @@ -3,17 +3,21 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1998 Ralf Baechle + * Copyright (C) 1998, 2002 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CURRENT_H #define _ASM_CURRENT_H -#ifdef _LANGUAGE_C +#include <linux/thread_info.h> -/* MIPS rules... */ -register struct task_struct *current asm("$28"); +struct task_struct; -#endif /* _LANGUAGE_C */ +static inline struct task_struct * get_current(void) +{ + return current_thread_info()->task; +} + +#define current get_current() #endif /* _ASM_CURRENT_H */ diff -Nru a/include/asm-mips/db1x00.h b/include/asm-mips/db1x00.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/db1x00.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,118 @@ +/* + * AMD Alchemy DB1x00 Reference Boards + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#ifndef __ASM_DB1X00_H +#define __ASM_DB1X00_H + + +/* + * Overlay data structure of the Db1x00 board registers. + * Registers located at physical 1E0000xx, KSEG1 0xAE0000xx + */ +typedef volatile struct +{ + /*00*/ unsigned long whoami; + /*04*/ unsigned long status; + /*08*/ unsigned long switches; + /*0C*/ unsigned long resets; + /*10*/ unsigned long pcmcia; + /*14*/ unsigned long specific; + /*18*/ unsigned long leds; + /*1C*/ unsigned long swreset; + +} BCSR; + +/* + * Register/mask bit definitions for the BCSRs + */ +#define BCSR_WHOAMI_DCID 0x000F +#define BCSR_WHOAMI_CPLD 0x00F0 +#define BCSR_WHOAMI_BOARD 0x0F00 + +#define BCSR_STATUS_PC0VS 0x0003 +#define BCSR_STATUS_PC1VS 0x000C +#define BCSR_STATUS_PC0FI 0x0010 +#define BCSR_STATUS_PC1FI 0x0020 +#define BCSR_STATUS_FLASHBUSY 0x0100 +#define BCSR_STATUS_ROMBUSY 0x0400 +#define BCSR_STATUS_SWAPBOOT 0x2000 +#define BCSR_STATUS_FLASHDEN 0xC000 + +#define BCSR_SWITCHES_DIP 0x00FF +#define BCSR_SWITCHES_DIP_1 0x0080 +#define BCSR_SWITCHES_DIP_2 0x0040 +#define BCSR_SWITCHES_DIP_3 0x0020 +#define BCSR_SWITCHES_DIP_4 0x0010 +#define BCSR_SWITCHES_DIP_5 0x0008 +#define BCSR_SWITCHES_DIP_6 0x0004 +#define BCSR_SWITCHES_DIP_7 0x0002 +#define BCSR_SWITCHES_DIP_8 0x0001 +#define BCSR_SWITCHES_ROTARY 0x0F00 + +#define BCSR_RESETS_PHY0 0x0001 +#define BCSR_RESETS_PHY1 0x0002 +#define BCSR_RESETS_DC 0x0004 + +#define BCSR_PCMCIA_PC0VPP 0x0003 +#define BCSR_PCMCIA_PC0VCC 0x000C +#define BCSR_PCMCIA_PC0DRVEN 0x0010 +#define BCSR_PCMCIA_PC0RST 0x0080 +#define BCSR_PCMCIA_PC1VPP 0x0300 +#define BCSR_PCMCIA_PC1VCC 0x0C00 +#define BCSR_PCMCIA_PC1DRVEN 0x1000 +#define BCSR_PCMCIA_PC1RST 0x8000 + +#define BCSR_BOARD_PCIM66EN 0x0001 +#define BCSR_BOARD_PCIM33 0x0100 +#define BCSR_BOARD_GPIO200RST 0x0400 +#define BCSR_BOARD_PCICFG 0x1000 + +#define BCSR_LEDS_DECIMALS 0x0003 +#define BCSR_LEDS_LED0 0x0100 +#define BCSR_LEDS_LED1 0x0200 +#define BCSR_LEDS_LED2 0x0400 +#define BCSR_LEDS_LED3 0x0800 + +#define BCSR_SWRESET_RESET 0x0080 + +/* PCMCIA Db1x00 specific defines */ +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) + +/* VPP/VCC */ +#define SET_VCC_VPP(VCC, VPP, SLOT)\ + ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) + +/* MTD CONFIG OPTIONS */ +#if defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER) +#define DB1X00_BOTH_BANKS +#elif defined(CONFIG_MTD_DB1X00_BOOT) && !defined(CONFIG_MTD_DB1X00_USER) +#define DB1X00_BOOT_ONLY +#elif !defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER) +#define DB1X00_USER_ONLY +#endif + +#endif /* __ASM_DB1X00_H */ diff -Nru a/include/asm-mips/ddb5xxx/ddb5074.h b/include/asm-mips/ddb5xxx/ddb5074.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/ddb5xxx/ddb5074.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,38 @@ +/* + * include/asm-mips/ddb5074.h -- NEC DDB Vrc-5074 definitions + * + * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> + * Sony Software Development Center Europe (SDCE), Brussels + */ + +#ifndef _ASM_DDB5XXX_DDB5074_H +#define _ASM_DDB5XXX_DDB5074_H + +#include <asm/nile4.h> + +#define DDB_SDRAM_SIZE 0x04000000 /* 64MB */ + +#define DDB_PCI_IO_BASE 0x06000000 +#define DDB_PCI_IO_SIZE 0x02000000 /* 32 MB */ + +#define DDB_PCI_MEM_BASE 0x08000000 +#define DDB_PCI_MEM_SIZE 0x08000000 /* 128 MB */ + +#define DDB_PCI_CONFIG_BASE DDB_PCI_MEM_BASE +#define DDB_PCI_CONFIG_SIZE DDB_PCI_MEM_SIZE + +#define NILE4_PCI_IO_BASE 0xa6000000 +#define NILE4_PCI_MEM_BASE 0xa8000000 +#define NILE4_PCI_CFG_BASE NILE4_PCI_MEM_BASE +#define DDB_PCI_IACK_BASE NILE4_PCI_IO_BASE + +#define NILE4_IRQ_BASE NUM_I8259_INTERRUPTS +#define CPU_IRQ_BASE (NUM_NILE4_INTERRUPTS + NILE4_IRQ_BASE) +#define CPU_NILE4_CASCADE 2 + +extern void ddb5074_led_hex(int hex); +extern void ddb5074_led_d2(int on); +extern void ddb5074_led_d3(int on); + +extern void nile4_irq_setup(u32 base); +#endif diff -Nru a/include/asm-mips/ddb5xxx/ddb5476.h b/include/asm-mips/ddb5xxx/ddb5476.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/ddb5xxx/ddb5476.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,157 @@ +/* + * header file specific for ddb5476 + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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. + * + */ + +/* + * Memory map (physical address) + * + * Note most of the following address must be properly aligned by the + * corresponding size. For example, if PCI_IO_SIZE is 16MB, then + * PCI_IO_BASE must be aligned along 16MB boundary. + */ +#define DDB_SDRAM_BASE 0x00000000 +#define DDB_SDRAM_SIZE 0x04000000 /* 64MB */ + +#define DDB_DCS3_BASE 0x04000000 /* flash 1 */ +#define DDB_DCS3_SIZE 0x01000000 /* 16MB */ + +#define DDB_DCS2_BASE 0x05000000 /* flash 2 */ +#define DDB_DCS2_SIZE 0x01000000 /* 16MB */ + +#define DDB_PCI_IO_BASE 0x06000000 +#define DDB_PCI_IO_SIZE 0x02000000 /* 32 MB */ + +#define DDB_PCI_MEM_BASE 0x08000000 +#define DDB_PCI_MEM_SIZE 0x08000000 /* 128 MB */ + +#define DDB_DCS5_BASE 0x13000000 /* DDB status regs */ +#define DDB_DCS5_SIZE 0x00200000 /* 2MB, 8-bit */ + +#define DDB_DCS4_BASE 0x14000000 /* DDB control regs */ +#define DDB_DCS4_SIZE 0x00200000 /* 2MB, 8-bit */ + +#define DDB_INTCS_BASE 0x1fa00000 /* VRC5476 control regs */ +#define DDB_INTCS_SIZE 0x00200000 /* 2MB */ + +#define DDB_BOOTCS_BASE 0x1fc00000 /* Boot ROM / EPROM /Flash */ +#define DDB_BOOTCS_SIZE 0x00200000 /* 2 MB - doc says 4MB */ + + +/* aliases */ +#define DDB_PCI_CONFIG_BASE DDB_PCI_MEM_BASE +#define DDB_PCI_CONFIG_SIZE DDB_PCI_MEM_SIZE + +/* PCI intr ack share PCIW0 with PCI IO */ +#define DDB_PCI_IACK_BASE DDB_PCI_IO_BASE + +/* + * Interrupt mapping + * + * We have three interrupt controllers: + * + * . CPU itself - 8 sources + * . i8259 - 16 sources + * . vrc5476 - 16 sources + * + * They connected as follows: + * all vrc5476 interrupts are routed to cpu IP2 (by software setting) + * all i2869 are routed to INTC in vrc5476 (by hardware connection) + * + * All VRC5476 PCI interrupts are level-triggered (no ack needed). + * All PCI irq but INTC are active low. + */ + +/* + * irq number block assignment + */ + +#define NUM_CPU_IRQ 8 +#define NUM_I8259_IRQ 16 +#define NUM_VRC5476_IRQ 16 + +#define DDB_IRQ_BASE 0 + +#define I8259_IRQ_BASE DDB_IRQ_BASE +#define VRC5476_IRQ_BASE (I8259_IRQ_BASE + NUM_I8259_IRQ) +#define CPU_IRQ_BASE (VRC5476_IRQ_BASE + NUM_VRC5476_IRQ) + +/* + * vrc5476 irq defs, see page 52-64 of Vrc5074 system controller manual + */ + +#define VRC5476_IRQ_CPCE 0 /* cpu parity error */ +#define VRC5476_IRQ_CNTD 1 /* cpu no target */ +#define VRC5476_IRQ_MCE 2 /* memory check error */ +#define VRC5476_IRQ_DMA 3 /* DMA */ +#define VRC5476_IRQ_UART 4 /* vrc5476 builtin UART, not used */ +#define VRC5476_IRQ_WDOG 5 /* watchdog timer */ +#define VRC5476_IRQ_GPT 6 /* general purpose timer */ +#define VRC5476_IRQ_LBRT 7 /* local bus read timeout */ +#define VRC5476_IRQ_INTA 8 /* PCI INT #A */ +#define VRC5476_IRQ_INTB 9 /* PCI INT #B */ +#define VRC5476_IRQ_INTC 10 /* PCI INT #C */ +#define VRC5476_IRQ_INTD 11 /* PCI INT #D */ +#define VRC5476_IRQ_INTE 12 /* PCI INT #E */ +#define VRC5476_IRQ_RESERVED_13 13 /* reserved */ +#define VRC5476_IRQ_PCIS 14 /* PCI SERR # */ +#define VRC5476_IRQ_PCI 15 /* PCI internal error */ + +/* + * i2859 irq assignment + */ +#define I8259_IRQ_RESERVED_0 0 +#define I8259_IRQ_KEYBOARD 1 /* M1543 default */ +#define I8259_IRQ_CASCADE 2 +#define I8259_IRQ_UART_B 3 /* M1543 default, may conflict with RTC according to schematic diagram */ +#define I8259_IRQ_UART_A 4 /* M1543 default */ +#define I8259_IRQ_PARALLEL 5 /* M1543 default */ +#define I8259_IRQ_RESERVED_6 6 +#define I8259_IRQ_RESERVED_7 7 +#define I8259_IRQ_RTC 8 /* who set this? */ +#define I8259_IRQ_USB 9 /* ddb_setup */ +#define I8259_IRQ_PMU 10 /* ddb_setup */ +#define I8259_IRQ_RESERVED_11 11 +#define I8259_IRQ_RESERVED_12 12 /* m1543_irq_setup */ +#define I8259_IRQ_RESERVED_13 13 +#define I8259_IRQ_HDC1 14 /* default and ddb_setup */ +#define I8259_IRQ_HDC2 15 /* default */ + + +/* + * misc + */ +#define VRC5476_I8259_CASCADE VRC5476_IRQ_INTC +#define CPU_VRC5476_CASCADE 2 + +#define is_i8259_irq(irq) ((irq) < NUM_I8259_IRQ) +#define nile4_to_irq(n) ((n)+NUM_I8259_IRQ) +#define irq_to_nile4(n) ((n)-NUM_I8259_IRQ) + +/* + * low-level irq functions + */ +#ifndef __ASSEMBLY__ +extern void nile4_map_irq(int nile4_irq, int cpu_irq); +extern void nile4_map_irq_all(int cpu_irq); +extern void nile4_enable_irq(int nile4_irq); +extern void nile4_disable_irq(int nile4_irq); +extern void nile4_disable_irq_all(void); +extern u16 nile4_get_irq_stat(int cpu_irq); +extern void nile4_enable_irq_output(int cpu_irq); +extern void nile4_disable_irq_output(int cpu_irq); +extern void nile4_set_pci_irq_polarity(int pci_irq, int high); +extern void nile4_set_pci_irq_level_or_edge(int pci_irq, int level); +extern void nile4_clear_irq(int nile4_irq); +extern void nile4_clear_irq_mask(u32 mask); +extern u8 nile4_i8259_iack(void); +extern void nile4_dump_irq_status(void); /* Debug */ +#endif /* !__ASSEMBLY__ */ diff -Nru a/include/asm-mips/ddb5xxx/ddb5477.h b/include/asm-mips/ddb5xxx/ddb5477.h --- a/include/asm-mips/ddb5xxx/ddb5477.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/ddb5xxx/ddb5477.h Fri Jun 27 14:19:54 2003 @@ -18,7 +18,6 @@ #define __ASM_DDB5XXX_DDB5477_H #include <linux/config.h> -#include <asm/ddb5xxx/ddb5xxx.h> /* * This contains macros that are specific to DDB5477 or renamed from @@ -28,9 +27,9 @@ /* * renamed PADRs */ -#define DDB_LCS0 DDB_LDCS0 -#define DDB_LCS1 DDB_LDCS1 -#define DDB_LCS2 DDB_LDCS2 +#define DDB_LCS0 DDB_DCS2 +#define DDB_LCS1 DDB_DCS3 +#define DDB_LCS2 DDB_DCS4 #define DDB_VRC5477 DDB_INTCS /* @@ -173,8 +172,10 @@ * corresponding size. For example, if PCI_IO_SIZE is 16MB, then * PCI_IO_BASE must be aligned along 16MB boundary. */ + +/* the actual ram size is detected at run-time */ #define DDB_SDRAM_BASE 0x00000000 -#define DDB_SDRAM_SIZE 0x08000000 /* 128MB, for sure? */ +#define DDB_MAX_SDRAM_SIZE 0x08000000 /* less than 128MB */ #define DDB_PCI0_MEM_BASE 0x08000000 #define DDB_PCI0_MEM_SIZE 0x08000000 /* 128 MB */ @@ -215,6 +216,7 @@ /* * DDB5477 specific functions */ +#ifndef __ASSEMBLY__ extern void ddb5477_irq_setup(void); /* route irq to cpu int pin */ @@ -223,16 +225,122 @@ /* low-level routine for enabling vrc5477 irq, bypassing high-level */ extern void ll_vrc5477_irq_enable(int vrc5477_irq); extern void ll_vrc5477_irq_disable(int vrc5477_irq); +#endif /* !__ASSEMBLY__ */ + +/* PCI intr ack share PCIW0 with PCI IO */ +#define DDB_PCI_IACK_BASE DDB_PCI_IO_BASE + +/* + * Interrupt mapping + * + * We have three interrupt controllers: + * + * . CPU itself - 8 sources + * . i8259 - 16 sources + * . vrc5477 - 32 sources + * + * They connected as follows: + * all vrc5477 interrupts are routed to cpu IP2 (by software setting) + * all i8359 are routed to INTC in vrc5477 (by hardware connection) + * + * All VRC5477 PCI interrupts are level-triggered (no ack needed). + * All PCI irq but INTC are active low. + */ /* + * irq number block assignment + */ + +#define NUM_CPU_IRQ 8 +#define NUM_I8259_IRQ 16 +#define NUM_VRC5477_IRQ 32 + +#define DDB_IRQ_BASE 0 + +#define I8259_IRQ_BASE DDB_IRQ_BASE +#define VRC5477_IRQ_BASE (I8259_IRQ_BASE + NUM_I8259_IRQ) +#define CPU_IRQ_BASE (VRC5477_IRQ_BASE + NUM_VRC5477_IRQ) + +/* + * vrc5477 irq defs + */ + +#define VRC5477_IRQ_CPCE (0 + VRC5477_IRQ_BASE) /* cpu parity error */ +#define VRC5477_IRQ_CNTD (1 + VRC5477_IRQ_BASE) /* cpu no target */ +#define VRC5477_IRQ_I2C (2 + VRC5477_IRQ_BASE) /* I2C */ +#define VRC5477_IRQ_DMA (3 + VRC5477_IRQ_BASE) /* DMA */ +#define VRC5477_IRQ_UART0 (4 + VRC5477_IRQ_BASE) +#define VRC5477_IRQ_WDOG (5 + VRC5477_IRQ_BASE) /* watchdog timer */ +#define VRC5477_IRQ_SPT1 (6 + VRC5477_IRQ_BASE) /* special purpose timer 1 */ +#define VRC5477_IRQ_LBRT (7 + VRC5477_IRQ_BASE) /* local bus read timeout */ +#define VRC5477_IRQ_INTA (8 + VRC5477_IRQ_BASE) /* PCI INT #A */ +#define VRC5477_IRQ_INTB (9 + VRC5477_IRQ_BASE) /* PCI INT #B */ +#define VRC5477_IRQ_INTC (10 + VRC5477_IRQ_BASE) /* PCI INT #C */ +#define VRC5477_IRQ_INTD (11 + VRC5477_IRQ_BASE) /* PCI INT #D */ +#define VRC5477_IRQ_INTE (12 + VRC5477_IRQ_BASE) /* PCI INT #E */ +#define VRC5477_IRQ_RESERVED_13 (13 + VRC5477_IRQ_BASE) /* reserved */ +#define VRC5477_IRQ_PCIS (14 + VRC5477_IRQ_BASE) /* PCI SERR # */ +#define VRC5477_IRQ_PCI (15 + VRC5477_IRQ_BASE) /* PCI internal error */ +#define VRC5477_IRQ_IOPCI_INTA (16 + VRC5477_IRQ_BASE) /* USB-H */ +#define VRC5477_IRQ_IOPCI_INTB (17 + VRC5477_IRQ_BASE) /* USB-P */ +#define VRC5477_IRQ_IOPCI_INTC (18 + VRC5477_IRQ_BASE) /* AC97 */ +#define VRC5477_IRQ_IOPCI_INTD (19 + VRC5477_IRQ_BASE) /* Reserved */ +#define VRC5477_IRQ_UART1 (20 + VRC5477_IRQ_BASE) +#define VRC5477_IRQ_SPT0 (21 + VRC5477_IRQ_BASE) /* special purpose timer 0 */ +#define VRC5477_IRQ_GPT0 (22 + VRC5477_IRQ_BASE) /* general purpose timer 0 */ +#define VRC5477_IRQ_GPT1 (23 + VRC5477_IRQ_BASE) /* general purpose timer 1 */ +#define VRC5477_IRQ_GPT2 (24 + VRC5477_IRQ_BASE) /* general purpose timer 2 */ +#define VRC5477_IRQ_GPT3 (25 + VRC5477_IRQ_BASE) /* general purpose timer 3 */ +#define VRC5477_IRQ_GPIO (26 + VRC5477_IRQ_BASE) +#define VRC5477_IRQ_SIO0 (27 + VRC5477_IRQ_BASE) +#define VRC5477_IRQ_SIO1 (28 + VRC5477_IRQ_BASE) +#define VRC5477_IRQ_RESERVED_29 (29 + VRC5477_IRQ_BASE) /* reserved */ +#define VRC5477_IRQ_IOPCISERR (30 + VRC5477_IRQ_BASE) /* IO PCI SERR # */ +#define VRC5477_IRQ_IOPCI (31 + VRC5477_IRQ_BASE) + +/* + * i2859 irq assignment + */ +#define I8259_IRQ_RESERVED_0 (0 + I8259_IRQ_BASE) +#define I8259_IRQ_KEYBOARD (1 + I8259_IRQ_BASE) /* M1543 default */ +#define I8259_IRQ_CASCADE (2 + I8259_IRQ_BASE) +#define I8259_IRQ_UART_B (3 + I8259_IRQ_BASE) /* M1543 default, may conflict with RTC according to schematic diagram */ +#define I8259_IRQ_UART_A (4 + I8259_IRQ_BASE) /* M1543 default */ +#define I8259_IRQ_PARALLEL (5 + I8259_IRQ_BASE) /* M1543 default */ +#define I8259_IRQ_RESERVED_6 (6 + I8259_IRQ_BASE) +#define I8259_IRQ_RESERVED_7 (7 + I8259_IRQ_BASE) +#define I8259_IRQ_RTC (8 + I8259_IRQ_BASE) /* who set this? */ +#define I8259_IRQ_USB (9 + I8259_IRQ_BASE) /* ddb_setup */ +#define I8259_IRQ_PMU (10 + I8259_IRQ_BASE) /* ddb_setup */ +#define I8259_IRQ_RESERVED_11 (11 + I8259_IRQ_BASE) +#define I8259_IRQ_RESERVED_12 (12 + I8259_IRQ_BASE) /* m1543_irq_setup */ +#define I8259_IRQ_RESERVED_13 (13 + I8259_IRQ_BASE) +#define I8259_IRQ_HDC1 (14 + I8259_IRQ_BASE) /* default and ddb_setup */ +#define I8259_IRQ_HDC2 (15 + I8259_IRQ_BASE) /* default */ + + +/* + * misc + */ +#define VRC5477_I8259_CASCADE (VRC5477_IRQ_INTC - VRC5477_IRQ_BASE) +#define CPU_VRC5477_CASCADE 2 + +/* * debug routines */ -#if defined(CONFIG_LL_DEBUG) +#ifndef __ASSEMBLY__ +#if defined(CONFIG_RUNTIME_DEBUG) extern void vrc5477_show_pdar_regs(void); extern void vrc5477_show_pci_regs(void); extern void vrc5477_show_bar_regs(void); extern void vrc5477_show_int_regs(void); extern void vrc5477_show_all_regs(void); #endif + +/* + * RAM size + */ +extern int board_ram_size; +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_DDB5XXX_DDB5477_H */ diff -Nru a/include/asm-mips/ddb5xxx/ddb5xxx.h b/include/asm-mips/ddb5xxx/ddb5xxx.h --- a/include/asm-mips/ddb5xxx/ddb5xxx.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/ddb5xxx/ddb5xxx.h Fri Jun 27 14:19:57 2003 @@ -1,5 +1,4 @@ -/*********************************************************************** - * +/* * Copyright 2001 MontaVista Software Inc. * Author: jsun@mvista.com or jsun@junsun.net * @@ -14,7 +13,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * - *********************************************************************** */ #ifndef __ASM_DDB5XXX_DDB5XXX_H @@ -23,8 +21,6 @@ #include <linux/config.h> #include <linux/types.h> -#include <asm/ddb5xxx/debug.h> - /* * This file is based on the following documentation: * @@ -34,8 +30,8 @@ * that are true for all DDB 5xxx boards. The modification is based on * * uPD31577(VRC5477) VR5432-SDRAM/PCI Bridge (Luke) - * Preliminary Specification Document, Rev 1.1, 27 Dec, 2000 - * + * Preliminary Specification Decoment, Rev 1.1, 27 Dec, 2000 + * */ @@ -49,12 +45,13 @@ #define DDB_SDRAM0 0x0000 /* SDRAM Bank 0 [R/W] */ #define DDB_SDRAM1 0x0008 /* SDRAM Bank 1 [R/W] */ -#define DDB_LDCS0 0x0010 /* Device Chip-Select 0 [R/W] */ -#define DDB_LDCS1 0x0018 /* Device Chip-Select 1 [R/W] */ -#define DDB_LDCS2 0x0020 /* Device Chip-Select 2 [R/W] */ -#define DDB_LDCS3 0x0028 /* Device Chip-Select 3 [R/W] */ -#define DDB_LDCS4 0x0030 /* Device Chip-Select 4 [R/W] */ -#define DDB_LDCS5 0x0038 /* Device Chip-Select 5 [R/W] */ +#define DDB_DCS2 0x0010 /* Device Chip-Select 2 [R/W] */ +#define DDB_DCS3 0x0018 /* Device Chip-Select 3 [R/W] */ +#define DDB_DCS4 0x0020 /* Device Chip-Select 4 [R/W] */ +#define DDB_DCS5 0x0028 /* Device Chip-Select 5 [R/W] */ +#define DDB_DCS6 0x0030 /* Device Chip-Select 6 [R/W] */ +#define DDB_DCS7 0x0038 /* Device Chip-Select 7 [R/W] */ +#define DDB_DCS8 0x0040 /* Device Chip-Select 8 [R/W] */ #define DDB_PCIW0 0x0060 /* PCI Address Window 0 [R/W] */ #define DDB_PCIW1 0x0068 /* PCI Address Window 1 [R/W] */ #define DDB_INTCS 0x0070 /* Controller Internal Registers and Devices */ @@ -177,8 +174,13 @@ static inline void ddb_sync(void) { +/* The DDB5074 doesn't seem to like these accesses. They kill the board on + * interrupt load + */ +#ifndef CONFIG_DDB5074 volatile u32 *p = (volatile u32 *)0xbfc00000; (void)(*p); +#endif } static inline void ddb_out32(u32 offset, u32 val) @@ -225,9 +227,9 @@ * Physical Device Address Registers */ -extern u32 +extern u32 ddb_calc_pdar(u32 phys, u32 size, int width, int on_memory_bus, int pci_visible); -extern void +extern void ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width, int on_memory_bus, int pci_visible); diff -Nru a/include/asm-mips/ddb5xxx/debug.h b/include/asm-mips/ddb5xxx/debug.h --- a/include/asm-mips/ddb5xxx/debug.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,42 +0,0 @@ -/*********************************************************************** - * - * Copyright 2001 MontaVista Software Inc. - * Author: jsun@mvista.com or jsun@junsun.net - * - * include/asm-mips/ddb5xxx/debug.h - * Some debug macros used by ddb code. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - *********************************************************************** - */ - -#ifndef __ASM_DDB5XXX_DEBUG_H -#define __ASM_DDB5XXX_DEBUG_H - -#include <linux/config.h> - -/* - * macro for catching spurious errors. Eable to LL_DEBUG in kernel hacking - * config menu. - */ -#ifdef CONFIG_LL_DEBUG - -#include <linux/kernel.h> - -#define MIPS_ASSERT(x) if (!(x)) { panic("MIPS_ASSERT failed at %s:%d\n", __FILE__, __LINE__); } -#define MIPS_VERIFY(x, y) MIPS_ASSERT(x y) -#define MIPS_DEBUG(x) do { x; } while (0) - -#else - -#define MIPS_ASSERT(x) -#define MIPS_VERIFY(x, y) x -#define MIPS_DEBUG(x) - -#endif - -#endif /* __ASM_DDB5XXX_DEBUG_H */ diff -Nru a/include/asm-mips/ddb5xxx/pci.h b/include/asm-mips/ddb5xxx/pci.h --- a/include/asm-mips/ddb5xxx/pci.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,34 +0,0 @@ -#ifndef __ASM_DDB5XXXX_PCI_H -#define __ASM_DDB5XXXX_PCI_H - -/* - * This file essentially defines the interface between board - * specific PCI code and MIPS common PCI code. Should potentially put - * into include/asm/pci.h file. - */ - -#include <linux/ioport.h> -#include <linux/pci.h> - -/* - * Each pci channel is a top-level PCI bus seem by CPU. A machine with - * multiple PCI channels may have multiple PCI host controllers or a - * single controller supporting multiple channels. - */ -struct pci_channel { - struct pci_ops *pci_ops; - struct resource *io_resource; - struct resource *mem_resource; -}; - -/* - * each board defines an array of pci_channels, that ends with all NULL entry - */ -extern struct pci_channel mips_pci_channels[]; - -/* - * board supplied pci irq fixup routine - */ -extern void pcibios_fixup_irqs(void); - -#endif /* __ASM_DDB5XXXX_PCI_H */ diff -Nru a/include/asm-mips/debug.h b/include/asm-mips/debug.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/debug.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,48 @@ +/* + * Debug macros for run-time debugging. Turned on/off with CONFIG_RUNTIME_DEBUG option. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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 _ASM_DEBUG_H +#define _ASM_DEBUG_H + +#include <linux/config.h> + +/* + * run-time macros for catching spurious errors. Eable CONFIG_RUNTIME_DEBUG in + * kernel hacking config menu to use them. + * + * Use them as run-time debugging aid. NEVER USE THEM AS ERROR HANDLING CODE!!! + */ + +#ifdef CONFIG_RUNTIME_DEBUG + +#include <linux/kernel.h> + +#define db_assert(x) if (!(x)) { \ + panic("assertion failed at %s:%d: %s\n", __FILE__, __LINE__, #x); } +#define db_warn(x) if (!(x)) { \ + printk(KERN_WARNING "warning at %s:%d: %s\n", __FILE__, __LINE__, #x); } +#define db_verify(x, y) db_assert(x y) +#define db_verify_warn(x, y) db_warn(x y) +#define db_run(x) do { x; } while (0) + +#else + +#define db_assert(x) +#define db_warn(x) +#define db_verify(x, y) x +#define db_verify_warn(x, y) x +#define db_run(x) + +#endif + +#endif /* _ASM_DEBUG_H */ diff -Nru a/include/asm-mips/dec/ecc.h b/include/asm-mips/dec/ecc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/ecc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,51 @@ +/* + * include/asm-mips/dec/ecc.h + * + * ECC handling logic definitions common to DECstation/DECsystem + * 5000/200 (KN02), 5000/240 (KN03), 5000/260 (KN05) and + * DECsystem 5900 (KN03), 5900/260 (KN05) systems. + * + * Copyright (C) 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_ECC_H +#define __ASM_MIPS_DEC_ECC_H + +/* + * Error Address Register bits. + * The register is r/wc -- any write clears it. + */ +#define KN0X_EAR_VALID (1<<31) /* error data valid, bus IRQ */ +#define KN0X_EAR_CPU (1<<30) /* CPU/DMA transaction */ +#define KN0X_EAR_WRITE (1<<29) /* write/read transaction */ +#define KN0X_EAR_ECCERR (1<<28) /* ECC/timeout or overrun */ +#define KN0X_EAR_RES_27 (1<<27) /* unused */ +#define KN0X_EAR_ADDRESS (0x7ffffff<<0) /* address involved */ + +/* + * Error Syndrome Register bits. + * The register is frozen when EAR.VALID is set, otherwise it records bits + * from the last memory read. The register is r/wc -- any write clears it. + */ +#define KN0X_ESR_VLDHI (1<<31) /* error data valid hi word */ +#define KN0X_ESR_CHKHI (0x7f<<24) /* check bits read from mem */ +#define KN0X_ESR_SNGHI (1<<23) /* single/double bit error */ +#define KN0X_ESR_SYNHI (0x7f<<16) /* syndrome from ECC logic */ +#define KN0X_ESR_VLDLO (1<<15) /* error data valid lo word */ +#define KN0X_ESR_CHKLO (0x7f<<8) /* check bits read from mem */ +#define KN0X_ESR_SNGLO (1<<7) /* single/double bit error */ +#define KN0X_ESR_SYNLO (0x7f<<0) /* syndrome from ECC logic */ + + +#ifndef __ASSEMBLY__ +struct pt_regs; +extern void dec_ecc_be_init(void); +extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup); +extern void dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs); +#endif + +#endif /* __ASM_MIPS_DEC_ECC_H */ diff -Nru a/include/asm-mips/dec/interrupts.h b/include/asm-mips/dec/interrupts.h --- a/include/asm-mips/dec/interrupts.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/dec/interrupts.h Fri Jun 27 14:19:55 2003 @@ -1,4 +1,4 @@ -/* +/* * Miscellaneous definitions used to initialise the interrupt vector table * with the machine-specific interrupt routines. * @@ -8,77 +8,118 @@ * * Copyright (C) 1997 by Paul M. Antoine. * reworked 1998 by Harald Koerfgen. + * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki */ -#ifndef __ASM_DEC_INTERRUPTS_H -#define __ASM_DEC_INTERRUPTS_H +#ifndef __ASM_DEC_INTERRUPTS_H +#define __ASM_DEC_INTERRUPTS_H + +#include <asm/mipsregs.h> -/* - * DECstation Interrupts - */ /* - * This list reflects the priority of the Interrupts. - * Exception: on kmins we have to handle Memory Error - * Interrupts before the TC Interrupts. + * The list of possible system devices which provide an + * interrupt. Not all devices exist on a given system. */ -#define CLOCK 0 -#define SCSI_DMA_INT 1 -#define SCSI_INT 2 -#define ETHER 3 -#define SERIAL 4 -#define TC0 5 -#define TC1 6 -#define TC2 7 -#define MEMORY 8 -#define FPU 9 -#define HALT 10 +#define DEC_IRQ_CASCADE 0 /* cascade from CSR or I/O ASIC */ + +/* Ordinary interrupts */ +#define DEC_IRQ_AB_RECV 1 /* ACCESS.bus receive */ +#define DEC_IRQ_AB_XMIT 2 /* ACCESS.bus transmit */ +#define DEC_IRQ_DZ11 3 /* DZ11 (DC7085) serial */ +#define DEC_IRQ_ASC 4 /* ASC (NCR53C94) SCSI */ +#define DEC_IRQ_FLOPPY 5 /* 82077 FDC */ +#define DEC_IRQ_FPU 6 /* R3k FPU */ +#define DEC_IRQ_HALT 7 /* HALT button or from ACCESS.Bus */ +#define DEC_IRQ_ISDN 8 /* Am79C30A ISDN */ +#define DEC_IRQ_LANCE 9 /* LANCE (Am7990) Ethernet */ +#define DEC_IRQ_BUS 10 /* memory, I/O bus read/write errors */ +#define DEC_IRQ_PSU 11 /* power supply unit warning */ +#define DEC_IRQ_RTC 12 /* DS1287 RTC */ +#define DEC_IRQ_SCC0 13 /* SCC (Z85C30) serial #0 */ +#define DEC_IRQ_SCC1 14 /* SCC (Z85C30) serial #1 */ +#define DEC_IRQ_SII 15 /* SII (DC7061) SCSI */ +#define DEC_IRQ_TC0 16 /* TURBOchannel slot #0 */ +#define DEC_IRQ_TC1 17 /* TURBOchannel slot #1 */ +#define DEC_IRQ_TC2 18 /* TURBOchannel slot #2 */ +#define DEC_IRQ_TIMER 19 /* ARC periodic timer */ +#define DEC_IRQ_VIDEO 20 /* framebuffer */ + +/* I/O ASIC DMA interrupts */ +#define DEC_IRQ_ASC_MERR 21 /* ASC memory read error */ +#define DEC_IRQ_ASC_ERR 22 /* ASC page overrun */ +#define DEC_IRQ_ASC_DMA 23 /* ASC buffer pointer loaded */ +#define DEC_IRQ_FLOPPY_ERR 24 /* FDC error */ +#define DEC_IRQ_ISDN_ERR 25 /* ISDN memory read/overrun error */ +#define DEC_IRQ_ISDN_RXDMA 26 /* ISDN recv buffer pointer loaded */ +#define DEC_IRQ_ISDN_TXDMA 27 /* ISDN xmit buffer pointer loaded */ +#define DEC_IRQ_LANCE_MERR 28 /* LANCE memory read error */ +#define DEC_IRQ_SCC0A_RXERR 29 /* SCC0A (printer) receive overrun */ +#define DEC_IRQ_SCC0A_RXDMA 30 /* SCC0A receive half page */ +#define DEC_IRQ_SCC0A_TXERR 31 /* SCC0A xmit memory read/overrun */ +#define DEC_IRQ_SCC0A_TXDMA 32 /* SCC0A transmit page end */ +#define DEC_IRQ_AB_RXERR 33 /* ACCESS.bus receive overrun */ +#define DEC_IRQ_AB_RXDMA 34 /* ACCESS.bus receive half page */ +#define DEC_IRQ_AB_TXERR 35 /* ACCESS.bus xmit memory read/ovrn */ +#define DEC_IRQ_AB_TXDMA 36 /* ACCESS.bus transmit page end */ +#define DEC_IRQ_SCC1A_RXERR 37 /* SCC1A (modem) receive overrun */ +#define DEC_IRQ_SCC1A_RXDMA 38 /* SCC1A receive half page */ +#define DEC_IRQ_SCC1A_TXERR 39 /* SCC1A xmit memory read/overrun */ +#define DEC_IRQ_SCC1A_TXDMA 40 /* SCC1A transmit page end */ + +/* TC5 & TC6 are virtual slots for KN02's onboard devices */ +#define DEC_IRQ_TC5 DEC_IRQ_ASC /* virtual PMAZ-AA */ +#define DEC_IRQ_TC6 DEC_IRQ_LANCE /* virtual PMAD-AA */ + +#define DEC_NR_INTS 41 + + +/* Largest of cpu mask_nr tables. */ +#define DEC_MAX_CPU_INTS 6 +/* Largest of asic mask_nr tables. */ +#define DEC_MAX_ASIC_INTS 9 -#define NR_INTS 11 -#ifndef __ASSEMBLY__ /* - * Data structure to hide the differences between the DECstation Interrupts - * - * If asic_mask == NULL, the interrupt is directly handled by the CPU. - * Otherwise this Interrupt is handled the IRQ Controller. + * CPU interrupt bits common to all systems. */ +#define DEC_CPU_INR_FPU 7 /* R3k FPU */ +#define DEC_CPU_INR_SW1 1 /* software #1 */ +#define DEC_CPU_INR_SW0 0 /* software #0 */ -typedef struct -{ - unsigned int cpu_mask; /* checking and enabling interrupts in CP0 */ - unsigned int iemask; /* enabling interrupts in IRQ Controller */ -} decint_t; - -extern volatile unsigned int *isr; - /* address of the interrupt status register */ -extern volatile unsigned int *imr; - /* address of the interrupt mask register */ -extern decint_t dec_interrupt[NR_INTS]; +#define DEC_CPU_IRQ_BASE 0 /* first IRQ assigned to CPU */ + +#define DEC_CPU_IRQ_NR(n) ((n) + DEC_CPU_IRQ_BASE) +#define DEC_CPU_IRQ_MASK(n) (1 << ((n) + CAUSEB_IP)) +#define DEC_CPU_IRQ_ALL (0xff << CAUSEB_IP) + + +#ifndef __ASSEMBLY__ /* - * Interrupt table structure to hide differences between different - * systems such. + * Interrupt table structures to hide differences between systems. */ -extern void *cpu_ivec_tbl[8]; -extern long cpu_mask_tbl[8]; -extern long cpu_irq_nr[8]; -extern long asic_irq_nr[32]; -extern long asic_mask_tbl[32]; +typedef union { int i; void *p; } int_ptr; +extern int dec_interrupt[DEC_NR_INTS]; +extern int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2]; +extern int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2]; +extern int cpu_fpu_mask; + /* * Common interrupt routine prototypes for all DECStations */ -extern void dec_intr_unimplemented(void); -extern void dec_intr_fpu(void); -extern void dec_intr_rtc(void); - -extern void kn02_io_int(void); -extern void kn02xa_io_int(void); -extern void kn03_io_int(void); +extern void kn02_io_int(void); +extern void kn02xa_io_int(void); +extern void kn03_io_int(void); +extern void asic_dma_int(void); +extern void asic_all_int(void); +extern void kn02_all_int(void); +extern void cpu_all_int(void); -extern void asic_intr_unimplemented(void); +extern void dec_intr_unimplemented(void); +extern void asic_intr_unimplemented(void); -#endif -#endif +#endif /* __ASSEMBLY__ */ +#endif diff -Nru a/include/asm-mips/dec/ioasic.h b/include/asm-mips/dec/ioasic.h --- a/include/asm-mips/dec/ioasic.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/dec/ioasic.h Fri Jun 27 14:19:57 2003 @@ -1,24 +1,36 @@ /* - * linux/asm-mips/dec/ioasic.h + * include/asm-mips/dec/ioasic.h * - * Copyright (C) 2000 Maciej W. Rozycki + * DEC I/O ASIC access operations. * - * DEC I/O ASIC access operations. + * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_DEC_IOASIC_H #define __ASM_DEC_IOASIC_H -extern volatile unsigned int *ioasic_base; +#include <linux/spinlock.h> +#include <linux/types.h> + +extern spinlock_t ioasic_ssr_lock; -extern inline void ioasic_write(unsigned int reg, unsigned int v) +extern volatile u32 *ioasic_base; + +static inline void ioasic_write(unsigned int reg, u32 v) { ioasic_base[reg / 4] = v; } -extern inline unsigned int ioasic_read(unsigned int reg) +static inline u32 ioasic_read(unsigned int reg) { return ioasic_base[reg / 4]; } + +extern void init_ioasic_irqs(int base); #endif /* __ASM_DEC_IOASIC_H */ diff -Nru a/include/asm-mips/dec/ioasic_addrs.h b/include/asm-mips/dec/ioasic_addrs.h --- a/include/asm-mips/dec/ioasic_addrs.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/dec/ioasic_addrs.h Fri Jun 27 14:19:53 2003 @@ -10,74 +10,142 @@ * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" * * and the Mach Sources + * + * Copyright (C) 199x the Anonymous + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ -#ifndef IOASIC_ADDRS_H -#define IOASIC_ADDRS_H +#ifndef __ASM_MIPS_DEC_IOASIC_ADDRS_H +#define __ASM_MIPS_DEC_IOASIC_ADDRS_H -#define CHUNK_SIZE 0x00040000 +#define IOASIC_SLOT_SIZE 0x00040000 + +/* + * Address ranges decoded by the I/O ASIC for onboard devices. + */ +#define IOASIC_SYS_ROM (0*IOASIC_SLOT_SIZE) /* system board ROM */ +#define IOASIC_IOCTL (1*IOASIC_SLOT_SIZE) /* I/O ASIC */ +#define IOASIC_ESAR (2*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */ +#define IOASIC_LANCE (3*IOASIC_SLOT_SIZE) /* LANCE Ethernet */ +#define IOASIC_SCC0 (4*IOASIC_SLOT_SIZE) /* SCC #0 */ +#define IOASIC_VDAC_HI (5*IOASIC_SLOT_SIZE) /* VDAC (maxine) */ +#define IOASIC_SCC1 (6*IOASIC_SLOT_SIZE) /* SCC #1 (3min, 3max+) */ +#define IOASIC_VDAC_LO (7*IOASIC_SLOT_SIZE) /* VDAC (maxine) */ +#define IOASIC_TOY (8*IOASIC_SLOT_SIZE) /* RTC */ +#define IOASIC_ISDN (9*IOASIC_SLOT_SIZE) /* ISDN (maxine) */ +#define IOASIC_ERRADDR (9*IOASIC_SLOT_SIZE) /* bus error address (3max+) */ +#define IOASIC_CHKSYN (10*IOASIC_SLOT_SIZE) /* ECC syndrome (3max+) */ +#define IOASIC_ACC_BUS (10*IOASIC_SLOT_SIZE) /* ACCESS.bus (maxine) */ +#define IOASIC_MCR (11*IOASIC_SLOT_SIZE) /* memory control (3max+) */ +#define IOASIC_FLOPPY (11*IOASIC_SLOT_SIZE) /* FDC (maxine) */ +#define IOASIC_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */ +#define IOASIC_FDC_DMA (13*IOASIC_SLOT_SIZE) /* FDC DMA (maxine) */ +#define IOASIC_SCSI_DMA (14*IOASIC_SLOT_SIZE) /* ??? */ +#define IOASIC_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */ -#define SYSTEM_ROM (0*CHUNK_SIZE) /* ??? */ -#define IOCTL (1*CHUNK_SIZE) -#define ESAR (2*CHUNK_SIZE) -#define LANCE (3*CHUNK_SIZE) -#define SCC0 (4*CHUNK_SIZE) -#define VDAC_HI (5*CHUNK_SIZE) /* maxine only */ -#define SCC1 (6*CHUNK_SIZE) -#define VDAC_LO (7*CHUNK_SIZE) /* maxine only */ -#define TOY (8*CHUNK_SIZE) -#define ISDN (9*CHUNK_SIZE) /* maxine only */ -#define ERRADDR (9*CHUNK_SIZE) /* 3maxplus only */ -#define CHKSYN (10*CHUNK_SIZE) /* 3maxplus only */ -#define ACCESS_BUS (10*CHUNK_SIZE) /* maxine only */ -#define MCR (11*CHUNK_SIZE) /* 3maxplus only */ -#define FLOPPY (11*CHUNK_SIZE) /* maxine only */ -#define SCSI (12*CHUNK_SIZE) -#define FLOPPY_DMA (13*CHUNK_SIZE) /* maxine only */ -#define SCSI_DMA (14*CHUNK_SIZE) -#define RESERVED_4 (15*CHUNK_SIZE) /* - * Offsets for IOCTL registers (relative to (system_base + IOCTL)) + * Offsets for I/O ASIC registers (relative to (system_base + IOASIC_IOCTL)). */ -#define SCSI_DMA_P 0x00 /* SCSI DMA Pointer */ -#define SCSI_DMA_BP 0x10 /* SCSI DMA Buffer Pointer */ -#define LANCE_DMA_P 0x20 /* LANCE DMA Pointer */ -#define SCC0_T_DMA_P 0x30 /* Communication Port 1 Transmit DMA Pointer */ -#define SCC0_R_DMA_P 0x40 /* Communication Port 1 Receive DMA Pointer */ -#define SCC1_T_DMA_P 0x50 /* Communication Port 2 Transmit DMA Pointer */ -#define SCC1_R_DMA_P 0x60 /* Communication Port 2 Receive DMA Pointer */ -#define FLOPPY_DMA_P 0x70 /* Floppy DMA Pointer */ -#define ISDN_T_DMA_P 0x80 /* ISDN Transmit DMA Pointer */ -#define ISDN_T_DMA_BP 0x90 /* ISDN Transmit DMA Buffer Pointer */ -#define ISDN_R_DMA_P 0xa0 /* ISDN Receive DMA Pointer */ -#define ISDN_R_DMA_BP 0xb0 /* ISDN Receive DMA Buffer Pointer */ - -#define SSR 0x100 /* System Support Register */ -#define SIR 0x110 /* System Interrupt Register */ -#define SIMR 0x120 /* System Interrupt Mask Register */ -#define FCTR 0x1e0 /* Free-Running Counter */ + /* all systems */ +#define IO_REG_SCSI_DMA_P 0x00 /* SCSI DMA Pointer */ +#define IO_REG_SCSI_DMA_BP 0x10 /* SCSI DMA Buffer Pointer */ +#define IO_REG_LANCE_DMA_P 0x20 /* LANCE DMA Pointer */ +#define IO_REG_SCC0A_T_DMA_P 0x30 /* SCC0A Transmit DMA Pointer */ +#define IO_REG_SCC0A_R_DMA_P 0x40 /* SCC0A Receive DMA Pointer */ + + /* except Maxine */ +#define IO_REG_SCC1A_T_DMA_P 0x50 /* SCC1A Transmit DMA Pointer */ +#define IO_REG_SCC1A_R_DMA_P 0x60 /* SCC1A Receive DMA Pointer */ + + /* Maxine */ +#define IO_REG_AB_T_DMA_P 0x50 /* ACCESS.bus Transmit DMA Pointer */ +#define IO_REG_AB_R_DMA_P 0x60 /* ACCESS.bus Receive DMA Pointer */ +#define IO_REG_FLOPPY_DMA_P 0x70 /* Floppy DMA Pointer */ +#define IO_REG_ISDN_T_DMA_P 0x80 /* ISDN Transmit DMA Pointer */ +#define IO_REG_ISDN_T_DMA_BP 0x90 /* ISDN Transmit DMA Buffer Pointer */ +#define IO_REG_ISDN_R_DMA_P 0xa0 /* ISDN Receive DMA Pointer */ +#define IO_REG_ISDN_R_DMA_BP 0xb0 /* ISDN Receive DMA Buffer Pointer */ + + /* all systems */ +#define IO_REG_DATA_0 0xc0 /* System Data Buffer 0 */ +#define IO_REG_DATA_1 0xd0 /* System Data Buffer 1 */ +#define IO_REG_DATA_2 0xe0 /* System Data Buffer 2 */ +#define IO_REG_DATA_3 0xf0 /* System Data Buffer 3 */ + + /* all systems */ +#define IO_REG_SSR 0x100 /* System Support Register */ +#define IO_REG_SIR 0x110 /* System Interrupt Register */ +#define IO_REG_SIMR 0x120 /* System Interrupt Mask Reg. */ +#define IO_REG_SAR 0x130 /* System Address Register */ + + /* Maxine */ +#define IO_REG_ISDN_T_DATA 0x140 /* ISDN Xmit Data Register */ +#define IO_REG_ISDN_R_DATA 0x150 /* ISDN Receive Data Register */ + + /* all systems */ +#define IO_REG_LANCE_SLOT 0x160 /* LANCE I/O Slot Register */ +#define IO_REG_SCSI_SLOT 0x170 /* SCSI Slot Register */ +#define IO_REG_SCC0A_SLOT 0x180 /* SCC0A DMA Slot Register */ + + /* except Maxine */ +#define IO_REG_SCC1A_SLOT 0x190 /* SCC1A DMA Slot Register */ + + /* Maxine */ +#define IO_REG_AB_SLOT 0x190 /* ACCESS.bus DMA Slot Register */ +#define IO_REG_FLOPPY_SLOT 0x1a0 /* Floppy Slot Register */ + + /* all systems */ +#define IO_REG_SCSI_SCR 0x1b0 /* SCSI Partial-Word DMA Control */ +#define IO_REG_SCSI_SDR0 0x1c0 /* SCSI DMA Partial Word 0 */ +#define IO_REG_SCSI_SDR1 0x1d0 /* SCSI DMA Partial Word 1 */ +#define IO_REG_FCTR 0x1e0 /* Free-Running Counter */ +#define IO_REG_RES_31 0x1f0 /* unused */ + /* - * Handle partial word SCSI DMA transfers + * The upper 16 bits of the System Support Register are a part of the + * I/O ASIC's internal DMA engine and thus are common to all I/O ASIC + * machines. The exception is the Maxine, which makes use of the + * FLOPPY and ISDN bits (otherwise unused) and has a different SCC + * wiring. */ -#define SCSI_SCR 0x1b0 -#define SCSI_SDR0 0x1c0 -#define SCSI_SDR1 0x1d0 + /* all systems */ +#define IO_SSR_SCC0A_TX_DMA_EN (1<<31) /* SCC0A transmit DMA enable */ +#define IO_SSR_SCC0A_RX_DMA_EN (1<<30) /* SCC0A receive DMA enable */ +#define IO_SSR_RES_27 (1<<27) /* unused */ +#define IO_SSR_RES_26 (1<<26) /* unused */ +#define IO_SSR_RES_25 (1<<25) /* unused */ +#define IO_SSR_RES_24 (1<<24) /* unused */ +#define IO_SSR_RES_23 (1<<23) /* unused */ +#define IO_SSR_SCSI_DMA_DIR (1<<18) /* SCSI DMA direction */ +#define IO_SSR_SCSI_DMA_EN (1<<17) /* SCSI DMA enable */ +#define IO_SSR_LANCE_DMA_EN (1<<16) /* LANCE DMA enable */ + + /* except Maxine */ +#define IO_SSR_SCC1A_TX_DMA_EN (1<<29) /* SCC1A transmit DMA enable */ +#define IO_SSR_SCC1A_RX_DMA_EN (1<<28) /* SCC1A receive DMA enable */ +#define IO_SSR_RES_22 (1<<22) /* unused */ +#define IO_SSR_RES_21 (1<<21) /* unused */ +#define IO_SSR_RES_20 (1<<20) /* unused */ +#define IO_SSR_RES_19 (1<<19) /* unused */ + + /* Maxine */ +#define IO_SSR_AB_TX_DMA_EN (1<<29) /* ACCESS.bus xmit DMA enable */ +#define IO_SSR_AB_RX_DMA_EN (1<<28) /* ACCESS.bus recv DMA enable */ +#define IO_SSR_FLOPPY_DMA_DIR (1<<22) /* Floppy DMA direction */ +#define IO_SSR_FLOPPY_DMA_EN (1<<21) /* Floppy DMA enable */ +#define IO_SSR_ISDN_TX_DMA_EN (1<<20) /* ISDN transmit DMA enable */ +#define IO_SSR_ISDN_RX_DMA_EN (1<<19) /* ISDN receive DMA enable */ /* - * DMA defines for the System Support Register + * The lower 16 bits are system-specific. Bits 15,11:8 are common and + * defined here. The rest is defined in system-specific headers. */ -#define LANCE_DMA_EN (1UL<<16) /* LANCE DMA enable */ -#define SCSI_DMA_EN (1UL<<17) /* SCSI DMA enable */ -#define SCSI_DMA_DIR (1UL<<18) /* SCSI DMA direction */ -#define ISDN_REC_DMA_EN (1UL<<19) /* ISDN receive DMA enable */ -#define ISDN_TRN_DMA_EN (1UL<<20) /* ISDN transmit DMA enable */ -#define FLOPPY_DMA_EN (1UL<<21) /* Floppy DMA enable */ -#define FLOPPY_DMA_DIR (1UL<<22) /* Floppy DMA direction */ -#define SCC1A_DMA_EN (1UL<<28) /* SCC1 Channel A DMA enable */ -#define SCC1B_DMA_EN (1UL<<29) /* SCC1 Channel B DMA enable */ -#define SCC0A_DMA_EN (1UL<<30) /* SCC0 Channel A DMA enable */ -#define SCC0B_DMA_EN (1UL<<31) /* Scc0 Channel B DMA enable */ +#define KN0X_IO_SSR_DIAGDN (1<<15) /* diagnostic jumper */ +#define KN0X_IO_SSR_SCC_RST (1<<11) /* ~SCC0,1 (Z85C30) reset */ +#define KN0X_IO_SSR_RTC_RST (1<<10) /* ~RTC (DS1287) reset */ +#define KN0X_IO_SSR_ASC_RST (1<<9) /* ~ASC (NCR53C94) reset */ +#define KN0X_IO_SSR_LANCE_RST (1<<8) /* ~LANCE (Am7990) reset */ -#endif +#endif /* __ASM_MIPS_DEC_IOASIC_ADDRS_H */ diff -Nru a/include/asm-mips/dec/ioasic_ints.h b/include/asm-mips/dec/ioasic_ints.h --- a/include/asm-mips/dec/ioasic_ints.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-mips/dec/ioasic_ints.h Fri Jun 27 14:20:01 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Definitions for the interrupt related bits in the JUNKIO Asic + * Definitions for the interrupt related bits in the I/O ASIC * interrupt status register (and the interrupt mask register, of course) * * Created with Information from: @@ -11,99 +11,64 @@ * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" * * and the Mach Sources + * + * Copyright (C) 199x the Anonymous + * Copyright (C) 2002 Maciej W. Rozycki */ -/* - * the upper 16 bits are common to all JUNKIO machines - * (except the FLOPPY and ISDN bits, which are Maxine sepcific) - */ -#define SCC0_TRANS_PAGEEND 0x80000000 /* Serial DMA Errors */ -#define SCC0_TRANS_MEMRDERR 0x40000000 /* see below */ -#define SCC0_RECV_HALFPAGE 0x20000000 -#define SCC0_RECV_PAGOVRRUN 0x10000000 -#define SCC1_TRANS_PAGEEND 0x08000000 /* end of page reached */ -#define SCC1_TRANS_MEMRDERR 0x04000000 /* SCC1 DMA memory err */ -#define SCC1_RECV_HALFPAGE 0x02000000 /* SCC1 half page */ -#define SCC1_RECV_PAGOVRRUN 0x01000000 /* SCC1 receive overrun */ -#define FLOPPY_DMA_ERROR 0x00800000 /* FDI DMA error */ -#define ISDN_TRANS_PTR_LOADED 0x00400000 /* xmitbuf ptr loaded */ -#define ISDN_RECV_PTR_LOADED 0x00200000 /* rcvbuf ptr loaded */ -#define ISDN_DMA_MEMRDERR 0x00100000 /* read or ovrrun error */ -#define SCSI_PTR_LOADED 0x00080000 -#define SCSI_PAGOVRRUN 0x00040000 /* page overrun? */ -#define SCSI_DMA_MEMRDERR 0x00020000 -#define LANCE_DMA_MEMRDERR 0x00010000 - -/* - * the lower 16 bits are system specific - */ - -/* - * The following three seem to be in common - */ -#define SCSI_CHIP 0x00000200 -#define LANCE_CHIP 0x00000100 -#define SCC1_CHIP 0x00000080 /* NOT on maxine */ -#define SCC0_CHIP 0x00000040 +#ifndef __ASM_DEC_IOASIC_INTS_H +#define __ASM_DEC_IOASIC_INTS_H /* - * The rest is different - */ + * The upper 16 bits are a part of the I/O ASIC's internal DMA engine + * and thus are common to all I/O ASIC machines. The exception is + * the Maxine, which makes use of the FLOPPY and ISDN bits (otherwise + * unused) and has a different SCC wiring. + */ + /* all systems */ +#define IO_INR_SCC0A_TXDMA 31 /* SCC0A transmit page end */ +#define IO_INR_SCC0A_TXERR 30 /* SCC0A transmit memory read error */ +#define IO_INR_SCC0A_RXDMA 29 /* SCC0A receive half page */ +#define IO_INR_SCC0A_RXERR 28 /* SCC0A receive overrun */ +#define IO_INR_ASC_DMA 19 /* ASC buffer pointer loaded */ +#define IO_INR_ASC_ERR 18 /* ASC page overrun */ +#define IO_INR_ASC_MERR 17 /* ASC memory read error */ +#define IO_INR_LANCE_MERR 16 /* LANCE memory read error */ + + /* except Maxine */ +#define IO_INR_SCC1A_TXDMA 27 /* SCC1A transmit page end */ +#define IO_INR_SCC1A_TXERR 26 /* SCC1A transmit memory read error */ +#define IO_INR_SCC1A_RXDMA 25 /* SCC1A receive half page */ +#define IO_INR_SCC1A_RXERR 24 /* SCC1A receive overrun */ +#define IO_INR_RES_23 23 /* unused */ +#define IO_INR_RES_22 22 /* unused */ +#define IO_INR_RES_21 21 /* unused */ +#define IO_INR_RES_20 20 /* unused */ + + /* Maxine */ +#define IO_INR_AB_TXDMA 27 /* ACCESS.bus transmit page end */ +#define IO_INR_AB_TXERR 26 /* ACCESS.bus xmit memory read error */ +#define IO_INR_AB_RXDMA 25 /* ACCESS.bus receive half page */ +#define IO_INR_AB_RXERR 24 /* ACCESS.bus receive overrun */ +#define IO_INR_FLOPPY_ERR 23 /* FDC error */ +#define IO_INR_ISDN_TXDMA 22 /* ISDN xmit buffer pointer loaded */ +#define IO_INR_ISDN_RXDMA 21 /* ISDN recv buffer pointer loaded */ +#define IO_INR_ISDN_ERR 20 /* ISDN memory read/overrun error */ -/* kmin aka 3min aka kn02ba aka DS5000_1xx */ -#define KMIN_TIMEOUT 0x00001000 /* CPU IO-Write Timeout */ -#define KMIN_CLOCK 0x00000020 -#define KMIN_SCSI_FIFO 0x00000004 /* SCSI Data Ready */ - -/* kn02ca aka maxine */ -#define MAXINE_FLOPPY 0x00008000 /* FDI Interrupt */ -#define MAXINE_TC0 0x00001000 /* TC Option 0 */ -#define MAXINE_ISDN 0x00000800 /* ISDN Chip */ -#define MAXINE_FLOPPY_HDS 0x00000080 /* Floppy Status */ -#define MAXINE_TC1 0x00000020 /* TC Option 1 */ -#define MAXINE_FLOPPY_XDS 0x00000010 /* Floppy Status */ -#define MAXINE_VINT 0x00000008 /* Video Frame */ -#define MAXINE_N_VINT 0x00000004 /* Not Video frame */ -#define MAXINE_DTOP_TRANS 0x00000002 /* DTI Xmit-Rdy */ -#define MAXINE_DTOP_RECV 0x00000001 /* DTI Recv-Available */ - -/* kn03 aka 3max+ aka DS5000_2x0 */ -#define KN03_TC2 0x00002000 -#define KN03_TC1 0x00001000 -#define KN03_TC0 0x00000800 -#define KN03_SCSI_FIFO 0x00000004 /* ??? Info from Mach */ +#define IO_INR_DMA 16 /* first DMA IRQ */ /* - * Now form groups, i.e. all serial interrupts, all SCSI interrupts and so on. + * The lower 16 bits are system-specific and thus defined in + * system-specific headers. */ -#define SERIAL_INTS (SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \ - SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \ - SCC1_TRANS_PAGEEND | SCC1_TRANS_MEMRDERR | \ - SCC1_RECV_HALFPAGE | SCC1_RECV_PAGOVRRUN | \ - SCC1_CHIP | SCC0_CHIP) - -#define XINE_SERIAL_INTS (SCC0_TRANS_PAGEEND | SCC0_TRANS_MEMRDERR | \ - SCC0_RECV_HALFPAGE | SCC0_RECV_PAGOVRRUN | \ - SCC0_CHIP) - -#define SCSI_DMA_INTS (/* SCSI_PTR_LOADED | */ SCSI_PAGOVRRUN | \ - SCSI_DMA_MEMRDERR) - -#define KMIN_SCSI_INTS (SCSI_PTR_LOADED | SCSI_PAGOVRRUN | \ - SCSI_DMA_MEMRDERR | SCSI_CHIP | KMIN_SCSI_FIFO) -#define LANCE_INTS (LANCE_DMA_MEMRDERR | LANCE_CHIP) - -/* - * For future use ... - */ -#define XINE_FLOPPY_INTS (MAXINE_FLOPPY | MAXINE_FLOPPY_HDS | \ - FLOPPY_DMA_ERROR | MAXINE_FLOPPY_XDS) -#define XINE_ISDN_INTS (MAXINE_ISDN | ISDN_TRANS_PTR_LOADED | \ - ISDN_RECV_PTR_LOADED | ISDN_DMA_MEMRDERR) +#define IO_IRQ_BASE 8 /* first IRQ assigned to I/O ASIC */ +#define IO_IRQ_LINES 32 /* number of I/O ASIC interrupts */ -#define XINE_DTOP_INTS (MAXINE_DTOP_TRANS | DTOP_RECV | \ - ISDN_TRANS_PTR_LOADED | ISDN_RECV_PTR_LOADED | \ - ISDN_DMA_MEMRDERR) +#define IO_IRQ_NR(n) ((n) + IO_IRQ_BASE) +#define IO_IRQ_MASK(n) (1 << (n)) +#define IO_IRQ_ALL 0x0000ffff +#define IO_IRQ_DMA 0xffff0000 +#endif /* __ASM_DEC_IOASIC_INTS_H */ diff -Nru a/include/asm-mips/dec/kn01.h b/include/asm-mips/dec/kn01.h --- a/include/asm-mips/dec/kn01.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/dec/kn01.h Fri Jun 27 14:19:54 2003 @@ -1,28 +1,83 @@ /* - * Hardware info about DEC DECstation DS2100/3100 systems (otherwise known - * as pmax or kn01. + * Hardware info about DECstation DS2100/3100 systems (otherwise known as + * pmin/pmax or KN01). * * 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) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * - * This file is under construction - you were warned! + * are by courtesy of Chris Fraser. + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ -#ifndef __ASM_MIPS_DEC_KN01_H -#define __ASM_MIPS_DEC_KN01_H +#ifndef __ASM_MIPS_DEC_KN01_H +#define __ASM_MIPS_DEC_KN01_H #include <asm/addrspace.h> +#define KN01_SLOT_BASE KSEG1ADDR(0x10000000) +#define KN01_SLOT_SIZE 0x01000000 + +/* + * Address ranges for devices. + */ +#define KN01_PMASK (0*KN01_SLOT_SIZE) /* color plane mask */ +#define KN01_PCC (1*KN01_SLOT_SIZE) /* PCC (DC503) cursor */ +#define KN01_VDAC (2*KN01_SLOT_SIZE) /* color map */ +#define KN01_RES_3 (3*KN01_SLOT_SIZE) /* unused */ +#define KN01_RES_4 (4*KN01_SLOT_SIZE) /* unused */ +#define KN01_RES_5 (5*KN01_SLOT_SIZE) /* unused */ +#define KN01_RES_6 (6*KN01_SLOT_SIZE) /* unused */ +#define KN01_ERRADDR (7*KN01_SLOT_SIZE) /* write error address */ +#define KN01_LANCE (8*KN01_SLOT_SIZE) /* LANCE (Am7990) Ethernet */ +#define KN01_LANCE_MEM (9*KN01_SLOT_SIZE) /* LANCE buffer memory */ +#define KN01_SII (10*KN01_SLOT_SIZE) /* SII (DC7061) SCSI */ +#define KN01_SII_MEM (11*KN01_SLOT_SIZE) /* SII buffer memory */ +#define KN01_DZ11 (12*KN01_SLOT_SIZE) /* DZ11 (DC7085) serial */ +#define KN01_RTC (13*KN01_SLOT_SIZE) /* DS1287 RTC (bytes #0) */ +#define KN01_ESAR (13*KN01_SLOT_SIZE) /* MAC address (bytes #1) */ +#define KN01_CSR (14*KN01_SLOT_SIZE) /* system ctrl & status reg */ +#define KN01_SYS_ROM (15*KN01_SLOT_SIZE) /* system board ROM */ + + /* * Some port addresses... - * FIXME: these addresses are incomplete and need tidying up! */ +#define KN01_LANCE_BASE (KN01_SLOT_BASE + KN01_LANCE) /* 0xB8000000 */ +#define KN01_DZ11_BASE (KN01_SLOT_BASE + KN01_DZ11) /* 0xBC000000 */ +#define KN01_RTC_BASE (KN01_SLOT_BASE + KN01_RTC) /* 0xBD000000 */ + + +/* + * Frame buffer memory address. + */ +#define KN01_VFB_MEM KSEG1ADDR(0x0fc00000) + +/* + * CPU interrupt bits. + */ +#define KN01_CPU_INR_BUS 6 /* memory, I/O bus read/write errors */ +#define KN01_CPU_INR_VIDEO 6 /* PCC area detect #2 */ +#define KN01_CPU_INR_RTC 5 /* DS1287 RTC */ +#define KN01_CPU_INR_DZ11 4 /* DZ11 (DC7085) serial */ +#define KN01_CPU_INR_LANCE 3 /* LANCE (Am7990) Ethernet */ +#define KN01_CPU_INR_SII 2 /* SII (DC7061) SCSI */ + -#define KN01_LANCE_BASE (KSEG1ADDR(0x18000000)) /* 0xB8000000 */ -#define KN01_DZ11_BASE (KSEG1ADDR(0x1c000000)) /* 0xBC000000 */ -#define KN01_RTC_BASE (KSEG1ADDR(0x1d000000)) /* 0xBD000000 */ +/* + * System Control & Status Register bits. + */ +#define KN01_CSR_MNFMOD (1<<15) /* MNFMOD manufacturing jumper */ +#define KN01_CSR_STATUS (1<<14) /* self-test result status output */ +#define KN01_CSR_PARDIS (1<<13) /* parity error disable */ +#define KN01_CSR_CRSRTST (1<<12) /* PCC test output */ +#define KN01_CSR_MONO (1<<11) /* mono/color fb SIMM installed */ +#define KN01_CSR_MEMERR (1<<10) /* write timeout error status & ack*/ +#define KN01_CSR_VINT (1<<9) /* PCC area detect #2 status & ack */ +#define KN01_CSR_TXDIS (1<<8) /* DZ11 transmit disable */ +#define KN01_CSR_VBGTRG (1<<2) /* blue DAC voltage over green (r/o) */ +#define KN01_CSR_VRGTRG (1<<1) /* red DAC voltage over green (r/o) */ +#define KN01_CSR_VRGTRB (1<<0) /* red DAC voltage over blue (r/o) */ +#define KN01_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */ #endif /* __ASM_MIPS_DEC_KN01_H */ diff -Nru a/include/asm-mips/dec/kn02.h b/include/asm-mips/dec/kn02.h --- a/include/asm-mips/dec/kn02.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/dec/kn02.h Fri Jun 27 14:19:59 2003 @@ -1,43 +1,106 @@ /* - * Hardware info about DEC DECstation 5000/2xx systems (otherwise known - * as 3max or kn02. + * Hardware info about DECstation 5000/200 systems (otherwise known as + * 3max or KN02). * * 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) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * - * This file is under construction - you were warned! + * are by courtesy of Chris Fraser. + * Copyright (C) 2002, 2003 Maciej W. Rozycki */ -#ifndef __ASM_MIPS_DEC_KN02_H -#define __ASM_MIPS_DEC_KN02_H +#ifndef __ASM_MIPS_DEC_KN02_H +#define __ASM_MIPS_DEC_KN02_H + +#ifndef __ASSEMBLY__ +#include <linux/spinlock.h> +#include <linux/types.h> +#endif #include <asm/addrspace.h> +#include <asm/dec/ecc.h> + + +#define KN02_SLOT_BASE KSEG1ADDR(0x1fc00000) +#define KN02_SLOT_SIZE 0x00080000 /* - * Motherboard regs (kseg1 addresses) + * Address ranges decoded by the "system slot" logic for onboard devices. */ -#define KN02_CSR_ADDR KSEG1ADDR(0x1ff00000) /* system control & status reg */ +#define KN02_SYS_ROM (0*KN02_SLOT_SIZE) /* system board ROM */ +#define KN02_RES_1 (1*KN02_SLOT_SIZE) /* unused */ +#define KN02_CHKSYN (2*KN02_SLOT_SIZE) /* ECC syndrome */ +#define KN02_ERRADDR (3*KN02_SLOT_SIZE) /* bus error address */ +#define KN02_DZ11 (4*KN02_SLOT_SIZE) /* DZ11 (DC7085) serial */ +#define KN02_RTC (5*KN02_SLOT_SIZE) /* DS1287 RTC */ +#define KN02_CSR (6*KN02_SLOT_SIZE) /* system ctrl & status reg */ +#define KN02_SYS_ROM_7 (7*KN02_SLOT_SIZE) /* system board ROM (alias) */ + /* * Some port addresses... - * FIXME: these addresses are incomplete and need tidying up! */ -#define KN02_RTC_BASE KSEG1ADDR(0x1fe80000) -#define KN02_DZ11_BASE KSEG1ADDR(0x1fe00000) +#define KN02_DZ11_BASE (KN02_SLOT_BASE + KN02_DZ11) /* DZ11 */ +#define KN02_RTC_BASE (KN02_SLOT_BASE + KN02_RTC) /* RTC */ +#define KN02_CSR_BASE (KN02_SLOT_BASE + KN02_CSR) /* CSR */ + + +/* + * System Control & Status Register bits. + */ +#define KN02_CSR_RES_28 (0xf<<28) /* unused */ +#define KN02_CSR_PSU (1<<27) /* power supply unit warning */ +#define KN02_CSR_NVRAM (1<<26) /* ~NVRAM clear jumper */ +#define KN02_CSR_REFEVEN (1<<25) /* mem refresh bank toggle */ +#define KN03_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */ +#define KN03_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */ +#define KN02_CSR_DIAGCHK (1<<15) /* diagn/norml ECC reads */ +#define KN02_CSR_DIAGGEN (1<<14) /* diagn/norml ECC writes */ +#define KN02_CSR_CORRECT (1<<13) /* ECC correct/check */ +#define KN02_CSR_LEDIAG (1<<12) /* ECC diagn. latch strobe */ +#define KN02_CSR_TXDIS (1<<11) /* DZ11 transmit disable */ +#define KN02_CSR_BNK32M (1<<10) /* 32M/8M stride */ +#define KN02_CSR_DIAGDN (1<<9) /* DIAGDN manufact. jumper */ +#define KN02_CSR_BAUD38 (1<<8) /* DZ11 38/19kbps ext. rate */ +#define KN03_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */ +#define KN03_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */ -#define KN02_CSR_BNK32M (1<<10) /* 32M stride */ /* - * Interrupt enable Bits + * CPU interrupt bits. */ -#define KN02_SLOT0 (1<<16) -#define KN02_SLOT1 (1<<17) -#define KN02_SLOT2 (1<<18) -#define KN02_SLOT5 (1<<21) -#define KN02_SLOT6 (1<<22) -#define KN02_SLOT7 (1<<23) +#define KN02_CPU_INR_RES_6 6 /* unused */ +#define KN02_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */ +#define KN02_CPU_INR_RES_4 4 /* unused */ +#define KN02_CPU_INR_RTC 3 /* DS1287 RTC */ +#define KN02_CPU_INR_CASCADE 2 /* CSR cascade */ + +/* + * CSR interrupt bits. + */ +#define KN02_CSR_INR_DZ11 7 /* DZ11 (DC7085) serial */ +#define KN02_CSR_INR_LANCE 6 /* LANCE (Am7990) Ethernet */ +#define KN02_CSR_INR_ASC 5 /* ASC (NCR53C94) SCSI */ +#define KN02_CSR_INR_RES_4 4 /* unused */ +#define KN02_CSR_INR_RES_3 3 /* unused */ +#define KN02_CSR_INR_TC2 2 /* TURBOchannel slot #2 */ +#define KN02_CSR_INR_TC1 1 /* TURBOchannel slot #1 */ +#define KN02_CSR_INR_TC0 0 /* TURBOchannel slot #0 */ + + +#define KN02_IRQ_BASE 8 /* first IRQ assigned to CSR */ +#define KN02_IRQ_LINES 8 /* number of CSR interrupts */ + +#define KN02_IRQ_NR(n) ((n) + KN02_IRQ_BASE) +#define KN02_IRQ_MASK(n) (1 << (n)) +#define KN02_IRQ_ALL 0xff + + +#ifndef __ASSEMBLY__ +extern u32 cached_kn02_csr; +extern spinlock_t kn02_lock; +extern void init_kn02_irqs(int base); +#endif #endif /* __ASM_MIPS_DEC_KN02_H */ diff -Nru a/include/asm-mips/dec/kn02ba.h b/include/asm-mips/dec/kn02ba.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/kn02ba.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,67 @@ +/* + * include/asm-mips/dec/kn02ba.h + * + * DECstation 5000/1xx (3min or KN02-BA) definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_KN02BA_H +#define __ASM_MIPS_DEC_KN02BA_H + +#include <asm/dec/kn02xa.h> /* For common definitions. */ + +/* + * CPU interrupt bits. + */ +#define KN02BA_CPU_INR_HALT 6 /* HALT button */ +#define KN02BA_CPU_INR_CASCADE 5 /* I/O ASIC cascade */ +#define KN02BA_CPU_INR_TC2 4 /* TURBOchannel slot #2 */ +#define KN02BA_CPU_INR_TC1 3 /* TURBOchannel slot #1 */ +#define KN02BA_CPU_INR_TC0 2 /* TURBOchannel slot #0 */ + +/* + * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits. + */ +#define KN02BA_IO_INR_RES_15 15 /* unused */ +#define KN02BA_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */ +#define KN02BA_IO_INR_RES_13 13 /* unused */ +#define KN02BA_IO_INR_BUS 12 /* memory, I/O bus read/write errors */ +#define KN02BA_IO_INR_RES_11 11 /* unused */ +#define KN02BA_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */ +#define KN02BA_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */ +#define KN02BA_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */ +#define KN02BA_IO_INR_SCC1 7 /* SCC (Z85C30) serial #1 */ +#define KN02BA_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */ +#define KN02BA_IO_INR_RTC 5 /* DS1287 RTC */ +#define KN02BA_IO_INR_PSU 4 /* power supply unit warning */ +#define KN02BA_IO_INR_RES_3 3 /* unused */ +#define KN02BA_IO_INR_ASC_DATA 2 /* SCSI data ready (for PIO) */ +#define KN02BA_IO_INR_PBNC 1 /* ~HALT button debouncer */ +#define KN02BA_IO_INR_PBNO 0 /* HALT button debouncer */ + + +/* + * Memory Error Register bits. + */ +#define KN02BA_MER_RES_27 (1<<27) /* unused */ + +/* + * Memory Size Register bits. + */ +#define KN02BA_MSR_RES_17 (0x3ff<<17) /* unused */ + +/* + * I/O ASIC System Support Register bits. + */ +#define KN02BA_IO_SSR_TXDIS1 (1<<14) /* SCC1 transmit disable */ +#define KN02BA_IO_SSR_TXDIS0 (1<<13) /* SCC0 transmit disable */ +#define KN02BA_IO_SSR_RES_12 (1<<12) /* unused */ + +#define KN02BA_IO_SSR_LEDS (0xff<<0) /* ~diagnostic LEDs */ + +#endif /* __ASM_MIPS_DEC_KN02BA_H */ diff -Nru a/include/asm-mips/dec/kn02ca.h b/include/asm-mips/dec/kn02ca.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/kn02ca.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,79 @@ +/* + * include/asm-mips/dec/kn02ca.h + * + * Personal DECstation 5000/xx (Maxine or KN02-CA) definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_KN02CA_H +#define __ASM_MIPS_DEC_KN02CA_H + +#include <asm/dec/kn02xa.h> /* For common definitions. */ + +/* + * CPU interrupt bits. + */ +#define KN02CA_CPU_INR_HALT 6 /* HALT from ACCESS.Bus */ +#define KN02CA_CPU_INR_CASCADE 5 /* I/O ASIC cascade */ +#define KN02CA_CPU_INR_BUS 4 /* memory, I/O bus read/write errors */ +#define KN02CA_CPU_INR_RTC 3 /* DS1287 RTC */ +#define KN02CA_CPU_INR_TIMER 2 /* ARC periodic timer */ + +/* + * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits. + */ +#define KN02CA_IO_INR_FLOPPY 15 /* 82077 FDC */ +#define KN02CA_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */ +#define KN02CA_IO_INR_POWERON 13 /* (*) ACCESS.Bus/power-on reset */ +#define KN02CA_IO_INR_TC0 12 /* TURBOchannel slot #0 */ +#define KN02CA_IO_INR_TIMER 12 /* ARC periodic timer (?) */ +#define KN02CA_IO_INR_ISDN 11 /* Am79C30A ISDN */ +#define KN02CA_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */ +#define KN02CA_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */ +#define KN02CA_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */ +#define KN02CA_IO_INR_HDFLOPPY 7 /* (*) HD (1.44MB) floppy status */ +#define KN02CA_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */ +#define KN02CA_IO_INR_TC1 5 /* TURBOchannel slot #1 */ +#define KN02CA_IO_INR_XDFLOPPY 4 /* (*) XD (2.88MB) floppy status */ +#define KN02CA_IO_INR_VIDEO 3 /* framebuffer */ +#define KN02CA_IO_INR_XVIDEO 2 /* ~framebuffer */ +#define KN02CA_IO_INR_AB_XMIT 1 /* ACCESS.bus transmit */ +#define KN02CA_IO_INR_AB_RECV 0 /* ACCESS.bus receive */ + + +/* + * Memory Error Register bits. + */ +#define KN02CA_MER_INTR (1<<27) /* ARC IRQ status & ack */ + +/* + * Memory Size Register bits. + */ +#define KN02CA_MSR_INTREN (1<<26) /* ARC periodic IRQ enable */ +#define KN02CA_MSR_MS10EN (1<<25) /* 10/1ms IRQ period select */ +#define KN02CA_MSR_PFORCE (0xf<<21) /* byte lane error force */ +#define KN02CA_MSR_MABEN (1<<20) /* A side VFB address enable */ +#define KN02CA_MSR_LASTBANK (0x7<<17) /* onboard RAM bank # */ + +/* + * I/O ASIC System Support Register bits. + */ +#define KN03CA_IO_SSR_RES_14 (1<<14) /* unused */ +#define KN03CA_IO_SSR_RES_13 (1<<13) /* unused */ +#define KN03CA_IO_SSR_ISDN_RST (1<<12) /* ~ISDN (Am79C30A) reset */ + +#define KN03CA_IO_SSR_FLOPPY_RST (1<<7) /* ~FDC (82077) reset */ +#define KN03CA_IO_SSR_VIDEO_RST (1<<6) /* ~framebuffer reset */ +#define KN03CA_IO_SSR_AB_RST (1<<5) /* ACCESS.bus reset */ +#define KN03CA_IO_SSR_RES_4 (1<<4) /* unused */ +#define KN03CA_IO_SSR_RES_3 (1<<4) /* unused */ +#define KN03CA_IO_SSR_RES_2 (1<<2) /* unused */ +#define KN03CA_IO_SSR_RES_1 (1<<1) /* unused */ +#define KN03CA_IO_SSR_LED (1<<0) /* power LED */ + +#endif /* __ASM_MIPS_DEC_KN02CA_H */ diff -Nru a/include/asm-mips/dec/kn02xa.h b/include/asm-mips/dec/kn02xa.h --- a/include/asm-mips/dec/kn02xa.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/dec/kn02xa.h Fri Jun 27 14:19:54 2003 @@ -1,31 +1,75 @@ /* - * Hardware info about DEC DECstation 5000/1xx systems (otherwise known - * as 3min or kn02ba. Apllies to the Personal DECstations 5000/xx (otherwise known - * as maxine or kn02ca) as well. + * Hardware info common to DECstation 5000/1xx systems (otherwise + * known as 3min or kn02ba) and Personal DECstations 5000/xx ones + * (otherwise known as maxine or kn02ca). * * 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) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * Copyright (C) 2000 Maciej W. Rozycki + * are by courtesy of Chris Fraser. + * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki * * These are addresses which have to be known early in the boot process. - * For other addresses refer to tc.h ioasic_addrs.h and friends. + * For other addresses refer to tc.h, ioasic_addrs.h and friends. */ -#ifndef __ASM_MIPS_DEC_KN02XA_H -#define __ASM_MIPS_DEC_KN02XA_H +#ifndef __ASM_MIPS_DEC_KN02XA_H +#define __ASM_MIPS_DEC_KN02XA_H #include <asm/addrspace.h> +#include <asm/dec/ioasic_addrs.h> + +#define KN02XA_SLOT_BASE KSEG1ADDR(0x1c000000) /* * Some port addresses... - * FIXME: these addresses are incomplete and need tidying up! */ -#define KN02XA_IOASIC_BASE KSEG1ADDR(0x1c040000) /* I/O ASIC */ -#define KN02XA_RTC_BASE KSEG1ADDR(0x1c200000) /* RTC */ +#define KN02XA_IOASIC_BASE (KN02XA_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */ +#define KN02XA_RTC_BASE (KN02XA_SLOT_BASE + IOASIC_TOY) /* RTC */ + + +/* + * Memory control ASIC registers. + */ +#define KN02XA_MER KSEG1ADDR(0x0c400000) /* memory error register */ +#define KN02XA_MSR KSEG1ADDR(0x0c800000) /* memory size register */ + +/* + * CPU control ASIC registers. + */ +#define KN02XA_MEM_CONF KSEG1ADDR(0x0e000000) /* write timeout config */ +#define KN02XA_EAR KSEG1ADDR(0x0e000004) /* error address register */ +#define KN02XA_BOOT0 KSEG1ADDR(0x0e000008) /* boot 0 register */ +#define KN02XA_MEM_INTR KSEG1ADDR(0x0e00000c) /* write err IRQ stat & ack */ -#define KN02XA_IOASIC_REG(r) (KN02XA_IOASIC_BASE+(r)) +/* + * Memory Error Register bits, common definitions. + * The rest is defined in system-specific headers. + */ +#define KN02XA_MER_RES_28 (0xf<<28) /* unused */ +#define KN02XA_MER_RES_17 (0x3ff<<17) /* unused */ +#define KN02XA_MER_PAGERR (1<<16) /* 2k page boundary error */ +#define KN02XA_MER_TRANSERR (1<<15) /* transfer length error */ +#define KN02XA_MER_PARDIS (1<<14) /* parity error disable */ +#define KN02XA_MER_RES_12 (0x3<<12) /* unused */ +#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask */ +#define KN02XA_MER_RES_0 (0xff<<0) /* unused */ + +/* + * Memory Size Register bits, common definitions. + * The rest is defined in system-specific headers. + */ +#define KN02XA_MSR_RES_27 (0x1f<<27) /* unused */ +#define KN02XA_MSR_RES_14 (0x7<<14) /* unused */ +#define KN02XA_MSR_SIZE (1<<13) /* 16M/4M stride */ +#define KN02XA_MSR_RES_0 (0x1fff<<0) /* unused */ + +/* + * Error Address Register bits. + */ +#define KN02XA_EAR_RES_29 (0x7<<29) /* unused */ +#define KN02XA_EAR_ADDRESS (0x7ffffff<<2) /* address involved */ +#define KN02XA_EAR_RES_0 (0x3<<0) /* unused */ #endif /* __ASM_MIPS_DEC_KN02XA_H */ diff -Nru a/include/asm-mips/dec/kn03.h b/include/asm-mips/dec/kn03.h --- a/include/asm-mips/dec/kn03.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/dec/kn03.h Fri Jun 27 14:19:56 2003 @@ -1,34 +1,83 @@ /* - * Hardware info about DEC DECstation 5000/2x0 systems (otherwise known - * as 3max+ or kn03. + * Hardware info about DECstation 5000/2x0 systems (otherwise known as + * 3max+) and DECsystem 5900 systems (otherwise known as bigmax) which + * differ mechanically but are otherwise identical (both are known as + * KN03). * * 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) 1995,1996 by Paul M. Antoine, some code and definitions - * are by curteousy of Chris Fraser. - * Copyright (C) 2000 Maciej W. Rozycki - * - * These are addresses which have to be known early in the boot process. - * For other addresses refer to tc.h ioasic_addrs.h and friends. + * are by courtesy of Chris Fraser. + * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki */ -#ifndef __ASM_MIPS_DEC_KN03_H -#define __ASM_MIPS_DEC_KN03_H +#ifndef __ASM_MIPS_DEC_KN03_H +#define __ASM_MIPS_DEC_KN03_H #include <asm/addrspace.h> +#include <asm/dec/ecc.h> +#include <asm/dec/ioasic_addrs.h> + +#define KN03_SLOT_BASE KSEG1ADDR(0x1f800000) /* * Some port addresses... - * FIXME: these addresses are incomplete and need tidying up! */ -#define KN03_IOASIC_BASE KSEG1ADDR(0x1f840000) /* I/O ASIC */ -#define KN03_RTC_BASE KSEG1ADDR(0x1fa00000) /* RTC */ -#define KN03_MCR_BASE KSEG1ADDR(0x1fac0000) /* MCR */ +#define KN03_IOASIC_BASE (KN03_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */ +#define KN03_RTC_BASE (KN03_SLOT_BASE + IOASIC_TOY) /* RTC */ +#define KN03_MCR_BASE (KN03_SLOT_BASE + IOASIC_MCR) /* MCR */ + + +/* + * CPU interrupt bits. + */ +#define KN03_CPU_INR_HALT 6 /* HALT button */ +#define KN03_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */ +#define KN03_CPU_INR_RES_4 4 /* unused */ +#define KN03_CPU_INR_RTC 3 /* DS1287 RTC */ +#define KN03_CPU_INR_CASCADE 2 /* I/O ASIC cascade */ -#define KN03_MCR_BNK32M (1<<10) /* 32M stride */ -#define KN03_MCR_ECCEN (1<<13) /* ECC enabled */ +/* + * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits. + */ +#define KN03_IO_INR_3MAXP 15 /* (*) 3max+/bigmax ID */ +#define KN03_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */ +#define KN03_IO_INR_TC2 13 /* TURBOchannel slot #2 */ +#define KN03_IO_INR_TC1 12 /* TURBOchannel slot #1 */ +#define KN03_IO_INR_TC0 11 /* TURBOchannel slot #0 */ +#define KN03_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */ +#define KN03_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */ +#define KN03_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */ +#define KN03_IO_INR_SCC1 7 /* SCC (Z85C30) serial #1 */ +#define KN03_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */ +#define KN03_IO_INR_RTC 5 /* DS1287 RTC */ +#define KN03_IO_INR_PSU 4 /* power supply unit warning */ +#define KN03_IO_INR_RES_3 3 /* unused */ +#define KN03_IO_INR_ASC_DATA 2 /* SCSI data ready (for PIO) */ +#define KN03_IO_INR_PBNC 1 /* ~HALT button debouncer */ +#define KN03_IO_INR_PBNO 0 /* HALT button debouncer */ + + +/* + * Memory Control Register bits. + */ +#define KN03_MCR_RES_16 (0xffff<<16) /* unused */ +#define KN03_MCR_DIAGCHK (1<<15) /* diagn/norml ECC reads */ +#define KN03_MCR_DIAGGEN (1<<14) /* diagn/norml ECC writes */ +#define KN03_MCR_CORRECT (1<<13) /* ECC correct/check */ +#define KN03_MCR_RES_11 (0x3<<12) /* unused */ +#define KN03_MCR_BNK32M (1<<10) /* 32M/8M stride */ +#define KN03_MCR_RES_7 (0x7<<7) /* unused */ +#define KN03_MCR_CHECK (0x7f<<0) /* diagnostic check bits */ + +/* + * I/O ASIC System Support Register bits. + */ +#define KN03_IO_SSR_TXDIS1 (1<<14) /* SCC1 transmit disable */ +#define KN03_IO_SSR_TXDIS0 (1<<13) /* SCC0 transmit disable */ +#define KN03_IO_SSR_RES_12 (1<<12) /* unused */ -#define KN03_IOASIC_REG(r) (KN03_IOASIC_BASE+(r)) +#define KN03_IO_SSR_LEDS (0xff<<0) /* ~diagnostic LEDs */ #endif /* __ASM_MIPS_DEC_KN03_H */ diff -Nru a/include/asm-mips/dec/kn05.h b/include/asm-mips/dec/kn05.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/kn05.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,70 @@ +/* + * include/asm-mips/dec/kn05.h + * + * DECstation 5000/260 (4max+ or KN05) and DECsystem 5900/260 + * definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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! All this information is pure guesswork based on the + * ROM. It is provided here in hope it will give someone some + * food for thought. No documentation for the KN05 module has + * been located so far. + */ +#ifndef __ASM_MIPS_DEC_KN05_H +#define __ASM_MIPS_DEC_KN05_H + +#include <asm/dec/ioasic_addrs.h> + +/* + * The oncard MB (Memory Buffer) ASIC provides an additional address + * decoder. Certain address ranges within the "high" 16 slots are + * passed to the I/O ASIC's decoder like with the KN03. Others are + * handled locally. "Low" slots are always passed. + */ +#define KN05_MB_ROM (16*IOASIC_SLOT_SIZE) /* KN05 card ROM */ +#define KN05_IOCTL (17*IOASIC_SLOT_SIZE) /* I/O ASIC */ +#define KN05_ESAR (18*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */ +#define KN05_LANCE (19*IOASIC_SLOT_SIZE) /* LANCE Ethernet */ +#define KN05_MB_INT (20*IOASIC_SLOT_SIZE) /* MB interrupt register */ +#define KN05_MB_EA (21*IOASIC_SLOT_SIZE) /* MB error address? */ +#define KN05_MB_EC (22*IOASIC_SLOT_SIZE) /* MB error ??? */ +#define KN05_MB_CSR (23*IOASIC_SLOT_SIZE) /* MB control & status */ +#define KN05_RES_24 (24*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_25 (25*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_26 (26*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_27 (27*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_SCSI (28*IOASIC_SLOT_SIZE) /* ASC SCSI */ +#define KN05_RES_29 (29*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_30 (30*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_31 (31*IOASIC_SLOT_SIZE) /* unused? */ + +/* + * Bits for the MB interrupt register. + * The register appears read-only. + */ +#define KN05_MB_INT_TC (1<<0) /* TURBOchannel? */ +#define KN05_MB_INT_RTC (1<<1) /* RTC? */ + +/* + * Bits for the MB control & status register. + * Set to 0x00bf8001 on my system by the ROM. + */ +#define KN05_MB_CSR_PF (1<<0) /* PreFetching enable? */ +#define KN05_MB_CSR_F (1<<1) /* ??? */ +#define KN05_MB_CSR_ECC (0xff<<2) /* ??? */ +#define KN05_MB_CSR_OD (1<<10) /* ??? */ +#define KN05_MB_CSR_CP (1<<11) /* ??? */ +#define KN05_MB_CSR_UNC (1<<12) /* ??? */ +#define KN05_MB_CSR_IM (1<<13) /* ??? */ +#define KN05_MB_CSR_NC (1<<14) /* ??? */ +#define KN05_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */ +#define KN05_MB_CSR_MSK (0x1f<<16) /* ??? */ +#define KN05_MB_CSR_FW (1<<21) /* ??? */ + +#endif /* __ASM_MIPS_DEC_KN05_H */ diff -Nru a/include/asm-mips/dec/kn230.h b/include/asm-mips/dec/kn230.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/kn230.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,26 @@ +/* + * include/asm-mips/dec/kn230.h + * + * DECsystem 5100 (MIPSmate or KN230) definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_KN230_H +#define __ASM_MIPS_DEC_KN230_H + +/* + * CPU interrupt bits. + */ +#define KN230_CPU_INR_HALT 6 /* HALT button */ +#define KN230_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */ +#define KN230_CPU_INR_RTC 4 /* DS1287 RTC */ +#define KN230_CPU_INR_SII 3 /* SII (DC7061) SCSI */ +#define KN230_CPU_INR_LANCE 3 /* LANCE (Am7990) Ethernet */ +#define KN230_CPU_INR_DZ11 2 /* DZ11 (DC7085) serial */ + +#endif /* __ASM_MIPS_DEC_KN230_H */ diff -Nru a/include/asm-mips/dec/machtype.h b/include/asm-mips/dec/machtype.h --- a/include/asm-mips/dec/machtype.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/dec/machtype.h Fri Jun 27 14:19:59 2003 @@ -8,18 +8,20 @@ * Copyright (c) 1998, 2000 Harald Koerfgen */ -#ifndef __ASM_DEC_MACHTYPE_H -#define __ASM_DEC_MACHTYPE_H +#ifndef __ASM_DEC_MACHTYPE_H +#define __ASM_DEC_MACHTYPE_H #include <asm/bootinfo.h> #define TURBOCHANNEL (mips_machtype == MACH_DS5000_200 || \ mips_machtype == MACH_DS5000_1XX || \ mips_machtype == MACH_DS5000_XX || \ - mips_machtype == MACH_DS5000_2X0) - + mips_machtype == MACH_DS5000_2X0 || \ + mips_machtype == MACH_DS5900) + #define IOASIC (mips_machtype == MACH_DS5000_1XX || \ mips_machtype == MACH_DS5000_XX || \ - mips_machtype == MACH_DS5000_2X0) + mips_machtype == MACH_DS5000_2X0 || \ + mips_machtype == MACH_DS5900) #endif diff -Nru a/include/asm-mips/dec/prom.h b/include/asm-mips/dec/prom.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/prom.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,169 @@ +/* + * include/asm-mips/dec/prom.h + * + * DECstation PROM interface. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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. + * + * Based on arch/mips/dec/prom/prom.h by the Anonymous. + */ +#ifndef __ASM_MIPS_DEC_PROM_H +#define __ASM_MIPS_DEC_PROM_H + +#include <linux/types.h> + +#include <asm/addrspace.h> + +/* + * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's. + * Many of these will work for MIPSen as well! + */ +#define VEC_RESET (u64 *)KSEG1ADDR(0x1fc00000) + /* Prom base address */ + +#define PMAX_PROM_ENTRY(x) (VEC_RESET + (x)) /* Prom jump table */ + +#define PMAX_PROM_HALT PMAX_PROM_ENTRY(2) /* valid on MIPSen */ +#define PMAX_PROM_AUTOBOOT PMAX_PROM_ENTRY(5) /* valid on MIPSen */ +#define PMAX_PROM_OPEN PMAX_PROM_ENTRY(6) +#define PMAX_PROM_READ PMAX_PROM_ENTRY(7) +#define PMAX_PROM_CLOSE PMAX_PROM_ENTRY(10) +#define PMAX_PROM_LSEEK PMAX_PROM_ENTRY(11) +#define PMAX_PROM_GETCHAR PMAX_PROM_ENTRY(12) +#define PMAX_PROM_PUTCHAR PMAX_PROM_ENTRY(13) /* 12 on MIPSen */ +#define PMAX_PROM_GETS PMAX_PROM_ENTRY(15) +#define PMAX_PROM_PRINTF PMAX_PROM_ENTRY(17) +#define PMAX_PROM_GETENV PMAX_PROM_ENTRY(33) /* valid on MIPSen */ + + +/* + * Magic number indicating REX PROM available on DECstation. Found in + * register a2 on transfer of control to program from PROM. + */ +#define REX_PROM_MAGIC 0x30464354 + +#ifdef CONFIG_MIPS64 + +#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */ + +#else /* !CONFIG_MIPS64 */ + +#define prom_is_rex(magic) ((magic) == REX_PROM_MAGIC) + +#endif /* !CONFIG_MIPS64 */ + + +/* + * 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's and + * DS5000/2x0. + */ +#define REX_PROM_GETBITMAP 0x84/4 /* get mem bitmap */ +#define REX_PROM_GETCHAR 0x24/4 /* getch() */ +#define REX_PROM_GETENV 0x64/4 /* get env. variable */ +#define REX_PROM_GETSYSID 0x80/4 /* get system id */ +#define REX_PROM_GETTCINFO 0xa4/4 +#define REX_PROM_PRINTF 0x30/4 /* printf() */ +#define REX_PROM_SLOTADDR 0x6c/4 /* slotaddr */ +#define REX_PROM_BOOTINIT 0x54/4 /* open() */ +#define REX_PROM_BOOTREAD 0x58/4 /* read() */ +#define REX_PROM_CLEARCACHE 0x7c/4 + + +/* + * Used by rex_getbitmap(). + */ +typedef struct { + int pagesize; + unsigned char bitmap[0]; +} memmap; + + +/* + * Function pointers as read from a PROM's callback vector. + */ +extern int (*__rex_bootinit)(void); +extern int (*__rex_bootread)(void); +extern int (*__rex_getbitmap)(memmap *); +extern unsigned long *(*__rex_slot_address)(int); +extern void *(*__rex_gettcinfo)(void); +extern int (*__rex_getsysid)(void); +extern void (*__rex_clear_cache)(void); + +extern int (*__prom_getchar)(void); +extern char *(*__prom_getenv)(char *); +extern int (*__prom_printf)(char *, ...); + +extern int (*__pmax_open)(char*, int); +extern int (*__pmax_lseek)(int, long, int); +extern int (*__pmax_read)(int, void *, int); +extern int (*__pmax_close)(int); + + +#ifdef CONFIG_MIPS64 + +/* + * On MIPS64 we have to call PROM functions via a helper + * dispatcher to accomodate ABI incompatibilities. + */ +#define __DEC_PROM_O32 __attribute__((alias("call_o32"))) + +int _rex_bootinit(int (*)(void)) __DEC_PROM_O32; +int _rex_bootread(int (*)(void)) __DEC_PROM_O32; +int _rex_getbitmap(int (*)(memmap *), memmap *) __DEC_PROM_O32; +unsigned long *_rex_slot_address(unsigned long *(*)(int), int) __DEC_PROM_O32; +void *_rex_gettcinfo(void *(*)(void)) __DEC_PROM_O32; +int _rex_getsysid(int (*)(void)) __DEC_PROM_O32; +void _rex_clear_cache(void (*)(void)) __DEC_PROM_O32; + +int _prom_getchar(int (*)(void)) __DEC_PROM_O32; +char *_prom_getenv(char *(*)(char *), char *) __DEC_PROM_O32; +int _prom_printf(int (*)(char *, ...), char *, ...) __DEC_PROM_O32; + + +#define rex_bootinit() _rex_bootinit(__rex_bootinit) +#define rex_bootread() _rex_bootread(__rex_bootread) +#define rex_getbitmap(x) _rex_getbitmap(__rex_getbitmap, x) +#define rex_slot_address(x) _rex_slot_address(__rex_slot_address, x) +#define rex_gettcinfo() _rex_gettcinfo(__rex_gettcinfo) +#define rex_getsysid() _rex_getsysid(__rex_getsysid) +#define rex_clear_cache() _rex_clear_cache(__rex_clear_cache) + +#define prom_getchar() _prom_getchar(__prom_getchar) +#define prom_getenv(x) _prom_getenv(__prom_getenv, x) +#define prom_printf(x...) _prom_printf(__prom_printf, x) + +#else /* !CONFIG_MIPS64 */ + +/* + * On plain MIPS we just call PROM functions directly. + */ +#define rex_bootinit __rex_bootinit +#define rex_bootread __rex_bootread +#define rex_getbitmap __rex_getbitmap +#define rex_slot_address __rex_slot_address +#define rex_gettcinfo __rex_gettcinfo +#define rex_getsysid __rex_getsysid +#define rex_clear_cache __rex_clear_cache + +#define prom_getchar __prom_getchar +#define prom_getenv __prom_getenv +#define prom_printf __prom_printf + +#define pmax_open __pmax_open +#define pmax_lseek __pmax_lseek +#define pmax_read __pmax_read +#define pmax_close __pmax_close + +#endif /* !CONFIG_MIPS64 */ + + +extern void prom_meminit(u32); +extern void prom_identify_arch(u32); +extern void prom_init_cmdline(s32, s32 *, u32); + +#endif /* __ASM_MIPS_DEC_PROM_H */ diff -Nru a/include/asm-mips/dec/rtc-dec.h b/include/asm-mips/dec/rtc-dec.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/dec/rtc-dec.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,32 @@ +/* + * include/asm-mips/dec/rtc-dec.h + * + * RTC definitions for DECstation style attached Dallas DS1287 chip. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_RTC_DEC_H +#define __ASM_MIPS_DEC_RTC_DEC_H + +#include <linux/types.h> + +#include <asm/addrspace.h> + +extern volatile u8 *dec_rtc_base; +extern unsigned long dec_kn_slot_size; + +extern struct rtc_ops dec_rtc_ops; + +#define RTC_PORT(x) CPHYSADDR(dec_rtc_base) +#define RTC_IO_EXTENT dec_kn_slot_size +#define RTC_IOMAPPED 0 +#define RTC_IRQ 0 + +#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */ + +#endif /* __ASM_MIPS_DEC_RTC_DEC_H */ diff -Nru a/include/asm-mips/dec/tc.h b/include/asm-mips/dec/tc.h --- a/include/asm-mips/dec/tc.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/dec/tc.h Fri Jun 27 14:19:52 2003 @@ -28,7 +28,7 @@ */ extern void release_tc_card(int); /* - * Return base address of card in slot + * Return base address of card in slot */ extern unsigned long get_tc_base_addr(int); /* diff -Nru a/include/asm-mips/dec/tcinfo.h b/include/asm-mips/dec/tcinfo.h --- a/include/asm-mips/dec/tcinfo.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/dec/tcinfo.h Fri Jun 27 14:19:54 2003 @@ -1,4 +1,4 @@ -/* +/* * Various TURBOchannel related stuff * * This file is subject to the terms and conditions of the GNU General Public diff -Nru a/include/asm-mips/dec/tcmodule.h b/include/asm-mips/dec/tcmodule.h --- a/include/asm-mips/dec/tcmodule.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/dec/tcmodule.h Fri Jun 27 14:19:54 2003 @@ -1,4 +1,4 @@ -/* +/* * 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. @@ -15,10 +15,11 @@ * * Jan.1998 Harald Koerfgen */ -#ifndef __ASM_DEC_TCMOULE_H -#define __ASM_DEC_TCMOULE_H - +#ifndef __ASM_DEC_TCMODULE_H +#define __ASM_DEC_TCMODULE_H + #define OLDCARD 0x3c0000 +#define NEWCARD 0x000000 #define TC_ROM_WIDTH 0x3e0 #define TC_ROM_STRIDE 0x3e4 @@ -35,4 +36,4 @@ #define TC_FLAGS 0x470 #define TC_ROM_OBJECTS 0x480 -#endif /* __ASM_DEC_TCMOULE_H */ +#endif /* __ASM_DEC_TCMODULE_H */ diff -Nru a/include/asm-mips/delay.h b/include/asm-mips/delay.h --- a/include/asm-mips/delay.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips/delay.h Fri Jun 27 14:20:04 2003 @@ -10,6 +10,7 @@ #define _ASM_DELAY_H #include <linux/config.h> +#include <linux/param.h> extern unsigned long loops_per_jiffy; @@ -26,7 +27,7 @@ } /* - * division by multiplication: you don't have to worry about + * Division by multiplication: you don't have to worry about * loss of precision. * * Use only for very small delays ( < 1 msec). Should probably use a @@ -39,7 +40,11 @@ { unsigned long lo; - usecs *= 0x00068db8; /* 2**32 / (1000000 / HZ) */ + /* + * Excessive precission? Probably ... + */ + usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + + 0x80000000ULL) >> 32); __asm__("multu\t%2,%3" :"=h" (usecs), "=l" (lo) :"r" (usecs),"r" (lpj)); diff -Nru a/include/asm-mips/div64.h b/include/asm-mips/div64.h --- a/include/asm-mips/div64.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/div64.h Fri Jun 27 14:19:59 2003 @@ -1,6 +1,4 @@ /* - * include/asm-mips/div64.h - * * Copyright (C) 2000 Maciej W. Rozycki * * This file is subject to the terms and conditions of the GNU General Public @@ -10,105 +8,69 @@ #ifndef _ASM_DIV64_H #define _ASM_DIV64_H -#include <asm/sgidefs.h> - /* * No traps on overflows for any of these... */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS1 ) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS32) - #define do_div64_32(res, high, low, base) ({ \ unsigned long __quot, __mod; \ - unsigned long __cf, __tmp, __i; \ + unsigned long __cf, __tmp, __tmp2, __i; \ \ __asm__(".set push\n\t" \ ".set noat\n\t" \ ".set noreorder\n\t" \ + "move %2, $0\n\t" \ + "move %3, $0\n\t" \ "b 1f\n\t" \ - " li %4,0x21\n" \ + " li %4, 0x21\n" \ "0:\n\t" \ - "sll $1,%0,0x1\n\t" \ - "srl %3,%0,0x1f\n\t" \ - "or %0,$1,$2\n\t" \ - "sll %1,%1,0x1\n\t" \ - "sll %2,%2,0x1\n" \ + "sll $1, %0, 0x1\n\t" \ + "srl %3, %0, 0x1f\n\t" \ + "or %0, $1, %5\n\t" \ + "sll %1, %1, 0x1\n\t" \ + "sll %2, %2, 0x1\n" \ "1:\n\t" \ - "bnez %3,2f\n\t" \ - "sltu $2,%0,%z5\n\t" \ - "bnez $2,3f\n\t" \ + "bnez %3, 2f\n\t" \ + " sltu %5, %0, %z6\n\t" \ + "bnez %5, 3f\n" \ "2:\n\t" \ - " addiu %4,%4,-1\n\t" \ - "subu %0,%0,%z5\n\t" \ - "addiu %2,%2,1\n" \ + " addiu %4, %4, -1\n\t" \ + "subu %0, %0, %z6\n\t" \ + "addiu %2, %2, 1\n" \ "3:\n\t" \ - "bnez %4,0b\n\t" \ - " srl $2,%1,0x1f\n\t" \ + "bnez %4, 0b\n\t" \ + " srl %5, %1, 0x1f\n\t" \ ".set pop" \ : "=&r" (__mod), "=&r" (__tmp), "=&r" (__quot), "=&r" (__cf), \ - "=&r" (__i) \ - : "Jr" (base), "0" (high), "1" (low), "2" (0), "3" (0) \ - /* Aarrgh! Ran out of gcc's limit on constraints... */ \ - : "$1", "$2"); \ + "=&r" (__i), "=&r" (__tmp2) \ + : "Jr" (base), "0" (high), "1" (low)); \ \ (res) = __quot; \ __mod; }) #define do_div(n, base) ({ \ unsigned long long __quot; \ - unsigned long __upper, __low, __high, __mod; \ + unsigned long __mod; \ + unsigned long long __div; \ + unsigned long __upper, __low, __high, __base; \ + \ + __div = (n); \ + __base = (base); \ \ - __quot = (n); \ - __high = __quot >> 32; \ - __low = __quot; \ + __high = __div >> 32; \ + __low = __div; \ __upper = __high; \ \ if (__high) \ - __asm__("divu $0,%z2,%z3" \ + __asm__("divu $0, %z2, %z3" \ : "=h" (__upper), "=l" (__high) \ - : "Jr" (__high), "Jr" (base)); \ + : "Jr" (__high), "Jr" (__base)); \ \ - __mod = do_div64_32(__low, __upper, __low, base); \ + __mod = do_div64_32(__low, __upper, __low, __base); \ \ __quot = __high; \ __quot = __quot << 32 | __low; \ (n) = __quot; \ __mod; }) - -#else - -#define do_div64_32(res, high, low, base) ({ \ - unsigned long __quot, __mod, __r0; \ - \ - __asm__("dsll32 %2,%z3,0\n\t" \ - "or %2,%2,%z4\n\t" \ - "ddivu $0,%2,%z5" \ - : "=h" (__mod), "=l" (__quot), "=&r" (__r0) \ - : "Jr" (high), "Jr" (low), "Jr" (base)); \ - \ - (res) = __quot; \ - __mod; }) - -#define do_div(n, base) ({ \ - unsigned long long __quot; \ - unsigned long __mod, __r0; \ - \ - __quot = (n); \ - \ - __asm__("dsll32 %2,%M3,0\n\t" \ - "or %2,%2,%L3\n\t" \ - "ddivu $0,%2,%z4\n\t" \ - "mflo %L1\n\t" \ - "dsra32 %M1,%L1,0\n\t" \ - "dsll32 %L1,%L1,0\n\t" \ - "dsra32 %L1,%L1,0" \ - : "=h" (__mod), "=r" (__quot), "=&r" (__r0) \ - : "r" (n), "Jr" (base)); \ - \ - (n) = __quot; \ - __mod; }) - -#endif #endif /* _ASM_DIV64_H */ diff -Nru a/include/asm-mips/dma.h b/include/asm-mips/dma.h --- a/include/asm-mips/dma.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips/dma.h Fri Jun 27 14:19:30 2003 @@ -1,4 +1,4 @@ -/* $Id: dma.h,v 1.6 1999/12/30 14:22:47 raiko Exp $ +/* * linux/include/asm/dma.h: Defines for using and allocating dma channels. * Written by Hennus Bergman, 1992. * High DMA channel support & info by Hannu Savolainen @@ -43,7 +43,7 @@ * - page registers for 5-7 don't use data bit 0, represent 128K pages * - page registers for 0-3 use bit 0, represent 64K pages * - * DMA transfers are limited to the lower 16MB of _physical_ memory. + * DMA transfers are limited to the lower 16MB of _physical_ memory. * Note that addresses loaded into registers must be _physical_ addresses, * not logical addresses (which may differ if paging is active). * @@ -53,7 +53,7 @@ * | ... | | ... | | ... | * | ... | | ... | | ... | * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 + * P7 ... P0 A7 ... A0 A7 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Address mapping for channels 5-7: @@ -62,7 +62,7 @@ * | ... | \ \ ... \ \ \ ... \ \ * | ... | \ \ ... \ \ \ ... \ (not used) * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses @@ -71,7 +71,7 @@ * * Transfer count (_not # bytes_) is limited to 64K, represented as actual * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * and up to 128K bytes may be transferred on channels 5-7 in one operation. * */ @@ -83,7 +83,13 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ +#ifdef CONFIG_SGI_IP22 +/* Horrible hack to have a correct DMA window on IP22 */ +#include <asm/sgi/mc.h> +#define MAX_DMA_ADDRESS (PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000) +#else #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) +#endif /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -142,6 +148,7 @@ #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ +#define DMA_AUTOINIT 0x10 extern spinlock_t dma_spin_lock; @@ -247,7 +254,7 @@ } -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for +/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for * a specific DMA channel. * You must ensure the parameters are valid. * NOTE: from a manual: "the number of transfers is one more @@ -286,7 +293,7 @@ count = 1 + dma_inb(io_port); count += dma_inb(io_port) << 8; - + return (dmanr<=3)? count : (count<<1); } diff -Nru a/include/asm-mips/ds1286.h b/include/asm-mips/ds1286.h --- a/include/asm-mips/ds1286.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/ds1286.h Fri Jun 27 14:19:57 2003 @@ -1,5 +1,4 @@ -/* $Id: ds1286.h,v 1.1 1998/07/10 01:14:55 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff -Nru a/include/asm-mips/elf.h b/include/asm-mips/elf.h --- a/include/asm-mips/elf.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/elf.h Fri Jun 27 14:19:56 2003 @@ -6,13 +6,32 @@ #ifndef __ASM_ELF_H #define __ASM_ELF_H +/* ELF header e_flags defines. */ +/* MIPS architecture level. */ +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ + +/* The ABI of a file. */ +#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */ +#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ + #define PT_MIPS_REGINFO 0x70000000 +#define PT_MIPS_OPTIONS 0x70000001 /* Flags in the e_flags field of the header */ -#define EF_MIPS_NOREORDER 0x00000001 -#define EF_MIPS_PIC 0x00000002 -#define EF_MIPS_CPIC 0x00000004 -#define EF_MIPS_ARCH 0xf0000000 +#define EF_MIPS_NOREORDER 0x00000001 +#define EF_MIPS_PIC 0x00000002 +#define EF_MIPS_CPIC 0x00000004 +#define EF_MIPS_ABI2 0x00000020 +#define EF_MIPS_OPTIONS_FIRST 0x00000080 +#define EF_MIPS_32BITMODE 0x00000100 +#define EF_MIPS_ABI 0x0000f000 +#define EF_MIPS_ARCH 0xf0000000 #define DT_MIPS_RLD_VERSION 0x70000001 #define DT_MIPS_TIME_STAMP 0x70000002 @@ -102,8 +121,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; /* - * This is used to ensure we don't load something for the wrong architecture - * and also rejects IRIX binaries. + * This is used to ensure we don't load something for the wrong architecture. */ #define elf_check_arch(hdr) \ ({ \ @@ -112,7 +130,12 @@ \ if (__h->e_machine != EM_MIPS) \ __res = 0; \ - if (__h->e_flags & EF_MIPS_ARCH) \ + if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ + __res = 0; \ + if ((__h->e_flags & EF_MIPS_ABI2) != 0) \ + __res = 0; \ + if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ + ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ __res = 0; \ \ __res; \ diff -Nru a/include/asm-mips/errno.h b/include/asm-mips/errno.h --- a/include/asm-mips/errno.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/errno.h Fri Jun 27 14:19:57 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1999, 2001 by Ralf Baechle + * Copyright (C) 1995, 1999, 2001, 2002 by Ralf Baechle */ #ifndef _ASM_ERRNO_H #define _ASM_ERRNO_H diff -Nru a/include/asm-mips/fcntl.h b/include/asm-mips/fcntl.h --- a/include/asm-mips/fcntl.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips/fcntl.h Fri Jun 27 14:20:00 2003 @@ -22,8 +22,8 @@ #define O_EXCL 0x0400 /* not fcntl */ #define O_NOCTTY 0x0800 /* not fcntl */ #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ -#define O_LARGEFILE 0x2000 /* allow large file opens - currently ignored */ -#define O_DIRECT 0x8000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0x2000 /* allow large file opens */ +#define O_DIRECT 0x8000 /* direct disk access hint */ #define O_DIRECTORY 0x10000 /* must be a directory */ #define O_NOFOLLOW 0x20000 /* don't follow links */ @@ -65,7 +65,7 @@ /* operations for bsd flock(), also used by the kernel implementation */ #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* or'd with one of the above to prevent XXXXXXXXXXXXXXXXXX +#define LOCK_NB 4 /* or'd with one of the above to prevent blocking */ #define LOCK_UN 8 /* remove lock */ @@ -74,14 +74,21 @@ #define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ #define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ +/* + * The flavours of struct flock. "struct flock" is the ABI compliant + * variant. Finally struct flock64 is the LFS variant of struct flock. As + * a historic accident and inconsistence with the ABI definition it doesn't + * contain all the same fields as struct flock. + */ + typedef struct flock { - short l_type; - short l_whence; + short l_type; + short l_whence; __kernel_off_t l_start; __kernel_off_t l_len; - long l_sysid; /* ABI junk, unused on Linux */ + long l_sysid; __kernel_pid_t l_pid; - long pad[4]; /* ABI junk, unused on Linux */ + long pad[4]; } flock_t; typedef struct flock64 { diff -Nru a/include/asm-mips/fixmap.h b/include/asm-mips/fixmap.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/fixmap.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,111 @@ +/* + * fixmap.h: compile-time virtual memory allocation + * + * 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) 1998 Ingo Molnar + * + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 + */ + +#ifndef _ASM_FIXMAP_H +#define _ASM_FIXMAP_H + +#include <linux/config.h> +#include <linux/kernel.h> +#include <asm/page.h> +#ifdef CONFIG_HIGHMEM +#include <linux/threads.h> +#include <asm/kmap_types.h> +#endif + +/* + * Here we define all the compile-time 'special' virtual + * addresses. The point is to have a constant address at + * compile time, but to set the physical address only + * in the boot process. We allocate these special addresses + * from the end of virtual memory (0xfffff000) backwards. + * Also this lets us do fail-safe vmalloc(), we + * can guarantee that these special addresses and + * vmalloc()-ed addresses never overlap. + * + * these 'compile-time allocated' memory buffers are + * fixed-size 4k pages. (or larger if used with an increment + * highger than 1) use fixmap_set(idx,phys) to associate + * physical memory with fixmap indices. + * + * TLB entries of such buffers will not be flushed across + * task switches. + */ + +/* + * on UP currently we will have no trace of the fixmap mechanizm, + * no page table allocations, etc. This might change in the + * future, say framebuffers for the console driver(s) could be + * fix-mapped? + */ +enum fixed_addresses { +#ifdef CONFIG_HIGHMEM + FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ + FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, +#endif + __end_of_fixed_addresses +}; + +extern void __set_fixmap (enum fixed_addresses idx, + unsigned long phys, pgprot_t flags); + +#define set_fixmap(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL) +/* + * Some hardware wants to get fixmapped without caching. + */ +#define set_fixmap_nocache(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) +/* + * used by vmalloc.c. + * + * Leave one empty page between vmalloc'ed areas and + * the start of the fixmap, and leave one page empty + * at the top of mem.. + */ +#define FIXADDR_TOP (0xffffe000UL) +#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) + +#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) +#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) + +extern void __this_fixmap_does_not_exist(void); + +/* + * 'index to address' translation. If anyone tries to use the idx + * directly without tranlation, we catch the bug with a NULL-deference + * kernel oops. Illegal ranges of incoming indices are caught too. + */ +static inline unsigned long fix_to_virt(const unsigned int idx) +{ + /* + * this branch gets completely eliminated after inlining, + * except when someone tries to use fixaddr indices in an + * illegal way. (such as mixing up address types or using + * out-of-range indices). + * + * If it doesn't get removed, the linker will complain + * loudly with a reasonably clear error message.. + */ + if (idx >= __end_of_fixed_addresses) + __this_fixmap_does_not_exist(); + + return __fix_to_virt(idx); +} + +static inline unsigned long virt_to_fix(const unsigned long vaddr) +{ + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); + return __virt_to_fix(vaddr); +} + +#endif diff -Nru a/include/asm-mips/floppy.h b/include/asm-mips/floppy.h --- a/include/asm-mips/floppy.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/floppy.h Fri Jun 27 14:19:52 2003 @@ -10,10 +10,6 @@ #ifndef _ASM_FLOPPY_H #define _ASM_FLOPPY_H -#include <asm/bootinfo.h> -#include <asm/jazz.h> -#include <asm/jazzdma.h> - struct fd_ops { unsigned char (*fd_inb)(unsigned int port); void (*fd_outb)(unsigned char value, unsigned int port); @@ -50,7 +46,7 @@ #define fd_clear_dma_ff() fd_ops->fd_clear_dma_ff(FLOPPY_DMA) #define fd_set_dma_mode(mode) fd_ops->fd_set_dma_mode(FLOPPY_DMA, mode) #define fd_set_dma_addr(addr) fd_ops->fd_set_dma_addr(FLOPPY_DMA, \ - virt_to_bus(addr)) + isa_virt_to_bus(addr)) #define fd_set_dma_count(count) fd_ops->fd_set_dma_count(FLOPPY_DMA,count) #define fd_get_dma_residue() fd_ops->fd_get_dma_residue(FLOPPY_DMA) @@ -63,7 +59,8 @@ #define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size) #define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size) #define fd_drive_type(n) fd_ops->fd_drive_type(n) -#define fd_cacheflush(addr,size) dma_cache_wback_inv(addr,size) +#define fd_cacheflush(addr,size) \ + dma_cache_wback_inv((unsigned long)(addr),(size)) #define MAX_BUFFER_SECTORS 24 diff -Nru a/include/asm-mips/fp.h b/include/asm-mips/fp.h --- a/include/asm-mips/fp.h Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,34 +0,0 @@ -/* $Id: fp.h,v 1.1 1998/07/16 19:10:04 ralf Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998 by Ralf Baechle - */ - -/* - * Activate and deactive the floatingpoint accelerator. - */ -#define enable_cp1() \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t$1,$12\n\t" \ - "or\t$1,%0\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tpop" \ - : : "r" (ST0_CU1)); - -#define disable_cp1() \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\tnoat\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t$1,$12\n\t" \ - "or\t$1,%0\n\t" \ - "xor\t$1,%0\n\t" \ - "mtc0\t$1,$12\n\t" \ - ".set\tpop" \ - : : "r" (ST0_CU1)); diff -Nru a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/fpu.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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 _ASM_FPU_H +#define _ASM_FPU_H + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/thread_info.h> + +#include <asm/mipsregs.h> +#include <asm/cpu.h> +#include <asm/bitops.h> +#include <asm/processor.h> +#include <asm/current.h> + +struct sigcontext; + +extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); +extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + +extern void fpu_emulator_init_fpu(void); +extern void _init_fpu(void); +extern void _save_fp(struct task_struct *); +extern void _restore_fp(struct task_struct *); + +#if defined(CONFIG_CPU_SB1) +#define __enable_fpu_hazard() \ +do { \ + asm(".set push \n\t" \ + ".set mips64 \n\t" \ + ".set noreorder \n\t" \ + "ssnop \n\t" \ + "bnezl $0, .+4 \n\t" \ + "ssnop \n\t" \ + ".set pop"); \ +} while (0) +#else +#define __enable_fpu_hazard() \ +do { \ + asm("nop;nop;nop;nop"); /* max. hazard */ \ +} while (0) +#endif + +#define __enable_fpu() \ +do { \ + set_c0_status(ST0_CU1); \ + __enable_fpu_hazard(); \ +} while (0) + +#define __disable_fpu() \ +do { \ + clear_c0_status(ST0_CU1); \ + /* We don't care about the c0 hazard here */ \ +} while (0) + +#define enable_fpu() \ +do { \ + if (cpu_has_fpu) \ + __enable_fpu(); \ +} while (0) + +#define disable_fpu() \ +do { \ + if (cpu_has_fpu) \ + __disable_fpu(); \ +} while (0) + + +#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) + +static inline int is_fpu_owner(void) +{ + return cpu_has_fpu && test_thread_flag(TIF_USEDFPU); +} + +static inline void own_fpu(void) +{ + if (cpu_has_fpu) { + __enable_fpu(); + KSTK_STATUS(current) |= ST0_CU1; + set_thread_flag(TIF_USEDFPU); + } +} + +static inline void loose_fpu(void) +{ + if (cpu_has_fpu) { + KSTK_STATUS(current) &= ~ST0_CU1; + clear_thread_flag(TIF_USEDFPU); + __disable_fpu(); + } +} + +static inline void init_fpu(void) +{ + if (cpu_has_fpu) { + _init_fpu(); + } else { + fpu_emulator_init_fpu(); + } +} + +static inline void save_fp(struct task_struct *tsk) +{ + if (cpu_has_fpu) + _save_fp(tsk); +} + +static inline void restore_fp(struct task_struct *tsk) +{ + if (cpu_has_fpu) + _restore_fp(tsk); +} + +static inline unsigned long long *get_fpu_regs(struct task_struct *tsk) +{ + if (cpu_has_fpu) { + if ((tsk == current) && is_fpu_owner()) + _save_fp(current); + return (unsigned long long *)&tsk->thread.fpu.hard.fp_regs[0]; + } else { + return (unsigned long long *)tsk->thread.fpu.soft.regs; + } +} + +#endif /* _ASM_FPU_H */ diff -Nru a/include/asm-mips/fpu_emulator.h b/include/asm-mips/fpu_emulator.h --- a/include/asm-mips/fpu_emulator.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/fpu_emulator.h Fri Jun 27 14:19:56 2003 @@ -1,15 +1,4 @@ /* - * Definitiona for the Algorithmics FPU Emulator port into MIPS Linux - */ -/************************************************************************** - * - * include/asm-mips/fpu_emulator.h - * - * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -23,13 +12,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - *************************************************************************/ -/* * Further private data for which no space exists in mips_fpu_soft_struct. * This should be subsumed into the mips_fpu_soft_struct structure as * defined in processor.h as soon as the absurd wired absolute assembler * offsets become dynamic at compile time. + * + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. */ +#ifndef _ASM_FPU_EMULATOR_H +#define _ASM_FPU_EMULATOR_H struct mips_fpu_emulator_private { unsigned int eir; @@ -42,3 +34,5 @@ unsigned int errors; } stats; }; + +#endif /* _ASM_FPU_EMULATOR_H */ diff -Nru a/include/asm-mips/galileo-boards/ev64120.h b/include/asm-mips/galileo-boards/ev64120.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/galileo-boards/ev64120.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,59 @@ +/* + * This is a direct copy of the ev96100.h file, with a global + * search and replace. The numbers are the same. + * + * The reason I'm duplicating this is so that the 64120/96100 + * defines won't be confusing in the source code. + */ +#ifndef _MIPS_EV64120_H +#define _MIPS_EV64120_H + +#include <asm/addrspace.h> + +/* + * GT64120 config space base address + */ +#define GT64120_BASE (KSEG1ADDR(0x14000000)) +#define MIPS_GT_BASE GT64120_BASE + +/* + * PCI Bus allocation + */ +#define GT_PCI_MEM_BASE 0x12000000 +#define GT_PCI_MEM_SIZE 0x02000000 +#define GT_PCI_IO_BASE 0x10000000 +#define GT_PCI_IO_SIZE 0x02000000 +#define GT_ISA_IO_BASE PCI_IO_BASE + +/* + * Duart I/O ports. + */ +#define EV64120_COM1_BASE_ADDR (0x1d000000 + 0x20) +#define EV64120_COM2_BASE_ADDR (0x1d000000 + 0x00) + + +/* + * EV64120 interrupt controller register base. + */ +#define EV64120_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000)) + +/* + * EV64120 UART register base. + */ +#define EV64120_UART0_REGS_BASE (KSEG1ADDR(EV64120_COM1_BASE_ADDR)) +#define EV64120_UART1_REGS_BASE (KSEG1ADDR(EV64120_COM2_BASE_ADDR)) +#define EV64120_BASE_BAUD ( 3686400 / 16 ) + + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ + +#define GT_WRITE(ofs, data) \ + *(volatile u32 *)(MIPS_GT_BASE+ofs) = cpu_to_le32(data) +#define GT_READ(ofs, data) \ + *data = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+ofs)) + + +#endif /* !(_MIPS_EV64120_H) */ diff -Nru a/include/asm-mips/galileo-boards/ev64120int.h b/include/asm-mips/galileo-boards/ev64120int.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/galileo-boards/ev64120int.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,36 @@ +#ifndef IRQ_HANDLER_ +#define IRQ_HANDLER_ + +#define INT_CAUSE_MAIN 0 +#define INT_CAUSE_HIGH 1 + +#define MAX_CAUSE_REGS 4 +#define MAX_CAUSE_REG_WIDTH 32 + +void hook_irq_handler (int int_cause , int bit_num , void *isr_ptr); +int disable_galileo_irq (int int_cause , int bit_num); +int enable_galileo_irq (int int_cause , int bit_num); + +extern struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; + +/* + PCI interrupts will come in on either the INTA or + INTD interrups lines, which are mapped to the #2 and + #5 interrupt pins of the MIPS. On our boards, they + all either come in on IntD or they all come in on + IntA, they aren't mixed. There can be numerous PCI + interrupts, so we keep a list of the "requested" + interrupt numbers and go through the list whenever + we get an IntA/D. + + All PCI interrupts have numbers >= 20 by arbitrary convention. Any + interrupt < 8 is an interrupt that is maskable on the + MIPS. +*/ + +#define TIMER 4 +#define INTA 2 +#define INTD 5 + + +#endif /* IRQ_HANDLER_ */ diff -Nru a/include/asm-mips/galileo-boards/ev96100.h b/include/asm-mips/galileo-boards/ev96100.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/galileo-boards/ev96100.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,55 @@ +/* + * + */ +#ifndef _MIPS_EV96100_H +#define _MIPS_EV96100_H + +#include <asm/addrspace.h> + +/* + * GT64120 config space base address + */ +#define GT64120_BASE (KSEG1ADDR(0x14000000)) +#define MIPS_GT_BASE GT64120_BASE + +/* + * PCI Bus allocation + */ +#define GT_PCI_MEM_BASE 0x12000000 +#define GT_PCI_MEM_SIZE 0x02000000 +#define GT_PCI_IO_BASE 0x10000000 +#define GT_PCI_IO_SIZE 0x02000000 +#define GT_ISA_IO_BASE PCI_IO_BASE + +/* + * Duart I/O ports. + */ +#define EV96100_COM1_BASE_ADDR (0xBD000000 + 0x20) +#define EV96100_COM2_BASE_ADDR (0xBD000000 + 0x00) + + +/* + * EV96100 interrupt controller register base. + */ +#define EV96100_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000)) + +/* + * EV96100 UART register base. + */ +#define EV96100_UART0_REGS_BASE EV96100_COM1_BASE_ADDR +#define EV96100_UART1_REGS_BASE EV96100_COM2_BASE_ADDR +#define EV96100_BASE_BAUD ( 3686400 / 16 ) + + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ + +#define GT_WRITE(ofs, data) \ + *(volatile u32 *)(MIPS_GT_BASE+ofs) = cpu_to_le32(data) +#define GT_READ(ofs, data) \ + data = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+ofs)) + + +#endif /* !(_MIPS_EV96100_H) */ diff -Nru a/include/asm-mips/galileo-boards/ev96100int.h b/include/asm-mips/galileo-boards/ev96100int.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/galileo-boards/ev96100int.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,12 @@ +/* + * + */ +#ifndef _MIPS_EV96100INT_H +#define _MIPS_EV96100INT_H + +#define EV96100INT_UART_0 6 /* IP 6 */ +#define EV96100INT_TIMER 7 /* IP 7 */ + +extern void ev96100int_init(void); + +#endif /* !(_MIPS_EV96100_H) */ diff -Nru a/include/asm-mips/galileo-boards/gt96100.h b/include/asm-mips/galileo-boards/gt96100.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/galileo-boards/gt96100.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,432 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * stevel@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Register offsets of the MIPS GT96100 Advanced Communication Controller. + * + */ +#ifndef _GT96100_H +#define _GT96100_H + +/* + * Galileo GT96100 internal register base. + */ +#define MIPS_GT96100_BASE (KSEG1ADDR(0x14000000)) + +#define GT96100_WRITE(ofs, data) \ + *(volatile u32 *)(MIPS_GT96100_BASE+ofs) = cpu_to_le32(data) +#define GT96100_READ(ofs) \ + le32_to_cpu(*(volatile u32 *)(MIPS_GT96100_BASE+ofs)) + +#define GT96100_ETH_IO_SIZE 0x4000 + +/************************************************************************ + * Register offset addresses follow + ************************************************************************/ + +/* CPU Interface Control Registers */ +#define GT96100_CPU_INTERF_CONFIG 0x000000 + +/* Ethernet Ports */ +#define GT96100_ETH_PHY_ADDR_REG 0x080800 +#define GT96100_ETH_SMI_REG 0x080810 +/* + These are offsets to port 0 registers. Add GT96100_ETH_IO_SIZE to + get offsets to port 1 registers. +*/ +#define GT96100_ETH_PORT_CONFIG 0x084800 +#define GT96100_ETH_PORT_CONFIG_EXT 0x084808 +#define GT96100_ETH_PORT_COMM 0x084810 +#define GT96100_ETH_PORT_STATUS 0x084818 +#define GT96100_ETH_SER_PARAM 0x084820 +#define GT96100_ETH_HASH_TBL_PTR 0x084828 +#define GT96100_ETH_FLOW_CNTRL_SRC_ADDR_L 0x084830 +#define GT96100_ETH_FLOW_CNTRL_SRC_ADDR_H 0x084838 +#define GT96100_ETH_SDMA_CONFIG 0x084840 +#define GT96100_ETH_SDMA_COMM 0x084848 +#define GT96100_ETH_INT_CAUSE 0x084850 +#define GT96100_ETH_INT_MASK 0x084858 +#define GT96100_ETH_1ST_RX_DESC_PTR0 0x084880 +#define GT96100_ETH_1ST_RX_DESC_PTR1 0x084884 +#define GT96100_ETH_1ST_RX_DESC_PTR2 0x084888 +#define GT96100_ETH_1ST_RX_DESC_PTR3 0x08488C +#define GT96100_ETH_CURR_RX_DESC_PTR0 0x0848A0 +#define GT96100_ETH_CURR_RX_DESC_PTR1 0x0848A4 +#define GT96100_ETH_CURR_RX_DESC_PTR2 0x0848A8 +#define GT96100_ETH_CURR_RX_DESC_PTR3 0x0848AC +#define GT96100_ETH_CURR_TX_DESC_PTR0 0x0848E0 +#define GT96100_ETH_CURR_TX_DESC_PTR1 0x0848E4 +#define GT96100_ETH_MIB_COUNT_BASE 0x085800 + +/* SDMAs */ +#define GT96100_SDMA_GROUP_CONFIG 0x101AF0 +/* SDMA Group 0 */ +#define GT96100_SDMA_G0_CHAN0_CONFIG 0x000900 +#define GT96100_SDMA_G0_CHAN0_COMM 0x000908 +#define GT96100_SDMA_G0_CHAN0_RX_DESC_BASE 0x008900 +#define GT96100_SDMA_G0_CHAN0_CURR_RX_DESC_PTR 0x008910 +#define GT96100_SDMA_G0_CHAN0_TX_DESC_BASE 0x00C900 +#define GT96100_SDMA_G0_CHAN0_CURR_TX_DESC_PTR 0x00C910 +#define GT96100_SDMA_G0_CHAN0_1ST_TX_DESC_PTR 0x00C914 +#define GT96100_SDMA_G0_CHAN1_CONFIG 0x010900 +#define GT96100_SDMA_G0_CHAN1_COMM 0x010908 +#define GT96100_SDMA_G0_CHAN1_RX_DESC_BASE 0x018900 +#define GT96100_SDMA_G0_CHAN1_CURR_RX_DESC_PTR 0x018910 +#define GT96100_SDMA_G0_CHAN1_TX_DESC_BASE 0x01C900 +#define GT96100_SDMA_G0_CHAN1_CURR_TX_DESC_PTR 0x01C910 +#define GT96100_SDMA_G0_CHAN1_1ST_TX_DESC_PTR 0x01C914 +#define GT96100_SDMA_G0_CHAN2_CONFIG 0x020900 +#define GT96100_SDMA_G0_CHAN2_COMM 0x020908 +#define GT96100_SDMA_G0_CHAN2_RX_DESC_BASE 0x028900 +#define GT96100_SDMA_G0_CHAN2_CURR_RX_DESC_PTR 0x028910 +#define GT96100_SDMA_G0_CHAN2_TX_DESC_BASE 0x02C900 +#define GT96100_SDMA_G0_CHAN2_CURR_TX_DESC_PTR 0x02C910 +#define GT96100_SDMA_G0_CHAN2_1ST_TX_DESC_PTR 0x02C914 +#define GT96100_SDMA_G0_CHAN3_CONFIG 0x030900 +#define GT96100_SDMA_G0_CHAN3_COMM 0x030908 +#define GT96100_SDMA_G0_CHAN3_RX_DESC_BASE 0x038900 +#define GT96100_SDMA_G0_CHAN3_CURR_RX_DESC_PTR 0x038910 +#define GT96100_SDMA_G0_CHAN3_TX_DESC_BASE 0x03C900 +#define GT96100_SDMA_G0_CHAN3_CURR_TX_DESC_PTR 0x03C910 +#define GT96100_SDMA_G0_CHAN3_1ST_TX_DESC_PTR 0x03C914 +#define GT96100_SDMA_G0_CHAN4_CONFIG 0x040900 +#define GT96100_SDMA_G0_CHAN4_COMM 0x040908 +#define GT96100_SDMA_G0_CHAN4_RX_DESC_BASE 0x048900 +#define GT96100_SDMA_G0_CHAN4_CURR_RX_DESC_PTR 0x048910 +#define GT96100_SDMA_G0_CHAN4_TX_DESC_BASE 0x04C900 +#define GT96100_SDMA_G0_CHAN4_CURR_TX_DESC_PTR 0x04C910 +#define GT96100_SDMA_G0_CHAN4_1ST_TX_DESC_PTR 0x04C914 +#define GT96100_SDMA_G0_CHAN5_CONFIG 0x050900 +#define GT96100_SDMA_G0_CHAN5_COMM 0x050908 +#define GT96100_SDMA_G0_CHAN5_RX_DESC_BASE 0x058900 +#define GT96100_SDMA_G0_CHAN5_CURR_RX_DESC_PTR 0x058910 +#define GT96100_SDMA_G0_CHAN5_TX_DESC_BASE 0x05C900 +#define GT96100_SDMA_G0_CHAN5_CURR_TX_DESC_PTR 0x05C910 +#define GT96100_SDMA_G0_CHAN5_1ST_TX_DESC_PTR 0x05C914 +#define GT96100_SDMA_G0_CHAN6_CONFIG 0x060900 +#define GT96100_SDMA_G0_CHAN6_COMM 0x060908 +#define GT96100_SDMA_G0_CHAN6_RX_DESC_BASE 0x068900 +#define GT96100_SDMA_G0_CHAN6_CURR_RX_DESC_PTR 0x068910 +#define GT96100_SDMA_G0_CHAN6_TX_DESC_BASE 0x06C900 +#define GT96100_SDMA_G0_CHAN6_CURR_TX_DESC_PTR 0x06C910 +#define GT96100_SDMA_G0_CHAN6_1ST_TX_DESC_PTR 0x06C914 +#define GT96100_SDMA_G0_CHAN7_CONFIG 0x070900 +#define GT96100_SDMA_G0_CHAN7_COMM 0x070908 +#define GT96100_SDMA_G0_CHAN7_RX_DESC_BASE 0x078900 +#define GT96100_SDMA_G0_CHAN7_CURR_RX_DESC_PTR 0x078910 +#define GT96100_SDMA_G0_CHAN7_TX_DESC_BASE 0x07C900 +#define GT96100_SDMA_G0_CHAN7_CURR_TX_DESC_PTR 0x07C910 +#define GT96100_SDMA_G0_CHAN7_1ST_TX_DESC_PTR 0x07C914 +/* SDMA Group 1 */ +#define GT96100_SDMA_G1_CHAN0_CONFIG 0x100900 +#define GT96100_SDMA_G1_CHAN0_COMM 0x100908 +#define GT96100_SDMA_G1_CHAN0_RX_DESC_BASE 0x108900 +#define GT96100_SDMA_G1_CHAN0_CURR_RX_DESC_PTR 0x108910 +#define GT96100_SDMA_G1_CHAN0_TX_DESC_BASE 0x10C900 +#define GT96100_SDMA_G1_CHAN0_CURR_TX_DESC_PTR 0x10C910 +#define GT96100_SDMA_G1_CHAN0_1ST_TX_DESC_PTR 0x10C914 +#define GT96100_SDMA_G1_CHAN1_CONFIG 0x110900 +#define GT96100_SDMA_G1_CHAN1_COMM 0x110908 +#define GT96100_SDMA_G1_CHAN1_RX_DESC_BASE 0x118900 +#define GT96100_SDMA_G1_CHAN1_CURR_RX_DESC_PTR 0x118910 +#define GT96100_SDMA_G1_CHAN1_TX_DESC_BASE 0x11C900 +#define GT96100_SDMA_G1_CHAN1_CURR_TX_DESC_PTR 0x11C910 +#define GT96100_SDMA_G1_CHAN1_1ST_TX_DESC_PTR 0x11C914 +#define GT96100_SDMA_G1_CHAN2_CONFIG 0x120900 +#define GT96100_SDMA_G1_CHAN2_COMM 0x120908 +#define GT96100_SDMA_G1_CHAN2_RX_DESC_BASE 0x128900 +#define GT96100_SDMA_G1_CHAN2_CURR_RX_DESC_PTR 0x128910 +#define GT96100_SDMA_G1_CHAN2_TX_DESC_BASE 0x12C900 +#define GT96100_SDMA_G1_CHAN2_CURR_TX_DESC_PTR 0x12C910 +#define GT96100_SDMA_G1_CHAN2_1ST_TX_DESC_PTR 0x12C914 +#define GT96100_SDMA_G1_CHAN3_CONFIG 0x130900 +#define GT96100_SDMA_G1_CHAN3_COMM 0x130908 +#define GT96100_SDMA_G1_CHAN3_RX_DESC_BASE 0x138900 +#define GT96100_SDMA_G1_CHAN3_CURR_RX_DESC_PTR 0x138910 +#define GT96100_SDMA_G1_CHAN3_TX_DESC_BASE 0x13C900 +#define GT96100_SDMA_G1_CHAN3_CURR_TX_DESC_PTR 0x13C910 +#define GT96100_SDMA_G1_CHAN3_1ST_TX_DESC_PTR 0x13C914 +#define GT96100_SDMA_G1_CHAN4_CONFIG 0x140900 +#define GT96100_SDMA_G1_CHAN4_COMM 0x140908 +#define GT96100_SDMA_G1_CHAN4_RX_DESC_BASE 0x148900 +#define GT96100_SDMA_G1_CHAN4_CURR_RX_DESC_PTR 0x148910 +#define GT96100_SDMA_G1_CHAN4_TX_DESC_BASE 0x14C900 +#define GT96100_SDMA_G1_CHAN4_CURR_TX_DESC_PTR 0x14C910 +#define GT96100_SDMA_G1_CHAN4_1ST_TX_DESC_PTR 0x14C914 +#define GT96100_SDMA_G1_CHAN5_CONFIG 0x150900 +#define GT96100_SDMA_G1_CHAN5_COMM 0x150908 +#define GT96100_SDMA_G1_CHAN5_RX_DESC_BASE 0x158900 +#define GT96100_SDMA_G1_CHAN5_CURR_RX_DESC_PTR 0x158910 +#define GT96100_SDMA_G1_CHAN5_TX_DESC_BASE 0x15C900 +#define GT96100_SDMA_G1_CHAN5_CURR_TX_DESC_PTR 0x15C910 +#define GT96100_SDMA_G1_CHAN5_1ST_TX_DESC_PTR 0x15C914 +#define GT96100_SDMA_G1_CHAN6_CONFIG 0x160900 +#define GT96100_SDMA_G1_CHAN6_COMM 0x160908 +#define GT96100_SDMA_G1_CHAN6_RX_DESC_BASE 0x168900 +#define GT96100_SDMA_G1_CHAN6_CURR_RX_DESC_PTR 0x168910 +#define GT96100_SDMA_G1_CHAN6_TX_DESC_BASE 0x16C900 +#define GT96100_SDMA_G1_CHAN6_CURR_TX_DESC_PTR 0x16C910 +#define GT96100_SDMA_G1_CHAN6_1ST_TX_DESC_PTR 0x16C914 +#define GT96100_SDMA_G1_CHAN7_CONFIG 0x170900 +#define GT96100_SDMA_G1_CHAN7_COMM 0x170908 +#define GT96100_SDMA_G1_CHAN7_RX_DESC_BASE 0x178900 +#define GT96100_SDMA_G1_CHAN7_CURR_RX_DESC_PTR 0x178910 +#define GT96100_SDMA_G1_CHAN7_TX_DESC_BASE 0x17C900 +#define GT96100_SDMA_G1_CHAN7_CURR_TX_DESC_PTR 0x17C910 +#define GT96100_SDMA_G1_CHAN7_1ST_TX_DESC_PTR 0x17C914 +/* MPSCs */ +#define GT96100_MPSC0_MAIN_CONFIG_LOW 0x000A00 +#define GT96100_MPSC0_MAIN_CONFIG_HIGH 0x000A04 +#define GT96100_MPSC0_PROTOCOL_CONFIG 0x000A08 +#define GT96100_MPSC_CHAN0_REG1 0x000A0C +#define GT96100_MPSC_CHAN0_REG2 0x000A10 +#define GT96100_MPSC_CHAN0_REG3 0x000A14 +#define GT96100_MPSC_CHAN0_REG4 0x000A18 +#define GT96100_MPSC_CHAN0_REG5 0x000A1C +#define GT96100_MPSC_CHAN0_REG6 0x000A20 +#define GT96100_MPSC_CHAN0_REG7 0x000A24 +#define GT96100_MPSC_CHAN0_REG8 0x000A28 +#define GT96100_MPSC_CHAN0_REG9 0x000A2C +#define GT96100_MPSC_CHAN0_REG10 0x000A30 +#define GT96100_MPSC_CHAN0_REG11 0x000A34 +#define GT96100_MPSC1_MAIN_CONFIG_LOW 0x008A00 +#define GT96100_MPSC1_MAIN_CONFIG_HIGH 0x008A04 +#define GT96100_MPSC1_PROTOCOL_CONFIG 0x008A08 +#define GT96100_MPSC_CHAN1_REG1 0x008A0C +#define GT96100_MPSC_CHAN1_REG2 0x008A10 +#define GT96100_MPSC_CHAN1_REG3 0x008A14 +#define GT96100_MPSC_CHAN1_REG4 0x008A18 +#define GT96100_MPSC_CHAN1_REG5 0x008A1C +#define GT96100_MPSC_CHAN1_REG6 0x008A20 +#define GT96100_MPSC_CHAN1_REG7 0x008A24 +#define GT96100_MPSC_CHAN1_REG8 0x008A28 +#define GT96100_MPSC_CHAN1_REG9 0x008A2C +#define GT96100_MPSC_CHAN1_REG10 0x008A30 +#define GT96100_MPSC_CHAN1_REG11 0x008A34 +#define GT96100_MPSC2_MAIN_CONFIG_LOW 0x010A00 +#define GT96100_MPSC2_MAIN_CONFIG_HIGH 0x010A04 +#define GT96100_MPSC2_PROTOCOL_CONFIG 0x010A08 +#define GT96100_MPSC_CHAN2_REG1 0x010A0C +#define GT96100_MPSC_CHAN2_REG2 0x010A10 +#define GT96100_MPSC_CHAN2_REG3 0x010A14 +#define GT96100_MPSC_CHAN2_REG4 0x010A18 +#define GT96100_MPSC_CHAN2_REG5 0x010A1C +#define GT96100_MPSC_CHAN2_REG6 0x010A20 +#define GT96100_MPSC_CHAN2_REG7 0x010A24 +#define GT96100_MPSC_CHAN2_REG8 0x010A28 +#define GT96100_MPSC_CHAN2_REG9 0x010A2C +#define GT96100_MPSC_CHAN2_REG10 0x010A30 +#define GT96100_MPSC_CHAN2_REG11 0x010A34 +#define GT96100_MPSC3_MAIN_CONFIG_LOW 0x018A00 +#define GT96100_MPSC3_MAIN_CONFIG_HIGH 0x018A04 +#define GT96100_MPSC3_PROTOCOL_CONFIG 0x018A08 +#define GT96100_MPSC_CHAN3_REG1 0x018A0C +#define GT96100_MPSC_CHAN3_REG2 0x018A10 +#define GT96100_MPSC_CHAN3_REG3 0x018A14 +#define GT96100_MPSC_CHAN3_REG4 0x018A18 +#define GT96100_MPSC_CHAN3_REG5 0x018A1C +#define GT96100_MPSC_CHAN3_REG6 0x018A20 +#define GT96100_MPSC_CHAN3_REG7 0x018A24 +#define GT96100_MPSC_CHAN3_REG8 0x018A28 +#define GT96100_MPSC_CHAN3_REG9 0x018A2C +#define GT96100_MPSC_CHAN3_REG10 0x018A30 +#define GT96100_MPSC_CHAN3_REG11 0x018A34 +#define GT96100_MPSC4_MAIN_CONFIG_LOW 0x020A00 +#define GT96100_MPSC4_MAIN_CONFIG_HIGH 0x020A04 +#define GT96100_MPSC4_PROTOCOL_CONFIG 0x020A08 +#define GT96100_MPSC_CHAN4_REG1 0x020A0C +#define GT96100_MPSC_CHAN4_REG2 0x020A10 +#define GT96100_MPSC_CHAN4_REG3 0x020A14 +#define GT96100_MPSC_CHAN4_REG4 0x020A18 +#define GT96100_MPSC_CHAN4_REG5 0x020A1C +#define GT96100_MPSC_CHAN4_REG6 0x020A20 +#define GT96100_MPSC_CHAN4_REG7 0x020A24 +#define GT96100_MPSC_CHAN4_REG8 0x020A28 +#define GT96100_MPSC_CHAN4_REG9 0x020A2C +#define GT96100_MPSC_CHAN4_REG10 0x020A30 +#define GT96100_MPSC_CHAN4_REG11 0x020A34 +#define GT96100_MPSC5_MAIN_CONFIG_LOW 0x028A00 +#define GT96100_MPSC5_MAIN_CONFIG_HIGH 0x028A04 +#define GT96100_MPSC5_PROTOCOL_CONFIG 0x028A08 +#define GT96100_MPSC_CHAN5_REG1 0x028A0C +#define GT96100_MPSC_CHAN5_REG2 0x028A10 +#define GT96100_MPSC_CHAN5_REG3 0x028A14 +#define GT96100_MPSC_CHAN5_REG4 0x028A18 +#define GT96100_MPSC_CHAN5_REG5 0x028A1C +#define GT96100_MPSC_CHAN5_REG6 0x028A20 +#define GT96100_MPSC_CHAN5_REG7 0x028A24 +#define GT96100_MPSC_CHAN5_REG8 0x028A28 +#define GT96100_MPSC_CHAN5_REG9 0x028A2C +#define GT96100_MPSC_CHAN5_REG10 0x028A30 +#define GT96100_MPSC_CHAN5_REG11 0x028A34 +#define GT96100_MPSC6_MAIN_CONFIG_LOW 0x030A00 +#define GT96100_MPSC6_MAIN_CONFIG_HIGH 0x030A04 +#define GT96100_MPSC6_PROTOCOL_CONFIG 0x030A08 +#define GT96100_MPSC_CHAN6_REG1 0x030A0C +#define GT96100_MPSC_CHAN6_REG2 0x030A10 +#define GT96100_MPSC_CHAN6_REG3 0x030A14 +#define GT96100_MPSC_CHAN6_REG4 0x030A18 +#define GT96100_MPSC_CHAN6_REG5 0x030A1C +#define GT96100_MPSC_CHAN6_REG6 0x030A20 +#define GT96100_MPSC_CHAN6_REG7 0x030A24 +#define GT96100_MPSC_CHAN6_REG8 0x030A28 +#define GT96100_MPSC_CHAN6_REG9 0x030A2C +#define GT96100_MPSC_CHAN6_REG10 0x030A30 +#define GT96100_MPSC_CHAN6_REG11 0x030A34 +#define GT96100_MPSC7_MAIN_CONFIG_LOW 0x038A00 +#define GT96100_MPSC7_MAIN_CONFIG_HIGH 0x038A04 +#define GT96100_MPSC7_PROTOCOL_CONFIG 0x038A08 +#define GT96100_MPSC_CHAN7_REG1 0x038A0C +#define GT96100_MPSC_CHAN7_REG2 0x038A10 +#define GT96100_MPSC_CHAN7_REG3 0x038A14 +#define GT96100_MPSC_CHAN7_REG4 0x038A18 +#define GT96100_MPSC_CHAN7_REG5 0x038A1C +#define GT96100_MPSC_CHAN7_REG6 0x038A20 +#define GT96100_MPSC_CHAN7_REG7 0x038A24 +#define GT96100_MPSC_CHAN7_REG8 0x038A28 +#define GT96100_MPSC_CHAN7_REG9 0x038A2C +#define GT96100_MPSC_CHAN7_REG10 0x038A30 +#define GT96100_MPSC_CHAN7_REG11 0x038A34 +/* FlexTDMs */ +/* TDPR0 - Transmit Dual Port RAM. block size 0xff */ +#define GT96100_FXTDM0_TDPR0_BLK0_BASE 0x000B00 +#define GT96100_FXTDM0_TDPR0_BLK1_BASE 0x001B00 +#define GT96100_FXTDM0_TDPR0_BLK2_BASE 0x002B00 +#define GT96100_FXTDM0_TDPR0_BLK3_BASE 0x003B00 +/* RDPR0 - Receive Dual Port RAM. block size 0xff */ +#define GT96100_FXTDM0_RDPR0_BLK0_BASE 0x004B00 +#define GT96100_FXTDM0_RDPR0_BLK1_BASE 0x005B00 +#define GT96100_FXTDM0_RDPR0_BLK2_BASE 0x006B00 +#define GT96100_FXTDM0_RDPR0_BLK3_BASE 0x007B00 +#define GT96100_FXTDM0_TX_READ_PTR 0x008B00 +#define GT96100_FXTDM0_RX_READ_PTR 0x008B04 +#define GT96100_FXTDM0_CONFIG 0x008B08 +#define GT96100_FXTDM0_AUX_CHANA_TX 0x008B0C +#define GT96100_FXTDM0_AUX_CHANA_RX 0x008B10 +#define GT96100_FXTDM0_AUX_CHANB_TX 0x008B14 +#define GT96100_FXTDM0_AUX_CHANB_RX 0x008B18 +#define GT96100_FXTDM1_TDPR1_BLK0_BASE 0x010B00 +#define GT96100_FXTDM1_TDPR1_BLK1_BASE 0x011B00 +#define GT96100_FXTDM1_TDPR1_BLK2_BASE 0x012B00 +#define GT96100_FXTDM1_TDPR1_BLK3_BASE 0x013B00 +#define GT96100_FXTDM1_RDPR1_BLK0_BASE 0x014B00 +#define GT96100_FXTDM1_RDPR1_BLK1_BASE 0x015B00 +#define GT96100_FXTDM1_RDPR1_BLK2_BASE 0x016B00 +#define GT96100_FXTDM1_RDPR1_BLK3_BASE 0x017B00 +#define GT96100_FXTDM1_TX_READ_PTR 0x018B00 +#define GT96100_FXTDM1_RX_READ_PTR 0x018B04 +#define GT96100_FXTDM1_CONFIG 0x018B08 +#define GT96100_FXTDM1_AUX_CHANA_TX 0x018B0C +#define GT96100_FXTDM1_AUX_CHANA_RX 0x018B10 +#define GT96100_FLTDM1_AUX_CHANB_TX 0x018B14 +#define GT96100_FLTDM1_AUX_CHANB_RX 0x018B18 +#define GT96100_FLTDM2_TDPR2_BLK0_BASE 0x020B00 +#define GT96100_FLTDM2_TDPR2_BLK1_BASE 0x021B00 +#define GT96100_FLTDM2_TDPR2_BLK2_BASE 0x022B00 +#define GT96100_FLTDM2_TDPR2_BLK3_BASE 0x023B00 +#define GT96100_FLTDM2_RDPR2_BLK0_BASE 0x024B00 +#define GT96100_FLTDM2_RDPR2_BLK1_BASE 0x025B00 +#define GT96100_FLTDM2_RDPR2_BLK2_BASE 0x026B00 +#define GT96100_FLTDM2_RDPR2_BLK3_BASE 0x027B00 +#define GT96100_FLTDM2_TX_READ_PTR 0x028B00 +#define GT96100_FLTDM2_RX_READ_PTR 0x028B04 +#define GT96100_FLTDM2_CONFIG 0x028B08 +#define GT96100_FLTDM2_AUX_CHANA_TX 0x028B0C +#define GT96100_FLTDM2_AUX_CHANA_RX 0x028B10 +#define GT96100_FLTDM2_AUX_CHANB_TX 0x028B14 +#define GT96100_FLTDM2_AUX_CHANB_RX 0x028B18 +#define GT96100_FLTDM3_TDPR3_BLK0_BASE 0x030B00 +#define GT96100_FLTDM3_TDPR3_BLK1_BASE 0x031B00 +#define GT96100_FLTDM3_TDPR3_BLK2_BASE 0x032B00 +#define GT96100_FLTDM3_TDPR3_BLK3_BASE 0x033B00 +#define GT96100_FXTDM3_RDPR3_BLK0_BASE 0x034B00 +#define GT96100_FXTDM3_RDPR3_BLK1_BASE 0x035B00 +#define GT96100_FXTDM3_RDPR3_BLK2_BASE 0x036B00 +#define GT96100_FXTDM3_RDPR3_BLK3_BASE 0x037B00 +#define GT96100_FXTDM3_TX_READ_PTR 0x038B00 +#define GT96100_FXTDM3_RX_READ_PTR 0x038B04 +#define GT96100_FXTDM3_CONFIG 0x038B08 +#define GT96100_FXTDM3_AUX_CHANA_TX 0x038B0C +#define GT96100_FXTDM3_AUX_CHANA_RX 0x038B10 +#define GT96100_FXTDM3_AUX_CHANB_TX 0x038B14 +#define GT96100_FXTDM3_AUX_CHANB_RX 0x038B18 +/* Baud Rate Generators */ +#define GT96100_BRG0_CONFIG 0x102A00 +#define GT96100_BRG0_BAUD_TUNE 0x102A04 +#define GT96100_BRG1_CONFIG 0x102A08 +#define GT96100_BRG1_BAUD_TUNE 0x102A0C +#define GT96100_BRG2_CONFIG 0x102A10 +#define GT96100_BRG2_BAUD_TUNE 0x102A14 +#define GT96100_BRG3_CONFIG 0x102A18 +#define GT96100_BRG3_BAUD_TUNE 0x102A1C +#define GT96100_BRG4_CONFIG 0x102A20 +#define GT96100_BRG4_BAUD_TUNE 0x102A24 +#define GT96100_BRG5_CONFIG 0x102A28 +#define GT96100_BRG5_BAUD_TUNE 0x102A2C +#define GT96100_BRG6_CONFIG 0x102A30 +#define GT96100_BRG6_BAUD_TUNE 0x102A34 +#define GT96100_BRG7_CONFIG 0x102A38 +#define GT96100_BRG7_BAUD_TUNE 0x102A3C +/* Routing Registers */ +#define GT96100_ROUTE_MAIN 0x101A00 +#define GT96100_ROUTE_RX_CLOCK 0x101A10 +#define GT96100_ROUTE_TX_CLOCK 0x101A20 +/* General Purpose Ports */ +#define GT96100_GPP_CONFIG0 0x100A00 +#define GT96100_GPP_CONFIG1 0x100A04 +#define GT96100_GPP_CONFIG2 0x100A08 +#define GT96100_GPP_CONFIG3 0x100A0C +#define GT96100_GPP_IO0 0x100A20 +#define GT96100_GPP_IO1 0x100A24 +#define GT96100_GPP_IO2 0x100A28 +#define GT96100_GPP_IO3 0x100A2C +#define GT96100_GPP_DATA0 0x100A40 +#define GT96100_GPP_DATA1 0x100A44 +#define GT96100_GPP_DATA2 0x100A48 +#define GT96100_GPP_DATA3 0x100A4C +#define GT96100_GPP_LEVEL0 0x100A60 +#define GT96100_GPP_LEVEL1 0x100A64 +#define GT96100_GPP_LEVEL2 0x100A68 +#define GT96100_GPP_LEVEL3 0x100A6C +/* Watchdog */ +#define GT96100_WD_CONFIG 0x101A80 +#define GT96100_WD_VALUE 0x101A84 +/* Communication Unit Arbiter */ +#define GT96100_COMM_UNIT_ARBTR_CONFIG 0x101AC0 +/* PCI Arbiters */ +#define GT96100_PCI0_ARBTR_CONFIG 0x101AE0 +#define GT96100_PCI1_ARBTR_CONFIG 0x101AE4 +/* CIU Arbiter */ +#define GT96100_CIU_ARBITER_CONFIG 0x101AC0 +/* Interrupt Controller */ +#define GT96100_MAIN_CAUSE 0x000C18 +#define GT96100_INT0_MAIN_MASK 0x000C1C +#define GT96100_INT1_MAIN_MASK 0x000C24 +#define GT96100_HIGH_CAUSE 0x000C98 +#define GT96100_INT0_HIGH_MASK 0x000C9C +#define GT96100_INT1_HIGH_MASK 0x000CA4 +#define GT96100_INT0_SELECT 0x000C70 +#define GT96100_INT1_SELECT 0x000C74 +#define GT96100_SERIAL_CAUSE 0x103A00 +#define GT96100_SERINT0_MASK 0x103A80 +#define GT96100_SERINT1_MASK 0x103A88 + +#endif /* _GT96100_H */ diff -Nru a/include/asm-mips/gdb-stub.h b/include/asm-mips/gdb-stub.h --- a/include/asm-mips/gdb-stub.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/gdb-stub.h Fri Jun 27 14:19:56 2003 @@ -1,5 +1,4 @@ -/* $Id: gdb-stub.h,v 1.3 1998/07/20 17:52:19 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -58,7 +57,7 @@ #define GDB_FR_REG29 ((GDB_FR_REG28) + 4) /* 29 */ #define GDB_FR_REG30 ((GDB_FR_REG29) + 4) /* 30 */ #define GDB_FR_REG31 ((GDB_FR_REG30) + 4) /* 31 */ - + /* * Saved special registers */ @@ -133,7 +132,7 @@ #define GDB_FR_SIZE ((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1)) -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* * This is the same as above, but for the high-level @@ -181,7 +180,7 @@ */ long frame_ptr; long dummy; /* unused */ - + /* * saved cp0 registers */ @@ -209,5 +208,5 @@ void set_debug_traps(void); -#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_MIPS_GDB_STUB_H */ diff -Nru a/include/asm-mips/gfx.h b/include/asm-mips/gfx.h --- a/include/asm-mips/gfx.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/gfx.h Fri Jun 27 14:19:52 2003 @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * 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. @@ -7,7 +6,7 @@ * This is the user-visible SGI GFX interface. * * This must be used verbatim into the GNU libc. It does not include - * any kernel-only bits on it. + * any kernel-only bits on it. * * miguel@nuclecu.unam.mx */ diff -Nru a/include/asm-mips/gt64120.h b/include/asm-mips/gt64120.h --- a/include/asm-mips/gt64120.h Fri Jun 27 14:19:58 2003 +++ b/include/asm-mips/gt64120.h Fri Jun 27 14:19:58 2003 @@ -60,7 +60,7 @@ #define GT_PCI1M0REMAP_OFS 0x110 #define GT_PCI1M1REMAP_OFS 0x118 -#define GT_SCS0LD_OFS 0x400 +#define GT_SCS0LD_OFS 0x400 #define GT_SCS0HD_OFS 0x404 #define GT_SCS1LD_OFS 0x408 #define GT_SCS1HD_OFS 0x40c @@ -324,7 +324,7 @@ #define GT_PCI0_BARE_SWSCS32DIS_SHF 1 #define GT_PCI0_BARE_SWSCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF) #define GT_PCI0_BARE_SWSCS32DIS_BIT GT_PCI0_BARE_SWSCS32DIS_MSK - + #define GT_PCI0_BARE_SWSCS10DIS_SHF 2 #define GT_PCI0_BARE_SWSCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF) #define GT_PCI0_BARE_SWSCS10DIS_BIT GT_PCI0_BARE_SWSCS10DIS_MSK diff -Nru a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h --- a/include/asm-mips/hardirq.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/hardirq.h Fri Jun 27 14:19:54 2003 @@ -13,12 +13,9 @@ #include <linux/config.h> #include <linux/threads.h> #include <linux/irq.h> -#include <linux/spinlock.h> typedef struct { unsigned int __softirq_pending; - unsigned int __local_irq_count; - unsigned int __local_bh_count; unsigned int __syscall_count; struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ } ____cacheline_aligned irq_cpustat_t; @@ -26,72 +23,83 @@ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ /* - * Are we in an interrupt context? Either doing bottom half - * or hardware interrupt processing? + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq count (max # of hardirqs: 256) + * + * - ( bit 26 is the PREEMPT_ACTIVE flag. ) + * + * PREEMPT_MASK: 0x000000ff + * SOFTIRQ_MASK: 0x0000ff00 + * HARDIRQ_MASK: 0x00ff0000 */ -#define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) -#define in_irq() (local_irq_count(smp_processor_id()) != 0) -#ifndef CONFIG_SMP - -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { } while (0) - -#define irq_enter(cpu, irq) (local_irq_count(cpu)++) -#define irq_exit(cpu, irq) (local_irq_count(cpu)--) +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 8 + +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) + +#define __MASK(x) ((1UL << (x))-1) + +#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) + +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) -#define synchronize_irq() barrier(); +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) + +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) + +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) + +#if CONFIG_PREEMPT +# define in_atomic() (preempt_count() != kernel_locked()) +# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) #else +# define in_atomic() (preempt_count() != 0) +# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET +#endif +#define irq_exit() \ +do { \ + preempt_count() -= IRQ_EXIT_OFFSET; \ + if (!in_interrupt() && softirq_pending(smp_processor_id())) \ + do_softirq(); \ + preempt_enable_no_resched(); \ +} while (0) -#include <asm/atomic.h> -#include <linux/spinlock.h> -#include <asm/smp.h> - -extern int global_irq_holder; -extern spinlock_t global_irq_lock; - -static inline int irqs_running (void) -{ - int i; - - for (i = 0; i < smp_num_cpus; i++) - if (local_irq_count(i)) - return 1; - return 0; -} - -static inline void release_irqlock(int cpu) -{ - /* if we didn't own the irq lock, just ignore.. */ - if (global_irq_holder == cpu) { - global_irq_holder = NO_PROC_ID; - spin_unlock(&global_irq_lock); - } -} - -static inline int hardirq_trylock(int cpu) -{ - return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock); -} - -#define hardirq_endlock(cpu) do { } while (0) - -static inline void irq_enter(int cpu, int irq) -{ - ++local_irq_count(cpu); - - while (spin_is_locked(&global_irq_lock)) - barrier(); -} - -static inline void irq_exit(int cpu, int irq) -{ - --local_irq_count(cpu); -} - -extern void synchronize_irq(void); - +#ifndef CONFIG_SMP +# define synchronize_irq(irq) barrier() +#else + extern void synchronize_irq(unsigned int irq); #endif /* CONFIG_SMP */ + #endif /* _ASM_HARDIRQ_H */ diff -Nru a/include/asm-mips/highmem.h b/include/asm-mips/highmem.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/highmem.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,59 @@ +/* + * highmem.h: virtual kernel memory mappings for high memory + * + * Used in CONFIG_HIGHMEM systems for memory pages which + * are not addressable by direct kernel virtual addresses. + * + * Copyright (C) 1999 Gerhard Wichert, Siemens AG + * Gerhard.Wichert@pdb.siemens.de + * + * + * Redesigned the x86 32-bit VM architecture to deal with + * up to 16 Terabyte physical memory. With current x86 CPUs + * we now support up to 64 Gigabytes physical RAM. + * + * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> + */ +#ifndef _ASM_HIGHMEM_H +#define _ASM_HIGHMEM_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <asm/kmap_types.h> + +/* undef for production */ +#define HIGHMEM_DEBUG 1 + +/* declarations for highmem.c */ +extern unsigned long highstart_pfn, highend_pfn; + +extern pte_t *kmap_pte; +extern pgprot_t kmap_prot; +extern pte_t *pkmap_page_table; + +/* + * Right now we initialize only a single pte table. It can be extended + * easily, subsequent pte tables have to be allocated in one physical + * chunk of RAM. + */ +#define PKMAP_BASE (0xfe000000UL) +#define LAST_PKMAP 1024 +#define LAST_PKMAP_MASK (LAST_PKMAP-1) +#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT) +#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) + +extern void * kmap_high(struct page *page); +extern void kunmap_high(struct page *page); + +extern void *kmap(struct page *page); +extern void kunmap(struct page *page); +extern void *kmap_atomic(struct page *page, enum km_type type); +extern void kunmap_atomic(void *kvaddr, enum km_type type); +extern struct page *kmap_atomic_to_page(void *ptr); + +#endif /* __KERNEL__ */ + +#endif /* _ASM_HIGHMEM_H */ diff -Nru a/include/asm-mips/hw_irq.h b/include/asm-mips/hw_irq.h --- a/include/asm-mips/hw_irq.h Fri Jun 27 14:20:03 2003 +++ b/include/asm-mips/hw_irq.h Fri Jun 27 14:20:03 2003 @@ -3,14 +3,27 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000, 2001 by Ralf Baechle + * Copyright (C) 2000, 2001, 2002 by Ralf Baechle */ -#ifndef _ASM_HW_IRQ_H -#define _ASM_HW_IRQ_H +#ifndef __ASM_HW_IRQ_H +#define __ASM_HW_IRQ_H + +#include <linux/profile.h> +#include <asm/atomic.h> + +extern void mask_irq(unsigned int irq); +extern void unmask_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void enable_8259A_irq(unsigned int irq); +extern int i8259A_irq_pending(unsigned int irq); +extern void make_8259A_irq(unsigned int irq); +extern void init_8259A(int aeoi); + +extern atomic_t irq_err_count; /* This may not be apropriate for all machines, we'll see ... */ static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { } -#endif /* _ASM_HW_IRQ_H */ +#endif /* __ASM_HW_IRQ_H */ diff -Nru a/include/asm-mips/i8259.h b/include/asm-mips/i8259.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/i8259.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,23 @@ +/* + * include/asm-mips/i8259.h + * + * i8259A interrupt definitions. + * + * Copyright (C) 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_I8259_H +#define __ASM_MIPS_I8259_H + +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/system.h> + +extern void init_i8259_irqs(void); + +#endif /* __ASM_MIPS_I8259_H */ diff -Nru a/include/asm-mips/ide.h b/include/asm-mips/ide.h --- a/include/asm-mips/ide.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/ide.h Fri Jun 27 14:19:59 2003 @@ -14,6 +14,7 @@ #ifdef __KERNEL__ #include <linux/config.h> +#include <asm/byteorder.h> #include <asm/io.h> #ifndef MAX_HWIFS @@ -58,10 +59,15 @@ for(index = 0; index < MAX_HWIFS; index++) { ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); hw.irq = ide_default_irq(ide_default_io_base(index)); - ide_register_hw(&hw); + ide_register_hw(&hw, NULL); } #endif } + +#define __ide_mm_insw ide_insw +#define __ide_mm_insl ide_insl +#define __ide_mm_outsw ide_outsw +#define __ide_mm_outsl ide_outsl #endif /* __KERNEL__ */ diff -Nru a/include/asm-mips/inventory.h b/include/asm-mips/inventory.h --- a/include/asm-mips/inventory.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/inventory.h Fri Jun 27 14:19:54 2003 @@ -1,12 +1,9 @@ /* - * $Id:$ + * Miguel de Icaza */ -#ifndef __ASM_MIPS_INVENTORY_H -#define __ASM_MIPS_INVENTORY_H +#ifndef __ASM_INVENTORY_H +#define __ASM_INVENTORY_H -#include <linux/config.h> - -#ifdef CONFIG_BINFMT_IRIX typedef struct inventory_s { struct inventory_s *inv_next; int inv_class; @@ -19,10 +16,5 @@ extern int inventory_items; void add_to_inventory (int class, int type, int controller, int unit, int state); int dump_inventory_to_user (void *userbuf, int size); -void init_inventory (void); -#else -#define add_to_inventory(c,t,o,u,s) -#define init_inventory() -#endif -#endif /* defined(CONFIG_BINFMT_IRIX) */ +#endif /* __ASM_INVENTORY_H */ diff -Nru a/include/asm-mips/io.h b/include/asm-mips/io.h --- a/include/asm-mips/io.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/io.h Fri Jun 27 14:19:55 2003 @@ -12,9 +12,22 @@ #define _ASM_IO_H #include <linux/config.h> -#include <linux/pagemap.h> +#include <linux/types.h> + #include <asm/addrspace.h> +#include <asm/pgtable-bits.h> #include <asm/byteorder.h> +#include <asm/mipsregs.h> + +#ifdef CONFIG_SGI_IP27 +extern unsigned long bus_to_baddr[256]; + +#define bus_to_baddr(bus, addr) (bus_to_baddr[(bus)->number] + (addr)) +#define baddr_to_bus(bus, addr) ((addr) - bus_to_baddr[(bus)->number]) +#else +#define bus_to_baddr(bus, addr) (addr) +#define baddr_to_bus(bus, addr) (addr) +#endif /* * Slowdown I/O port space accesses for antique hardware. @@ -28,7 +41,13 @@ #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__) #define __ioswab8(x) (x) +#ifdef CONFIG_SGI_IP22 +/* IP22 seems braindead enough to swap 16bits values in hardware, but + not 32bits. Go figure... Can't tell without documentation. */ +#define __ioswab16(x) (x) +#else #define __ioswab16(x) swab16(x) +#endif #define __ioswab32(x) swab32(x) #else @@ -40,27 +59,17 @@ #endif /* - * This file contains the definitions for the MIPS counterpart of the - * x86 in/out instructions. This heap of macros and C results in much - * better code than the approach of doing it in plain C. The macros - * result in code that is to fast for certain hardware. On the other - * side the performance of the string functions should be improved for - * sake of certain devices like EIDE disks that do highspeed polled I/O. - * - * Ralf - * - * This file contains the definitions for the x86 IO instructions - * inb/inw/inl/outb/outw/outl and the "string versions" of the same - * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" - * versions of the single-IO instructions (inb_p/inw_p/..). - * - * This file is not meant to be obfuscating: it's just complicated - * to (a) handle it all in a way that makes gcc able to optimize it - * as well as possible and (b) trying to avoid writing the same thing - * over and over again with slight variations and possibly making a - * mistake somewhere. + * <Bacchus> Historically I wrote this stuff the same way as Linus did + * because I was young and clueless. And now it's so jucky that I + * don't want to put my eyes on it again to get rid of it :-) + * + * I'll do it then, because this code offends both me and my compiler + * - particularly the bits of inline asm which end up doing crap like + * 'lb $2,$2($5)' -- dwmw2 */ +#define IO_SPACE_LIMIT 0xffff + /* * On MIPS I/O ports are memory mapped, so we access them using normal * load/store instructions. mips_io_port_base is the virtual address to @@ -69,7 +78,10 @@ * instruction, so the lower 16 bits must be zero. Should be true on * on any sane architecture; generic code does not use this assumption. */ -extern unsigned long mips_io_port_base; +extern const unsigned long mips_io_port_base; + +#define set_io_port_base(base) \ + do { * (unsigned long *) &mips_io_port_base = (base); } while (0) /* * Thanks to James van Artsdalen for a better timing-fix than @@ -99,49 +111,116 @@ #endif /* - * Change virtual addresses to physical addresses and vv. - * These are trivial on the 1:1 Linux/MIPS mapping + * virt_to_phys - map virtual addresses to physical + * @address: address to remap + * + * The returned physical address is the physical (CPU) mapping for + * the memory address given. It is only valid to use this function on + * addresses directly mapped or allocated via kmalloc. + * + * This function does not give bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function */ -extern inline unsigned long virt_to_phys(volatile void * address) +static inline unsigned long virt_to_phys(volatile void * address) { return PHYSADDR(address); } -extern inline void * phys_to_virt(unsigned long address) +/* + * phys_to_virt - map physical address to virtual + * @address: address to remap + * + * The returned virtual address is a current CPU mapping for + * the memory address given. It is only valid to use this function on + * addresses that have a kernel mapping + * + * This function does not handle bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ +static inline void * phys_to_virt(unsigned long address) { return (void *)KSEG0ADDR(address); } /* - * IO bus memory addresses are also 1:1 with the physical address + * ISA I/O bus memory addresses are 1:1 with the physical address. */ -extern inline unsigned long virt_to_bus(volatile void * address) +static inline unsigned long isa_virt_to_bus(volatile void * address) { return PHYSADDR(address); } -extern inline void * bus_to_virt(unsigned long address) +static inline void * isa_bus_to_virt(unsigned long address) { return (void *)KSEG0ADDR(address); } +#define isa_page_to_bus page_to_phys + +/* + * However PCI ones are not necessarily 1:1 and therefore these interfaces + * are forbidden in portable PCI drivers. + * + * Allow them for x86 for legacy drivers, though. + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + /* * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. */ extern unsigned long isa_slot_offset; -extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); +/* + * Change "struct page" to physical address. + */ +#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) -extern inline void *ioremap(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, _CACHE_UNCACHED); -} +extern void * __ioremap(phys_t offset, phys_t size, unsigned long flags); -extern inline void *ioremap_nocache(unsigned long offset, unsigned long size) -{ - return __ioremap(offset, size, _CACHE_UNCACHED); -} + +/* + * ioremap - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + */ +#define ioremap(offset, size) \ + __ioremap((offset), (size), _CACHE_UNCACHED) + +/* + * ioremap_nocache - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap_nocache performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + * + * This version of ioremap ensures that the memory is marked uncachable + * on the CPU as well as honouring existing caching rules from things like + * the PCI bus. Note that there are other caches and buffers on many + * busses. In paticular driver authors should read up on PCI writes + * + * It's useful if some control registers are in such an area and + * write combining or read caching is not desirable: + */ +#define ioremap_nocache(offset, size) \ + __ioremap((offset), (size), _CACHE_UNCACHED) +#define ioremap_cacheable_cow(offset, size) \ + __ioremap((offset), (size), _CACHE_CACHABLE_COW) +#define ioremap_uncached_accelerated(offset, size) \ + __ioremap((offset), (size), _CACHE_UNCACHED_ACCELERATED) extern void iounmap(void *addr); @@ -150,26 +229,26 @@ * 24-31 on SNI. * XXX more SNI hacks. */ -#define readb(addr) (*(volatile unsigned char *)(addr)) -#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr))) -#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr))) -#define __raw_readb readb -#define __raw_readw readw -#define __raw_readl readl - -#define writeb(b,addr) (*(volatile unsigned char *)(addr)) = (b) -#define writew(b,addr) (*(volatile unsigned short *)(addr)) = (__ioswab16(b)) -#define writel(b,addr) (*(volatile unsigned int *)(addr)) = (__ioswab32(b)) -#define __raw_writeb writeb -#define __raw_writew writew -#define __raw_writel writel +#define readb(addr) (*(volatile unsigned char *)(addr)) +#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr))) +#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr))) + +#define __raw_readb(addr) (*(volatile unsigned char *)(addr)) +#define __raw_readw(addr) (*(volatile unsigned short *)(addr)) +#define __raw_readl(addr) (*(volatile unsigned int *)(addr)) + +#define writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (__ioswab8(b))) +#define writew(b,addr) ((*(volatile unsigned short *)(addr)) = (__ioswab16(b))) +#define writel(b,addr) ((*(volatile unsigned int *)(addr)) = (__ioswab32(b))) + +#define __raw_writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (b)) +#define __raw_writew(w,addr) ((*(volatile unsigned short *)(addr)) = (w)) +#define __raw_writel(l,addr) ((*(volatile unsigned int *)(addr)) = (l)) #define memset_io(a,b,c) memset((void *)(a),(b),(c)) #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) -/* END SNI HACKS ... */ - /* * ISA space is 'always mapped' on currently supported MIPS systems, no need * to explicitly ioremap() it. The fact that the ISA IO space is mapped @@ -178,18 +257,17 @@ * used as the IO-area pointer (it can be iounmapped as well, so the * analogy with PCI is quite large): */ -#define __ISA_IO_base ((char *)(PAGE_OFFSET)) +#define __ISA_IO_base ((char *)(isa_slot_offset)) -#define isa_readb(a) readb(a) -#define isa_readw(a) readw(a) -#define isa_readl(a) readl(a) -#define isa_writeb(b,a) writeb(b,a) -#define isa_writew(w,a) writew(w,a) -#define isa_writel(l,a) writel(l,a) - -#define isa_memset_io(a,b,c) memset_io((a),(b),(c)) -#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c)) -#define isa_memcpy_toio(a,b,c) memcpy_toio((a),(b),(c)) +#define isa_readb(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) +#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) /* * We don't have csum_partial_copy_fromio() yet, so we cheat here and @@ -198,6 +276,16 @@ #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) #define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(b),(c),(d)) +/* + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ static inline int check_signature(unsigned long io_addr, const unsigned char *signature, int length) { @@ -213,209 +301,160 @@ out: return retval; } -#define isa_check_signature(io, s, l) check_signature(i,s,l) /* - * Talk about misusing macros.. + * isa_check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. */ +#define isa_check_signature(io, s, l) check_signature(i,s,l) -#define __OUT1(s) \ -extern inline void __out##s(unsigned int value, unsigned int port) { -#define __OUT2(m) \ -__asm__ __volatile__ ("s" #m "\t%0,%1(%2)" +#define outb(val,port) \ +do { \ + *(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val); \ +} while(0) + +#define outw(val,port) \ +do { \ + *(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val); \ +} while(0) + +#define outl(val,port) \ +do { \ + *(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\ +} while(0) + +#define outb_p(val,port) \ +do { \ + *(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val); \ + SLOW_DOWN_IO; \ +} while(0) + +#define outw_p(val,port) \ +do { \ + *(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val);\ + SLOW_DOWN_IO; \ +} while(0) + +#define outl_p(val,port) \ +do { \ + *(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\ + SLOW_DOWN_IO; \ +} while(0) + +#define inb(port) __inb(port) +#define inw(port) __inw(port) +#define inl(port) __inl(port) +#define inb_p(port) __inb_p(port) +#define inw_p(port) __inw_p(port) +#define inl_p(port) __inl_p(port) -#define __OUT(m,s,w) \ -__OUT1(s) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); } \ -__OUT1(s##c) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); } \ -__OUT1(s##_p) __OUT2(m) : : "r" (__ioswab##w(value)), "i" (0), "r" (mips_io_port_base+port)); \ - SLOW_DOWN_IO; } \ -__OUT1(s##c_p) __OUT2(m) : : "r" (__ioswab##w(value)), "ir" (port), "r" (mips_io_port_base)); \ - SLOW_DOWN_IO; } - -#define __IN1(t,s) \ -extern __inline__ t __in##s(unsigned int port) { t _v; - -/* - * Required nops will be inserted by the assembler - */ -#define __IN2(m) \ -__asm__ __volatile__ ("l" #m "\t%0,%1(%2)" - -#define __IN(t,m,s,w) \ -__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return __ioswab##w(_v); } \ -__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return __ioswab##w(_v); } \ -__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return __ioswab##w(_v); } \ -__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return __ioswab##w(_v); } - -#define __INS1(s) \ -extern inline void __ins##s(unsigned int port, void * addr, unsigned long count) { - -#define __INS2(m) \ -if (count) \ -__asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n" \ - "1:\tl" #m "\t$1,%4(%5)\n\t" \ - "subu\t%1,1\n\t" \ - "s" #m "\t$1,(%0)\n\t" \ - "bne\t$0,%1,1b\n\t" \ - "addiu\t%0,%6\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" - -#define __INS(m,s,i) \ -__INS1(s) __INS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (0), \ - "r" (mips_io_port_base+port), "I" (i) \ - : "$1");} \ -__INS1(s##c) __INS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "ir" (port), \ - "r" (mips_io_port_base), "I" (i) \ - : "$1");} - -#define __OUTS1(s) \ -extern inline void __outs##s(unsigned int port, const void * addr, unsigned long count) { - -#define __OUTS2(m) \ -if (count) \ -__asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n" \ - "1:\tl" #m "\t$1,(%0)\n\t" \ - "subu\t%1,1\n\t" \ - "s" #m "\t$1,%4(%5)\n\t" \ - "bne\t$0,%1,1b\n\t" \ - "addiu\t%0,%6\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" - -#define __OUTS(m,s,i) \ -__OUTS1(s) __OUTS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \ - : "$1");} \ -__OUTS1(s##c) __OUTS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \ - : "$1");} - -__IN(unsigned char,b,b,8) -__IN(unsigned short,h,w,16) -__IN(unsigned int,w,l,32) - -__OUT(b,b,8) -__OUT(h,w,16) -__OUT(w,l,32) - -__INS(b,b,1) -__INS(h,w,2) -__INS(w,l,4) - -__OUTS(b,b,1) -__OUTS(h,w,2) -__OUTS(w,l,4) - - -/* - * Note that due to the way __builtin_constant_p() works, you - * - can't use it inside an inline function (it will never be true) - * - you don't have to worry about side effects within the __builtin.. - */ -#define outb(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outbc((val),(port)) : \ - __outb((val),(port))) - -#define inb(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inbc(port) : \ - __inb(port)) - -#define outb_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outbc_p((val),(port)) : \ - __outb_p((val),(port))) - -#define inb_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inbc_p(port) : \ - __inb_p(port)) - -#define outw(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outwc((val),(port)) : \ - __outw((val),(port))) - -#define inw(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inwc(port) : \ - __inw(port)) - -#define outw_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outwc_p((val),(port)) : \ - __outw_p((val),(port))) - -#define inw_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inwc_p(port) : \ - __inw_p(port)) - -#define outl(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outlc((val),(port)) : \ - __outl((val),(port))) - -#define inl(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inlc(port) : \ - __inl(port)) - -#define outl_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outlc_p((val),(port)) : \ - __outl_p((val),(port))) - -#define inl_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inlc_p(port) : \ - __inl_p(port)) - - -#define outsb(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outsbc((port),(addr),(count)) : \ - __outsb ((port),(addr),(count))) - -#define insb(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __insbc((port),(addr),(count)) : \ - __insb((port),(addr),(count))) - -#define outsw(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outswc((port),(addr),(count)) : \ - __outsw ((port),(addr),(count))) - -#define insw(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inswc((port),(addr),(count)) : \ - __insw((port),(addr),(count))) - -#define outsl(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outslc((port),(addr),(count)) : \ - __outsl ((port),(addr),(count))) - -#define insl(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inslc((port),(addr),(count)) : \ - __insl((port),(addr),(count))) +static inline unsigned char __inb(unsigned long port) +{ + return __ioswab8(*(volatile u8 *)(mips_io_port_base + port)); +} -#define IO_SPACE_LIMIT 0xffff +static inline unsigned short __inw(unsigned long port) +{ + return __ioswab16(*(volatile u16 *)(mips_io_port_base + port)); +} + +static inline unsigned int __inl(unsigned long port) +{ + return __ioswab32(*(volatile u32 *)(mips_io_port_base + port)); +} + +static inline unsigned char __inb_p(unsigned long port) +{ + u8 __val; + + __val = *(volatile u8 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + + return __ioswab8(__val); +} + +static inline unsigned short __inw_p(unsigned long port) +{ + u16 __val; + + __val = *(volatile u16 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + + return __ioswab16(__val); +} + +static inline unsigned int __inl_p(unsigned long port) +{ + u32 __val; + + __val = *(volatile u32 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + return __ioswab32(__val); +} + +#define outsb(port, addr, count) __outsb(port, addr, count) +#define insb(port, addr, count) __insb(port, addr, count) +#define outsw(port, addr, count) __outsw(port, addr, count) +#define insw(port, addr, count) __insw(port, addr, count) +#define outsl(port, addr, count) __outsl(port, addr, count) +#define insl(port, addr, count) __insl(port, addr, count) + +static inline void __outsb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outb(*(u8 *)addr, port); + addr++; + } +} + +static inline void __insb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u8 *)addr = inb(port); + addr++; + } +} + +static inline void __outsw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outw(*(u16 *)addr, port); + addr += 2; + } +} + +static inline void __insw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u16 *)addr = inw(port); + addr += 2; + } +} + +static inline void __outsl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outl(*(u32 *)addr, port); + addr += 4; + } +} + +static inline void __insl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u32 *)addr = inl(port); + addr += 4; + } +} /* * The caches on some architectures aren't dma-coherent and have need to @@ -435,12 +474,25 @@ * be discarded. This operation is necessary before dma operations * to the memory. */ +#ifdef CONFIG_NONCOHERENT_IO + extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); extern void (*_dma_cache_wback)(unsigned long start, unsigned long size); extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); -#define dma_cache_wback_inv(start,size) _dma_cache_wback_inv(start,size) -#define dma_cache_wback(start,size) _dma_cache_wback(start,size) -#define dma_cache_inv(start,size) _dma_cache_inv(start,size) +#define dma_cache_wback_inv(start, size)_dma_cache_wback_inv(start,size) +#define dma_cache_wback(start, size) _dma_cache_wback(start,size) +#define dma_cache_inv(start, size) _dma_cache_inv(start,size) + +#else /* Sane hardware */ + +#define dma_cache_wback_inv(start,size) \ + do { (void) (start); (void) (size); } while (0) +#define dma_cache_wback(start,size) \ + do { (void) (start); (void) (size); } while (0) +#define dma_cache_inv(start,size) \ + do { (void) (start); (void) (size); } while (0) + +#endif /* CONFIG_NONCOHERENT_IO */ #endif /* _ASM_IO_H */ diff -Nru a/include/asm-mips/ioctls.h b/include/asm-mips/ioctls.h --- a/include/asm-mips/ioctls.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-mips/ioctls.h Fri Jun 27 14:20:01 2003 @@ -12,7 +12,7 @@ #include <asm/ioctl.h> #define TCGETA 0x5401 -#define TCSETA 0x5402 +#define TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */ #define TCSETAW 0x5403 #define TCSETAF 0x5404 @@ -49,7 +49,7 @@ #define TIOCGETD 0x7400 #define FIOCLEX 0x6601 -#define FIONCLEX 0x6602 /* these numbers need to be adjusted. */ +#define FIONCLEX 0x6602 #define FIOASYNC 0x667d #define FIONBIO 0x667e #define FIOQSIZE 0x667f @@ -66,7 +66,7 @@ #define TIOCGETP 0x7408 #define TIOCSETP 0x7409 #define TIOCSETN 0x740a /* TIOCSETP wo flush */ - + /* #define TIOCSETA _IOW('t', 20, struct termios) set termios struct */ /* #define TIOCSETAW _IOW('t', 21, struct termios) drain output, set */ /* #define TIOCSETAF _IOW('t', 22, struct termios) drn out, fls in, set */ diff -Nru a/include/asm-mips/ipc.h b/include/asm-mips/ipc.h --- a/include/asm-mips/ipc.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips/ipc.h Fri Jun 27 14:20:05 2003 @@ -1,7 +1,7 @@ #ifndef __ASM_MIPS_IPC_H #define __ASM_MIPS_IPC_H -/* +/* * These are used to wrap system calls on MIPS. * * See arch/mips/kernel/sysmips.c for ugly details.. @@ -15,6 +15,7 @@ #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 diff -Nru a/include/asm-mips/ipcbuf.h b/include/asm-mips/ipcbuf.h --- a/include/asm-mips/ipcbuf.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips/ipcbuf.h Fri Jun 27 14:20:05 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_IPCBUF_H #define _ASM_IPCBUF_H -/* +/* * The ipc64_perm structure for alpha architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. @@ -18,7 +18,7 @@ __kernel_gid_t gid; __kernel_uid_t cuid; __kernel_gid_t cgid; - __kernel_mode_t mode; + __kernel_mode_t mode; unsigned short seq; unsigned short __pad1; unsigned long __unused1; diff -Nru a/include/asm-mips/irq.h b/include/asm-mips/irq.h --- a/include/asm-mips/irq.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/irq.h Fri Jun 27 14:19:53 2003 @@ -4,16 +4,17 @@ * for more details. * * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle - * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2001 Kanoj Sarcar */ #ifndef _ASM_IRQ_H #define _ASM_IRQ_H #include <linux/config.h> +#include <linux/linkage.h> -#define NR_IRQS 64 /* Largest number of ints of all machines. */ - -#define TIMER_IRQ 0 +#define NR_IRQS 128 /* Largest number of ints of all machines. */ #ifdef CONFIG_I8259 static inline int irq_canonicalize(int irq) @@ -24,19 +25,16 @@ #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ #endif -struct irqaction; -extern int i8259_setup_irq(int irq, struct irqaction * new); extern void disable_irq(unsigned int); - -#ifndef CONFIG_NEW_IRQ -#define disable_irq_nosync disable_irq -#else extern void disable_irq_nosync(unsigned int); -#endif - extern void enable_irq(unsigned int); +struct pt_regs; +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); + /* Machine specific interrupt initialization */ extern void (*irq_setup)(void); + +extern void init_generic_irq(void); #endif /* _ASM_IRQ_H */ diff -Nru a/include/asm-mips/irq_cpu.h b/include/asm-mips/irq_cpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/irq_cpu.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,18 @@ +/* + * include/asm-mips/irq_cpu.h + * + * MIPS CPU interrupt definitions. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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 __ASM_MIPS_IRQ_CPU_H +#define __ASM_MIPS_IRQ_CPU_H + +extern void mips_cpu_irq_init(int irq_base); + +#endif /* __ASM_MIPS_IRQ_CPU_H */ diff -Nru a/include/asm-mips/isadep.h b/include/asm-mips/isadep.h --- a/include/asm-mips/isadep.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/isadep.h Fri Jun 27 14:19:54 2003 @@ -10,7 +10,7 @@ #ifndef __ASM_ISADEP_H #define __ASM_ISADEP_H -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) /* * R2000 or R3000 */ diff -Nru a/include/asm-mips/jmr3927/ds1742rtc.h b/include/asm-mips/jmr3927/ds1742rtc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/jmr3927/ds1742rtc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,67 @@ +/* + * ds1742rtc.h - register definitions for the Real-Time-Clock / CMOS RAM + * + * Based on include/asm-mips/ds1643rtc.h. + * + * Copyright (C) 1999-2001 Toshiba Corporation + * It was written to be part of the Linux operating system. + */ +/* permission is hereby granted to copy, modify and redistribute this code + * in terms of the GNU Library General Public License, Version 2 or later, + * at your option. + */ +#ifndef _DS1742RTC_H +#define _DS1742RTC_H + +#include <linux/rtc.h> +#include <asm/mc146818rtc.h> /* bad name... */ + +#define RTC_BRAM_SIZE 0x800 +#define RTC_OFFSET 0x7f8 + +/********************************************************************** + * register summary + **********************************************************************/ +#define RTC_CONTROL (RTC_OFFSET + 0) +#define RTC_CENTURY (RTC_OFFSET + 0) +#define RTC_SECONDS (RTC_OFFSET + 1) +#define RTC_MINUTES (RTC_OFFSET + 2) +#define RTC_HOURS (RTC_OFFSET + 3) +#define RTC_DAY (RTC_OFFSET + 4) +#define RTC_DATE (RTC_OFFSET + 5) +#define RTC_MONTH (RTC_OFFSET + 6) +#define RTC_YEAR (RTC_OFFSET + 7) + +#define RTC_CENTURY_MASK 0x3f +#define RTC_SECONDS_MASK 0x7f +#define RTC_DAY_MASK 0x07 + +/* + * Bits in the Control/Century register + */ +#define RTC_WRITE 0x80 +#define RTC_READ 0x40 + +/* + * Bits in the Seconds register + */ +#define RTC_STOP 0x80 + +/* + * Bits in the Day register + */ +#define RTC_BATT_FLAG 0x80 +#define RTC_FREQ_TEST 0x40 + +/* + * Conversion between binary and BCD. + */ +#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 + +#endif /* _DS1742RTC_H */ diff -Nru a/include/asm-mips/jmr3927/irq.h b/include/asm-mips/jmr3927/irq.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/jmr3927/irq.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,62 @@ +/* + * linux/include/asm-mips/tx3927/irq.h + * + * 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) 2001 Toshiba Corporation + */ +#ifndef __ASM_TX3927_IRQ_H +#define __ASM_TX3927_IRQ_H + +#ifndef __ASSEMBLY__ + +#include <linux/config.h> +#include <asm/irq.h> + +struct tb_irq_space { + struct tb_irq_space* next; + int start_irqno; + int nr_irqs; + void (*mask_func)(int irq_nr, int space_id); + void (*unmask_func)(int irq_no, int space_id); + const char *name; + int space_id; + int can_share; +}; +extern struct tb_irq_space* tb_irq_spaces; + +static __inline__ void add_tb_irq_space(struct tb_irq_space* sp) +{ + sp->next = tb_irq_spaces; + tb_irq_spaces = sp; +} + + +struct pt_regs; +extern void +toshibaboards_spurious(struct pt_regs *regs, int irq); +extern void +toshibaboards_irqdispatch(struct pt_regs *regs, int irq); + +extern struct irqaction * +toshibaboards_get_irq_action(int irq); +extern int +toshibaboards_setup_irq(int irq, struct irqaction * new); + + +#ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND +extern void tx_branch_likely_bug_fixup(struct pt_regs *regs); +#endif + +extern int (*toshibaboards_gen_iack)(void); + +#endif /* !__ASSEMBLY__ */ + +#define NR_ISA_IRQS 16 +#define TB_IRQ_IS_ISA(irq) \ + (0 <= (irq) && (irq) < NR_ISA_IRQS) +#define TB_IRQ_TO_ISA_IRQ(irq) (irq) + +#endif /* __ASM_TX3927_IRQ_H */ diff -Nru a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/jmr3927/jmr3927.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,325 @@ +/* + * Defines for the TJSYS JMR-TX3927/JMI-3927IO2/JMY-1394IF. + * + * 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) 2000-2001 Toshiba Corporation + */ +#ifndef __ASM_TX3927_JMR3927_H +#define __ASM_TX3927_JMR3927_H + +#include <asm/jmr3927/tx3927.h> +#include <asm/addrspace.h> +#include <asm/jmr3927/irq.h> +#ifndef __ASSEMBLY__ +#include <asm/system.h> +#endif + +/* CS */ +#define JMR3927_ROMCE0 0x1fc00000 /* 4M */ +#define JMR3927_ROMCE1 0x1e000000 /* 4M */ +#define JMR3927_ROMCE2 0x14000000 /* 16M */ +#define JMR3927_ROMCE3 0x10000000 /* 64M */ +#define JMR3927_ROMCE5 0x1d000000 /* 4M */ +#define JMR3927_SDCS0 0x00000000 /* 32M */ +#define JMR3927_SDCS1 0x02000000 /* 32M */ +/* PCI Direct Mappings */ + +#define JMR3927_PCIMEM 0x08000000 +#define JMR3927_PCIMEM_SIZE 0x08000000 /* 128M */ +#define JMR3927_PCIIO 0x15000000 +#define JMR3927_PCIIO_SIZE 0x01000000 /* 16M */ + +#define JMR3927_SDRAM_SIZE 0x02000000 /* 32M */ +#define JMR3927_PORT_BASE KSEG1 + +/* select indirect initiator access per errata */ +#define JMR3927_INIT_INDIRECT_PCI +#define PCI_ISTAT_IDICC 0x1000 +#define PCI_IPCIBE_IBE_LONG 0 +#define PCI_IPCIBE_ICMD_IOREAD 2 +#define PCI_IPCIBE_ICMD_IOWRITE 3 +#define PCI_IPCIBE_ICMD_MEMREAD 6 +#define PCI_IPCIBE_ICMD_MEMWRITE 7 +#define PCI_IPCIBE_ICMD_SHIFT 4 + +/* Address map (virtual address) */ +#define JMR3927_ROM0_BASE (KSEG1 + JMR3927_ROMCE0) +#define JMR3927_ROM1_BASE (KSEG1 + JMR3927_ROMCE1) +#define JMR3927_IOC_BASE (KSEG1 + JMR3927_ROMCE2) +#define JMR3927_IOB_BASE (KSEG1 + JMR3927_ROMCE3) +#define JMR3927_ISAMEM_BASE (JMR3927_IOB_BASE) +#define JMR3927_ISAIO_BASE (JMR3927_IOB_BASE + 0x01000000) +#define JMR3927_ISAC_BASE (JMR3927_IOB_BASE + 0x02000000) +#define JMR3927_LCDVGA_REG_BASE (JMR3927_IOB_BASE + 0x03000000) +#define JMR3927_LCDVGA_MEM_BASE (JMR3927_IOB_BASE + 0x03800000) +#define JMR3927_JMY1394_BASE (KSEG1 + JMR3927_ROMCE5) +#define JMR3927_PREMIER3_BASE (JMR3927_JMY1394_BASE + 0x00100000) +#define JMR3927_PCIMEM_BASE (KSEG1 + JMR3927_PCIMEM) +#define JMR3927_PCIIO_BASE (KSEG1 + JMR3927_PCIIO) + +#define JMR3927_IOC_REV_ADDR (JMR3927_IOC_BASE + 0x00000000) +#define JMR3927_IOC_NVRAMB_ADDR (JMR3927_IOC_BASE + 0x00010000) +#define JMR3927_IOC_LED_ADDR (JMR3927_IOC_BASE + 0x00020000) +#define JMR3927_IOC_DIPSW_ADDR (JMR3927_IOC_BASE + 0x00030000) +#define JMR3927_IOC_BREV_ADDR (JMR3927_IOC_BASE + 0x00040000) +#define JMR3927_IOC_DTR_ADDR (JMR3927_IOC_BASE + 0x00050000) +#define JMR3927_IOC_INTS1_ADDR (JMR3927_IOC_BASE + 0x00080000) +#define JMR3927_IOC_INTS2_ADDR (JMR3927_IOC_BASE + 0x00090000) +#define JMR3927_IOC_INTM_ADDR (JMR3927_IOC_BASE + 0x000a0000) +#define JMR3927_IOC_INTP_ADDR (JMR3927_IOC_BASE + 0x000b0000) +#define JMR3927_IOC_RESET_ADDR (JMR3927_IOC_BASE + 0x000f0000) + +#define JMR3927_ISAC_REV_ADDR (JMR3927_ISAC_BASE + 0x00000000) +#define JMR3927_ISAC_EINTS_ADDR (JMR3927_ISAC_BASE + 0x00200000) +#define JMR3927_ISAC_EINTM_ADDR (JMR3927_ISAC_BASE + 0x00300000) +#define JMR3927_ISAC_NMI_ADDR (JMR3927_ISAC_BASE + 0x00400000) +#define JMR3927_ISAC_LED_ADDR (JMR3927_ISAC_BASE + 0x00500000) +#define JMR3927_ISAC_INTP_ADDR (JMR3927_ISAC_BASE + 0x00800000) +#define JMR3927_ISAC_INTS1_ADDR (JMR3927_ISAC_BASE + 0x00900000) +#define JMR3927_ISAC_INTS2_ADDR (JMR3927_ISAC_BASE + 0x00a00000) +#define JMR3927_ISAC_INTM_ADDR (JMR3927_ISAC_BASE + 0x00b00000) + +/* Flash ROM */ +#define JMR3927_FLASH_BASE (JMR3927_ROM0_BASE) +#define JMR3927_FLASH_SIZE 0x00400000 + +/* bits for IOC_REV/IOC_BREV/ISAC_REV (high byte) */ +#define JMR3927_IDT_MASK 0xfc +#define JMR3927_REV_MASK 0x03 +#define JMR3927_IOC_IDT 0xe0 +#define JMR3927_ISAC_IDT 0x20 + +/* bits for IOC_INTS1/IOC_INTS2/IOC_INTM/IOC_INTP (high byte) */ +#define JMR3927_IOC_INTB_PCIA 0 +#define JMR3927_IOC_INTB_PCIB 1 +#define JMR3927_IOC_INTB_PCIC 2 +#define JMR3927_IOC_INTB_PCID 3 +#define JMR3927_IOC_INTB_MODEM 4 +#define JMR3927_IOC_INTB_INT6 5 +#define JMR3927_IOC_INTB_INT7 6 +#define JMR3927_IOC_INTB_SOFT 7 +#define JMR3927_IOC_INTF_PCIA (1 << JMR3927_IOC_INTF_PCIA) +#define JMR3927_IOC_INTF_PCIB (1 << JMR3927_IOC_INTB_PCIB) +#define JMR3927_IOC_INTF_PCIC (1 << JMR3927_IOC_INTB_PCIC) +#define JMR3927_IOC_INTF_PCID (1 << JMR3927_IOC_INTB_PCID) +#define JMR3927_IOC_INTF_MODEM (1 << JMR3927_IOC_INTB_MODEM) +#define JMR3927_IOC_INTF_INT6 (1 << JMR3927_IOC_INTB_INT6) +#define JMR3927_IOC_INTF_INT7 (1 << JMR3927_IOC_INTB_INT7) +#define JMR3927_IOC_INTF_SOFT (1 << JMR3927_IOC_INTB_SOFT) + +/* bits for IOC_RESET (high byte) */ +#define JMR3927_IOC_RESET_CPU 1 +#define JMR3927_IOC_RESET_PCI 2 + +/* bits for ISAC_EINTS/ISAC_EINTM (high byte) */ +#define JMR3927_ISAC_EINTB_IOCHK 2 +#define JMR3927_ISAC_EINTB_BWTH 4 +#define JMR3927_ISAC_EINTF_IOCHK (1 << JMR3927_ISAC_EINTB_IOCHK) +#define JMR3927_ISAC_EINTF_BWTH (1 << JMR3927_ISAC_EINTB_BWTH) + +/* bits for ISAC_LED (high byte) */ +#define JMR3927_ISAC_LED_ISALED 0x01 +#define JMR3927_ISAC_LED_USRLED 0x02 + +/* bits for ISAC_INTS/ISAC_INTM/ISAC_INTP (high byte) */ +#define JMR3927_ISAC_INTB_IRQ5 0 +#define JMR3927_ISAC_INTB_IRQKB 1 +#define JMR3927_ISAC_INTB_IRQMOUSE 2 +#define JMR3927_ISAC_INTB_IRQ4 3 +#define JMR3927_ISAC_INTB_IRQ12 4 +#define JMR3927_ISAC_INTB_IRQ3 5 +#define JMR3927_ISAC_INTB_IRQ10 6 +#define JMR3927_ISAC_INTB_ISAER 7 +#define JMR3927_ISAC_INTF_IRQ5 (1 << JMR3927_ISAC_INTB_IRQ5) +#define JMR3927_ISAC_INTF_IRQKB (1 << JMR3927_ISAC_INTB_IRQKB) +#define JMR3927_ISAC_INTF_IRQMOUSE (1 << JMR3927_ISAC_INTB_IRQMOUSE) +#define JMR3927_ISAC_INTF_IRQ4 (1 << JMR3927_ISAC_INTB_IRQ4) +#define JMR3927_ISAC_INTF_IRQ12 (1 << JMR3927_ISAC_INTB_IRQ12) +#define JMR3927_ISAC_INTF_IRQ3 (1 << JMR3927_ISAC_INTB_IRQ3) +#define JMR3927_ISAC_INTF_IRQ10 (1 << JMR3927_ISAC_INTB_IRQ10) +#define JMR3927_ISAC_INTF_ISAER (1 << JMR3927_ISAC_INTB_ISAER) + +#ifndef __ASSEMBLY__ + +#if 0 +#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned short *)(a)) = (d) << 8) +#define jmr3927_ioc_reg_in(a) (((*(volatile unsigned short *)(a)) >> 8) & 0xff) +#else +#if defined(__BIG_ENDIAN) +#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)(a)) = (d)) +#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)(a)) +#elif defined(__LITTLE_ENDIAN) +#define jmr3927_ioc_reg_out(d, a) ((*(volatile unsigned char *)((a)^1)) = (d)) +#define jmr3927_ioc_reg_in(a) (*(volatile unsigned char *)((a)^1)) +#else +#error "No Endian" +#endif +#endif +#define jmr3927_isac_reg_out(d, a) ((*(volatile unsigned char *)(a)) = (d)) +#define jmr3927_isac_reg_in(a) (*(volatile unsigned char *)(a)) + +extern inline int jmr3927_have_isac(void) +{ + unsigned char idt; + unsigned long flags; + unsigned long romcr3; + + local_irq_save(flags); + romcr3 = tx3927_romcptr->cr[3]; + tx3927_romcptr->cr[3] &= 0xffffefff; /* do not wait infinitely */ + idt = jmr3927_isac_reg_in(JMR3927_ISAC_REV_ADDR) & JMR3927_IDT_MASK; + tx3927_romcptr->cr[3] = romcr3; + local_irq_restore(flags); + + return idt == JMR3927_ISAC_IDT; +} +#define jmr3927_have_nvram() \ + ((jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_IDT_MASK) == JMR3927_IOC_IDT) + +/* NVRAM macro */ +#define jmr3927_nvram_in(ofs) \ + jmr3927_ioc_reg_in(JMR3927_IOC_NVRAMB_ADDR + ((ofs) << 1)) +#define jmr3927_nvram_out(d, ofs) \ + jmr3927_ioc_reg_out(d, JMR3927_IOC_NVRAMB_ADDR + ((ofs) << 1)) + +/* LED macro */ +#define jmr3927_led_set(n/*0-16*/) jmr3927_ioc_reg_out(~(n), JMR3927_IOC_LED_ADDR) +#define jmr3927_io_led_set(n/*0-3*/) jmr3927_isac_reg_out((n), JMR3927_ISAC_LED_ADDR) + +#define jmr3927_led_and_set(n/*0-16*/) jmr3927_ioc_reg_out((~(n)) & jmr3927_ioc_reg_in(JMR3927_IOC_LED_ADDR), JMR3927_IOC_LED_ADDR) + +/* DIPSW4 macro */ +#define jmr3927_dipsw1() ((tx3927_pioptr->din & (1 << 11)) == 0) +#define jmr3927_dipsw2() ((tx3927_pioptr->din & (1 << 10)) == 0) +#define jmr3927_dipsw3() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 2) == 0) +#define jmr3927_dipsw4() ((jmr3927_ioc_reg_in(JMR3927_IOC_DIPSW_ADDR) & 1) == 0) +#define jmr3927_io_dipsw() (jmr3927_isac_reg_in(JMR3927_ISAC_LED_ADDR) >> 4) + + +#endif /* !__ASSEMBLY__ */ + +/* + * UART defines for serial.h + */ + +/* use Pre-scaler T0 (1/2) */ +#define JMR3927_BASE_BAUD (JMR3927_IMCLK / 2 / 16) + +#define UART0_ADDR 0xfffef300 +#define UART1_ADDR 0xfffef400 +#define UART0_INT JMR3927_IRQ_IRC_SIO0 +#define UART1_INT JMR3927_IRQ_IRC_SIO1 +#define UART0_FLAGS ASYNC_BOOT_AUTOCONF +#define UART1_FLAGS 0 + +/* + * IRQ mappings + */ + +/* These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an JMR machine. Add new 'spaces' as new + * IRQ hardware is supported. + */ +#define JMR3927_NR_IRQ_IRC 16 /* On-Chip IRC */ +#define JMR3927_NR_IRQ_IOC 8 /* PCI/MODEM/INT[6:7] */ +#define JMR3927_NR_IRQ_ISAC 8 /* ISA */ + + +#define JMR3927_IRQ_IRC NR_ISA_IRQS +#define JMR3927_IRQ_IOC (JMR3927_IRQ_IRC + JMR3927_NR_IRQ_IRC) +#define JMR3927_IRQ_ISAC (JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC) +#define JMR3927_IRQ_END (JMR3927_IRQ_ISAC + JMR3927_NR_IRQ_ISAC) +#define JMR3927_IRQ_IS_IRC(irq) (JMR3927_IRQ_IRC <= (irq) && (irq) < JMR3927_IRQ_IOC) +#define JMR3927_IRQ_IS_IOC(irq) (JMR3927_IRQ_IOC <= (irq) && (irq) < JMR3927_IRQ_ISAC) +#define JMR3927_IRQ_IS_ISAC(irq) (JMR3927_IRQ_ISAC <= (irq) && (irq) < JMR3927_IRQ_END) + +#define JMR3927_IRQ_IRC_INT0 (JMR3927_IRQ_IRC + TX3927_IR_INT0) +#define JMR3927_IRQ_IRC_INT1 (JMR3927_IRQ_IRC + TX3927_IR_INT1) +#define JMR3927_IRQ_IRC_INT2 (JMR3927_IRQ_IRC + TX3927_IR_INT2) +#define JMR3927_IRQ_IRC_INT3 (JMR3927_IRQ_IRC + TX3927_IR_INT3) +#define JMR3927_IRQ_IRC_INT4 (JMR3927_IRQ_IRC + TX3927_IR_INT4) +#define JMR3927_IRQ_IRC_INT5 (JMR3927_IRQ_IRC + TX3927_IR_INT5) +#define JMR3927_IRQ_IRC_SIO0 (JMR3927_IRQ_IRC + TX3927_IR_SIO0) +#define JMR3927_IRQ_IRC_SIO1 (JMR3927_IRQ_IRC + TX3927_IR_SIO1) +#define JMR3927_IRQ_IRC_SIO(ch) (JMR3927_IRQ_IRC + TX3927_IR_SIO(ch)) +#define JMR3927_IRQ_IRC_DMA (JMR3927_IRQ_IRC + TX3927_IR_DMA) +#define JMR3927_IRQ_IRC_PIO (JMR3927_IRQ_IRC + TX3927_IR_PIO) +#define JMR3927_IRQ_IRC_PCI (JMR3927_IRQ_IRC + TX3927_IR_PCI) +#define JMR3927_IRQ_IRC_TMR0 (JMR3927_IRQ_IRC + TX3927_IR_TMR0) +#define JMR3927_IRQ_IRC_TMR1 (JMR3927_IRQ_IRC + TX3927_IR_TMR1) +#define JMR3927_IRQ_IRC_TMR2 (JMR3927_IRQ_IRC + TX3927_IR_TMR2) +#define JMR3927_IRQ_IOC_PCIA (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA) +#define JMR3927_IRQ_IOC_PCIB (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB) +#define JMR3927_IRQ_IOC_PCIC (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC) +#define JMR3927_IRQ_IOC_PCID (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCID) +#define JMR3927_IRQ_IOC_MODEM (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_MODEM) +#define JMR3927_IRQ_IOC_INT6 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT6) +#define JMR3927_IRQ_IOC_INT7 (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_INT7) +#define JMR3927_IRQ_IOC_SOFT (JMR3927_IRQ_IOC + JMR3927_IOC_INTB_SOFT) +#define JMR3927_IRQ_ISAC_IRQ5 (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ5) +#define JMR3927_IRQ_ISAC_IRQKB (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQKB) +#define JMR3927_IRQ_ISAC_IRQMOUSE (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQMOUSE) +#define JMR3927_IRQ_ISAC_IRQ4 (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ4) +#define JMR3927_IRQ_ISAC_IRQ12 (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ12) +#define JMR3927_IRQ_ISAC_IRQ3 (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ3) +#define JMR3927_IRQ_ISAC_IRQ10 (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_IRQ10) +#define JMR3927_IRQ_ISAC_ISAER (JMR3927_IRQ_ISAC + JMR3927_ISAC_INTB_ISAER) + +#if 0 /* auto detect */ +/* RTL8019AS 10M Ether (JMI-3927IO2:JPW2:1-2 Short) */ +#define JMR3927_IRQ_ETHER1 JMR3927_IRQ_IRC_INT0 +#endif +/* IOC (PCI, MODEM) */ +#define JMR3927_IRQ_IOCINT JMR3927_IRQ_IRC_INT1 +/* ISAC (ISA, PCMCIA, KEYBOARD, MOUSE) */ +#define JMR3927_IRQ_ISACINT JMR3927_IRQ_IRC_INT2 +/* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */ +#define JMR3927_IRQ_ETHER0 JMR3927_IRQ_IRC_INT3 +/* Clock Tick (10ms) */ +#define JMR3927_IRQ_TICK JMR3927_IRQ_IRC_TMR0 +#define JMR3927_IRQ_IDE JMR3927_IRQ_ISAC_IRQ12 + +/* IEEE1394 (Note that this may conflicts with RTL8019AS 10M Ether...) */ +#define JMR3927_IRQ_PREMIER3 JMR3927_IRQ_IRC_INT0 + +/* I/O Ports */ +/* RTL8019AS 10M Ether */ +#define JMR3927_ETHER1_PORT (JMR3927_ISAIO_BASE - JMR3927_PORT_BASE + 0x280) +#define JMR3927_KBD_PORT (JMR3927_ISAIO_BASE - JMR3927_PORT_BASE + 0x00800060) +#define JMR3927_IDE_PORT (JMR3927_ISAIO_BASE - JMR3927_PORT_BASE + 0x001001f0) + +/* Clocks */ +#define JMR3927_CORECLK 132710400 /* 132.7MHz */ +#define JMR3927_GBUSCLK (JMR3927_CORECLK / 2) /* 66.35MHz */ +#define JMR3927_IMCLK (JMR3927_CORECLK / 4) /* 33.17MHz */ + +#define jmr3927_tmrptr tx3927_tmrptr(0) /* TMR0 */ + + +/* + * TX3927 Pin Configuration: + * + * PCFG bits Avail Dead + * SELSIO[1:0]:11 RXD[1:0], TXD[1:0] PIO[6:3] + * SELSIOC[0]:1 CTS[0], RTS[0] INT[5:4] + * SELSIOC[1]:0,SELDSF:0, GSDAO[0],GPCST[3] CTS[1], RTS[1],DSF, + * GDBGE* PIO[2:1] + * SELDMA[2]:1 DMAREQ[2],DMAACK[2] PIO[13:12] + * SELTMR[2:0]:000 TIMER[1:0] + * SELCS:0,SELDMA[1]:0 PIO[11;10] SDCS_CE[7:6], + * DMAREQ[1],DMAACK[1] + * SELDMA[0]:1 DMAREQ[0],DMAACK[0] PIO[9:8] + * SELDMA[3]:1 DMAREQ[3],DMAACK[3] PIO[15:14] + * SELDONE:1 DMADONE PIO[7] + * + * Usable pins are: + * RXD[1;0],TXD[1:0],CTS[0],RTS[0], + * DMAREQ[0,2,3],DMAACK[0,2,3],DMADONE,PIO[0,10,11] + * INT[3:0] + */ + +#endif /* __ASM_TX3927_JMR3927_H */ diff -Nru a/include/asm-mips/jmr3927/pci.h b/include/asm-mips/jmr3927/pci.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/jmr3927/pci.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,64 @@ +/*********************************************************************** + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * include/asm-mips/jmr3927/pci.h + * Based on include/asm-mips/ddb5xxx/pci.h + * + * This file essentially defines the interface between board + * specific PCI code and MIPS common PCI code. Should potentially put + * into include/asm/pci.h file. + * + * 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. + * + *********************************************************************** + */ + +#ifndef __ASM_TX3927_PCI_H +#define __ASM_TX3927__PCI_H + +#include <linux/ioport.h> +#include <linux/pci.h> + +/* + * Each pci channel is a top-level PCI bus seem by CPU. A machine with + * multiple PCI channels may have multiple PCI host controllers or a + * single controller supporting multiple channels. + */ +struct pci_channel { + struct pci_ops *pci_ops; + struct resource *io_resource; + struct resource *mem_resource; +}; + +/* + * each board defines an array of pci_channels, that ends with all NULL entry + */ +extern struct pci_channel mips_pci_channels[]; + +/* + * board supplied pci irq fixup routine + */ +extern void pcibios_fixup_irqs(void); + +#endif /* __ASM_TX3927_PCI_H */ diff -Nru a/include/asm-mips/jmr3927/tx3927.h b/include/asm-mips/jmr3927/tx3927.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/jmr3927/tx3927.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,365 @@ +/* + * 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) 2000 Toshiba Corporation + */ +#ifndef __ASM_TX3927_H +#define __ASM_TX3927_H + +#include <asm/jmr3927/txx927.h> + +#define TX3927_SDRAMC_REG 0xfffe8000 +#define TX3927_ROMC_REG 0xfffe9000 +#define TX3927_DMA_REG 0xfffeb000 +#define TX3927_IRC_REG 0xfffec000 +#define TX3927_PCIC_REG 0xfffed000 +#define TX3927_CCFG_REG 0xfffee000 +#define TX3927_NR_TMR 3 +#define TX3927_TMR_REG(ch) (0xfffef000 + (ch) * 0x100) +#define TX3927_NR_SIO 2 +#define TX3927_SIO_REG(ch) (0xfffef300 + (ch) * 0x100) +#define TX3927_PIO_REG 0xfffef500 + +#ifndef __ASSEMBLY__ + +struct tx3927_sdramc_reg { + volatile unsigned long cr[8]; + volatile unsigned long tr[3]; + volatile unsigned long cmd; + volatile unsigned long smrs[2]; +}; + +struct tx3927_romc_reg { + volatile unsigned long cr[8]; +}; + +struct tx3927_dma_reg { + struct tx3927_dma_ch_reg { + volatile unsigned long cha; + volatile unsigned long sar; + volatile unsigned long dar; + volatile unsigned long cntr; + volatile unsigned long sair; + volatile unsigned long dair; + volatile unsigned long ccr; + volatile unsigned long csr; + } ch[4]; + volatile unsigned long dbr[8]; + volatile unsigned long tdhr; + volatile unsigned long mcr; + volatile unsigned long unused0; +}; + +struct tx3927_irc_reg { + volatile unsigned long cer; + volatile unsigned long cr[2]; + volatile unsigned long unused0; + volatile unsigned long ilr[8]; + volatile unsigned long unused1[4]; + volatile unsigned long imr; + volatile unsigned long unused2[7]; + volatile unsigned long scr; + volatile unsigned long unused3[7]; + volatile unsigned long ssr; + volatile unsigned long unused4[7]; + volatile unsigned long csr; +}; + +#include <asm/byteorder.h> + +#ifdef __BIG_ENDIAN +#define endian_def_s2(e1,e2) \ + volatile unsigned short e1,e2 +#define endian_def_sb2(e1,e2,e3) \ + volatile unsigned short e1;volatile unsigned char e2,e3 +#define endian_def_b2s(e1,e2,e3) \ + volatile unsigned char e1,e2;volatile unsigned short e3 +#define endian_def_b4(e1,e2,e3,e4) \ + volatile unsigned char e1,e2,e3,e4 +#else +#define endian_def_s2(e1,e2) \ + volatile unsigned short e2,e1 +#define endian_def_sb2(e1,e2,e3) \ + volatile unsigned char e3,e2;volatile unsigned short e1 +#define endian_def_b2s(e1,e2,e3) \ + volatile unsigned short e3;volatile unsigned char e2,e1 +#define endian_def_b4(e1,e2,e3,e4) \ + volatile unsigned char e4,e3,e2,e1 +#endif + +struct tx3927_pcic_reg { + endian_def_s2(did, vid); + endian_def_s2(pcistat, pcicmd); + endian_def_b4(cc, scc, rpli, rid); + endian_def_b4(unused0, ht, mlt, cls); + volatile unsigned long ioba; /* +10 */ + volatile unsigned long mba; + volatile unsigned long unused1[5]; + endian_def_s2(svid, ssvid); + volatile unsigned long unused2; /* +30 */ + endian_def_sb2(unused3, unused4, capptr); + volatile unsigned long unused5; + endian_def_b4(ml, mg, ip, il); + volatile unsigned long unused6; /* +40 */ + volatile unsigned long istat; + volatile unsigned long iim; + volatile unsigned long rrt; + volatile unsigned long unused7[3]; /* +50 */ + volatile unsigned long ipbmma; + volatile unsigned long ipbioma; /* +60 */ + volatile unsigned long ilbmma; + volatile unsigned long ilbioma; + volatile unsigned long unused8[9]; + volatile unsigned long tc; /* +90 */ + volatile unsigned long tstat; + volatile unsigned long tim; + volatile unsigned long tccmd; + volatile unsigned long pcirrt; /* +a0 */ + volatile unsigned long pcirrt_cmd; + volatile unsigned long pcirrdt; + volatile unsigned long unused9[3]; + volatile unsigned long tlboap; + volatile unsigned long tlbiap; + volatile unsigned long tlbmma; /* +c0 */ + volatile unsigned long tlbioma; + volatile unsigned long sc_msg; + volatile unsigned long sc_be; + volatile unsigned long tbl; /* +d0 */ + volatile unsigned long unused10[3]; + volatile unsigned long pwmng; /* +e0 */ + volatile unsigned long pwmngs; + volatile unsigned long unused11[6]; + volatile unsigned long req_trace; /* +100 */ + volatile unsigned long pbapmc; + volatile unsigned long pbapms; + volatile unsigned long pbapmim; + volatile unsigned long bm; /* +110 */ + volatile unsigned long cpcibrs; + volatile unsigned long cpcibgs; + volatile unsigned long pbacs; + volatile unsigned long iobas; /* +120 */ + volatile unsigned long mbas; + volatile unsigned long lbc; + volatile unsigned long lbstat; + volatile unsigned long lbim; /* +130 */ + volatile unsigned long pcistatim; + volatile unsigned long ica; + volatile unsigned long icd; + volatile unsigned long iiadp; /* +140 */ + volatile unsigned long iscdp; + volatile unsigned long mmas; + volatile unsigned long iomas; + volatile unsigned long ipciaddr; /* +150 */ + volatile unsigned long ipcidata; + volatile unsigned long ipcibe; +}; + +struct tx3927_ccfg_reg { + volatile unsigned long ccfg; + volatile unsigned long crir; + volatile unsigned long pcfg; + volatile unsigned long tear; + volatile unsigned long pdcr; +}; + +#endif /* !__ASSEMBLY__ */ + +/* + * SDRAMC + */ + +/* + * ROMC + */ + +/* + * DMA + */ +/* bits for MCR */ +#define TX3927_DMA_MCR_EIS(ch) (0x10000000<<(ch)) +#define TX3927_DMA_MCR_DIS(ch) (0x01000000<<(ch)) +#define TX3927_DMA_MCR_RSFIF 0x00000080 +#define TX3927_DMA_MCR_FIFUM(ch) (0x00000008<<(ch)) +#define TX3927_DMA_MCR_LE 0x00000004 +#define TX3927_DMA_MCR_RPRT 0x00000002 +#define TX3927_DMA_MCR_MSTEN 0x00000001 + +/* bits for CCRn */ +#define TX3927_DMA_CCR_DBINH 0x04000000 +#define TX3927_DMA_CCR_SBINH 0x02000000 +#define TX3927_DMA_CCR_CHRST 0x01000000 +#define TX3927_DMA_CCR_RVBYTE 0x00800000 +#define TX3927_DMA_CCR_ACKPOL 0x00400000 +#define TX3927_DMA_CCR_REQPL 0x00200000 +#define TX3927_DMA_CCR_EGREQ 0x00100000 +#define TX3927_DMA_CCR_CHDN 0x00080000 +#define TX3927_DMA_CCR_DNCTL 0x00060000 +#define TX3927_DMA_CCR_EXTRQ 0x00010000 +#define TX3927_DMA_CCR_INTRQD 0x0000e000 +#define TX3927_DMA_CCR_INTENE 0x00001000 +#define TX3927_DMA_CCR_INTENC 0x00000800 +#define TX3927_DMA_CCR_INTENT 0x00000400 +#define TX3927_DMA_CCR_CHNEN 0x00000200 +#define TX3927_DMA_CCR_XFACT 0x00000100 +#define TX3927_DMA_CCR_SNOP 0x00000080 +#define TX3927_DMA_CCR_DSTINC 0x00000040 +#define TX3927_DMA_CCR_SRCINC 0x00000020 +#define TX3927_DMA_CCR_XFSZ(order) (((order) << 2) & 0x0000001c) +#define TX3927_DMA_CCR_XFSZ_1W TX3927_DMA_CCR_XFSZ(2) +#define TX3927_DMA_CCR_XFSZ_4W TX3927_DMA_CCR_XFSZ(4) +#define TX3927_DMA_CCR_XFSZ_8W TX3927_DMA_CCR_XFSZ(5) +#define TX3927_DMA_CCR_XFSZ_16W TX3927_DMA_CCR_XFSZ(6) +#define TX3927_DMA_CCR_XFSZ_32W TX3927_DMA_CCR_XFSZ(7) +#define TX3927_DMA_CCR_MEMIO 0x00000002 +#define TX3927_DMA_CCR_ONEAD 0x00000001 + +/* bits for CSRn */ +#define TX3927_DMA_CSR_CHNACT 0x00000100 +#define TX3927_DMA_CSR_ABCHC 0x00000080 +#define TX3927_DMA_CSR_NCHNC 0x00000040 +#define TX3927_DMA_CSR_NTRNFC 0x00000020 +#define TX3927_DMA_CSR_EXTDN 0x00000010 +#define TX3927_DMA_CSR_CFERR 0x00000008 +#define TX3927_DMA_CSR_CHERR 0x00000004 +#define TX3927_DMA_CSR_DESERR 0x00000002 +#define TX3927_DMA_CSR_SORERR 0x00000001 + +/* + * IRC + */ +#define TX3927_IR_MAX_LEVEL 7 + +/* IRCER : Int. Control Enable */ +#define TX3927_IRCER_ICE 0x00000001 + +/* IRCR : Int. Control */ +#define TX3927_IRCR_LOW 0x00000000 +#define TX3927_IRCR_HIGH 0x00000001 +#define TX3927_IRCR_DOWN 0x00000002 +#define TX3927_IRCR_UP 0x00000003 + +/* IRSCR : Int. Status Control */ +#define TX3927_IRSCR_EIClrE 0x00000100 +#define TX3927_IRSCR_EIClr_MASK 0x0000000f + +/* IRCSR : Int. Current Status */ +#define TX3927_IRCSR_IF 0x00010000 +#define TX3927_IRCSR_ILV_MASK 0x00000700 +#define TX3927_IRCSR_IVL_MASK 0x0000001f + +#define TX3927_IR_INT0 0 +#define TX3927_IR_INT1 1 +#define TX3927_IR_INT2 2 +#define TX3927_IR_INT3 3 +#define TX3927_IR_INT4 4 +#define TX3927_IR_INT5 5 +#define TX3927_IR_SIO0 6 +#define TX3927_IR_SIO1 7 +#define TX3927_IR_SIO(ch) (6 + (ch)) +#define TX3927_IR_DMA 8 +#define TX3927_IR_PIO 9 +#define TX3927_IR_PCI 10 +#define TX3927_IR_TMR0 13 +#define TX3927_IR_TMR1 14 +#define TX3927_IR_TMR2 15 +#define TX3927_NUM_IR 16 + +/* + * PCIC + */ +/* bits for PCICMD */ +/* see PCI_COMMAND_XXX in linux/pci.h */ + +/* bits for PCISTAT */ +/* see PCI_STATUS_XXX in linux/pci.h */ +#define PCI_STATUS_NEW_CAP 0x0010 + +/* bits for TC */ +#define TX3927_PCIC_TC_OF16E 0x00000020 +#define TX3927_PCIC_TC_IF8E 0x00000010 +#define TX3927_PCIC_TC_OF8E 0x00000008 + +/* bits for IOBA/MBA */ +/* see PCI_BASE_ADDRESS_XXX in linux/pci.h */ + +/* bits for PBAPMC */ +#define TX3927_PCIC_PBAPMC_RPBA 0x00000004 +#define TX3927_PCIC_PBAPMC_PBAEN 0x00000002 +#define TX3927_PCIC_PBAPMC_BMCEN 0x00000001 + +/* bits for LBSTAT/LBIM */ +#define TX3927_PCIC_LBIM_ALL 0x0000003e + +/* bits for PCISTATIM (see also PCI_STATUS_XXX in linux/pci.h */ +#define TX3927_PCIC_PCISTATIM_ALL 0x0000f900 + +/* bits for LBC */ +#define TX3927_PCIC_LBC_IBSE 0x00004000 +#define TX3927_PCIC_LBC_TIBSE 0x00002000 +#define TX3927_PCIC_LBC_TMFBSE 0x00001000 +#define TX3927_PCIC_LBC_HRST 0x00000800 +#define TX3927_PCIC_LBC_SRST 0x00000400 +#define TX3927_PCIC_LBC_EPCAD 0x00000200 +#define TX3927_PCIC_LBC_MSDSE 0x00000100 +#define TX3927_PCIC_LBC_CRR 0x00000080 +#define TX3927_PCIC_LBC_ILMDE 0x00000040 +#define TX3927_PCIC_LBC_ILIDE 0x00000020 + +#define TX3927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX3927_PCIC_MAX_DEVNU TX3927_PCIC_IDSEL_AD_TO_SLOT(32) + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX3927_CCFG_TLBOFF 0x00020000 +#define TX3927_CCFG_BEOW 0x00010000 +#define TX3927_CCFG_WR 0x00008000 +#define TX3927_CCFG_TOE 0x00004000 +#define TX3927_CCFG_PCIXARB 0x00002000 +#define TX3927_CCFG_PCI3 0x00001000 +#define TX3927_CCFG_PSNP 0x00000800 +#define TX3927_CCFG_PPRI 0x00000400 +#define TX3927_CCFG_PLLM 0x00000030 +#define TX3927_CCFG_ENDIAN 0x00000004 +#define TX3927_CCFG_HALT 0x00000002 +#define TX3927_CCFG_ACEHOLD 0x00000001 + +/* PCFG : Pin Configuration */ +#define TX3927_PCFG_SYSCLKEN 0x08000000 +#define TX3927_PCFG_SDRCLKEN_ALL 0x07c00000 +#define TX3927_PCFG_SDRCLKEN(ch) (0x00400000<<(ch)) +#define TX3927_PCFG_PCICLKEN_ALL 0x003c0000 +#define TX3927_PCFG_PCICLKEN(ch) (0x00040000<<(ch)) +#define TX3927_PCFG_SELALL 0x0003ffff +#define TX3927_PCFG_SELCS 0x00020000 +#define TX3927_PCFG_SELDSF 0x00010000 +#define TX3927_PCFG_SELSIOC_ALL 0x0000c000 +#define TX3927_PCFG_SELSIOC(ch) (0x00004000<<(ch)) +#define TX3927_PCFG_SELSIO_ALL 0x00003000 +#define TX3927_PCFG_SELSIO(ch) (0x00001000<<(ch)) +#define TX3927_PCFG_SELTMR_ALL 0x00000e00 +#define TX3927_PCFG_SELTMR(ch) (0x00000200<<(ch)) +#define TX3927_PCFG_SELDONE 0x00000100 +#define TX3927_PCFG_INTDMA_ALL 0x000000f0 +#define TX3927_PCFG_INTDMA(ch) (0x00000010<<(ch)) +#define TX3927_PCFG_SELDMA_ALL 0x0000000f +#define TX3927_PCFG_SELDMA(ch) (0x00000001<<(ch)) + +#ifndef __ASSEMBLY__ + +#define tx3927_sdramcptr ((struct tx3927_sdramc_reg *)TX3927_SDRAMC_REG) +#define tx3927_romcptr ((struct tx3927_romc_reg *)TX3927_ROMC_REG) +#define tx3927_dmaptr ((struct tx3927_dma_reg *)TX3927_DMA_REG) +#define tx3927_ircptr ((struct tx3927_irc_reg *)TX3927_IRC_REG) +#define tx3927_pcicptr ((struct tx3927_pcic_reg *)TX3927_PCIC_REG) +#define tx3927_ccfgptr ((struct tx3927_ccfg_reg *)TX3927_CCFG_REG) +#define tx3927_tmrptr(ch) ((struct txx927_tmr_reg *)TX3927_TMR_REG(ch)) +#define tx3927_sioptr(ch) ((struct txx927_sio_reg *)TX3927_SIO_REG(ch)) +#define tx3927_pioptr ((struct txx927_pio_reg *)TX3927_PIO_REG) + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_TX3927_H */ diff -Nru a/include/asm-mips/jmr3927/txx927.h b/include/asm-mips/jmr3927/txx927.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/jmr3927/txx927.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,175 @@ +/* + * Common definitions for TX3927/TX4927 + * + * 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) 2000 Toshiba Corporation + */ +#ifndef __ASM_TXX927_H +#define __ASM_TXX927_H + +#ifndef __ASSEMBLY__ + +struct txx927_tmr_reg { + volatile unsigned long tcr; + volatile unsigned long tisr; + volatile unsigned long cpra; + volatile unsigned long cprb; + volatile unsigned long itmr; + volatile unsigned long unused0[3]; + volatile unsigned long ccdr; + volatile unsigned long unused1[3]; + volatile unsigned long pgmr; + volatile unsigned long unused2[3]; + volatile unsigned long wtmr; + volatile unsigned long unused3[43]; + volatile unsigned long trr; +}; + +struct txx927_sio_reg { + volatile unsigned long lcr; + volatile unsigned long dicr; + volatile unsigned long disr; + volatile unsigned long cisr; + volatile unsigned long fcr; + volatile unsigned long flcr; + volatile unsigned long bgr; + volatile unsigned long tfifo; + volatile unsigned long rfifo; +}; + +struct txx927_pio_reg { + volatile unsigned long dout; + volatile unsigned long din; + volatile unsigned long dir; + volatile unsigned long od; + volatile unsigned long flag[2]; + volatile unsigned long pol; + volatile unsigned long intc; + volatile unsigned long maskcpu; + volatile unsigned long maskext; +}; + +#endif /* !__ASSEMBLY__ */ + + +/* + * TMR + */ +/* TMTCR : Timer Control */ +#define TXx927_TMTCR_TCE 0x00000080 +#define TXx927_TMTCR_CCDE 0x00000040 +#define TXx927_TMTCR_CRE 0x00000020 +#define TXx927_TMTCR_ECES 0x00000008 +#define TXx927_TMTCR_CCS 0x00000004 +#define TXx927_TMTCR_TMODE_MASK 0x00000003 +#define TXx927_TMTCR_TMODE_ITVL 0x00000000 + +/* TMTISR : Timer Int. Status */ +#define TXx927_TMTISR_TPIBS 0x00000004 +#define TXx927_TMTISR_TPIAS 0x00000002 +#define TXx927_TMTISR_TIIS 0x00000001 + +/* TMTITMR : Interval Timer Mode */ +#define TXx927_TMTITMR_TIIE 0x00008000 +#define TXx927_TMTITMR_TZCE 0x00000001 + +/* + * SIO + */ +/* SILCR : Line Control */ +#define TXx927_SILCR_SCS_MASK 0x00000060 +#define TXx927_SILCR_SCS_IMCLK 0x00000000 +#define TXx927_SILCR_SCS_IMCLK_BG 0x00000020 +#define TXx927_SILCR_SCS_SCLK 0x00000040 +#define TXx927_SILCR_SCS_SCLK_BG 0x00000060 +#define TXx927_SILCR_UEPS 0x00000010 +#define TXx927_SILCR_UPEN 0x00000008 +#define TXx927_SILCR_USBL_MASK 0x00000004 +#define TXx927_SILCR_USBL_1BIT 0x00000004 +#define TXx927_SILCR_USBL_2BIT 0x00000000 +#define TXx927_SILCR_UMODE_MASK 0x00000003 +#define TXx927_SILCR_UMODE_8BIT 0x00000000 +#define TXx927_SILCR_UMODE_7BIT 0x00000001 + +/* SIDICR : DMA/Int. Control */ +#define TXx927_SIDICR_TDE 0x00008000 +#define TXx927_SIDICR_RDE 0x00004000 +#define TXx927_SIDICR_TIE 0x00002000 +#define TXx927_SIDICR_RIE 0x00001000 +#define TXx927_SIDICR_SPIE 0x00000800 +#define TXx927_SIDICR_CTSAC 0x00000600 +#define TXx927_SIDICR_STIE_MASK 0x0000003f +#define TXx927_SIDICR_STIE_OERS 0x00000020 +#define TXx927_SIDICR_STIE_CTSS 0x00000010 +#define TXx927_SIDICR_STIE_RBRKD 0x00000008 +#define TXx927_SIDICR_STIE_TRDY 0x00000004 +#define TXx927_SIDICR_STIE_TXALS 0x00000002 +#define TXx927_SIDICR_STIE_UBRKD 0x00000001 + +/* SIDISR : DMA/Int. Status */ +#define TXx927_SIDISR_UBRK 0x00008000 +#define TXx927_SIDISR_UVALID 0x00004000 +#define TXx927_SIDISR_UFER 0x00002000 +#define TXx927_SIDISR_UPER 0x00001000 +#define TXx927_SIDISR_UOER 0x00000800 +#define TXx927_SIDISR_ERI 0x00000400 +#define TXx927_SIDISR_TOUT 0x00000200 +#define TXx927_SIDISR_TDIS 0x00000100 +#define TXx927_SIDISR_RDIS 0x00000080 +#define TXx927_SIDISR_STIS 0x00000040 +#define TXx927_SIDISR_RFDN_MASK 0x0000001f + +/* SICISR : Change Int. Status */ +#define TXx927_SICISR_OERS 0x00000020 +#define TXx927_SICISR_CTSS 0x00000010 +#define TXx927_SICISR_RBRKD 0x00000008 +#define TXx927_SICISR_TRDY 0x00000004 +#define TXx927_SICISR_TXALS 0x00000002 +#define TXx927_SICISR_UBRKD 0x00000001 + +/* SIFCR : FIFO Control */ +#define TXx927_SIFCR_SWRST 0x00008000 +#define TXx927_SIFCR_RDIL_MASK 0x00000180 +#define TXx927_SIFCR_RDIL_1 0x00000000 +#define TXx927_SIFCR_RDIL_4 0x00000080 +#define TXx927_SIFCR_RDIL_8 0x00000100 +#define TXx927_SIFCR_RDIL_12 0x00000180 +#define TXx927_SIFCR_RDIL_MAX 0x00000180 +#define TXx927_SIFCR_TDIL_MASK 0x00000018 +#define TXx927_SIFCR_TDIL_MASK 0x00000018 +#define TXx927_SIFCR_TDIL_1 0x00000000 +#define TXx927_SIFCR_TDIL_4 0x00000001 +#define TXx927_SIFCR_TDIL_8 0x00000010 +#define TXx927_SIFCR_TDIL_MAX 0x00000010 +#define TXx927_SIFCR_TFRST 0x00000004 +#define TXx927_SIFCR_RFRST 0x00000002 +#define TXx927_SIFCR_FRSTE 0x00000001 +#define TXx927_SIO_TX_FIFO 8 +#define TXx927_SIO_RX_FIFO 16 + +/* SIFLCR : Flow Control */ +#define TXx927_SIFLCR_RCS 0x00001000 +#define TXx927_SIFLCR_TES 0x00000800 +#define TXx927_SIFLCR_RTSSC 0x00000200 +#define TXx927_SIFLCR_RSDE 0x00000100 +#define TXx927_SIFLCR_TSDE 0x00000080 +#define TXx927_SIFLCR_RTSTL_MASK 0x0000001e +#define TXx927_SIFLCR_RTSTL_MAX 0x0000001e +#define TXx927_SIFLCR_TBRK 0x00000001 + +/* SIBGR : Baudrate Control */ +#define TXx927_SIBGR_BCLK_MASK 0x00000300 +#define TXx927_SIBGR_BCLK_T0 0x00000000 +#define TXx927_SIBGR_BCLK_T2 0x00000100 +#define TXx927_SIBGR_BCLK_T4 0x00000200 +#define TXx927_SIBGR_BCLK_T6 0x00000300 +#define TXx927_SIBGR_BRD_MASK 0x000000ff + +/* + * PIO + */ + +#endif /* __ASM_TXX927_H */ diff -Nru a/include/asm-mips/keyboard.h b/include/asm-mips/keyboard.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/keyboard.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,96 @@ +/* + * 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 - 1999 Ralf Baechle + */ +#ifndef _ASM_KEYBOARD_H +#define _ASM_KEYBOARD_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/kd.h> +#include <linux/pm.h> + +#define DISABLE_KBD_DURING_INTERRUPTS 0 + +#ifdef CONFIG_PC_KEYB + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *); +extern pm_callback pm_kbd_request_override; +extern unsigned char pckbd_sysrq_xlate[128]; +extern void kbd_forward_char (int ch); + +#define kbd_setkeycode pckbd_setkeycode +#define kbd_getkeycode pckbd_getkeycode +#define kbd_translate pckbd_translate +#define kbd_unexpected_up pckbd_unexpected_up +#define kbd_leds pckbd_leds +#define kbd_init_hw pckbd_init_hw +#define kbd_sysrq_xlate pckbd_sysrq_xlate + +#define SYSRQ_KEY 0x54 + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +struct kbd_ops { + /* Keyboard driver resource allocation */ + void (*kbd_request_region)(void); + int (*kbd_request_irq)(void (*handler)(int, void *, struct pt_regs *)); + + /* PSaux driver resource management */ + int (*aux_request_irq)(void (*handler)(int, void *, struct pt_regs *)); + void (*aux_free_irq)(void); + + /* Methods to access the keyboard processor's I/O registers */ + unsigned char (*kbd_read_input)(void); + void (*kbd_write_output)(unsigned char val); + void (*kbd_write_command)(unsigned char val); + unsigned char (*kbd_read_status)(void); +}; + +extern struct kbd_ops *kbd_ops; + +/* Do the actual calls via kbd_ops vector */ +#define kbd_request_region() kbd_ops->kbd_request_region() +#define kbd_request_irq(handler) kbd_ops->kbd_request_irq(handler) + +#define aux_request_irq(hand, dev_id) kbd_ops->aux_request_irq(hand) +#define aux_free_irq(dev_id) kbd_ops->aux_free_irq() + +#define kbd_read_input() kbd_ops->kbd_read_input() +#define kbd_write_output(val) kbd_ops->kbd_write_output(val) +#define kbd_write_command(val) kbd_ops->kbd_write_command(val) +#define kbd_read_status() kbd_ops->kbd_read_status() + +#else + +extern int kbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int kbd_getkeycode(unsigned int scancode); +extern int kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char kbd_unexpected_up(unsigned char keycode); +extern void kbd_leds(unsigned char leds); +extern void kbd_init_hw(void); +extern unsigned char *kbd_sysrq_xlate; + +extern unsigned char kbd_sysrq_key; +#define SYSRQ_KEY kbd_sysrq_key + +#endif + +#endif /* __KERNEL */ + +#endif /* _ASM_KEYBOARD_H */ diff -Nru a/include/asm-mips/kmap_types.h b/include/asm-mips/kmap_types.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/kmap_types.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,32 @@ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +#include <linux/config.h> + +#ifdef CONFIG_DEBUG_HIGHMEM +# define D(n) __KM_FENCE_##n , +#else +# define D(n) +#endif + +enum km_type { +D(0) KM_BOUNCE_READ, +D(1) KM_SKB_SUNRPC_DATA, +D(2) KM_SKB_DATA_SOFTIRQ, +D(3) KM_USER0, +D(4) KM_USER1, +D(5) KM_BIO_SRC_IRQ, +D(6) KM_BIO_DST_IRQ, +D(7) KM_PTE0, +D(8) KM_PTE1, +D(9) KM_PTE2, +D(10) KM_IRQ0, +D(11) KM_IRQ1, +D(12) KM_SOFTIRQ0, +D(13) KM_SOFTIRQ1, +D(14) KM_TYPE_NR +}; + +#undef D + +#endif diff -Nru a/include/asm-mips/lasat/ds1603.h b/include/asm-mips/lasat/ds1603.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/ds1603.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,18 @@ +#include <asm/addrspace.h> + +/* Lasat 100 */ +#define DS1603_REG_100 (KSEG1ADDR(0x1c810000)) +#define DS1603_RST_100 (1 << 2) +#define DS1603_CLK_100 (1 << 0) +#define DS1603_DATA_SHIFT_100 1 +#define DS1603_DATA_100 (1 << DS1603_DATA_SHIFT_100) + +/* Lasat 200 */ +#define DS1603_REG_200 (KSEG1ADDR(0x11000000)) +#define DS1603_RST_200 (1 << 3) +#define DS1603_CLK_200 (1 << 4) +#define DS1603_DATA_200 (1 << 5) + +#define DS1603_DATA_REG_200 (DS1603_REG_200 + 0x10000) +#define DS1603_DATA_READ_SHIFT_200 9 +#define DS1603_DATA_READ_200 (1 << DS1603_DATA_READ_SHIFT_200) diff -Nru a/include/asm-mips/lasat/eeprom.h b/include/asm-mips/lasat/eeprom.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/eeprom.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,17 @@ +#include <asm/addrspace.h> + +/* lasat 100 */ +#define AT93C_REG_100 KSEG1ADDR(0x1c810000) +#define AT93C_RDATA_REG_100 AT93C_REG_100 +#define AT93C_RDATA_SHIFT_100 4 +#define AT93C_WDATA_SHIFT_100 4 +#define AT93C_CS_M_100 ( 1 << 5 ) +#define AT93C_CLK_M_100 ( 1 << 3 ) + +/* lasat 200 */ +#define AT93C_REG_200 KSEG1ADDR(0x11000000) +#define AT93C_RDATA_REG_200 (AT93C_REG_200+0x10000) +#define AT93C_RDATA_SHIFT_200 8 +#define AT93C_WDATA_SHIFT_200 2 +#define AT93C_CS_M_200 ( 1 << 0 ) +#define AT93C_CLK_M_200 ( 1 << 1 ) diff -Nru a/include/asm-mips/lasat/head.h b/include/asm-mips/lasat/head.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/head.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,22 @@ +/* + * Image header stuff + */ +#ifndef _HEAD_H +#define _HEAD_H + +#define LASAT_K_MAGIC0_VAL 0xfedeabba +#define LASAT_K_MAGIC1_VAL 0x00bedead + +#ifndef _LANGUAGE_ASSEMBLY +#include <linux/types.h> +struct bootloader_header { + u32 magic[2]; + u32 version; + u32 image_start; + u32 image_size; + u32 kernel_start; + u32 kernel_entry; +}; +#endif + +#endif /* _HEAD_H */ diff -Nru a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/lasat.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,240 @@ +/* + * lasat.h + * + * Thomas Horsten <thh@lasat.com> + * Copyright (C) 2000 LASAT Networks A/S. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Configuration for LASAT boards, loads the appropriate include files. + */ +#ifndef _LASAT_H +#define _LASAT_H + +#ifndef _LANGUAGE_ASSEMBLY + +extern struct lasat_misc { + volatile u32 *reset_reg; + volatile u32 *flash_wp_reg; + u32 flash_wp_bit; +} *lasat_misc; + +enum lasat_mtdparts { + LASAT_MTD_BOOTLOADER, + LASAT_MTD_SERVICE, + LASAT_MTD_NORMAL, + LASAT_MTD_CONFIG, + LASAT_MTD_FS, + LASAT_MTD_LAST +}; + +/* + * The format of the data record in the EEPROM. + * See Documentation/LASAT/eeprom.txt for a detailed description + * of the fields in this struct, and the LASAT Hardware Configuration + * field specification for a detailed description of the config + * field. + */ +#include <linux/types.h> + +#define LASAT_EEPROM_VERSION 7 +struct lasat_eeprom_struct { + unsigned int version; + unsigned int cfg[3]; + unsigned char hwaddr[6]; + unsigned char print_partno[12]; + unsigned char term0; + unsigned char print_serial[14]; + unsigned char term1; + unsigned char prod_partno[12]; + unsigned char term2; + unsigned char prod_serial[14]; + unsigned char term3; + unsigned char passwd_hash[16]; + unsigned char pwdnull; + unsigned char vendid; + unsigned char ts_ref; + unsigned char ts_signoff; + unsigned char reserved[11]; + unsigned char debugaccess; + unsigned short prid; + unsigned int serviceflag; + unsigned int ipaddr; + unsigned int netmask; + unsigned int crc32; +}; + +struct lasat_eeprom_struct_pre7 { + unsigned int version; + unsigned int flags[3]; + unsigned char hwaddr0[6]; + unsigned char hwaddr1[6]; + unsigned char print_partno[9]; + unsigned char term0; + unsigned char print_serial[14]; + unsigned char term1; + unsigned char prod_partno[9]; + unsigned char term2; + unsigned char prod_serial[14]; + unsigned char term3; + unsigned char passwd_hash[24]; + unsigned char pwdnull; + unsigned char vendor; + unsigned char ts_ref; + unsigned char ts_signoff; + unsigned char reserved[6]; + unsigned int writecount; + unsigned int ipaddr; + unsigned int netmask; + unsigned int crc32; +}; + +/* Configuration descriptor encoding - see the doc for details */ + +#define LASAT_W0_DSCTYPE(v) ( ( (v) ) & 0xf ) +#define LASAT_W0_BMID(v) ( ( (v) >> 0x04 ) & 0xf ) +#define LASAT_W0_CPUTYPE(v) ( ( (v) >> 0x08 ) & 0xf ) +#define LASAT_W0_BUSSPEED(v) ( ( (v) >> 0x0c ) & 0xf ) +#define LASAT_W0_CPUCLK(v) ( ( (v) >> 0x10 ) & 0xf ) +#define LASAT_W0_SDRAMBANKSZ(v) ( ( (v) >> 0x14 ) & 0xf ) +#define LASAT_W0_SDRAMBANKS(v) ( ( (v) >> 0x18 ) & 0xf ) +#define LASAT_W0_L2CACHE(v) ( ( (v) >> 0x1c ) & 0xf ) + +#define LASAT_W1_EDHAC(v) ( ( (v) ) & 0xf ) +#define LASAT_W1_HIFN(v) ( ( (v) >> 0x04 ) & 0x1 ) +#define LASAT_W1_ISDN(v) ( ( (v) >> 0x05 ) & 0x1 ) +#define LASAT_W1_IDE(v) ( ( (v) >> 0x06 ) & 0x1 ) +#define LASAT_W1_HDLC(v) ( ( (v) >> 0x07 ) & 0x1 ) +#define LASAT_W1_USVERSION(v) ( ( (v) >> 0x08 ) & 0x1 ) +#define LASAT_W1_4MACS(v) ( ( (v) >> 0x09 ) & 0x1 ) +#define LASAT_W1_EXTSERIAL(v) ( ( (v) >> 0x0a ) & 0x1 ) +#define LASAT_W1_FLASHSIZE(v) ( ( (v) >> 0x0c ) & 0xf ) +#define LASAT_W1_PCISLOTS(v) ( ( (v) >> 0x10 ) & 0xf ) +#define LASAT_W1_PCI1OPT(v) ( ( (v) >> 0x14 ) & 0xf ) +#define LASAT_W1_PCI2OPT(v) ( ( (v) >> 0x18 ) & 0xf ) +#define LASAT_W1_PCI3OPT(v) ( ( (v) >> 0x1c ) & 0xf ) + +/* Routines specific to LASAT boards */ + +#define LASAT_BMID_MASQUERADE2 0 +#define LASAT_BMID_MASQUERADEPRO 1 +#define LASAT_BMID_SAFEPIPE25 2 +#define LASAT_BMID_SAFEPIPE50 3 +#define LASAT_BMID_SAFEPIPE100 4 +#define LASAT_BMID_SAFEPIPE5000 5 +#define LASAT_BMID_SAFEPIPE7000 6 +#define LASAT_BMID_SAFEPIPE1000 7 +//#define LASAT_BMID_SAFEPIPE30 7 +//#define LASAT_BMID_SAFEPIPE5100 8 +//#define LASAT_BMID_SAFEPIPE7100 9 +#define LASAT_BMID_UNKNOWN 0xf +#define LASAT_MAX_BMID_NAMES 9 // no larger than 15! + +#define LASAT_HAS_EDHAC ( 1 << 0 ) +#define LASAT_EDHAC_FAST ( 1 << 1 ) +#define LASAT_HAS_EADI ( 1 << 2 ) +#define LASAT_HAS_HIFN ( 1 << 3 ) +#define LASAT_HAS_ISDN ( 1 << 4 ) +#define LASAT_HAS_LEASEDLINE_IF ( 1 << 5 ) +#define LASAT_HAS_HDC ( 1 << 6 ) + +#define LASAT_PRID_MASQUERADE2 0 +#define LASAT_PRID_MASQUERADEPRO 1 +#define LASAT_PRID_SAFEPIPE25 2 +#define LASAT_PRID_SAFEPIPE50 3 +#define LASAT_PRID_SAFEPIPE100 4 +#define LASAT_PRID_SAFEPIPE5000 5 +#define LASAT_PRID_SAFEPIPE7000 6 +#define LASAT_PRID_SAFEPIPE30 7 +#define LASAT_PRID_SAFEPIPE5100 8 +#define LASAT_PRID_SAFEPIPE7100 9 + +#define LASAT_PRID_SAFEPIPE1110 10 +#define LASAT_PRID_SAFEPIPE3020 11 +#define LASAT_PRID_SAFEPIPE3030 12 +#define LASAT_PRID_SAFEPIPE5020 13 +#define LASAT_PRID_SAFEPIPE5030 14 +#define LASAT_PRID_SAFEPIPE1120 15 +#define LASAT_PRID_SAFEPIPE1130 16 +#define LASAT_PRID_SAFEPIPE6010 17 +#define LASAT_PRID_SAFEPIPE6110 18 +#define LASAT_PRID_SAFEPIPE6210 19 +#define LASAT_PRID_SAFEPIPE1020 20 +#define LASAT_PRID_SAFEPIPE1040 21 +#define LASAT_PRID_SAFEPIPE1060 22 + +struct lasat_info { + unsigned int li_cpu_hz; + unsigned int li_bus_hz; + unsigned int li_bmid; + unsigned int li_memsize; + unsigned int li_flash_size; + unsigned int li_prid; + unsigned char li_bmstr[16]; + unsigned char li_namestr[32]; + unsigned char li_typestr[16]; + /* Info on the Flash layout */ + unsigned int li_flash_base; + unsigned long li_flashpart_base[LASAT_MTD_LAST]; + unsigned long li_flashpart_size[LASAT_MTD_LAST]; + struct lasat_eeprom_struct li_eeprom_info; + unsigned int li_eeprom_upgrade_version; + unsigned int li_debugaccess; +}; + +extern struct lasat_info lasat_board_info; + +static inline unsigned long lasat_flash_partition_start(int partno) +{ + if (partno < 0 || partno >= LASAT_MTD_LAST) + return 0; + + return lasat_board_info.li_flashpart_base[partno]; +} + +static inline unsigned long lasat_flash_partition_size(int partno) +{ + if (partno < 0 || partno >= LASAT_MTD_LAST) + return 0; + + return lasat_board_info.li_flashpart_size[partno]; +} + +/* Called from setup() to initialize the global board_info struct */ +extern int lasat_init_board_info(void); + +/* Write the modified EEPROM info struct */ +extern void lasat_write_eeprom_info(void); + +#define N_MACHTYPES 2 +/* for calibration of delays */ + +#include <asm/delay.h> + +extern void (* prom_printf)(const char *fmt, ...); + +#endif /* !defined (_LANGUAGE_ASSEMBLY) */ + +#define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef +#define LASAT_SERVICEMODE_MAGIC_2 0xfedeabba + +/* Lasat 100 boards */ +#define LASAT_GT_BASE (KSEG1ADDR(0x14000000)) + +/* Lasat 200 boards */ +#define Vrc5074_PHYS_BASE 0x1fa00000 +#define Vrc5074_BASE (KSEG1ADDR(Vrc5074_PHYS_BASE)) +#define PCI_WINDOW1 0x1a000000 + +#endif /* _LASAT_H */ diff -Nru a/include/asm-mips/lasat/lasatint.h b/include/asm-mips/lasat/lasatint.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/lasatint.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,12 @@ +#define LASATINT_END 16 + +/* lasat 100 */ +#define LASAT_INT_STATUS_REG_100 (KSEG1ADDR(0x1c880000)) +#define LASAT_INT_MASK_REG_100 (KSEG1ADDR(0x1c890000)) +#define LASATINT_MASK_SHIFT_100 0 + +/* lasat 200 */ +#define LASAT_INT_STATUS_REG_200 (KSEG1ADDR(0x1104003c)) +#define LASAT_INT_MASK_REG_200 (KSEG1ADDR(0x1104003c)) +#define LASATINT_MASK_SHIFT_200 16 + diff -Nru a/include/asm-mips/lasat/picvue.h b/include/asm-mips/lasat/picvue.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/picvue.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,15 @@ +/* Lasat 100 */ +#define PVC_REG_100 KSEG1ADDR(0x1c820000) +#define PVC_DATA_SHIFT_100 0 +#define PVC_DATA_M_100 0xFF +#define PVC_E_100 (1 << 8) +#define PVC_RW_100 (1 << 9) +#define PVC_RS_100 (1 << 10) + +/* Lasat 200 */ +#define PVC_REG_200 KSEG1ADDR(0x11000000) +#define PVC_DATA_SHIFT_200 24 +#define PVC_DATA_M_200 (0xFF << PVC_DATA_SHIFT_200) +#define PVC_E_200 (1 << 16) +#define PVC_RW_200 (1 << 17) +#define PVC_RS_200 (1 << 18) diff -Nru a/include/asm-mips/lasat/serial.h b/include/asm-mips/lasat/serial.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/lasat/serial.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,28 @@ +#include <asm/lasat/lasat.h> + +/* Lasat 100 boards serial configuration */ +#define LASAT_BASE_BAUD_100 ( 7372800 / 16 ) +#define LASAT_UART_REGS_BASE_100 0x1c8b0000 +#define LASAT_UART_REGS_SHIFT_100 2 +#define LASATINT_UART_100 8 + +/* * LASAT 200 boards serial configuration */ +#define LASAT_BASE_BAUD_200 (100000000 / 16 / 12) +#define LASAT_UART_REGS_BASE_200 (Vrc5074_PHYS_BASE + 0x0300) +#define LASAT_UART_REGS_SHIFT_200 3 +#define LASATINT_UART_200 13 + +#if defined(CONFIG_LASAT_100) +#define LASAT_BASE_BAUD LASAT_BASE_BAUD_200 +#define LASAT_UART_REGS_BASE LASAT_UART_REGS_BASE_200 +#define LASAT_UART_REGS_SHIFT LASAT_UART_REGS_SHIFT_200 +#define LASATINT_UART LASAT_UART_REGS_SHIFT_200 +#elif defined(CONFIG_LASAT_200) +#define LASAT_BASE_BAUD LASAT_BASE_BAUD_200 +#define LASAT_UART_REGS_BASE LASAT_UART_REGS_BASE_200 +#define LASAT_UART_REGS_SHIFT LASAT_UART_REGS_SHIFT_200 +#define LASATINT_UART LASAT_UART_REGS_SHIFT_200 +#else +#error Select a Lasat board in the configuration menu +#endif + diff -Nru a/include/asm-mips/mc146818rtc.h b/include/asm-mips/mc146818rtc.h --- a/include/asm-mips/mc146818rtc.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips/mc146818rtc.h Fri Jun 27 14:20:06 2003 @@ -6,33 +6,15 @@ * Machine dependent access functions for RTC registers. * * Copyright (C) 1996, 1997, 1998, 2000 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef _ASM_MC146818RTC_H #define _ASM_MC146818RTC_H #include <linux/config.h> -#include <asm/io.h> -#ifndef RTC_PORT -#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) -#define RTC_PORT(x) (0x14014800 + (x)) -#else -#define RTC_PORT(x) (0x70 + (x)) -#endif -#endif +#include <asm/io.h> -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) ({ \ -rtc_ops->rtc_read_data(addr); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -rtc_ops->rtc_write_data(val, addr); \ -}) -#define RTC_ALWAYS_BCD \ -rtc_ops->rtc_bcd_mode() /* * This structure defines how to access various features of @@ -47,15 +29,38 @@ extern struct rtc_ops *rtc_ops; +/* + * Most supported machines access the RTC index register via an ISA + * port access but the way to access the date register differs ... + * The DECstation directly maps the RTC memory in the CPU's address + * space with the chipset generating necessary index write/data access + * cycles automagically. + */ +#define CMOS_READ(addr) ({ \ +rtc_ops->rtc_read_data(addr); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +rtc_ops->rtc_write_data(val, addr); \ +}) +#define RTC_ALWAYS_BCD \ +rtc_ops->rtc_bcd_mode() + + #ifdef CONFIG_DECSTATION -#define RTC_IRQ 0 -#elif defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) -#include <asm/it8172/it8172_int.h> -#define RTC_IRQ IT8172_RTC_IRQ + +#include <asm/dec/rtc-dec.h> + +#elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) + +#define RTC_PORT(x) (0x0c000000 + (x)) +#define RTC_IOMAPPED 0 +#define RTC_IRQ 0 + #else -#define RTC_IRQ 8 -#endif -#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */ +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +#endif #endif /* _ASM_MC146818RTC_H */ diff -Nru a/include/asm-mips/mips-boards/atlas.h b/include/asm-mips/mips-boards/atlas.h --- a/include/asm-mips/mips-boards/atlas.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/mips-boards/atlas.h Fri Jun 27 14:19:55 2003 @@ -27,7 +27,7 @@ #include <asm/addrspace.h> -/* +/* * Atlas RTC-device indirect register access. */ #define ATLAS_RTC_ADR_REG (KSEG1ADDR(0x1f000800)) @@ -43,7 +43,7 @@ * Atlas UART register base. */ #define ATLAS_UART_REGS_BASE (0x1f000900) -#define ATLAS_BASE_BAUD ( 3686400 / 16 ) +#define ATLAS_BASE_BAUD ( 3686400 / 16 ) /* * Atlas PSU standby register. @@ -54,7 +54,7 @@ /* * We make a universal assumption about the way the bootloader (YAMON) * have located the Philips SAA9730 chip. - * This is not ideal, but is needed for setting up remote debugging as + * This is not ideal, but is needed for setting up remote debugging as * soon as possible. */ #define ATLAS_SAA9730_REG (KSEG1ADDR(0x08800000)) diff -Nru a/include/asm-mips/mips-boards/atlasint.h b/include/asm-mips/mips-boards/atlasint.h --- a/include/asm-mips/mips-boards/atlasint.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/mips-boards/atlasint.h Fri Jun 27 14:19:57 2003 @@ -29,8 +29,8 @@ #define ATLASINT_UART 0 #define ATLASINT_END 32 -/* - * Atlas registers are memory mapped on 64-bit aligned boundaries and +/* + * Atlas registers are memory mapped on 64-bit aligned boundaries and * only word access are allowed. */ struct atlas_ictrl_regs { diff -Nru a/include/asm-mips/mips-boards/bonito64.h b/include/asm-mips/mips-boards/bonito64.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/mips-boards/bonito64.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,432 @@ +/* + * bonito.h + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2001 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This file is the original bonito.h from Algorithmics with minor changes + * to fit into linux. + */ + +/* + * Bonito Register Map + * Copyright (c) 1999 Algorithmics Ltd + * + * Algorithmics gives permission for anyone to use and modify this file + * without any obligation or license condition except that you retain + * this copyright message in any source redistribution in whole or part. + * + * Updated copies of this and other files can be found at + * ftp://ftp.algor.co.uk/pub/bonito/ + * + * Users of the Bonito controller are warmly recommended to contribute + * any useful changes back to Algorithmics (mail to bonito@algor.co.uk). + */ + +/* Revision 1.48 autogenerated on 08/17/99 15:20:01 */ +/* This bonito64 version editted from bonito.h Revision 1.48 on 11/09/00 */ + +#ifndef _ASM_MIPS_BOARDS_BONITO64_H +#define _ASM_MIPS_BOARDS_BONITO64_H + +#ifdef __ASSEMBLY__ + +/* offsets from base register */ +#define BONITO(x) (x) + +#else /* !__ASSEMBLY__ */ + +/* offsets from base pointer, this construct allows optimisation */ +/* static char * const _bonito = PA_TO_KVA1(BONITO_BASE); */ +#define BONITO(x) *(volatile u32 *)(_bonito + (x)) + +#endif /* __ASSEMBLY__ */ + + +#define BONITO_BOOT_BASE 0x1fc00000 +#define BONITO_BOOT_SIZE 0x00100000 +#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1) +#define BONITO_FLASH_BASE 0x1c000000 +#define BONITO_FLASH_SIZE 0x03000000 +#define BONITO_FLASH_TOP (BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1) +#define BONITO_SOCKET_BASE 0x1f800000 +#define BONITO_SOCKET_SIZE 0x00400000 +#define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1) +#define BONITO_REG_BASE 0x1fe00000 +#define BONITO_REG_SIZE 0x00040000 +#define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1) +#define BONITO_DEV_BASE 0x1ff00000 +#define BONITO_DEV_SIZE 0x00100000 +#define BONITO_DEV_TOP (BONITO_DEV_BASE+BONITO_DEV_SIZE-1) +#define BONITO_PCILO_BASE 0x10000000 +#define BONITO_PCILO_SIZE 0x0c000000 +#define BONITO_PCILO_TOP (BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1) +#define BONITO_PCILO0_BASE 0x10000000 +#define BONITO_PCILO1_BASE 0x14000000 +#define BONITO_PCILO2_BASE 0x18000000 +#define BONITO_PCIHI_BASE 0x20000000 +#define BONITO_PCIHI_SIZE 0x20000000 +#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1) +#define BONITO_PCIIO_BASE 0x1fd00000 +#define BONITO_PCIIO_SIZE 0x00100000 +#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1) +#define BONITO_PCICFG_BASE 0x1fe80000 +#define BONITO_PCICFG_SIZE 0x00080000 +#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1) + + +/* Bonito Register Bases */ + +#define BONITO_PCICONFIGBASE 0x00 +#define BONITO_REGBASE 0x100 + + +/* PCI Configuration Registers */ + +#define BONITO_PCI_REG(x) BONITO(BONITO_PCICONFIGBASE + (x)) +#define BONITO_PCIDID BONITO_PCI_REG(0x00) +#define BONITO_PCICMD BONITO_PCI_REG(0x04) +#define BONITO_PCICLASS BONITO_PCI_REG(0x08) +#define BONITO_PCILTIMER BONITO_PCI_REG(0x0c) +#define BONITO_PCIBASE0 BONITO_PCI_REG(0x10) +#define BONITO_PCIBASE1 BONITO_PCI_REG(0x14) +#define BONITO_PCIBASE2 BONITO_PCI_REG(0x18) +#define BONITO_PCIEXPRBASE BONITO_PCI_REG(0x30) +#define BONITO_PCIINT BONITO_PCI_REG(0x3c) + +#define BONITO_PCICMD_PERR_CLR 0x80000000 +#define BONITO_PCICMD_SERR_CLR 0x40000000 +#define BONITO_PCICMD_MABORT_CLR 0x20000000 +#define BONITO_PCICMD_MTABORT_CLR 0x10000000 +#define BONITO_PCICMD_TABORT_CLR 0x08000000 +#define BONITO_PCICMD_MPERR_CLR 0x01000000 +#define BONITO_PCICMD_PERRRESPEN 0x00000040 +#define BONITO_PCICMD_ASTEPEN 0x00000080 +#define BONITO_PCICMD_SERREN 0x00000100 +#define BONITO_PCILTIMER_BUSLATENCY 0x0000ff00 +#define BONITO_PCILTIMER_BUSLATENCY_SHIFT 8 + + + + +/* 1. Bonito h/w Configuration */ +/* Power on register */ + +#define BONITO_BONPONCFG BONITO(BONITO_REGBASE + 0x00) + +#define BONITO_BONPONCFG_SYSCONTROLLERRD 0x00040000 +#define BONITO_BONPONCFG_ROMCS1SAMP 0x00020000 +#define BONITO_BONPONCFG_ROMCS0SAMP 0x00010000 +#define BONITO_BONPONCFG_CPUBIGEND 0x00004000 +/* Added by RPF 11-9-00 */ +#define BONITO_BONPONCFG_BURSTORDER 0x00001000 +/* --- */ +#define BONITO_BONPONCFG_CPUPARITY 0x00002000 +#define BONITO_BONPONCFG_CPUTYPE 0x00000007 +#define BONITO_BONPONCFG_CPUTYPE_SHIFT 0 +#define BONITO_BONPONCFG_PCIRESET_OUT 0x00000008 +#define BONITO_BONPONCFG_IS_ARBITER 0x00000010 +#define BONITO_BONPONCFG_ROMBOOT 0x000000c0 +#define BONITO_BONPONCFG_ROMBOOT_SHIFT 6 + +#define BONITO_BONPONCFG_ROMBOOT_FLASH (0x0<<BONITO_BONPONCFG_ROMBOOT_SHIFT) +#define BONITO_BONPONCFG_ROMBOOT_SOCKET (0x1<<BONITO_BONPONCFG_ROMBOOT_SHIFT) +#define BONITO_BONPONCFG_ROMBOOT_SDRAM (0x2<<BONITO_BONPONCFG_ROMBOOT_SHIFT) +#define BONITO_BONPONCFG_ROMBOOT_CPURESET (0x3<<BONITO_BONPONCFG_ROMBOOT_SHIFT) + +#define BONITO_BONPONCFG_ROMCS0WIDTH 0x00000100 +#define BONITO_BONPONCFG_ROMCS1WIDTH 0x00000200 +#define BONITO_BONPONCFG_ROMCS0FAST 0x00000400 +#define BONITO_BONPONCFG_ROMCS1FAST 0x00000800 +#define BONITO_BONPONCFG_CONFIG_DIS 0x00000020 + + +/* Other Bonito configuration */ + +#define BONITO_BONGENCFG_OFFSET 0x4 +#define BONITO_BONGENCFG BONITO(BONITO_REGBASE + BONITO_BONGENCFG_OFFSET) + +#define BONITO_BONGENCFG_DEBUGMODE 0x00000001 +#define BONITO_BONGENCFG_SNOOPEN 0x00000002 +#define BONITO_BONGENCFG_CPUSELFRESET 0x00000004 + +#define BONITO_BONGENCFG_FORCE_IRQA 0x00000008 +#define BONITO_BONGENCFG_IRQA_ISOUT 0x00000010 +#define BONITO_BONGENCFG_IRQA_FROM_INT1 0x00000020 +#define BONITO_BONGENCFG_BYTESWAP 0x00000040 + +#define BONITO_BONGENCFG_UNCACHED 0x00000080 +#define BONITO_BONGENCFG_PREFETCHEN 0x00000100 +#define BONITO_BONGENCFG_WBEHINDEN 0x00000200 +#define BONITO_BONGENCFG_CACHEALG 0x00000c00 +#define BONITO_BONGENCFG_CACHEALG_SHIFT 10 +#define BONITO_BONGENCFG_PCIQUEUE 0x00001000 +#define BONITO_BONGENCFG_CACHESTOP 0x00002000 +#define BONITO_BONGENCFG_MSTRBYTESWAP 0x00004000 +#define BONITO_BONGENCFG_BUSERREN 0x00008000 +#define BONITO_BONGENCFG_NORETRYTIMEOUT 0x00010000 +#define BONITO_BONGENCFG_SHORTCOPYTIMEOUT 0x00020000 + +/* 2. IO & IDE configuration */ + +#define BONITO_IODEVCFG BONITO(BONITO_REGBASE + 0x08) + +/* 3. IO & IDE configuration */ + +#define BONITO_SDCFG BONITO(BONITO_REGBASE + 0x0c) + +/* 4. PCI address map control */ + +#define BONITO_PCIMAP BONITO(BONITO_REGBASE + 0x10) +#define BONITO_PCIMEMBASECFG BONITO(BONITO_REGBASE + 0x14) +#define BONITO_PCIMAP_CFG BONITO(BONITO_REGBASE + 0x18) + +/* 5. ICU & GPIO regs */ + +/* GPIO Regs - r/w */ + +#define BONITO_GPIODATA_OFFSET 0x1c +#define BONITO_GPIODATA BONITO(BONITO_REGBASE + BONITO_GPIODATA_OFFSET) +#define BONITO_GPIOIE BONITO(BONITO_REGBASE + 0x20) + +/* ICU Configuration Regs - r/w */ + +#define BONITO_INTEDGE BONITO(BONITO_REGBASE + 0x24) +#define BONITO_INTSTEER BONITO(BONITO_REGBASE + 0x28) +#define BONITO_INTPOL BONITO(BONITO_REGBASE + 0x2c) + +/* ICU Enable Regs - IntEn & IntISR are r/o. */ + +#define BONITO_INTENSET BONITO(BONITO_REGBASE + 0x30) +#define BONITO_INTENCLR BONITO(BONITO_REGBASE + 0x34) +#define BONITO_INTEN BONITO(BONITO_REGBASE + 0x38) +#define BONITO_INTISR BONITO(BONITO_REGBASE + 0x3c) + +/* PCI mail boxes */ + +#define BONITO_PCIMAIL0_OFFSET 0x40 +#define BONITO_PCIMAIL1_OFFSET 0x44 +#define BONITO_PCIMAIL2_OFFSET 0x48 +#define BONITO_PCIMAIL3_OFFSET 0x4c +#define BONITO_PCIMAIL0 BONITO(BONITO_REGBASE + 0x40) +#define BONITO_PCIMAIL1 BONITO(BONITO_REGBASE + 0x44) +#define BONITO_PCIMAIL2 BONITO(BONITO_REGBASE + 0x48) +#define BONITO_PCIMAIL3 BONITO(BONITO_REGBASE + 0x4c) + + +/* 6. PCI cache */ + +#define BONITO_PCICACHECTRL BONITO(BONITO_REGBASE + 0x50) +#define BONITO_PCICACHETAG BONITO(BONITO_REGBASE + 0x54) + +#define BONITO_PCIBADADDR BONITO(BONITO_REGBASE + 0x58) +#define BONITO_PCIMSTAT BONITO(BONITO_REGBASE + 0x5c) + + +/* +#define BONITO_PCIRDPOST BONITO(BONITO_REGBASE + 0x60) +#define BONITO_PCIDATA BONITO(BONITO_REGBASE + 0x64) +*/ + +/* 7. IDE DMA & Copier */ + +#define BONITO_CONFIGBASE 0x000 +#define BONITO_BONITOBASE 0x100 +#define BONITO_LDMABASE 0x200 +#define BONITO_COPBASE 0x300 +#define BONITO_REG_BLOCKMASK 0x300 + +#define BONITO_LDMACTRL BONITO(BONITO_LDMABASE + 0x0) +#define BONITO_LDMASTAT BONITO(BONITO_LDMABASE + 0x0) +#define BONITO_LDMAADDR BONITO(BONITO_LDMABASE + 0x4) +#define BONITO_LDMAGO BONITO(BONITO_LDMABASE + 0x8) +#define BONITO_LDMADATA BONITO(BONITO_LDMABASE + 0xc) + +#define BONITO_COPCTRL BONITO(BONITO_COPBASE + 0x0) +#define BONITO_COPSTAT BONITO(BONITO_COPBASE + 0x0) +#define BONITO_COPPADDR BONITO(BONITO_COPBASE + 0x4) +#define BONITO_COPDADDR BONITO(BONITO_COPBASE + 0x8) +#define BONITO_COPGO BONITO(BONITO_COPBASE + 0xc) + + +/* ###### Bit Definitions for individual Registers #### */ + +/* Gen DMA. */ + +#define BONITO_IDECOPDADDR_DMA_DADDR 0x0ffffffc +#define BONITO_IDECOPDADDR_DMA_DADDR_SHIFT 2 +#define BONITO_IDECOPPADDR_DMA_PADDR 0xfffffffc +#define BONITO_IDECOPPADDR_DMA_PADDR_SHIFT 2 +#define BONITO_IDECOPGO_DMA_SIZE 0x0000fffe +#define BONITO_IDECOPGO_DMA_SIZE_SHIFT 0 +#define BONITO_IDECOPGO_DMA_WRITE 0x00010000 +#define BONITO_IDECOPGO_DMAWCOUNT 0x000f0000 +#define BONITO_IDECOPGO_DMAWCOUNT_SHIFT 16 + +#define BONITO_IDECOPCTRL_DMA_STARTBIT 0x80000000 +#define BONITO_IDECOPCTRL_DMA_RSTBIT 0x40000000 + +/* DRAM - sdCfg */ + +#define BONITO_SDCFG_AROWBITS 0x00000003 +#define BONITO_SDCFG_AROWBITS_SHIFT 0 +#define BONITO_SDCFG_ACOLBITS 0x0000000c +#define BONITO_SDCFG_ACOLBITS_SHIFT 2 +#define BONITO_SDCFG_ABANKBIT 0x00000010 +#define BONITO_SDCFG_ASIDES 0x00000020 +#define BONITO_SDCFG_AABSENT 0x00000040 +#define BONITO_SDCFG_AWIDTH64 0x00000080 + +#define BONITO_SDCFG_BROWBITS 0x00000300 +#define BONITO_SDCFG_BROWBITS_SHIFT 8 +#define BONITO_SDCFG_BCOLBITS 0x00000c00 +#define BONITO_SDCFG_BCOLBITS_SHIFT 10 +#define BONITO_SDCFG_BBANKBIT 0x00001000 +#define BONITO_SDCFG_BSIDES 0x00002000 +#define BONITO_SDCFG_BABSENT 0x00004000 +#define BONITO_SDCFG_BWIDTH64 0x00008000 + +#define BONITO_SDCFG_EXTRDDATA 0x00010000 +#define BONITO_SDCFG_EXTRASCAS 0x00020000 +#define BONITO_SDCFG_EXTPRECH 0x00040000 +#define BONITO_SDCFG_EXTRASWIDTH 0x00180000 +#define BONITO_SDCFG_EXTRASWIDTH_SHIFT 19 +/* Changed by RPF 11-9-00 */ +#define BONITO_SDCFG_DRAMMODESET 0x00200000 +/* --- */ +#define BONITO_SDCFG_DRAMEXTREGS 0x00400000 +#define BONITO_SDCFG_DRAMPARITY 0x00800000 +/* Added by RPF 11-9-00 */ +#define BONITO_SDCFG_DRAMBURSTLEN 0x03000000 +#define BONITO_SDCFG_DRAMBURSTLEN_SHIFT 24 +#define BONITO_SDCFG_DRAMMODESET_DONE 0x80000000 +/* --- */ + +/* PCI Cache - pciCacheCtrl */ + +#define BONITO_PCICACHECTRL_CACHECMD 0x00000007 +#define BONITO_PCICACHECTRL_CACHECMD_SHIFT 0 +#define BONITO_PCICACHECTRL_CACHECMDLINE 0x00000018 +#define BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT 3 +#define BONITO_PCICACHECTRL_CMDEXEC 0x00000020 + +#define BONITO_IODEVCFG_BUFFBIT_CS0 0x00000001 +#define BONITO_IODEVCFG_SPEEDBIT_CS0 0x00000002 +#define BONITO_IODEVCFG_MOREABITS_CS0 0x00000004 + +#define BONITO_IODEVCFG_BUFFBIT_CS1 0x00000008 +#define BONITO_IODEVCFG_SPEEDBIT_CS1 0x00000010 +#define BONITO_IODEVCFG_MOREABITS_CS1 0x00000020 + +#define BONITO_IODEVCFG_BUFFBIT_CS2 0x00000040 +#define BONITO_IODEVCFG_SPEEDBIT_CS2 0x00000080 +#define BONITO_IODEVCFG_MOREABITS_CS2 0x00000100 + +#define BONITO_IODEVCFG_BUFFBIT_CS3 0x00000200 +#define BONITO_IODEVCFG_SPEEDBIT_CS3 0x00000400 +#define BONITO_IODEVCFG_MOREABITS_CS3 0x00000800 + +#define BONITO_IODEVCFG_BUFFBIT_IDE 0x00001000 +#define BONITO_IODEVCFG_SPEEDBIT_IDE 0x00002000 +#define BONITO_IODEVCFG_WORDSWAPBIT_IDE 0x00004000 +#define BONITO_IODEVCFG_MODEBIT_IDE 0x00008000 +#define BONITO_IODEVCFG_DMAON_IDE 0x001f0000 +#define BONITO_IODEVCFG_DMAON_IDE_SHIFT 16 +#define BONITO_IODEVCFG_DMAOFF_IDE 0x01e00000 +#define BONITO_IODEVCFG_DMAOFF_IDE_SHIFT 21 +#define BONITO_IODEVCFG_EPROMSPLIT 0x02000000 +/* Added by RPF 11-9-00 */ +#define BONITO_IODEVCFG_CPUCLOCKPERIOD 0xfc000000 +#define BONITO_IODEVCFG_CPUCLOCKPERIOD_SHIFT 26 +/* --- */ + +/* gpio */ +#define BONITO_GPIO_GPIOW 0x000003ff +#define BONITO_GPIO_GPIOW_SHIFT 0 +#define BONITO_GPIO_GPIOR 0x01ff0000 +#define BONITO_GPIO_GPIOR_SHIFT 16 +#define BONITO_GPIO_GPINR 0xfe000000 +#define BONITO_GPIO_GPINR_SHIFT 25 +#define BONITO_GPIO_IOW(N) (1<<(BONITO_GPIO_GPIOW_SHIFT+(N))) +#define BONITO_GPIO_IOR(N) (1<<(BONITO_GPIO_GPIOR_SHIFT+(N))) +#define BONITO_GPIO_INR(N) (1<<(BONITO_GPIO_GPINR_SHIFT+(N))) + +/* ICU */ +#define BONITO_ICU_MBOXES 0x0000000f +#define BONITO_ICU_MBOXES_SHIFT 0 +#define BONITO_ICU_DMARDY 0x00000010 +#define BONITO_ICU_DMAEMPTY 0x00000020 +#define BONITO_ICU_COPYRDY 0x00000040 +#define BONITO_ICU_COPYEMPTY 0x00000080 +#define BONITO_ICU_COPYERR 0x00000100 +#define BONITO_ICU_PCIIRQ 0x00000200 +#define BONITO_ICU_MASTERERR 0x00000400 +#define BONITO_ICU_SYSTEMERR 0x00000800 +#define BONITO_ICU_DRAMPERR 0x00001000 +#define BONITO_ICU_RETRYERR 0x00002000 +#define BONITO_ICU_GPIOS 0x01ff0000 +#define BONITO_ICU_GPIOS_SHIFT 16 +#define BONITO_ICU_GPINS 0x7e000000 +#define BONITO_ICU_GPINS_SHIFT 25 +#define BONITO_ICU_MBOX(N) (1<<(BONITO_ICU_MBOXES_SHIFT+(N))) +#define BONITO_ICU_GPIO(N) (1<<(BONITO_ICU_GPIOS_SHIFT+(N))) +#define BONITO_ICU_GPIN(N) (1<<(BONITO_ICU_GPINS_SHIFT+(N))) + +/* pcimap */ + +#define BONITO_PCIMAP_PCIMAP_LO0 0x0000003f +#define BONITO_PCIMAP_PCIMAP_LO0_SHIFT 0 +#define BONITO_PCIMAP_PCIMAP_LO1 0x00000fc0 +#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT 6 +#define BONITO_PCIMAP_PCIMAP_LO2 0x0003f000 +#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT 12 +#define BONITO_PCIMAP_PCIMAP_2 0x00040000 +#define BONITO_PCIMAP_WIN(WIN,ADDR) ((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) + +#define BONITO_PCIMAP_WINSIZE (1<<26) +#define BONITO_PCIMAP_WINOFFSET(ADDR) ((ADDR) & (BONITO_PCIMAP_WINSIZE - 1)) +#define BONITO_PCIMAP_WINBASE(ADDR) ((ADDR) << 26) + +/* pcimembaseCfg */ + +#define BONITO_PCIMEMBASECFG_MASK 0xf0000000 +#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK 0x0000001f +#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT 0 +#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS 0x000003e0 +#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT 5 +#define BONITO_PCIMEMBASECFG_MEMBASE0_CACHED 0x00000400 +#define BONITO_PCIMEMBASECFG_MEMBASE0_IO 0x00000800 + +#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK 0x0001f000 +#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT 12 +#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS 0x003e0000 +#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT 17 +#define BONITO_PCIMEMBASECFG_MEMBASE1_CACHED 0x00400000 +#define BONITO_PCIMEMBASECFG_MEMBASE1_IO 0x00800000 + +#define BONITO_PCIMEMBASECFG_ASHIFT 23 +#define BONITO_PCIMEMBASECFG_AMASK 0x007fffff +#define BONITO_PCIMEMBASECFGSIZE(WIN,SIZE) (((~((SIZE)-1))>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) +#define BONITO_PCIMEMBASECFGBASE(WIN,BASE) (((BASE)>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) + +#define BONITO_PCIMEMBASECFG_SIZE(WIN,CFG) (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK) + + +#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) +#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) +#define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) + +#define BONITO_PCITOPHYS(WIN,ADDR,CFG) ( \ + (((ADDR) & (~(BONITO_PCIMEMBASECFG_MASK))) & (~(BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)))) | \ + (BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG)) \ + ) + +/* PCICmd */ + +#define BONITO_PCICMD_MEMEN 0x00000002 +#define BONITO_PCICMD_MSTREN 0x00000004 + + +#endif /* _ASM_MIPS_BOARDS_BONITO64_H */ diff -Nru a/include/asm-mips/mips-boards/generic.h b/include/asm-mips/mips-boards/generic.h --- a/include/asm-mips/mips-boards/generic.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/mips-boards/generic.h Fri Jun 27 14:19:59 2003 @@ -25,14 +25,20 @@ #ifndef _MIPS_GENERIC_H #define _MIPS_GENERIC_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/byteorder.h> +#include <asm/mips-boards/bonito64.h> /* * Display register base. */ +#if defined(CONFIG_MIPS_SEAD) +#define ASCII_DISPLAY_POS_BASE (KSEG1ADDR(0x1f0005c0)) +#else #define ASCII_DISPLAY_WORD_BASE (KSEG1ADDR(0x1f000410)) #define ASCII_DISPLAY_POS_BASE (KSEG1ADDR(0x1f000418)) +#endif /* @@ -44,8 +50,28 @@ /* * Reset register. */ +#if defined(CONFIG_MIPS_SEAD) +#define SOFTRES_REG (KSEG1ADDR(0x1e800050)) +#define GORESET 0x4d +#else #define SOFTRES_REG (KSEG1ADDR(0x1f000500)) #define GORESET 0x42 +#endif + +/* + * Revision register. + */ +#define MIPS_REVISION_REG (KSEG1ADDR(0x1fc00010)) +#define MIPS_REVISION_CORID_QED_RM5261 0 +#define MIPS_REVISION_CORID_CORE_LV 1 +#define MIPS_REVISION_CORID_BONITO64 2 +#define MIPS_REVISION_CORID_CORE_20K 3 +#define MIPS_REVISION_CORID_CORE_FPGA 4 +#define MIPS_REVISION_CORID_CORE_MSC 5 + +#define MIPS_REVISION_CORID (((*(volatile u32 *)(MIPS_REVISION_REG)) >> 10) & 0x3f) + +extern unsigned int mips_revision_corid; /* @@ -66,5 +92,20 @@ *(volatile u32 *)(MIPS_GT_BASE+ofs) = data #define GT_PCI_READ(ofs, data) \ data = *(volatile u32 *)(MIPS_GT_BASE+ofs) + +/* + * Algorithmics Bonito64 system controller register base. + */ +static char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE); + +/* + * MIPS System controller PCI register base. + */ +#define MSC01_PCI_REG_BASE (KSEG1ADDR(0x1bd00000)) + +#define MSC_WRITE(reg, data) \ + *(volatile u32 *)(reg) = data +#define MSC_READ(reg, data) \ + data = *(volatile u32 *)(reg) #endif /* !(_MIPS_GENERIC_H) */ diff -Nru a/include/asm-mips/mips-boards/malta.h b/include/asm-mips/mips-boards/malta.h --- a/include/asm-mips/mips-boards/malta.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/mips-boards/malta.h Fri Jun 27 14:19:53 2003 @@ -2,8 +2,6 @@ * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. * - * ######################################################################## - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -17,23 +15,38 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * ######################################################################## - * * Defines of the Malta board specific address-MAP, registers, etc. - * */ -#ifndef _MIPS_MALTA_H -#define _MIPS_MALTA_H +#ifndef __ASM_MIPS_MALTA_H +#define __ASM_MIPS_MALTA_H #include <asm/addrspace.h> +#include <asm/gt64120/gt64120.h> #include <asm/io.h> -/* - * Malta I/O ports base address. -*/ -#define MALTA_PORT_BASE (KSEG1ADDR(0x18000000)) +/* + * Malta I/O ports base address for the Galileo GT64120 and Algorithmics + * Bonito system controllers. + */ +#define MALTA_GT_PORT_BASE get_gt_port_base(GT_PCI0IOLD_OFS) +#define MALTA_BONITO_PORT_BASE (KSEG1ADDR(0x1fd00000)) +#define MALTA_MSC_PORT_BASE get_msc_port_base(MSC01_PCI_SC2PIOBASL) + +static inline unsigned long get_gt_port_base(unsigned long reg) +{ + unsigned long addr; + GT_READ(reg, addr); + return KSEG1ADDR((addr & 0xffff) << 21); +} + +static inline unsigned long get_msc_port_base(unsigned long reg) +{ + unsigned long addr; + MSC_READ(reg, addr); + return KSEG1ADDR(addr); +} -/* +/* * Malta RTC-device indirect register access. */ #define MALTA_RTC_ADR_REG 0x70 @@ -56,4 +69,6 @@ #define SMSC_WRITE(x,a) outb(x,a) -#endif /* !(_MIPS_MALTA_H) */ +#define MALTA_JMPRS_REG (KSEG1ADDR(0x1f000210)) + +#endif /* __ASM_MIPS_MALTA_H */ diff -Nru a/include/asm-mips/mips-boards/msc01_pci.h b/include/asm-mips/mips-boards/msc01_pci.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/mips-boards/msc01_pci.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,244 @@ +/* + * mcs01_pci.h + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * PCI Register definitions for the MIPS System Controller. + */ +#ifndef MSC01_PCI_H +#define MSC01_PCI_H + +/***************************************************************************** + * Register offset addresses + ****************************************************************************/ + +#define MSC01_PCI_ID_OFS 0x0000 +#define MSC01_PCI_SC2PMBASL_OFS 0x0208 +#define MSC01_PCI_SC2PMMSKL_OFS 0x0218 +#define MSC01_PCI_SC2PMMAPL_OFS 0x0228 +#define MSC01_PCI_SC2PIOBASL_OFS 0x0248 +#define MSC01_PCI_SC2PIOMSKL_OFS 0x0258 +#define MSC01_PCI_SC2PIOMAPL_OFS 0x0268 +#define MSC01_PCI_P2SCMSKL_OFS 0x0308 +#define MSC01_PCI_P2SCMAPL_OFS 0x0318 +#define MSC01_PCI_INTCFG_OFS 0x0600 +#define MSC01_PCI_INTSTAT_OFS 0x0608 +#define MSC01_PCI_CFGADDR_OFS 0x0610 +#define MSC01_PCI_CFGDATA_OFS 0x0618 +#define MSC01_PCI_IACK_OFS 0x0620 +#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */ +#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */ +#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */ +#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */ +#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */ +#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */ +#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */ +#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */ +#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */ +#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */ +#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */ +#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */ +#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */ +#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */ +#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */ +#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */ +#define MSC01_PCI_BAR0_OFS 0x2220 +#define MSC01_PCI_CFG_OFS 0x2380 +#define MSC01_PCI_SWAP_OFS 0x2388 + + +/***************************************************************************** + * Register encodings + ****************************************************************************/ + +#define MSC01_PCI_ID_ID_SHF 16 +#define MSC01_PCI_ID_ID_MSK 0x00ff0000 +#define MSC01_PCI_ID_ID_HOSTBRIDGE 82 +#define MSC01_PCI_ID_MAR_SHF 8 +#define MSC01_PCI_ID_MAR_MSK 0x0000ff00 +#define MSC01_PCI_ID_MIR_SHF 0 +#define MSC01_PCI_ID_MIR_MSK 0x000000ff + +#define MSC01_PCI_SC2PMBASL_BAS_SHF 24 +#define MSC01_PCI_SC2PMBASL_BAS_MSK 0xff000000 + +#define MSC01_PCI_SC2PMMSKL_MSK_SHF 24 +#define MSC01_PCI_SC2PMMSKL_MSK_MSK 0xff000000 + +#define MSC01_PCI_SC2PMMAPL_MAP_SHF 24 +#define MSC01_PCI_SC2PMMAPL_MAP_MSK 0xff000000 + +#define MSC01_PCI_SC2PIOBASL_BAS_SHF 24 +#define MSC01_PCI_SC2PIOBASL_BAS_MSK 0xff000000 + +#define MSC01_PCI_SC2PIOMSKL_MSK_SHF 24 +#define MSC01_PCI_SC2PIOMSKL_MSK_MSK 0xff000000 + +#define MSC01_PCI_SC2PIOMAPL_MAP_SHF 24 +#define MSC01_PCI_SC2PIOMAPL_MAP_MSK 0xff000000 + +#define MSC01_PCI_P2SCMSKL_MSK_SHF 24 +#define MSC01_PCI_P2SCMSKL_MSK_MSK 0xff000000 + +#define MSC01_PCI_P2SCMAPL_MAP_SHF 24 +#define MSC01_PCI_P2SCMAPL_MAP_MSK 0xff000000 + +#define MSC01_PCI_INTCFG_RST_SHF 10 +#define MSC01_PCI_INTCFG_RST_MSK 0x00000400 +#define MSC01_PCI_INTCFG_RST_BIT 0x00000400 +#define MSC01_PCI_INTCFG_MWE_SHF 9 +#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200 +#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200 +#define MSC01_PCI_INTCFG_DTO_SHF 8 +#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100 +#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100 +#define MSC01_PCI_INTCFG_MA_SHF 7 +#define MSC01_PCI_INTCFG_MA_MSK 0x00000080 +#define MSC01_PCI_INTCFG_MA_BIT 0x00000080 +#define MSC01_PCI_INTCFG_TA_SHF 6 +#define MSC01_PCI_INTCFG_TA_MSK 0x00000040 +#define MSC01_PCI_INTCFG_TA_BIT 0x00000040 +#define MSC01_PCI_INTCFG_RTY_SHF 5 +#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020 +#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020 +#define MSC01_PCI_INTCFG_MWP_SHF 4 +#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010 +#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010 +#define MSC01_PCI_INTCFG_MRP_SHF 3 +#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008 +#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008 +#define MSC01_PCI_INTCFG_SWP_SHF 2 +#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004 +#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004 +#define MSC01_PCI_INTCFG_SRP_SHF 1 +#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002 +#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002 +#define MSC01_PCI_INTCFG_SE_SHF 0 +#define MSC01_PCI_INTCFG_SE_MSK 0x00000001 +#define MSC01_PCI_INTCFG_SE_BIT 0x00000001 + +#define MSC01_PCI_INTSTAT_RST_SHF 10 +#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400 +#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400 +#define MSC01_PCI_INTSTAT_MWE_SHF 9 +#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200 +#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200 +#define MSC01_PCI_INTSTAT_DTO_SHF 8 +#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100 +#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100 +#define MSC01_PCI_INTSTAT_MA_SHF 7 +#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080 +#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080 +#define MSC01_PCI_INTSTAT_TA_SHF 6 +#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040 +#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040 +#define MSC01_PCI_INTSTAT_RTY_SHF 5 +#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020 +#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020 +#define MSC01_PCI_INTSTAT_MWP_SHF 4 +#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010 +#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010 +#define MSC01_PCI_INTSTAT_MRP_SHF 3 +#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008 +#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008 +#define MSC01_PCI_INTSTAT_SWP_SHF 2 +#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004 +#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004 +#define MSC01_PCI_INTSTAT_SRP_SHF 1 +#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002 +#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002 +#define MSC01_PCI_INTSTAT_SE_SHF 0 +#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001 +#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001 + +#define MSC01_PCI_CFGADDR_BNUM_SHF 16 +#define MSC01_PCI_CFGADDR_BNUM_MSK 0x00ff0000 +#define MSC01_PCI_CFGADDR_DNUM_SHF 11 +#define MSC01_PCI_CFGADDR_DNUM_MSK 0x0000f800 +#define MSC01_PCI_CFGADDR_FNUM_SHF 8 +#define MSC01_PCI_CFGADDR_FNUM_MSK 0x00000700 +#define MSC01_PCI_CFGADDR_RNUM_SHF 2 +#define MSC01_PCI_CFGADDR_RNUM_MSK 0x000000fc + +#define MSC01_PCI_CFGDATA_DATA_SHF 0 +#define MSC01_PCI_CFGDATA_DATA_MSK 0xffffffff + +/* The defines below are ONLY valid for a MEM bar! */ +#define MSC01_PCI_BAR0_SIZE_SHF 4 +#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0 +#define MSC01_PCI_BAR0_P_SHF 3 +#define MSC01_PCI_BAR0_P_MSK 0x00000008 +#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK +#define MSC01_PCI_BAR0_D_SHF 1 +#define MSC01_PCI_BAR0_D_MSK 0x00000006 +#define MSC01_PCI_BAR0_T_SHF 0 +#define MSC01_PCI_BAR0_T_MSK 0x00000001 +#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK + + +#define MSC01_PCI_CFG_RA_SHF 17 +#define MSC01_PCI_CFG_RA_MSK 0x00020000 +#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK +#define MSC01_PCI_CFG_G_SHF 16 +#define MSC01_PCI_CFG_G_MSK 0x00010000 +#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK +#define MSC01_PCI_CFG_EN_SHF 15 +#define MSC01_PCI_CFG_EN_MSK 0x00008000 +#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK +#define MSC01_PCI_CFG_MAXRTRY_SHF 0 +#define MSC01_PCI_CFG_MAXRTRY_MSK 0x000000ff + +#define MSC01_PCI_SWAP_IO_SHF 18 +#define MSC01_PCI_SWAP_IO_MSK 0x000c0000 +#define MSC01_PCI_SWAP_MEM_SHF 16 +#define MSC01_PCI_SWAP_MEM_MSK 0x00030000 +#define MSC01_PCI_SWAP_BAR0_SHF 0 +#define MSC01_PCI_SWAP_BAR0_MSK 0x00000003 +#define MSC01_PCI_SWAP_NOSWAP 0 +#define MSC01_PCI_SWAP_BYTESWAP 1 + +/***************************************************************************** + * Registers absolute addresses + ****************************************************************************/ + +#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS) +#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS) +#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS) +#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS) +#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS) +#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS) +#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS) +#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS) +#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS) +#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS) +#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS) +#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS) +#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS) +#define MSC01_PCI_IACK (MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS) +#define MSC01_PCI_HEAD0 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS) +#define MSC01_PCI_HEAD1 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS) +#define MSC01_PCI_HEAD2 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD2_OFS) +#define MSC01_PCI_HEAD3 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD3_OFS) +#define MSC01_PCI_HEAD4 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD4_OFS) +#define MSC01_PCI_HEAD5 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD5_OFS) +#define MSC01_PCI_HEAD6 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD6_OFS) +#define MSC01_PCI_HEAD7 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD7_OFS) +#define MSC01_PCI_HEAD8 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD8_OFS) +#define MSC01_PCI_HEAD9 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD9_OFS) +#define MSC01_PCI_HEAD10 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD10_OFS) +#define MSC01_PCI_HEAD11 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD12 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD13 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD14 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_BAR0 (MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS) +#define MSC01_PCI_CFG (MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS) +#define MSC01_PCI_SWAP (MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS) + +#endif +/***************************************************************************** + * End of msc01_pci.h + *****************************************************************************/ diff -Nru a/include/asm-mips/mips-boards/sead.h b/include/asm-mips/mips-boards/sead.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/mips-boards/sead.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,36 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Defines of the SEAD board specific address-MAP, registers, etc. + * + */ +#ifndef _MIPS_SEAD_H +#define _MIPS_SEAD_H + +#include <asm/addrspace.h> + +/* + * SEAD UART register base. + */ +#define SEAD_UART0_REGS_BASE (0x1f000800) +#define SEAD_BASE_BAUD ( 3686400 / 16 ) + +#endif /* !(_MIPS_SEAD_H) */ diff -Nru a/include/asm-mips/mips-boards/seadint.h b/include/asm-mips/mips-boards/seadint.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/mips-boards/seadint.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,35 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Defines for the SEAD interrupt controller. + * + */ +#ifndef _MIPS_SEADINT_H +#define _MIPS_SEADINT_H + +/* Number of IRQ supported */ +#define SEADINT_UART0 0 +#define SEADINT_UART1 1 +#define SEADINT_END 2 + +extern void seadint_init(void); + +#endif /* !(_MIPS_SEADINT_H) */ diff -Nru a/include/asm-mips/mips32_cache.h b/include/asm-mips/mips32_cache.h --- a/include/asm-mips/mips32_cache.h Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,288 +0,0 @@ -/* - * mips32_cache.h - * - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. - * - * ######################################################################## - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * ######################################################################## - * - * Inline assembly cache operations. - * - * This file is the original r4cache.c file with modification that makes the - * cache handling more generic. - * - * FIXME: Handle split L2 caches. - * - */ -#ifndef _MIPS_R4KCACHE_H -#define _MIPS_R4KCACHE_H - -#include <asm/asm.h> -#include <asm/cacheops.h> - -extern inline void flush_icache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); -} - -extern inline void flush_dcache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); -} - -extern inline void flush_scache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_SD)); -} - -extern inline void flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -extern inline void flush_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); -} - -extern inline void invalidate_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); -} - -extern inline void invalidate_scache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_SD)); -} - -extern inline void flush_scache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_SD)); -} - -/* - * The next two are for badland addresses like signal trampolines. - */ -extern inline void protected_flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); -} - -extern inline void protected_writeback_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n" - "1:\tcache %1,(%0)\n" - "2:\t.set mips0\n\t" - ".set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - STR(PTR)"\t1b,2b\n\t" - ".previous" - : - : "r" (addr), - "i" (Hit_Writeback_D)); -} - -#define cache_unroll(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - .set mips3; \ - cache %1, (%0); \ - .set mips0; \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - - -extern inline void blast_dcache(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_D); - start += dc_lsize; - } -} - -extern inline void blast_dcache_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Hit_Writeback_Inv_D); - start += dc_lsize; - } -} - -extern inline void blast_dcache_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_D); - start += dc_lsize; - } -} - -extern inline void blast_icache(void) -{ - unsigned long start = KSEG0; - unsigned long end = (start + icache_size); - - while(start < end) { - cache_unroll(start,Index_Invalidate_I); - start += ic_lsize; - } -} - -extern inline void blast_icache_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Hit_Invalidate_I); - start += ic_lsize; - } -} - -extern inline void blast_icache_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - while(start < end) { - cache_unroll(start,Index_Invalidate_I); - start += ic_lsize; - } -} - -extern inline void blast_scache(void) -{ - unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_SD); - start += sc_lsize; - } -} - -extern inline void blast_scache_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache_unroll(start,Hit_Writeback_Inv_SD); - start += sc_lsize; - } -} - -extern inline void blast_scache_page_indexed(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache_unroll(start,Index_Writeback_Inv_SD); - start += sc_lsize; - } -} - -#endif /* !(_MIPS_R4KCACHE_H) */ diff -Nru a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h --- a/include/asm-mips/mipsregs.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/mipsregs.h Fri Jun 27 14:19:56 2003 @@ -8,10 +8,12 @@ * Modified for further R[236]000 support by Paul M. Antoine, 1996. * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2003 Maciej W. Rozycki */ #ifndef _ASM_MIPSREGS_H #define _ASM_MIPSREGS_H +#include <linux/config.h> #include <linux/linkage.h> /* @@ -26,6 +28,15 @@ #endif /* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ULCAST_ +#else +#define _ULCAST_ (unsigned long) +#endif + +/* * Coprocessor 0 register names */ #define CP0_INDEX $0 @@ -52,12 +63,15 @@ #define CP0_XCONTEXT $20 #define CP0_FRAMEMASK $21 #define CP0_DIAGNOSTIC $22 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 #define CP0_PERFORMANCE $25 #define CP0_ECC $26 #define CP0_CACHEERR $27 #define CP0_TAGLO $28 #define CP0_TAGHI $29 #define CP0_ERROREPC $30 +#define CP0_DESAVE $31 /* * R4640/R4650 cp0 register names. These registers are listed @@ -73,12 +87,18 @@ #define CP0_IWATCH $18 #define CP0_DWATCH $19 -/* +/* * Coprocessor 0 Set 1 register names */ #define CP0_S1_DERRADDR0 $26 #define CP0_S1_DERRADDR1 $27 #define CP0_S1_INTCONTROL $20 + +/* + * TX39 Series + */ +#define CP0_TX39_CACHE $7 + /* * Coprocessor 1 (FPU) register names */ @@ -108,7 +128,7 @@ * E the exception enable * S the sticky/flag bit */ -#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_ALL_X 0x0003f000 #define FPU_CSR_UNI_X 0x00020000 #define FPU_CSR_INV_X 0x00010000 #define FPU_CSR_DIV_X 0x00008000 @@ -140,176 +160,66 @@ /* * Values for PageMask register */ -#include <linux/config.h> #ifdef CONFIG_CPU_VR41XX -#define PM_1K 0x00000000 -#define PM_4K 0x00001800 -#define PM_16K 0x00007800 -#define PM_64K 0x0001f800 -#define PM_256K 0x0007f800 -#else -#define PM_4K 0x00000000 -#define PM_16K 0x00006000 -#define PM_64K 0x0001e000 -#define PM_256K 0x0007e000 -#define PM_1M 0x001fe000 -#define PM_4M 0x007fe000 -#define PM_16M 0x01ffe000 -#endif -/* - * Values used for computation of new tlb entries - */ -#define PL_4K 12 -#define PL_16K 14 -#define PL_64K 16 -#define PL_256K 18 -#define PL_1M 20 -#define PL_4M 22 -#define PL_16M 24 +/* Why doesn't stupidity hurt ... */ -/* - * Macros to access the system control coprocessor - */ -#define read_32bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) +#define PM_1K 0x00000000 +#define PM_4K 0x00001800 +#define PM_16K 0x00007800 +#define PM_64K 0x0001f800 +#define PM_256K 0x0007f800 -#define read_32bit_cp0_set1_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "cfc0\t%0,"STR(source)"\n\t" \ - ".set\tpop" \ - : "=r" (__res)); \ - __res;}) - -/* - * For now use this only with interrupts disabled! - */ -#define read_64bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmfc0\t%0,"STR(source)"\n\t" \ - ".set\tmips0" \ - : "=r" (__res)); \ - __res;}) - -#define write_32bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - "mtc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); +#else -#define write_32bit_cp0_set1_register(register,value) \ - __asm__ __volatile__( \ - "ctc0\t%0,"STR(register)"\n\t" \ - "nop" \ - : : "r" (value)); +#define PM_4K 0x00000000 +#define PM_16K 0x00006000 +#define PM_64K 0x0001e000 +#define PM_256K 0x0007e000 +#define PM_1M 0x001fe000 +#define PM_4M 0x007fe000 +#define PM_16M 0x01ffe000 +#define PM_64M 0x07ffe000 +#define PM_256M 0x1fffe000 -#define write_64bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmtc0\t%0,"STR(register)"\n\t" \ - ".set\tmips0" \ - : : "r" (value)) +#endif -/* - * This should be changed when we get a compiler that support the MIPS32 ISA. +/* + * Values used for computation of new tlb entries */ -#define read_mips32_cp0_config1() \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - ".word\t0x40018001\n\t" \ - "move\t%0,$1\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ - :"=r" (__res)); \ - __res;}) +#define PL_4K 12 +#define PL_16K 14 +#define PL_64K 16 +#define PL_256K 18 +#define PL_1M 20 +#define PL_4M 22 +#define PL_16M 24 +#define PL_64M 26 +#define PL_256M 28 /* * R4x00 interrupt enable / cause bits */ -#define IE_SW0 (1<< 8) -#define IE_SW1 (1<< 9) -#define IE_IRQ0 (1<<10) -#define IE_IRQ1 (1<<11) -#define IE_IRQ2 (1<<12) -#define IE_IRQ3 (1<<13) -#define IE_IRQ4 (1<<14) -#define IE_IRQ5 (1<<15) +#define IE_SW0 (_ULCAST_(1) << 8) +#define IE_SW1 (_ULCAST_(1) << 9) +#define IE_IRQ0 (_ULCAST_(1) << 10) +#define IE_IRQ1 (_ULCAST_(1) << 11) +#define IE_IRQ2 (_ULCAST_(1) << 12) +#define IE_IRQ3 (_ULCAST_(1) << 13) +#define IE_IRQ4 (_ULCAST_(1) << 14) +#define IE_IRQ5 (_ULCAST_(1) << 15) /* * R4x00 interrupt cause bits */ -#define C_SW0 (1<< 8) -#define C_SW1 (1<< 9) -#define C_IRQ0 (1<<10) -#define C_IRQ1 (1<<11) -#define C_IRQ2 (1<<12) -#define C_IRQ3 (1<<13) -#define C_IRQ4 (1<<14) -#define C_IRQ5 (1<<15) - -#ifndef _LANGUAGE_ASSEMBLY -/* - * Manipulate the status register. - * Mostly used to access the interrupt bits. - */ -#define __BUILD_SET_CP0(name,register) \ -extern __inline__ unsigned int \ -set_cp0_##name(unsigned int set) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res |= set; \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} \ - \ -extern __inline__ unsigned int \ -clear_cp0_##name(unsigned int clear) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~clear; \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} \ - \ -extern __inline__ unsigned int \ -change_cp0_##name(unsigned int change, unsigned int new) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~change; \ - res |= (new & change); \ - if(change) \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} - -__BUILD_SET_CP0(status,CP0_STATUS) -__BUILD_SET_CP0(cause,CP0_CAUSE) -__BUILD_SET_CP0(config,CP0_CONFIG) - -#endif /* defined (_LANGUAGE_ASSEMBLY) */ +#define C_SW0 (_ULCAST_(1) << 8) +#define C_SW1 (_ULCAST_(1) << 9) +#define C_IRQ0 (_ULCAST_(1) << 10) +#define C_IRQ1 (_ULCAST_(1) << 11) +#define C_IRQ2 (_ULCAST_(1) << 12) +#define C_IRQ3 (_ULCAST_(1) << 13) +#define C_IRQ4 (_ULCAST_(1) << 14) +#define C_IRQ5 (_ULCAST_(1) << 15) /* * Bitfields in the R4xx0 cp0 status register @@ -344,9 +254,9 @@ /* * Bits specific to the R4640/R4650 */ -#define ST0_UM (1 << 4) -#define ST0_IL (1 << 23) -#define ST0_DL (1 << 24) +#define ST0_UM (_ULCAST_(1) << 4) +#define ST0_IL (_ULCAST_(1) << 23) +#define ST0_DL (_ULCAST_(1) << 24) /* * Bitfields in the TX39 family CP0 Configuration Register 3 @@ -386,39 +296,40 @@ */ #define ST0_IM 0x0000ff00 #define STATUSB_IP0 8 -#define STATUSF_IP0 (1 << 8) +#define STATUSF_IP0 (_ULCAST_(1) << 8) #define STATUSB_IP1 9 -#define STATUSF_IP1 (1 << 9) +#define STATUSF_IP1 (_ULCAST_(1) << 9) #define STATUSB_IP2 10 -#define STATUSF_IP2 (1 << 10) +#define STATUSF_IP2 (_ULCAST_(1) << 10) #define STATUSB_IP3 11 -#define STATUSF_IP3 (1 << 11) +#define STATUSF_IP3 (_ULCAST_(1) << 11) #define STATUSB_IP4 12 -#define STATUSF_IP4 (1 << 12) +#define STATUSF_IP4 (_ULCAST_(1) << 12) #define STATUSB_IP5 13 -#define STATUSF_IP5 (1 << 13) +#define STATUSF_IP5 (_ULCAST_(1) << 13) #define STATUSB_IP6 14 -#define STATUSF_IP6 (1 << 14) +#define STATUSF_IP6 (_ULCAST_(1) << 14) #define STATUSB_IP7 15 -#define STATUSF_IP7 (1 << 15) +#define STATUSF_IP7 (_ULCAST_(1) << 15) #define STATUSB_IP8 0 -#define STATUSF_IP8 (1 << 0) +#define STATUSF_IP8 (_ULCAST_(1) << 0) #define STATUSB_IP9 1 -#define STATUSF_IP9 (1 << 1) +#define STATUSF_IP9 (_ULCAST_(1) << 1) #define STATUSB_IP10 2 -#define STATUSF_IP10 (1 << 2) +#define STATUSF_IP10 (_ULCAST_(1) << 2) #define STATUSB_IP11 3 -#define STATUSF_IP11 (1 << 3) +#define STATUSF_IP11 (_ULCAST_(1) << 3) #define STATUSB_IP12 4 -#define STATUSF_IP12 (1 << 4) +#define STATUSF_IP12 (_ULCAST_(1) << 4) #define STATUSB_IP13 5 -#define STATUSF_IP13 (1 << 5) +#define STATUSF_IP13 (_ULCAST_(1) << 5) #define STATUSB_IP14 6 -#define STATUSF_IP14 (1 << 6) +#define STATUSF_IP14 (_ULCAST_(1) << 6) #define STATUSB_IP15 7 -#define STATUSF_IP15 (1 << 7) +#define STATUSF_IP15 (_ULCAST_(1) << 7) #define ST0_CH 0x00040000 #define ST0_SR 0x00100000 +#define ST0_TS 0x00200000 #define ST0_BEV 0x00400000 #define ST0_RE 0x02000000 #define ST0_FR 0x04000000 @@ -435,35 +346,36 @@ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. */ #define CAUSEB_EXCCODE 2 -#define CAUSEF_EXCCODE (31 << 2) +#define CAUSEF_EXCCODE (_ULCAST_(31) << 2) #define CAUSEB_IP 8 -#define CAUSEF_IP (255 << 8) +#define CAUSEF_IP (_ULCAST_(255) << 8) #define CAUSEB_IP0 8 -#define CAUSEF_IP0 (1 << 8) +#define CAUSEF_IP0 (_ULCAST_(1) << 8) #define CAUSEB_IP1 9 -#define CAUSEF_IP1 (1 << 9) +#define CAUSEF_IP1 (_ULCAST_(1) << 9) #define CAUSEB_IP2 10 -#define CAUSEF_IP2 (1 << 10) +#define CAUSEF_IP2 (_ULCAST_(1) << 10) #define CAUSEB_IP3 11 -#define CAUSEF_IP3 (1 << 11) +#define CAUSEF_IP3 (_ULCAST_(1) << 11) #define CAUSEB_IP4 12 -#define CAUSEF_IP4 (1 << 12) +#define CAUSEF_IP4 (_ULCAST_(1) << 12) #define CAUSEB_IP5 13 -#define CAUSEF_IP5 (1 << 13) +#define CAUSEF_IP5 (_ULCAST_(1) << 13) #define CAUSEB_IP6 14 -#define CAUSEF_IP6 (1 << 14) +#define CAUSEF_IP6 (_ULCAST_(1) << 14) #define CAUSEB_IP7 15 -#define CAUSEF_IP7 (1 << 15) +#define CAUSEF_IP7 (_ULCAST_(1) << 15) #define CAUSEB_IV 23 -#define CAUSEF_IV (1 << 23) +#define CAUSEF_IV (_ULCAST_(1) << 23) #define CAUSEB_CE 28 -#define CAUSEF_CE (3 << 28) +#define CAUSEF_CE (_ULCAST_(3) << 28) #define CAUSEB_BD 31 -#define CAUSEF_BD (1 << 31) +#define CAUSEF_BD (_ULCAST_(1) << 31) /* - * Bits in the coprozessor 0 config register. + * Bits in the coprocessor 0 config register. */ +/* Generic bits. */ #define CONF_CM_CACHABLE_NO_WA 0 #define CONF_CM_CACHABLE_WA 1 #define CONF_CM_UNCACHED 2 @@ -473,11 +385,72 @@ #define CONF_CM_CACHABLE_CUW 6 #define CONF_CM_CACHABLE_ACCELERATED 7 #define CONF_CM_CMASK 7 -#define CONF_DB (1 << 4) -#define CONF_IB (1 << 5) -#define CONF_SC (1 << 17) -#define CONF_AC (1 << 23) -#define CONF_HALT (1 << 25) +#define CONF_BE (_ULCAST_(1) << 15) + +/* Bits common to various processors. */ +#define CONF_CU (_ULCAST_(1) << 3) +#define CONF_DB (_ULCAST_(1) << 4) +#define CONF_IB (_ULCAST_(1) << 5) +#define CONF_DC (_ULCAST_(7) << 6) +#define CONF_IC (_ULCAST_(7) << 9) +#define CONF_EB (_ULCAST_(1) << 13) +#define CONF_EM (_ULCAST_(1) << 14) +#define CONF_SM (_ULCAST_(1) << 16) +#define CONF_SC (_ULCAST_(1) << 17) +#define CONF_EW (_ULCAST_(3) << 18) +#define CONF_EP (_ULCAST_(15)<< 24) +#define CONF_EC (_ULCAST_(7) << 28) +#define CONF_CM (_ULCAST_(1) << 31) + +/* Bits specific to the R4xx0. */ +#define R4K_CONF_SW (_ULCAST_(1) << 20) +#define R4K_CONF_SS (_ULCAST_(1) << 21) +#define R4K_CONF_SB (_ULCAST_(3) << 22) + +/* Bits specific to the R5000. */ +#define R5K_CONF_SE (_ULCAST_(1) << 12) +#define R5K_CONF_SS (_ULCAST_(3) << 20) + +/* Bits specific to the R10000. */ +#define R10K_CONF_DN (_ULCAST_(3) << 3) +#define R10K_CONF_CT (_ULCAST_(1) << 5) +#define R10K_CONF_PE (_ULCAST_(1) << 6) +#define R10K_CONF_PM (_ULCAST_(3) << 7) +#define R10K_CONF_EC (_ULCAST_(15)<< 9) +#define R10K_CONF_SB (_ULCAST_(1) << 13) +#define R10K_CONF_SK (_ULCAST_(1) << 14) +#define R10K_CONF_SS (_ULCAST_(7) << 16) +#define R10K_CONF_SC (_ULCAST_(7) << 19) +#define R10K_CONF_DC (_ULCAST_(7) << 26) +#define R10K_CONF_IC (_ULCAST_(7) << 29) + +/* Bits specific to the VR41xx. */ +#define VR41_CONF_CS (_ULCAST_(1) << 12) +#define VR41_CONF_M16 (_ULCAST_(1) << 20) +#define VR41_CONF_AD (_ULCAST_(1) << 23) + +/* Bits specific to the R30xx. */ +#define R30XX_CONF_FDM (_ULCAST_(1) << 19) +#define R30XX_CONF_REV (_ULCAST_(1) << 22) +#define R30XX_CONF_AC (_ULCAST_(1) << 23) +#define R30XX_CONF_RF (_ULCAST_(1) << 24) +#define R30XX_CONF_HALT (_ULCAST_(1) << 25) +#define R30XX_CONF_FPINT (_ULCAST_(7) << 26) +#define R30XX_CONF_DBR (_ULCAST_(1) << 29) +#define R30XX_CONF_SB (_ULCAST_(1) << 30) +#define R30XX_CONF_LOCK (_ULCAST_(1) << 31) + +/* Bits specific to the TX49. */ +#define TX49_CONF_DC (_ULCAST_(1) << 16) +#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */ +#define TX49_CONF_HALT (_ULCAST_(1) << 18) +#define TX49_CONF_CWFON (_ULCAST_(1) << 27) + +/* Bits specific to the MIPS32/64 PRA. */ +#define MIPS_CONF_MT (_ULCAST_(7) << 7) +#define MIPS_CONF_AR (_ULCAST_(7) << 10) +#define MIPS_CONF_AT (_ULCAST_(3) << 13) +#define MIPS_CONF_M (_ULCAST_(1) << 31) /* * R10000 performance counter definitions. @@ -534,5 +507,395 @@ #define CEB_SUPERVISOR 4 /* Count events in supvervisor mode EXL = ERL = 0 */ #define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */ #define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ + +#ifndef __ASSEMBLY__ + +/* + * Functions to access the r10k performance counter and control registers + */ +#define read_r10k_perf_cntr(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntr(counter,val) \ + __asm__ __volatile__( \ + "mtpc\t%0, "STR(counter) \ + : : "r" (val)); + +#define read_r10k_perf_cntl(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntl(counter,val) \ + __asm__ __volatile__( \ + "mtps\t%0, "STR(counter) \ + : : "r" (val)); + +/* + * Macros to access the system control coprocessor + */ + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read_64bit_c0_register(source, sel) \ +({ unsigned long __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0, " #source "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __write_64bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%z0, " #register "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + __read_32bit_c0_register(reg, sel) : \ + __read_64bit_c0_register(reg, sel)) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_32bit_c0_register(reg, sel, val); \ + else \ + __write_64bit_c0_register(reg, sel, val); \ +} while (0) + +/* + * These versions are only needed for systems with more than 38 bits of + * physical address space running the 32-bit kernel. That's none atm :-) + */ +#define __read_64bit_c0_split(source, sel) \ +({ \ + unsigned long long val; \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source ", " #sel "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (val)); \ + local_irq_restore(flags); \ + \ + val; \ +}) + +#define __write_64bit_c0_split(source, sel, val) \ +do { \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + local_irq_restore(flags); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ +#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define read_c0_config3() __read_32bit_c0_register($16, 3) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) +#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_register($20, 1) +#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +#define read_c0_debug() __read_32bit_c0_register($23, 0) +#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) + +#define read_c0_depc() __read_ulong_c0_register($24, 0) +#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) + +#define read_c0_ecc() __read_32bit_c0_register($26, 0) +#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) + +#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) +#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) + +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) +#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +/* TLB operations. */ +static inline void tlb_probe(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); +} + +static inline void tlb_read(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); +} + +static inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} + +static inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} + +/* + * Manipulate bits in a c0 register. + */ +#define __BUILD_SET_C0(name,register) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res |= set; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~clear; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~change; \ + res |= (new & change); \ + write_c0_##name(res); \ + \ + return res; \ +} + +__BUILD_SET_C0(status,CP0_STATUS) +__BUILD_SET_C0(cause,CP0_CAUSE) +__BUILD_SET_C0(config,CP0_CONFIG) + +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_MIPSREGS_H */ diff -Nru a/include/asm-mips/mman.h b/include/asm-mips/mman.h --- a/include/asm-mips/mman.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/mman.h Fri Jun 27 14:19:54 2003 @@ -1,14 +1,12 @@ /* - * Linux/MIPS memory manager definitions - * * 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) 1995 by Ralf Baechle + * Copyright (C) 1995, 1999, 2002 by Ralf Baechle */ -#ifndef __ASM_MIPS_MMAN_H -#define __ASM_MIPS_MMAN_H +#ifndef _ASM_MMAN_H +#define _ASM_MMAN_H /* * Protections are chosen from these bits, OR'd together. The @@ -16,10 +14,12 @@ * without PROT_READ. The only guarantees are that no writing will be * allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x00 /* page can not be accessed */ +#define PROT_READ 0x01 /* page can be read */ +#define PROT_WRITE 0x02 /* page can be written */ +#define PROT_EXEC 0x04 /* page can be executed */ +/* 0x08 reserved for PROT_EXEC_NOFLUSH */ +#define PROT_SEM 0x10 /* page may be used for atomic ops */ /* * Flags for mmap @@ -42,6 +42,8 @@ #define MAP_DENYWRITE 0x2000 /* ETXTBSY */ #define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ #define MAP_LOCKED 0x8000 /* pages are locked */ +#define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x20000 /* do not block on IO */ /* * Flags for msync @@ -66,4 +68,4 @@ #define MAP_ANON MAP_ANONYMOUS #define MAP_FILE 0 -#endif /* __ASM_MIPS_MMAN_H */ +#endif /* _ASM_MMAN_H */ diff -Nru a/include/asm-mips/mmu.h b/include/asm-mips/mmu.h --- a/include/asm-mips/mmu.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/mmu.h Fri Jun 27 14:19:54 2003 @@ -1,7 +1,6 @@ -#ifndef __MMU_H -#define __MMU_H +#ifndef __ASM_MMU_H +#define __ASM_MMU_H -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; +typedef unsigned long mm_context_t[NR_CPUS]; -#endif +#endif /* __ASM_MMU_H */ diff -Nru a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h --- a/include/asm-mips/mmu_context.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/mmu_context.h Fri Jun 27 14:19:56 2003 @@ -12,14 +12,28 @@ #define _ASM_MMU_CONTEXT_H #include <linux/config.h> +#include <linux/errno.h> +#include <linux/sched.h> #include <linux/slab.h> -#include <asm/pgalloc.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> -/* Fuck. The f-word is here so you can grep for it :-) */ -extern unsigned long asid_cache; -extern pgd_t *current_pgd[]; +/* + * For the fast tlb miss handlers, we currently keep a per cpu array + * of pointers to the current pgd for each processor. Also, the proc. + * id is stuffed into the context register. This should be changed to + * use the processor id via current->processor, where current is stored + * in watchhi/lo. The context register should be used to contiguously + * map the page tables. + */ +#define TLBMISS_HANDLER_SETUP_PGD(pgd) \ + pgd_current[smp_processor_id()] = (unsigned long)(pgd) +#define TLBMISS_HANDLER_SETUP() \ + write_c0_context((unsigned long) smp_processor_id() << (23 + 3)); \ + TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) +extern unsigned long pgd_current[]; -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) #define ASID_INC 0x40 #define ASID_MASK 0xfc0 @@ -31,6 +45,10 @@ #endif +#define cpu_context(cpu, mm) ((mm)->context[cpu]) +#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) +#define asid_cache(cpu) (cpu_data[cpu].asid_cache) + static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } @@ -42,60 +60,67 @@ #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) -extern inline void -get_new_mmu_context(struct mm_struct *mm, unsigned long asid) +static inline void +get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) { + unsigned long asid = asid_cache(cpu); + if (! ((asid += ASID_INC) & ASID_MASK) ) { - flush_tlb_all(); /* start new asid cycle */ - if (!asid) /* fix version if needed */ +#ifdef CONFIG_VTAG_ICACHE + flush_icache_all(); +#endif + local_flush_tlb_all(); /* start new asid cycle */ + if (!asid) /* fix version if needed */ asid = ASID_FIRST_VERSION; } - mm->context = asid_cache = asid; + cpu_context(cpu, mm) = asid_cache(cpu) = asid; } /* * Initialize the context related info for a new mm_struct * instance. */ -extern inline int +static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { -#ifndef CONFIG_SMP - mm->context = 0; -#else - mm->context = (unsigned long)kmalloc(smp_num_cpus * - sizeof(unsigned long), GFP_KERNEL); - /* - * Init the "context" values so that a tlbpid allocation - * happens on the first switch. - */ - if (mm->context == 0) - return -ENOMEM; - memset((void *)mm->context, 0, smp_num_cpus * sizeof(unsigned long)); -#endif + int i; + + for (i = 0; i < num_online_cpus(); i++) + cpu_context(i, mm) = 0; + return 0; } -extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) { - unsigned long asid = asid_cache; + unsigned long flags; + + local_irq_save(flags); /* Check if our ASID is of an older version and thus invalid */ - if ((next->context ^ asid) & ASID_VERSION_MASK) - get_new_mmu_context(next, asid); + if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) + get_new_mmu_context(next, cpu); + + write_c0_entryhi(cpu_context(cpu, next)); + TLBMISS_HANDLER_SETUP_PGD(next->pgd); + + /* + * Mark current->active_mm as not "active" anymore. + * We don't want to mislead possible IPI tlb flush routines. + */ + clear_bit(cpu, &prev->cpu_vm_mask); + set_bit(cpu, &next->cpu_vm_mask); - current_pgd[cpu] = next->pgd; - set_entryhi(next->context); + local_irq_restore(flags); } /* * Destroy context related info for an mm_struct that is about * to be put to rest. */ -extern inline void destroy_context(struct mm_struct *mm) +static inline void destroy_context(struct mm_struct *mm) { - /* Nothing to do. */ } #define deactivate_mm(tsk,mm) do { } while (0) @@ -104,14 +129,47 @@ * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings. */ -extern inline void +static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { + unsigned long flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + /* Unconditionally get a new ASID. */ - get_new_mmu_context(next, asid_cache); + get_new_mmu_context(next, cpu); + + write_c0_entryhi(cpu_context(cpu, next)); + TLBMISS_HANDLER_SETUP_PGD(next->pgd); + + /* mark mmu ownership change */ + clear_bit(cpu, &prev->cpu_vm_mask); + set_bit(cpu, &next->cpu_vm_mask); + + local_irq_restore(flags); +} + +/* + * If mm is currently active_mm, we can't really drop it. Instead, + * we will get a new one for it. + */ +static inline void +drop_mmu_context(struct mm_struct *mm, unsigned cpu) +{ + unsigned long flags; + + local_irq_save(flags); + + if (test_bit(cpu, &mm->cpu_vm_mask)) { + get_new_mmu_context(mm, cpu); + write_c0_entryhi(cpu_asid(cpu, mm)); + } else { + /* will get a new context next time */ + cpu_context(cpu, mm) = 0; + } - current_pgd[smp_processor_id()] = next->pgd; - set_entryhi(next->context); + local_irq_restore(flags); } #endif /* _ASM_MMU_CONTEXT_H */ diff -Nru a/include/asm-mips/module.h b/include/asm-mips/module.h --- a/include/asm-mips/module.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/module.h Fri Jun 27 14:19:54 2003 @@ -1,67 +1,14 @@ -#ifndef _ASM_MIPS_MODULE_H -#define _ASM_MIPS_MODULE_H -/* - * This file contains the mips architecture specific module code. - */ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H -#include <linux/module.h> -#include <asm/uaccess.h> - -#define module_map(x) vmalloc(x) -#define module_unmap(x) vfree(x) -#define module_arch_init(x) mips_module_init(x) -#define arch_init_modules(x) mips_init_modules(x) - -/* - * This must match in size and layout the data created by - * modutils/obj/obj-mips.c - */ -struct archdata { +struct mod_arch_specific { + /* Data Bus Error exception tables */ const struct exception_table_entry *dbe_table_start; const struct exception_table_entry *dbe_table_end; }; -static inline int -mips_module_init(struct module *mod) -{ - struct archdata *archdata; - - if (!mod_member_present(mod, archdata_end)) - return 0; - - archdata = (struct archdata *)(mod->archdata_start); - if (!mod_archdata_member_present(mod, struct archdata, dbe_table_end)) - return 0; - - if (archdata->dbe_table_start > archdata->dbe_table_end || - (archdata->dbe_table_start && - !((unsigned long)archdata->dbe_table_start >= - ((unsigned long)mod + mod->size_of_struct) && - ((unsigned long)archdata->dbe_table_end < - (unsigned long)mod + mod->size))) || - (((unsigned long)archdata->dbe_table_start - - (unsigned long)archdata->dbe_table_end) % - sizeof(struct exception_table_entry))) { - printk(KERN_ERR - "module_arch_init: archdata->dbe_table_* invalid.\n"); - return 1; - } - - return 0; -} - -static inline void -mips_init_modules(struct module *mod) -{ - extern const struct exception_table_entry __start___dbe_table[]; - extern const struct exception_table_entry __stop___dbe_table[]; - static struct archdata archdata = { - dbe_table_start: __start___dbe_table, - dbe_table_end: __stop___dbe_table, - }; - - mod->archdata_start = (char *)&archdata; - mod->archdata_end = mod->archdata_start + sizeof(archdata); -} +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr -#endif /* _ASM_MIPS_MODULE_H */ +#endif /* _ASM_MODULE_H */ diff -Nru a/include/asm-mips/msgbuf.h b/include/asm-mips/msgbuf.h --- a/include/asm-mips/msgbuf.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/msgbuf.h Fri Jun 27 14:19:55 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_MSGBUF_H #define _ASM_MSGBUF_H -/* +/* * The msqid64_ds structure for alpha architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. @@ -13,15 +13,18 @@ struct msqid64_ds { struct ipc64_perm msg_perm; __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; unsigned long msg_cbytes; /* current number of bytes on queue */ unsigned long msg_qnum; /* number of messages in queue */ unsigned long msg_qbytes; /* max number of bytes on queue */ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused1; - unsigned long __unused2; + unsigned long __unused4; + unsigned long __unused5; }; #endif /* _ASM_MSGBUF_H */ diff -Nru a/include/asm-mips/mv64340.h b/include/asm-mips/mv64340.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/mv64340.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,1037 @@ +/******************************************************************************* +* mv64340.h - MV-64340 Internal registers definition file. +* +* Copyright 2002 Momentum Computer, Inc. +* Copyright 2002 GALILEO TECHNOLOGY, LTD. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +*******************************************************************************/ + +#ifndef __MV64340_H__ +#define __MV64340_H__ + +#include <asm/mv64340_dep.h> + +/****************************************/ +/* Processor Address Space */ +/****************************************/ + +/* DDR SDRAM BAR and size registers */ + +#define MV64340_CS_0_BASE_ADDR 0x008 +#define MV64340_CS_0_SIZE 0x010 +#define MV64340_CS_1_BASE_ADDR 0x208 +#define MV64340_CS_1_SIZE 0x210 +#define MV64340_CS_2_BASE_ADDR 0x018 +#define MV64340_CS_2_SIZE 0x020 +#define MV64340_CS_3_BASE_ADDR 0x218 +#define MV64340_CS_3_SIZE 0x220 + +/* Devices BAR and size registers */ + +#define MV64340_DEV_CS0_BASE_ADDR 0x028 +#define MV64340_DEV_CS0_SIZE 0x030 +#define MV64340_DEV_CS1_BASE_ADDR 0x228 +#define MV64340_DEV_CS1_SIZE 0x230 +#define MV64340_DEV_CS2_BASE_ADDR 0x248 +#define MV64340_DEV_CS2_SIZE 0x250 +#define MV64340_DEV_CS3_BASE_ADDR 0x038 +#define MV64340_DEV_CS3_SIZE 0x040 +#define MV64340_BOOTCS_BASE_ADDR 0x238 +#define MV64340_BOOTCS_SIZE 0x240 + +/* PCI 0 BAR and size registers */ + +#define MV64340_PCI_0_IO_BASE_ADDR 0x048 +#define MV64340_PCI_0_IO_SIZE 0x050 +#define MV64340_PCI_0_MEMORY0_BASE_ADDR 0x058 +#define MV64340_PCI_0_MEMORY0_SIZE 0x060 +#define MV64340_PCI_0_MEMORY1_BASE_ADDR 0x080 +#define MV64340_PCI_0_MEMORY1_SIZE 0x088 +#define MV64340_PCI_0_MEMORY2_BASE_ADDR 0x258 +#define MV64340_PCI_0_MEMORY2_SIZE 0x260 +#define MV64340_PCI_0_MEMORY3_BASE_ADDR 0x280 +#define MV64340_PCI_0_MEMORY3_SIZE 0x288 + +/* PCI 1 BAR and size registers */ +#define MV64340_PCI_1_IO_BASE_ADDR 0x090 +#define MV64340_PCI_1_IO_SIZE 0x098 +#define MV64340_PCI_1_MEMORY0_BASE_ADDR 0x0a0 +#define MV64340_PCI_1_MEMORY0_SIZE 0x0a8 +#define MV64340_PCI_1_MEMORY1_BASE_ADDR 0x0b0 +#define MV64340_PCI_1_MEMORY1_SIZE 0x0b8 +#define MV64340_PCI_1_MEMORY2_BASE_ADDR 0x2a0 +#define MV64340_PCI_1_MEMORY2_SIZE 0x2a8 +#define MV64340_PCI_1_MEMORY3_BASE_ADDR 0x2b0 +#define MV64340_PCI_1_MEMORY3_SIZE 0x2b8 + +/* SRAM base address */ +#define MV64340_INTEGRATED_SRAM_BASE_ADDR 0x268 + +/* internal registers space base address */ +#define MV64340_INTERNAL_SPACE_BASE_ADDR 0x068 + +/* Enables the CS , DEV_CS , PCI 0 and PCI 1 + windows above */ +#define MV64340_BASE_ADDR_ENABLE 0x278 + +/****************************************/ +/* PCI remap registers */ +/****************************************/ + /* PCI 0 */ +#define MV64340_PCI_0_IO_ADDR_REMAP 0x0f0 +#define MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP 0x0f8 +#define MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP 0x320 +#define MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP 0x100 +#define MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP 0x328 +#define MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP 0x2f8 +#define MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP 0x330 +#define MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP 0x300 +#define MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP 0x338 + /* PCI 1 */ +#define MV64340_PCI_1_IO_ADDR_REMAP 0x108 +#define MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP 0x110 +#define MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP 0x340 +#define MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP 0x118 +#define MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP 0x348 +#define MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP 0x310 +#define MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP 0x350 +#define MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP 0x318 +#define MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP 0x358 + +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_CONTROL 0x3b0 +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_BASE 0x3b8 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_CONTROL 0x3c0 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_BASE 0x3c8 +#define MV64340_CPU_GE_HEADERS_RETARGET_CONTROL 0x3d0 +#define MV64340_CPU_GE_HEADERS_RETARGET_BASE 0x3d8 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_CONTROL 0x3e0 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_BASE 0x3e8 + +/****************************************/ +/* CPU Control Registers */ +/****************************************/ + +#define MV64340_CPU_CONFIG 0x000 +#define MV64340_CPU_MODE 0x120 +#define MV64340_CPU_MASTER_CONTROL 0x160 +#define MV64340_CPU_CROSS_BAR_CONTROL_LOW 0x150 +#define MV64340_CPU_CROSS_BAR_CONTROL_HIGH 0x158 +#define MV64340_CPU_CROSS_BAR_TIMEOUT 0x168 + +/****************************************/ +/* SMP RegisterS */ +/****************************************/ + +#define MV64340_SMP_WHO_AM_I 0x200 +#define MV64340_SMP_CPU0_DOORBELL 0x214 +#define MV64340_SMP_CPU0_DOORBELL_CLEAR 0x21C +#define MV64340_SMP_CPU1_DOORBELL 0x224 +#define MV64340_SMP_CPU1_DOORBELL_CLEAR 0x22C +#define MV64340_SMP_CPU0_DOORBELL_MASK 0x234 +#define MV64340_SMP_CPU1_DOORBELL_MASK 0x23C +#define MV64340_SMP_SEMAPHOR0 0x244 +#define MV64340_SMP_SEMAPHOR1 0x24c +#define MV64340_SMP_SEMAPHOR2 0x254 +#define MV64340_SMP_SEMAPHOR3 0x25c +#define MV64340_SMP_SEMAPHOR4 0x264 +#define MV64340_SMP_SEMAPHOR5 0x26c +#define MV64340_SMP_SEMAPHOR6 0x274 +#define MV64340_SMP_SEMAPHOR7 0x27c + +/****************************************/ +/* CPU Sync Barrier Register */ +/****************************************/ + +#define MV64340_CPU_0_SYNC_BARRIER_TRIGGER 0x0c0 +#define MV64340_CPU_0_SYNC_BARRIER_VIRTUAL 0x0c8 +#define MV64340_CPU_1_SYNC_BARRIER_TRIGGER 0x0d0 +#define MV64340_CPU_1_SYNC_BARRIER_VIRTUAL 0x0d8 + +/****************************************/ +/* CPU Access Protect */ +/****************************************/ + +#define MV64340_CPU_PROTECT_WINDOW_0_BASE_ADDR 0x180 +#define MV64340_CPU_PROTECT_WINDOW_0_SIZE 0x188 +#define MV64340_CPU_PROTECT_WINDOW_1_BASE_ADDR 0x190 +#define MV64340_CPU_PROTECT_WINDOW_1_SIZE 0x198 +#define MV64340_CPU_PROTECT_WINDOW_2_BASE_ADDR 0x1a0 +#define MV64340_CPU_PROTECT_WINDOW_2_SIZE 0x1a8 +#define MV64340_CPU_PROTECT_WINDOW_3_BASE_ADDR 0x1b0 +#define MV64340_CPU_PROTECT_WINDOW_3_SIZE 0x1b8 + + +/****************************************/ +/* CPU Error Report */ +/****************************************/ + +#define MV64340_CPU_ERROR_ADDR_LOW 0x070 +#define MV64340_CPU_ERROR_ADDR_HIGH 0x078 +#define MV64340_CPU_ERROR_DATA_LOW 0x128 +#define MV64340_CPU_ERROR_DATA_HIGH 0x130 +#define MV64340_CPU_ERROR_PARITY 0x138 +#define MV64340_CPU_ERROR_CAUSE 0x140 +#define MV64340_CPU_ERROR_MASK 0x148 + +/****************************************/ +/* CPU Interface Debug Registers */ +/****************************************/ + +#define MV64340_PUNIT_SLAVE_DEBUG_LOW 0x360 +#define MV64340_PUNIT_SLAVE_DEBUG_HIGH 0x368 +#define MV64340_PUNIT_MASTER_DEBUG_LOW 0x370 +#define MV64340_PUNIT_MASTER_DEBUG_HIGH 0x378 +#define MV64340_PUNIT_MMASK 0x3e4 + +/****************************************/ +/* Integrated SRAM Registers */ +/****************************************/ + +#define MV64340_SRAM_CONFIG 0x380 +#define MV64340_SRAM_TEST_MODE 0X3F4 +#define MV64340_SRAM_ERROR_CAUSE 0x388 +#define MV64340_SRAM_ERROR_ADDR 0x390 +#define MV64340_SRAM_ERROR_ADDR_HIGH 0X3F8 +#define MV64340_SRAM_ERROR_DATA_LOW 0x398 +#define MV64340_SRAM_ERROR_DATA_HIGH 0x3a0 +#define MV64340_SRAM_ERROR_DATA_PARITY 0x3a8 + +/****************************************/ +/* SDRAM Configuration */ +/****************************************/ + +#define MV64340_SDRAM_CONFIG 0x1400 +#define MV64340_D_UNIT_CONTROL_LOW 0x1404 +#define MV64340_D_UNIT_CONTROL_HIGH 0x1424 +#define MV64340_SDRAM_TIMING_CONTROL_LOW 0x1408 +#define MV64340_SDRAM_TIMING_CONTROL_HIGH 0x140c +#define MV64340_SDRAM_ADDR_CONTROL 0x1410 +#define MV64340_SDRAM_OPEN_PAGES_CONTROL 0x1414 +#define MV64340_SDRAM_OPERATION 0x1418 +#define MV64340_SDRAM_MODE 0x141c +#define MV64340_EXTENDED_DRAM_MODE 0x1420 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_LOW 0x1430 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_HIGH 0x1434 +#define MV64340_SDRAM_CROSS_BAR_TIMEOUT 0x1438 +#define MV64340_SDRAM_ADDR_CTRL_PADS_CALIBRATION 0x14c0 +#define MV64340_SDRAM_DATA_PADS_CALIBRATION 0x14c4 + +/****************************************/ +/* SDRAM Error Report */ +/****************************************/ + +#define MV64340_SDRAM_ERROR_DATA_LOW 0x1444 +#define MV64340_SDRAM_ERROR_DATA_HIGH 0x1440 +#define MV64340_SDRAM_ERROR_ADDR 0x1450 +#define MV64340_SDRAM_RECEIVED_ECC 0x1448 +#define MV64340_SDRAM_CALCULATED_ECC 0x144c +#define MV64340_SDRAM_ECC_CONTROL 0x1454 +#define MV64340_SDRAM_ECC_ERROR_COUNTER 0x1458 + +/******************************************/ +/* Controlled Delay Line (CDL) Registers */ +/******************************************/ + +#define MV64340_DFCDL_CONFIG0 0x1480 +#define MV64340_DFCDL_CONFIG1 0x1484 +#define MV64340_DLL_WRITE 0x1488 +#define MV64340_DLL_READ 0x148c +#define MV64340_SRAM_ADDR 0x1490 +#define MV64340_SRAM_DATA0 0x1494 +#define MV64340_SRAM_DATA1 0x1498 +#define MV64340_SRAM_DATA2 0x149c +#define MV64340_DFCL_PROBE 0x14a0 + +/******************************************/ +/* Debug Registers */ +/******************************************/ + +#define MV64340_DUNIT_DEBUG_LOW 0x1460 +#define MV64340_DUNIT_DEBUG_HIGH 0x1464 +#define MV64340_DUNIT_MMASK 0X1b40 + +/****************************************/ +/* Device Parameters */ +/****************************************/ + +#define MV64340_DEVICE_BANK0_PARAMETERS 0x45c +#define MV64340_DEVICE_BANK1_PARAMETERS 0x460 +#define MV64340_DEVICE_BANK2_PARAMETERS 0x464 +#define MV64340_DEVICE_BANK3_PARAMETERS 0x468 +#define MV64340_DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define MV64340_DEVICE_INTERFACE_CONTROL 0x4c0 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_TIMEOUT 0x4c4 + +/****************************************/ +/* Device interrupt registers */ +/****************************************/ + +#define MV64340_DEVICE_INTERRUPT_CAUSE 0x4d0 +#define MV64340_DEVICE_INTERRUPT_MASK 0x4d4 +#define MV64340_DEVICE_ERROR_ADDR 0x4d8 +#define MV64340_DEVICE_ERROR_DATA 0x4dc +#define MV64340_DEVICE_ERROR_PARITY 0x4e0 + +/****************************************/ +/* Device debug registers */ +/****************************************/ + +#define MV64340_DEVICE_DEBUG_LOW 0x4e4 +#define MV64340_DEVICE_DEBUG_HIGH 0x4e8 +#define MV64340_RUNIT_MMASK 0x4f0 + +/****************************************/ +/* PCI Slave Address Decoding registers */ +/****************************************/ + +#define MV64340_PCI_0_CS_0_BANK_SIZE 0xc08 +#define MV64340_PCI_1_CS_0_BANK_SIZE 0xc88 +#define MV64340_PCI_0_CS_1_BANK_SIZE 0xd08 +#define MV64340_PCI_1_CS_1_BANK_SIZE 0xd88 +#define MV64340_PCI_0_CS_2_BANK_SIZE 0xc0c +#define MV64340_PCI_1_CS_2_BANK_SIZE 0xc8c +#define MV64340_PCI_0_CS_3_BANK_SIZE 0xd0c +#define MV64340_PCI_1_CS_3_BANK_SIZE 0xd8c +#define MV64340_PCI_0_DEVCS_0_BANK_SIZE 0xc10 +#define MV64340_PCI_1_DEVCS_0_BANK_SIZE 0xc90 +#define MV64340_PCI_0_DEVCS_1_BANK_SIZE 0xd10 +#define MV64340_PCI_1_DEVCS_1_BANK_SIZE 0xd90 +#define MV64340_PCI_0_DEVCS_2_BANK_SIZE 0xd18 +#define MV64340_PCI_1_DEVCS_2_BANK_SIZE 0xd98 +#define MV64340_PCI_0_DEVCS_3_BANK_SIZE 0xc14 +#define MV64340_PCI_1_DEVCS_3_BANK_SIZE 0xc94 +#define MV64340_PCI_0_DEVCS_BOOT_BANK_SIZE 0xd14 +#define MV64340_PCI_1_DEVCS_BOOT_BANK_SIZE 0xd94 +#define MV64340_PCI_0_P2P_MEM0_BAR_SIZE 0xd1c +#define MV64340_PCI_1_P2P_MEM0_BAR_SIZE 0xd9c +#define MV64340_PCI_0_P2P_MEM1_BAR_SIZE 0xd20 +#define MV64340_PCI_1_P2P_MEM1_BAR_SIZE 0xda0 +#define MV64340_PCI_0_P2P_I_O_BAR_SIZE 0xd24 +#define MV64340_PCI_1_P2P_I_O_BAR_SIZE 0xda4 +#define MV64340_PCI_0_CPU_BAR_SIZE 0xd28 +#define MV64340_PCI_1_CPU_BAR_SIZE 0xda8 +#define MV64340_PCI_0_INTERNAL_SRAM_BAR_SIZE 0xe00 +#define MV64340_PCI_1_INTERNAL_SRAM_BAR_SIZE 0xe80 +#define MV64340_PCI_0_EXPANSION_ROM_BAR_SIZE 0xd2c +#define MV64340_PCI_1_EXPANSION_ROM_BAR_SIZE 0xd9c +#define MV64340_PCI_0_BASE_ADDR_REG_ENABLE 0xc3c +#define MV64340_PCI_1_BASE_ADDR_REG_ENABLE 0xcbc +#define MV64340_PCI_0_CS_0_BASE_ADDR_REMAP 0xc48 +#define MV64340_PCI_1_CS_0_BASE_ADDR_REMAP 0xcc8 +#define MV64340_PCI_0_CS_1_BASE_ADDR_REMAP 0xd48 +#define MV64340_PCI_1_CS_1_BASE_ADDR_REMAP 0xdc8 +#define MV64340_PCI_0_CS_2_BASE_ADDR_REMAP 0xc4c +#define MV64340_PCI_1_CS_2_BASE_ADDR_REMAP 0xccc +#define MV64340_PCI_0_CS_3_BASE_ADDR_REMAP 0xd4c +#define MV64340_PCI_1_CS_3_BASE_ADDR_REMAP 0xdcc +#define MV64340_PCI_0_CS_0_BASE_HIGH_ADDR_REMAP 0xF04 +#define MV64340_PCI_1_CS_0_BASE_HIGH_ADDR_REMAP 0xF84 +#define MV64340_PCI_0_CS_1_BASE_HIGH_ADDR_REMAP 0xF08 +#define MV64340_PCI_1_CS_1_BASE_HIGH_ADDR_REMAP 0xF88 +#define MV64340_PCI_0_CS_2_BASE_HIGH_ADDR_REMAP 0xF0C +#define MV64340_PCI_1_CS_2_BASE_HIGH_ADDR_REMAP 0xF8C +#define MV64340_PCI_0_CS_3_BASE_HIGH_ADDR_REMAP 0xF10 +#define MV64340_PCI_1_CS_3_BASE_HIGH_ADDR_REMAP 0xF90 +#define MV64340_PCI_0_DEVCS_0_BASE_ADDR_REMAP 0xc50 +#define MV64340_PCI_1_DEVCS_0_BASE_ADDR_REMAP 0xcd0 +#define MV64340_PCI_0_DEVCS_1_BASE_ADDR_REMAP 0xd50 +#define MV64340_PCI_1_DEVCS_1_BASE_ADDR_REMAP 0xdd0 +#define MV64340_PCI_0_DEVCS_2_BASE_ADDR_REMAP 0xd58 +#define MV64340_PCI_1_DEVCS_2_BASE_ADDR_REMAP 0xdd8 +#define MV64340_PCI_0_DEVCS_3_BASE_ADDR_REMAP 0xc54 +#define MV64340_PCI_1_DEVCS_3_BASE_ADDR_REMAP 0xcd4 +#define MV64340_PCI_0_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xd54 +#define MV64340_PCI_1_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xdd4 +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xd5c +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xddc +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xd60 +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xde0 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xd64 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xde4 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xd68 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xde8 +#define MV64340_PCI_0_P2P_I_O_BASE_ADDR_REMAP 0xd6c +#define MV64340_PCI_1_P2P_I_O_BASE_ADDR_REMAP 0xdec +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_LOW 0xd70 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_LOW 0xdf0 +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_HIGH 0xd74 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_HIGH 0xdf4 +#define MV64340_PCI_0_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf00 +#define MV64340_PCI_1_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf80 +#define MV64340_PCI_0_EXPANSION_ROM_BASE_ADDR_REMAP 0xf38 +#define MV64340_PCI_1_EXPANSION_ROM_BASE_ADDR_REMAP 0xfb8 +#define MV64340_PCI_0_ADDR_DECODE_CONTROL 0xd3c +#define MV64340_PCI_1_ADDR_DECODE_CONTROL 0xdbc +#define MV64340_PCI_0_HEADERS_RETARGET_CONTROL 0xF40 +#define MV64340_PCI_1_HEADERS_RETARGET_CONTROL 0xFc0 +#define MV64340_PCI_0_HEADERS_RETARGET_BASE 0xF44 +#define MV64340_PCI_1_HEADERS_RETARGET_BASE 0xFc4 +#define MV64340_PCI_0_HEADERS_RETARGET_HIGH 0xF48 +#define MV64340_PCI_1_HEADERS_RETARGET_HIGH 0xFc8 + +/***********************************/ +/* PCI Control Register Map */ +/***********************************/ + +#define MV64340_PCI_0_DLL_STATUS_AND_COMMAND 0x1d20 +#define MV64340_PCI_1_DLL_STATUS_AND_COMMAND 0x1da0 +#define MV64340_PCI_0_MPP_PADS_DRIVE_CONTROL 0x1d1C +#define MV64340_PCI_1_MPP_PADS_DRIVE_CONTROL 0x1d9C +#define MV64340_PCI_0_COMMAND 0xc00 +#define MV64340_PCI_1_COMMAND 0xc80 +#define MV64340_PCI_0_MODE 0xd00 +#define MV64340_PCI_1_MODE 0xd80 +#define MV64340_PCI_0_RETRY 0xc04 +#define MV64340_PCI_1_RETRY 0xc84 +#define MV64340_PCI_0_READ_BUFFER_DISCARD_TIMER 0xd04 +#define MV64340_PCI_1_READ_BUFFER_DISCARD_TIMER 0xd84 +#define MV64340_PCI_0_MSI_TRIGGER_TIMER 0xc38 +#define MV64340_PCI_1_MSI_TRIGGER_TIMER 0xcb8 +#define MV64340_PCI_0_ARBITER_CONTROL 0x1d00 +#define MV64340_PCI_1_ARBITER_CONTROL 0x1d80 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_LOW 0x1d08 +#define MV64340_PCI_1_CROSS_BAR_CONTROL_LOW 0x1d88 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_HIGH 0x1d0c +#define MV64340_PCI_1_CROSS_BAR_CONTROL_HIGH 0x1d8c +#define MV64340_PCI_0_CROSS_BAR_TIMEOUT 0x1d04 +#define MV64340_PCI_1_CROSS_BAR_TIMEOUT 0x1d84 +#define MV64340_PCI_0_SYNC_BARRIER_TRIGGER_REG 0x1D18 +#define MV64340_PCI_1_SYNC_BARRIER_TRIGGER_REG 0x1D98 +#define MV64340_PCI_0_SYNC_BARRIER_VIRTUAL_REG 0x1d10 +#define MV64340_PCI_1_SYNC_BARRIER_VIRTUAL_REG 0x1d90 +#define MV64340_PCI_0_P2P_CONFIG 0x1d14 +#define MV64340_PCI_1_P2P_CONFIG 0x1d94 + +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_0 0x1e08 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_LOW 0x1e10 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_1 0x1e18 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_LOW 0x1e20 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_2 0x1e28 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_LOW 0x1e30 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_3 0x1e38 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_LOW 0x1e40 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_4 0x1e48 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_LOW 0x1e50 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_5 0x1e58 + +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_0 0x1e88 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_LOW 0x1e90 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_1 0x1e98 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_LOW 0x1ea0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_2 0x1ea8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_LOW 0x1eb0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_3 0x1eb8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_LOW 0x1ec0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_4 0x1ec8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_LOW 0x1ed0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_5 0x1ed8 + +/****************************************/ +/* PCI Configuration Access Registers */ +/****************************************/ + +#define MV64340_PCI_0_CONFIG_ADDR 0xcf8 +#define MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG 0xcfc +#define MV64340_PCI_1_CONFIG_ADDR 0xc78 +#define MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG 0xc7c +#define MV64340_PCI_0_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xc34 +#define MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xcb4 + +/****************************************/ +/* PCI Error Report Registers */ +/****************************************/ + +#define MV64340_PCI_0_SERR_MASK 0xc28 +#define MV64340_PCI_1_SERR_MASK 0xca8 +#define MV64340_PCI_0_ERROR_ADDR_LOW 0x1d40 +#define MV64340_PCI_1_ERROR_ADDR_LOW 0x1dc0 +#define MV64340_PCI_0_ERROR_ADDR_HIGH 0x1d44 +#define MV64340_PCI_1_ERROR_ADDR_HIGH 0x1dc4 +#define MV64340_PCI_0_ERROR_ATTRIBUTE 0x1d48 +#define MV64340_PCI_1_ERROR_ATTRIBUTE 0x1dc8 +#define MV64340_PCI_0_ERROR_COMMAND 0x1d50 +#define MV64340_PCI_1_ERROR_COMMAND 0x1dd0 +#define MV64340_PCI_0_ERROR_CAUSE 0x1d58 +#define MV64340_PCI_1_ERROR_CAUSE 0x1dd8 +#define MV64340_PCI_0_ERROR_MASK 0x1d5c +#define MV64340_PCI_1_ERROR_MASK 0x1ddc + +/****************************************/ +/* PCI Debug Registers */ +/****************************************/ + +#define MV64340_PCI_0_MMASK 0X1D24 +#define MV64340_PCI_1_MMASK 0X1DA4 + +/*********************************************/ +/* PCI Configuration, Function 0, Registers */ +/*********************************************/ + +#define MV64340_PCI_DEVICE_AND_VENDOR_ID 0x000 +#define MV64340_PCI_STATUS_AND_COMMAND 0x004 +#define MV64340_PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define MV64340_PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C + +#define MV64340_PCI_SCS_0_BASE_ADDR_LOW 0x010 +#define MV64340_PCI_SCS_0_BASE_ADDR_HIGH 0x014 +#define MV64340_PCI_SCS_1_BASE_ADDR_LOW 0x018 +#define MV64340_PCI_SCS_1_BASE_ADDR_HIGH 0x01C +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_LOW 0x020 +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_HIGH 0x024 +#define MV64340_PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02c +#define MV64340_PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030 +#define MV64340_PCI_CAPABILTY_LIST_POINTER 0x034 +#define MV64340_PCI_INTERRUPT_PIN_AND_LINE 0x03C + /* capability list */ +#define MV64340_PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define MV64340_PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define MV64340_PCI_VPD_ADDR 0x048 +#define MV64340_PCI_VPD_DATA 0x04c +#define MV64340_PCI_MSI_MESSAGE_CONTROL 0x050 +#define MV64340_PCI_MSI_MESSAGE_ADDR 0x054 +#define MV64340_PCI_MSI_MESSAGE_UPPER_ADDR 0x058 +#define MV64340_PCI_MSI_MESSAGE_DATA 0x05c +#define MV64340_PCI_X_COMMAND 0x060 +#define MV64340_PCI_X_STATUS 0x064 +#define MV64340_PCI_COMPACT_PCI_HOT_SWAP 0x068 + +/***********************************************/ +/* PCI Configuration, Function 1, Registers */ +/***********************************************/ + +#define MV64340_PCI_SCS_2_BASE_ADDR_LOW 0x110 +#define MV64340_PCI_SCS_2_BASE_ADDR_HIGH 0x114 +#define MV64340_PCI_SCS_3_BASE_ADDR_LOW 0x118 +#define MV64340_PCI_SCS_3_BASE_ADDR_HIGH 0x11c +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_LOW 0x120 +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_HIGH 0x124 + +/***********************************************/ +/* PCI Configuration, Function 2, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_0_BASE_ADDR_LOW 0x210 +#define MV64340_PCI_DEVCS_0_BASE_ADDR_HIGH 0x214 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_LOW 0x218 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_HIGH 0x21c +#define MV64340_PCI_DEVCS_2_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_DEVCS_2_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 3, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_3_BASE_ADDR_LOW 0x310 +#define MV64340_PCI_DEVCS_3_BASE_ADDR_HIGH 0x314 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_LOW 0x318 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_HIGH 0x31c +#define MV64340_PCI_CPU_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_CPU_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 4, Registers */ +/***********************************************/ + +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_LOW 0x410 +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_HIGH 0x414 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_LOW 0x418 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_HIGH 0x41c +#define MV64340_PCI_P2P_I_O_BASE_ADDR 0x420 +#define MV64340_PCI_INTERNAL_REGS_I_O_MAPPED_BASE_ADDR 0x424 + +/****************************************/ +/* Messaging Unit Registers (I20) */ +/****************************************/ + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_0_SIDE 0x010 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_0_SIDE 0x014 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_0_SIDE 0x018 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_0_SIDE 0x01C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_0_SIDE 0x020 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x024 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x028 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_0_SIDE 0x02C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x030 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x034 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x040 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x044 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_0_SIDE 0x050 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_0_SIDE 0x054 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x060 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x064 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x068 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x06C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x070 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x074 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x0F8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x0FC + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_1_SIDE 0x090 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_1_SIDE 0x094 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_1_SIDE 0x098 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_1_SIDE 0x09C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_1_SIDE 0x0A0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0A4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0A8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_1_SIDE 0x0AC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0B0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0B4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C4 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_1_SIDE 0x0D0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_1_SIDE 0x0D4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0E0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0E4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x0E8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x0EC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0F0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0F4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x078 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x07C + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C10 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C14 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C18 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C1C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU0_SIDE 0x1C20 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C24 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C28 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU0_SIDE 0x1C2C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C30 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C34 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C40 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C44 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU0_SIDE 0x1C50 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU0_SIDE 0x1C54 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C60 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C64 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1C68 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1C6C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C70 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C74 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1CF8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1CFC +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C90 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C94 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C98 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C9C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU1_SIDE 0x1CA0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CA4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CA8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU1_SIDE 0x1CAC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CB0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CB4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC4 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU1_SIDE 0x1CD0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU1_SIDE 0x1CD4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CE0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CE4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1CE8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1CEC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CF0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CF4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1C78 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1C7C + +/****************************************/ +/* Ethernet Unit Registers */ +/****************************************/ + +#define MV64340_ETH_PHY_ADDR_REG 0x2000 +#define MV64340_ETH_SMI_REG 0x2004 +#define MV64340_ETH_UNIT_DEFAULT_ADDR_REG 0x2008 +#define MV64340_ETH_UNIT_DEFAULTID_REG 0x200c +#define MV64340_ETH_UNIT_INTERRUPT_CAUSE_REG 0x2080 +#define MV64340_ETH_UNIT_INTERRUPT_MASK_REG 0x2084 +#define MV64340_ETH_UNIT_INTERNAL_USE_REG 0x24fc +#define MV64340_ETH_UNIT_ERROR_ADDR_REG 0x2094 +#define MV64340_ETH_BAR_0 0x2200 +#define MV64340_ETH_BAR_1 0x2208 +#define MV64340_ETH_BAR_2 0x2210 +#define MV64340_ETH_BAR_3 0x2218 +#define MV64340_ETH_BAR_4 0x2220 +#define MV64340_ETH_BAR_5 0x2228 +#define MV64340_ETH_SIZE_REG_0 0x2204 +#define MV64340_ETH_SIZE_REG_1 0x220c +#define MV64340_ETH_SIZE_REG_2 0x2214 +#define MV64340_ETH_SIZE_REG_3 0x221c +#define MV64340_ETH_SIZE_REG_4 0x2224 +#define MV64340_ETH_SIZE_REG_5 0x222c +#define MV64340_ETH_HEADERS_RETARGET_BASE_REG 0x2230 +#define MV64340_ETH_HEADERS_RETARGET_CONTROL_REG 0x2234 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_0 0x2280 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_1 0x2284 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_2 0x2288 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_3 0x228c +#define MV64340_ETH_BASE_ADDR_ENABLE_REG 0x2290 +#define MV64340_ETH_ACCESS_PROTECTION_REG(port) (0x2294 + (port<<2)) +#define MV64340_ETH_MIB_COUNTERS_BASE(port) (0x3000 + (port<<7)) +#define MV64340_ETH_PORT_CONFIG_REG(port) (0x2400 + (port<<10)) +#define MV64340_ETH_PORT_CONFIG_EXTEND_REG(port) (0x2404 + (port<<10)) +#define MV64340_ETH_MII_SERIAL_PARAMETRS_REG(port) (0x2408 + (port<<10)) +#define MV64340_ETH_GMII_SERIAL_PARAMETRS_REG(port) (0x240c + (port<<10)) +#define MV64340_ETH_VLAN_ETHERTYPE_REG(port) (0x2410 + (port<<10)) +#define MV64340_ETH_MAC_ADDR_LOW(port) (0x2414 + (port<<10)) +#define MV64340_ETH_MAC_ADDR_HIGH(port) (0x2418 + (port<<10)) +#define MV64340_ETH_SDMA_CONFIG_REG(port) (0x241c + (port<<10)) +#define MV64340_ETH_DSCP_0(port) (0x2420 + (port<<10)) +#define MV64340_ETH_DSCP_1(port) (0x2424 + (port<<10)) +#define MV64340_ETH_DSCP_2(port) (0x2428 + (port<<10)) +#define MV64340_ETH_DSCP_3(port) (0x242c + (port<<10)) +#define MV64340_ETH_DSCP_4(port) (0x2430 + (port<<10)) +#define MV64340_ETH_DSCP_5(port) (0x2434 + (port<<10)) +#define MV64340_ETH_DSCP_6(port) (0x2438 + (port<<10)) +#define MV64340_ETH_PORT_SERIAL_CONTROL_REG(port) (0x243c + (port<<10)) +#define MV64340_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port) (0x2440 + (port<<10)) +#define MV64340_ETH_PORT_STATUS_REG(port) (0x2444 + (port<<10)) +#define MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port) (0x2448 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_FIXED_PRIORITY(port) (0x244c + (port<<10)) +#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port) (0x2450 + (port<<10)) +#define MV64340_ETH_MAXIMUM_TRANSMIT_UNIT(port) (0x2458 + (port<<10)) +#define MV64340_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port) (0x245c + (port<<10)) +#define MV64340_ETH_INTERRUPT_CAUSE_REG(port) (0x2460 + (port<<10)) +#define MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port) (0x2464 + (port<<10)) +#define MV64340_ETH_INTERRUPT_MASK_REG(port) (0x2468 + (port<<10)) +#define MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port) (0x246c + (port<<10)) +#define MV64340_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + (port<<10)) +#define MV64340_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + (port<<10)) +#define MV64340_ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (0x247c + (port<<10)) +#define MV64340_ETH_RX_DISCARDED_FRAMES_COUNTER(port) (0x2484 + (port<<10) +#define MV64340_ETH_PORT_DEBUG_0_REG(port) (0x248c + (port<<10)) +#define MV64340_ETH_PORT_DEBUG_1_REG(port) (0x2490 + (port<<10)) +#define MV64340_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + (port<<10)) +#define MV64340_ETH_INTERNAL_USE_REG(port) (0x24fc + (port<<10)) +#define MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port) (0x2680 + (port<<10)) +#define MV64340_ETH_CURRENT_SERVED_TX_DESC_PTR(port) (0x2684 + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port) (0x260c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port) (0x261c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port) (0x262c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port) (0x263c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port) (0x264c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port) (0x265c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port) (0x266c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port) (0x267c + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port) (0x26c0 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port) (0x26c4 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port) (0x26c8 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port) (0x26cc + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port) (0x26d0 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port) (0x26d4 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port) (0x26d8 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port) (0x26dc + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port) (0x2700 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port) (0x2710 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port) (0x2720 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port) (0x2730 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port) (0x2740 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port) (0x2750 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port) (0x2760 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port) (0x2770 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port) (0x2704 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port) (0x2714 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port) (0x2724 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port) (0x2734 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port) (0x2744 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port) (0x2754 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port) (0x2764 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port) (0x2774 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_ARBITER_CONFIG(port) (0x2708 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_ARBITER_CONFIG(port) (0x2718 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_ARBITER_CONFIG(port) (0x2728 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_ARBITER_CONFIG(port) (0x2738 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_ARBITER_CONFIG(port) (0x2748 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_ARBITER_CONFIG(port) (0x2758 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_ARBITER_CONFIG(port) (0x2768 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_ARBITER_CONFIG(port) (0x2778 + (port<<10)) +#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port) (0x2780 + (port<<10)) +#define MV64340_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port) (0x3400 + (port<<10)) +#define MV64340_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port) (0x3500 + (port<<10)) +#define MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE(port) (0x3600 + (port<<10)) + +/*******************************************/ +/* CUNIT Registers */ +/*******************************************/ + + /* Address Decoding Register Map */ + +#define MV64340_CUNIT_BASE_ADDR_REG0 0xf200 +#define MV64340_CUNIT_BASE_ADDR_REG1 0xf208 +#define MV64340_CUNIT_BASE_ADDR_REG2 0xf210 +#define MV64340_CUNIT_BASE_ADDR_REG3 0xf218 +#define MV64340_CUNIT_SIZE0 0xf204 +#define MV64340_CUNIT_SIZE1 0xf20c +#define MV64340_CUNIT_SIZE2 0xf214 +#define MV64340_CUNIT_SIZE3 0xf21c +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG0 0xf240 +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG1 0xf244 +#define MV64340_CUNIT_BASE_ADDR_ENABLE_REG 0xf250 +#define MV64340_MPSC0_ACCESS_PROTECTION_REG 0xf254 +#define MV64340_MPSC1_ACCESS_PROTECTION_REG 0xf258 +#define MV64340_CUNIT_INTERNAL_SPACE_BASE_ADDR_REG 0xf25C + + /* Error Report Registers */ + +#define MV64340_CUNIT_INTERRUPT_CAUSE_REG 0xf310 +#define MV64340_CUNIT_INTERRUPT_MASK_REG 0xf314 +#define MV64340_CUNIT_ERROR_ADDR 0xf318 + + /* Cunit Control Registers */ + +#define MV64340_CUNIT_ARBITER_CONTROL_REG 0xf300 +#define MV64340_CUNIT_CONFIG_REG 0xb40c +#define MV64340_CUNIT_CRROSBAR_TIMEOUT_REG 0xf304 + + /* Cunit Debug Registers */ + +#define MV64340_CUNIT_DEBUG_LOW 0xf340 +#define MV64340_CUNIT_DEBUG_HIGH 0xf344 +#define MV64340_CUNIT_MMASK 0xf380 + + /* MPSCs Clocks Routing Registers */ + +#define MV64340_MPSC_ROUTING_REG 0xb400 +#define MV64340_MPSC_RX_CLOCK_ROUTING_REG 0xb404 +#define MV64340_MPSC_TX_CLOCK_ROUTING_REG 0xb408 + + /* MPSCs Interrupts Registers */ + +#define MV64340_MPSC_CAUSE_REG(port) (0xb804 + (port<<3)) +#define MV64340_MPSC_MASK_REG(port) (0xb884 + (port<<3)) + +#define MV64340_MPSC_MAIN_CONFIG_LOW(port) (0x8000 + (port<<12)) +#define MV64340_MPSC_MAIN_CONFIG_HIGH(port) (0x8004 + (port<<12)) +#define MV64340_MPSC_PROTOCOL_CONFIG(port) (0x8008 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG1(port) (0x800c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG2(port) (0x8010 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG3(port) (0x8014 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG4(port) (0x8018 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG5(port) (0x801c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG6(port) (0x8020 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG7(port) (0x8024 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG8(port) (0x8028 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG9(port) (0x802c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG10(port) (0x8030 + (port<<12)) + + /* MPSC0 Registers */ + + +/***************************************/ +/* SDMA Registers */ +/***************************************/ + +#define MV64340_SDMA_CONFIG_REG(channel) (0x4000 + (channel<<13)) +#define MV64340_SDMA_COMMAND_REG(channel) (0x4008 + (channel<<13)) +#define MV64340_SDMA_CURRENT_RX_DESCRIPTOR_POINTER(channel) (0x4810 + (channel<<13)) +#define MV64340_SDMA_CURRENT_TX_DESCRIPTOR_POINTER(channel) (0x4c10 + (channel<<13)) +#define MV64340_SDMA_FIRST_TX_DESCRIPTOR_POINTER(channel) (0x4c14 + (channel<<13)) + +#define MV64340_SDMA_CAUSE_REG 0xb800 +#define MV64340_SDMA_MASK_REG 0xb880 + +/* BRG Interrupts */ + +#define MV64340_BRG_CONFIG_REG(brg) (0xb200 + (brg<<3)) +#define MV64340_BRG_BAUDE_TUNING_REG(brg) (0xb208 + (brg<<3)) +#define MV64340_BRG_CAUSE_REG 0xb834 +#define MV64340_BRG_MASK_REG 0xb8b4 + +/****************************************/ +/* DMA Channel Control */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_CONTROL 0x840 +#define MV64340_DMA_CHANNEL0_CONTROL_HIGH 0x880 +#define MV64340_DMA_CHANNEL1_CONTROL 0x844 +#define MV64340_DMA_CHANNEL1_CONTROL_HIGH 0x884 +#define MV64340_DMA_CHANNEL2_CONTROL 0x848 +#define MV64340_DMA_CHANNEL2_CONTROL_HIGH 0x888 +#define MV64340_DMA_CHANNEL3_CONTROL 0x84C +#define MV64340_DMA_CHANNEL3_CONTROL_HIGH 0x88C + + +/****************************************/ +/* IDMA Registers */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_BYTE_COUNT 0x800 +#define MV64340_DMA_CHANNEL1_BYTE_COUNT 0x804 +#define MV64340_DMA_CHANNEL2_BYTE_COUNT 0x808 +#define MV64340_DMA_CHANNEL3_BYTE_COUNT 0x80C +#define MV64340_DMA_CHANNEL0_SOURCE_ADDR 0x810 +#define MV64340_DMA_CHANNEL1_SOURCE_ADDR 0x814 +#define MV64340_DMA_CHANNEL2_SOURCE_ADDR 0x818 +#define MV64340_DMA_CHANNEL3_SOURCE_ADDR 0x81c +#define MV64340_DMA_CHANNEL0_DESTINATION_ADDR 0x820 +#define MV64340_DMA_CHANNEL1_DESTINATION_ADDR 0x824 +#define MV64340_DMA_CHANNEL2_DESTINATION_ADDR 0x828 +#define MV64340_DMA_CHANNEL3_DESTINATION_ADDR 0x82C +#define MV64340_DMA_CHANNEL0_NEXT_DESCRIPTOR_POINTER 0x830 +#define MV64340_DMA_CHANNEL1_NEXT_DESCRIPTOR_POINTER 0x834 +#define MV64340_DMA_CHANNEL2_NEXT_DESCRIPTOR_POINTER 0x838 +#define MV64340_DMA_CHANNEL3_NEXT_DESCRIPTOR_POINTER 0x83C +#define MV64340_DMA_CHANNEL0_CURRENT_DESCRIPTOR_POINTER 0x870 +#define MV64340_DMA_CHANNEL1_CURRENT_DESCRIPTOR_POINTER 0x874 +#define MV64340_DMA_CHANNEL2_CURRENT_DESCRIPTOR_POINTER 0x878 +#define MV64340_DMA_CHANNEL3_CURRENT_DESCRIPTOR_POINTER 0x87C + + /* IDMA Address Decoding Base Address Registers */ + +#define MV64340_DMA_BASE_ADDR_REG0 0xa00 +#define MV64340_DMA_BASE_ADDR_REG1 0xa08 +#define MV64340_DMA_BASE_ADDR_REG2 0xa10 +#define MV64340_DMA_BASE_ADDR_REG3 0xa18 +#define MV64340_DMA_BASE_ADDR_REG4 0xa20 +#define MV64340_DMA_BASE_ADDR_REG5 0xa28 +#define MV64340_DMA_BASE_ADDR_REG6 0xa30 +#define MV64340_DMA_BASE_ADDR_REG7 0xa38 + + /* IDMA Address Decoding Size Address Register */ + +#define MV64340_DMA_SIZE_REG0 0xa04 +#define MV64340_DMA_SIZE_REG1 0xa0c +#define MV64340_DMA_SIZE_REG2 0xa14 +#define MV64340_DMA_SIZE_REG3 0xa1c +#define MV64340_DMA_SIZE_REG4 0xa24 +#define MV64340_DMA_SIZE_REG5 0xa2c +#define MV64340_DMA_SIZE_REG6 0xa34 +#define MV64340_DMA_SIZE_REG7 0xa3C + + /* IDMA Address Decoding High Address Remap and Access + Protection Registers */ + +#define MV64340_DMA_HIGH_ADDR_REMAP_REG0 0xa60 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG1 0xa64 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG2 0xa68 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG3 0xa6C +#define MV64340_DMA_BASE_ADDR_ENABLE_REG 0xa80 +#define MV64340_DMA_CHANNEL0_ACCESS_PROTECTION_REG 0xa70 +#define MV64340_DMA_CHANNEL1_ACCESS_PROTECTION_REG 0xa74 +#define MV64340_DMA_CHANNEL2_ACCESS_PROTECTION_REG 0xa78 +#define MV64340_DMA_CHANNEL3_ACCESS_PROTECTION_REG 0xa7c +#define MV64340_DMA_ARBITER_CONTROL 0x860 +#define MV64340_DMA_CROSS_BAR_TIMEOUT 0x8d0 + + /* IDMA Headers Retarget Registers */ + +#define MV64340_DMA_HEADERS_RETARGET_CONTROL 0xa84 +#define MV64340_DMA_HEADERS_RETARGET_BASE 0xa88 + + /* IDMA Interrupt Register */ + +#define MV64340_DMA_INTERRUPT_CAUSE_REG 0x8c0 +#define MV64340_DMA_INTERRUPT_CAUSE_MASK 0x8c4 +#define MV64340_DMA_ERROR_ADDR 0x8c8 +#define MV64340_DMA_ERROR_SELECT 0x8cc + + /* IDMA Debug Register ( for internal use ) */ + +#define MV64340_DMA_DEBUG_LOW 0x8e0 +#define MV64340_DMA_DEBUG_HIGH 0x8e4 +#define MV64340_DMA_SPARE 0xA8C + +/****************************************/ +/* Timer_Counter */ +/****************************************/ + +#define MV64340_TIMER_COUNTER0 0x850 +#define MV64340_TIMER_COUNTER1 0x854 +#define MV64340_TIMER_COUNTER2 0x858 +#define MV64340_TIMER_COUNTER3 0x85C +#define MV64340_TIMER_COUNTER_0_3_CONTROL 0x864 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c + +/****************************************/ +/* Watchdog registers */ +/****************************************/ + +#define MV64340_WATCHDOG_CONFIG_REG 0xb410 +#define MV64340_WATCHDOG_VALUE_REG 0xb414 + +/****************************************/ +/* I2C Registers */ +/****************************************/ + +#define MV64340_I2C_SLAVE_ADDR 0xc000 +#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 +#define MV64340_I2C_DATA 0xc004 +#define MV64340_I2C_CONTROL 0xc008 +#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C +#define MV64340_I2C_SOFT_RESET 0xc01c + +/****************************************/ +/* GPP Interface Registers */ +/****************************************/ + +#define MV64340_GPP_IO_CONTROL 0xf100 +#define MV64340_GPP_LEVEL_CONTROL 0xf110 +#define MV64340_GPP_VALUE 0xf104 +#define MV64340_GPP_INTERRUPT_CAUSE 0xf108 +#define MV64340_GPP_INTERRUPT_MASK0 0xf10c +#define MV64340_GPP_INTERRUPT_MASK1 0xf114 +#define MV64340_GPP_VALUE_SET 0xf118 +#define MV64340_GPP_VALUE_CLEAR 0xf11c + +/****************************************/ +/* Interrupt Controller Registers */ +/****************************************/ + +/****************************************/ +/* Interrupts */ +/****************************************/ + +#define MV64340_MAIN_INTERRUPT_CAUSE_LOW 0x004 +#define MV64340_MAIN_INTERRUPT_CAUSE_HIGH 0x00c +#define MV64340_CPU_INTERRUPT0_MASK_LOW 0x014 +#define MV64340_CPU_INTERRUPT0_MASK_HIGH 0x01c +#define MV64340_CPU_INTERRUPT0_SELECT_CAUSE 0x024 +#define MV64340_CPU_INTERRUPT1_MASK_LOW 0x034 +#define MV64340_CPU_INTERRUPT1_MASK_HIGH 0x03c +#define MV64340_CPU_INTERRUPT1_SELECT_CAUSE 0x044 +#define MV64340_INTERRUPT0_MASK_0_LOW 0x054 +#define MV64340_INTERRUPT0_MASK_0_HIGH 0x05c +#define MV64340_INTERRUPT0_SELECT_CAUSE 0x064 +#define MV64340_INTERRUPT1_MASK_0_LOW 0x074 +#define MV64340_INTERRUPT1_MASK_0_HIGH 0x07c +#define MV64340_INTERRUPT1_SELECT_CAUSE 0x084 + +/****************************************/ +/* MPP Interface Registers */ +/****************************************/ + +#define MV64340_MPP_CONTROL0 0xf000 +#define MV64340_MPP_CONTROL1 0xf004 +#define MV64340_MPP_CONTROL2 0xf008 +#define MV64340_MPP_CONTROL3 0xf00c + +/****************************************/ +/* Serial Initialization registers */ +/****************************************/ + +#define MV64340_SERIAL_INIT_LAST_DATA 0xf324 +#define MV64340_SERIAL_INIT_CONTROL 0xf328 +#define MV64340_SERIAL_INIT_STATUS 0xf32c + +#endif diff -Nru a/include/asm-mips/mv64340_dep.h b/include/asm-mips/mv64340_dep.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/mv64340_dep.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,51 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * include/asm-mips/mv64340-dep.h + * Board-dependent definitions for MV-64340 chip. + * + * 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 __MV64340_DEP_H__ +#define __MV64340_DEP_H__ + +#include <asm/addrspace.h> /* for KSEG1ADDR() */ +#include <asm/byteorder.h> /* for cpu_to_le32() */ + +extern unsigned long mv64340_base; + +#define MV64340_BASE (mv64340_base) + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ + +#define MV_WRITE(ofs, data) \ + *(volatile u32 *)(MV64340_BASE+(ofs)) = cpu_to_le32(data) +#define MV_READ(ofs, data) \ + *(data) = le32_to_cpu(*(volatile u32 *)(MV64340_BASE+(ofs))) +#define MV_READ_DATA(ofs) \ + le32_to_cpu(*(volatile u32 *)(MV64340_BASE+(ofs))) + +#define MV_WRITE_16(ofs, data) \ + *(volatile u16 *)(MV64340_BASE+(ofs)) = cpu_to_le16(data) +#define MV_READ_16(ofs, data) \ + *(data) = le16_to_cpu(*(volatile u16 *)(MV64340_BASE+(ofs))) + +#define MV_WRITE_8(ofs, data) \ + *(volatile u8 *)(MV64340_BASE+(ofs)) = data +#define MV_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(MV64340_BASE+(ofs)) + +#define MV_SET_REG_BITS(ofs,bits) \ + (*((volatile u32 *)(MV64340_BASE+(ofs)))) |= ((u32)cpu_to_le32(bits)) +#define MV_RESET_REG_BITS(ofs,bits) \ + (*((volatile u32 *)(MV64340_BASE+(ofs)))) &= ~((u32)cpu_to_le32(bits)) + +#endif diff -Nru a/include/asm-mips/namei.h b/include/asm-mips/namei.h --- a/include/asm-mips/namei.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/namei.h Fri Jun 27 14:19:56 2003 @@ -2,11 +2,9 @@ * linux/include/asm-mips/namei.h * * Included from linux/fs/namei.c - * - * $Id: namei.h,v 1.6 1999/01/04 16:09:23 ralf Exp $ */ -#ifndef __ASM_MIPS_NAMEI_H -#define __ASM_MIPS_NAMEI_H +#ifndef __ASM_NAMEI_H +#define __ASM_NAMEI_H #include <linux/config.h> @@ -28,4 +26,4 @@ #endif /* !defined(CONFIG_BINFMT_IRIX) */ -#endif /* __ASM_MIPS_NAMEI_H */ +#endif /* __ASM_NAMEI_H */ diff -Nru a/include/asm-mips/ng1.h b/include/asm-mips/ng1.h --- a/include/asm-mips/ng1.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips/ng1.h Fri Jun 27 14:20:04 2003 @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * 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. diff -Nru a/include/asm-mips/ng1hw.h b/include/asm-mips/ng1hw.h --- a/include/asm-mips/ng1hw.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/ng1hw.h Fri Jun 27 14:19:59 2003 @@ -1,12 +1,9 @@ -/* $Id: ng1hw.h,v 1.4 1999/08/04 06:01:51 ulfc Exp $ - * +/* * ng1hw.h: Tweaks the newport.h structures and definitions to be compatible * with IRIX. Quite ugly, but it works. * * Copyright (C) 1999 Ulf Carlsson (ulfc@thepuffingroup.com) - * */ - #ifndef _SGI_NG1HW_H #define _SGI_NG1HW_H @@ -77,7 +74,7 @@ #define DM0_XYOFFSET NPORT_DMODE0_XYOFF #define DM0_CICLAMP NPORT_DMODE0_CLAMP #define DM0_ENDPTFILTER NPORT_DMODE0_ENDPF -#define DM0_YSTRIDE NPORT_DMODE0_YSTR +#define DM0_YSTRIDE NPORT_DMODE0_YSTR #define DM1_PLANES_SHIFT 0 /* The rest of the DM1 planes defines are in newport.h */ @@ -119,7 +116,7 @@ #define DM1_SF_SHIFT 19 #define DM1_SF_MASK NPORT_DMODE1_SFMASK -#define DM1_SF NPORT_DMODE1_SFMASK +#define DM1_SF NPORT_DMODE1_SFMASK #define DM1_SF_ZERO NPORT_DMODE1_SF0 #define DM1_SF_ONE NPORT_DMODE1_SF1 #define DM1_SF_DC NPORT_DMODE1_SFDC @@ -128,8 +125,8 @@ #define DM1_SF_MSA NPORT_DMODE1_SFMSA #define DM1_DF_SHIFT 22 /* dfactor(2:0) */ -#define DM1_DF_MASK NPORT_DMODE1_DFMASK -#define DM1_DF NPORT_DMODE1_DFMASK +#define DM1_DF_MASK NPORT_DMODE1_DFMASK +#define DM1_DF NPORT_DMODE1_DFMASK #define DM1_DF_ZERO NPORT_DMODE1_DF0 #define DM1_DF_ONE NPORT_DMODE1_DF1 #define DM1_DF_SC NPORT_DMODE1_DFSC @@ -177,23 +174,23 @@ #define VRINT NPORT_STAT_VRINT #define VIDEOINT NPORT_STAT_VIDINT #define GFIFO_LEVEL_SHIFT 7 -#define GFIFO_LEVEL_MASK NPORT_STAT_GLMSK +#define GFIFO_LEVEL_MASK NPORT_STAT_GLMSK #define BFIFO_LEVEL_SHIFT 13 -#define BFIFO_LEVEL_MASK NPORT_STAT_BLMSK +#define BFIFO_LEVEL_MASK NPORT_STAT_BLMSK #define BFIFO_INT NPORT_STAT_BFIRQ #define GFIFO_INT NPORT_STAT_GFIRQ -#define GIO32MODE NPORT_CFG_G32MD +#define GIO32MODE NPORT_CFG_G32MD #define BUSWIDTH NPORT_CFG_BWIDTH -#define EXTREGXCVR NPORT_CFG_ERCVR +#define EXTREGXCVR NPORT_CFG_ERCVR #define BFIFODEPTH_SHIFT 3 #define BFIFODEPTH_MASK NPORT_CFG_BDMSK #define BFIFOABOVEINT NPORT_CFG_BFAINT #define GFIFODEPTH_SHIFT 8 -#define GFIFODEPTH_MASK NPORT_CFG_GDMSK +#define GFIFODEPTH_MASK NPORT_CFG_GDMSK #define GFIFOABOVEINT NPORT_CFG_GFAINT #define TIMEOUT_SHIFT 14 -#define TIMEOUT_MASK NPORT_CFG_TOMSK +#define TIMEOUT_MASK NPORT_CFG_TOMSK #define VREFRESH_SHIFT 17 #define VREFRESH_MASK NPORT_CFG_VRMSK #define FB_TYPE NPORT_CFG_FBTYP diff -Nru a/include/asm-mips/nile4.h b/include/asm-mips/nile4.h --- a/include/asm-mips/nile4.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/nile4.h Fri Jun 27 14:19:52 2003 @@ -7,10 +7,10 @@ * This file is based on the following documentation: * * NEC Vrc 5074 System Controller Data Sheet, June 1998 - * - * $Id: nile4.h,v 1.1 2000/01/26 00:07:45 ralf Exp $ */ +#ifndef _ASM_NILE4_H +#define _ASM_NILE4_H #define NILE4_BASE 0xbfa00000 #define NILE4_SIZE 0x00200000 /* 2 MB */ @@ -293,8 +293,8 @@ extern void nile4_map_irq(int nile4_irq, int cpu_irq); extern void nile4_map_irq_all(int cpu_irq); -extern void nile4_enable_irq(int nile4_irq); -extern void nile4_disable_irq(int nile4_irq); +extern void nile4_enable_irq(unsigned int nile4_irq); +extern void nile4_disable_irq(unsigned int nile4_irq); extern void nile4_disable_irq_all(void); extern u16 nile4_get_irq_stat(int cpu_irq); extern void nile4_enable_irq_output(int cpu_irq); @@ -305,4 +305,6 @@ extern void nile4_clear_irq_mask(u32 mask); extern u8 nile4_i8259_iack(void); extern void nile4_dump_irq_status(void); /* Debug */ + +#endif diff -Nru a/include/asm-mips/paccess.h b/include/asm-mips/paccess.h --- a/include/asm-mips/paccess.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/paccess.h Fri Jun 27 14:19:55 2003 @@ -1,5 +1,4 @@ -/* $Id: paccess.h,v 1.1 2000/04/07 12:55:57 raiko Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -16,6 +15,9 @@ #include <linux/errno.h> +extern asmlinkage void handle_ibe(void); +extern asmlinkage void handle_dbe(void); + #define put_dbe(x,ptr) __put_dbe((x),(ptr),sizeof(*(ptr))) #define get_dbe(x,ptr) __get_dbe((x),(ptr),sizeof(*(ptr))) @@ -94,5 +96,7 @@ :"r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT)); }) extern void __put_dbe_unknown(void); + +extern unsigned long search_dbe_table(unsigned long addr); #endif /* _ASM_PACCESS_H */ diff -Nru a/include/asm-mips/page.h b/include/asm-mips/page.h --- a/include/asm-mips/page.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/page.h Fri Jun 27 14:19:55 2003 @@ -1,5 +1,4 @@ -/* $Id: page.h,v 1.9 2000/02/24 00:13:19 ralf Exp $ - * +/* * Definitions for page handling * * This file is subject to the terms and conditions of the GNU General Public @@ -8,8 +7,10 @@ * * Copyright (C) 1994 - 1999 by Ralf Baechle */ -#ifndef __ASM_PAGE_H -#define __ASM_PAGE_H +#ifndef _ASM_PAGE_H +#define _ASM_PAGE_H + +#include <linux/config.h> /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 @@ -18,27 +19,52 @@ #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ extern void (*_clear_page)(void * page); extern void (*_copy_page)(void * to, void * from); -#define clear_page(page) _clear_page(page) -#define copy_page(to, from) _copy_page(to, from) +#define clear_page(addr) _clear_page((void *)(addr)) +#define copy_page(to, from) _copy_page((void *)(to), (void *)(from)) + +extern unsigned long shm_align_mask; + +static inline unsigned long pages_do_alias(unsigned long addr1, + unsigned long addr2) +{ + return (addr1 ^ addr2) & shm_align_mask; +} + +struct page; + +static inline void clear_user_page(void *addr, unsigned long vaddr, + struct page *page) +{ + extern void (*flush_data_cache_page)(unsigned long addr); -#define clear_user_page(addr, vaddr, page) \ - do { clear_page(addr); \ - flush_dcache_page(page); \ - } while (0) -#define copy_user_page(to, from, vaddr, page) \ - do { copy_page(to, from); \ - flush_dcache_page(page); \ - } while (0) + clear_page(addr); + if (pages_do_alias((unsigned long) addr, vaddr)) + flush_data_cache_page((unsigned long)addr); +} + +static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *to) +{ + extern void (*flush_data_cache_page)(unsigned long addr); + + copy_page(vto, vfrom); + if (pages_do_alias((unsigned long)vto, vaddr)) + flush_data_cache_page((unsigned long)vto); +} /* * These are used to make use of C type-checking.. */ +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef struct { unsigned long long pte; } pte_t; +#else typedef struct { unsigned long pte; } pte_t; +#endif typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; @@ -48,8 +74,10 @@ #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) +#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t))) + #define __pte(x) ((pte_t) { (x) } ) -#define __pme(x) ((pme_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) @@ -67,24 +95,40 @@ return order; } -#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) /* * This handles the memory map. * We handle pages at KSEG0 for kernels with 32 bit address space. */ -#define PAGE_OFFSET 0x80000000UL -#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) -#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) -#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) +#define PAGE_OFFSET 0x80000000UL +#define UNCAC_BASE 0xa0000000UL + +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) + +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#define pfn_to_page(pfn) (mem_map + (pfn)) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) + +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE) +#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET) + +/* + * Memory above this physical address will be considered highmem. + */ +#define HIGHMEM_START 0x20000000UL + #endif /* defined (__KERNEL__) */ -#endif /* __ASM_PAGE_H */ +#endif /* _ASM_PAGE_H */ diff -Nru a/include/asm-mips/param.h b/include/asm-mips/param.h --- a/include/asm-mips/param.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/param.h Fri Jun 27 14:19:54 2003 @@ -1,15 +1,16 @@ +/* + * 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 1994 - 2000, 2002 Ralf Baechle (ralf@gnu.org) + * Copyright 2000 Silicon Graphics, Inc. + */ #ifndef _ASM_PARAM_H #define _ASM_PARAM_H -#ifndef HZ - #ifdef __KERNEL__ -/* Safeguard against user stupidity */ -#ifdef _SYS_PARAM_H -#error Do not include <asm/param.h> with __KERNEL__ defined! -#endif - #include <linux/config.h> #ifdef CONFIG_DECSTATION @@ -19,38 +20,16 @@ */ # define LOG_2_HZ 7 # define HZ (1 << LOG_2_HZ) - /* - * Ye olde division-by-multiplication trick. - * This works only if 100 / HZ <= 1 - */ -# define QUOTIENT ((1UL << (32 - LOG_2_HZ)) * 100) -# define hz_to_std(a) \ - ({ unsigned int __res; \ - unsigned long __lo; \ - __asm__("multu\t%2,%3\n\t" \ - :"=h" (__res), "=l" (__lo) \ - :"r" (a),"r" (QUOTIENT)); \ - (__typeof__(a)) __res;}) - -#else /* Not a DECstation */ - -/* This is the internal value of HZ, that is the rate at which the jiffies - counter is increasing. This value is independent from the external value - and can be changed in order to suit the hardware and application - requirements. */ -# define HZ 100 -# define hz_to_std(a) (a) - -#endif /* Not a DECstation */ - -#else /* defined(__KERNEL__) */ +#else +# define HZ 1000 /* Internal kernel timer frequency */ +#endif +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif -/* This is the external value of HZ as seen by user programs. Don't change - unless you know what you're doing - changing breaks binary compatibility. */ +#ifndef HZ #define HZ 100 - -#endif /* defined(__KERNEL__) */ -#endif /* defined(HZ) */ +#endif #define EXEC_PAGESIZE 4096 @@ -63,9 +42,5 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#ifdef __KERNEL__ -# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ -#endif #endif /* _ASM_PARAM_H */ diff -Nru a/include/asm-mips/parport.h b/include/asm-mips/parport.h --- a/include/asm-mips/parport.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/parport.h Fri Jun 27 14:19:52 2003 @@ -1,5 +1,4 @@ -/* $Id$ - * +/* * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk> * * This file should only be included by drivers/parport/parport_pc.c. diff -Nru a/include/asm-mips/pb1000.h b/include/asm-mips/pb1000.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/pb1000.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,172 @@ +/* + * Alchemy Semi PB1000 Referrence Board + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#ifndef __ASM_PB1000_H +#define __ASM_PB1000_H + +/* PCMCIA PB1000 specific defines */ +#define PCMCIA_MAX_SOCK 1 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) + +#define PB1000_PCR 0xBE000000 + #define PCR_SLOT_0_VPP0 (1<<0) + #define PCR_SLOT_0_VPP1 (1<<1) + #define PCR_SLOT_0_VCC0 (1<<2) + #define PCR_SLOT_0_VCC1 (1<<3) + #define PCR_SLOT_0_RST (1<<4) + + #define PCR_SLOT_1_VPP0 (1<<8) + #define PCR_SLOT_1_VPP1 (1<<9) + #define PCR_SLOT_1_VCC0 (1<<10) + #define PCR_SLOT_1_VCC1 (1<<11) + #define PCR_SLOT_1_RST (1<<12) + +#define PB1000_MDR 0xBE000004 + #define MDR_PI (1<<5) /* pcmcia int latch */ + #define MDR_EPI (1<<14) /* enable pcmcia int */ + #define MDR_CPI (1<<15) /* clear pcmcia int */ + +#define PB1000_ACR1 0xBE000008 + #define ACR1_SLOT_0_CD1 (1<<0) /* card detect 1 */ + #define ACR1_SLOT_0_CD2 (1<<1) /* card detect 2 */ + #define ACR1_SLOT_0_READY (1<<2) /* ready */ + #define ACR1_SLOT_0_STATUS (1<<3) /* status change */ + #define ACR1_SLOT_0_VS1 (1<<4) /* voltage sense 1 */ + #define ACR1_SLOT_0_VS2 (1<<5) /* voltage sense 2 */ + #define ACR1_SLOT_0_INPACK (1<<6) /* inpack pin status */ + #define ACR1_SLOT_1_CD1 (1<<8) /* card detect 1 */ + #define ACR1_SLOT_1_CD2 (1<<9) /* card detect 2 */ + #define ACR1_SLOT_1_READY (1<<10) /* ready */ + #define ACR1_SLOT_1_STATUS (1<<11) /* status change */ + #define ACR1_SLOT_1_VS1 (1<<12) /* voltage sense 1 */ + #define ACR1_SLOT_1_VS2 (1<<13) /* voltage sense 2 */ + #define ACR1_SLOT_1_INPACK (1<<14) /* inpack pin status */ + +#define CPLD_AUX0 0xBE00000C +#define CPLD_AUX1 0xBE000010 +#define CPLD_AUX2 0xBE000014 + +/* Voltage levels */ + +/* VPPEN1 - VPPEN0 */ +#define VPP_GND ((0<<1) | (0<<0)) +#define VPP_5V ((1<<1) | (0<<0)) +#define VPP_3V ((0<<1) | (1<<0)) +#define VPP_12V ((0<<1) | (1<<0)) +#define VPP_HIZ ((1<<1) | (1<<0)) + +/* VCCEN1 - VCCEN0 */ +#define VCC_3V ((0<<1) | (1<<0)) +#define VCC_5V ((1<<1) | (0<<0)) +#define VCC_HIZ ((0<<1) | (0<<0)) + +/* VPP/VCC */ +#define SET_VCC_VPP(VCC, VPP, SLOT)\ + ((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8)) + + +/* PCI PB1000 specific defines */ +/* The reason these defines are here instead of au1000.h is because + * the Au1000 does not have a PCI bus controller so the PCI implementation + * on the some of the older Pb1000 boards was very board specific. + */ +#define PCI_CONFIG_BASE 0xBA020000 /* the only external slot */ + +#define SDRAM_DEVID 0xBA010000 +#define SDRAM_CMD 0xBA010004 +#define SDRAM_CLASS 0xBA010008 +#define SDRAM_MISC 0xBA01000C +#define SDRAM_MBAR 0xBA010010 + +#define PCI_IO_DATA_PORT 0xBA800000 + +#define PCI_IO_ADDR 0xBE00001C +#define PCI_INT_ACK 0xBBC00000 +#define PCI_IO_READ 0xBBC00020 +#define PCI_IO_WRITE 0xBBC00030 + +#define PCI_BRIDGE_CONFIG 0xBE000018 + +#define PCI_IO_START 0x10000000 +#define PCI_IO_END 0x1000ffff +#define PCI_MEM_START 0x18000000 +#define PCI_MEM_END 0x18ffffff + +#define PCI_FIRST_DEVFN 0 +#define PCI_LAST_DEVFN 1 + +static inline u8 au_pci_io_readb(u32 addr) +{ + writel(addr, PCI_IO_ADDR); + writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG); + return (readl(PCI_IO_DATA_PORT) & 0xff); +} + +static inline u16 au_pci_io_readw(u32 addr) +{ + writel(addr, PCI_IO_ADDR); + writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG); + return (readl(PCI_IO_DATA_PORT) & 0xffff); +} + +static inline u32 au_pci_io_readl(u32 addr) +{ + writel(addr, PCI_IO_ADDR); + writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff), PCI_BRIDGE_CONFIG); + return readl(PCI_IO_DATA_PORT); +} + +static inline void au_pci_io_writeb(u8 val, u32 addr) +{ + writel(addr, PCI_IO_ADDR); + writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<12), PCI_BRIDGE_CONFIG); + writel(val, PCI_IO_DATA_PORT); +} + +static inline void au_pci_io_writew(u16 val, u32 addr) +{ + writel(addr, PCI_IO_ADDR); + writel((readl(PCI_BRIDGE_CONFIG) & 0xffffcfff) | (1<<13), PCI_BRIDGE_CONFIG); + writel(val, PCI_IO_DATA_PORT); +} + +static inline void au_pci_io_writel(u32 val, u32 addr) +{ + writel(addr, PCI_IO_ADDR); + writel(readl(PCI_BRIDGE_CONFIG) & 0xffffcfff, PCI_BRIDGE_CONFIG); + writel(val, PCI_IO_DATA_PORT); +} + +static inline void set_sdram_extbyte(void) +{ + writel(readl(PCI_BRIDGE_CONFIG) & 0xffffff00, PCI_BRIDGE_CONFIG); +} + +static inline void set_slot_extbyte(void) +{ + writel((readl(PCI_BRIDGE_CONFIG) & 0xffffbf00) | 0x18, PCI_BRIDGE_CONFIG); +} +#endif /* __ASM_PB1000_H */ diff -Nru a/include/asm-mips/pb1100.h b/include/asm-mips/pb1100.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/pb1100.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,85 @@ +/* + * Alchemy Semi PB1100 Referrence Board + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#ifndef __ASM_PB1100_H +#define __ASM_PB1100_H + +#define PB1100_IDENT 0xAE000000 +#define BOARD_STATUS_REG 0xAE000004 + #define PB1100_ROM_SEL (1<<15) + #define PB1100_ROM_SIZ (1<<14) + #define PB1100_SWAP_BOOT (1<<13) + #define PB1100_FLASH_WP (1<<12) + #define PB1100_ROM_H_STS (1<<11) + #define PB1100_ROM_L_STS (1<<10) + #define PB1100_FLASH_H_STS (1<<9) + #define PB1100_FLASH_L_STS (1<<8) + #define PB1100_SRAM_SIZ (1<<7) + #define PB1100_TSC_BUSY (1<<6) + #define PB1100_PCMCIA_VS_MASK (3<<4) + #define PB1100_RS232_CD (1<<3) + #define PB1100_RS232_CTS (1<<2) + #define PB1100_RS232_DSR (1<<1) + #define PB1100_RS232_RI (1<<0) + +#define PB1100_IRDA_RS232 0xAE00000C + #define PB1100_IRDA_FULL (0<<14) /* full power */ + #define PB1100_IRDA_SHUTDOWN (1<<14) + #define PB1100_IRDA_TT (2<<14) /* 2/3 power */ + #define PB1100_IRDA_OT (3<<14) /* 1/3 power */ + #define PB1100_IRDA_FIR (1<<13) + +#define PCMCIA_BOARD_REG 0xAE000010 + #define PB1100_SD_WP1_RO (1<<15) /* read only */ + #define PB1100_SD_WP0_RO (1<<14) /* read only */ + #define PB1100_SD_PWR1 (1<<11) /* applies power to SD1 */ + #define PB1100_SD_PWR0 (1<<10) /* applies power to SD0 */ + #define PB1100_SEL_SD_CONN1 (1<<9) + #define PB1100_SEL_SD_CONN0 (1<<8) + #define PC_DEASSERT_RST (1<<7) + #define PC_DRV_EN (1<<4) + +#define PB1100_G_CONTROL 0xAE000014 /* graphics control */ + +#define PB1100_RST_VDDI 0xAE00001C + #define PB1100_SOFT_RESET (1<<15) /* clear to reset the board */ + #define PB1100_VDDI_MASK (0x1F) + +#define PB1100_LEDS 0xAE000018 + +/* 11:8 is 4 discreet LEDs. Clearing a bit illuminates the LED. + * 7:0 is the LED Display's decimal points. + */ +#define PB1100_HEX_LED 0xAE000018 + +/* PCMCIA PB1100 specific defines */ +#define PCMCIA_MAX_SOCK 0 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) + +/* VPP/VCC */ +#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0)) + +#endif /* __ASM_PB1100_H */ diff -Nru a/include/asm-mips/pb1500.h b/include/asm-mips/pb1500.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/pb1500.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,51 @@ +/* + * Alchemy Semi PB1500 Referrence Board + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * + */ +#ifndef __ASM_PB1500_H +#define __ASM_PB1500_H + + +#define IDENT_BOARD_REG 0xAE000000 +#define BOARD_STATUS_REG 0xAE000004 +#define PCI_BOARD_REG 0xAE000010 +#define PCMCIA_BOARD_REG 0xAE000010 + #define PC_DEASSERT_RST 0x80 + #define PC_DRV_EN 0x10 +#define PB1500_G_CONTROL 0xAE000014 +#define PB1500_RST_VDDI 0xAE00001C +#define PB1500_LEDS 0xAE000018 + +#define PB1500_HEX_LED 0xAF000004 +#define PB1500_HEX_LED_BLANK 0xAF000008 + +/* PCMCIA PB1500 specific defines */ +#define PCMCIA_MAX_SOCK 0 +#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1) + +/* VPP/VCC */ +#define SET_VCC_VPP(VCC, VPP) (((VCC)<<2) | ((VPP)<<0)) + +#endif /* __ASM_PB1500_H */ diff -Nru a/include/asm-mips/pci.h b/include/asm-mips/pci.h --- a/include/asm-mips/pci.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/pci.h Fri Jun 27 14:19:59 2003 @@ -7,6 +7,7 @@ #define _ASM_PCI_H #include <linux/config.h> +#include <linux/mm.h> #ifdef __KERNEL__ @@ -23,12 +24,12 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 -extern inline void pcibios_set_master(struct pci_dev *dev) +static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ } -extern inline void pcibios_penalize_isa_irq(int irq) +static inline void pcibios_penalize_isa_irq(int irq) { /* We don't do dynamic PCI IRQ allocation */ } @@ -38,14 +39,13 @@ * MIPS has everything mapped statically. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/slab.h> #include <asm/scatterlist.h> #include <linux/string.h> #include <asm/io.h> -#if (defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476)) +#if defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476) #undef PCIBIOS_MIN_IO #undef PCIBIOS_MIN_MEM #define PCIBIOS_MIN_IO 0x0100000 @@ -55,6 +55,13 @@ struct pci_dev; /* + * The PCI address space does equal the physical memory address space. The + * networking and block device layers use this boolean for bounce buffer + * decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +/* * Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices, * NULL for PCI-like buses (ISA, EISA). @@ -77,6 +84,32 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); + +#ifdef CONFIG_MAPPED_PCI_IO + +extern dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, + int direction); +extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size, int direction); +extern int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, + int direction); +extern void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nents, int direction); +extern void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, + size_t size, int direction); +extern void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, + int nelems, int direction); + +/* pci_unmap_{single,page} is not a nop, thus... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; +#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) + +#else /* CONFIG_MAPPED_PCI_IO */ + /* * Map a single buffer of the indicated size for DMA in streaming mode. * The 32-bit bus address to use is returned. @@ -84,17 +117,17 @@ * Once the device is given the dma address, the device owns this memory * until either pci_unmap_single or pci_dma_sync_single is performed. */ -extern inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, +static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) { + unsigned long addr = (unsigned long) ptr; + if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)ptr, size); -#endif + dma_cache_wback_inv(addr, size); - return virt_to_bus(ptr); + return bus_to_baddr(hwdev->bus, __pa(ptr)); } /* @@ -105,13 +138,18 @@ * After this call, reads by the cpu to the buffer are guaranteed to see * whatever the device wrote there. */ -extern inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, +static inline void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) { if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do */ + if (direction != PCI_DMA_TODEVICE) { + unsigned long addr; + + addr = baddr_to_bus(hwdev->bus, dma_addr) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); + } } /* pci_unmap_{page,single} is a nop so... */ @@ -123,6 +161,39 @@ #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) /* + * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical + * to pci_map_single, but takes a struct page instead of a virtual address + */ +static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, + int direction) +{ + unsigned long addr; + + if (direction == PCI_DMA_NONE) + BUG(); + + addr = (unsigned long) page_address(page) + offset; + dma_cache_wback_inv(addr, size); + + return bus_to_baddr(hwdev->bus, page_to_phys(page) + offset); +} + +static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + if (direction != PCI_DMA_TODEVICE) { + unsigned long addr; + + addr = baddr_to_bus(hwdev->bus, dma_address) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); + } +} + +/* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list @@ -138,21 +209,23 @@ * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -extern inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, +static inline int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { -#ifndef CONFIG_COHERENT_IO int i; -#endif if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - /* Make sure that gcc doesn't leave the empty loop body. */ - for (i = 0; i < nents; i++, sg++) - dma_cache_wback_inv((unsigned long)sg->address, sg->length); -#endif + for (i = 0; i < nents; i++, sg++) { + unsigned long addr; + + addr = (unsigned long) page_address(sg->page); + if (addr) + dma_cache_wback_inv(addr + sg->offset, sg->length); + sg->dma_address = (dma_addr_t) bus_to_baddr(hwdev->bus, + page_to_phys(sg->page) + sg->offset); + } return nents; } @@ -162,13 +235,27 @@ * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -extern inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, +static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { + int i; + if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do */ + if (direction == PCI_DMA_TODEVICE) + return; + + for (i = 0; i < nents; i++, sg++) { + unsigned long addr; + + if (!sg->page) + BUG(); + + addr = (unsigned long) page_address(sg->page); + if (addr) + dma_cache_wback_inv(addr + sg->offset, sg->length); + } } /* @@ -181,16 +268,17 @@ * next point you give the PCI dma address back to the card, the * device again owns the buffer. */ -extern inline void pci_dma_sync_single(struct pci_dev *hwdev, +static inline void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + unsigned long addr; + if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)bus_to_virt(dma_handle), size); -#endif + addr = baddr_to_bus(hwdev->bus, dma_handle) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); } /* @@ -200,11 +288,11 @@ * The same as pci_dma_sync_single but for a scatter-gather list, * same rules and usage. */ -extern inline void pci_dma_sync_sg(struct pci_dev *hwdev, +static inline void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) { -#ifndef CONFIG_COHERENT_IO +#ifdef CONFIG_NONCOHERENT_IO int i; #endif @@ -212,30 +300,71 @@ BUG(); /* Make sure that gcc doesn't leave the empty loop body. */ -#ifndef CONFIG_COHERENT_IO +#ifdef CONFIG_NONCOHERENT_IO for (i = 0; i < nelems; i++, sg++) - dma_cache_wback_inv((unsigned long)sg->address, sg->length); + dma_cache_wback_inv((unsigned long)page_address(sg->page), + sg->length); #endif } +#endif /* CONFIG_MAPPED_PCI_IO */ -/* Return whether the given PCI device DMA address mask can +/* + * Return whether the given PCI device DMA address mask can * be supported properly. For example, if your device can * only drive the low 24-bits during PCI bus mastering, then * you would pass 0x00ffffff as the mask to this function. */ -extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) +static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) { /* * we fall back to GFP_DMA when the mask isn't all 1s, * so we can't guarantee allocations that must be * within a tighter range than GFP_DMA.. */ - if (mask < 0x1fffffff) +#ifdef CONFIG_ISA + if (mask < 0x00ffffff) return 0; +#endif return 1; } +/* This is always fine. */ +#define pci_dac_dma_supported(pci_dev, mask) (1) + +static inline dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, + struct page *page, unsigned long offset, int direction) +{ + dma64_addr_t addr = page_to_phys(page) + offset; + + return (dma64_addr_t) bus_to_baddr(pdev->bus, addr); +} + +static inline struct page *pci_dac_dma_to_page(struct pci_dev *pdev, + dma64_addr_t dma_addr) +{ + unsigned long poff = baddr_to_bus(pdev->bus, dma_addr) >> PAGE_SHIFT; + + return mem_map + poff; +} + +static inline unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev, + dma64_addr_t dma_addr) +{ + return dma_addr & ~PAGE_MASK; +} + +static inline void pci_dac_dma_sync_single(struct pci_dev *pdev, + dma64_addr_t dma_addr, size_t len, int direction) +{ + unsigned long addr; + + if (direction == PCI_DMA_NONE) + BUG(); + + addr = baddr_to_bus(pdev->bus, dma_addr) + PAGE_OFFSET; + dma_cache_wback_inv(addr, len); +} /* * These macros should be used after a pci_map_sg call has been done @@ -244,7 +373,7 @@ * returns, or alternatively stop on the first sg_dma_len(sg) which * is 0. */ -#define sg_dma_address(sg) (virt_to_bus((sg)->address)) +#define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) #endif /* __KERNEL__ */ diff -Nru a/include/asm-mips/pci_channel.h b/include/asm-mips/pci_channel.h --- a/include/asm-mips/pci_channel.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips/pci_channel.h Fri Jun 27 14:19:30 2003 @@ -23,7 +23,7 @@ int last_devfn; }; -/* +/* * each board defines an array of pci_channels, that ends with all NULL entry */ extern struct pci_channel mips_pci_channels[]; @@ -33,7 +33,7 @@ */ extern void pcibios_fixup_irqs(void); -/* +/* * board supplied pci fixup routines */ extern void pcibios_fixup_resources(struct pci_dev *dev); diff -Nru a/include/asm-mips/percpu.h b/include/asm-mips/percpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/percpu.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +#ifndef __ASM_PERCPU_H +#define __ASM_PERCPU_H + +#include <asm-generic/percpu.h> + +#endif /* __ASM_PERCPU_H */ diff -Nru a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h --- a/include/asm-mips/pgalloc.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/pgalloc.h Fri Jun 27 14:19:57 2003 @@ -11,46 +11,32 @@ #include <linux/config.h> #include <linux/mm.h> +#include <linux/highmem.h> +#include <asm/fixmap.h> -/* TLB flushing: - * - * - flush_tlb_all() flushes all processes TLB entries - * - flush_tlb_mm(mm) flushes the specified mm context TLB entries - * - flush_tlb_page(vma, vmaddr) flushes a single page - * - flush_tlb_range(vma, start, end) flushes a range of pages - */ -extern void flush_tlb_all(void); -extern void flush_tlb_mm(struct mm_struct *mm); -extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); - -extern inline void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, unsigned long end) +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, + pte_t *pte) { - /* Nothing to do on MIPS. */ + set_pmd(pmd, __pmd(__pa(pte))); } +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, + struct page *pte) +{ + set_pmd(pmd, __pmd(((unsigned long long)page_to_pfn(pte) << + (unsigned long long) PAGE_SHIFT))); +} -/* - * Allocate and free page tables. - */ - -#define pgd_quicklist (current_cpu_data.pgd_quick) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (current_cpu_data.pte_quick) -#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) - -#define pmd_populate(mm, pmd, pte) pmd_set(pmd, pte) +#define pgd_populate(mm, pmd, pte) BUG() /* * Initialize new page directory with pointers to invalid ptes */ extern void pgd_init(unsigned long page); -extern __inline__ pgd_t *get_pgd_slow(void) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init; + pgd_t *ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGD_ORDER), *init; if (ret) { init = pgd_offset(&init_mm, 0); @@ -61,120 +47,59 @@ return ret; } -extern __inline__ pgd_t *get_pgd_fast(void) -{ - unsigned long *ret; - - if((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } else - ret = (unsigned long *)get_pgd_slow(); - return (pgd_t *)ret; -} - -extern __inline__ void free_pgd_fast(pgd_t *pgd) -{ - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; -} - -extern __inline__ void free_pgd_slow(pgd_t *pgd) -{ - free_page((unsigned long)pgd); -} - -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); - -extern __inline__ pte_t *get_pte_fast(void) +static inline void pgd_free(pgd_t *pgd) { - unsigned long *ret; - - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; + free_pages((unsigned long)pgd, PGD_ORDER); } -extern __inline__ void free_pte_fast(pte_t *pte) -{ - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; -} - -extern __inline__ void free_pte_slow(pte_t *pte) -{ - free_page((unsigned long)pte); -} - -/* We don't use pmd cache, so these are dummy routines */ -extern __inline__ pmd_t *get_pmd_fast(void) -{ - return (pmd_t *)0; -} - -extern __inline__ void free_pmd_fast(pmd_t *pmd) -{ -} - -extern __inline__ void free_pmd_slow(pmd_t *pmd) -{ -} - -extern void __bad_pte(pmd_t *pmd); - -static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) { pte_t *pte; pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT); if (pte) clear_page(pte); + return pte; } -static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) { - unsigned long *ret; + struct page *pte; - if ((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; +#if CONFIG_HIGHPTE + pte = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT, 0); +#else + pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, 0); +#endif + if (pte) + clear_highpage(pte); + + return pte; } -extern __inline__ void pte_free_fast(pte_t *pte) +static inline void pte_free_kernel(pte_t *pte) { - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; + free_page((unsigned long)pte); } -extern __inline__ void pte_free_slow(pte_t *pte) +static inline void pte_free(struct page *pte) { - free_page((unsigned long)pte); + __free_page(pte); } -#define pte_free(pte) pte_free_slow(pte) -#define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc(mm) get_pgd_fast() +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); }) #define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) #define pmd_free(x) do { } while (0) -#define pgd_populate(mm, pmd, pte) BUG() +#define __pmd_free_tlb(tlb,x) do { } while (0) -extern int do_check_pgt_cache(int, int); +#define check_pgt_cache() do { } while (0) #endif /* _ASM_PGALLOC_H */ diff -Nru a/include/asm-mips/pgtable-bits.h b/include/asm-mips/pgtable-bits.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/pgtable-bits.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,102 @@ +/* + * 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 - 2002 by Ralf Baechle + * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + * Copyright (C) 2002 Maciej W. Rozycki + */ +#ifndef _ASM_PGTABLE_BITS_H +#define _ASM_PGTABLE_BITS_H + +#include <linux/config.h> + +/* + * Note that we shift the lower 32bits of each EntryLo[01] entry + * 6 bits to the left. That way we can convert the PFN into the + * physical address by a single 'and' operation and gain 6 additional + * bits for storing information which isn't present in a normal + * MIPS page table. + * + * Similar to the Alpha port, we need to keep track of the ref + * and mod bits in software. We have a software "yeah you can read + * from this page" bit, and a hardware one which actually lets the + * process read from the page. On the same token we have a software + * writable bit and the real hardware one which actually lets the + * process write to the page, this keeps a mod bit via the hardware + * dirty bit. + * + * Certain revisions of the R4000 and R5000 have a bug where if a + * certain sequence occurs in the last 3 instructions of an executable + * page, and the following page is not mapped, the cpu can do + * unpredictable things. The code (when it is written) to deal with + * this problem will be in the update_mmu_cache() code for the r4k. + */ +#define _PAGE_PRESENT (1<<0) /* implemented in software */ +#define _PAGE_READ (1<<1) /* implemented in software */ +#define _PAGE_WRITE (1<<2) /* implemented in software */ +#define _PAGE_ACCESSED (1<<3) /* implemented in software */ +#define _PAGE_MODIFIED (1<<4) /* implemented in software */ +#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */ + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + +#define _PAGE_GLOBAL (1<<8) +#define _PAGE_VALID (1<<9) +#define _PAGE_SILENT_READ (1<<9) /* synonym */ +#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<10) +#define _CACHE_UNCACHED (1<<11) +#define _CACHE_MASK (1<<11) +#define _CACHE_CACHABLE_NONCOHERENT 0 + +#else +#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ +#define _PAGE_GLOBAL (1<<6) +#define _PAGE_VALID (1<<7) +#define _PAGE_SILENT_READ (1<<7) /* synonym */ +#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<8) +#define _CACHE_MASK (7<<9) + +#if defined(CONFIG_CPU_SB1) + +/* No penalty for being coherent on the SB1, so just + use it for "noncoherent" spaces, too. Shouldn't hurt. */ + +#define _CACHE_UNCACHED (2<<9) +#define _CACHE_CACHABLE_COW (5<<9) +#define _CACHE_CACHABLE_NONCOHERENT (5<<9) +#define _CACHE_UNCACHED_ACCELERATED (7<<9) + +#else + +#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ +#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ +#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00MC only */ +#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00MC only */ +#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00MC only */ +#define _CACHE_UNCACHED_ACCELERATED (7<<9) /* R10000 only */ + +#endif +#endif + +#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) +#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) + +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) + +#ifdef CONFIG_MIPS_UNCACHED +#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED +#elif defined(CONFIG_NONCOHERENT_IO) +#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT +#else +#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW +#endif + +#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 9) + +#endif /* _ASM_PGTABLE_BITS_H */ diff -Nru a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h --- a/include/asm-mips/pgtable.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/pgtable.h Fri Jun 27 14:19:54 2003 @@ -9,48 +9,13 @@ #ifndef _ASM_PGTABLE_H #define _ASM_PGTABLE_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/page.h> -#ifndef _LANGUAGE_ASSEMBLY - #include <linux/linkage.h> #include <asm/cachectl.h> -#include <linux/config.h> - -/* Cache flushing: - * - * - flush_cache_all() flushes entire cache - * - flush_cache_mm(mm) flushes the specified mm context's cache lines - * - flush_cache_page(mm, vmaddr) flushes a single page - * - flush_cache_range(vma, start, end) flushes a range of pages - * - flush_icache_range(start, end) flush a range of instructions - */ -extern void (*_flush_cache_all)(void); -extern void (*___flush_cache_all)(void); -extern void (*_flush_cache_mm)(struct mm_struct *mm); -extern void (*_flush_cache_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -extern void (*_flush_cache_sigtramp)(unsigned long addr); -extern void (*_flush_page_to_ram)(struct page * page); -extern void (*_flush_icache_range)(unsigned long start, unsigned long end); -extern void (*_flush_icache_page)(struct vm_area_struct *vma, - struct page *page); - -#define flush_cache_all() _flush_cache_all() -#define __flush_cache_all() ___flush_cache_all() -#define flush_cache_mm(mm) _flush_cache_mm(mm) -#define flush_cache_range(vma,start,end) _flush_cache_range(vma,start,end) -#define flush_cache_page(vma,page) _flush_cache_page(vma, page) -#define flush_cache_sigtramp(addr) _flush_cache_sigtramp(addr) -#define flush_dcache_page(page) _flush_page_to_ram(page) - -#define flush_icache_range(start, end) _flush_icache_range(start,end) -#define flush_icache_page(vma, page) _flush_icache_page(vma, page) -#define flush_icache_user_range(vma, page, addr, len) \ - _flush_icache_page((vma), (page)) - +#include <asm/fixmap.h> /* * - add_wired_entry() add a fixed TLB entry, and move wired register @@ -61,7 +26,7 @@ /* * - add_temporary_entry() add a temporary TLB entry. We use TLB entries * starting at the top and working down. This is for populating the - * TLB before trap_init() puts the TLB miss handler in place. It + * TLB before trap_init() puts the TLB miss handler in place. It * should be used only for entries matching the actual page tables, * to prevent inconsistencies. */ @@ -76,114 +41,49 @@ * works even with the cache aliasing problem the R4k and above have. */ -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ - /* PMD_SHIFT determines the size of the area a second-level page table can map */ +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PMD_SHIFT 21 +#else #define PMD_SHIFT 22 +#endif #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) /* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT 22 +#define PGDIR_SHIFT PMD_SHIFT #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -/* Entries per page directory level: we use two-level, so +/* + * Entries per page directory level: we use two-level, so * we don't really have any PMD directory physically. */ +#ifdef CONFIG_64BIT_PHYS_ADDR +#define PTRS_PER_PTE 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 +#define PGD_ORDER 1 +#else #define PTRS_PER_PTE 1024 #define PTRS_PER_PMD 1 #define PTRS_PER_PGD 1024 -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define PGD_ORDER 0 +#endif + +#define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 #define VMALLOC_START KSEG2 #define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END KSEG3 - -/* Note that we shift the lower 32bits of each EntryLo[01] entry - * 6 bits to the left. That way we can convert the PFN into the - * physical address by a single 'and' operation and gain 6 additional - * bits for storing information which isn't present in a normal - * MIPS page table. - * - * Similar to the Alpha port, we need to keep track of the ref - * and mod bits in software. We have a software "yeah you can read - * from this page" bit, and a hardware one which actually lets the - * process read from the page. On the same token we have a software - * writable bit and the real hardware one which actually lets the - * process write to the page, this keeps a mod bit via the hardware - * dirty bit. - * - * Certain revisions of the R4000 and R5000 have a bug where if a - * certain sequence occurs in the last 3 instructions of an executable - * page, and the following page is not mapped, the cpu can do - * unpredictable things. The code (when it is written) to deal with - * this problem will be in the update_mmu_cache() code for the r4k. - */ -#define _PAGE_PRESENT (1<<0) /* implemented in software */ -#define _PAGE_READ (1<<1) /* implemented in software */ -#define _PAGE_WRITE (1<<2) /* implemented in software */ -#define _PAGE_ACCESSED (1<<3) /* implemented in software */ -#define _PAGE_MODIFIED (1<<4) /* implemented in software */ - -#if defined(CONFIG_CPU_R3000) - -#define _PAGE_GLOBAL (1<<8) -#define _PAGE_VALID (1<<9) -#define _PAGE_SILENT_READ (1<<9) /* synonym */ -#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<10) -#define _CACHE_UNCACHED (1<<11) /* R4[0246]00 */ -#define _CACHE_MASK (1<<11) -#define _CACHE_CACHABLE_NONCOHERENT 0 +#if CONFIG_HIGHMEM +# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) #else -#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ -#define _PAGE_GLOBAL (1<<6) -#define _PAGE_VALID (1<<7) -#define _PAGE_SILENT_READ (1<<7) /* synonym */ -#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<8) -#define _CACHE_MASK (7<<9) - -#if defined(CONFIG_CPU_SB1) - -/* No penalty for being coherent on the SB1, so just - use it for "noncoherent" spaces, too. Shouldn't hurt. */ - -#define _CACHE_UNCACHED (2<<9) -#define _CACHE_CACHABLE_COW (5<<9) -#define _CACHE_CACHABLE_NONCOHERENT (5<<9) - -#else - -#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ -#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ -#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ -#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ -#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */ - -#endif +# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) #endif -#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) -#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) - -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) - -#ifdef CONFIG_MIPS_UNCACHED -#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED -#else -#ifdef CONFIG_CPU_SB1 -#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW -#else -#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT -#endif -#endif +#include <asm/pgtable-bits.h> #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ @@ -193,11 +93,11 @@ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ PAGE_CACHABLE_DEFAULT) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - PAGE_CACHABLE_DEFAULT) + _PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT) #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ PAGE_CACHABLE_DEFAULT) -#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - _CACHE_UNCACHED) +#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ + __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) /* * MIPS can't do page protection for execute, and considers that the same like @@ -222,14 +122,22 @@ #define __S110 PAGE_SHARED #define __S111 PAGE_SHARED -#if !defined (_LANGUAGE_ASSEMBLY) - +#ifdef CONFIG_64BIT_PHYS_ADDR #define pte_ERROR(e) \ - printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) + printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) +#else +#define pte_ERROR(e) \ + printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) +#endif #define pmd_ERROR(e) \ - printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e)) + printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ - printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) + printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) + +/* + * ZERO_PAGE is a global shared page that is always zero; used + * for zero-mapped memory areas etc.. + */ extern unsigned long empty_zero_page; extern unsigned long zero_page_mask; @@ -237,21 +145,6 @@ #define ZERO_PAGE(vaddr) \ (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) -/* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) - -/* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - -/* - * sizeof(void*) == (1 << SIZEOF_PTR_LOG2) - */ -#define SIZEOF_PTR_LOG2 2 - -/* to find an entry in a page-table */ -#define PAGE_PTR(address) \ -((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) - extern void load_pgd(unsigned long pg_dir); extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; @@ -260,60 +153,68 @@ * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -extern inline unsigned long pmd_page(pmd_t pmd) -{ - return pmd_val(pmd); -} - -extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK); -} +#define page_pte(page) page_pte_prot(page, __pgprot(0)) +#define pmd_phys(pmd) (pmd_val(pmd) - PAGE_OFFSET) +#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) +#define pmd_page_kernel(pmd) pmd_val(pmd) -extern inline int pte_none(pte_t pte) { return !pte_val(pte); } -extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } +#define pte_none(pte) (!(pte_val(pte) & ~_PAGE_GLOBAL)) +#define pte_present(pte) (pte_val(pte) & _PAGE_PRESENT) /* Certain architectures need to do special things when pte's * within a page table are directly modified. Thus, the following * hook is made available. */ -extern inline void set_pte(pte_t *ptep, pte_t pteval) +static inline void set_pte(pte_t *ptep, pte_t pteval) { *ptep = pteval; +#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) + if (pte_val(pteval) & _PAGE_GLOBAL) { + pte_t *buddy = ptep_buddy(ptep); + /* + * Make sure the buddy is global too (if it's !none, + * it better already be global) + */ + if (pte_none(*buddy)) + pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; + } +#endif } -extern inline void pte_clear(pte_t *ptep) +static inline void pte_clear(pte_t *ptep) { - set_pte(ptep, __pte(0)); +#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) + /* Preserve global status for the pair */ + if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL) + set_pte(ptep, __pte(_PAGE_GLOBAL)); + else +#endif + set_pte(ptep, __pte(0)); } /* * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) */ -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) -#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) +#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0) +#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0) /* * Empty pgd/pmd entries point to the invalid_pte_table. */ -extern inline int pmd_none(pmd_t pmd) +static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) == (unsigned long) invalid_pte_table; } -extern inline int pmd_bad(pmd_t pmd) -{ - return ((pmd_page(pmd) > (unsigned long) high_memory) || - (pmd_page(pmd) < PAGE_OFFSET)); -} +#define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK) -extern inline int pmd_present(pmd_t pmd) +static inline int pmd_present(pmd_t pmd) { return (pmd_val(pmd) != (unsigned long) invalid_pte_table); } -extern inline void pmd_clear(pmd_t *pmdp) +static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); } @@ -323,51 +224,79 @@ * setup: the pgd is never bad, and a pmd always exists (as it's folded * into the pgd entry) */ -extern inline int pgd_none(pgd_t pgd) { return 0; } -extern inline int pgd_bad(pgd_t pgd) { return 0; } -extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline void pgd_clear(pgd_t *pgdp) { } +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } +static inline void pgd_clear(pgd_t *pgdp) { } + +#define pte_page(x) pfn_to_page(pte_pfn(x)) +#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT)) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define PTE_FILE_MAX_BITS 27 + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + +/* + * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset + * into this range: + */ +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) -#ifdef CONFIG_CPU_VR41XX -#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2)))) #else -#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT))) + +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset + * into this range: + */ +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) + #endif /* * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } -extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_user(pte_t pte) { BUG(); return 0; } +static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } -extern inline pte_t pte_wrprotect(pte_t pte) +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_rdprotect(pte_t pte) +static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; } -extern inline pte_t pte_mkclean(pte_t pte) +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_mkold(pte_t pte) +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; if (pte_val(pte) & _PAGE_MODIFIED) @@ -375,7 +304,7 @@ return pte; } -extern inline pte_t pte_mkread(pte_t pte) +static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_READ; if (pte_val(pte) & _PAGE_ACCESSED) @@ -383,7 +312,7 @@ return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_MODIFIED; if (pte_val(pte) & _PAGE_WRITE) @@ -391,6 +320,14 @@ return pte; } +static inline pte_t pte_mkyoung(pte_t pte) +{ + pte_val(pte) |= _PAGE_ACCESSED; + if (pte_val(pte) & _PAGE_READ) + pte_val(pte) |= _PAGE_SILENT_READ; + return pte; +} + /* * Macro to make mark a page protection value as "uncacheable". Note * that "protection" is really a misnomer here as the protection value @@ -408,55 +345,20 @@ return __pgprot(prot); } -extern inline pte_t pte_mkyoung(pte_t pte) -{ - pte_val(pte) |= _PAGE_ACCESSED; - if (pte_val(pte) & _PAGE_READ) - pte_val(pte) |= _PAGE_SILENT_READ; - return pte; -} - /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#ifdef CONFIG_CPU_VR41XX -#define mk_pte(page, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = ((unsigned long)(page - mem_map) << (PAGE_SHIFT + 2)) | \ - pgprot_val(pgprot); \ - \ - __pte; \ -}) -#else -#define mk_pte(page, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = ((unsigned long)(page - mem_map) << PAGE_SHIFT) | \ - pgprot_val(pgprot); \ - \ - __pte; \ -}) -#endif - -extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) -{ -#ifdef CONFIG_CPU_VR41XX - return __pte((physpage << 2) | pgprot_val(pgprot)); -#else - return __pte(physpage | pgprot_val(pgprot)); -#endif -} +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); } -#define page_pte(page) page_pte_prot(page, __pgprot(0)) +#define __pgd_offset(address) pgd_index(address) +#define __pmd_offset(address) \ + (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -464,313 +366,86 @@ #define pgd_index(address) ((address) >> PGDIR_SHIFT) /* to find an entry in a page-table-directory */ -extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address) -{ - return mm->pgd + pgd_index(address); -} +#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr)) /* Find an entry in the second-level page table.. */ -extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) +static inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address) { return (pmd_t *) dir; } -/* Find an entry in the third-level page table.. */ -extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) (pmd_page(*dir)) + - ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} - -extern int do_check_pgt_cache(int, int); +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset(dir, address) \ + ((pte_t *) (pmd_page_kernel(*dir)) + __pte_offset(address)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address)) + +#ifdef CONFIG_HIGHPTE +#define pte_offset_map(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + __pte_offset(address)) +#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) +#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) +#else +#define pte_offset_map(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_unmap(pte) ((void)(pte)) +#define pte_unmap_nested(pte) ((void)(pte)) +#endif extern pgd_t swapper_pg_dir[1024]; extern void paging_init(void); -extern void update_mmu_cache(struct vm_area_struct *vma, - unsigned long address, pte_t pte); - -#define __swp_type(x) (((x).val >> 1) & 0x3f) -#define __swp_offset(x) ((x).val >> 8) -#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) -#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - -#define kern_addr_valid(addr) (1) - -/* TLB operations. */ -extern inline void tlb_probe(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbp\n\t" - ".set pop"); -} - -extern inline void tlb_read(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbr\n\t" - ".set pop"); -} - -extern inline void tlb_write_indexed(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbwi\n\t" - ".set pop"); -} - -extern inline void tlb_write_random(void) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "tlbwr\n\t" - ".set pop"); -} - -/* Dealing with various CP0 mmu/cache related registers. */ - -/* CP0_PAGEMASK register */ -extern inline unsigned long get_pagemask(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $5\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_pagemask(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $5\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */ -extern inline unsigned long get_entrylo0(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $2\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_entrylo0(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $2\n\t" - ".set pop" - : : "Jr" (val)); -} - -extern inline unsigned long get_entrylo1(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $3\n\t" - ".set pop" : "=r" (val)); - - return val; -} - -extern inline void set_entrylo1(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $3\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_ENTRYHI register */ -extern inline unsigned long get_entryhi(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $10\n\t" - ".set pop" - : "=r" (val)); - - return val; -} - -extern inline void set_entryhi(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $10\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_INDEX register */ -extern inline unsigned long get_index(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $0\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_index(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $0\n\t" - ".set pop" - : : "Jr" (val)); -} - -/* CP0_WIRED register */ -extern inline unsigned long get_wired(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $6\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -extern inline void set_wired(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $6\n\t" - ".set pop" - : : "Jr" (val)); -} - -extern inline unsigned long get_info(void) -{ - unsigned long val; - - __asm__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $7\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -/* CP0_TAGLO and CP0_TAGHI registers */ -extern inline unsigned long get_taglo(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $28\n\t" - ".set pop" - : "=r" (val)); - return val; -} +extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, + pte_t pte); +extern void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte); -extern inline void set_taglo(unsigned long val) +static inline void update_mmu_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) { - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $28\n\t" - ".set pop" - : : "Jr" (val)); + __update_tlb(vma, address, pte); + __update_cache(vma, address, pte); } -extern inline unsigned long get_taghi(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $29\n\t" - ".set pop" - : "=r" (val)); - return val; -} +/* Swap entries must have VALID and GLOBAL bits cleared. */ +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -extern inline void set_taghi(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $29\n\t" - ".set pop" - : : "Jr" (val)); -} +#define __swp_type(x) (((x).val >> 1) & 0x7f) +#define __swp_offset(x) ((x).val >> 10) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) }) +#else -/* CP0_CONTEXT register */ -extern inline unsigned long get_context(void) -{ - unsigned long val; +#define __swp_type(x) (((x).val >> 1) & 0x1f) +#define __swp_offset(x) ((x).val >> 8) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) +#endif - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $4\n\t" - ".set pop" - : "=r" (val)); +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) - return val; -} -extern inline void set_context(unsigned long val) -{ - __asm__ __volatile__( - ".set push\n\t" - ".set reorder\n\t" - "mtc0 %z0, $4\n\t" - ".set pop" - : : "Jr" (val)); -} +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +#define kern_addr_valid(addr) (1) #include <asm-generic/pgtable.h> +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef u64 pte_addr_t; +#else typedef pte_t *pte_addr_t; +#endif -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +/* + * We provide our own get_unmapped area to cope with the virtual aliasing + * constraints placed on us by the cache architecture. + */ +#define HAVE_ARCH_UNMAPPED_AREA #define io_remap_page_range remap_page_range diff -Nru a/include/asm-mips/pmc/ev64120.h b/include/asm-mips/pmc/ev64120.h --- a/include/asm-mips/pmc/ev64120.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,59 +0,0 @@ -/* - * This is a direct copy of the ev96100.h file, with a global search and - * replace. The numbers are the same. - * - * The reason I'm duplicating this is so that the 64120/96100 - * defines won't be confusing in the source code. - */ -#ifndef _ASM_PMC_CP7000_H -#define _ASM_PMC_CP7000_H - -#include <asm/addrspace.h> - -/* - * GT64120 config space base address - */ -#define GT64120_BASE (KSEG1ADDR(0x14000000)) -#define MIPS_GT_BASE GT64120_BASE - -/* - * PCI Bus allocation - */ -#define GT_PCI_MEM_BASE 0x12000000 -#define GT_PCI_MEM_SIZE 0x02000000 -#define GT_PCI_IO_BASE 0x10000000 -#define GT_PCI_IO_SIZE 0x02000000 -#define GT_ISA_IO_BASE PCI_IO_BASE - -/* - * Duart I/O ports. - */ -#define EV64120_COM1_BASE_ADDR (0x1d000000 + 0x20) -#define EV64120_COM2_BASE_ADDR (0x1d000000 + 0x00) - - -/* - * EV64120 interrupt controller register base. - */ -#define EV64120_ICTRL_REGS_BASE (KSEG1ADDR(0x1f000000)) - -/* - * EV64120 UART register base. - */ -#define EV64120_UART0_REGS_BASE (KSEG1ADDR(EV64120_COM1_BASE_ADDR)) -#define EV64120_UART1_REGS_BASE (KSEG1ADDR(EV64120_COM2_BASE_ADDR)) -#define EV64120_BASE_BAUD ( 3686400 / 16 ) - - -/* - * Because of an error/peculiarity in the Galileo chip, we need to swap the - * bytes when running bigendian. - */ - -#define GT_WRITE(ofs, data) \ - *(volatile u32 *)(MIPS_GT_BASE+ofs) = cpu_to_le32(data) -#define GT_READ(ofs, data) \ - *data = le32_to_cpu(*(volatile u32 *)(MIPS_GT_BASE+ofs)) - - -#endif /* _ASM_PMC_CP7000_H */ diff -Nru a/include/asm-mips/pmc/ev64120int.h b/include/asm-mips/pmc/ev64120int.h --- a/include/asm-mips/pmc/ev64120int.h Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,32 +0,0 @@ -#ifndef _ASM_PMC_CP7000INT_H -#define _ASM_PMC_CP7000INT_H - -#define INT_CAUSE_MAIN 0 -#define INT_CAUSE_HIGH 1 - -#define MAX_CAUSE_REGS 4 -#define MAX_CAUSE_REG_WIDTH 32 - -void hook_irq_handler (int int_cause , int bit_num , void *isr_ptr); -int disable_galileo_irq (int int_cause , int bit_num); -int enable_galileo_irq (int int_cause , int bit_num); - -extern struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; - -/* - * PCI interrupts will come in on either the INTA or INTD interrups lines, - * which are mapped to the #2 and #5 interrupt pins of the MIPS. On our - * boards, they all either come in on IntD or they all come in on IntA, they - * aren't mixed. There can be numerous PCI interrupts, so we keep a list of the - * "requested" interrupt numbers and go through the list whenever we get an - * IntA/D. - * - * All PCI interrupts have numbers >= 20 by arbitrary convention. Any - * interrupt < 8 is an interrupt that is maskable on MIPS. - */ - -#define TIMER 4 -#define INTA 2 -#define INTD 5 - -#endif /* _ASM_PMC_CP7000INT_H */ diff -Nru a/include/asm-mips/poll.h b/include/asm-mips/poll.h --- a/include/asm-mips/poll.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips/poll.h Fri Jun 27 14:20:04 2003 @@ -1,5 +1,5 @@ -#ifndef __ASM_MIPS_POLL_H -#define __ASM_MIPS_POLL_H +#ifndef __ASM_POLL_H +#define __ASM_POLL_H #define POLLIN 0x0001 #define POLLPRI 0x0002 @@ -14,8 +14,9 @@ #define POLLWRNORM POLLOUT #define POLLWRBAND 0x0100 -/* XXX This one seems to be more-or-less nonstandard. */ +/* These seem to be more or less nonstandard ... */ #define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 struct pollfd { int fd; @@ -23,4 +24,4 @@ short revents; }; -#endif /* __ASM_MIPS_POLL_H */ +#endif /* __ASM_POLL_H */ diff -Nru a/include/asm-mips/posix_types.h b/include/asm-mips/posix_types.h --- a/include/asm-mips/posix_types.h Fri Jun 27 14:19:58 2003 +++ b/include/asm-mips/posix_types.h Fri Jun 27 14:19:58 2003 @@ -1,5 +1,4 @@ -/* $Id: posix_types.h,v 1.6 2000/02/04 23:32:54 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -18,7 +17,7 @@ typedef unsigned int __kernel_dev_t; typedef unsigned long __kernel_ino_t; typedef unsigned int __kernel_mode_t; -typedef int __kernel_nlink_t; +typedef unsigned long __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; typedef int __kernel_ipc_pid_t; @@ -30,6 +29,8 @@ typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; typedef long __kernel_daddr_t; typedef char * __kernel_caddr_t; @@ -69,7 +70,7 @@ #undef __FD_ISSET static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) -{ +{ unsigned long __tmp = __fd / __NFDBITS; unsigned long __rem = __fd % __NFDBITS; return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; diff -Nru a/include/asm-mips/prctl.h b/include/asm-mips/prctl.h --- a/include/asm-mips/prctl.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/prctl.h Fri Jun 27 14:19:55 2003 @@ -3,7 +3,6 @@ * * The IRIX kernel maps a page at PRDA_ADDRESS with the * contents of prda and fills it the bits on prda_sys. - * $Id$ */ #ifndef __PRCTL_H__ @@ -13,14 +12,14 @@ #define PRDA ((struct prda *) PRDA_ADDRESS) struct prda_sys { - pid_t t_pid; + pid_t t_pid; u32 t_hint; u32 t_dlactseq; u32 t_fpflags; u32 t_prid; /* processor type, $prid CP0 register */ u32 t_dlendseq; u64 t_unused1[5]; - pid_t t_rpid; + pid_t t_rpid; s32 t_resched; u32 t_unused[8]; u32 t_cpu; /* current/last cpu */ diff -Nru a/include/asm-mips/processor.h b/include/asm-mips/processor.h --- a/include/asm-mips/processor.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/processor.h Fri Jun 27 14:19:52 2003 @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994 Waldorf GMBH - * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001 Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle * Copyright (C) 1996 Paul M. Antoine * Copyright (C) 1999 Silicon Graphics, Inc. */ @@ -12,8 +12,9 @@ #define _ASM_PROCESSOR_H #include <linux/config.h> - +#include <linux/threads.h> #include <asm/isadep.h> +#include <asm/page.h> /* * Default implementation of macro that returns current @@ -21,59 +22,102 @@ */ #define current_text_addr() ({ __label__ _l; _l: &&_l;}) -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ +#include <linux/cache.h> #include <linux/threads.h> + #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/reg.h> #include <asm/system.h> -struct mips_cpuinfo { - unsigned long udelay_val; - unsigned long *pgd_quick; - unsigned long *pte_quick; - unsigned long pgtable_cache_sz; +/* + * Descriptor for a cache + */ +struct cache_desc { + unsigned short linesz; + unsigned short ways; + unsigned int sets; + unsigned int waybit; /* Bits to select in a cache set */ + unsigned int flags; /* Flags describingcache properties */ }; /* - * System setup and hardware flags.. - * XXX: Should go into mips_cpuinfo. + * Flag definitions */ -extern void (*cpu_wait)(void); /* only available on R4[26]00 and R3081 */ -extern void r3081_wait(void); -extern void r4k_wait(void); -extern char cyclecounter_available; /* only available from R4000 upwards. */ +#define MIPS_CACHE_NOT_PRESENT 0x00000001 +#define MIPS_CACHE_VTAG 0x00000002 /* Virtually tagged cache */ +#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */ +#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */ -extern struct mips_cpuinfo boot_cpu_data; -extern unsigned int vced_count, vcei_count; +struct cpuinfo_mips { + unsigned long udelay_val; + unsigned long asid_cache; + + /* + * Capability and feature descriptor structure for MIPS CPU + */ + unsigned long options; + unsigned int processor_id; + unsigned int fpu_id; + unsigned int cputype; + int isa_level; + int tlbsize; + struct cache_desc icache; /* Primary I-cache */ + struct cache_desc dcache; /* Primary D or combined I/D cache */ + struct cache_desc scache; /* Secondary cache */ + struct cache_desc tcache; /* Tertiary/split secondary cache */ +} __attribute__((__aligned__(SMP_CACHE_BYTES))); + +/* + * Assumption: Options of CPU 0 are a superset of all processors. + * This is true for all known MIPS systems. + */ +#define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB) +#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX) +#define cpu_has_4ktlb (cpu_data[0].options & MIPS_CPU_4KTLB) +#define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU) +#define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) +#define cpu_has_counter (cpu_data[0].options & MIPS_CPU_COUNTER) +#define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH) +#define cpu_has_mips16 (cpu_data[0].options & MIPS_CPU_MIPS16) +#define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC) +#define cpu_has_vce (cpu_data[0].options & MIPS_CPU_VCE) +#define cpu_has_cache_cdex (cpu_data[0].options & MIPS_CPU_CACHE_CDEX) +#define cpu_has_mcheck (cpu_data[0].options & MIPS_CPU_MCHECK) +#define cpu_has_ejtag (cpu_data[0].options & MIPS_CPU_EJTAG) +#define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX) +#define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC) +#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) +#define cpu_has_dc_aliases (cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES) +#define cpu_has_ic_fills_f_dc (cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC) +#define cpu_has_64bits (cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT) +#define cpu_has_subset_pcaches (cpu_data[0].options & MIPS_CPU_SUBSET_CACHES) -#ifdef CONFIG_SMP -extern struct mips_cpuinfo cpu_data[]; +extern struct cpuinfo_mips cpu_data[]; #define current_cpu_data cpu_data[smp_processor_id()] -#else -#define cpu_data &boot_cpu_data -#define current_cpu_data boot_cpu_data -#endif + +extern void cpu_probe(void); +extern void cpu_report(void); /* - * Bus types (default is ISA, but people can check others with these..) - * MCA_bus hardcoded to 0 for now. - * - * This needs to be extended since MIPS systems are being delivered with - * numerous different types of bus systems. + * System setup and hardware flags.. */ -extern int EISA_bus; -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ +extern void (*cpu_wait)(void); + +extern unsigned int vced_count, vcei_count; /* - * MIPS has no problems with write protection + * Bus types (default is ISA, but people can check others with these..) */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ +#ifdef CONFIG_EISA +extern int EISA_bus; +#else +#define EISA_bus (0) +#endif -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ /* * User space process size: 2GB. This is hardcoded into a few places, @@ -86,7 +130,7 @@ /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) +#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) /* * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. @@ -148,27 +192,11 @@ #define MF_FIXADE 1 /* Fix address errors in software */ #define MF_LOGADE 2 /* Log address errors to syslog */ unsigned long mflags; - mm_segment_t current_ds; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; - - /* - * These are really only needed if the full FPU emulator is configured. - * Would be made conditional on MIPS_FPU_EMULATOR if it weren't for the - * fact that having offset.h rebuilt differently for different config - * options would be asking for trouble. - * - * Saved EPC during delay-slot emulation (see math-emu/cp1emu.c) - */ - unsigned long dsemul_epc; - - /* - * Pointer to instruction used to induce address error - */ - unsigned long dsemul_aerpc; }; -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #define INIT_THREAD { \ /* \ @@ -191,19 +219,14 @@ /* \ * For now the default is to fix address errors \ */ \ - MF_FIXADE, { 0 }, 0, 0, \ - /* \ - * dsemul_epc and dsemul_aerpc should never be used uninitialized, \ - * but... \ - */ \ - 0 ,0 \ + MF_FIXADE, 0, 0 \ } #ifdef __KERNEL__ #define KERNEL_STACK_SIZE 8192 -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) @@ -213,54 +236,25 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* - * Return saved PC of a blocked thread. - */ -extern inline unsigned long thread_saved_pc(struct thread_struct *t) -{ - extern void ret_from_fork(void); - - /* New born processes are a special case */ - if (t->reg31 == (unsigned long) ret_from_fork) - return t->reg31; - - return ((unsigned long *)t->reg29)[10]; -} +extern unsigned long thread_saved_pc(struct thread_struct *t); /* * Do necessary setup to start up a newly executed thread. */ -#define start_thread(regs, new_pc, new_sp) do { \ - /* New thread loses kernel privileges. */ \ - regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KU_USER;\ - regs->cp0_epc = new_pc; \ - regs->regs[29] = new_sp; \ - current->thread.current_ds = USER_DS; \ -} while (0) +extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); +struct task_struct; unsigned long get_wchan(struct task_struct *p); #define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs)) -#define __KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32) +#define __KSTK_TOS(tsk) ((unsigned long)(tsk->thread_info) + KERNEL_STACK_SIZE - 32) #define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc))) #define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29]))) - -/* Allocation and freeing of basic task resources. */ -/* - * NOTE! The task struct and the stack go together - */ -#define THREAD_SIZE (2*PAGE_SIZE) -#define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long)(p),1) -#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - -#define init_task (init_task_union.task) -#define init_stack (init_task_union.stack) +#define KSTK_STATUS(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_status))) #define cpu_relax() barrier() -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ /* diff -Nru a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h --- a/include/asm-mips/ptrace.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/ptrace.h Fri Jun 27 14:19:57 2003 @@ -12,7 +12,6 @@ #define _ASM_PTRACE_H #include <asm/isadep.h> -#include <linux/types.h> /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ #define FPR_BASE 32 @@ -24,7 +23,7 @@ #define FPC_CSR 69 #define FPC_EIR 70 -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* * This struct defines the way the registers are stored on the stack during a * system call/exception. As usual the registers k0/k1 aren't being saved. @@ -49,7 +48,34 @@ unsigned long cp0_cause; }; -#endif /* !(_LANGUAGE_ASSEMBLY) */ +#define __str2(x) #x +#define __str(x) __str2(x) + +#define save_static_function(symbol) \ +__asm__ ( \ + ".text\n\t" \ + ".globl\t" #symbol "\n\t" \ + ".align\t2\n\t" \ + ".type\t" #symbol ", @function\n\t" \ + ".ent\t" #symbol ", 0\n" \ + #symbol":\n\t" \ + ".frame\t$29, 0, $31\n\t" \ + "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t" \ + "sw\t$17,"__str(PT_R17)"($29)\n\t" \ + "sw\t$18,"__str(PT_R18)"($29)\n\t" \ + "sw\t$19,"__str(PT_R19)"($29)\n\t" \ + "sw\t$20,"__str(PT_R20)"($29)\n\t" \ + "sw\t$21,"__str(PT_R21)"($29)\n\t" \ + "sw\t$22,"__str(PT_R22)"($29)\n\t" \ + "sw\t$23,"__str(PT_R23)"($29)\n\t" \ + "sw\t$30,"__str(PT_R30)"($29)\n\t" \ + ".end\t" #symbol "\n\t" \ + ".size\t" #symbol",. - " #symbol) + +/* Used in declaration of save_static functions. */ +#define static_unused static __attribute__((unused)) + +#endif /* !__ASSEMBLY__ */ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ /* #define PTRACE_GETREGS 12 */ @@ -61,13 +87,16 @@ #define PTRACE_OLDSETOPTIONS 21 -#ifdef _LANGUAGE_ASSEMBLY +#define PTRACE_GET_THREAD_AREA 25 +#define PTRACE_SET_THREAD_AREA 26 + +#ifdef __ASSEMBLY__ #include <asm/offset.h> #endif #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* * Does the process account for user or for system time? */ @@ -76,7 +105,7 @@ #define instruction_pointer(regs) ((regs)->cp0_epc) extern void show_regs(struct pt_regs *); -#endif /* !(_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #endif diff -Nru a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h --- a/include/asm-mips/r4kcache.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/r4kcache.h Fri Jun 27 14:19:53 2003 @@ -1,155 +1,114 @@ /* - * r4kcache.h: Inline assembly cache operations. + * 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) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: r4kcache.h,v 1.7 1997/12/18 13:00:45 ralf Exp $ + * Inline assembly cache operations. * - * FIXME: Handle split L2 caches. + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org) */ -#ifndef _MIPS_R4KCACHE_H -#define _MIPS_R4KCACHE_H +#ifndef __ASM_R4KCACHE_H +#define __ASM_R4KCACHE_H #include <asm/asm.h> #include <asm/cacheops.h> -extern inline void flush_icache_line_indexed(unsigned long addr) +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set mips0 \n" \ + " .set reorder" \ + : \ + : "i" (op), "m" (*(unsigned char *)(addr))) + +static inline void flush_icache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Invalidate_I)); + cache_op(Index_Invalidate_I, addr); } -extern inline void flush_dcache_line_indexed(unsigned long addr) +static inline void flush_dcache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_D)); + cache_op(Index_Writeback_Inv_D, addr); } -extern inline void flush_scache_line_indexed(unsigned long addr) +static inline void flush_scache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Index_Writeback_Inv_SD)); + cache_op(Index_Writeback_Inv_SD, addr); } -extern inline void flush_icache_line(unsigned long addr) +static inline void flush_icache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_I)); + cache_op(Hit_Invalidate_I, addr); } -extern inline void flush_dcache_line(unsigned long addr) +static inline void flush_dcache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_D)); + cache_op(Hit_Writeback_Inv_D, addr); } -extern inline void invalidate_dcache_line(unsigned long addr) +static inline void invalidate_dcache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_D)); + cache_op(Hit_Invalidate_D, addr); } -extern inline void invalidate_scache_line(unsigned long addr) +static inline void invalidate_scache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Invalidate_SD)); + cache_op(Hit_Invalidate_SD, addr); } -extern inline void flush_scache_line(unsigned long addr) +static inline void flush_scache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - ".set mips3\n\t" - "cache %1, (%0)\n\t" - ".set mips0\n\t" - ".set reorder" - : - : "r" (addr), - "i" (Hit_Writeback_Inv_SD)); + cache_op(Hit_Writeback_Inv_SD, addr); } /* * The next two are for badland addresses like signal trampolines. */ -extern inline void protected_flush_icache_line(unsigned long addr) +static inline void protected_flush_icache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n" - "1:\tcache %1,(%0)\n" + "1:\tcache %0,(%1)\n" "2:\t.set mips0\n\t" ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" STR(PTR)"\t1b,2b\n\t" ".previous" : - : "r" (addr), - "i" (Hit_Invalidate_I)); + : "i" (Hit_Invalidate_I), "r" (addr)); } -extern inline void protected_writeback_dcache_line(unsigned long addr) +/* + * R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D + * cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style + * caches. We're talking about one cacheline unnecessarily getting invalidated + * here so the penaltiy isn't overly hard. + */ +static inline void protected_writeback_dcache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n" - "1:\tcache %1,(%0)\n" + "1:\tcache %0,(%1)\n" "2:\t.set mips0\n\t" ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" STR(PTR)"\t1b,2b\n\t" ".previous" : - : "r" (addr), - "i" (Hit_Writeback_D)); + : "i" (Hit_Writeback_Inv_D), "r" (addr)); +} + +/* + * This one is RM7000-specific + */ +static inline void invalidate_tcache_page(unsigned long addr) +{ + cache_op(Page_Invalidate_T, addr); } #define cache16_unroll32(base,op) \ @@ -178,103 +137,121 @@ : "r" (base), \ "i" (op)); -extern inline void blast_dcache16(void) +static inline void blast_dcache16(void) { unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); + unsigned long end = start + dcache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_D); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_dcache16_page(unsigned long page) +static inline void blast_dcache16_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Writeback_Inv_D); start += 0x200; } } -extern inline void blast_dcache16_page_indexed(unsigned long page) +static inline void blast_dcache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_D); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_icache16(void) +static inline void blast_icache16(void) { unsigned long start = KSEG0; - unsigned long end = (start + icache_size); + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_icache16_page(unsigned long page) +static inline void blast_icache16_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Invalidate_I); start += 0x200; } } -extern inline void blast_icache16_page_indexed(unsigned long page) +static inline void blast_icache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache16(void) +static inline void blast_scache16(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_SD); - start += 0x200; - } + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache16_page(unsigned long page) +static inline void blast_scache16_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Writeback_Inv_SD); start += 0x200; } } -extern inline void blast_scache16_page_indexed(unsigned long page) +static inline void blast_scache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_SD); - start += 0x200; - } + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache32_unroll32(base,op) \ @@ -303,121 +280,121 @@ : "r" (base), \ "i" (op)); -extern inline void blast_dcache32(void) +static inline void blast_dcache32(void) { unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); + unsigned long end = start + dcache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); } -/* - * Call this function only with interrupts disabled or R4600 V2.0 may blow - * up on you. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -extern inline void blast_dcache32_page(unsigned long page) +static inline void blast_dcache32_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - /* - * Sigh ... workaround for R4600 v1.7 bug. Explanation see above. - */ - *(volatile unsigned long *)KSEG1; + unsigned long end = start + PAGE_SIZE; - __asm__ __volatile__("nop;nop;nop;nop"); - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Writeback_Inv_D); start += 0x400; } } -extern inline void blast_dcache32_page_indexed(unsigned long page) +static inline void blast_dcache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_icache32(void) +static inline void blast_icache32(void) { unsigned long start = KSEG0; - unsigned long end = (start + icache_size); + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_icache32_page(unsigned long page) +static inline void blast_icache32_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Invalidate_I); start += 0x400; } } -extern inline void blast_icache32_page_indexed(unsigned long page) +static inline void blast_icache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache32(void) +static inline void blast_scache32(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_SD); - start += 0x400; - } + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache32_page(unsigned long page) +static inline void blast_scache32_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Writeback_Inv_SD); start += 0x400; } } -extern inline void blast_scache32_page_indexed(unsigned long page) +static inline void blast_scache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_SD); - start += 0x400; - } + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache64_unroll32(base,op) \ @@ -446,39 +423,84 @@ : "r" (base), \ "i" (op)); -extern inline void blast_scache64(void) +static inline void blast_icache64(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache64_unroll32(start,Index_Writeback_Inv_SD); - start += 0x800; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache64_page(unsigned long page) +static inline void blast_icache64_page(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; + unsigned long end = start + PAGE_SIZE; - while(start < end) { - cache64_unroll32(start,Hit_Writeback_Inv_SD); + while (start < end) { + cache64_unroll32(start,Hit_Invalidate_I); start += 0x800; } } -extern inline void blast_scache64_page_indexed(unsigned long page) +static inline void blast_icache64_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Invalidate_I); +} + +static inline void blast_scache64(void) +{ + unsigned long start = KSEG0; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); +} + +static inline void blast_scache64_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { - cache64_unroll32(start,Index_Writeback_Inv_SD); + while (start < end) { + cache64_unroll32(start,Hit_Writeback_Inv_SD); start += 0x800; } } +static inline void blast_scache64_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); +} + #define cache128_unroll32(base,op) \ __asm__ __volatile__(" \ .set noreorder; \ @@ -505,25 +527,43 @@ : "r" (base), \ "i" (op)); -extern inline void blast_scache128(void) +static inline void blast_scache128(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x1000) + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); +} - while(start < end) { - cache128_unroll32(start,Index_Writeback_Inv_SD); +static inline void blast_scache128_page(unsigned long page) +{ + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while (start < end) { + cache128_unroll32(start,Hit_Writeback_Inv_SD); start += 0x1000; } } -extern inline void blast_scache128_page(unsigned long page) +static inline void blast_scache128_page_indexed(unsigned long page) { - cache128_unroll32(page,Hit_Writeback_Inv_SD); -} + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; -extern inline void blast_scache128_page_indexed(unsigned long page) -{ - cache128_unroll32(page,Index_Writeback_Inv_SD); + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x1000) + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } -#endif /* !(_MIPS_R4KCACHE_H) */ +#endif /* __ASM_R4KCACHE_H */ diff -Nru a/include/asm-mips/reg.h b/include/asm-mips/reg.h --- a/include/asm-mips/reg.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/reg.h Fri Jun 27 14:19:59 2003 @@ -59,7 +59,7 @@ #define EF_CP0_EPC 40 #define EF_CP0_BADVADDR 41 #define EF_CP0_STATUS 42 -#define EF_CP0_CAUSE 44 +#define EF_CP0_CAUSE 43 #define EF_SIZE 180 /* size in bytes */ diff -Nru a/include/asm-mips/riscos-syscall.h b/include/asm-mips/riscos-syscall.h --- a/include/asm-mips/riscos-syscall.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/riscos-syscall.h Fri Jun 27 14:19:57 2003 @@ -220,7 +220,7 @@ #define __NR_SVR4_reserved62 (__NR_SVR4 + 199) #define __NR_SVR4_reserved63 (__NR_SVR4 + 200) #define __NR_SVR4_aread (__NR_SVR4 + 201) -#define __NR_SVR4_awrite (__NR_SVR4 + 202) +#define __NR_SVR4_awrite (__NR_SVR4 + 202) #define __NR_SVR4_listio (__NR_SVR4 + 203) #define __NR_SVR4_mips_acancel (__NR_SVR4 + 204) #define __NR_SVR4_astatus (__NR_SVR4 + 205) diff -Nru a/include/asm-mips/rmap.h b/include/asm-mips/rmap.h --- a/include/asm-mips/rmap.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/rmap.h Fri Jun 27 14:19:59 2003 @@ -1,7 +1,7 @@ -#ifndef _MIPS_RMAP_H -#define _MIPS_RMAP_H +#ifndef __ASM_RMAP_H +#define __ASM_RMAP_H /* nothing to see, move along */ #include <asm-generic/rmap.h> -#endif +#endif /* __ASM_RMAP_H */ diff -Nru a/include/asm-mips/rrm.h b/include/asm-mips/rrm.h --- a/include/asm-mips/rrm.h Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,88 +0,0 @@ -/* - * SGI Rendering Resource Manager API (?). - * - * written by Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * Ok, even if SGI choosed to do mmap trough ioctls, their - * kernel support for virtualizing the graphics card is nice. - * - * We should be able to make graphic applications on Linux - * fly. - * - * This header file should be included from GNU libc as well. - */ - - -/* Why like this you say? Well, gdb can print enums */ -#define RRM_BASE 1000 -#define RRM_CMD_LIMIT (RRM_BASE + 100) - -enum { - RRM_OPENRN = RRM_BASE, /* open rendering node */ - RRM_CLOSERN, - RRM_BINDPROCTORN, /* set current rendering region for node */ - RRM_BINDRNTOCLIP, - RRM_UNBINDRNFROMCLIP, - RRM_SWAPBUF, - RRM_SETSWAPINTERVAL, - RRM_WAITFORRETRACE, - RRM_SETDISPLAYMODE, - RRM_MESSAGE, - RRM_INVALIDATERN, - RRM_VALIDATECLIP, - RRM_VALIDATESWAPBUF, - RRM_SWAPGROUP, - RRM_SWAPUNGROUP, - RRM_VALIDATEMESSAGE, - RRM_GETDISPLAYMODES, - RRM_LOADDISPLAYMODE, - RRM_CUSHIONBUFFER, - RRM_SWAPREADY, - RRM_MGR_SWAPBUF, - RRM_SETVSYNC, - RRM_GETVSYNC, - RRM_WAITVSYNC, - RRM_BINDRNTOREADANDCLIP, - RRM_MAPCLIPTOSWPBUFID -}; - -/* Parameters for the above ioctls - * - * All of the ioctls take as their first argument the rendering node id. - * - */ - -/* - * RRM_OPENRN: - * - * This is called by the IRIX X server with: - * rnid = 0xffffffff rmask = 0 - * - * Returns a number like this: 0x10001. - * If you run the X server over and over, you get a value - * that is of the form (n * 0x10000) + 1. - * - * The return value seems to be the RNID. - */ -struct RRM_OpenRN { - int rnid; - unsigned int rmask; -}; - -struct RRM_CloseRN { - int rnid; -}; - -/* - * RRM_BINDPROCTORN: - * - * Return value when the X server calls it: 0 - */ -struct RRM_BindProcToRN { - int rnid; -}; - -#ifdef __KERNEL__ -int rrm_command (unsigned int cmd, void *arg); -int rrm_close (struct inode *inode, struct file *file); -#endif diff -Nru a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/rtc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,10 @@ +#ifndef _I386_RTC_H +#define _I386_RTC_H + +/* + * x86 uses the default access methods for the RTC. + */ + +#include <asm-generic/rtc.h> + +#endif diff -Nru a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h --- a/include/asm-mips/scatterlist.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/scatterlist.h Fri Jun 27 14:19:59 2003 @@ -1,21 +1,13 @@ -#ifndef __ASM_MIPS_SCATTERLIST_H -#define __ASM_MIPS_SCATTERLIST_H +#ifndef __ASM_SCATTERLIST_H +#define __ASM_SCATTERLIST_H struct scatterlist { - struct page *page; - unsigned int offset; - unsigned int length; - - __u32 dvma_address; + struct page * page; + unsigned int offset; + dma_addr_t dma_address; + unsigned int length; }; -struct mmu_sglist { - char *addr; - char *__dont_touch; - unsigned int len; - __u32 dvma_addr; -}; - -#define ISA_DMA_THRESHOLD (0x00ffffff) +#define ISA_DMA_THRESHOLD (0x00ffffffUL) -#endif /* __ASM_MIPS_SCATTERLIST_H */ +#endif /* __ASM_SCATTERLIST_H */ diff -Nru a/include/asm-mips/sections.h b/include/asm-mips/sections.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sections.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,9 @@ +#ifndef __ASM_SECTIONS_H +#define __ASM_SECTIONS_H + +#include <asm-generic/sections.h> + +extern char _stext, _etext; +extern char _end; + +#endif /* __ASM_SECTIONS_H */ diff -Nru a/include/asm-mips/semaphore-helper.h b/include/asm-mips/semaphore-helper.h --- a/include/asm-mips/semaphore-helper.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/semaphore-helper.h Fri Jun 27 14:19:57 2003 @@ -3,14 +3,15 @@ * * Copyright (C) 1996 Linus Torvalds * Copyright (C) 1999 Andrea Arcangeli - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. + * Copyright (C) 1999, 2001, 2002 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. * Copyright (C) 2000 MIPS Technologies, Inc. */ #ifndef _ASM_SEMAPHORE_HELPER_H #define _ASM_SEMAPHORE_HELPER_H #include <linux/config.h> +#include <linux/errno.h> #define sem_read(a) ((a)->counter) #define sem_inc(a) (((a)->counter)++) @@ -25,20 +26,19 @@ #ifdef CONFIG_CPU_HAS_LLSC -static inline int -waking_non_zero(struct semaphore *sem) +static inline int waking_non_zero(struct semaphore *sem) { int ret, tmp; __asm__ __volatile__( - "1:\tll\t%1, %2\n\t" + "1:\tll\t%1, %2\t\t\t# waking_non_zero\n\t" "blez\t%1, 2f\n\t" "subu\t%0, %1, 1\n\t" "sc\t%0, %2\n\t" - "beqz\t%0, 1b\n\t" + "beqz\t%0, 1b\n" "2:" - : "=r" (ret), "=r" (tmp), "=m" (sem->waking) - : "0"(0)); + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) + : "0" (0)); return ret; } @@ -55,12 +55,12 @@ unsigned long flags; int ret = 0; - save_and_cli(flags); + local_irq_save(flags); if (sem_read(&sem->waking) > 0) { sem_dec(&sem->waking); ret = 1; } - restore_flags(flags); + local_irq_restore(flags); return ret; } #endif /* !CONFIG_CPU_HAS_LLSC */ @@ -74,22 +74,22 @@ * -EINTR interrupted * * We must undo the sem->count down_interruptible decrement - * simultaneously and atomicly with the sem->waking adjustment, + * simultaneously and atomically with the sem->waking adjustment, * otherwise we can race with wake_one_more. * - * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words. + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. * - * This is crazy. Normally it stricly forbidden to use 64-bit operations + * This is crazy. Normally it's strictly forbidden to use 64-bit operations * in the 32-bit MIPS kernel. In this case it's however ok because if an * interrupt has destroyed the upper half of registers sc will fail. - * Note also that this will not work for MIPS32 CPUS! + * Note also that this will not work for MIPS32 CPUs! * * Pseudocode: * * If(sem->waking > 0) { * Decrement(sem->waking) * Return(SUCCESS) - * } else If(segnal_pending(tsk)) { + * } else If(signal_pending(tsk)) { * Increment(sem->count) * Return(-EINTR) * } else { @@ -103,7 +103,7 @@ long ret, tmp; __asm__ __volatile__( - ".set\tpush\n\t" + ".set\tpush\t\t\t# waking_non_zero_interruptible\n\t" ".set\tmips3\n\t" ".set\tnoat\n" "0:\tlld\t%1, %2\n\t" @@ -127,12 +127,11 @@ } /* - * waking_non_zero_trylock is unused. we do everything in + * waking_non_zero_trylock is unused. we do everything in * down_trylock and let non-ll/sc hosts bounce around. */ -static inline int -waking_non_zero_trylock(struct semaphore *sem) +static inline int waking_non_zero_trylock(struct semaphore *sem) { #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); @@ -149,7 +148,7 @@ int ret = 0; unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); if (sem_read(&sem->waking) > 0) { sem_dec(&sem->waking); ret = 1; @@ -157,7 +156,7 @@ sem_inc(&sem->count); ret = -EINTR; } - restore_flags(flags); + local_irq_restore(flags); return ret; } @@ -166,14 +165,14 @@ int ret = 1; unsigned long flags; - save_and_cli(flags); + local_irq_save(flags); if (sem_read(&sem->waking) <= 0) sem_inc(&sem->count); else { sem_dec(&sem->waking); ret = 0; } - restore_flags(flags); + local_irq_restore(flags); return ret; } diff -Nru a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h --- a/include/asm-mips/semaphore.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/semaphore.h Fri Jun 27 14:19:55 2003 @@ -1,23 +1,21 @@ /* - * SMP- and interrupt-safe semaphores.. - * * 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. * - * (C) Copyright 1996 Linus Torvalds - * (C) Copyright 1998, 99, 2000, 01 Ralf Baechle - * (C) Copyright 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 2000, 01 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 1996 Linus Torvalds + * Copyright (C) 1998, 99, 2000, 01 Ralf Baechle + * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. + * Copyright (C) 2000, 01 MIPS Technologies, Inc. */ #ifndef _ASM_SEMAPHORE_H #define _ASM_SEMAPHORE_H +#include <linux/config.h> #include <asm/system.h> #include <asm/atomic.h> #include <linux/spinlock.h> #include <linux/wait.h> -#include <linux/config.h> #include <linux/rwsem.h> struct semaphore { @@ -94,6 +92,10 @@ __down(sem); } +/* + * Interruptible try to acquire a semaphore. If we obtained + * it, return zero. If we were interrupted, returns -EINTR + */ static inline int down_interruptible(struct semaphore * sem) { int ret = 0; @@ -108,6 +110,10 @@ #ifndef CONFIG_CPU_HAS_LLDSCD +/* + * Non-blockingly attempt to down() a semaphore. + * Returns zero if we acquired it + */ static inline int down_trylock(struct semaphore * sem) { int ret = 0; @@ -122,8 +128,7 @@ * down_trylock returns 0 on success, 1 if we failed to get the lock. * * We must manipulate count and waking simultaneously and atomically. - * Here, we this by using ll/sc on the pair of 32-bit words. This - * won't work on MIPS32 platforms, however, and must be rewritten. + * Here, we do this by using lld/scd on the pair of 32-bit words. * * Pseudocode: * @@ -158,12 +163,12 @@ "sll\t%2, %1, 0\n\t" "blez\t%2, 1f\n\t" "daddiu\t%1, %1, -1\n\t" - "b\t2f\n\t" - "1:\tdaddu\t%1, %1, %3\n" + "b\t2f\n" + "1:\tdaddu\t%1, %1, %3\n\t" "li\t%0, 1\n" "2:\tscd\t%1, %4\n\t" "beqz\t%1, 0b\n\t" - ".set mips0" + ".set\tmips0" : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) : "m"(*sem) : "memory"); diff -Nru a/include/asm-mips/sembuf.h b/include/asm-mips/sembuf.h --- a/include/asm-mips/sembuf.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/sembuf.h Fri Jun 27 14:19:55 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_SEMBUF_H #define _ASM_SEMBUF_H -/* +/* * The semid64_ds structure for the MIPS architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. diff -Nru a/include/asm-mips/serial.h b/include/asm-mips/serial.h --- a/include/asm-mips/serial.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips/serial.h Fri Jun 27 14:20:06 2003 @@ -7,7 +7,6 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #include <linux/config.h> -#include <asm/bootinfo.h> #include <asm/jazz.h> /* @@ -65,9 +64,9 @@ #ifdef CONFIG_MIPS_JAZZ #define _JAZZ_SERIAL_INIT(int, base) \ - { baud_base: JAZZ_BASE_BAUD, irq: int, flags: STD_COM_FLAGS, \ - iomem_base: (u8 *) base, iomem_reg_shift: 0, \ - io_type: SERIAL_IO_MEM } + { .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) base, .iomem_reg_shift = 0, \ + .io_type = SERIAL_IO_MEM } #define JAZZ_SERIAL_PORT_DEFNS \ _JAZZ_SERIAL_INIT(JAZZ_SERIAL1_IRQ, JAZZ_SERIAL1_BASE), \ _JAZZ_SERIAL_INIT(JAZZ_SERIAL2_IRQ, JAZZ_SERIAL2_BASE), @@ -85,6 +84,26 @@ #define ATLAS_SERIAL_PORT_DEFNS #endif +#ifdef CONFIG_MIPS_SEAD +#include <asm/mips-boards/sead.h> +#include <asm/mips-boards/seadint.h> +#define SEAD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, SEAD_BASE_BAUD, SEAD_UART0_REGS_BASE, SEADINT_UART0, STD_COM_FLAGS }, /* ttyS0 */ +#else +#define SEAD_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_MIPS_COBALT +#include <asm/cobalt/cobalt.h> +#define COBALT_BASE_BAUD (18432000 / 16) +#define COBALT_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, COBALT_BASE_BAUD, 0xc800000, COBALT_SERIAL_IRQ, STD_COM_FLAGS }, /* ttyS0 */ +#else +#define COBALT_SERIAL_PORT_DEFNS +#endif + /* * Both Galileo boards have the same UART mappings. */ @@ -92,12 +111,14 @@ #include <asm/galileo-boards/ev96100.h> #include <asm/galileo-boards/ev96100int.h> #define EV96100_SERIAL_PORT_DEFNS \ - { baud_base: EV96100_BASE_BAUD, port: EV96100_UART0_REGS_BASE, \ - irq: EV96100INT_UART_0, flags: STD_COM_FLAGS, type: 0x3, \ - iomem_base: EV96100_UART0_REGS_BASE }, \ - { baud_base: EV96100_BASE_BAUD, port: EV96100_UART1_REGS_BASE, \ - irq: EV96100INT_UART_0, flags: STD_COM_FLAGS, type: 0x3, \ - iomem_base: EV96100_UART1_REGS_BASE }, + { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = EV96100_UART0_REGS_BASE, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM }, \ + { .baud_base = EV96100_BASE_BAUD, .irq = EV96100INT_UART_0, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = EV96100_UART1_REGS_BASE, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM }, #else #define EV96100_SERIAL_PORT_DEFNS #endif @@ -107,16 +128,16 @@ #include <asm/it8172/it8172_int.h> #include <asm/it8712.h> #define ITE_SERIAL_PORT_DEFNS \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_UART_BASE), \ - irq: IT8172_UART_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, \ - { baud_base: (24000000/(16*13)), port: (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ - irq: IT8172_SERIRQ_4, flags: STD_COM_FLAGS, type: 0x3 }, \ + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ + .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ + { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ + .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .type = 0x3 }, \ /* Smart Card Reader 0 */ \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ - irq: IT8172_SCR0_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, \ + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ + .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ /* Smart Card Reader 1 */ \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ - irq: IT8172_SCR1_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ + .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, #else #define ITE_SERIAL_PORT_DEFNS #endif @@ -125,28 +146,55 @@ #include <asm/it8172/it8172.h> #include <asm/it8172/it8172_int.h> #define IVR_SERIAL_PORT_DEFNS \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_UART_BASE), \ - irq: IT8172_UART_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, \ + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ + .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ /* Smart Card Reader 1 */ \ - { baud_base: BASE_BAUD, port: (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ - irq: IT8172_SCR1_IRQ, flags: STD_COM_FLAGS, type: 0x3 }, + { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ + .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, #else #define IVR_SERIAL_PORT_DEFNS #endif -#ifdef CONFIG_AU1000_UART +#ifdef CONFIG_LASAT +#include <asm/lasat/serial.h> +#define LASAT_SERIAL_PORT_DEFNS \ + { .baud_base = LASAT_BASE_BAUD, .irq = LASATINT_UART, \ + .flags = STD_COM_FLAGS, \ + .port = LASAT_UART_REGS_BASE, /* Only for display */ \ + .iomem_base = (u8 *)KSEG1ADDR(LASAT_UART_REGS_BASE), \ + .iomem_reg_shift = LASAT_UART_REGS_SHIFT, .io_type = SERIAL_IO_MEM }, +#else +#define LASAT_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_SERIAL_AU1X00 #include <asm/au1000.h> -#define AU1000_SERIAL_PORT_DEFNS \ - { baud_base: 0, port: UART0_ADDR, irq: AU1000_UART0_INT, \ - flags: STD_COM_FLAGS, type: 1 }, \ - { baud_base: 0, port: UART1_ADDR, irq: AU1000_UART1_INT, \ - flags: STD_COM_FLAGS, type: 1 }, \ - { baud_base: 0, port: UART2_ADDR, irq: AU1000_UART2_INT, \ - flags: STD_COM_FLAGS, type: 1 }, \ - { baud_base: 0, port: UART3_ADDR, irq: AU1000_UART3_INT, \ - flags: STD_COM_FLAGS, type: 1 }, +#define AU1X00_SERIAL_PORT_DEFNS \ + { .baud_base = 0, .iomem_base = (u8 *)UART0_ADDR, \ + .irq = AU1000_UART0_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2, }, \ + { .baud_base = 0, .iomem_base = (u8 *)UART1_ADDR, \ + .irq = AU1000_UART1_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2 }, \ + { .baud_base = 0, .iomem_base = (u8 *)UART2_ADDR, \ + .irq = AU1000_UART2_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2}, \ + { .baud_base = 0, .iomem_base = (u8 *)UART3_ADDR, \ + .irq = AU1000_UART3_INT, .flags = STD_COM_FLAGS, \ + .iomem_reg_shift = 2}, +#else +#define AU1X00_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_TOSHIBA_JMR3927 +#include <asm/jmr3927/jmr3927.h> +#define TXX927_SERIAL_PORT_DEFNS \ + { .baud_base = JMR3927_BASE_BAUD, .port = UART0_ADDR, .irq = UART0_INT, \ + .flags = UART0_FLAGS, .type = 1 }, \ + { .baud_base = JMR3927_BASE_BAUD, .port = UART1_ADDR, .irq = UART1_INT, \ + .flags = UART1_FLAGS, .type = 1 }, #else -#define AU1000_SERIAL_PORT_DEFNS +#define TXX927_SERIAL_PORT_DEFNS #endif #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT @@ -237,36 +285,85 @@ #define OCELOT_SERIAL1_BASE 0xe0001020 #define _OCELOT_SERIAL_INIT(int, base) \ - { baud_base: OCELOT_BASE_BAUD, irq: int, flags: STD_COM_FLAGS, \ - iomem_base: (u8 *) base, iomem_reg_shift: 2, \ - io_type: SERIAL_IO_MEM } + { .baud_base = OCELOT_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM } #define MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ _OCELOT_SERIAL_INIT(OCELOT_SERIAL1_IRQ, OCELOT_SERIAL1_BASE) #else #define MOMENCO_OCELOT_SERIAL_PORT_DEFNS #endif +#ifdef CONFIG_MOMENCO_OCELOT_G +/* Ordinary NS16552 duart with a 20MHz crystal. */ +#define OCELOT_G_BASE_BAUD ( 20000000 / 16 ) + +#define OCELOT_G_SERIAL1_IRQ 4 +#if 0 +#define OCELOT_G_SERIAL1_BASE 0xe0001020 +#else +#define OCELOT_G_SERIAL1_BASE 0xfd000020 +#endif + +#define _OCELOT_G_SERIAL_INIT(int, base) \ + { .baud_base = OCELOT_G_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS,\ + .iomem_base = (u8 *) base, .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM } +#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \ + _OCELOT_G_SERIAL_INIT(OCELOT_G_SERIAL1_IRQ, OCELOT_G_SERIAL1_BASE) +#else +#define MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_MOMENCO_OCELOT_C +/* Ordinary NS16552 duart with a 20MHz crystal. */ +#define OCELOT_C_BASE_BAUD ( 20000000 / 16 ) + +#define OCELOT_C_SERIAL1_IRQ 80 +#define OCELOT_C_SERIAL1_BASE 0xfd000020 + +#define OCELOT_C_SERIAL2_IRQ 81 +#define OCELOT_C_SERIAL2_BASE 0xfd000000 + +#define _OCELOT_C_SERIAL_INIT(int, base) \ + { baud_base: OCELOT_C_BASE_BAUD, irq: int, flags: STD_COM_FLAGS,\ + iomem_base: (u8 *) base, iomem_reg_shift: 2, \ + io_type: SERIAL_IO_MEM } +#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ + _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL1_IRQ, OCELOT_C_SERIAL1_BASE), \ + _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL2_IRQ, OCELOT_C_SERIAL2_BASE) +#else +#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS +#endif + #ifdef CONFIG_DDB5477 +#include <asm/ddb5xxx/ddb5477.h> #define DDB5477_SERIAL_PORT_DEFNS \ - { baud_base: BASE_BAUD, irq: 12, flags: STD_COM_FLAGS, \ - iomem_base: (u8*)0xbfa04200, iomem_reg_shift: 3, \ - io_type: SERIAL_IO_MEM},\ - { baud_base: BASE_BAUD, irq: 28, flags: STD_COM_FLAGS, \ - iomem_base: (u8*)0xbfa04240, iomem_reg_shift: 3, \ - io_type: SERIAL_IO_MEM}, + { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART0, \ + .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04200, \ + .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, \ + { .baud_base = BASE_BAUD, .irq = VRC5477_IRQ_UART1, \ + .flags = STD_COM_FLAGS, .iomem_base = (u8*)0xbfa04240, \ + .iomem_reg_shift = 3, .io_type = SERIAL_IO_MEM}, #else #define DDB5477_SERIAL_PORT_DEFNS #endif -#define SERIAL_PORT_DFNS \ - IVR_SERIAL_PORT_DEFNS \ - ITE_SERIAL_PORT_DEFNS \ - ATLAS_SERIAL_PORT_DEFNS \ - EV96100_SERIAL_PORT_DEFNS \ - JAZZ_SERIAL_PORT_DEFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MOMENCO_OCELOT_SERIAL_PORT_DEFNS\ - AU1000_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ + IVR_SERIAL_PORT_DEFNS \ + ITE_SERIAL_PORT_DEFNS \ + ATLAS_SERIAL_PORT_DEFNS \ + SEAD_SERIAL_PORT_DEFNS \ + COBALT_SERIAL_PORT_DEFNS \ + LASAT_SERIAL_PORT_DEFNS \ + EV96100_SERIAL_PORT_DEFNS \ + JAZZ_SERIAL_PORT_DEFNS \ + STD_SERIAL_PORT_DEFNS \ + EXTRA_SERIAL_PORT_DEFNS \ + HUB6_SERIAL_PORT_DFNS \ + MOMENCO_OCELOT_SERIAL_PORT_DEFNS \ + MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS \ + MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ + AU1X00_SERIAL_PORT_DEFNS \ + TXX927_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS diff -Nru a/include/asm-mips/sgi/gio.h b/include/asm-mips/sgi/gio.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sgi/gio.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,86 @@ +/* + * 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. + * + * gio.h: Definitions for SGI GIO bus + * + * Copyright (C) 2002 Ladislav Michl + */ + +#ifndef _SGI_GIO_H +#define _SGI_GIO_H + +/* + * GIO bus addresses + * + * The Indigo and Indy have two GIO bus connectors. Indigo2 (all models) have + * three physical connectors, but only two slots, GFX and EXP0. + * + * There is 10MB of GIO address space for GIO64 slot devices + * slot# slot type address range size + * ----- --------- ----------------------- ----- + * 0 GFX 0x1f000000 - 0x1f3fffff 4MB + * 1 EXP0 0x1f400000 - 0x1f5fffff 2MB + * 2 EXP1 0x1f600000 - 0x1f9fffff 4MB + * + * There are un-slotted devices, HPC, I/O and misc devices, which are grouped + * into the HPC address space. + * - MISC 0x1fb00000 - 0x1fbfffff 1MB + * + * Following space is reserved and unused + * - RESERVED 0x18000000 - 0x1effffff 112MB + * + * GIO bus IDs + * + * Each GIO bus device identifies itself to the system by answering a + * read with an "ID" value. IDs are either 8 or 32 bits long. IDs less + * than 128 are 8 bits long, with the most significant 24 bits read from + * the slot undefined. + * + * 32-bit IDs are divided into + * bits 0:6 the product ID; ranges from 0x00 to 0x7F. + * bit 7 0=GIO Product ID is 8 bits wide + * 1=GIO Product ID is 32 bits wide. + * bits 8:15 manufacturer version for the product. + * bit 16 0=GIO32 and GIO32-bis, 1=GIO64. + * bit 17 0=no ROM present + * 1=ROM present on this board AND next three words + * space define the ROM. + * bits 18:31 up to manufacturer. + * + * IDs above 0x50/0xd0 are of 3rd party boards. + * + * 8-bit IDs + * 0x01 XPI low cost FDDI + * 0x02 GTR TokenRing + * 0x04 Synchronous ISDN + * 0x05 ATM board [*] + * 0x06 Canon Interface + * 0x07 16 bit SCSI Card [*] + * 0x08 JPEG (Double Wide) + * 0x09 JPEG (Single Wide) + * 0x0a XPI mez. FDDI device 0 + * 0x0b XPI mez. FDDI device 1 + * 0x0c SMPTE 259M Video [*] + * 0x0d Babblefish Compression [*] + * 0x0e E-Plex 8-port Ethernet + * 0x30 Lyon Lamb IVAS + * 0xb8 GIO 100BaseTX Fast Ethernet (gfe) + * + * [*] Device provide 32-bit ID. + * + */ + +#define GIO_ID(x) (x & 0x7f) +#define GIO_32BIT_ID 0x80 +#define GIO_REV(x) ((x >> 8) & 0xff) +#define GIO_64BIT_IFACE 0x10000 +#define GIO_ROM_PRESENT 0x20000 +#define GIO_VENDOR_CODE(x) ((x >> 18) & 0x3fff) + +#define GIO_SLOT_GFX_BASE 0x1f000000 +#define GIO_SLOT_EXP0_BASE 0x1f400000 +#define GIO_SLOT_EXP1_BASE 0x1f600000 + +#endif /* _SGI_GIO_H */ diff -Nru a/include/asm-mips/sgi/hpc3.h b/include/asm-mips/sgi/hpc3.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sgi/hpc3.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,316 @@ +/* + * 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. + * + * hpc3.h: Definitions for SGI HPC3 controller + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1998 Ralf Baechle + */ + +#ifndef _SGI_HPC3_H +#define _SGI_HPC3_H + +#include <linux/types.h> +#include <asm/page.h> + +/* An HPC DMA descriptor. */ +struct hpc_dma_desc { + u32 pbuf; /* physical address of data buffer */ + u32 cntinfo; /* counter and info bits */ +#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */ +#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */ +#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */ +#define HPCDMA_EORP 0x40000000 /* end of packet for rx */ +#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */ +#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */ +#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */ +#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */ +#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */ +#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */ + + u32 pnext; /* paddr of next hpc_dma_desc if any */ +}; + +/* The set of regs for each HPC3 PBUS DMA channel. */ +struct hpc3_pbus_dmacregs { + volatile u32 pbdma_bptr; /* pbus dma channel buffer ptr */ + volatile u32 pbdma_dptr; /* pbus dma channel desc ptr */ + u32 _unused0[0x1000/4 - 2]; /* padding */ + volatile u32 pbdma_ctrl; /* pbus dma channel control register has + * copletely different meaning for read + * compared with write */ + /* read */ +#define HPC3_PDMACTRL_INT 0x00000001 /* interrupt (cleared after read) */ +#define HPC3_PDMACTRL_ISACT 0x00000002 /* channel active */ + /* write */ +#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */ +#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */ +#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */ +#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */ +#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */ +#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */ +#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */ +#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */ +#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */ + + u32 _unused1[0x1000/4 - 1]; /* padding */ +}; + +/* The HPC3 SCSI registers, this does not include external ones. */ +struct hpc3_scsiregs { + volatile u32 cbptr; /* current dma buffer ptr, diagnostic use only */ + volatile u32 ndptr; /* next dma descriptor ptr */ + u32 _unused0[0x1000/4 - 2]; /* padding */ + volatile u32 bcd; /* byte count info */ +#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */ +#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */ +#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */ + + volatile u32 ctrl; /* control register */ +#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */ +#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */ +#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */ +#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */ +#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */ +#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */ +#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */ +#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */ + + volatile u32 gfptr; /* current GIO fifo ptr */ + volatile u32 dfptr; /* current device fifo ptr */ + volatile u32 dconfig; /* DMA configuration register */ +#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */ +#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */ +#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */ +#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */ +#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */ +#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */ +#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */ +#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */ +#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */ +#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */ + + volatile u32 pconfig; /* PIO configuration register */ +#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */ +#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */ +#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */ +#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */ +#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */ +#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */ +#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */ +#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */ + + u32 _unused1[0x1000/4 - 6]; /* padding */ +}; + +/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */ +struct hpc3_ethregs { + /* Receiver registers. */ + volatile u32 rx_cbptr; /* current dma buffer ptr, diagnostic use only */ + volatile u32 rx_ndptr; /* next dma descriptor ptr */ + u32 _unused0[0x1000/4 - 2]; /* padding */ + volatile u32 rx_bcd; /* byte count info */ +#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */ +#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */ +#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */ + + volatile u32 rx_ctrl; /* control register */ +#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */ +#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */ +#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */ +#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */ +#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */ +#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */ +#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */ + + volatile u32 rx_gfptr; /* current GIO fifo ptr */ + volatile u32 rx_dfptr; /* current device fifo ptr */ + u32 _unused1; /* padding */ + volatile u32 rx_reset; /* reset register */ +#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */ +#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */ +#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */ + + volatile u32 rx_dconfig; /* DMA configuration register */ +#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */ +#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */ +#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */ +#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */ +#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */ +#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */ +#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */ +#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */ + + volatile u32 rx_pconfig; /* PIO configuration register */ +#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ +#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ +#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ +#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ + + u32 _unused2[0x1000/4 - 8]; /* padding */ + + /* Transmitter registers. */ + volatile u32 tx_cbptr; /* current dma buffer ptr, diagnostic use only */ + volatile u32 tx_ndptr; /* next dma descriptor ptr */ + u32 _unused3[0x1000/4 - 2]; /* padding */ + volatile u32 tx_bcd; /* byte count info */ +#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */ +#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */ +#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */ +#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */ +#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */ + + volatile u32 tx_ctrl; /* control register */ +#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */ +#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */ +#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */ +#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* DMA channel endian mode, 1=little 0=big */ +#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */ +#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */ + + volatile u32 tx_gfptr; /* current GIO fifo ptr */ + volatile u32 tx_dfptr; /* current device fifo ptr */ + u32 _unused4[0x1000/4 - 4]; /* padding */ +}; + +struct hpc3_regs { + /* First regs for the PBUS 8 dma channels. */ + struct hpc3_pbus_dmacregs pbdma[8]; + + /* Now the HPC scsi registers, we get two scsi reg sets. */ + struct hpc3_scsiregs scsi_chan0, scsi_chan1; + + /* The SEEQ hpc3 ethernet dma/control registers. */ + struct hpc3_ethregs ethregs; + + /* Here are where the hpc3 fifo's can be directly accessed + * via PIO accesses. Under normal operation we never stick + * our grubby paws in here so it's just padding. */ + u32 _unused0[0x18000/4]; + + /* HPC3 irq status regs. Due to a peculiar bug you need to + * look at two different register addresses to get at all of + * the status bits. The first reg can only reliably report + * bits 4:0 of the status, and the second reg can only + * reliably report bits 9:5 of the hpc3 irq status. I told + * you it was a peculiar bug. ;-) + */ + volatile u32 istat0; /* Irq status, only bits <4:0> reliable. */ +#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */ +#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */ +#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */ + + volatile u32 gio_misc; /* GIO misc control bits. */ +#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */ +#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */ + + volatile u32 eeprom; /* EEPROM data reg. */ +#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */ +#define HPC3_EEPROM_CSEL 0x02 /* Chip select */ +#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */ +#define HPC3_EEPROM_DATO 0x08 /* Data out */ +#define HPC3_EEPROM_DATI 0x10 /* Data in */ + + volatile u32 istat1; /* Irq status, only bits <9:5> reliable. */ + volatile u32 gio_estat; /* GIO error interrupt status reg. */ +#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */ +#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */ +#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */ + + u32 _unused1[0x14000/4 - 5]; /* padding */ + + /* Now direct PIO per-HPC3 peripheral access to external regs. */ + volatile u32 scsi0_ext[256]; /* SCSI channel 0 external regs */ + u32 _unused2[0x7c00/4]; + volatile u32 scsi1_ext[256]; /* SCSI channel 1 external regs */ + u32 _unused3[0x7c00/4]; + volatile u32 eth_ext[320]; /* Ethernet external registers */ + u32 _unused4[0x3b00/4]; + + /* Per-peripheral device external registers and DMA/PIO control. */ + volatile u32 pbus_extregs[16][256]; + volatile u32 pbus_dmacfg[8][128]; + /* Cycles to spend in D3 for reads */ +#define HPC3_DMACFG_D3R_MASK 0x00000001 +#define HPC3_DMACFG_D3R_SHIFT 0 + /* Cycles to spend in D4 for reads */ +#define HPC3_DMACFG_D4R_MASK 0x0000001e +#define HPC3_DMACFG_D4R_SHIFT 1 + /* Cycles to spend in D5 for reads */ +#define HPC3_DMACFG_D5R_MASK 0x000001e0 +#define HPC3_DMACFG_D5R_SHIFT 5 + /* Cycles to spend in D3 for writes */ +#define HPC3_DMACFG_D3W_MASK 0x00000200 +#define HPC3_DMACFG_D3W_SHIFT 9 + /* Cycles to spend in D4 for writes */ +#define HPC3_DMACFG_D4W_MASK 0x00003c00 +#define HPC3_DMACFG_D4W_SHIFT 10 + /* Cycles to spend in D5 for writes */ +#define HPC3_DMACFG_D5W_MASK 0x0003c000 +#define HPC3_DMACFG_D5W_SHIFT 14 + /* Enable 16-bit DMA access mode */ +#define HPC3_DMACFG_DS16 0x00040000 + /* Places halfwords on high 16 bits of bus */ +#define HPC3_DMACFG_EVENHI 0x00080000 + /* Make this device real time */ +#define HPC3_DMACFG_RTIME 0x00200000 + /* 5 bit burst count for DMA device */ +#define HPC3_DMACFG_BURST_MASK 0x07c00000 +#define HPC3_DMACFG_BURST_SHIFT 22 + /* Use live pbus_dreq unsynchronized signal */ +#define HPC3_DMACFG_DRQLIVE 0x08000000 + volatile u32 pbus_piocfg[16][64]; + /* Cycles to spend in P2 state for reads */ +#define HPC3_PIOCFG_P2R_MASK 0x00001 +#define HPC3_PIOCFG_P2R_SHIFT 0 + /* Cycles to spend in P3 state for reads */ +#define HPC3_PIOCFG_P3R_MASK 0x0001e +#define HPC3_PIOCFG_P3R_SHIFT 1 + /* Cycles to spend in P4 state for reads */ +#define HPC3_PIOCFG_P4R_MASK 0x001e0 +#define HPC3_PIOCFG_P4R_SHIFT 5 + /* Cycles to spend in P2 state for writes */ +#define HPC3_PIOCFG_P2W_MASK 0x00200 +#define HPC3_PIOCFG_P2W_SHIFT 9 + /* Cycles to spend in P3 state for writes */ +#define HPC3_PIOCFG_P3W_MASK 0x03c00 +#define HPC3_PIOCFG_P3W_SHIFT 10 + /* Cycles to spend in P4 state for writes */ +#define HPC3_PIOCFG_P4W_MASK 0x3c000 +#define HPC3_PIOCFG_P4W_SHIFT 14 + /* Enable 16-bit PIO accesses */ +#define HPC3_PIOCFG_DS16 0x40000 + /* Place even address bits in bits <15:8> */ +#define HPC3_PIOCFG_EVENHI 0x80000 + + /* PBUS PROM control regs. */ + volatile u32 pbus_promwe; /* PROM write enable register */ +#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */ + + u32 _unused5[0x0800/4 - 1]; + volatile u32 pbus_promswap; /* Chip select swap reg */ +#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */ + + u32 _unused6[0x0800/4 - 1]; + volatile u32 pbus_gout; /* PROM general purpose output reg */ +#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */ + + u32 _unused7[0x1000/4 - 1]; + volatile u32 rtcregs[14]; /* Dallas clock registers */ + u32 _unused8[50]; + volatile u32 bbram[8192-50-14]; /* Battery backed ram */ +}; + +/* + * It is possible to have two HPC3's within the address space on + * one machine, though only having one is more likely on an Indy. + */ +extern struct hpc3_regs *hpc3c0, *hpc3c1; +#define HPC3_CHIP0_BASE 0x1fb80000 /* physical */ +#define HPC3_CHIP1_BASE 0x1fb00000 /* physical */ + +extern void sgihpc_init(void); + +#endif /* _SGI_HPC3_H */ diff -Nru a/include/asm-mips/sgi/ioc.h b/include/asm-mips/sgi/ioc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sgi/ioc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,209 @@ +/* + * 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. + * + * ioc.h: Definitions for SGI I/O Controller + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle + * Copyright (C) 2001, 2003 Ladislav Michl + */ + +#ifndef _SGI_IOC_H +#define _SGI_IOC_H + +#include <linux/types.h> + +/* + * All registers are 8-bit wide alligned on 32-bit boundary. Bad things + * happen if you try word access them. You have been warned. + */ + +struct sgioc_pport_regs { + u8 _data[3]; + volatile u8 data; + u8 _ctrl[3]; + volatile u8 ctrl; +#define SGIOC_PCTRL_STROBE 0x01 +#define SGIOC_PCTRL_AFD 0x02 +#define SGIOC_PCTRL_INIT 0x04 +#define SGIOC_PCTRL_SLIN 0x08 +#define SGIOC_PCTRL_DIRECTION 0x20 +#define SGIOC_PCTRL_SEL 0x40 + u8 _status[3]; + volatile u8 status; +#define SGIOC_PSTAT_DEVID 0x03 +#define SGIOC_PSTAT_NOINK 0x04 +#define SGIOC_PSTAT_ERROR 0x08 +#define SGIOC_PSTAT_ONLINE 0x10 +#define SGIOC_PSTAT_PE 0x20 +#define SGIOC_PSTAT_ACK 0x40 +#define SGIOC_PSTAT_BUSY 0x80 + u8 _dmactrl[3]; + volatile u8 dmactrl; + u8 _intrstat[3]; + volatile u8 intrstat; + u8 _intrmask[3]; + volatile u8 intrmask; + u8 _timer1[3]; + volatile u8 timer1; + u8 _timer2[3]; + volatile u8 timer2; + u8 _timer3[3]; + volatile u8 timer3; + u8 _timer4[3]; + volatile u8 timer4; +}; + +struct sgioc_uart_regs { + u8 _ctrl1[3]; + volatile u8 ctrl1; + u8 _data1[3]; + volatile u8 data1; + u8 _ctrl2[3]; + volatile u8 ctrl2; + u8 _data2[3]; + volatile u8 data2; +}; + +struct sgioc_keyb_regs { + u8 _data[3]; + volatile u8 data; + u8 _command[3]; + volatile u8 command; +}; + +struct sgint_regs { + u8 _istat0[3]; + volatile u8 istat0; /* Interrupt status zero */ +#define SGINT_ISTAT0_FFULL 0x01 +#define SGINT_ISTAT0_SCSI0 0x02 +#define SGINT_ISTAT0_SCSI1 0x04 +#define SGINT_ISTAT0_ENET 0x08 +#define SGINT_ISTAT0_GFXDMA 0x10 +#define SGINT_ISTAT0_PPORT 0x20 +#define SGINT_ISTAT0_HPC2 0x40 +#define SGINT_ISTAT0_LIO2 0x80 + u8 _imask0[3]; + volatile u8 imask0; /* Interrupt mask zero */ + u8 _istat1[3]; + volatile u8 istat1; /* Interrupt status one */ +#define SGINT_ISTAT1_ISDNI 0x01 +#define SGINT_ISTAT1_PWR 0x02 +#define SGINT_ISTAT1_ISDNH 0x04 +#define SGINT_ISTAT1_LIO3 0x08 +#define SGINT_ISTAT1_HPC3 0x10 +#define SGINT_ISTAT1_AFAIL 0x20 +#define SGINT_ISTAT1_VIDEO 0x40 +#define SGINT_ISTAT1_GIO2 0x80 + u8 _imask1[3]; + volatile u8 imask1; /* Interrupt mask one */ + u8 _vmeistat[3]; + volatile u8 vmeistat; /* VME interrupt status */ + u8 _cmeimask0[3]; + volatile u8 cmeimask0; /* VME interrupt mask zero */ + u8 _cmeimask1[3]; + volatile u8 cmeimask1; /* VME interrupt mask one */ + u8 _cmepol[3]; + volatile u8 cmepol; /* VME polarity */ + u8 _tclear[3]; + volatile u8 tclear; + u8 _errstat[3]; + volatile u8 errstat; /* Error status reg, reserved on INT2 */ + u32 _unused0[2]; + u8 _tcnt0[3]; + volatile u8 tcnt0; /* counter 0 */ + u8 _tcnt1[3]; + volatile u8 tcnt1; /* counter 1 */ + u8 _tcnt2[3]; + volatile u8 tcnt2; /* counter 2 */ + u8 _tcword[3]; + volatile u8 tcword; /* control word */ +#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */ +#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */ +#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */ +#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */ +#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */ +#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */ +#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */ +#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */ +#define SGINT_TCWORD_CMASK 0x30 /* Command mask */ +#define SGINT_TCWORD_CLAT 0x00 /* Latch command */ +#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */ +#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */ +#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */ +#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */ +#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */ +#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */ +#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */ +}; + +#define SGINT_TCSAMP_COUNTER 10255 + +/* We need software copies of these because they are write only. */ +extern u8 sgi_ioc_reset, sgi_ioc_write; + +struct sgioc_regs { + struct sgioc_pport_regs pport; + u32 _unused0[2]; + struct sgioc_uart_regs serport; + struct sgioc_keyb_regs kbdmouse; + u8 _gcsel[3]; + volatile u8 gcsel; + u8 _genctrl[3]; + volatile u8 genctrl; + u8 _panel[3]; + volatile u8 panel; +#define SGIOC_PANEL_POWERON 0x01 +#define SGIOC_PANEL_POWERINTR 0x02 +#define SGIOC_PANEL_VOLDNINTR 0x10 +#define SGIOC_PANEL_VOLDNHOLD 0x20 +#define SGIOC_PANEL_VOLUPINTR 0x40 +#define SGIOC_PANEL_VOLUPHOLD 0x80 + u32 _unused1; + u8 _sysid[3]; + volatile u8 sysid; +#define SGIOC_SYSID_FULLHOUSE 0x01 +#define SGIOC_SYSID_BOARDREV(x) ((x & 0xe0) > 5) +#define SGIOC_SYSID_CHIPREV(x) ((x & 0x1e) > 1) + u32 _unused2; + u8 _read[3]; + volatile u8 read; + u32 _unused3; + u8 _dmasel[3]; + volatile u8 dmasel; +#define SGIOC_DMASEL_SCLK10MHZ 0x00 /* use 10MHZ serial clock */ +#define SGIOC_DMASEL_ISDNB 0x01 /* enable isdn B */ +#define SGIOC_DMASEL_ISDNA 0x02 /* enable isdn A */ +#define SGIOC_DMASEL_PPORT 0x04 /* use parallel DMA */ +#define SGIOC_DMASEL_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */ +#define SGIOC_DMASEL_SCLKEXT 0x20 /* use external serial clock */ + u32 _unused4; + u8 _reset[3]; + volatile u8 reset; +#define SGIOC_RESET_PPORT 0x01 /* 0=parport reset, 1=nornal */ +#define SGIOC_RESET_KBDMOUSE 0x02 /* 0=kbdmouse reset, 1=normal */ +#define SGIOC_RESET_EISA 0x04 /* 0=eisa reset, 1=normal */ +#define SGIOC_RESET_ISDN 0x08 /* 0=isdn reset, 1=normal */ +#define SGIOC_RESET_LC0OFF 0x10 /* guiness: turn led off (red, else green) */ +#define SGIOC_RESET_LC1OFF 0x20 /* guiness: turn led off (green, else amber) */ + u32 _unused5; + u8 _write[3]; + volatile u8 write; +#define SGIOC_WRITE_NTHRESH 0x01 /* use 4.5db threshhold */ +#define SGIOC_WRITE_TPSPEED 0x02 /* use 100ohm TP speed */ +#define SGIOC_WRITE_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ +#define SGIOC_WRITE_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ +#define SGIOC_WRITE_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */ +#define SGIOC_WRITE_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */ +#define SGIOC_WRITE_MLO 0x40 /* 1=4.75V 0=+5V */ +#define SGIOC_WRITE_MHI 0x80 /* 1=5.25V 0=+5V */ + u32 _unused6; + struct sgint_regs int3; +}; + +extern struct sgioc_regs *sgioc; +extern struct sgint_regs *sgint; + +#endif diff -Nru a/include/asm-mips/sgi/ip22.h b/include/asm-mips/sgi/ip22.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sgi/ip22.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,77 @@ +/* + * 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. + * + * ip22.h: Definitions for SGI IP22 machines + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle + */ + +#ifndef _SGI_IP22_H +#define _SGI_IP22_H + +/* + * These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an SGI machine. HPC DMA and MC DMA interrups + * are not supported this way. Driver is supposed to allocate HPC/MC + * interrupt as shareable and then look to proper status bit (see + * HAL2 driver). This will prevent many complications, trust me ;-) + */ + +#include <asm/sgi/ioc.h> + +#define SGINT_EISA 0 /* INDIGO 2 has 16 EISA irq levels */ +#define SGINT_CPU 16 /* MIPS CPU define 8 interrupt sources */ +#define SGINT_LOCAL0 24 /* INDY has 8 local0 irq levels */ +#define SGINT_LOCAL1 32 /* INDY has 8 local1 irq levels */ +#define SGINT_LOCAL2 40 /* INDY has 8 local2 vectored irq levels */ +#define SGINT_LOCAL3 48 /* INDY has 8 local3 vectored irq levels */ +#define SGINT_END 56 /* End of 'spaces' */ + +/* + * Individual interrupt definitions for the Indy and Indigo2 + */ + +#define SGI_SOFT_0_IRQ SGINT_CPU + 0 +#define SGI_SOFT_1_IRQ SGINT_CPU + 1 +#define SGI_LOCAL_0_IRQ SGINT_CPU + 2 +#define SGI_LOCAL_1_IRQ SGINT_CPU + 3 +#define SGI_8254_0_IRQ SGINT_CPU + 4 +#define SGI_8254_1_IRQ SGINT_CPU + 5 +#define SGI_BUSERR_IRQ SGINT_CPU + 6 +#define SGI_TIMER_IRQ SGINT_CPU + 7 + +#define SGI_FIFO_IRQ SGINT_LOCAL0 + 0 /* FIFO full */ +#define SGI_GIO_0_IRQ SGI_FIFO_IRQ /* GIO-0 */ +#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */ +#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */ +#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */ +#define SGI_MCDMA_IRQ SGINT_LOCAL0 + 4 /* MC DMA done */ +#define SGI_PARPORT_IRQ SGINT_LOCAL0 + 5 /* Parallel port */ +#define SGI_GIO_1_IRQ SGINT_LOCAL0 + 6 /* GE / GIO-1 / 2nd-HPC */ +#define SGI_MAP_0_IRQ SGINT_LOCAL0 + 7 /* Mappable interrupt 0 */ + +#define SGI_GPL0_IRQ SGINT_LOCAL1 + 0 /* General Purpose LOCAL1_N<0> */ +#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */ +#define SGI_GPL2_IRQ SGINT_LOCAL1 + 2 /* General Purpose LOCAL1_N<2> */ +#define SGI_MAP_1_IRQ SGINT_LOCAL1 + 3 /* Mappable interrupt 1 */ +#define SGI_HPCDMA_IRQ SGINT_LOCAL1 + 4 /* HPC DMA done */ +#define SGI_ACFAIL_IRQ SGINT_LOCAL1 + 5 /* AC fail */ +#define SGI_VINO_IRQ SGINT_LOCAL1 + 6 /* Indy VINO */ +#define SGI_GIO_2_IRQ SGINT_LOCAL1 + 7 /* Vert retrace / GIO-2 */ + +/* Mapped interrupts. These interrupts may be mapped to either 0, or 1 */ +#define SGI_VERT_IRQ SGINT_LOCAL2 + 0 /* INT3: newport vertical status */ +#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */ +#define SGI_KEYBD_IRQ SGINT_LOCAL2 + 4 /* keyboard */ +#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */ + +#define ip22_is_fullhouse() (sgioc->sysid & SGIOC_SYSID_FULLHOUSE) + +extern unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg); +extern unsigned short ip22_nvram_read(int reg); + +#endif diff -Nru a/include/asm-mips/sgi/mc.h b/include/asm-mips/sgi/mc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sgi/mc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,231 @@ +/* + * 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. + * + * mc.h: Definitions for SGI Memory Controller + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ + +#ifndef _SGI_MC_H +#define _SGI_MC_H + +struct sgimc_regs { + u32 _unused0; + volatile u32 cpuctrl0; /* CPU control register 0, readwrite */ +#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */ +#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */ +#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */ +#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */ +#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */ +#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */ +#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */ +#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */ +#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */ +#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */ +#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */ +#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */ +#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */ +#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */ +#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */ +#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */ +#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */ +#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */ +#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */ + u32 _unused1; + volatile u32 cpuctrl1; /* CPU control register 1, readwrite */ +#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */ +#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */ +#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */ +#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */ +#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */ + + u32 _unused2; + volatile u32 watchdogt; /* Watchdog reg rdonly, write clears */ + + u32 _unused3; + volatile u32 systemid; /* MC system ID register, readonly */ +#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */ +#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */ + + u32 _unused4[3]; + volatile u32 divider; /* Divider reg for RPSS */ + + u32 _unused5; + volatile u32 eeprom; /* EEPROM byte reg for r4k */ +#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */ +#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */ +#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */ +#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */ +#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */ + + u32 _unused6[3]; + volatile u32 rcntpre; /* Preload refresh counter */ + + u32 _unused7; + volatile u32 rcounter; /* Readonly refresh counter */ + + u32 _unused8[13]; + volatile u32 giopar; /* Parameter word for GIO64 */ +#define SGIMC_GIOPAR_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */ +#define SGIMC_GIOPAR_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */ +#define SGIMC_GIOPAR_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */ +#define SGIMC_GIOPAR_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */ +#define SGIMC_GIOPAR_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */ +#define SGIMC_GIOPAR_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */ +#define SGIMC_GIOPAR_RTIMEGFX 0x00000040 /* GFX device has realtime attr */ +#define SGIMC_GIOPAR_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */ +#define SGIMC_GIOPAR_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */ +#define SGIMC_GIOPAR_MASTEREISA 0x00000200 /* EISA bus can act as bus master */ +#define SGIMC_GIOPAR_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */ +#define SGIMC_GIOPAR_MASTERGFX 0x00000800 /* GFX can act as a bus master */ +#define SGIMC_GIOPAR_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */ +#define SGIMC_GIOPAR_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */ +#define SGIMC_GIOPAR_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */ +#define SGIMC_GIOPAR_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */ + + u32 _unused9; + volatile u32 cputp; /* CPU bus arb time period */ + + u32 _unused10[3]; + volatile u32 lbursttp; /* Time period for long bursts */ + + /* MC chip can drive up to 4 bank 4 SIMMs each. All SIMMs in bank must + * be the same size. The size encoding for supported SIMMs is bellow */ + u32 _unused11[9]; + volatile u32 mconfig0; /* Memory config register zero */ + u32 _unused12; + volatile u32 mconfig1; /* Memory config register one */ +#define SGIMC_MCONFIG_BASEADDR 0x000000ff /* Base address of bank*/ +#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */ +#define SGIMC_MCONFIG_BVALID 0x00002000 /* Bank is valid */ +#define SGIMC_MCONFIG_SBANKS 0x00004000 /* Number of subbanks */ + + u32 _unused13; + volatile u32 cmacc; /* Mem access config for CPU */ + u32 _unused14; + volatile u32 gmacc; /* Mem access config for GIO */ + + /* This define applies to both cmacc and gmacc registers above. */ +#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */ + + /* Error address/status regs from GIO and CPU perspectives. */ + u32 _unused15; + volatile u32 cerr; /* Error address reg for CPU */ + u32 _unused16; + volatile u32 cstat; /* Status reg for CPU */ +#define SGIMC_CSTAT_RD 0x00000100 /* read parity error */ +#define SGIMC_CSTAT_PAR 0x00000200 /* CPU parity error */ +#define SGIMC_CSTAT_ADDR 0x00000400 /* memory bus error bad addr */ +#define SGIMC_CSTAT_SYSAD_PAR 0x00000800 /* sysad parity error */ +#define SGIMC_CSTAT_SYSCMD_PAR 0x00001000 /* syscmd parity error */ +#define SGIMC_CSTAT_BAD_DATA 0x00002000 /* bad data identifier */ +#define SGIMC_CSTAT_PAR_MASK 0x00001f00 /* parity error mask */ +#define SGIMC_CSTAT_RD_PAR (SGIMC_CSTAT_RD | SGIMC_CSTAT_PAR) + + u32 _unused17; + volatile u32 gerr; /* Error address reg for GIO */ + u32 _unused18; + volatile u32 gstat; /* Status reg for GIO */ +#define SGIMC_GSTAT_RD 0x00000100 /* read parity error */ +#define SGIMC_GSTAT_WR 0x00000200 /* write parity error */ +#define SGIMC_GSTAT_TIME 0x00000400 /* GIO bus timed out */ +#define SGIMC_GSTAT_PROM 0x00000800 /* write to PROM when PROM_EN not set */ +#define SGIMC_GSTAT_ADDR 0x00001000 /* parity error on addr cycle */ +#define SGIMC_GSTAT_BC 0x00002000 /* parity error on byte count cycle */ +#define SGIMC_GSTAT_PIO_RD 0x00004000 /* read data parity on pio */ +#define SGIMC_GSTAT_PIO_WR 0x00008000 /* write data parity on pio */ + + /* Special hard bus locking registers. */ + u32 _unused19; + volatile u32 syssembit; /* Uni-bit system semaphore */ + u32 _unused20; + volatile u32 mlock; /* Global GIO memory access lock */ + u32 _unused21; + volatile u32 elock; /* Locks EISA from GIO accesses */ + + /* GIO dma control registers. */ + u32 _unused22[15]; + volatile u32 gio_dma_trans; /* DMA mask to translation GIO addrs */ + u32 _unused23; + volatile u32 gio_dma_sbits; /* DMA GIO addr substitution bits */ + u32 _unused24; + volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */ + u32 _unused25; + volatile u32 dma_ctrl; /* Main DMA control reg */ + + /* DMA TLB entry 0 */ + u32 _unused26[5]; + volatile u32 dtlb_hi0; + u32 _unused27; + volatile u32 dtlb_lo0; + + /* DMA TLB entry 1 */ + u32 _unused28; + volatile u32 dtlb_hi1; + u32 _unused29; + volatile u32 dtlb_lo1; + + /* DMA TLB entry 2 */ + u32 _unused30; + volatile u32 dtlb_hi2; + u32 _unused31; + volatile u32 dtlb_lo2; + + /* DMA TLB entry 3 */ + u32 _unused32; + volatile u32 dtlb_hi3; + u32 _unused33; + volatile u32 dtlb_lo3; + + u32 _unused34[0x0392]; + + u32 _unused35; + volatile u32 rpsscounter; /* Chirps at 100ns */ + + u32 _unused36[0x1000/4-2*4]; + + u32 _unused37; + volatile u32 maddronly; /* Address DMA goes at */ + u32 _unused38; + volatile u32 maddrpdeflts; /* Same as above, plus set defaults */ + u32 _unused39; + volatile u32 dmasz; /* DMA count */ + u32 _unused40; + volatile u32 ssize; /* DMA stride size */ + u32 _unused41; + volatile u32 gmaddronly; /* Set GIO DMA but don't start trans */ + u32 _unused42; + volatile u32 dmaddnpgo; /* Set GIO DMA addr + start transfer */ + u32 _unused43; + volatile u32 dmamode; /* DMA mode config bit settings */ + u32 _unused44; + volatile u32 dmaccount; /* Zoom and byte count for DMA */ + u32 _unused45; + volatile u32 dmastart; /* Pedal to the metal. */ + u32 _unused46; + volatile u32 dmarunning; /* DMA op is in progress */ + u32 _unused47; + volatile u32 maddrdefstart; /* Set dma addr, defaults, and kick it */ +}; + +extern struct sgimc_regs *sgimc; +#define SGIMC_BASE 0x1fa00000 /* physical */ + +/* Base location of the two ram banks found in IP2[0268] machines. */ +#define SGIMC_SEG0_BADDR 0x08000000 +#define SGIMC_SEG1_BADDR 0x20000000 + +/* Maximum size of the above banks are per machine. */ +#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */ +#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */ +#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ + +extern void sgimc_init(void); + +#endif /* _SGI_MC_H */ diff -Nru a/include/asm-mips/sgi/sgi.h b/include/asm-mips/sgi/sgi.h --- a/include/asm-mips/sgi/sgi.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/sgi/sgi.h Fri Jun 27 14:19:59 2003 @@ -1,28 +1,33 @@ -/* $Id: sgi.h,v 1.1.1.1 1997/06/01 03:17:12 ralf Exp $ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * * sgi.h: Definitions specific to SGI machines. * * Copyright (C) 1996 David S. Miller (dm@sgi.com) */ -#ifndef _MIPS_SGI_H -#define _MIPS_SGI_H +#ifndef _ASM_SGI_SGI_H +#define _ASM_SGI_SGI_H /* UP=UniProcessor MP=MultiProcessor(capable) */ enum sgi_mach { - ip4, /* R2k UP */ - ip5, /* R2k MP */ - ip6, /* R3k UP */ - ip7, /* R3k MP */ - ip9, /* R3k UP */ - ip12, /* R3kA UP, Indigo */ - ip15, /* R3kA MP */ - ip17, /* R4K UP */ - ip19, /* R4K MP */ - ip20, /* R4K UP, Indigo */ - ip21, /* TFP MP */ - ip22, /* R4x00 UP, Indigo2 */ - ip25, /* R10k MP */ - ip26, /* TFP UP, Indigo2 */ - ip28, /* R10k UP, Indigo2 */ + ip4, /* R2k UP */ + ip5, /* R2k MP */ + ip6, /* R3k UP */ + ip7, /* R3k MP */ + ip9, /* R3k UP */ + ip12, /* R3kA UP, Indigo */ + ip15, /* R3kA MP */ + ip17, /* R4K UP */ + ip19, /* R4K MP */ + ip20, /* R4K UP, Indigo */ + ip21, /* TFP MP */ + ip22, /* R4x00 UP, Indigo2 */ + ip25, /* R10k MP */ + ip26, /* TFP UP, Indigo2 */ + ip27, /* R10k MP, R12k MP, Origin */ + ip28, /* R10k UP, Indigo2 */ ip30, ip32, }; @@ -39,4 +44,4 @@ #define SGI_MSB(regaddr) ((regaddr) | 0x3) #endif -#endif /* !(_MIPS_SGI_H) */ +#endif /* _ASM_SGI_SGI_H */ diff -Nru a/include/asm-mips/sgi/sgihpc.h b/include/asm-mips/sgi/sgihpc.h --- a/include/asm-mips/sgi/sgihpc.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,372 +0,0 @@ -/* $Id: sgihpc.h,v 1.2 1999/12/06 23:13:21 ralf Exp $ - * - * sgihpc.h: Various HPC I/O controller defines. The HPC is basically - * the approximate functional equivalent of the Sun SYSIO - * on SGI INDY machines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org) - */ -#ifndef _MIPS_SGIHPC_H -#define _MIPS_SGIHPC_H - -#include <asm/page.h> - -extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */ -extern int sgi_guiness; /* GUINESS or FULLHOUSE machine. */ -extern int sgi_boardid; /* Board revision. */ - -/* An HPC dma descriptor. */ -struct hpc_dma_desc { - unsigned int pbuf; /* physical address of data buffer */ - unsigned int cntinfo; /* counter and info bits */ -#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */ -#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */ -#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */ -#define HPCDMA_EORP 0x40000000 /* end of packet for rx */ -#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */ -#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */ -#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */ -#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */ -#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */ -#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */ - - unsigned int pnext; /* paddr of next hpc_dma_desc if any */ -}; - -typedef volatile unsigned int hpcreg; - -/* HPC1 stuff. */ - -/* HPC3 stuff. */ - -/* The set of regs for each HPC3 pbus dma channel. */ -struct hpc3_pbus_dmacregs { - hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */ - hpcreg pbdma_dptr; /* pbus dma channel desc ptr */ - char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg pbdma_ctrl; /* pbus dma channel control reg */ -#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */ -#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */ -#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */ -#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */ -#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */ -#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */ -#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */ -#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */ -#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */ - - char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */ -}; - -/* The HPC3 scsi registers, this does not include external ones. */ -struct hpc3_scsiregs { - hpcreg cbptr; /* current dma buffer ptr, diagnostic use only */ - hpcreg ndptr; /* next dma descriptor ptr */ - char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg bcd; /* byte count info */ -#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */ -#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */ -#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */ - - hpcreg ctrl; /* control register */ -#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */ -#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */ -#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */ -#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */ -#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */ -#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */ -#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */ -#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */ - - hpcreg gfptr; /* current GIO fifo ptr */ - hpcreg dfptr; /* current device fifo ptr */ - hpcreg dconfig; /* DMA configuration register */ -#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */ -#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */ -#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */ -#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */ -#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */ -#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */ -#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */ -#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */ -#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */ -#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */ - - hpcreg pconfig; /* PIO configuration register */ -#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */ -#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */ -#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */ -#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */ -#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */ -#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */ -#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */ -#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */ - - char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */ -}; - -/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */ -struct hpc3_ethregs { - /* Receiver registers. */ - hpcreg rx_cbptr; /* current dma buffer ptr, diagnostic use only */ - hpcreg rx_ndptr; /* next dma descriptor ptr */ - char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg rx_bcd; /* byte count info */ -#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */ -#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */ -#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */ - - hpcreg rx_ctrl; /* control register */ -#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */ -#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */ -#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */ -#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */ -#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */ -#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */ -#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */ - - hpcreg rx_gfptr; /* current GIO fifo ptr */ - hpcreg rx_dfptr; /* current device fifo ptr */ - hpcreg _unused2; /* padding */ - hpcreg rx_reset; /* reset register */ -#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */ -#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */ -#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */ - - hpcreg rx_dconfig; /* DMA configuration register */ -#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */ -#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */ -#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */ -#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */ -#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */ -#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */ -#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */ -#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */ - - hpcreg rx_pconfig; /* PIO configuration register */ -#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ -#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ -#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ -#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ - - char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */ - - /* Transmitter registers. */ - hpcreg tx_cbptr; /* current dma buffer ptr, diagnostic use only */ - hpcreg tx_ndptr; /* next dma descriptor ptr */ - char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg tx_bcd; /* byte count info */ -#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */ -#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */ -#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */ -#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */ -#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */ - - hpcreg tx_ctrl; /* control register */ -#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */ -#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */ -#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */ -#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */ -#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */ -#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */ - - hpcreg tx_gfptr; /* current GIO fifo ptr */ - hpcreg tx_dfptr; /* current device fifo ptr */ - char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */ -}; - -struct hpc3_regs { - /* First regs for the PBUS 8 dma channels. */ - struct hpc3_pbus_dmacregs pbdma[8]; - - /* Now the HPC scsi registers, we get two scsi reg sets. */ - struct hpc3_scsiregs scsi_chan0, scsi_chan1; - - /* The SEEQ hpc3 ethernet dma/control registers. */ - struct hpc3_ethregs ethregs; - - /* Here are where the hpc3 fifo's can be directly accessed - * via PIO accesses. Under normal operation we never stick - * our grubby paws in here so it's just padding. - */ - char _unused1[PAGE_SIZE * 24]; - - /* HPC3 irq status regs. Due to a peculiar bug you need to - * look at two different register addresses to get at all of - * the status bits. The first reg can only reliably report - * bits 4:0 of the status, and the second reg can only - * reliably report bits 9:5 of the hpc3 irq status. I told - * you it was a peculiar bug. ;-) - */ - hpcreg istat0; /* Irq status, only bits <4:0> reliable. */ -#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */ -#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */ -#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */ - - hpcreg gio64_misc; /* GIO64 misc control bits. */ -#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */ -#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */ - - hpcreg eeprom_data; /* EEPROM data reg. */ -#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */ -#define HPC3_EEPROM_CSEL 0x02 /* Chip select */ -#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */ -#define HPC3_EEPROM_DATO 0x08 /* Data out */ -#define HPC3_EEPROM_DATI 0x10 /* Data in */ - - hpcreg istat1; /* Irq status, only bits <9:5> reliable. */ - hpcreg gio64_estat; /* GIO64 error interrupt status reg. */ -#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */ -#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */ -#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */ - - /* Now direct PIO per-HPC3 peripheral access to external regs. */ - char _unused2[0x13fec]; /* Trust me... */ - hpcreg scsi0_ext[256]; /* SCSI channel 0 external regs */ - char _unused3[0x07c00]; /* Trust me... */ - hpcreg scsi1_ext[256]; /* SCSI channel 1 external regs */ - char _unused4[0x07c00]; /* It'll only hurt a little... */ - - /* Did DaveM forget the ethernet external regs? - * Anyhow, they're not here and we need some padding instead. - */ - char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */ - - /* Per-peripheral device external registers and dma/pio control. */ - hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */ - hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */ -#define HPC3_PIODCFG_D3R 0x00000001 /* Cycles to spend in D3 for reads */ -#define HPC3_PIODCFG_D4R 0x0000001e /* Cycles to spend in D4 for reads */ -#define HPC3_PIODCFG_D5R 0x000001e0 /* Cycles to spend in D5 for reads */ -#define HPC3_PIODCFG_D3W 0x00000200 /* Cycles to spend in D3 for writes */ -#define HPC3_PIODCFG_D4W 0x00003c00 /* Cycles to spend in D4 for writes */ -#define HPC3_PIODCFG_D5W 0x0003c000 /* Cycles to spend in D5 for writes */ -#define HPC3_PIODCFG_HWORD 0x00040000 /* Enable 16-bit dma access mode */ -#define HPC3_PIODCFG_EHI 0x00080000 /* Places halfwords on high 16 bits of bus */ -#define HPC3_PIODCFG_RTIME 0x00200000 /* Make this device real time on GIO bus */ -#define HPC3_PIODCFG_BURST 0x07c00000 /* 5 bit burst count for DMA device */ -#define HPC3_PIODCFG_DRQLV 0x08000000 /* Use live pbus_dreq unsynchronized signal */ - - hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */ -#define HPC3_PIOPCFG_RP2 0x00001 /* Cycles to spend in P2 state for reads */ -#define HPC3_PIOPCFG_RP3 0x0001e /* Cycles to spend in P3 state for reads */ -#define HPC3_PIOPCFG_RP4 0x001e0 /* Cycles to spend in P4 state for reads */ -#define HPC3_PIOPCFG_WP2 0x00200 /* Cycles to spend in P2 state for writes */ -#define HPC3_PIOPCFG_WP3 0x03c00 /* Cycles to spend in P3 state for writes */ -#define HPC3_PIOPCFG_WP4 0x3c000 /* Cycles to spend in P4 state for writes */ -#define HPC3_PIOPCFG_HW 0x40000 /* Enable 16-bit PIO accesses */ -#define HPC3_PIOPCFG_EHI 0x80000 /* Place even address bits in bits <15:8> */ - - /* PBUS PROM control regs. */ - hpcreg pbus_promwe; /* PROM write enable register */ -#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */ - - char _unused6[0x800 - sizeof(hpcreg)]; - hpcreg pbus_promswap; /* Chip select swap reg */ -#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */ - - char _unused7[0x800 - sizeof(hpcreg)]; - hpcreg pbus_gout; /* PROM general purpose output reg */ -#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */ - - char _unused8[0x1000 - sizeof(hpcreg)]; - hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */ -}; - -/* It is possible to have two HPC3's within the address space on - * one machine, though only having one is more likely on an INDY. - * Controller 0 lives at physical address 0x1fb80000 and the controller - * 1 if present lives at address 0x1fb00000. - */ -extern struct hpc3_regs *hpc3c0, *hpc3c1; -#define HPC3_CHIP0_PBASE 0x1fb80000 /* physical */ -#define HPC3_CHIP1_PBASE 0x1fb00000 /* physical */ - -/* Control and misc status information, these live in pbus channel 6. */ -struct hpc3_miscregs { - hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask; - hpcreg ptimer1, ptimer2, ptimer3, ptimer4; - hpcreg _unused1[2]; - hpcreg ser1cmd, ser1data; - hpcreg ser0cmd, ser0data; - hpcreg kbdmouse0, kbdmouse1; - hpcreg gcsel, genctrl, panel; - hpcreg _unused2; - hpcreg sysid; - hpcreg _unused3; - hpcreg read, _unused4; - hpcreg dselect; -#define HPC3_DSELECT_SCLK10MHZ 0x00 /* use 10MHZ serial clock */ -#define HPC3_DSELECT_ISDNB 0x01 /* enable isdn B */ -#define HPC3_DSELECT_ISDNA 0x02 /* enable isdn A */ -#define HPC3_DSELECT_LPR 0x04 /* use parallel DMA */ -#define HPC3_DSELECT_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */ -#define HPC3_DSELECT_SCLKEXT 0x20 /* use external serial clock */ - - hpcreg _unused5; - hpcreg write1; -#define HPC3_WRITE1_PRESET 0x01 /* 0=LPR_RESET, 1=NORMAL */ -#define HPC3_WRITE1_KMRESET 0x02 /* 0=KBDMOUSE_RESET, 1=NORMAL */ -#define HPC3_WRITE1_ERESET 0x04 /* 0=EISA_RESET, 1=NORMAL */ -#define HPC3_WRITE1_GRESET 0x08 /* 0=MAGIC_GIO_RESET, 1=NORMAL */ -#define HPC3_WRITE1_LC0OFF 0x10 /* turn led off (guiness=red, else green) */ -#define HPC3_WRITE1_LC1OFF 0x20 /* turn led off (guiness=green, else amber) */ - - hpcreg _unused6; - hpcreg write2; -#define HPC3_WRITE2_NTHRESH 0x01 /* use 4.5db threshhold */ -#define HPC3_WRITE2_TPSPEED 0x02 /* use 100ohm TP speed */ -#define HPC3_WRITE2_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ -#define HPC3_WRITE2_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ -#define HPC3_WRITE2_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */ -#define HPC3_WRITE2_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */ -#define HPC3_WRITE2_MLO 0x40 /* 1=4.75V 0=+5V */ -#define HPC3_WRITE2_MHI 0x80 /* 1=5.25V 0=+5V */ -}; -extern struct hpc3_miscregs *hpc3mregs; -#define HPC3_MREGS_PBASE 0x1fbd9800 /* physical */ - -/* We need software copies of these because they are write only. */ -extern unsigned int sgi_hpc_write1, sgi_hpc_write2; - -struct hpc_keyb { -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char data; - unsigned char _unused1[3]; - volatile unsigned char command; -#else - volatile unsigned char data; - unsigned char _unused0[3]; - volatile unsigned char command; - unsigned char _unused1[3]; -#endif -}; - -/* Indy RTC */ - -/* The layout of registers for the INDY Dallas 1286 clock chipset. */ -struct indy_clock { - volatile unsigned int hsec; - volatile unsigned int sec; - volatile unsigned int min; - volatile unsigned int malarm; - volatile unsigned int hr; - volatile unsigned int halarm; - volatile unsigned int day; - volatile unsigned int dalarm; - volatile unsigned int date; - volatile unsigned int month; - volatile unsigned int year; - volatile unsigned int cmd; - volatile unsigned int whsec; - volatile unsigned int wsec; - volatile unsigned int _unused0[50]; -}; - -#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000)) - -extern void sgihpc_init(void); - -#endif /* !(_MIPS_SGIHPC_H) */ diff -Nru a/include/asm-mips/sgi/sgimc.h b/include/asm-mips/sgi/sgimc.h --- a/include/asm-mips/sgi/sgimc.h Fri Jun 27 14:20:05 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,229 +0,0 @@ -/* $Id: sgimc.h,v 1.1.1.1 1997/06/01 03:17:13 ralf Exp $ - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * sgimc.h: Definitions for memory controller hardware found on - * SGI IP20, IP22, IP26, and IP28 machines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#ifndef _ASM_SGI_SGIMC_H -#define _ASM_SGI_SGIMC_H - -struct sgimc_misc_ctrl { - u32 _unused1; - volatile u32 cpuctrl0; /* CPU control register 0, readwrite */ -#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */ -#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */ -#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */ -#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */ -#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */ -#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */ -#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */ -#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */ -#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */ -#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */ -#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */ -#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */ -#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */ -#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */ -#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */ -#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */ -#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */ -#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */ -#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */ - - u32 _unused2; - volatile u32 cpuctrl1; /* CPU control register 1, readwrite */ -#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */ -#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */ -#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */ -#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */ -#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */ -#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */ -#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */ - - u32 _unused3; - volatile u32 watchdogt; /* Watchdog reg rdonly, write clears */ - - u32 _unused4; - volatile u32 systemid; /* MC system ID register, readonly */ -#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */ -#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */ - - u32 _unused5[3]; - volatile u32 divider; /* Divider reg for RPSS */ - - u32 _unused6; - volatile unsigned char eeprom; /* EEPROM byte reg for r4k */ -#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */ -#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */ -#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */ -#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */ -#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */ - - unsigned char _unused7[3]; - u32 _unused8[3]; - volatile unsigned short rcntpre; /* Preload refresh counter */ - - unsigned short _unused9; - u32 _unused9a; - volatile unsigned short rcounter; /* Readonly refresh counter */ - - unsigned short _unused10; - u32 _unused11[13]; - volatile u32 gioparm; /* Parameter word for GIO64 */ -#define SGIMC_GIOPARM_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */ -#define SGIMC_GIOPARM_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */ -#define SGIMC_GIOPARM_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */ -#define SGIMC_GIOPARM_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */ -#define SGIMC_GIOPARM_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */ -#define SGIMC_GIOPARM_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */ -#define SGIMC_GIOPARM_RTIMEGFX 0x00000040 /* GFX device has realtime attr */ -#define SGIMC_GIOPARM_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */ -#define SGIMC_GIOPARM_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */ -#define SGIMC_GIOPARM_MASTEREISA 0x00000200 /* EISA bus can act as bus master */ -#define SGIMC_GIOPARM_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */ -#define SGIMC_GIOPARM_MASTERGFX 0x00000800 /* GFX can act as a bus master */ -#define SGIMC_GIOPARM_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */ -#define SGIMC_GIOPARM_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */ -#define SGIMC_GIOPARM_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */ -#define SGIMC_GIOPARM_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */ - - u32 _unused13; - volatile unsigned short cputp; /* CPU bus arb time period */ - - unsigned short _unused14; - u32 _unused15[3]; - volatile unsigned short lbursttp; /* Time period for long bursts */ - - unsigned short _unused16; - u32 _unused17[9]; - volatile u32 mconfig0; /* Memory config register zero */ - u32 _unused18; - volatile u32 mconfig1; /* Memory config register one */ - - /* These defines apply to both mconfig registers above. */ -#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */ -#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */ -#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */ -#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */ -#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */ -#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */ -#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */ - - u32 _unused19; - volatile u32 cmacc; /* Mem access config for CPU */ - u32 _unused20; - volatile u32 gmacc; /* Mem access config for GIO */ - - /* This define applies to both cmacc and gmacc registers above. */ -#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */ - - /* Error address/status regs from GIO and CPU perspectives. */ - u32 _unused21; - volatile u32 cerr; /* Error address reg for CPU */ - u32 _unused22; - volatile u32 cstat; /* Status reg for CPU */ - u32 _unused23; - volatile u32 gerr; /* Error address reg for GIO */ - u32 _unused24; - volatile u32 gstat; /* Status reg for GIO */ - - /* Special hard bus locking registers. */ - u32 _unused25; - volatile unsigned char syssembit; /* Uni-bit system semaphore */ - unsigned char _unused26[3]; - u32 _unused27; - volatile unsigned char mlock; /* Global GIO memory access lock */ - unsigned char _unused28[3]; - u32 _unused29; - volatile unsigned char elock; /* Locks EISA from GIO accesses */ - - /* GIO dma control registers. */ - unsigned char _unused30[3]; - u32 _unused31[14]; - volatile u32 gio_dma_trans;/* DMA mask to translation GIO addrs */ - u32 _unused32; - volatile u32 gio_dma_sbits;/* DMA GIO addr substitution bits */ - u32 _unused33; - volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */ - u32 _unused34; - volatile u32 dma_ctrl; /* Main DMA control reg */ - - /* DMA TLB entry 0 */ - u32 _unused35; - volatile u32 dtlb_hi0; - u32 _unused36; - volatile u32 dtlb_lo0; - - /* DMA TLB entry 1 */ - u32 _unused37; - volatile u32 dtlb_hi1; - u32 _unused38; - volatile u32 dtlb_lo1; - - /* DMA TLB entry 2 */ - u32 _unused39; - volatile u32 dtlb_hi2; - u32 _unused40; - volatile u32 dtlb_lo2; - - /* DMA TLB entry 3 */ - u32 _unused41; - volatile u32 dtlb_hi3; - u32 _unused42; - volatile u32 dtlb_lo3; -}; - -/* MC misc control registers live at physical 0x1fa00000. */ -extern struct sgimc_misc_ctrl *mcmisc_regs; -extern u32 *rpsscounter; /* Chirps at 100ns */ - -struct sgimc_dma_ctrl { - u32 _unused1; - volatile u32 maddronly; /* Address DMA goes at */ - u32 _unused2; - volatile u32 maddrpdeflts; /* Same as above, plus set defaults */ - u32 _unused3; - volatile u32 dmasz; /* DMA count */ - u32 _unused4; - volatile u32 ssize; /* DMA stride size */ - u32 _unused5; - volatile u32 gmaddronly; /* Set GIO DMA but do not start trans */ - u32 _unused6; - volatile u32 dmaddnpgo; /* Set GIO DMA addr + start transfer */ - u32 _unused7; - volatile u32 dmamode; /* DMA mode config bit settings */ - u32 _unused8; - volatile u32 dmaccount; /* Zoom and byte count for DMA */ - u32 _unused9; - volatile u32 dmastart; /* Pedal to the metal. */ - u32 _unused10; - volatile u32 dmarunning; /* DMA op is in progress */ - u32 _unused11; - - /* Set dma addr, defaults, and kick it */ - volatile u32 maddr_defl_go; /* go go go! -lm */ -}; - -/* MC controller dma regs live at physical 0x1fa02000. */ -extern struct sgimc_dma_ctrl *dmactrlregs; - -/* Base location of the two ram banks found in IP2[0268] machines. */ -#define SGIMC_SEG0_BADDR 0x08000000 -#define SGIMC_SEG1_BADDR 0x20000000 - -/* Maximum size of the above banks are per machine. */ -extern u32 sgimc_seg0_size, sgimc_seg1_size; -#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */ -#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */ -#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ - -extern void sgimc_init(void); - -#endif /* _ASM_SGI_SGIMC_H */ diff -Nru a/include/asm-mips/sgi/sgint23.h b/include/asm-mips/sgi/sgint23.h --- a/include/asm-mips/sgi/sgint23.h Fri Jun 27 14:19:53 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,206 +0,0 @@ -/* - * 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. - * - * sgint23.h: Defines for the SGI INT2 and INT3 chipsets. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 98, 1999, 2000 Ralf Baechle - * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections - */ -#ifndef _ASM_SGI_SGINT23_H -#define _ASM_SGI_SGINT23_H - -/* These are the virtual IRQ numbers, we divide all IRQ's into - * 'spaces', the 'space' determines where and how to enable/disable - * that particular IRQ on an SGI machine. Add new 'spaces' as new - * IRQ hardware is supported. - */ -#define SGINT_LOCAL0 0 /* INDY has 8 local0 irq levels */ -#define SGINT_LOCAL1 8 /* INDY has 8 local1 irq levels */ -#define SGINT_LOCAL2 16 /* INDY has 8 local2 vectored irq levels */ -#define SGINT_LOCAL3 24 /* INDY has 8 local3 vectored irq levels */ -#define SGINT_GIO 32 /* INDY has 9 GIO irq levels */ -#define SGINT_HPCDMA 41 /* INDY has 11 HPCDMA irq _sources_ */ -#define SGINT_END 52 /* End of 'spaces' */ - -/* - * Individual interrupt definitions for the INDY and Indigo2 - */ - -#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */ -#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */ -#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */ - -#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */ - -#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */ -#define SGI_KEYBOARD_IRQ SGINT_LOCAL2 + 4 /* keyboard */ -#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */ - -/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */ -#define SGI_INT2_BASE 0x1fbd9000 /* physical */ -#define SGI_INT3_BASE 0x1fbd9880 /* physical */ - -struct sgi_ioc_ints { -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char istat0; /* Interrupt status zero */ -#else - volatile unsigned char istat0; /* Interrupt status zero */ - unsigned char _unused0[3]; -#endif -#define ISTAT0_FFULL 0x01 -#define ISTAT0_SCSI0 0x02 -#define ISTAT0_SCSI1 0x04 -#define ISTAT0_ENET 0x08 -#define ISTAT0_GFXDMA 0x10 -#define ISTAT0_LPR 0x20 -#define ISTAT0_HPC2 0x40 -#define ISTAT0_LIO2 0x80 - -#ifdef __MIPSEB__ - unsigned char _unused1[3]; - volatile unsigned char imask0; /* Interrupt mask zero */ - unsigned char _unused2[3]; - volatile unsigned char istat1; /* Interrupt status one */ -#else - volatile unsigned char imask0; /* Interrupt mask zero */ - unsigned char _unused1[3]; - volatile unsigned char istat1; /* Interrupt status one */ - unsigned char _unused2[3]; -#endif -#define ISTAT1_ISDNI 0x01 -#define ISTAT1_PWR 0x02 -#define ISTAT1_ISDNH 0x04 -#define ISTAT1_LIO3 0x08 -#define ISTAT1_HPC3 0x10 -#define ISTAT1_AFAIL 0x20 -#define ISTAT1_VIDEO 0x40 -#define ISTAT1_GIO2 0x80 - -#ifdef __MIPSEB__ - unsigned char _unused3[3]; - volatile unsigned char imask1; /* Interrupt mask one */ - unsigned char _unused4[3]; - volatile unsigned char vmeistat; /* VME interrupt status */ - unsigned char _unused5[3]; - volatile unsigned char cmeimask0; /* VME interrupt mask zero */ - unsigned char _unused6[3]; - volatile unsigned char cmeimask1; /* VME interrupt mask one */ - unsigned char _unused7[3]; - volatile unsigned char cmepol; /* VME polarity */ -#else - volatile unsigned char imask1; /* Interrupt mask one */ - unsigned char _unused3[3]; - volatile unsigned char vmeistat; /* VME interrupt status */ - unsigned char _unused4[3]; - volatile unsigned char cmeimask0; /* VME interrupt mask zero */ - unsigned char _unused5[3]; - volatile unsigned char cmeimask1; /* VME interrupt mask one */ - unsigned char _unused6[3]; - volatile unsigned char cmepol; /* VME polarity */ - unsigned char _unused7[3]; -#endif -}; - -struct sgi_ioc_timers { -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char tcnt0; /* counter 0 */ - unsigned char _unused1[3]; - volatile unsigned char tcnt1; /* counter 1 */ - unsigned char _unused2[3]; - volatile unsigned char tcnt2; /* counter 2 */ - unsigned char _unused3[3]; - volatile unsigned char tcword; /* control word */ -#else - volatile unsigned char tcnt0; /* counter 0 */ - unsigned char _unused0[3]; - volatile unsigned char tcnt1; /* counter 1 */ - unsigned char _unused1[3]; - volatile unsigned char tcnt2; /* counter 2 */ - unsigned char _unused2[3]; - volatile unsigned char tcword; /* control word */ - unsigned char _unused3[3]; -#endif -}; - -/* Timer control word bits. */ -#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */ -#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */ -#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */ -#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */ -#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */ -#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */ -#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */ -#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */ -#define SGINT_TCWORD_CMASK 0x30 /* Command mask */ -#define SGINT_TCWORD_CLAT 0x00 /* Latch command */ -#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */ -#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */ -#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */ -#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */ -#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */ -#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */ -#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */ - -#define SGINT_TCSAMP_COUNTER 10255 - -/* FIXME: What does this really look like? It was written to have - * 17 registers, but there are only 16 in my Indigo2. - * I guessed at which one to remove... - andrewb - */ -struct sgi_int2_regs { - struct sgi_ioc_ints ints; - - volatile u32 ledbits; /* LED control bits */ -#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */ -#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */ -#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */ -#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */ -#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */ - -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char tclear; /* Timer clear strobe address */ -#else - volatile unsigned char tclear; /* Timer clear strobe address */ - unsigned char _unused0[3]; -#endif -#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */ -#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */ -/* I am guesing there are only two unused registers here - * but I could be wrong... - andrewb - */ -/* u32 _unused[3]; */ - u32 _unused[2]; - struct sgi_ioc_timers timers; -}; - -struct sgi_int3_regs { - struct sgi_ioc_ints ints; - -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char tclear; /* Timer clear strobe address */ -#else - volatile unsigned char tclear; /* Timer clear strobe address */ - unsigned char _unused0[3]; -#endif - volatile u32 estatus; /* Error status reg */ - u32 _unused1[2]; - struct sgi_ioc_timers timers; -}; - -extern struct sgi_int2_regs *sgi_i2regs; -extern struct sgi_int3_regs *sgi_i3regs; -extern struct sgi_ioc_ints *ioc_icontrol; -extern struct sgi_ioc_timers *ioc_timers; -extern volatile unsigned char *ioc_tclear; - -extern void sgint_init(void); -extern void indy_timer_init(void); - -#endif /* _ASM_SGI_SGINT23_H */ diff -Nru a/include/asm-mips/sgialib.h b/include/asm-mips/sgialib.h --- a/include/asm-mips/sgialib.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/sgialib.h Fri Jun 27 14:19:59 2003 @@ -1,25 +1,33 @@ /* - * sgialib.h: SGI ARCS firmware interface library for the Linux kernel. + * 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. + * + * SGI ARCS firmware interface library for the Linux kernel. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org) */ #ifndef _ASM_SGIALIB_H #define _ASM_SGIALIB_H #include <asm/sgiarcs.h> -extern struct linux_promblock *sgi_pblock; extern struct linux_romvec *romvec; extern int prom_argc; -extern char **prom_argv, **prom_envp; + +extern LONG *_prom_argv, *_prom_envp; + +/* A 32-bit ARC PROM pass arguments and environment as 32-bit pointer. + These macros take care of sign extension. */ +#define prom_argv(index) ((char *) (long) _prom_argv[(index)]) +#define prom_argc(index) ((char *) (long) _prom_argc[(index)]) extern int prom_flags; -#define PROM_FLAG_ARCS 1 +#define PROM_FLAG_ARCS 1 +#define PROM_FLAG_USE_AS_CONSOLE 2 -/* - * Init the PROM library and it's internal data structures. Called - * at boot time from head.S before start_kernel is invoked. - */ +/* Init the PROM library and it's internal data structures. */ extern void prom_init(int argc, char **argv, char **envp, int *prom_vec); /* Simple char-by-char console I/O. */ @@ -29,21 +37,34 @@ /* Generic printf() using ARCS console I/O. */ extern void prom_printf(char *fmt, ...); +/* Memory descriptor management. */ +#define PROM_MAX_PMEMBLOCKS 32 +struct prom_pmemblock { + LONG base; /* Within KSEG0 or XKPHYS. */ + ULONG size; /* In bytes. */ + ULONG type; /* free or prom memory */ +}; + +/* Get next memory descriptor after CURR, returns first descriptor + * in chain is CURR is NULL. + */ +extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr); #define PROM_NULL_MDESC ((struct linux_mdesc *) 0) /* Called by prom_init to setup the physical memory pmemblock * array. */ extern void prom_meminit(void); +extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); /* PROM device tree library routines. */ #define PROM_NULL_COMPONENT ((pcomponent *) 0) /* Get sibling component of THIS. */ -extern pcomponent *prom_getsibling(pcomponent *this); +extern pcomponent *ArcGetPeer(pcomponent *this); /* Get child component of THIS. */ -extern pcomponent *prom_getchild(pcomponent *this); +extern pcomponent *ArcGetChild(pcomponent *this); /* Get parent component of CHILD. */ extern pcomponent *prom_getparent(pcomponent *child); @@ -65,7 +86,7 @@ extern void prom_identify_arch(void); /* Environment variable routines. */ -extern PCHAR ArcGetEnvironmentVariable(CHAR *name); +extern PCHAR ArcGetEnvironmentVariable(PCHAR name); extern LONG ArcSetEnvironmentVariable(PCHAR name, PCHAR value); /* ARCS command line acquisition and parsing. */ @@ -80,9 +101,9 @@ extern long prom_getvdirent(unsigned long fd, struct linux_vdirent *ent, unsigned long num, unsigned long *cnt); extern long prom_open(char *name, enum linux_omode md, unsigned long *fd); extern long prom_close(unsigned long fd); -extern long prom_read(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern LONG ArcRead(ULONG fd, PVOID buf, ULONG num, PULONG cnt); extern long prom_getrstatus(unsigned long fd); -extern long prom_write(unsigned long fd, void *buf, unsigned long num, unsigned long *cnt); +extern LONG ArcWrite(ULONG fd, PVOID buf, ULONG num, PULONG cnt); extern long prom_seek(unsigned long fd, struct linux_bigint *off, enum linux_seekmode sm); extern long prom_mount(char *name, enum linux_mountops op); extern long prom_getfinfo(unsigned long fd, struct linux_finfo *buf); @@ -94,13 +115,13 @@ extern long prom_exec(char *name, long argc, char **argv, char **envp); /* Misc. routines. */ -extern void prom_halt(void) __attribute__((noreturn)); -extern void prom_powerdown(void) __attribute__((noreturn)); -extern void prom_restart(void) __attribute__((noreturn)); -extern void prom_reboot(void) __attribute__((noreturn)); -extern void ArcEnterInteractiveMode(void) __attribute__((noreturn)); -extern long prom_cfgsave(void); -extern struct linux_sysid *prom_getsysid(void); -extern void prom_cacheflush(void); +extern VOID prom_halt(VOID) __attribute__((noreturn)); +extern VOID prom_powerdown(VOID) __attribute__((noreturn)); +extern VOID prom_restart(VOID) __attribute__((noreturn)); +extern VOID ArcReboot(VOID) __attribute__((noreturn)); +extern VOID ArcEnterInteractiveMode(VOID) __attribute__((noreturn)); +extern long prom_cfgsave(VOID); +extern struct linux_sysid *prom_getsysid(VOID); +extern VOID ArcFlushAllCaches(VOID); #endif /* _ASM_SGIALIB_H */ diff -Nru a/include/asm-mips/sgiarcs.h b/include/asm-mips/sgiarcs.h --- a/include/asm-mips/sgiarcs.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/sgiarcs.h Fri Jun 27 14:19:55 2003 @@ -1,12 +1,19 @@ -/* $Id: sgiarcs.h,v 1.3 1999/02/25 20:55:08 tsbogend Exp $ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. * - * SGI ARCS firmware interface defines. + * ARC firmware interface defines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_SGIARCS_H #define _ASM_SGIARCS_H +#include <linux/config.h> +#include <asm/types.h> #include <asm/arc/types.h> /* Various ARCS error codes. */ @@ -71,16 +78,16 @@ /* A prom device tree component. */ struct linux_component { - enum linux_devclass class; /* node class */ - enum linux_devtypes type; /* node type */ - enum linux_identifier iflags; /* node flags */ - unsigned short vers; /* node version */ - unsigned short rev; /* node revision */ - unsigned long key; /* completely magic */ - unsigned long amask; /* XXX affinity mask??? */ - unsigned long cdsize; /* size of configuration data */ - unsigned long ilen; /* length of string identifier */ - char *iname; /* string identifier */ + enum linux_devclass class; /* node class */ + enum linux_devtypes type; /* node type */ + enum linux_identifier iflags; /* node flags */ + USHORT vers; /* node version */ + USHORT rev; /* node revision */ + ULONG key; /* completely magic */ + ULONG amask; /* XXX affinity mask??? */ + ULONG cdsize; /* size of configuration data */ + ULONG ilen; /* length of string identifier */ + _PULONG iname; /* string identifier */ }; typedef struct linux_component pcomponent; @@ -109,7 +116,7 @@ arc_prog, /* A loaded program resides here */ arc_atmp, /* temporary storage area */ arc_aperm, /* permanent storage */ - arc_fcontig, /* Contiguous and free */ + arc_fcontig, /* Contiguous and free */ }; union linux_memtypes { @@ -118,9 +125,9 @@ }; struct linux_mdesc { - union linux_memtypes type; - unsigned long base; - unsigned long pages; + union linux_memtypes type; + ULONG base; + ULONG pages; }; /* Time of day descriptor. */ @@ -136,7 +143,7 @@ /* ARCS virtual dirents. */ struct linux_vdirent { - unsigned long namelen; + ULONG namelen; unsigned char attr; char fname[32]; /* XXX imperical, should be a define */ }; @@ -158,11 +165,11 @@ /* This prom has a bolixed design. */ struct linux_bigint { #ifdef __MIPSEL__ - unsigned long lo; - long hi; + u32 lo; + s32 hi; #else /* !(__MIPSEL__) */ - long hi; - unsigned long lo; + s32 hi; + u32 lo; #endif }; @@ -170,110 +177,97 @@ struct linux_bigint begin; struct linux_bigint end; struct linux_bigint cur; - enum linux_devtypes dtype; + enum linux_devtypes dtype; unsigned long namelen; unsigned char attr; char name[32]; /* XXX imperical, should be define */ }; +/* This describes the vector containing function pointers to the ARC + firmware functions. */ struct linux_romvec { - /* Load an executable image. */ - long (*load)(char *file, unsigned long end, - unsigned long *start_pc, - unsigned long *end_addr); - - /* Invoke a standalong image. */ - long (*invoke)(unsigned long startpc, unsigned long sp, - long argc, char **argv, char **envp); - - /* Load and begin execution of a standalong image. */ - long (*exec)(char *file, long argc, char **argv, char **envp); - - void (*halt)(void) __attribute__((noreturn)); /* Halt the machine. */ - void (*pdown)(void) __attribute__((noreturn)); /* Power down the machine. */ - void (*restart)(void) __attribute__((noreturn)); /* XXX soft reset??? */ - void (*reboot)(void) __attribute__((noreturn)); /* Reboot the machine. */ - void (*imode)(void) __attribute__((noreturn)); /* Enter PROM interactive mode. */ - int _unused1; /* padding */ + LONG load; /* Load an executable image. */ + LONG invoke; /* Invoke a standalong image. */ + LONG exec; /* Load and begin execution of a + standalone image. */ + LONG halt; /* Halt the machine. */ + LONG pdown; /* Power down the machine. */ + LONG restart; /* XXX soft reset??? */ + LONG reboot; /* Reboot the machine. */ + LONG imode; /* Enter PROM interactive mode. */ + LONG _unused1; /* Was ReturnFromMain(). */ /* PROM device tree interface. */ - pcomponent *(*next_component)(pcomponent *this); - pcomponent *(*child_component)(pcomponent *this); - pcomponent *(*parent_component)(pcomponent *this); - long (*component_data)(void *opaque_data, pcomponent *this); - pcomponent *(*child_add)(pcomponent *this, - pcomponent *tmp, - void *opaque_data); - long (*comp_del)(pcomponent *this); - pcomponent *(*component_by_path)(char *file); + LONG next_component; + LONG child_component; + LONG parent_component; + LONG component_data; + LONG child_add; + LONG comp_del; + LONG component_by_path; /* Misc. stuff. */ - long (*cfg_save)(void); - struct linux_sysid *(*get_sysid)(void); + LONG cfg_save; + LONG get_sysid; /* Probing for memory. */ - struct linux_mdesc *(*get_mdesc)(struct linux_mdesc *curr); - long _unused2; /* padding */ + LONG get_mdesc; + LONG _unused2; /* was Signal() */ - struct linux_tinfo *(*get_tinfo)(void); - unsigned long (*get_rtime)(void); + LONG get_tinfo; + LONG get_rtime; /* File type operations. */ - long (*get_vdirent)(unsigned long fd, struct linux_vdirent *entry, - unsigned long num, unsigned long *count); - long (*open)(char *file, enum linux_omode mode, unsigned long *fd); - long (*close)(unsigned long fd); - long (*read)(unsigned long fd, void *buffer, unsigned long num, - unsigned long *count); - long (*get_rstatus)(unsigned long fd); - long (*write)(unsigned long fd, void *buffer, unsigned long num, - unsigned long *count); - long (*seek)(unsigned long fd, struct linux_bigint *offset, - enum linux_seekmode smode); - long (*mount)(char *file, enum linux_mountops op); + LONG get_vdirent; + LONG open; + LONG close; + LONG read; + LONG get_rstatus; + LONG write; + LONG seek; + LONG mount; /* Dealing with firmware environment variables. */ - PCHAR (*get_evar)(CHAR *name); - LONG (*set_evar)(PCHAR name, PCHAR value); + LONG get_evar; + LONG set_evar; - long (*get_finfo)(unsigned long fd, struct linux_finfo *buf); - long (*set_finfo)(unsigned long fd, unsigned long flags, - unsigned long mask); + LONG get_finfo; + LONG set_finfo; /* Miscellaneous. */ - void (*cache_flush)(void); + LONG cache_flush; }; /* The SGI ARCS parameter block is in a fixed location for standalone * programs to access PROM facilities easily. */ -struct linux_promblock { - long magic; /* magic cookie */ +typedef struct _SYSTEM_PARAMETER_BLOCK { + ULONG magic; /* magic cookie */ #define PROMBLOCK_MAGIC 0x53435241 - unsigned long len; /* length of parm block */ - unsigned short ver; /* ARCS firmware version */ - unsigned short rev; /* ARCS firmware revision */ - long *rs_block; /* Restart block. */ - long *dbg_block; /* Debug block. */ - long *gevect; /* XXX General vector??? */ - long *utlbvect; /* XXX UTLB vector??? */ - unsigned long rveclen; /* Size of romvec struct. */ - struct linux_romvec *romvec; /* Function interface. */ - unsigned long pveclen; /* Length of private vector. */ - long *pvector; /* Private vector. */ - long adap_cnt; /* Adapter count. */ - long adap_typ0; /* First adapter type. */ - long adap_vcnt0; /* Adapter 0 vector count. */ - long *adap_vector; /* Adapter 0 vector ptr. */ - long adap_typ1; /* Second adapter type. */ - long adap_vcnt1; /* Adapter 1 vector count. */ - long *adap_vector1; /* Adapter 1 vector ptr. */ + ULONG len; /* length of parm block */ + USHORT ver; /* ARCS firmware version */ + USHORT rev; /* ARCS firmware revision */ + _PLONG rs_block; /* Restart block. */ + _PLONG dbg_block; /* Debug block. */ + _PLONG gevect; /* XXX General vector??? */ + _PLONG utlbvect; /* XXX UTLB vector??? */ + ULONG rveclen; /* Size of romvec struct. */ + _PVOID romvec; /* Function interface. */ + ULONG pveclen; /* Length of private vector. */ + _PVOID pvector; /* Private vector. */ + ULONG adap_cnt; /* Adapter count. */ + ULONG adap_typ0; /* First adapter type. */ + ULONG adap_vcnt0; /* Adapter 0 vector count. */ + _PVOID adap_vector; /* Adapter 0 vector ptr. */ + ULONG adap_typ1; /* Second adapter type. */ + ULONG adap_vcnt1; /* Adapter 1 vector count. */ + _PVOID adap_vector1; /* Adapter 1 vector ptr. */ /* More adapter vectors go here... */ -}; +} SYSTEM_PARAMETER_BLOCK, *PSYSTEM_PARAMETER_BLOCK; -#define PROMBLOCK ((struct linux_promblock *)0xA0001000UL) -#define ROMVECTOR ((PROMBLOCK)->romvec) +#define PROMBLOCK ((PSYSTEM_PARAMETER_BLOCK) (int)0xA0001000) +#define ROMVECTOR ((struct linux_romvec *) (long)(PROMBLOCK)->romvec) /* Cache layout parameter block. */ union linux_cache_key { @@ -366,5 +360,188 @@ unsigned long stab; /* Symbol table. */ int smax; /* Max # of symbols. */ }; + +/* + * Macros for calling a 32-bit ARC implementation from 64-bit code + */ + +#if defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) + +#define __arc_clobbers \ + "$2","$3" /* ... */, "$8","$9","$10","$11", \ + "$12","$13","$14","$15","$16","$24","25","$31" + +#define ARC_CALL0(dest) \ +({ long __res; \ + long __vec = (long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec) \ + : __arc_clobbers, "$4","$5","$6","$7"); \ + (unsigned long) __res; \ +}) + +#define ARC_CALL1(dest,a1) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + long __vec = (long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1) \ + : __arc_clobbers, "$5","$6","$7"); \ + (unsigned long) __res; \ +}) + +#define ARC_CALL2(dest,a1,a2) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + long __vec = (long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1), "r" (__a2) \ + : __arc_clobbers, "$6","$7"); \ + __res; \ +}) + +#define ARC_CALL3(dest,a1,a2,a3) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + register signed int __a3 __asm__("$6") = (int) (long) (a3); \ + long __vec = (long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \ + : __arc_clobbers, "$7"); \ + __res; \ +}) + +#define ARC_CALL4(dest,a1,a2,a3,a4) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + register signed int __a3 __asm__("$6") = (int) (long) (a3); \ + register signed int __a4 __asm__("$7") = (int) (long) (a4); \ + long __vec = (long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3), \ + "r" (__a4) \ + : __arc_clobbers); \ + __res; \ +}) + +#define ARC_CALL5(dest,a1,a2,a3,a4,a5) \ +({ long __res; \ + register signed int __a1 __asm__("$4") = (int) (long) (a1); \ + register signed int __a2 __asm__("$5") = (int) (long) (a2); \ + register signed int __a3 __asm__("$6") = (int) (long) (a3); \ + register signed int __a4 __asm__("$7") = (int) (long) (a4); \ + register signed int __a5 = (a5); \ + long __vec = (long) romvec->dest; \ + __asm__ __volatile__( \ + "dsubu\t$29, 32\n\t" \ + "sw\t%6, 16($29)\n\t" \ + "jalr\t%1\n\t" \ + "daddu\t$29, 32\n\t" \ + "move\t%0, $2" \ + : "=r" (__res), "=r" (__vec) \ + : "1" (__vec), \ + "r" (__a1), "r" (__a2), "r" (__a3), "r" (__a4), \ + "r" (__a5) \ + : __arc_clobbers); \ + __res; \ +}) + +#endif /* defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) */ + +#if (defined(CONFIG_MIPS32) && defined(CONFIG_ARC32)) || \ + (defined(CONFIG_MIPS64) && defined(CONFIG_ARC64)) + +#define ARC_CALL0(dest) \ +({ long __res; \ + long (*__vec)(void) = (void *) romvec->dest; \ + \ + __res = __vec(); \ + __res; \ +}) + +#define ARC_CALL1(dest,a1) \ +({ long __res; \ + long __a1 = (long) (a1); \ + long (*__vec)(long) = (void *) romvec->dest; \ + \ + __res = __vec(__a1); \ + __res; \ +}) + +#define ARC_CALL2(dest,a1,a2) \ +({ long __res; \ + long __a1 = (long) (a1); \ + long __a2 = (long) (a2); \ + long (*__vec)(long, long) = (void *) romvec->dest; \ + \ + __res = __vec(__a1, __a2); \ + __res; \ +}) + +#define ARC_CALL3(dest,a1,a2,a3) \ +({ long __res; \ + long __a1 = (long) (a1); \ + long __a2 = (long) (a2); \ + long __a3 = (long) (a3); \ + long (*__vec)(long, long, long) = (void *) romvec->dest; \ + \ + __res = __vec(__a1, __a2, __a3); \ + __res; \ +}) + +#define ARC_CALL4(dest,a1,a2,a3,a4) \ +({ long __res; \ + long __a1 = (long) (a1); \ + long __a2 = (long) (a2); \ + long __a3 = (long) (a3); \ + long __a4 = (long) (a4); \ + long (*__vec)(long, long, long, long) = (void *) romvec->dest; \ + \ + __res = __vec(__a1, __a2, __a3, __a4); \ + __res; \ +}) + +#define ARC_CALL5(dest,a1,a2,a3,a4,a5) \ +({ long __res; \ + long __a1 = (long) (a1); \ + long __a2 = (long) (a2); \ + long __a3 = (long) (a3); \ + long __a4 = (long) (a4); \ + long __a5 = (long) (a5); \ + long (*__vec)(long, long, long, long, long); \ + __vec = (void *) romvec->dest; \ + \ + __res = __vec(__a1, __a2, __a3, __a4, __a5); \ + __res; \ +}) +#endif /* both kernel and ARC either 32-bit or 64-bit */ #endif /* _ASM_SGIARCS_H */ diff -Nru a/include/asm-mips/shmbuf.h b/include/asm-mips/shmbuf.h --- a/include/asm-mips/shmbuf.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/shmbuf.h Fri Jun 27 14:19:56 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_SHMBUF_H #define _ASM_SHMBUF_H -/* +/* * The shmid64_ds structure for the MIPS architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. diff -Nru a/include/asm-mips/shmiq.h b/include/asm-mips/shmiq.h --- a/include/asm-mips/shmiq.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/shmiq.h Fri Jun 27 14:19:54 2003 @@ -5,7 +5,7 @@ * * This also contains some streams and idev bits. * - * They may contain errors, please, refer to the source code of the Linux + * They may contain errors, please, refer to the source code of the Linux * kernel for a definitive answer on what we have implemented * * Miguel. @@ -91,7 +91,7 @@ * head is the user index into the events, user can modify this one. * tail is managed by the kernel. * flags is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED - * if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called + * if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called * to notify the kernel. * events where the kernel sticks the events. */ @@ -186,14 +186,14 @@ unsigned hwMaxRes; int hwMinVal; int hwMaxVal; - + unsigned char possibleModes; #define IDEV_ABSOLUTE 0x0 #define IDEV_RELATIVE 0x1 #define IDEV_EITHER 0x2 - + unsigned char mode; /* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */ - + unsigned short resolution; int minVal; int maxVal; diff -Nru a/include/asm-mips/shmparam.h b/include/asm-mips/shmparam.h --- a/include/asm-mips/shmparam.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips/shmparam.h Fri Jun 27 14:20:00 2003 @@ -1,5 +1,4 @@ -/* $Id: shmparam.h,v 1.3 2000/01/28 19:46:32 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff -Nru a/include/asm-mips/sibyte/64bit.h b/include/asm-mips/sibyte/64bit.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/64bit.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2002 Ralf Baechle + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ASM_SIBYTE_64BIT_H +#define __ASM_SIBYTE_64BIT_H + +#include <linux/config.h> +#include <linux/types.h> + +#ifdef CONFIG_MIPS32 + +#include <asm/system.h> + +/* + * This is annoying...we can't actually write the 64-bit IO register properly + * without having access to 64-bit registers... which doesn't work by default + * in o32 format...grrr... + */ +static inline void __out64(u64 val, unsigned long addr) +{ + u64 tmp; + + __asm__ __volatile__ ( + " .set mips3 \n" + " dsll32 %L0, %L0, 0 # __out64 \n" + " dsrl32 %L0, %L0, 0 \n" + " dsll32 %M0, %M0, 0 \n" + " or %L0, %L0, %M0 \n" + " sd %L0, (%2) \n" + " .set mips0 \n" + : "=r" (tmp) + : "0" (val), "r" (addr)); +} + +static inline void out64(u64 val, unsigned long addr) +{ + unsigned long flags; + + local_irq_save(flags); + __out64(val, addr); + local_irq_restore(flags); +} + +static inline u64 __in64(unsigned long addr) +{ + u64 res; + + __asm__ __volatile__ ( + " .set mips3 # __in64 \n" + " ld %L0, (%1) \n" + " dsra32 %M0, %L0, 0 \n" + " sll %L0, %L0, 0 \n" + " .set mips0 \n" + : "=r" (res) + : "r" (addr)); + + return res; +} + +static inline u64 in64(unsigned long addr) +{ + unsigned long flags; + u64 res; + + local_irq_save(flags); + res = __in64(addr); + local_irq_restore(flags); + + return res; +} + +#endif /* CONFIG_MIPS32 */ + +#ifdef CONFIG_MIPS64 + +/* + * These are provided so as to be able to use common + * driver code for the 32-bit and 64-bit trees + */ +extern inline void out64(u64 val, unsigned long addr) +{ + *(volatile unsigned long *)addr = val; +} + +extern inline u64 in64(unsigned long addr) +{ + return *(volatile unsigned long *)addr; +} + +#define __in64(a) in64(a) +#define __out64(v,a) out64(v,a) + +#endif /* CONFIG_MIPS64 */ + +/* + * Avoid interrupt mucking, just adjust the address for 4-byte access. + * Assume the addresses are 8-byte aligned. + */ + +#ifdef __MIPSEB__ +#define __CSR_32_ADJUST 4 +#else +#define __CSR_32_ADJUST 0 +#endif + +#define csr_out32(v,a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v)) +#define csr_in32(a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST)) + +#endif /* __ASM_SIBYTE_64BIT_H */ diff -Nru a/include/asm-mips/sibyte/board.h b/include/asm-mips/sibyte/board.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/board.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _SIBYTE_BOARD_H +#define _SIBYTE_BOARD_H + +#ifdef CONFIG_SIBYTE_BOARD + +#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \ + defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) +#include <asm/sibyte/swarm.h> +#endif + +#if defined(CONFIG_SIBYTE_SENTOSA) || defined(CONFIG_SIBYTE_RHONE) +#include <asm/sibyte/sentosa.h> +#endif + +#ifdef CONFIG_SIBYTE_CARMEL +#include <asm/sibyte/carmel.h> +#endif + +#ifdef __ASSEMBLY__ + +#ifdef LEDS_PHYS +#define setleds(t0,t1,c0,c1,c2,c3) \ + li t0, (LEDS_PHYS|0xa0000000); \ + li t1, c0; \ + sb t1, 0x18(t0); \ + li t1, c1; \ + sb t1, 0x10(t0); \ + li t1, c2; \ + sb t1, 0x08(t0); \ + li t1, c3; \ + sb t1, 0x00(t0) +#else +#define setleds(t0,t1,c0,c1,c2,c3) +#endif /* LEDS_PHYS */ + +#else + +void swarm_setup(void); + +#ifdef LEDS_PHYS +extern void setleds(char *str); +#else +#define setleds(s) do { } while (0) +#endif /* LEDS_PHYS */ + +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_SIBYTE_BOARD */ + +#endif /* _SIBYTE_BOARD_H */ diff -Nru a/include/asm-mips/sibyte/carmel.h b/include/asm-mips/sibyte/carmel.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/carmel.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __ASM_SIBYTE_CARMEL_H +#define __ASM_SIBYTE_CARMEL_H + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_int.h> + +#define SIBYTE_BOARD_NAME "Carmel" + +#define GPIO_PHY_INTERRUPT 2 +#define GPIO_NONMASKABLE_INT 3 +#define GPIO_CF_INSERTED 6 +#define GPIO_MONTEREY_RESET 7 +#define GPIO_QUADUART_INT 8 +#define GPIO_CF_INT 9 +#define GPIO_FPGA_CCLK 10 +#define GPIO_FPGA_DOUT 11 +#define GPIO_FPGA_DIN 12 +#define GPIO_FPGA_PGM 13 +#define GPIO_FPGA_DONE 14 +#define GPIO_FPGA_INIT 15 + +#define LEDS_CS 2 +#define LEDS_PHYS 0x100C0000 +#define MLEDS_CS 3 +#define MLEDS_PHYS 0x100A0000 +#define UART_CS 4 +#define UART_PHYS 0x100D0000 +#define ARAVALI_CS 5 +#define ARAVALI_PHYS 0x11000000 +#define IDE_CS 6 +#define IDE_PHYS 0x100B0000 +#define ARAVALI2_CS 7 +#define ARAVALI2_PHYS 0x100E0000 + +#if defined(CONFIG_SIBYTE_CARMEL) +#define K_GPIO_GB_IDE 9 +#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE) +#endif + + +#endif /* __ASM_SIBYTE_CARMEL_H */ diff -Nru a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ASM_SIBYTE_SB1250_H +#define _ASM_SIBYTE_SB1250_H + +#define SB1250_NR_IRQS 64 + +#ifndef __ASSEMBLY__ + +#include <asm/addrspace.h> + +/* For revision/pass information */ +#include <asm/sibyte/sb1250_scd.h> +extern unsigned int sb1_pass; +extern unsigned int soc_pass; +extern unsigned int soc_type; +extern unsigned int periph_rev; + +extern void sb1250_time_init(void); +extern unsigned long sb1250_gettimeoffset(void); +extern void sb1250_mask_irq(int cpu, int irq); +extern void sb1250_unmask_irq(int cpu, int irq); +extern void sb1250_smp_finish(void); +extern void prom_printf(char *fmt, ...); + +#define AT_spin \ + __asm__ __volatile__ ( \ + ".set noat\n" \ + "li $at, 0\n" \ + "1: beqz $at, 1b\n" \ + ".set at\n" \ + ) + +#endif + +#define IO_SPACE_BASE KSEG1 + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_defs.h b/include/asm-mips/sibyte/sb1250_defs.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_defs.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,242 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Global constants and macros File: sb1250_defs.h + * + * This file contains macros and definitions used by the other + * include files. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + +#ifndef _SB1250_DEFS_H +#define _SB1250_DEFS_H + +/* + * These headers require ANSI C89 string concatenation, and GCC or other + * 'long long' (64-bit integer) support. + */ +#if !defined(__STDC__) && !defined(_MSC_VER) +#error SiByte headers require ANSI C89 support +#endif + + +/* ********************************************************************* + * Macros for feature tests, used to enable include file features + * for chip features only present in certain chip revisions. + * + * SIBYTE_HDR_FEATURES may be defined to be the mask value chip/revision + * which is to be exposed by the headers. If undefined, it defaults to + * "all features." + * + * Use like: + * + * #define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_112x_PASS1 + * + * Generate defines only for that revision of chip. + * + * #if SIBYTE_HDR_FEATURE(chip,pass) + * + * True if header features for that revision or later of + * that particular chip type are enabled in SIBYTE_HDR_FEATURES. + * (Use this to bracket #defines for features present in a given + * revision and later.) + * + * Note that there is no implied ordering between chip types. + * + * Note also that 'chip' and 'pass' must textually exactly + * match the defines below. So, for example, + * SIBYTE_HDR_FEATURE(112x, PASS1) is OK, but + * SIBYTE_HDR_FEATURE(1120, pass1) is not (for two reasons). + * + * #if SIBYTE_HDR_FEATURE_UP_TO(chip,pass) + * + * Same as SIBYTE_HDR_FEATURE, but true for the named revision + * and earlier revisions of the named chip type. + * + * #if SIBYTE_HDR_FEATURE_EXACT(chip,pass) + * + * Same as SIBYTE_HDR_FEATURE, but only true for the named + * revision of the named chip type. (Note that this CANNOT + * be used to verify that you're compiling only for that + * particular chip/revision. It will be true any time this + * chip/revision is included in SIBYTE_HDR_FEATURES.) + * + * #if SIBYTE_HDR_FEATURE_CHIP(chip) + * + * True if header features for (any revision of) that chip type + * are enabled in SIBYTE_HDR_FEATURES. (Use this to bracket + * #defines for features specific to a given chip type.) + * + * Mask values currently include room for additional revisions of each + * chip type, but can be renumbered at will. Note that they MUST fit + * into 31 bits and may not include C type constructs, for safe use in + * CPP conditionals. Bit positions within chip types DO indicate + * ordering, so be careful when adding support for new minor revs. + ********************************************************************* */ + +#define SIBYTE_HDR_FMASK_1250_ALL 0x00000ff +#define SIBYTE_HDR_FMASK_1250_PASS1 0x0000001 +#define SIBYTE_HDR_FMASK_1250_PASS2 0x0000002 + +#define SIBYTE_HDR_FMASK_112x_ALL 0x0000f00 +#define SIBYTE_HDR_FMASK_112x_PASS1 0x0000100 +#define SIBYTE_HDR_FMASK_112x_PASS3 0x0000200 + +/* Bit mask for chip/revision. (use _ALL for all revisions of a chip). */ +#define SIBYTE_HDR_FMASK(chip, pass) \ + (SIBYTE_HDR_FMASK_ ## chip ## _ ## pass) +#define SIBYTE_HDR_FMASK_ALLREVS(chip) \ + (SIBYTE_HDR_FMASK_ ## chip ## _ALL) + +#define SIBYTE_HDR_FMASK_ALL \ + (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL) + +#ifndef SIBYTE_HDR_FEATURES +#define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_ALL +#endif + + +/* Bit mask for revisions of chip exclusively before the named revision. */ +#define SIBYTE_HDR_FMASK_BEFORE(chip, pass) \ + ((SIBYTE_HDR_FMASK(chip, pass) - 1) & SIBYTE_HDR_FMASK_ALLREVS(chip)) + +/* Bit mask for revisions of chip exclusively after the named revision. */ +#define SIBYTE_HDR_FMASK_AFTER(chip, pass) \ + (~(SIBYTE_HDR_FMASK(chip, pass) \ + | (SIBYTE_HDR_FMASK(chip, pass) - 1)) & SIBYTE_HDR_FMASK_ALLREVS(chip)) + + +/* True if header features enabled for (any revision of) that chip type. */ +#define SIBYTE_HDR_FEATURE_CHIP(chip) \ + (!! (SIBYTE_HDR_FMASK_ALLREVS(chip) & SIBYTE_HDR_FEATURES)) + +/* True if header features enabled for that rev or later, inclusive. */ +#define SIBYTE_HDR_FEATURE(chip, pass) \ + (!! ((SIBYTE_HDR_FMASK(chip, pass) \ + | SIBYTE_HDR_FMASK_AFTER(chip, pass)) & SIBYTE_HDR_FEATURES)) + +/* True if header features enabled for exactly that rev. */ +#define SIBYTE_HDR_FEATURE_EXACT(chip, pass) \ + (!! (SIBYTE_HDR_FMASK(chip, pass) & SIBYTE_HDR_FEATURES)) + +/* True if header features enabled for that rev or before, inclusive. */ +#define SIBYTE_HDR_FEATURE_UP_TO(chip, pass) \ + (!! ((SIBYTE_HDR_FMASK(chip, pass) \ + | SIBYTE_HDR_FMASK_BEFORE(chip, pass)) & SIBYTE_HDR_FEATURES)) + + +/* ********************************************************************* + * Naming schemes for constants in these files: + * + * M_xxx MASK constant (identifies bits in a register). + * For multi-bit fields, all bits in the field will + * be set. + * + * K_xxx "Code" constant (value for data in a multi-bit + * field). The value is right justified. + * + * V_xxx "Value" constant. This is the same as the + * corresponding "K_xxx" constant, except it is + * shifted to the correct position in the register. + * + * S_xxx SHIFT constant. This is the number of bits that + * a field value (code) needs to be shifted + * (towards the left) to put the value in the right + * position for the register. + * + * A_xxx ADDRESS constant. This will be a physical + * address. Use the PHYS_TO_K1 macro to generate + * a K1SEG address. + * + * R_xxx RELATIVE offset constant. This is an offset from + * an A_xxx constant (usually the first register in + * a group). + * + * G_xxx(X) GET value. This macro obtains a multi-bit field + * from a register, masks it, and shifts it to + * the bottom of the register (retrieving a K_xxx + * value, for example). + * + * V_xxx(X) VALUE. This macro computes the value of a + * K_xxx constant shifted to the correct position + * in the register. + ********************************************************************* */ + + + + +/* + * Cast to 64-bit number. Presumably the syntax is different in + * assembly language. + * + * Note: you'll need to define uint32_t and uint64_t in your headers. + */ + +#if !defined(__ASSEMBLER__) +#define _SB_MAKE64(x) ((uint64_t)(x)) +#define _SB_MAKE32(x) ((uint32_t)(x)) +#else +#define _SB_MAKE64(x) (x) +#define _SB_MAKE32(x) (x) +#endif + + +/* + * Make a mask for 1 bit at position 'n' + */ + +#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n)) +#define _SB_MAKEMASK1_32(n) (_SB_MAKE32(1) << _SB_MAKE32(n)) + +/* + * Make a mask for 'v' bits at position 'n' + */ + +#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n)) +#define _SB_MAKEMASK_32(v,n) (_SB_MAKE32((_SB_MAKE32(1)<<(v))-1) << _SB_MAKE32(n)) + +/* + * Make a value at 'v' at bit position 'n' + */ + +#define _SB_MAKEVALUE(v,n) (_SB_MAKE64(v) << _SB_MAKE64(n)) +#define _SB_MAKEVALUE_32(v,n) (_SB_MAKE32(v) << _SB_MAKE32(n)) + +#define _SB_GETVALUE(v,n,m) ((_SB_MAKE64(v) & _SB_MAKE64(m)) >> _SB_MAKE64(n)) +#define _SB_GETVALUE_32(v,n,m) ((_SB_MAKE32(v) & _SB_MAKE32(m)) >> _SB_MAKE32(n)) + +/* + * Macros to read/write on-chip registers + * XXX should we do the PHYS_TO_K1 here? + */ + + +#if !defined(__ASSEMBLER__) +#define SBWRITECSR(csr,val) *((volatile uint64_t *) PHYS_TO_K1(csr)) = (val) +#define SBREADCSR(csr) (*((volatile uint64_t *) PHYS_TO_K1(csr))) +#endif /* __ASSEMBLER__ */ + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_dma.h b/include/asm-mips/sibyte/sb1250_dma.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_dma.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,594 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * DMA definitions File: sb1250_dma.h + * + * This module contains constants and macros useful for + * programming the SB1250's DMA controllers, both the data mover + * and the Ethernet DMA. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_DMA_H +#define _SB1250_DMA_H + + +#include "sb1250_defs.h" + +/* ********************************************************************* + * DMA Registers + ********************************************************************* */ + +/* + * Ethernet and Serial DMA Configuration Register 0 (Table 7-4) + * Registers: DMA_CONFIG0_MAC_x_RX_CH_0 + * Registers: DMA_CONFIG0_MAC_x_TX_CH_0 + * Registers: DMA_CONFIG0_SER_x_RX + * Registers: DMA_CONFIG0_SER_x_TX + */ + + +#define M_DMA_DROP _SB_MAKEMASK1(0) + +#define M_DMA_CHAIN_SEL _SB_MAKEMASK1(1) +#define M_DMA_RESERVED1 _SB_MAKEMASK1(2) + +#define S_DMA_DESC_TYPE _SB_MAKE64(1) +#define M_DMA_DESC_TYPE _SB_MAKE64(2,S_DMA_DESC_TYPE) +#define V_DMA_DESC_TYPE(x) _SB_MAKEVALUE(x,S_DMA_DESC_TYPE) +#define G_DMA_DESC_TYPE(x) _SB_GETVALUE(x,S_DMA_DESC_TYPE,M_DMA_DESC_TYPE) + +#define K_DMA_DESC_TYPE_RING_AL 0 +#define K_DMA_DESC_TYPE_CHAIN_AL 1 + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define K_DMA_DESC_TYPE_RING_UAL_WI 2 +#define K_DMA_DESC_TYPE_RING_UAL_RMW 3 +#endif + +#define M_DMA_EOP_INT_EN _SB_MAKEMASK1(3) +#define M_DMA_HWM_INT_EN _SB_MAKEMASK1(4) +#define M_DMA_LWM_INT_EN _SB_MAKEMASK1(5) +#define M_DMA_TBX_EN _SB_MAKEMASK1(6) +#define M_DMA_TDX_EN _SB_MAKEMASK1(7) + +#define S_DMA_INT_PKTCNT _SB_MAKE64(8) +#define M_DMA_INT_PKTCNT _SB_MAKEMASK(8,S_DMA_INT_PKTCNT) +#define V_DMA_INT_PKTCNT(x) _SB_MAKEVALUE(x,S_DMA_INT_PKTCNT) +#define G_DMA_INT_PKTCNT(x) _SB_GETVALUE(x,S_DMA_INT_PKTCNT,M_DMA_INT_PKTCNT) + +#define S_DMA_RINGSZ _SB_MAKE64(16) +#define M_DMA_RINGSZ _SB_MAKEMASK(16,S_DMA_RINGSZ) +#define V_DMA_RINGSZ(x) _SB_MAKEVALUE(x,S_DMA_RINGSZ) +#define G_DMA_RINGSZ(x) _SB_GETVALUE(x,S_DMA_RINGSZ,M_DMA_RINGSZ) + +#define S_DMA_HIGH_WATERMARK _SB_MAKE64(32) +#define M_DMA_HIGH_WATERMARK _SB_MAKEMASK(16,S_DMA_HIGH_WATERMARK) +#define V_DMA_HIGH_WATERMARK(x) _SB_MAKEVALUE(x,S_DMA_HIGH_WATERMARK) +#define G_DMA_HIGH_WATERMARK(x) _SB_GETVALUE(x,S_DMA_HIGH_WATERMARK,M_DMA_HIGH_WATERMARK) + +#define S_DMA_LOW_WATERMARK _SB_MAKE64(48) +#define M_DMA_LOW_WATERMARK _SB_MAKEMASK(16,S_DMA_LOW_WATERMARK) +#define V_DMA_LOW_WATERMARK(x) _SB_MAKEVALUE(x,S_DMA_LOW_WATERMARK) +#define G_DMA_LOW_WATERMARK(x) _SB_GETVALUE(x,S_DMA_LOW_WATERMARK,M_DMA_LOW_WATERMARK) + +/* + * Ethernet and Serial DMA Configuration Register 1 (Table 7-5) + * Registers: DMA_CONFIG1_MAC_x_RX_CH_0 + * Registers: DMA_CONFIG1_DMA_x_TX_CH_0 + * Registers: DMA_CONFIG1_SER_x_RX + * Registers: DMA_CONFIG1_SER_x_TX + */ + +#define M_DMA_HDR_CF_EN _SB_MAKEMASK1(0) +#define M_DMA_ASIC_XFR_EN _SB_MAKEMASK1(1) +#define M_DMA_PRE_ADDR_EN _SB_MAKEMASK1(2) +#define M_DMA_FLOW_CTL_EN _SB_MAKEMASK1(3) +#define M_DMA_NO_DSCR_UPDT _SB_MAKEMASK1(4) +#define M_DMA_L2CA _SB_MAKEMASK1(5) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define M_DMA_RX_XTRA_STATUS _SB_MAKEMASK1(6) +#define M_DMA_TX_CPU_PAUSE _SB_MAKEMASK1(6) +#define M_DMA_TX_FC_PAUSE_EN _SB_MAKEMASK1(7) +#endif + +#define M_DMA_MBZ1 _SB_MAKEMASK(6,15) + +#define S_DMA_HDR_SIZE _SB_MAKE64(21) +#define M_DMA_HDR_SIZE _SB_MAKEMASK(9,S_DMA_HDR_SIZE) +#define V_DMA_HDR_SIZE(x) _SB_MAKEVALUE(x,S_DMA_HDR_SIZE) +#define G_DMA_HDR_SIZE(x) _SB_GETVALUE(x,S_DMA_HDR_SIZE,M_DMA_HDR_SIZE) + +#define M_DMA_MBZ2 _SB_MAKEMASK(5,32) + +#define S_DMA_ASICXFR_SIZE _SB_MAKE64(37) +#define M_DMA_ASICXFR_SIZE _SB_MAKEMASK(9,S_DMA_ASICXFR_SIZE) +#define V_DMA_ASICXFR_SIZE(x) _SB_MAKEVALUE(x,S_DMA_ASICXFR_SIZE) +#define G_DMA_ASICXFR_SIZE(x) _SB_GETVALUE(x,S_DMA_ASICXFR_SIZE,M_DMA_ASICXFR_SIZE) + +#define S_DMA_INT_TIMEOUT _SB_MAKE64(48) +#define M_DMA_INT_TIMEOUT _SB_MAKEMASK(16,S_DMA_INT_TIMEOUT) +#define V_DMA_INT_TIMEOUT(x) _SB_MAKEVALUE(x,S_DMA_INT_TIMEOUT) +#define G_DMA_INT_TIMEOUT(x) _SB_GETVALUE(x,S_DMA_INT_TIMEOUT,M_DMA_INT_TIMEOUT) + +/* + * Ethernet and Serial DMA Descriptor base address (Table 7-6) + */ + +#define M_DMA_DSCRBASE_MBZ _SB_MAKEMASK(4,0) + + +/* + * ASIC Mode Base Address (Table 7-7) + */ + +#define M_DMA_ASIC_BASE_MBZ _SB_MAKEMASK(20,0) + +/* + * DMA Descriptor Count Registers (Table 7-8) + */ + +/* No bitfields */ + + +/* + * Current Descriptor Address Register (Table 7-11) + */ + +#define S_DMA_CURDSCR_ADDR _SB_MAKE64(0) +#define M_DMA_CURDSCR_ADDR _SB_MAKEMASK(40,S_DMA_CURDSCR_ADDR) +#define S_DMA_CURDSCR_COUNT _SB_MAKE64(40) +#define M_DMA_CURDSCR_COUNT _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define M_DMA_TX_CH_PAUSE_ON _SB_MAKEMASK1(56) +#endif + +/* + * Receive Packet Drop Registers + */ +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_OODLOST_RX _SB_MAKE64(0) +#define M_DMA_OODLOST_RX _SB_MAKEMASK(16,S_DMA_OODLOST_RX) +#define G_DMA_OODLOST_RX(x) _SB_GETVALUE(x,S_DMA_OODLOST_RX,M_DMA_OODLOST_RX) + +#define S_DMA_EOP_COUNT_RX _SB_MAKE64(16) +#define M_DMA_EOP_COUNT_RX _SB_MAKEMASK(8,S_DMA_EOP_COUNT_RX) +#define G_DMA_EOP_COUNT_RX(x) _SB_GETVALUE(x,S_DMA_EOP_COUNT_RX,M_DMA_EOP_COUNT_RX) +#endif + +/* ********************************************************************* + * DMA Descriptors + ********************************************************************* */ + +/* + * Descriptor doubleword "A" (Table 7-12) + */ + +#define S_DMA_DSCRA_OFFSET _SB_MAKE64(0) +#define M_DMA_DSCRA_OFFSET _SB_MAKEMASK(5,S_DMA_DSCRA_OFFSET) +#define V_DMA_DSCRA_OFFSET(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_OFFSET) +#define G_DMA_DSCRA_OFFSET(x) _SB_GETVALUE(x,S_DMA_DSCRA_OFFSET,M_DMA_DSCRA_OFFSET) + +/* Note: Don't shift the address over, just mask it with the mask below */ +#define S_DMA_DSCRA_A_ADDR _SB_MAKE64(5) +#define M_DMA_DSCRA_A_ADDR _SB_MAKEMASK(35,S_DMA_DSCRA_A_ADDR) + +#define M_DMA_DSCRA_A_ADDR_OFFSET (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRA_A_ADDR_UA _SB_MAKE64(0) +#define M_DMA_DSCRA_A_ADDR_UA _SB_MAKEMASK(40,S_DMA_DSCRA_A_ADDR_UA) +#endif + +#define S_DMA_DSCRA_A_SIZE _SB_MAKE64(40) +#define M_DMA_DSCRA_A_SIZE _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE) +#define V_DMA_DSCRA_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE) +#define G_DMA_DSCRA_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRA_DSCR_CNT _SB_MAKE64(40) +#define M_DMA_DSCRA_DSCR_CNT _SB_MAKEMASK(8,S_DMA_DSCRA_DSCR_CNT) +#define G_DMA_DSCRA_DSCR_CNT(x) _SB_GETVALUE(x,S_DMA_DSCRA_DSCR_CNT,M_DMA_DSCRA_DSCR_CNT) +#endif + +#define M_DMA_DSCRA_INTERRUPT _SB_MAKEMASK1(49) +#define M_DMA_DSCRA_OFFSETB _SB_MAKEMASK1(50) + +#define S_DMA_DSCRA_STATUS _SB_MAKE64(51) +#define M_DMA_DSCRA_STATUS _SB_MAKEMASK(13,S_DMA_DSCRA_STATUS) +#define V_DMA_DSCRA_STATUS(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_STATUS) +#define G_DMA_DSCRA_STATUS(x) _SB_GETVALUE(x,S_DMA_DSCRA_STATUS,M_DMA_DSCRA_STATUS) + +/* + * Descriptor doubleword "B" (Table 7-13) + */ + + +#define S_DMA_DSCRB_OPTIONS _SB_MAKE64(0) +#define M_DMA_DSCRB_OPTIONS _SB_MAKEMASK(4,S_DMA_DSCRB_OPTIONS) +#define V_DMA_DSCRB_OPTIONS(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS) +#define G_DMA_DSCRB_OPTIONS(x) _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRB_A_SIZE _SB_MAKE64(8) +#define M_DMA_DSCRB_A_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_A_SIZE) +#define V_DMA_DSCRB_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_A_SIZE) +#define G_DMA_DSCRB_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_A_SIZE,M_DMA_DSCRB_A_SIZE) +#endif + +#define R_DMA_DSCRB_ADDR _SB_MAKE64(0x10) + +/* Note: Don't shift the address over, just mask it with the mask below */ +#define S_DMA_DSCRB_B_ADDR _SB_MAKE64(5) +#define M_DMA_DSCRB_B_ADDR _SB_MAKEMASK(35,S_DMA_DSCRB_B_ADDR) + +#define S_DMA_DSCRB_B_SIZE _SB_MAKE64(40) +#define M_DMA_DSCRB_B_SIZE _SB_MAKEMASK(9,S_DMA_DSCRB_B_SIZE) +#define V_DMA_DSCRB_B_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_B_SIZE) +#define G_DMA_DSCRB_B_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_B_SIZE,M_DMA_DSCRB_B_SIZE) + +#define M_DMA_DSCRB_B_VALID _SB_MAKEMASK1(49) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKE64(48) +#define M_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKEMASK(2,S_DMA_DSCRB_PKT_SIZE_MSB) +#define V_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB) +#define G_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB,M_DMA_DSCRB_PKT_SIZE_MSB) +#endif + +#define S_DMA_DSCRB_PKT_SIZE _SB_MAKE64(50) +#define M_DMA_DSCRB_PKT_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE) +#define V_DMA_DSCRB_PKT_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE) +#define G_DMA_DSCRB_PKT_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE,M_DMA_DSCRB_PKT_SIZE) + +/* + * from pass2 some bits in dscr_b are also used for rx status + */ +#define S_DMA_DSCRB_STATUS _SB_MAKE64(0) +#define M_DMA_DSCRB_STATUS _SB_MAKEMASK(1,S_DMA_DSCRB_STATUS) +#define V_DMA_DSCRB_STATUS(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_STATUS) +#define G_DMA_DSCRB_STATUS(x) _SB_GETVALUE(x,S_DMA_DSCRB_STATUS,M_DMA_DSCRB_STATUS) + +/* + * Ethernet Descriptor Status Bits (Table 7-15) + */ + +#define M_DMA_ETHRX_BADIP4CS _SB_MAKEMASK1(51) +#define M_DMA_ETHRX_DSCRERR _SB_MAKEMASK1(52) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +/* Note: BADTCPCS is actually in DSCR_B options field */ +#define M_DMA_ETHRX_BADTCPCS _SB_MAKEMASK1(0) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define M_DMA_ETH_VLAN_FLAG _SB_MAKEMASK1(1) +#define M_DMA_ETH_CRC_FLAG _SB_MAKEMASK1(2) +#endif + +#define S_DMA_ETHRX_RXCH 53 +#define M_DMA_ETHRX_RXCH _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH) +#define V_DMA_ETHRX_RXCH(x) _SB_MAKEVALUE(x,S_DMA_ETHRX_RXCH) +#define G_DMA_ETHRX_RXCH(x) _SB_GETVALUE(x,S_DMA_ETHRX_RXCH,M_DMA_ETHRX_RXCH) + +#define S_DMA_ETHRX_PKTTYPE 55 +#define M_DMA_ETHRX_PKTTYPE _SB_MAKEMASK(3,S_DMA_ETHRX_PKTTYPE) +#define V_DMA_ETHRX_PKTTYPE(x) _SB_MAKEVALUE(x,S_DMA_ETHRX_PKTTYPE) +#define G_DMA_ETHRX_PKTTYPE(x) _SB_GETVALUE(x,S_DMA_ETHRX_PKTTYPE,M_DMA_ETHRX_PKTTYPE) + +#define K_DMA_ETHRX_PKTTYPE_IPV4 0 +#define K_DMA_ETHRX_PKTTYPE_ARPV4 1 +#define K_DMA_ETHRX_PKTTYPE_802 2 +#define K_DMA_ETHRX_PKTTYPE_OTHER 3 +#define K_DMA_ETHRX_PKTTYPE_USER0 4 +#define K_DMA_ETHRX_PKTTYPE_USER1 5 +#define K_DMA_ETHRX_PKTTYPE_USER2 6 +#define K_DMA_ETHRX_PKTTYPE_USER3 7 + +#define M_DMA_ETHRX_MATCH_HASH _SB_MAKEMASK1(58) +#define M_DMA_ETHRX_MATCH_EXACT _SB_MAKEMASK1(59) +#define M_DMA_ETHRX_BCAST _SB_MAKEMASK1(60) +#define M_DMA_ETHRX_MCAST _SB_MAKEMASK1(61) +#define M_DMA_ETHRX_BAD _SB_MAKEMASK1(62) +#define M_DMA_ETHRX_SOP _SB_MAKEMASK1(63) + +/* + * Ethernet Transmit Status Bits (Table 7-16) + */ + +#define M_DMA_ETHTX_SOP _SB_MAKEMASK1(63) + +/* + * Ethernet Transmit Options (Table 7-17) + */ + +#define K_DMA_ETHTX_NOTSOP _SB_MAKE64(0x00) +#define K_DMA_ETHTX_APPENDCRC _SB_MAKE64(0x01) +#define K_DMA_ETHTX_REPLACECRC _SB_MAKE64(0x02) +#define K_DMA_ETHTX_APPENDCRC_APPENDPAD _SB_MAKE64(0x03) +#define K_DMA_ETHTX_APPENDVLAN_REPLACECRC _SB_MAKE64(0x04) +#define K_DMA_ETHTX_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x05) +#define K_DMA_ETHTX_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x6) +#define K_DMA_ETHTX_NOMODS _SB_MAKE64(0x07) +#define K_DMA_ETHTX_RESERVED1 _SB_MAKE64(0x08) +#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC _SB_MAKE64(0x09) +#define K_DMA_ETHTX_REPLACESADDR_REPLACECRC _SB_MAKE64(0x0A) +#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC_APPENDPAD _SB_MAKE64(0x0B) +#define K_DMA_ETHTX_REPLACESADDR_APPENDVLAN_REPLACECRC _SB_MAKE64(0x0C) +#define K_DMA_ETHTX_REPLACESADDR_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x0D) +#define K_DMA_ETHTX_REPLACESADDR_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x0E) +#define K_DMA_ETHTX_RESERVED2 _SB_MAKE64(0x0F) + +/* + * Serial Receive Options (Table 7-18) + */ +#define M_DMA_SERRX_CRC_ERROR _SB_MAKEMASK1(56) +#define M_DMA_SERRX_ABORT _SB_MAKEMASK1(57) +#define M_DMA_SERRX_OCTET_ERROR _SB_MAKEMASK1(58) +#define M_DMA_SERRX_LONGFRAME_ERROR _SB_MAKEMASK1(59) +#define M_DMA_SERRX_SHORTFRAME_ERROR _SB_MAKEMASK1(60) +#define M_DMA_SERRX_OVERRUN_ERROR _SB_MAKEMASK1(61) +#define M_DMA_SERRX_GOOD _SB_MAKEMASK1(62) +#define M_DMA_SERRX_SOP _SB_MAKEMASK1(63) + +/* + * Serial Transmit Status Bits (Table 7-20) + */ + +#define M_DMA_SERTX_FLAG _SB_MAKEMASK1(63) + +/* + * Serial Transmit Options (Table 7-21) + */ + +#define K_DMA_SERTX_RESERVED _SB_MAKEMASK1(0) +#define K_DMA_SERTX_APPENDCRC _SB_MAKEMASK1(1) +#define K_DMA_SERTX_APPENDPAD _SB_MAKEMASK1(2) +#define K_DMA_SERTX_ABORT _SB_MAKEMASK1(3) + + +/* ********************************************************************* + * Data Mover Registers + ********************************************************************* */ + +/* + * Data Mover Descriptor Base Address Register (Table 7-22) + * Register: DM_DSCR_BASE_0 + * Register: DM_DSCR_BASE_1 + * Register: DM_DSCR_BASE_2 + * Register: DM_DSCR_BASE_3 + */ + +#define M_DM_DSCR_BASE_MBZ _SB_MAKEMASK(4,0) + +/* Note: Just mask the base address and then OR it in. */ +#define S_DM_DSCR_BASE_ADDR _SB_MAKE64(4) +#define M_DM_DSCR_BASE_ADDR _SB_MAKEMASK(36,S_DM_DSCR_BASE_ADDR) + +#define S_DM_DSCR_BASE_RINGSZ _SB_MAKE64(40) +#define M_DM_DSCR_BASE_RINGSZ _SB_MAKEMASK(16,S_DM_DSCR_BASE_RINGSZ) +#define V_DM_DSCR_BASE_RINGSZ(x) _SB_MAKEVALUE(x,S_DM_DSCR_BASE_RINGSZ) +#define G_DM_DSCR_BASE_RINGSZ(x) _SB_GETVALUE(x,S_DM_DSCR_BASE_RINGSZ,M_DM_DSCR_BASE_RINGSZ) + +#define S_DM_DSCR_BASE_PRIORITY _SB_MAKE64(56) +#define M_DM_DSCR_BASE_PRIORITY _SB_MAKEMASK(3,S_DM_DSCR_BASE_PRIORITY) +#define V_DM_DSCR_BASE_PRIORITY(x) _SB_MAKEVALUE(x,S_DM_DSCR_BASE_PRIORITY) +#define G_DM_DSCR_BASE_PRIORITY(x) _SB_GETVALUE(x,S_DM_DSCR_BASE_PRIORITY,M_DM_DSCR_BASE_PRIORITY) + +#define K_DM_DSCR_BASE_PRIORITY_1 0 +#define K_DM_DSCR_BASE_PRIORITY_2 1 +#define K_DM_DSCR_BASE_PRIORITY_4 2 +#define K_DM_DSCR_BASE_PRIORITY_8 3 +#define K_DM_DSCR_BASE_PRIORITY_16 4 + +#define M_DM_DSCR_BASE_ACTIVE _SB_MAKEMASK1(59) +#define M_DM_DSCR_BASE_INTERRUPT _SB_MAKEMASK1(60) +#define M_DM_DSCR_BASE_RESET _SB_MAKEMASK1(61) /* write register */ +#define M_DM_DSCR_BASE_ERROR _SB_MAKEMASK1(61) /* read register */ +#define M_DM_DSCR_BASE_ABORT _SB_MAKEMASK1(62) +#define M_DM_DSCR_BASE_ENABL _SB_MAKEMASK1(63) + +/* + * Data Mover Descriptor Count Register (Table 7-25) + */ + +/* no bitfields */ + +/* + * Data Mover Current Descriptor Address (Table 7-24) + * Register: DM_CUR_DSCR_ADDR_0 + * Register: DM_CUR_DSCR_ADDR_1 + * Register: DM_CUR_DSCR_ADDR_2 + * Register: DM_CUR_DSCR_ADDR_3 + */ + +#define S_DM_CUR_DSCR_DSCR_ADDR _SB_MAKE64(0) +#define M_DM_CUR_DSCR_DSCR_ADDR _SB_MAKEMASK(40,S_DM_CUR_DSCR_DSCR_ADDR) + +#define S_DM_CUR_DSCR_DSCR_COUNT _SB_MAKE64(48) +#define M_DM_CUR_DSCR_DSCR_COUNT _SB_MAKEMASK(16,S_DM_CUR_DSCR_DSCR_COUNT) +#define V_DM_CUR_DSCR_DSCR_COUNT(r) _SB_MAKEVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT) +#define G_DM_CUR_DSCR_DSCR_COUNT(r) _SB_GETVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT,\ + M_DM_CUR_DSCR_DSCR_COUNT) + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Data Mover Channel Partial Result Registers + * Register: DM_PARTIAL_0 + * Register: DM_PARTIAL_1 + * Register: DM_PARTIAL_2 + * Register: DM_PARTIAL_3 + */ +#define S_DM_PARTIAL_CRC_PARTIAL _SB_MAKE64(0) +#define M_DM_PARTIAL_CRC_PARTIAL _SB_MAKEMASK(32,S_DM_PARTIAL_CRC_PARTIAL) +#define V_DM_PARTIAL_CRC_PARTIAL(r) _SB_MAKEVALUE(r,S_DM_PARTIAL_CRC_PARTIAL) +#define G_DM_PARTIAL_CRC_PARTIAL(r) _SB_GETVALUE(r,S_DM_PARTIAL_CRC_PARTIAL,\ + M_DM_PARTIAL_CRC_PARTIAL) + +#define S_DM_PARTIAL_TCPCS_PARTIAL _SB_MAKE64(32) +#define M_DM_PARTIAL_TCPCS_PARTIAL _SB_MAKEMASK(16,S_DM_PARTIAL_TCPCS_PARTIAL) +#define V_DM_PARTIAL_TCPCS_PARTIAL(r) _SB_MAKEVALUE(r,S_DM_PARTIAL_TCPCS_PARTIAL) +#define G_DM_PARTIAL_TCPCS_PARTIAL(r) _SB_GETVALUE(r,S_DM_PARTIAL_TCPCS_PARTIAL,\ + M_DM_PARTIAL_TCPCS_PARTIAL) + +#define M_DM_PARTIAL_ODD_BYTE _SB_MAKEMASK1(48) +#endif /* 112x PASS1 */ + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Data Mover CRC Definition Registers + * Register: CRC_DEF_0 + * Register: CRC_DEF_1 + */ +#define S_CRC_DEF_CRC_INIT _SB_MAKE64(0) +#define M_CRC_DEF_CRC_INIT _SB_MAKEMASK(32,S_CRC_DEF_CRC_INIT) +#define V_CRC_DEF_CRC_INIT(r) _SB_MAKEVALUE(r,S_CRC_DEF_CRC_INIT) +#define G_CRC_DEF_CRC_INIT(r) _SB_GETVALUE(r,S_CRC_DEF_CRC_INIT,\ + M_CRC_DEF_CRC_INIT) + +#define S_CRC_DEF_CRC_POLY _SB_MAKE64(32) +#define M_CRC_DEF_CRC_POLY _SB_MAKEMASK(32,S_CRC_DEF_CRC_POLY) +#define V_CRC_DEF_CRC_POLY(r) _SB_MAKEVALUE(r,S_CRC_DEF_CRC_POLY) +#define G_CRC_DEF_CRC_POLY(r) _SB_GETVALUE(r,S_CRC_DEF_CRC_POLY,\ + M_CRC_DEF_CRC_POLY) +#endif /* 112x PASS1 */ + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Data Mover CRC/Checksum Definition Registers + * Register: CTCP_DEF_0 + * Register: CTCP_DEF_1 + */ +#define S_CTCP_DEF_CRC_TXOR _SB_MAKE64(0) +#define M_CTCP_DEF_CRC_TXOR _SB_MAKEMASK(32,S_CTCP_DEF_CRC_TXOR) +#define V_CTCP_DEF_CRC_TXOR(r) _SB_MAKEVALUE(r,S_CTCP_DEF_CRC_TXOR) +#define G_CTCP_DEF_CRC_TXOR(r) _SB_GETVALUE(r,S_CTCP_DEF_CRC_TXOR,\ + M_CTCP_DEF_CRC_TXOR) + +#define S_CTCP_DEF_TCPCS_INIT _SB_MAKE64(32) +#define M_CTCP_DEF_TCPCS_INIT _SB_MAKEMASK(16,S_CTCP_DEF_TCPCS_INIT) +#define V_CTCP_DEF_TCPCS_INIT(r) _SB_MAKEVALUE(r,S_CTCP_DEF_TCPCS_INIT) +#define G_CTCP_DEF_TCPCS_INIT(r) _SB_GETVALUE(r,S_CTCP_DEF_TCPCS_INIT,\ + M_CTCP_DEF_TCPCS_INIT) + +#define S_CTCP_DEF_CRC_WIDTH _SB_MAKE64(48) +#define M_CTCP_DEF_CRC_WIDTH _SB_MAKEMASK(2,S_CTCP_DEF_CRC_WIDTH) +#define V_CTCP_DEF_CRC_WIDTH(r) _SB_MAKEVALUE(r,S_CTCP_DEF_CRC_WIDTH) +#define G_CTCP_DEF_CRC_WIDTH(r) _SB_GETVALUE(r,S_CTCP_DEF_CRC_WIDTH,\ + M_CTCP_DEF_CRC_WIDTH) + +#define K_CTCP_DEF_CRC_WIDTH_4 0 +#define K_CTCP_DEF_CRC_WIDTH_2 1 +#define K_CTCP_DEF_CRC_WIDTH_1 2 + +#define M_CTCP_DEF_CRC_BIT_ORDER _SB_MAKEMASK1(50) +#endif /* 112x PASS1 */ + + +/* + * Data Mover Descriptor Doubleword "A" (Table 7-26) + */ + +#define S_DM_DSCRA_DST_ADDR _SB_MAKE64(0) +#define M_DM_DSCRA_DST_ADDR _SB_MAKEMASK(40,S_DM_DSCRA_DST_ADDR) + +#define M_DM_DSCRA_UN_DEST _SB_MAKEMASK1(40) +#define M_DM_DSCRA_UN_SRC _SB_MAKEMASK1(41) +#define M_DM_DSCRA_INTERRUPT _SB_MAKEMASK1(42) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +#define M_DM_DSCRA_THROTTLE _SB_MAKEMASK1(43) +#endif /* up to 1250 PASS1 */ + +#define S_DM_DSCRA_DIR_DEST _SB_MAKE64(44) +#define M_DM_DSCRA_DIR_DEST _SB_MAKEMASK(2,S_DM_DSCRA_DIR_DEST) +#define V_DM_DSCRA_DIR_DEST(x) _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_DEST) +#define G_DM_DSCRA_DIR_DEST(x) _SB_GETVALUE(x,S_DM_DSCRA_DIR_DEST,M_DM_DSCRA_DIR_DEST) + +#define K_DM_DSCRA_DIR_DEST_INCR 0 +#define K_DM_DSCRA_DIR_DEST_DECR 1 +#define K_DM_DSCRA_DIR_DEST_CONST 2 + +#define V_DM_DSCRA_DIR_DEST_INCR _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_INCR,S_DM_DSCRA_DIR_DEST) +#define V_DM_DSCRA_DIR_DEST_DECR _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_DECR,S_DM_DSCRA_DIR_DEST) +#define V_DM_DSCRA_DIR_DEST_CONST _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_CONST,S_DM_DSCRA_DIR_DEST) + +#define S_DM_DSCRA_DIR_SRC _SB_MAKE64(46) +#define M_DM_DSCRA_DIR_SRC _SB_MAKEMASK(2,S_DM_DSCRA_DIR_SRC) +#define V_DM_DSCRA_DIR_SRC(x) _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_SRC) +#define G_DM_DSCRA_DIR_SRC(x) _SB_GETVALUE(x,S_DM_DSCRA_DIR_SRC,M_DM_DSCRA_DIR_SRC) + +#define K_DM_DSCRA_DIR_SRC_INCR 0 +#define K_DM_DSCRA_DIR_SRC_DECR 1 +#define K_DM_DSCRA_DIR_SRC_CONST 2 + +#define V_DM_DSCRA_DIR_SRC_INCR _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_INCR,S_DM_DSCRA_DIR_SRC) +#define V_DM_DSCRA_DIR_SRC_DECR _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_DECR,S_DM_DSCRA_DIR_SRC) +#define V_DM_DSCRA_DIR_SRC_CONST _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_CONST,S_DM_DSCRA_DIR_SRC) + + +#define M_DM_DSCRA_ZERO_MEM _SB_MAKEMASK1(48) +#define M_DM_DSCRA_PREFETCH _SB_MAKEMASK1(49) +#define M_DM_DSCRA_L2C_DEST _SB_MAKEMASK1(50) +#define M_DM_DSCRA_L2C_SRC _SB_MAKEMASK1(51) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_DM_DSCRA_RD_BKOFF _SB_MAKEMASK1(52) +#define M_DM_DSCRA_WR_BKOFF _SB_MAKEMASK1(53) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_DM_DSCRA_TCPCS_EN _SB_MAKEMASK1(54) +#define M_DM_DSCRA_TCPCS_RES _SB_MAKEMASK1(55) +#define M_DM_DSCRA_TCPCS_AP _SB_MAKEMASK1(56) +#define M_DM_DSCRA_CRC_EN _SB_MAKEMASK1(57) +#define M_DM_DSCRA_CRC_RES _SB_MAKEMASK1(58) +#define M_DM_DSCRA_CRC_AP _SB_MAKEMASK1(59) +#define M_DM_DSCRA_CRC_DFN _SB_MAKEMASK1(60) +#define M_DM_DSCRA_CRC_XBIT _SB_MAKEMASK1(61) +#endif /* 112x PASS1 */ + +#define M_DM_DSCRA_RESERVED2 _SB_MAKEMASK(3,61) + +/* + * Data Mover Descriptor Doubleword "B" (Table 7-25) + */ + +#define S_DM_DSCRB_SRC_ADDR _SB_MAKE64(0) +#define M_DM_DSCRB_SRC_ADDR _SB_MAKEMASK(40,S_DM_DSCRB_SRC_ADDR) + +#define S_DM_DSCRB_SRC_LENGTH _SB_MAKE64(40) +#define M_DM_DSCRB_SRC_LENGTH _SB_MAKEMASK(20,S_DM_DSCRB_SRC_LENGTH) +#define V_DM_DSCRB_SRC_LENGTH(x) _SB_MAKEVALUE(x,S_DM_DSCRB_SRC_LENGTH) +#define G_DM_DSCRB_SRC_LENGTH(x) _SB_GETVALUE(x,S_DM_DSCRB_SRC_LENGTH,M_DM_DSCRB_SRC_LENGTH) + + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_genbus.h b/include/asm-mips/sibyte/sb1250_genbus.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_genbus.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,276 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Generic Bus Constants File: sb1250_genbus.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's Generic Bus interface + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_GENBUS_H +#define _SB1250_GENBUS_H + +#include "sb1250_defs.h" + +/* + * Generic Bus Region Configuration Registers (Table 11-4) + */ + +#define S_IO_RDY_ACTIVE 0 +#define M_IO_RDY_ACTIVE _SB_MAKEMASK1(S_IO_RDY_ACTIVE) + +#define S_IO_ENA_RDY 1 +#define M_IO_ENA_RDY _SB_MAKEMASK1(S_IO_ENA_RDY) + +#define S_IO_WIDTH_SEL 2 +#define M_IO_WIDTH_SEL _SB_MAKEMASK(2,S_IO_WIDTH_SEL) +#define K_IO_WIDTH_SEL_1 0 +#define K_IO_WIDTH_SEL_2 1 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define K_IO_WIDTH_SEL_1L 2 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define K_IO_WIDTH_SEL_4 3 +#define V_IO_WIDTH_SEL(x) _SB_MAKEVALUE(x,S_IO_WIDTH_SEL) +#define G_IO_WIDTH_SEL(x) _SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL) + +#define S_IO_PARITY_ENA 4 +#define M_IO_PARITY_ENA _SB_MAKEMASK1(S_IO_PARITY_ENA) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_IO_BURST_EN 5 +#define M_IO_BURST_EN _SB_MAKEMASK1(S_IO_BURST_EN) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define S_IO_PARITY_ODD 6 +#define M_IO_PARITY_ODD _SB_MAKEMASK1(S_IO_PARITY_ODD) +#define S_IO_NONMUX 7 +#define M_IO_NONMUX _SB_MAKEMASK1(S_IO_NONMUX) + +#define S_IO_TIMEOUT 8 +#define M_IO_TIMEOUT _SB_MAKEMASK(8,S_IO_TIMEOUT) +#define V_IO_TIMEOUT(x) _SB_MAKEVALUE(x,S_IO_TIMEOUT) +#define G_IO_TIMEOUT(x) _SB_GETVALUE(x,S_IO_TIMEOUT,M_IO_TIMEOUT) + +/* + * Generic Bus Region Size register (Table 11-5) + */ + +#define S_IO_MULT_SIZE 0 +#define M_IO_MULT_SIZE _SB_MAKEMASK(12,S_IO_MULT_SIZE) +#define V_IO_MULT_SIZE(x) _SB_MAKEVALUE(x,S_IO_MULT_SIZE) +#define G_IO_MULT_SIZE(x) _SB_GETVALUE(x,S_IO_MULT_SIZE,M_IO_MULT_SIZE) + +#define S_IO_REGSIZE 16 /* # bits to shift size for this reg */ + +/* + * Generic Bus Region Address (Table 11-6) + */ + +#define S_IO_START_ADDR 0 +#define M_IO_START_ADDR _SB_MAKEMASK(14,S_IO_START_ADDR) +#define V_IO_START_ADDR(x) _SB_MAKEVALUE(x,S_IO_START_ADDR) +#define G_IO_START_ADDR(x) _SB_GETVALUE(x,S_IO_START_ADDR,M_IO_START_ADDR) + +#define S_IO_ADDRBASE 16 /* # bits to shift addr for this reg */ + +/* + * Generic Bus Region 0 Timing Registers (Table 11-7) + */ + +#define S_IO_ALE_WIDTH 0 +#define M_IO_ALE_WIDTH _SB_MAKEMASK(3,S_IO_ALE_WIDTH) +#define V_IO_ALE_WIDTH(x) _SB_MAKEVALUE(x,S_IO_ALE_WIDTH) +#define G_IO_ALE_WIDTH(x) _SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_IO_EARLY_CS _SB_MAKEMASK1(3) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_IO_ALE_TO_CS 4 +#define M_IO_ALE_TO_CS _SB_MAKEMASK(2,S_IO_ALE_TO_CS) +#define V_IO_ALE_TO_CS(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_CS) +#define G_IO_ALE_TO_CS(x) _SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_IO_BURST_WIDTH _SB_MAKE64(6) +#define M_IO_BURST_WIDTH _SB_MAKEMASK(2,S_IO_BURST_WIDTH) +#define V_IO_BURST_WIDTH(x) _SB_MAKEVALUE(x,S_IO_BURST_WIDTH) +#define G_IO_BURST_WIDTH(x) _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_IO_CS_WIDTH 8 +#define M_IO_CS_WIDTH _SB_MAKEMASK(5,S_IO_CS_WIDTH) +#define V_IO_CS_WIDTH(x) _SB_MAKEVALUE(x,S_IO_CS_WIDTH) +#define G_IO_CS_WIDTH(x) _SB_GETVALUE(x,S_IO_CS_WIDTH,M_IO_CS_WIDTH) + +#define S_IO_RDY_SMPLE 13 +#define M_IO_RDY_SMPLE _SB_MAKEMASK(3,S_IO_RDY_SMPLE) +#define V_IO_RDY_SMPLE(x) _SB_MAKEVALUE(x,S_IO_RDY_SMPLE) +#define G_IO_RDY_SMPLE(x) _SB_GETVALUE(x,S_IO_RDY_SMPLE,M_IO_RDY_SMPLE) + + +/* + * Generic Bus Timing 1 Registers (Table 11-8) + */ + +#define S_IO_ALE_TO_WRITE 0 +#define M_IO_ALE_TO_WRITE _SB_MAKEMASK(3,S_IO_ALE_TO_WRITE) +#define V_IO_ALE_TO_WRITE(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE) +#define G_IO_ALE_TO_WRITE(x) _SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_IO_RDY_SYNC _SB_MAKEMASK1(3) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_IO_WRITE_WIDTH 4 +#define M_IO_WRITE_WIDTH _SB_MAKEMASK(4,S_IO_WRITE_WIDTH) +#define V_IO_WRITE_WIDTH(x) _SB_MAKEVALUE(x,S_IO_WRITE_WIDTH) +#define G_IO_WRITE_WIDTH(x) _SB_GETVALUE(x,S_IO_WRITE_WIDTH,M_IO_WRITE_WIDTH) + +#define S_IO_IDLE_CYCLE 8 +#define M_IO_IDLE_CYCLE _SB_MAKEMASK(4,S_IO_IDLE_CYCLE) +#define V_IO_IDLE_CYCLE(x) _SB_MAKEVALUE(x,S_IO_IDLE_CYCLE) +#define G_IO_IDLE_CYCLE(x) _SB_GETVALUE(x,S_IO_IDLE_CYCLE,M_IO_IDLE_CYCLE) + +#define S_IO_OE_TO_CS 12 +#define M_IO_OE_TO_CS _SB_MAKEMASK(2,S_IO_OE_TO_CS) +#define V_IO_OE_TO_CS(x) _SB_MAKEVALUE(x,S_IO_OE_TO_CS) +#define G_IO_OE_TO_CS(x) _SB_GETVALUE(x,S_IO_OE_TO_CS,M_IO_OE_TO_CS) + +#define S_IO_CS_TO_OE 14 +#define M_IO_CS_TO_OE _SB_MAKEMASK(2,S_IO_CS_TO_OE) +#define V_IO_CS_TO_OE(x) _SB_MAKEVALUE(x,S_IO_CS_TO_OE) +#define G_IO_CS_TO_OE(x) _SB_GETVALUE(x,S_IO_CS_TO_OE,M_IO_CS_TO_OE) + +/* + * Generic Bus Interrupt Status Register (Table 11-9) + */ + +#define M_IO_CS_ERR_INT _SB_MAKEMASK(0,8) +#define M_IO_CS0_ERR_INT _SB_MAKEMASK1(0) +#define M_IO_CS1_ERR_INT _SB_MAKEMASK1(1) +#define M_IO_CS2_ERR_INT _SB_MAKEMASK1(2) +#define M_IO_CS3_ERR_INT _SB_MAKEMASK1(3) +#define M_IO_CS4_ERR_INT _SB_MAKEMASK1(4) +#define M_IO_CS5_ERR_INT _SB_MAKEMASK1(5) +#define M_IO_CS6_ERR_INT _SB_MAKEMASK1(6) +#define M_IO_CS7_ERR_INT _SB_MAKEMASK1(7) + +#define M_IO_RD_PAR_INT _SB_MAKEMASK1(9) +#define M_IO_TIMEOUT_INT _SB_MAKEMASK1(10) +#define M_IO_ILL_ADDR_INT _SB_MAKEMASK1(11) +#define M_IO_MULT_CS_INT _SB_MAKEMASK1(12) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_IO_COH_ERR _SB_MAKEMASK1(14) +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * PCMCIA configuration register (Table 12-6) + */ + +#define M_PCMCIA_CFG_ATTRMEM _SB_MAKEMASK1(0) +#define M_PCMCIA_CFG_3VEN _SB_MAKEMASK1(1) +#define M_PCMCIA_CFG_5VEN _SB_MAKEMASK1(2) +#define M_PCMCIA_CFG_VPPEN _SB_MAKEMASK1(3) +#define M_PCMCIA_CFG_RESET _SB_MAKEMASK1(4) +#define M_PCMCIA_CFG_APWRONEN _SB_MAKEMASK1(5) +#define M_PCMCIA_CFG_CDMASK _SB_MAKEMASK1(6) +#define M_PCMCIA_CFG_WPMASK _SB_MAKEMASK1(7) +#define M_PCMCIA_CFG_RDYMASK _SB_MAKEMASK1(8) +#define M_PCMCIA_CFG_PWRCTL _SB_MAKEMASK1(9) + +/* + * PCMCIA status register (Table 12-7) + */ + +#define M_PCMCIA_STATUS_CD1 _SB_MAKEMASK1(0) +#define M_PCMCIA_STATUS_CD2 _SB_MAKEMASK1(1) +#define M_PCMCIA_STATUS_VS1 _SB_MAKEMASK1(2) +#define M_PCMCIA_STATUS_VS2 _SB_MAKEMASK1(3) +#define M_PCMCIA_STATUS_WP _SB_MAKEMASK1(4) +#define M_PCMCIA_STATUS_RDY _SB_MAKEMASK1(5) +#define M_PCMCIA_STATUS_3VEN _SB_MAKEMASK1(6) +#define M_PCMCIA_STATUS_5VEN _SB_MAKEMASK1(7) +#define M_PCMCIA_STATUS_CDCHG _SB_MAKEMASK1(8) +#define M_PCMCIA_STATUS_WPCHG _SB_MAKEMASK1(9) +#define M_PCMCIA_STATUS_RDYCHG _SB_MAKEMASK1(10) + +/* + * GPIO Interrupt Type Register (table 13-3) + */ + +#define K_GPIO_INTR_DISABLE 0 +#define K_GPIO_INTR_EDGE 1 +#define K_GPIO_INTR_LEVEL 2 +#define K_GPIO_INTR_SPLIT 3 + +#define S_GPIO_INTR_TYPEX(n) (((n)/2)*2) +#define M_GPIO_INTR_TYPEX(n) _SB_MAKEMASK(2,S_GPIO_INTR_TYPEX(n)) +#define V_GPIO_INTR_TYPEX(n,x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPEX(n)) +#define G_GPIO_INTR_TYPEX(n,x) _SB_GETVALUE(x,S_GPIO_INTR_TYPEX(n),M_GPIO_INTR_TYPEX(n)) + +#define S_GPIO_INTR_TYPE0 0 +#define M_GPIO_INTR_TYPE0 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE0) +#define V_GPIO_INTR_TYPE0(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE0) +#define G_GPIO_INTR_TYPE0(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE0,M_GPIO_INTR_TYPE0) + +#define S_GPIO_INTR_TYPE2 2 +#define M_GPIO_INTR_TYPE2 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE2) +#define V_GPIO_INTR_TYPE2(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE2) +#define G_GPIO_INTR_TYPE2(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE2,M_GPIO_INTR_TYPE2) + +#define S_GPIO_INTR_TYPE4 4 +#define M_GPIO_INTR_TYPE4 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE4) +#define V_GPIO_INTR_TYPE4(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE4) +#define G_GPIO_INTR_TYPE4(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE4,M_GPIO_INTR_TYPE4) + +#define S_GPIO_INTR_TYPE6 6 +#define M_GPIO_INTR_TYPE6 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE6) +#define V_GPIO_INTR_TYPE6(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE6) +#define G_GPIO_INTR_TYPE6(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE6,M_GPIO_INTR_TYPE6) + +#define S_GPIO_INTR_TYPE8 8 +#define M_GPIO_INTR_TYPE8 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE8) +#define V_GPIO_INTR_TYPE8(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE8) +#define G_GPIO_INTR_TYPE8(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE8,M_GPIO_INTR_TYPE8) + +#define S_GPIO_INTR_TYPE10 10 +#define M_GPIO_INTR_TYPE10 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE10) +#define V_GPIO_INTR_TYPE10(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE10) +#define G_GPIO_INTR_TYPE10(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE10,M_GPIO_INTR_TYPE10) + +#define S_GPIO_INTR_TYPE12 12 +#define M_GPIO_INTR_TYPE12 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE12) +#define V_GPIO_INTR_TYPE12(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE12) +#define G_GPIO_INTR_TYPE12(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE12,M_GPIO_INTR_TYPE12) + +#define S_GPIO_INTR_TYPE14 14 +#define M_GPIO_INTR_TYPE14 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE14) +#define V_GPIO_INTR_TYPE14(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14) +#define G_GPIO_INTR_TYPE14(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14) + + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_int.h b/include/asm-mips/sibyte/sb1250_int.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_int.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,247 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Interrupt Mapper definitions File: sb1250_int.h + * + * This module contains constants for manipulating the SB1250's + * interrupt mapper and definitions for the interrupt sources. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_INT_H +#define _SB1250_INT_H + +#include "sb1250_defs.h" + +/* ********************************************************************* + * Interrupt Mapper Constants + ********************************************************************* */ + +/* + * Interrupt sources (Table 4-8, UM 0.2) + * + * First, the interrupt numbers. + */ + +#define K_INT_WATCHDOG_TIMER_0 0 +#define K_INT_WATCHDOG_TIMER_1 1 +#define K_INT_TIMER_0 2 +#define K_INT_TIMER_1 3 +#define K_INT_TIMER_2 4 +#define K_INT_TIMER_3 5 +#define K_INT_SMB_0 6 +#define K_INT_SMB_1 7 +#define K_INT_UART_0 8 +#define K_INT_UART_1 9 +#define K_INT_SER_0 10 +#define K_INT_SER_1 11 +#define K_INT_PCMCIA 12 +#define K_INT_ADDR_TRAP 13 +#define K_INT_PERF_CNT 14 +#define K_INT_TRACE_FREEZE 15 +#define K_INT_BAD_ECC 16 +#define K_INT_COR_ECC 17 +#define K_INT_IO_BUS 18 +#define K_INT_MAC_0 19 +#define K_INT_MAC_1 20 +#define K_INT_MAC_2 21 +#define K_INT_DM_CH_0 22 +#define K_INT_DM_CH_1 23 +#define K_INT_DM_CH_2 24 +#define K_INT_DM_CH_3 25 +#define K_INT_MBOX_0 26 +#define K_INT_MBOX_1 27 +#define K_INT_MBOX_2 28 +#define K_INT_MBOX_3 29 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define K_INT_CYCLE_CP0_INT 30 +#define K_INT_CYCLE_CP1_INT 31 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define K_INT_GPIO_0 32 +#define K_INT_GPIO_1 33 +#define K_INT_GPIO_2 34 +#define K_INT_GPIO_3 35 +#define K_INT_GPIO_4 36 +#define K_INT_GPIO_5 37 +#define K_INT_GPIO_6 38 +#define K_INT_GPIO_7 39 +#define K_INT_GPIO_8 40 +#define K_INT_GPIO_9 41 +#define K_INT_GPIO_10 42 +#define K_INT_GPIO_11 43 +#define K_INT_GPIO_12 44 +#define K_INT_GPIO_13 45 +#define K_INT_GPIO_14 46 +#define K_INT_GPIO_15 47 +#define K_INT_LDT_FATAL 48 +#define K_INT_LDT_NONFATAL 49 +#define K_INT_LDT_SMI 50 +#define K_INT_LDT_NMI 51 +#define K_INT_LDT_INIT 52 +#define K_INT_LDT_STARTUP 53 +#define K_INT_LDT_EXT 54 +#define K_INT_PCI_ERROR 55 +#define K_INT_PCI_INTA 56 +#define K_INT_PCI_INTB 57 +#define K_INT_PCI_INTC 58 +#define K_INT_PCI_INTD 59 +#define K_INT_SPARE_2 60 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define K_INT_MAC_0_CH1 61 +#define K_INT_MAC_1_CH1 62 +#define K_INT_MAC_2_CH1 63 +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * Mask values for each interrupt + */ + +#define M_INT_WATCHDOG_TIMER_0 _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_0) +#define M_INT_WATCHDOG_TIMER_1 _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_1) +#define M_INT_TIMER_0 _SB_MAKEMASK1(K_INT_TIMER_0) +#define M_INT_TIMER_1 _SB_MAKEMASK1(K_INT_TIMER_1) +#define M_INT_TIMER_2 _SB_MAKEMASK1(K_INT_TIMER_2) +#define M_INT_TIMER_3 _SB_MAKEMASK1(K_INT_TIMER_3) +#define M_INT_SMB_0 _SB_MAKEMASK1(K_INT_SMB_0) +#define M_INT_SMB_1 _SB_MAKEMASK1(K_INT_SMB_1) +#define M_INT_UART_0 _SB_MAKEMASK1(K_INT_UART_0) +#define M_INT_UART_1 _SB_MAKEMASK1(K_INT_UART_1) +#define M_INT_SER_0 _SB_MAKEMASK1(K_INT_SER_0) +#define M_INT_SER_1 _SB_MAKEMASK1(K_INT_SER_1) +#define M_INT_PCMCIA _SB_MAKEMASK1(K_INT_PCMCIA) +#define M_INT_ADDR_TRAP _SB_MAKEMASK1(K_INT_ADDR_TRAP) +#define M_INT_PERF_CNT _SB_MAKEMASK1(K_INT_PERF_CNT) +#define M_INT_TRACE_FREEZE _SB_MAKEMASK1(K_INT_TRACE_FREEZE) +#define M_INT_BAD_ECC _SB_MAKEMASK1(K_INT_BAD_ECC) +#define M_INT_COR_ECC _SB_MAKEMASK1(K_INT_COR_ECC) +#define M_INT_IO_BUS _SB_MAKEMASK1(K_INT_IO_BUS) +#define M_INT_MAC_0 _SB_MAKEMASK1(K_INT_MAC_0) +#define M_INT_MAC_1 _SB_MAKEMASK1(K_INT_MAC_1) +#define M_INT_MAC_2 _SB_MAKEMASK1(K_INT_MAC_2) +#define M_INT_DM_CH_0 _SB_MAKEMASK1(K_INT_DM_CH_0) +#define M_INT_DM_CH_1 _SB_MAKEMASK1(K_INT_DM_CH_1) +#define M_INT_DM_CH_2 _SB_MAKEMASK1(K_INT_DM_CH_2) +#define M_INT_DM_CH_3 _SB_MAKEMASK1(K_INT_DM_CH_3) +#define M_INT_MBOX_0 _SB_MAKEMASK1(K_INT_MBOX_0) +#define M_INT_MBOX_1 _SB_MAKEMASK1(K_INT_MBOX_1) +#define M_INT_MBOX_2 _SB_MAKEMASK1(K_INT_MBOX_2) +#define M_INT_MBOX_3 _SB_MAKEMASK1(K_INT_MBOX_3) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_INT_CYCLE_CP0_INT _SB_MAKEMASK1(K_INT_CYCLE_CP0_INT) +#define M_INT_CYCLE_CP1_INT _SB_MAKEMASK1(K_INT_CYCLE_CP1_INT) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define M_INT_GPIO_0 _SB_MAKEMASK1(K_INT_GPIO_0) +#define M_INT_GPIO_1 _SB_MAKEMASK1(K_INT_GPIO_1) +#define M_INT_GPIO_2 _SB_MAKEMASK1(K_INT_GPIO_2) +#define M_INT_GPIO_3 _SB_MAKEMASK1(K_INT_GPIO_3) +#define M_INT_GPIO_4 _SB_MAKEMASK1(K_INT_GPIO_4) +#define M_INT_GPIO_5 _SB_MAKEMASK1(K_INT_GPIO_5) +#define M_INT_GPIO_6 _SB_MAKEMASK1(K_INT_GPIO_6) +#define M_INT_GPIO_7 _SB_MAKEMASK1(K_INT_GPIO_7) +#define M_INT_GPIO_8 _SB_MAKEMASK1(K_INT_GPIO_8) +#define M_INT_GPIO_9 _SB_MAKEMASK1(K_INT_GPIO_9) +#define M_INT_GPIO_10 _SB_MAKEMASK1(K_INT_GPIO_10) +#define M_INT_GPIO_11 _SB_MAKEMASK1(K_INT_GPIO_11) +#define M_INT_GPIO_12 _SB_MAKEMASK1(K_INT_GPIO_12) +#define M_INT_GPIO_13 _SB_MAKEMASK1(K_INT_GPIO_13) +#define M_INT_GPIO_14 _SB_MAKEMASK1(K_INT_GPIO_14) +#define M_INT_GPIO_15 _SB_MAKEMASK1(K_INT_GPIO_15) +#define M_INT_LDT_FATAL _SB_MAKEMASK1(K_INT_LDT_FATAL) +#define M_INT_LDT_NONFATAL _SB_MAKEMASK1(K_INT_LDT_NONFATAL) +#define M_INT_LDT_SMI _SB_MAKEMASK1(K_INT_LDT_SMI) +#define M_INT_LDT_NMI _SB_MAKEMASK1(K_INT_LDT_NMI) +#define M_INT_LDT_INIT _SB_MAKEMASK1(K_INT_LDT_INIT) +#define M_INT_LDT_STARTUP _SB_MAKEMASK1(K_INT_LDT_STARTUP) +#define M_INT_LDT_EXT _SB_MAKEMASK1(K_INT_LDT_EXT) +#define M_INT_PCI_ERROR _SB_MAKEMASK1(K_INT_PCI_ERROR) +#define M_INT_PCI_INTA _SB_MAKEMASK1(K_INT_PCI_INTA) +#define M_INT_PCI_INTB _SB_MAKEMASK1(K_INT_PCI_INTB) +#define M_INT_PCI_INTC _SB_MAKEMASK1(K_INT_PCI_INTC) +#define M_INT_PCI_INTD _SB_MAKEMASK1(K_INT_PCI_INTD) +#define M_INT_SPARE_2 _SB_MAKEMASK1(K_INT_SPARE_2) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_INT_MAC_0_CH1 _SB_MAKEMASK1(K_INT_MAC_0_CH1) +#define M_INT_MAC_1_CH1 _SB_MAKEMASK1(K_INT_MAC_1_CH1) +#define M_INT_MAC_2_CH1 _SB_MAKEMASK1(K_INT_MAC_2_CH1) +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * Interrupt mappings + */ + +#define K_INT_MAP_I0 0 /* interrupt pins on processor */ +#define K_INT_MAP_I1 1 +#define K_INT_MAP_I2 2 +#define K_INT_MAP_I3 3 +#define K_INT_MAP_I4 4 +#define K_INT_MAP_I5 5 +#define K_INT_MAP_NMI 6 /* nonmaskable */ +#define K_INT_MAP_DINT 7 /* debug interrupt */ + +/* + * LDT Interrupt Set Register (table 4-5) + */ + +#define S_INT_LDT_INTMSG 0 +#define M_INT_LDT_INTMSG _SB_MAKEMASK(3,S_INT_LDT_INTMSG) +#define V_INT_LDT_INTMSG(x) _SB_MAKEVALUE(x,S_INT_LDT_INTMSG) +#define G_INT_LDT_INTMSG(x) _SB_GETVALUE(x,S_INT_LDT_INTMSG,M_INT_LDT_INTMSG) + +#define K_INT_LDT_INTMSG_FIXED 0 +#define K_INT_LDT_INTMSG_ARBITRATED 1 +#define K_INT_LDT_INTMSG_SMI 2 +#define K_INT_LDT_INTMSG_NMI 3 +#define K_INT_LDT_INTMSG_INIT 4 +#define K_INT_LDT_INTMSG_STARTUP 5 +#define K_INT_LDT_INTMSG_EXTINT 6 +#define K_INT_LDT_INTMSG_RESERVED 7 + +#define M_INT_LDT_EDGETRIGGER 0 +#define M_INT_LDT_LEVELTRIGGER _SB_MAKEMASK1(3) + +#define M_INT_LDT_PHYSICALDEST 0 +#define M_INT_LDT_LOGICALDEST _SB_MAKEMASK1(4) + +#define S_INT_LDT_INTDEST 5 +#define M_INT_LDT_INTDEST _SB_MAKEMASK(10,S_INT_LDT_INTDEST) +#define V_INT_LDT_INTDEST(x) _SB_MAKEVALUE(x,S_INT_LDT_INTDEST) +#define G_INT_LDT_INTDEST(x) _SB_GETVALUE(x,S_INT_LDT_INTDEST,M_INT_LDT_INTDEST) + +#define S_INT_LDT_VECTOR 13 +#define M_INT_LDT_VECTOR _SB_MAKEMASK(8,S_INT_LDT_VECTOR) +#define V_INT_LDT_VECTOR(x) _SB_MAKEVALUE(x,S_INT_LDT_VECTOR) +#define G_INT_LDT_VECTOR(x) _SB_GETVALUE(x,S_INT_LDT_VECTOR,M_INT_LDT_VECTOR) + +/* + * Vector format (Table 4-6) + */ + +#define M_LDTVECT_RAISEINT 0x00 +#define M_LDTVECT_RAISEMBOX 0x40 + + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_l2c.h b/include/asm-mips/sibyte/sb1250_l2c.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_l2c.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,128 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * L2 Cache constants and macros File: sb1250_l2c.h + * + * This module contains constants useful for manipulating the + * level 2 cache. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_L2C_H +#define _SB1250_L2C_H + +#include "sb1250_defs.h" + +/* + * Level 2 Cache Tag register (Table 5-3) + */ + +#define S_L2C_TAG_MBZ 0 +#define M_L2C_TAG_MBZ _SB_MAKEMASK(5,S_L2C_TAG_MBZ) + +#define S_L2C_TAG_INDEX 5 +#define M_L2C_TAG_INDEX _SB_MAKEMASK(12,S_L2C_TAG_INDEX) +#define V_L2C_TAG_INDEX(x) _SB_MAKEVALUE(x,S_L2C_TAG_INDEX) +#define G_L2C_TAG_INDEX(x) _SB_GETVALUE(x,S_L2C_TAG_INDEX,M_L2C_TAG_INDEX) + +#define S_L2C_TAG_TAG 17 +#define M_L2C_TAG_TAG _SB_MAKEMASK(23,S_L2C_TAG_TAG) +#define V_L2C_TAG_TAG(x) _SB_MAKEVALUE(x,S_L2C_TAG_TAG) +#define G_L2C_TAG_TAG(x) _SB_GETVALUE(x,S_L2C_TAG_TAG,M_L2C_TAG_TAG) + +#define S_L2C_TAG_ECC 40 +#define M_L2C_TAG_ECC _SB_MAKEMASK(6,S_L2C_TAG_ECC) +#define V_L2C_TAG_ECC(x) _SB_MAKEVALUE(x,S_L2C_TAG_ECC) +#define G_L2C_TAG_ECC(x) _SB_GETVALUE(x,S_L2C_TAG_ECC,M_L2C_TAG_ECC) + +#define S_L2C_TAG_WAY 46 +#define M_L2C_TAG_WAY _SB_MAKEMASK(2,S_L2C_TAG_WAY) +#define V_L2C_TAG_WAY(x) _SB_MAKEVALUE(x,S_L2C_TAG_WAY) +#define G_L2C_TAG_WAY(x) _SB_GETVALUE(x,S_L2C_TAG_WAY,M_L2C_TAG_WAY) + +#define M_L2C_TAG_DIRTY _SB_MAKEMASK1(48) +#define M_L2C_TAG_VALID _SB_MAKEMASK1(49) + +/* + * Format of level 2 cache management address (table 5-2) + */ + +#define S_L2C_MGMT_INDEX 5 +#define M_L2C_MGMT_INDEX _SB_MAKEMASK(12,S_L2C_MGMT_INDEX) +#define V_L2C_MGMT_INDEX(x) _SB_MAKEVALUE(x,S_L2C_MGMT_INDEX) +#define G_L2C_MGMT_INDEX(x) _SB_GETVALUE(x,S_L2C_MGMT_INDEX,M_L2C_MGMT_INDEX) + +#define S_L2C_MGMT_QUADRANT 15 +#define M_L2C_MGMT_QUADRANT _SB_MAKEMASK(2,S_L2C_MGMT_QUADRANT) +#define V_L2C_MGMT_QUADRANT(x) _SB_MAKEVALUE(x,S_L2C_MGMT_QUADRANT) +#define G_L2C_MGMT_QUADRANT(x) _SB_GETVALUE(x,S_L2C_MGMT_QUADRANT,M_L2C_MGMT_QUADRANT) + +#define S_L2C_MGMT_HALF 16 +#define M_L2C_MGMT_HALF _SB_MAKEMASK(1,S_L2C_MGMT_HALF) + +#define S_L2C_MGMT_WAY 17 +#define M_L2C_MGMT_WAY _SB_MAKEMASK(2,S_L2C_MGMT_WAY) +#define V_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x,S_L2C_MGMT_WAY) +#define G_L2C_MGMT_WAY(x) _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY) + +#define S_L2C_MGMT_TAG 21 +#define M_L2C_MGMT_TAG _SB_MAKEMASK(6,S_L2C_MGMT_TAG) +#define V_L2C_MGMT_TAG(x) _SB_MAKEVALUE(x,S_L2C_MGMT_TAG) +#define G_L2C_MGMT_TAG(x) _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG) + +#define M_L2C_MGMT_DIRTY _SB_MAKEMASK1(19) +#define M_L2C_MGMT_VALID _SB_MAKEMASK1(20) + +#define A_L2C_MGMT_TAG_BASE 0x00D0000000 + +#define L2C_ENTRIES_PER_WAY 4096 +#define L2C_NUM_WAYS 4 + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * L2 Read Misc. register (A_L2_READ_MISC) + */ +#define S_L2C_MISC_NO_WAY 10 +#define M_L2C_MISC_NO_WAY _SB_MAKEMASK(4,S_L2C_MISC_NO_WAY) +#define V_L2C_MISC_NO_WAY(x) _SB_MAKEVALUE(x,S_L2C_MISC_NO_WAY) +#define G_L2C_MISC_NO_WAY(x) _SB_GETVALUE(x,S_L2C_MISC_NO_WAY,M_L2C_MISC_NO_WAY) + +#define M_L2C_MISC_ECC_CLEANUP_DIS _SB_MAKEMASK1(9) +#define M_L2C_MISC_MC_PRIO_LOW _SB_MAKEMASK1(8) +#define M_L2C_MISC_SOFT_DISABLE_T _SB_MAKEMASK1(7) +#define M_L2C_MISC_SOFT_DISABLE_B _SB_MAKEMASK1(6) +#define M_L2C_MISC_SOFT_DISABLE_R _SB_MAKEMASK1(5) +#define M_L2C_MISC_SOFT_DISABLE_L _SB_MAKEMASK1(4) +#define M_L2C_MISC_SCACHE_DISABLE_T _SB_MAKEMASK1(3) +#define M_L2C_MISC_SCACHE_DISABLE_B _SB_MAKEMASK1(2) +#define M_L2C_MISC_SCACHE_DISABLE_R _SB_MAKEMASK1(1) +#define M_L2C_MISC_SCACHE_DISABLE_L _SB_MAKEMASK1(0) +#endif /* 112x PASS1 */ + + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_ldt.h b/include/asm-mips/sibyte/sb1250_ldt.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_ldt.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,425 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * LDT constants File: sb1250_ldt.h + * + * This module contains constants and macros to describe + * the LDT interface on the SB1250. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_LDT_H +#define _SB1250_LDT_H + +#include "sb1250_defs.h" + +#define K_LDT_VENDOR_SIBYTE 0x166D +#define K_LDT_DEVICE_SB1250 0x0002 + +/* + * LDT Interface Type 1 (bridge) configuration header + */ + +#define R_LDT_TYPE1_DEVICEID 0x0000 +#define R_LDT_TYPE1_CMDSTATUS 0x0004 +#define R_LDT_TYPE1_CLASSREV 0x0008 +#define R_LDT_TYPE1_DEVHDR 0x000C +#define R_LDT_TYPE1_BAR0 0x0010 /* not used */ +#define R_LDT_TYPE1_BAR1 0x0014 /* not used */ + +#define R_LDT_TYPE1_BUSID 0x0018 /* bus ID register */ +#define R_LDT_TYPE1_SECSTATUS 0x001C /* secondary status / I/O base/limit */ +#define R_LDT_TYPE1_MEMLIMIT 0x0020 +#define R_LDT_TYPE1_PREFETCH 0x0024 +#define R_LDT_TYPE1_PREF_BASE 0x0028 +#define R_LDT_TYPE1_PREF_LIMIT 0x002C +#define R_LDT_TYPE1_IOLIMIT 0x0030 +#define R_LDT_TYPE1_CAPPTR 0x0034 +#define R_LDT_TYPE1_ROMADDR 0x0038 +#define R_LDT_TYPE1_BRCTL 0x003C +#define R_LDT_TYPE1_CMD 0x0040 +#define R_LDT_TYPE1_LINKCTRL 0x0044 +#define R_LDT_TYPE1_LINKFREQ 0x0048 +#define R_LDT_TYPE1_RESERVED1 0x004C +#define R_LDT_TYPE1_SRICMD 0x0050 +#define R_LDT_TYPE1_SRITXNUM 0x0054 +#define R_LDT_TYPE1_SRIRXNUM 0x0058 +#define R_LDT_TYPE1_ERRSTATUS 0x0068 +#define R_LDT_TYPE1_SRICTRL 0x006C +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_LDT_TYPE1_ADDSTATUS 0x0070 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define R_LDT_TYPE1_TXBUFCNT 0x00C8 +#define R_LDT_TYPE1_EXPCRC 0x00DC +#define R_LDT_TYPE1_RXCRC 0x00F0 + + +/* + * LDT Device ID register + */ + +#define S_LDT_DEVICEID_VENDOR 0 +#define M_LDT_DEVICEID_VENDOR _SB_MAKEMASK_32(16,S_LDT_DEVICEID_VENDOR) +#define V_LDT_DEVICEID_VENDOR(x) _SB_MAKEVALUE_32(x,S_LDT_DEVICEID_VENDOR) +#define G_LDT_DEVICEID_VENDOR(x) _SB_GETVALUE_32(x,S_LDT_DEVICEID_VENDOR,M_LDT_DEVICEID_VENDOR) + +#define S_LDT_DEVICEID_DEVICEID 16 +#define M_LDT_DEVICEID_DEVICEID _SB_MAKEMASK_32(16,S_LDT_DEVICEID_DEVICEID) +#define V_LDT_DEVICEID_DEVICEID(x) _SB_MAKEVALUE_32(x,S_LDT_DEVICEID_DEVICEID) +#define G_LDT_DEVICEID_DEVICEID(x) _SB_GETVALUE_32(x,S_LDT_DEVICEID_DEVICEID,M_LDT_DEVICEID_DEVICEID) + + +/* + * LDT Command Register (Table 8-13) + */ + +#define M_LDT_CMD_IOSPACE_EN _SB_MAKEMASK1_32(0) +#define M_LDT_CMD_MEMSPACE_EN _SB_MAKEMASK1_32(1) +#define M_LDT_CMD_MASTER_EN _SB_MAKEMASK1_32(2) +#define M_LDT_CMD_SPECCYC_EN _SB_MAKEMASK1_32(3) +#define M_LDT_CMD_MEMWRINV_EN _SB_MAKEMASK1_32(4) +#define M_LDT_CMD_VGAPALSNP_EN _SB_MAKEMASK1_32(5) +#define M_LDT_CMD_PARERRRESP _SB_MAKEMASK1_32(6) +#define M_LDT_CMD_WAITCYCCTRL _SB_MAKEMASK1_32(7) +#define M_LDT_CMD_SERR_EN _SB_MAKEMASK1_32(8) +#define M_LDT_CMD_FASTB2B_EN _SB_MAKEMASK1_32(9) + +/* + * LDT class and revision registers + */ + +#define S_LDT_CLASSREV_REV 0 +#define M_LDT_CLASSREV_REV _SB_MAKEMASK_32(8,S_LDT_CLASSREV_REV) +#define V_LDT_CLASSREV_REV(x) _SB_MAKEVALUE_32(x,S_LDT_CLASSREV_REV) +#define G_LDT_CLASSREV_REV(x) _SB_GETVALUE_32(x,S_LDT_CLASSREV_REV,M_LDT_CLASSREV_REV) + +#define S_LDT_CLASSREV_CLASS 8 +#define M_LDT_CLASSREV_CLASS _SB_MAKEMASK_32(24,S_LDT_CLASSREV_CLASS) +#define V_LDT_CLASSREV_CLASS(x) _SB_MAKEVALUE_32(x,S_LDT_CLASSREV_CLASS) +#define G_LDT_CLASSREV_CLASS(x) _SB_GETVALUE_32(x,S_LDT_CLASSREV_CLASS,M_LDT_CLASSREV_CLASS) + +#define K_LDT_REV 0x01 +#define K_LDT_CLASS 0x060000 + +/* + * Device Header (offset 0x0C) + */ + +#define S_LDT_DEVHDR_CLINESZ 0 +#define M_LDT_DEVHDR_CLINESZ _SB_MAKEMASK_32(8,S_LDT_DEVHDR_CLINESZ) +#define V_LDT_DEVHDR_CLINESZ(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_CLINESZ) +#define G_LDT_DEVHDR_CLINESZ(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_CLINESZ,M_LDT_DEVHDR_CLINESZ) + +#define S_LDT_DEVHDR_LATTMR 8 +#define M_LDT_DEVHDR_LATTMR _SB_MAKEMASK_32(8,S_LDT_DEVHDR_LATTMR) +#define V_LDT_DEVHDR_LATTMR(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_LATTMR) +#define G_LDT_DEVHDR_LATTMR(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_LATTMR,M_LDT_DEVHDR_LATTMR) + +#define S_LDT_DEVHDR_HDRTYPE 16 +#define M_LDT_DEVHDR_HDRTYPE _SB_MAKEMASK_32(8,S_LDT_DEVHDR_HDRTYPE) +#define V_LDT_DEVHDR_HDRTYPE(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_HDRTYPE) +#define G_LDT_DEVHDR_HDRTYPE(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_HDRTYPE,M_LDT_DEVHDR_HDRTYPE) + +#define K_LDT_DEVHDR_HDRTYPE_TYPE1 1 + +#define S_LDT_DEVHDR_BIST 24 +#define M_LDT_DEVHDR_BIST _SB_MAKEMASK_32(8,S_LDT_DEVHDR_BIST) +#define V_LDT_DEVHDR_BIST(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_BIST) +#define G_LDT_DEVHDR_BIST(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_BIST,M_LDT_DEVHDR_BIST) + + + +/* + * LDT Status Register (Table 8-14). Note that these constants + * assume you've read the command and status register + * together (32-bit read at offset 0x04) + * + * These bits also apply to the secondary status + * register (Table 8-15), offset 0x1C + */ + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_LDT_STATUS_VGAEN _SB_MAKEMASK1_32(3) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define M_LDT_STATUS_CAPLIST _SB_MAKEMASK1_32(20) +#define M_LDT_STATUS_66MHZCAP _SB_MAKEMASK1_32(21) +#define M_LDT_STATUS_RESERVED2 _SB_MAKEMASK1_32(22) +#define M_LDT_STATUS_FASTB2BCAP _SB_MAKEMASK1_32(23) +#define M_LDT_STATUS_MSTRDPARERR _SB_MAKEMASK1_32(24) + +#define S_LDT_STATUS_DEVSELTIMING 25 +#define M_LDT_STATUS_DEVSELTIMING _SB_MAKEMASK_32(2,S_LDT_STATUS_DEVSELTIMING) +#define V_LDT_STATUS_DEVSELTIMING(x) _SB_MAKEVALUE_32(x,S_LDT_STATUS_DEVSELTIMING) +#define G_LDT_STATUS_DEVSELTIMING(x) _SB_GETVALUE_32(x,S_LDT_STATUS_DEVSELTIMING,M_LDT_STATUS_DEVSELTIMING) + +#define M_LDT_STATUS_SIGDTGTABORT _SB_MAKEMASK1_32(27) +#define M_LDT_STATUS_RCVDTGTABORT _SB_MAKEMASK1_32(28) +#define M_LDT_STATUS_RCVDMSTRABORT _SB_MAKEMASK1_32(29) +#define M_LDT_STATUS_SIGDSERR _SB_MAKEMASK1_32(30) +#define M_LDT_STATUS_DETPARERR _SB_MAKEMASK1_32(31) + +/* + * Bridge Control Register (Table 8-16). Note that these + * constants assume you've read the register as a 32-bit + * read (offset 0x3C) + */ + +#define M_LDT_BRCTL_PARERRRESP_EN _SB_MAKEMASK1_32(16) +#define M_LDT_BRCTL_SERR_EN _SB_MAKEMASK1_32(17) +#define M_LDT_BRCTL_ISA_EN _SB_MAKEMASK1_32(18) +#define M_LDT_BRCTL_VGA_EN _SB_MAKEMASK1_32(19) +#define M_LDT_BRCTL_MSTRABORTMODE _SB_MAKEMASK1_32(21) +#define M_LDT_BRCTL_SECBUSRESET _SB_MAKEMASK1_32(22) +#define M_LDT_BRCTL_FASTB2B_EN _SB_MAKEMASK1_32(23) +#define M_LDT_BRCTL_PRIDISCARD _SB_MAKEMASK1_32(24) +#define M_LDT_BRCTL_SECDISCARD _SB_MAKEMASK1_32(25) +#define M_LDT_BRCTL_DISCARDSTAT _SB_MAKEMASK1_32(26) +#define M_LDT_BRCTL_DISCARDSERR_EN _SB_MAKEMASK1_32(27) + +/* + * LDT Command Register (Table 8-17). Note that these constants + * assume you've read the command and status register together + * 32-bit read at offset 0x40 + */ + +#define M_LDT_CMD_WARMRESET _SB_MAKEMASK1_32(16) +#define M_LDT_CMD_DOUBLEENDED _SB_MAKEMASK1_32(17) + +#define S_LDT_CMD_CAPTYPE 29 +#define M_LDT_CMD_CAPTYPE _SB_MAKEMASK_32(3,S_LDT_CMD_CAPTYPE) +#define V_LDT_CMD_CAPTYPE(x) _SB_MAKEVALUE_32(x,S_LDT_CMD_CAPTYPE) +#define G_LDT_CMD_CAPTYPE(x) _SB_GETVALUE_32(x,S_LDT_CMD_CAPTYPE,M_LDT_CMD_CAPTYPE) + +/* + * LDT link control register (Table 8-18), and (Table 8-19) + */ + +#define M_LDT_LINKCTRL_CAPSYNCFLOOD_EN _SB_MAKEMASK1_32(1) +#define M_LDT_LINKCTRL_CRCSTARTTEST _SB_MAKEMASK1_32(2) +#define M_LDT_LINKCTRL_CRCFORCEERR _SB_MAKEMASK1_32(3) +#define M_LDT_LINKCTRL_LINKFAIL _SB_MAKEMASK1_32(4) +#define M_LDT_LINKCTRL_INITDONE _SB_MAKEMASK1_32(5) +#define M_LDT_LINKCTRL_EOC _SB_MAKEMASK1_32(6) +#define M_LDT_LINKCTRL_XMITOFF _SB_MAKEMASK1_32(7) + +#define S_LDT_LINKCTRL_CRCERR 8 +#define M_LDT_LINKCTRL_CRCERR _SB_MAKEMASK_32(4,S_LDT_LINKCTRL_CRCERR) +#define V_LDT_LINKCTRL_CRCERR(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_CRCERR) +#define G_LDT_LINKCTRL_CRCERR(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_CRCERR,M_LDT_LINKCTRL_CRCERR) + +#define S_LDT_LINKCTRL_MAXIN 16 +#define M_LDT_LINKCTRL_MAXIN _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXIN) +#define V_LDT_LINKCTRL_MAXIN(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXIN) +#define G_LDT_LINKCTRL_MAXIN(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXIN,M_LDT_LINKCTRL_MAXIN) + +#define M_LDT_LINKCTRL_DWFCLN _SB_MAKEMASK1_32(19) + +#define S_LDT_LINKCTRL_MAXOUT 20 +#define M_LDT_LINKCTRL_MAXOUT _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXOUT) +#define V_LDT_LINKCTRL_MAXOUT(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXOUT) +#define G_LDT_LINKCTRL_MAXOUT(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXOUT,M_LDT_LINKCTRL_MAXOUT) + +#define M_LDT_LINKCTRL_DWFCOUT _SB_MAKEMASK1_32(23) + +#define S_LDT_LINKCTRL_WIDTHIN 24 +#define M_LDT_LINKCTRL_WIDTHIN _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHIN) +#define V_LDT_LINKCTRL_WIDTHIN(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN) +#define G_LDT_LINKCTRL_WIDTHIN(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN,M_LDT_LINKCTRL_WIDTHIN) + +#define M_LDT_LINKCTRL_DWFCLIN_EN _SB_MAKEMASK1_32(27) + +#define S_LDT_LINKCTRL_WIDTHOUT 28 +#define M_LDT_LINKCTRL_WIDTHOUT _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHOUT) +#define V_LDT_LINKCTRL_WIDTHOUT(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT) +#define G_LDT_LINKCTRL_WIDTHOUT(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT,M_LDT_LINKCTRL_WIDTHOUT) + +#define M_LDT_LINKCTRL_DWFCOUT_EN _SB_MAKEMASK1_32(31) + +/* + * LDT Link frequency register (Table 8-20) offset 0x48 + */ + +#define S_LDT_LINKFREQ_FREQ 8 +#define M_LDT_LINKFREQ_FREQ _SB_MAKEMASK_32(4,S_LDT_LINKFREQ_FREQ) +#define V_LDT_LINKFREQ_FREQ(x) _SB_MAKEVALUE_32(x,S_LDT_LINKFREQ_FREQ) +#define G_LDT_LINKFREQ_FREQ(x) _SB_GETVALUE_32(x,S_LDT_LINKFREQ_FREQ,M_LDT_LINKFREQ_FREQ) + +#define K_LDT_LINKFREQ_200MHZ 0 +#define K_LDT_LINKFREQ_300MHZ 1 +#define K_LDT_LINKFREQ_400MHZ 2 +#define K_LDT_LINKFREQ_500MHZ 3 +#define K_LDT_LINKFREQ_600MHZ 4 +#define K_LDT_LINKFREQ_800MHZ 5 +#define K_LDT_LINKFREQ_1000MHZ 6 + +/* + * LDT SRI Command Register (Table 8-21). Note that these constants + * assume you've read the command and status register together + * 32-bit read at offset 0x50 + */ + +#define M_LDT_SRICMD_SIPREADY _SB_MAKEMASK1_32(16) +#define M_LDT_SRICMD_SYNCPTRCTL _SB_MAKEMASK1_32(17) +#define M_LDT_SRICMD_REDUCESYNCZERO _SB_MAKEMASK1_32(18) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +#define M_LDT_SRICMD_DISSTARVATIONCNT _SB_MAKEMASK1_32(19) /* PASS1 */ +#endif /* up to 1250 PASS1 */ +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_LDT_SRICMD_DISMULTTXVLD _SB_MAKEMASK1_32(19) +#define M_LDT_SRICMD_EXPENDIAN _SB_MAKEMASK1_32(26) +#endif /* 1250 PASS2 || 112x PASS1 */ + + +#define S_LDT_SRICMD_RXMARGIN 20 +#define M_LDT_SRICMD_RXMARGIN _SB_MAKEMASK_32(5,S_LDT_SRICMD_RXMARGIN) +#define V_LDT_SRICMD_RXMARGIN(x) _SB_MAKEVALUE_32(x,S_LDT_SRICMD_RXMARGIN) +#define G_LDT_SRICMD_RXMARGIN(x) _SB_GETVALUE_32(x,S_LDT_SRICMD_RXMARGIN,M_LDT_SRICMD_RXMARGIN) + +#define M_LDT_SRICMD_LDTPLLCOMPAT _SB_MAKEMASK1_32(25) + +#define S_LDT_SRICMD_TXINITIALOFFSET 28 +#define M_LDT_SRICMD_TXINITIALOFFSET _SB_MAKEMASK_32(3,S_LDT_SRICMD_TXINITIALOFFSET) +#define V_LDT_SRICMD_TXINITIALOFFSET(x) _SB_MAKEVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET) +#define G_LDT_SRICMD_TXINITIALOFFSET(x) _SB_GETVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET,M_LDT_SRICMD_TXINITIALOFFSET) + +#define M_LDT_SRICMD_LINKFREQDIRECT _SB_MAKEMASK1_32(31) + +/* + * LDT Error control and status register (Table 8-22) (Table 8-23) + */ + +#define M_LDT_ERRCTL_PROTFATAL_EN _SB_MAKEMASK1_32(0) +#define M_LDT_ERRCTL_PROTNONFATAL_EN _SB_MAKEMASK1_32(1) +#define M_LDT_ERRCTL_PROTSYNCFLOOD_EN _SB_MAKEMASK1_32(2) +#define M_LDT_ERRCTL_OVFFATAL_EN _SB_MAKEMASK1_32(3) +#define M_LDT_ERRCTL_OVFNONFATAL_EN _SB_MAKEMASK1_32(4) +#define M_LDT_ERRCTL_OVFSYNCFLOOD_EN _SB_MAKEMASK1_32(5) +#define M_LDT_ERRCTL_EOCNXAFATAL_EN _SB_MAKEMASK1_32(6) +#define M_LDT_ERRCTL_EOCNXANONFATAL_EN _SB_MAKEMASK1_32(7) +#define M_LDT_ERRCTL_EOCNXASYNCFLOOD_EN _SB_MAKEMASK1_32(8) +#define M_LDT_ERRCTL_CRCFATAL_EN _SB_MAKEMASK1_32(9) +#define M_LDT_ERRCTL_CRCNONFATAL_EN _SB_MAKEMASK1_32(10) +#define M_LDT_ERRCTL_SERRFATAL_EN _SB_MAKEMASK1_32(11) +#define M_LDT_ERRCTL_SRCTAGFATAL_EN _SB_MAKEMASK1_32(12) +#define M_LDT_ERRCTL_SRCTAGNONFATAL_EN _SB_MAKEMASK1_32(13) +#define M_LDT_ERRCTL_SRCTAGSYNCFLOOD_EN _SB_MAKEMASK1_32(14) +#define M_LDT_ERRCTL_MAPNXAFATAL_EN _SB_MAKEMASK1_32(15) +#define M_LDT_ERRCTL_MAPNXANONFATAL_EN _SB_MAKEMASK1_32(16) +#define M_LDT_ERRCTL_MAPNXASYNCFLOOD_EN _SB_MAKEMASK1_32(17) + +#define M_LDT_ERRCTL_PROTOERR _SB_MAKEMASK1_32(24) +#define M_LDT_ERRCTL_OVFERR _SB_MAKEMASK1_32(25) +#define M_LDT_ERRCTL_EOCNXAERR _SB_MAKEMASK1_32(26) +#define M_LDT_ERRCTL_SRCTAGERR _SB_MAKEMASK1_32(27) +#define M_LDT_ERRCTL_MAPNXAERR _SB_MAKEMASK1_32(28) + +/* + * SRI Control register (Table 8-24, 8-25) Offset 0x6C + */ + +#define S_LDT_SRICTRL_NEEDRESP 0 +#define M_LDT_SRICTRL_NEEDRESP _SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDRESP) +#define V_LDT_SRICTRL_NEEDRESP(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDRESP) +#define G_LDT_SRICTRL_NEEDRESP(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDRESP,M_LDT_SRICTRL_NEEDRESP) + +#define S_LDT_SRICTRL_NEEDNPREQ 2 +#define M_LDT_SRICTRL_NEEDNPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDNPREQ) +#define V_LDT_SRICTRL_NEEDNPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ) +#define G_LDT_SRICTRL_NEEDNPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ,M_LDT_SRICTRL_NEEDNPREQ) + +#define S_LDT_SRICTRL_NEEDPREQ 4 +#define M_LDT_SRICTRL_NEEDPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDPREQ) +#define V_LDT_SRICTRL_NEEDPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ) +#define G_LDT_SRICTRL_NEEDPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ,M_LDT_SRICTRL_NEEDPREQ) + +#define S_LDT_SRICTRL_WANTRESP 8 +#define M_LDT_SRICTRL_WANTRESP _SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTRESP) +#define V_LDT_SRICTRL_WANTRESP(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTRESP) +#define G_LDT_SRICTRL_WANTRESP(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTRESP,M_LDT_SRICTRL_WANTRESP) + +#define S_LDT_SRICTRL_WANTNPREQ 10 +#define M_LDT_SRICTRL_WANTNPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTNPREQ) +#define V_LDT_SRICTRL_WANTNPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ) +#define G_LDT_SRICTRL_WANTNPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ,M_LDT_SRICTRL_WANTNPREQ) + +#define S_LDT_SRICTRL_WANTPREQ 12 +#define M_LDT_SRICTRL_WANTPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTPREQ) +#define V_LDT_SRICTRL_WANTPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTPREQ) +#define G_LDT_SRICTRL_WANTPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTPREQ,M_LDT_SRICTRL_WANTPREQ) + +#define S_LDT_SRICTRL_BUFRELSPACE 16 +#define M_LDT_SRICTRL_BUFRELSPACE _SB_MAKEMASK_32(4,S_LDT_SRICTRL_BUFRELSPACE) +#define V_LDT_SRICTRL_BUFRELSPACE(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE) +#define G_LDT_SRICTRL_BUFRELSPACE(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE,M_LDT_SRICTRL_BUFRELSPACE) + +/* + * LDT SRI Transmit Buffer Count register (Table 8-26) + */ + +#define S_LDT_TXBUFCNT_PCMD 0 +#define M_LDT_TXBUFCNT_PCMD _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PCMD) +#define V_LDT_TXBUFCNT_PCMD(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PCMD) +#define G_LDT_TXBUFCNT_PCMD(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PCMD,M_LDT_TXBUFCNT_PCMD) + +#define S_LDT_TXBUFCNT_PDATA 4 +#define M_LDT_TXBUFCNT_PDATA _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PDATA) +#define V_LDT_TXBUFCNT_PDATA(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PDATA) +#define G_LDT_TXBUFCNT_PDATA(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PDATA,M_LDT_TXBUFCNT_PDATA) + +#define S_LDT_TXBUFCNT_NPCMD 8 +#define M_LDT_TXBUFCNT_NPCMD _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPCMD) +#define V_LDT_TXBUFCNT_NPCMD(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPCMD) +#define G_LDT_TXBUFCNT_NPCMD(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPCMD,M_LDT_TXBUFCNT_NPCMD) + +#define S_LDT_TXBUFCNT_NPDATA 12 +#define M_LDT_TXBUFCNT_NPDATA _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPDATA) +#define V_LDT_TXBUFCNT_NPDATA(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPDATA) +#define G_LDT_TXBUFCNT_NPDATA(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPDATA,M_LDT_TXBUFCNT_NPDATA) + +#define S_LDT_TXBUFCNT_RCMD 16 +#define M_LDT_TXBUFCNT_RCMD _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RCMD) +#define V_LDT_TXBUFCNT_RCMD(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RCMD) +#define G_LDT_TXBUFCNT_RCMD(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RCMD,M_LDT_TXBUFCNT_RCMD) + +#define S_LDT_TXBUFCNT_RDATA 20 +#define M_LDT_TXBUFCNT_RDATA _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RDATA) +#define V_LDT_TXBUFCNT_RDATA(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RDATA) +#define G_LDT_TXBUFCNT_RDATA(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RDATA,M_LDT_TXBUFCNT_RDATA) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Additional Status Register + */ + +#define S_LDT_ADDSTATUS_TGTDONE 0 +#define M_LDT_ADDSTATUS_TGTDONE _SB_MAKEMASK_32(8,S_LDT_ADDSTATUS_TGTDONE) +#define V_LDT_ADDSTATUS_TGTDONE(x) _SB_MAKEVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE) +#define G_LDT_ADDSTATUS_TGTDONE(x) _SB_GETVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE,M_LDT_ADDSTATUS_TGTDONE) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#endif + diff -Nru a/include/asm-mips/sibyte/sb1250_mac.h b/include/asm-mips/sibyte/sb1250_mac.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_mac.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,643 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * MAC constants and macros File: sb1250_mac.h + * + * This module contains constants and macros for the SB1250's + * ethernet controllers. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_MAC_H +#define _SB1250_MAC_H + +#include "sb1250_defs.h" + +/* ********************************************************************* + * Ethernet MAC Registers + ********************************************************************* */ + +/* + * MAC Configuration Register (Table 9-13) + * Register: MAC_CFG_0 + * Register: MAC_CFG_1 + * Register: MAC_CFG_2 + */ + + +#define M_MAC_RESERVED0 _SB_MAKEMASK1(0) +#define M_MAC_TX_HOLD_SOP_EN _SB_MAKEMASK1(1) +#define M_MAC_RETRY_EN _SB_MAKEMASK1(2) +#define M_MAC_RET_DRPREQ_EN _SB_MAKEMASK1(3) +#define M_MAC_RET_UFL_EN _SB_MAKEMASK1(4) +#define M_MAC_BURST_EN _SB_MAKEMASK1(5) + +#define S_MAC_TX_PAUSE _SB_MAKE64(6) +#define M_MAC_TX_PAUSE_CNT _SB_MAKEMASK(3,S_MAC_TX_PAUSE) +#define V_MAC_TX_PAUSE_CNT(x) _SB_MAKEVALUE(x,S_MAC_TX_PAUSE) + +#define K_MAC_TX_PAUSE_CNT_512 0 +#define K_MAC_TX_PAUSE_CNT_1K 1 +#define K_MAC_TX_PAUSE_CNT_2K 2 +#define K_MAC_TX_PAUSE_CNT_4K 3 +#define K_MAC_TX_PAUSE_CNT_8K 4 +#define K_MAC_TX_PAUSE_CNT_16K 5 +#define K_MAC_TX_PAUSE_CNT_32K 6 +#define K_MAC_TX_PAUSE_CNT_64K 7 + +#define V_MAC_TX_PAUSE_CNT_512 V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_512) +#define V_MAC_TX_PAUSE_CNT_1K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_1K) +#define V_MAC_TX_PAUSE_CNT_2K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_2K) +#define V_MAC_TX_PAUSE_CNT_4K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_4K) +#define V_MAC_TX_PAUSE_CNT_8K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_8K) +#define V_MAC_TX_PAUSE_CNT_16K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_16K) +#define V_MAC_TX_PAUSE_CNT_32K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_32K) +#define V_MAC_TX_PAUSE_CNT_64K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_64K) + +#define M_MAC_RESERVED1 _SB_MAKEMASK(8,9) + +#define M_MAC_AP_STAT_EN _SB_MAKEMASK1(17) +#define M_MAC_RESERVED2 _SB_MAKEMASK1(18) +#define M_MAC_DRP_ERRPKT_EN _SB_MAKEMASK1(19) +#define M_MAC_DRP_FCSERRPKT_EN _SB_MAKEMASK1(20) +#define M_MAC_DRP_CODEERRPKT_EN _SB_MAKEMASK1(21) +#define M_MAC_DRP_DRBLERRPKT_EN _SB_MAKEMASK1(22) +#define M_MAC_DRP_RNTPKT_EN _SB_MAKEMASK1(23) +#define M_MAC_DRP_OSZPKT_EN _SB_MAKEMASK1(24) +#define M_MAC_DRP_LENERRPKT_EN _SB_MAKEMASK1(25) + +#define M_MAC_RESERVED3 _SB_MAKEMASK(6,26) + +#define M_MAC_BYPASS_SEL _SB_MAKEMASK1(32) +#define M_MAC_HDX_EN _SB_MAKEMASK1(33) + +#define S_MAC_SPEED_SEL _SB_MAKE64(34) +#define M_MAC_SPEED_SEL _SB_MAKEMASK(2,S_MAC_SPEED_SEL) +#define V_MAC_SPEED_SEL(x) _SB_MAKEVALUE(x,S_MAC_SPEED_SEL) +#define G_MAC_SPEED_SEL(x) _SB_GETVALUE(x,S_MAC_SPEED_SEL,M_MAC_SPEED_SEL) + +#define K_MAC_SPEED_SEL_10MBPS 0 +#define K_MAC_SPEED_SEL_100MBPS 1 +#define K_MAC_SPEED_SEL_1000MBPS 2 +#define K_MAC_SPEED_SEL_RESERVED 3 + +#define V_MAC_SPEED_SEL_10MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_10MBPS) +#define V_MAC_SPEED_SEL_100MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_100MBPS) +#define V_MAC_SPEED_SEL_1000MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_1000MBPS) +#define V_MAC_SPEED_SEL_RESERVED V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_RESERVED) + +#define M_MAC_TX_CLK_EDGE_SEL _SB_MAKEMASK1(36) +#define M_MAC_LOOPBACK_SEL _SB_MAKEMASK1(37) +#define M_MAC_FAST_SYNC _SB_MAKEMASK1(38) +#define M_MAC_SS_EN _SB_MAKEMASK1(39) + +#define S_MAC_BYPASS_CFG _SB_MAKE64(40) +#define M_MAC_BYPASS_CFG _SB_MAKEMASK(2,S_MAC_BYPASS_CFG) +#define V_MAC_BYPASS_CFG(x) _SB_MAKEVALUE(x,S_MAC_BYPASS_CFG) +#define G_MAC_BYPASS_CFG(x) _SB_GETVALUE(x,S_MAC_BYPASS_CFG,M_MAC_BYPASS_CFG) + +#define K_MAC_BYPASS_GMII 0 +#define K_MAC_BYPASS_ENCODED 1 +#define K_MAC_BYPASS_SOP 2 +#define K_MAC_BYPASS_EOP 3 + +#define M_MAC_BYPASS_16 _SB_MAKEMASK1(42) +#define M_MAC_BYPASS_FCS_CHK _SB_MAKEMASK1(43) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_RX_CH_SEL_MSB _SB_MAKEMASK1(44) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_SPLIT_CH_SEL _SB_MAKEMASK1(45) +#endif /* 112x PASS1 */ + +#define S_MAC_BYPASS_IFG _SB_MAKE64(46) +#define M_MAC_BYPASS_IFG _SB_MAKEMASK(8,S_MAC_BYPASS_IFG) +#define V_MAC_BYPASS_IFG(x) _SB_MAKEVALUE(x,S_MAC_BYPASS_IFG) +#define G_MAC_BYPASS_IFG(x) _SB_GETVALUE(x,S_MAC_BYPASS_IFG,M_MAC_BYPASS_IFG) + +#define K_MAC_FC_CMD_DISABLED 0 +#define K_MAC_FC_CMD_ENABLED 1 +#define K_MAC_FC_CMD_ENAB_FALSECARR 2 + +#define V_MAC_FC_CMD_DISABLED V_MAC_FC_CMD(K_MAC_FC_CMD_DISABLED) +#define V_MAC_FC_CMD_ENABLED V_MAC_FC_CMD(K_MAC_FC_CMD_ENABLED) +#define V_MAC_FC_CMD_ENAB_FALSECARR V_MAC_FC_CMD(K_MAC_FC_CMD_ENAB_FALSECARR) + +#define M_MAC_FC_SEL _SB_MAKEMASK1(54) + +#define S_MAC_FC_CMD _SB_MAKE64(55) +#define M_MAC_FC_CMD _SB_MAKEMASK(2,S_MAC_FC_CMD) +#define V_MAC_FC_CMD(x) _SB_MAKEVALUE(x,S_MAC_FC_CMD) +#define G_MAC_FC_CMD(x) _SB_GETVALUE(x,S_MAC_FC_CMD,M_MAC_FC_CMD) + +#define S_MAC_RX_CH_SEL _SB_MAKE64(57) +#define M_MAC_RX_CH_SEL _SB_MAKEMASK(7,S_MAC_RX_CH_SEL) +#define V_MAC_RX_CH_SEL(x) _SB_MAKEVALUE(x,S_MAC_RX_CH_SEL) +#define G_MAC_RX_CH_SEL(x) _SB_GETVALUE(x,S_MAC_RX_CH_SEL,M_MAC_RX_CH_SEL) + + +/* + * MAC Enable Registers + * Register: MAC_ENABLE_0 + * Register: MAC_ENABLE_1 + * Register: MAC_ENABLE_2 + */ + +#define M_MAC_RXDMA_EN0 _SB_MAKEMASK1(0) +#define M_MAC_RXDMA_EN1 _SB_MAKEMASK1(1) +#define M_MAC_TXDMA_EN0 _SB_MAKEMASK1(4) +#define M_MAC_TXDMA_EN1 _SB_MAKEMASK1(5) + +#define M_MAC_PORT_RESET _SB_MAKEMASK1(8) + +#define M_MAC_RX_ENABLE _SB_MAKEMASK1(10) +#define M_MAC_TX_ENABLE _SB_MAKEMASK1(11) +#define M_MAC_BYP_RX_ENABLE _SB_MAKEMASK1(12) +#define M_MAC_BYP_TX_ENABLE _SB_MAKEMASK1(13) + +/* + * MAC DMA Control Register + * Register: MAC_TXD_CTL_0 + * Register: MAC_TXD_CTL_1 + * Register: MAC_TXD_CTL_2 + */ + +#define S_MAC_TXD_WEIGHT0 _SB_MAKE64(0) +#define M_MAC_TXD_WEIGHT0 _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT0) +#define V_MAC_TXD_WEIGHT0(x) _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT0) +#define G_MAC_TXD_WEIGHT0(x) _SB_GETVALUE(x,S_MAC_TXD_WEIGHT0,M_MAC_TXD_WEIGHT0) + +#define S_MAC_TXD_WEIGHT1 _SB_MAKE64(4) +#define M_MAC_TXD_WEIGHT1 _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT1) +#define V_MAC_TXD_WEIGHT1(x) _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT1) +#define G_MAC_TXD_WEIGHT1(x) _SB_GETVALUE(x,S_MAC_TXD_WEIGHT1,M_MAC_TXD_WEIGHT1) + +/* + * MAC Fifo Threshhold registers (Table 9-14) + * Register: MAC_THRSH_CFG_0 + * Register: MAC_THRSH_CFG_1 + * Register: MAC_THRSH_CFG_2 + */ + +#define S_MAC_TX_WR_THRSH _SB_MAKE64(0) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +/* XXX: Can't enable, as it has the same name as a pass2+ define below. */ +/* #define M_MAC_TX_WR_THRSH _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH) */ +#endif /* up to 1250 PASS1 */ +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_TX_WR_THRSH _SB_MAKEMASK(7,S_MAC_TX_WR_THRSH) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define V_MAC_TX_WR_THRSH(x) _SB_MAKEVALUE(x,S_MAC_TX_WR_THRSH) +#define G_MAC_TX_WR_THRSH(x) _SB_GETVALUE(x,S_MAC_TX_WR_THRSH,M_MAC_TX_WR_THRSH) + +#define S_MAC_TX_RD_THRSH _SB_MAKE64(8) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +/* XXX: Can't enable, as it has the same name as a pass2+ define below. */ +/* #define M_MAC_TX_RD_THRSH _SB_MAKEMASK(6,S_MAC_TX_RD_THRSH) */ +#endif /* up to 1250 PASS1 */ +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_TX_RD_THRSH _SB_MAKEMASK(7,S_MAC_TX_RD_THRSH) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define V_MAC_TX_RD_THRSH(x) _SB_MAKEVALUE(x,S_MAC_TX_RD_THRSH) +#define G_MAC_TX_RD_THRSH(x) _SB_GETVALUE(x,S_MAC_TX_RD_THRSH,M_MAC_TX_RD_THRSH) + +#define S_MAC_TX_RL_THRSH _SB_MAKE64(16) +#define M_MAC_TX_RL_THRSH _SB_MAKEMASK(4,S_MAC_TX_RL_THRSH) +#define V_MAC_TX_RL_THRSH(x) _SB_MAKEVALUE(x,S_MAC_TX_RL_THRSH) +#define G_MAC_TX_RL_THRSH(x) _SB_GETVALUE(x,S_MAC_TX_RL_THRSH,M_MAC_TX_RL_THRSH) + +#define S_MAC_RX_PL_THRSH _SB_MAKE64(24) +#define M_MAC_RX_PL_THRSH _SB_MAKEMASK(6,S_MAC_RX_PL_THRSH) +#define V_MAC_RX_PL_THRSH(x) _SB_MAKEVALUE(x,S_MAC_RX_PL_THRSH) +#define G_MAC_RX_PL_THRSH(x) _SB_GETVALUE(x,S_MAC_RX_PL_THRSH,M_MAC_RX_PL_THRSH) + +#define S_MAC_RX_RD_THRSH _SB_MAKE64(32) +#define M_MAC_RX_RD_THRSH _SB_MAKEMASK(6,S_MAC_RX_RD_THRSH) +#define V_MAC_RX_RD_THRSH(x) _SB_MAKEVALUE(x,S_MAC_RX_RD_THRSH) +#define G_MAC_RX_RD_THRSH(x) _SB_GETVALUE(x,S_MAC_RX_RD_THRSH,M_MAC_RX_RD_THRSH) + +#define S_MAC_RX_RL_THRSH _SB_MAKE64(40) +#define M_MAC_RX_RL_THRSH _SB_MAKEMASK(6,S_MAC_RX_RL_THRSH) +#define V_MAC_RX_RL_THRSH(x) _SB_MAKEVALUE(x,S_MAC_RX_RL_THRSH) +#define G_MAC_RX_RL_THRSH(x) _SB_GETVALUE(x,S_MAC_RX_RL_THRSH,M_MAC_RX_RL_THRSH) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_ENC_FC_THRSH _SB_MAKE64(56) +#define M_MAC_ENC_FC_THRSH _SB_MAKEMASK(6,S_MAC_ENC_FC_THRSH) +#define V_MAC_ENC_FC_THRSH(x) _SB_MAKEVALUE(x,S_MAC_ENC_FC_THRSH) +#define G_MAC_ENC_FC_THRSH(x) _SB_GETVALUE(x,S_MAC_ENC_FC_THRSH,M_MAC_ENC_FC_THRSH) +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * MAC Frame Configuration Registers (Table 9-15) + * Register: MAC_FRAME_CFG_0 + * Register: MAC_FRAME_CFG_1 + * Register: MAC_FRAME_CFG_2 + */ + +/* XXXCGD: ??? Unused in pass2? */ +#define S_MAC_IFG_RX _SB_MAKE64(0) +#define M_MAC_IFG_RX _SB_MAKEMASK(6,S_MAC_IFG_RX) +#define V_MAC_IFG_RX(x) _SB_MAKEVALUE(x,S_MAC_IFG_RX) +#define G_MAC_IFG_RX(x) _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_PRE_LEN _SB_MAKE64(0) +#define M_MAC_PRE_LEN _SB_MAKEMASK(6,S_MAC_PRE_LEN) +#define V_MAC_PRE_LEN(x) _SB_MAKEVALUE(x,S_MAC_PRE_LEN) +#define G_MAC_PRE_LEN(x) _SB_GETVALUE(x,S_MAC_PRE_LEN,M_MAC_PRE_LEN) +#endif /* 112x PASS1 */ + +#define S_MAC_IFG_TX _SB_MAKE64(6) +#define M_MAC_IFG_TX _SB_MAKEMASK(6,S_MAC_IFG_TX) +#define V_MAC_IFG_TX(x) _SB_MAKEVALUE(x,S_MAC_IFG_TX) +#define G_MAC_IFG_TX(x) _SB_GETVALUE(x,S_MAC_IFG_TX,M_MAC_IFG_TX) + +#define S_MAC_IFG_THRSH _SB_MAKE64(12) +#define M_MAC_IFG_THRSH _SB_MAKEMASK(6,S_MAC_IFG_THRSH) +#define V_MAC_IFG_THRSH(x) _SB_MAKEVALUE(x,S_MAC_IFG_THRSH) +#define G_MAC_IFG_THRSH(x) _SB_GETVALUE(x,S_MAC_IFG_THRSH,M_MAC_IFG_THRSH) + +#define S_MAC_BACKOFF_SEL _SB_MAKE64(18) +#define M_MAC_BACKOFF_SEL _SB_MAKEMASK(4,S_MAC_BACKOFF_SEL) +#define V_MAC_BACKOFF_SEL(x) _SB_MAKEVALUE(x,S_MAC_BACKOFF_SEL) +#define G_MAC_BACKOFF_SEL(x) _SB_GETVALUE(x,S_MAC_BACKOFF_SEL,M_MAC_BACKOFF_SEL) + +#define S_MAC_LFSR_SEED _SB_MAKE64(22) +#define M_MAC_LFSR_SEED _SB_MAKEMASK(8,S_MAC_LFSR_SEED) +#define V_MAC_LFSR_SEED(x) _SB_MAKEVALUE(x,S_MAC_LFSR_SEED) +#define G_MAC_LFSR_SEED(x) _SB_GETVALUE(x,S_MAC_LFSR_SEED,M_MAC_LFSR_SEED) + +#define S_MAC_SLOT_SIZE _SB_MAKE64(30) +#define M_MAC_SLOT_SIZE _SB_MAKEMASK(10,S_MAC_SLOT_SIZE) +#define V_MAC_SLOT_SIZE(x) _SB_MAKEVALUE(x,S_MAC_SLOT_SIZE) +#define G_MAC_SLOT_SIZE(x) _SB_GETVALUE(x,S_MAC_SLOT_SIZE,M_MAC_SLOT_SIZE) + +#define S_MAC_MIN_FRAMESZ _SB_MAKE64(40) +#define M_MAC_MIN_FRAMESZ _SB_MAKEMASK(8,S_MAC_MIN_FRAMESZ) +#define V_MAC_MIN_FRAMESZ(x) _SB_MAKEVALUE(x,S_MAC_MIN_FRAMESZ) +#define G_MAC_MIN_FRAMESZ(x) _SB_GETVALUE(x,S_MAC_MIN_FRAMESZ,M_MAC_MIN_FRAMESZ) + +#define S_MAC_MAX_FRAMESZ _SB_MAKE64(48) +#define M_MAC_MAX_FRAMESZ _SB_MAKEMASK(16,S_MAC_MAX_FRAMESZ) +#define V_MAC_MAX_FRAMESZ(x) _SB_MAKEVALUE(x,S_MAC_MAX_FRAMESZ) +#define G_MAC_MAX_FRAMESZ(x) _SB_GETVALUE(x,S_MAC_MAX_FRAMESZ,M_MAC_MAX_FRAMESZ) + +/* + * These constants are used to configure the fields within the Frame + * Configuration Register. + */ + +#define K_MAC_IFG_RX_10 _SB_MAKE64(0) /* See table 176, not used */ +#define K_MAC_IFG_RX_100 _SB_MAKE64(0) +#define K_MAC_IFG_RX_1000 _SB_MAKE64(0) + +#define K_MAC_IFG_TX_10 _SB_MAKE64(20) +#define K_MAC_IFG_TX_100 _SB_MAKE64(20) +#define K_MAC_IFG_TX_1000 _SB_MAKE64(8) + +#define K_MAC_IFG_THRSH_10 _SB_MAKE64(4) +#define K_MAC_IFG_THRSH_100 _SB_MAKE64(4) +#define K_MAC_IFG_THRSH_1000 _SB_MAKE64(0) + +#define K_MAC_SLOT_SIZE_10 _SB_MAKE64(0) +#define K_MAC_SLOT_SIZE_100 _SB_MAKE64(0) +#define K_MAC_SLOT_SIZE_1000 _SB_MAKE64(0) + +#define V_MAC_IFG_RX_10 V_MAC_IFG_RX(K_MAC_IFG_RX_10) +#define V_MAC_IFG_RX_100 V_MAC_IFG_RX(K_MAC_IFG_RX_100) +#define V_MAC_IFG_RX_1000 V_MAC_IFG_RX(K_MAC_IFG_RX_1000) + +#define V_MAC_IFG_TX_10 V_MAC_IFG_TX(K_MAC_IFG_TX_10) +#define V_MAC_IFG_TX_100 V_MAC_IFG_TX(K_MAC_IFG_TX_100) +#define V_MAC_IFG_TX_1000 V_MAC_IFG_TX(K_MAC_IFG_TX_1000) + +#define V_MAC_IFG_THRSH_10 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_10) +#define V_MAC_IFG_THRSH_100 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_100) +#define V_MAC_IFG_THRSH_1000 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_1000) + +#define V_MAC_SLOT_SIZE_10 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_10) +#define V_MAC_SLOT_SIZE_100 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_100) +#define V_MAC_SLOT_SIZE_1000 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_1000) + +#define K_MAC_MIN_FRAMESZ_FIFO _SB_MAKE64(9) +#define K_MAC_MIN_FRAMESZ_DEFAULT _SB_MAKE64(64) +#define K_MAC_MAX_FRAMESZ_DEFAULT _SB_MAKE64(1518) +#define K_MAC_MAX_FRAMESZ_JUMBO _SB_MAKE64(9216) + +#define V_MAC_MIN_FRAMESZ_FIFO V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_FIFO) +#define V_MAC_MIN_FRAMESZ_DEFAULT V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_DEFAULT) +#define V_MAC_MAX_FRAMESZ_DEFAULT V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_DEFAULT) +#define V_MAC_MAX_FRAMESZ_JUMBO V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_JUMBO) + +/* + * MAC VLAN Tag Registers (Table 9-16) + * Register: MAC_VLANTAG_0 + * Register: MAC_VLANTAG_1 + * Register: MAC_VLANTAG_2 + */ + +#define S_MAC_VLAN_TAG _SB_MAKE64(0) +#define M_MAC_VLAN_TAG _SB_MAKEMASK(32,S_MAC_VLAN_TAG) +#define V_MAC_VLAN_TAG(x) _SB_MAKEVALUE(x,S_MAC_VLAN_TAG) +#define G_MAC_VLAN_TAG(x) _SB_GETVALUE(x,S_MAC_VLAN_TAG,M_MAC_VLAN_TAG) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_TX_PKT_OFFSET _SB_MAKE64(32) +#define M_MAC_TX_PKT_OFFSET _SB_MAKEMASK(8,S_MAC_TX_PKT_OFFSET) +#define V_MAC_TX_PKT_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_TX_PKT_OFFSET) +#define G_MAC_TX_PKT_OFFSET(x) _SB_GETVALUE(x,S_MAC_TX_PKT_OFFSET,M_MAC_TX_PKT_OFFSET) + +#define S_MAC_TX_CRC_OFFSET _SB_MAKE64(40) +#define M_MAC_TX_CRC_OFFSET _SB_MAKEMASK(8,S_MAC_TX_CRC_OFFSET) +#define V_MAC_TX_CRC_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_TX_CRC_OFFSET) +#define G_MAC_TX_CRC_OFFSET(x) _SB_GETVALUE(x,S_MAC_TX_CRC_OFFSET,M_MAC_TX_CRC_OFFSET) + +#define M_MAC_CH_BASE_FC_EN _SB_MAKEMASK1(48) +#endif /* 112x PASS1 */ + +/* + * MAC Status Registers (Table 9-17) + * Also used for the MAC Interrupt Mask Register (Table 9-18) + * Register: MAC_STATUS_0 + * Register: MAC_STATUS_1 + * Register: MAC_STATUS_2 + * Register: MAC_INT_MASK_0 + * Register: MAC_INT_MASK_1 + * Register: MAC_INT_MASK_2 + */ + +/* + * Use these constants to shift the appropriate channel + * into the CH0 position so the same tests can be used + * on each channel. + */ + +#define S_MAC_RX_CH0 _SB_MAKE64(0) +#define S_MAC_RX_CH1 _SB_MAKE64(8) +#define S_MAC_TX_CH0 _SB_MAKE64(16) +#define S_MAC_TX_CH1 _SB_MAKE64(24) + +#define S_MAC_TXCHANNELS _SB_MAKE64(16) /* this is 1st TX chan */ +#define S_MAC_CHANWIDTH _SB_MAKE64(8) /* bits between channels */ + +/* + * These are the same as RX channel 0. The idea here + * is that you'll use one of the "S_" things above + * and pass just the six bits to a DMA-channel-specific ISR + */ +#define M_MAC_INT_CHANNEL _SB_MAKEMASK(8,0) +#define M_MAC_INT_EOP_COUNT _SB_MAKEMASK1(0) +#define M_MAC_INT_EOP_TIMER _SB_MAKEMASK1(1) +#define M_MAC_INT_EOP_SEEN _SB_MAKEMASK1(2) +#define M_MAC_INT_HWM _SB_MAKEMASK1(3) +#define M_MAC_INT_LWM _SB_MAKEMASK1(4) +#define M_MAC_INT_DSCR _SB_MAKEMASK1(5) +#define M_MAC_INT_ERR _SB_MAKEMASK1(6) +#define M_MAC_INT_DZERO _SB_MAKEMASK1(7) /* only for TX channels */ +#define M_MAC_INT_DROP _SB_MAKEMASK1(7) /* only for RX channels */ + +/* + * In the following definitions we use ch (0/1) and txrx (TX=1, RX=0, see + * also DMA_TX/DMA_RX in sb_regs.h). + */ +#define S_MAC_STATUS_CH_OFFSET(ch,txrx) _SB_MAKE64(((ch) + 2 * (txrx)) * S_MAC_CHANWIDTH) + +#define M_MAC_STATUS_CHANNEL(ch,txrx) _SB_MAKEVALUE(_SB_MAKEMASK(8,0),S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_EOP_COUNT(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_COUNT,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_EOP_TIMER(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_TIMER,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_EOP_SEEN(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_SEEN,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_HWM(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_HWM,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_LWM(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_LWM,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_DSCR(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_DSCR,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_ERR(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_ERR,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_DZERO(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_DZERO,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_DROP(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_DROP,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_OTHER_ERR _SB_MAKEVALUE(_SB_MAKEMASK(7,0),40) + + +#define M_MAC_RX_UNDRFL _SB_MAKEMASK1(40) +#define M_MAC_RX_OVRFL _SB_MAKEMASK1(41) +#define M_MAC_TX_UNDRFL _SB_MAKEMASK1(42) +#define M_MAC_TX_OVRFL _SB_MAKEMASK1(43) +#define M_MAC_LTCOL_ERR _SB_MAKEMASK1(44) +#define M_MAC_EXCOL_ERR _SB_MAKEMASK1(45) +#define M_MAC_CNTR_OVRFL_ERR _SB_MAKEMASK1(46) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_SPLIT_EN _SB_MAKEMASK1(47) /* interrupt mask only */ +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_MAC_COUNTER_ADDR _SB_MAKE64(47) +#define M_MAC_COUNTER_ADDR _SB_MAKEMASK(5,S_MAC_COUNTER_ADDR) +#define V_MAC_COUNTER_ADDR(x) _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR) +#define G_MAC_COUNTER_ADDR(x) _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_TX_PAUSE_ON _SB_MAKEMASK1(52) +#endif /* 112x PASS1 */ + +/* + * MAC Fifo Pointer Registers (Table 9-19) [Debug register] + * Register: MAC_FIFO_PTRS_0 + * Register: MAC_FIFO_PTRS_1 + * Register: MAC_FIFO_PTRS_2 + */ + +#define S_MAC_TX_WRPTR _SB_MAKE64(0) +#define M_MAC_TX_WRPTR _SB_MAKEMASK(6,S_MAC_TX_WRPTR) +#define V_MAC_TX_WRPTR(x) _SB_MAKEVALUE(x,S_MAC_TX_WRPTR) +#define G_MAC_TX_WRPTR(x) _SB_GETVALUE(x,S_MAC_TX_WRPTR,M_MAC_TX_WRPTR) + +#define S_MAC_TX_RDPTR _SB_MAKE64(8) +#define M_MAC_TX_RDPTR _SB_MAKEMASK(6,S_MAC_TX_RDPTR) +#define V_MAC_TX_RDPTR(x) _SB_MAKEVALUE(x,S_MAC_TX_RDPTR) +#define G_MAC_TX_RDPTR(x) _SB_GETVALUE(x,S_MAC_TX_RDPTR,M_MAC_TX_RDPTR) + +#define S_MAC_RX_WRPTR _SB_MAKE64(16) +#define M_MAC_RX_WRPTR _SB_MAKEMASK(6,S_MAC_RX_WRPTR) +#define V_MAC_RX_WRPTR(x) _SB_MAKEVALUE(x,S_MAC_RX_WRPTR) +#define G_MAC_RX_WRPTR(x) _SB_GETVALUE(x,S_MAC_RX_WRPTR,M_MAC_TX_WRPTR) + +#define S_MAC_RX_RDPTR _SB_MAKE64(24) +#define M_MAC_RX_RDPTR _SB_MAKEMASK(6,S_MAC_RX_RDPTR) +#define V_MAC_RX_RDPTR(x) _SB_MAKEVALUE(x,S_MAC_RX_RDPTR) +#define G_MAC_RX_RDPTR(x) _SB_GETVALUE(x,S_MAC_RX_RDPTR,M_MAC_TX_RDPTR) + +/* + * MAC Fifo End Of Packet Count Registers (Table 9-20) [Debug register] + * Register: MAC_EOPCNT_0 + * Register: MAC_EOPCNT_1 + * Register: MAC_EOPCNT_2 + */ + +#define S_MAC_TX_EOP_COUNTER _SB_MAKE64(0) +#define M_MAC_TX_EOP_COUNTER _SB_MAKEMASK(6,S_MAC_TX_EOP_COUNTER) +#define V_MAC_TX_EOP_COUNTER(x) _SB_MAKEVALUE(x,S_MAC_TX_EOP_COUNTER) +#define G_MAC_TX_EOP_COUNTER(x) _SB_GETVALUE(x,S_MAC_TX_EOP_COUNTER,M_MAC_TX_EOP_COUNTER) + +#define S_MAC_RX_EOP_COUNTER _SB_MAKE64(8) +#define M_MAC_RX_EOP_COUNTER _SB_MAKEMASK(6,S_MAC_RX_EOP_COUNTER) +#define V_MAC_RX_EOP_COUNTER(x) _SB_MAKEVALUE(x,S_MAC_RX_EOP_COUNTER) +#define G_MAC_RX_EOP_COUNTER(x) _SB_GETVALUE(x,S_MAC_RX_EOP_COUNTER,M_MAC_RX_EOP_COUNTER) + +/* + * MAC Recieve Address Filter Exact Match Registers (Table 9-21) + * Registers: MAC_ADDR0_0 through MAC_ADDR7_0 + * Registers: MAC_ADDR0_1 through MAC_ADDR7_1 + * Registers: MAC_ADDR0_2 through MAC_ADDR7_2 + */ + +/* No bitfields */ + +/* + * MAC Receive Address Filter Mask Registers + * Registers: MAC_ADDRMASK0_0 and MAC_ADDRMASK0_1 + * Registers: MAC_ADDRMASK1_0 and MAC_ADDRMASK1_1 + * Registers: MAC_ADDRMASK2_0 and MAC_ADDRMASK2_1 + */ + +/* No bitfields */ + +/* + * MAC Recieve Address Filter Hash Match Registers (Table 9-22) + * Registers: MAC_HASH0_0 through MAC_HASH7_0 + * Registers: MAC_HASH0_1 through MAC_HASH7_1 + * Registers: MAC_HASH0_2 through MAC_HASH7_2 + */ + +/* No bitfields */ + +/* + * MAC Transmit Source Address Registers (Table 9-23) + * Register: MAC_ETHERNET_ADDR_0 + * Register: MAC_ETHERNET_ADDR_1 + * Register: MAC_ETHERNET_ADDR_2 + */ + +/* No bitfields */ + +/* + * MAC Packet Type Configuration Register + * Register: MAC_TYPE_CFG_0 + * Register: MAC_TYPE_CFG_1 + * Register: MAC_TYPE_CFG_2 + */ + +#define S_TYPECFG_TYPESIZE _SB_MAKE64(16) + +#define S_TYPECFG_TYPE0 _SB_MAKE64(0) +#define M_TYPECFG_TYPE0 _SB_MAKEMASK(16,S_TYPECFG_TYPE0) +#define V_TYPECFG_TYPE0(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE0) +#define G_TYPECFG_TYPE0(x) _SB_GETVALUE(x,S_TYPECFG_TYPE0,M_TYPECFG_TYPE0) + +#define S_TYPECFG_TYPE1 _SB_MAKE64(0) +#define M_TYPECFG_TYPE1 _SB_MAKEMASK(16,S_TYPECFG_TYPE1) +#define V_TYPECFG_TYPE1(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE1) +#define G_TYPECFG_TYPE1(x) _SB_GETVALUE(x,S_TYPECFG_TYPE1,M_TYPECFG_TYPE1) + +#define S_TYPECFG_TYPE2 _SB_MAKE64(0) +#define M_TYPECFG_TYPE2 _SB_MAKEMASK(16,S_TYPECFG_TYPE2) +#define V_TYPECFG_TYPE2(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE2) +#define G_TYPECFG_TYPE2(x) _SB_GETVALUE(x,S_TYPECFG_TYPE2,M_TYPECFG_TYPE2) + +#define S_TYPECFG_TYPE3 _SB_MAKE64(0) +#define M_TYPECFG_TYPE3 _SB_MAKEMASK(16,S_TYPECFG_TYPE3) +#define V_TYPECFG_TYPE3(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE3) +#define G_TYPECFG_TYPE3(x) _SB_GETVALUE(x,S_TYPECFG_TYPE3,M_TYPECFG_TYPE3) + +/* + * MAC Receive Address Filter Control Registers (Table 9-24) + * Register: MAC_ADFILTER_CFG_0 + * Register: MAC_ADFILTER_CFG_1 + * Register: MAC_ADFILTER_CFG_2 + */ + +#define M_MAC_ALLPKT_EN _SB_MAKEMASK1(0) +#define M_MAC_UCAST_EN _SB_MAKEMASK1(1) +#define M_MAC_UCAST_INV _SB_MAKEMASK1(2) +#define M_MAC_MCAST_EN _SB_MAKEMASK1(3) +#define M_MAC_MCAST_INV _SB_MAKEMASK1(4) +#define M_MAC_BCAST_EN _SB_MAKEMASK1(5) +#define M_MAC_DIRECT_INV _SB_MAKEMASK1(6) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_ALLMCAST_EN _SB_MAKEMASK1(7) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_MAC_IPHDR_OFFSET _SB_MAKE64(8) +#define M_MAC_IPHDR_OFFSET _SB_MAKEMASK(8,S_MAC_IPHDR_OFFSET) +#define V_MAC_IPHDR_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET) +#define G_MAC_IPHDR_OFFSET(x) _SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_RX_CRC_OFFSET _SB_MAKE64(16) +#define M_MAC_RX_CRC_OFFSET _SB_MAKEMASK(8,S_MAC_RX_CRC_OFFSET) +#define V_MAC_RX_CRC_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_RX_CRC_OFFSET) +#define G_MAC_RX_CRC_OFFSET(x) _SB_GETVALUE(x,S_MAC_RX_CRC_OFFSET,M_MAC_RX_CRC_OFFSET) + +#define S_MAC_RX_PKT_OFFSET _SB_MAKE64(24) +#define M_MAC_RX_PKT_OFFSET _SB_MAKEMASK(8,S_MAC_RX_PKT_OFFSET) +#define V_MAC_RX_PKT_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_RX_PKT_OFFSET) +#define G_MAC_RX_PKT_OFFSET(x) _SB_GETVALUE(x,S_MAC_RX_PKT_OFFSET,M_MAC_RX_PKT_OFFSET) + +#define M_MAC_FWDPAUSE_EN _SB_MAKEMASK1(32) +#define M_MAC_VLAN_DET_EN _SB_MAKEMASK1(33) + +#define S_MAC_RX_CH_MSN_SEL _SB_MAKE64(34) +#define M_MAC_RX_CH_MSN_SEL _SB_MAKEMASK(8,S_MAC_RX_CH_MSN_SEL) +#define V_MAC_RX_CH_MSN_SEL(x) _SB_MAKEVALUE(x,S_MAC_RX_CH_MSN_SEL) +#define G_MAC_RX_CH_MSN_SEL(x) _SB_GETVALUE(x,S_MAC_RX_CH_MSN_SEL,M_MAC_RX_CH_MSN_SEL) +#endif /* 112x PASS1 */ + +/* + * MAC Receive Channel Select Registers (Table 9-25) + */ + +/* no bitfields */ + +/* + * MAC MII Management Interface Registers (Table 9-26) + * Register: MAC_MDIO_0 + * Register: MAC_MDIO_1 + * Register: MAC_MDIO_2 + */ + +#define S_MAC_MDC 0 +#define S_MAC_MDIO_DIR 1 +#define S_MAC_MDIO_OUT 2 +#define S_MAC_GENC 3 +#define S_MAC_MDIO_IN 4 + +#define M_MAC_MDC _SB_MAKEMASK1(S_MAC_MDC) +#define M_MAC_MDIO_DIR _SB_MAKEMASK1(S_MAC_MDIO_DIR) +#define M_MAC_MDIO_DIR_INPUT _SB_MAKEMASK1(S_MAC_MDIO_DIR) +#define M_MAC_MDIO_OUT _SB_MAKEMASK1(S_MAC_MDIO_OUT) +#define M_MAC_GENC _SB_MAKEMASK1(S_MAC_GENC) +#define M_MAC_MDIO_IN _SB_MAKEMASK1(S_MAC_MDIO_IN) + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_mc.h b/include/asm-mips/sibyte/sb1250_mc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_mc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,548 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Memory Controller constants File: sb1250_mc.h + * + * This module contains constants and macros useful for + * programming the memory controller. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_MC_H +#define _SB1250_MC_H + +#include "sb1250_defs.h" + +/* + * Memory Channel Config Register (table 6-14) + */ + +#define S_MC_RESERVED0 0 +#define M_MC_RESERVED0 _SB_MAKEMASK(8,S_MC_RESERVED0) + +#define S_MC_CHANNEL_SEL 8 +#define M_MC_CHANNEL_SEL _SB_MAKEMASK(8,S_MC_CHANNEL_SEL) +#define V_MC_CHANNEL_SEL(x) _SB_MAKEVALUE(x,S_MC_CHANNEL_SEL) +#define G_MC_CHANNEL_SEL(x) _SB_GETVALUE(x,S_MC_CHANNEL_SEL,M_MC_CHANNEL_SEL) + +#define S_MC_BANK0_MAP 16 +#define M_MC_BANK0_MAP _SB_MAKEMASK(4,S_MC_BANK0_MAP) +#define V_MC_BANK0_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK0_MAP) +#define G_MC_BANK0_MAP(x) _SB_GETVALUE(x,S_MC_BANK0_MAP,M_MC_BANK0_MAP) + +#define K_MC_BANK0_MAP_DEFAULT 0x00 +#define V_MC_BANK0_MAP_DEFAULT V_MC_BANK0_MAP(K_MC_BANK0_MAP_DEFAULT) + +#define S_MC_BANK1_MAP 20 +#define M_MC_BANK1_MAP _SB_MAKEMASK(4,S_MC_BANK1_MAP) +#define V_MC_BANK1_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK1_MAP) +#define G_MC_BANK1_MAP(x) _SB_GETVALUE(x,S_MC_BANK1_MAP,M_MC_BANK1_MAP) + +#define K_MC_BANK1_MAP_DEFAULT 0x08 +#define V_MC_BANK1_MAP_DEFAULT V_MC_BANK1_MAP(K_MC_BANK1_MAP_DEFAULT) + +#define S_MC_BANK2_MAP 24 +#define M_MC_BANK2_MAP _SB_MAKEMASK(4,S_MC_BANK2_MAP) +#define V_MC_BANK2_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK2_MAP) +#define G_MC_BANK2_MAP(x) _SB_GETVALUE(x,S_MC_BANK2_MAP,M_MC_BANK2_MAP) + +#define K_MC_BANK2_MAP_DEFAULT 0x09 +#define V_MC_BANK2_MAP_DEFAULT V_MC_BANK2_MAP(K_MC_BANK2_MAP_DEFAULT) + +#define S_MC_BANK3_MAP 28 +#define M_MC_BANK3_MAP _SB_MAKEMASK(4,S_MC_BANK3_MAP) +#define V_MC_BANK3_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK3_MAP) +#define G_MC_BANK3_MAP(x) _SB_GETVALUE(x,S_MC_BANK3_MAP,M_MC_BANK3_MAP) + +#define K_MC_BANK3_MAP_DEFAULT 0x0C +#define V_MC_BANK3_MAP_DEFAULT V_MC_BANK3_MAP(K_MC_BANK3_MAP_DEFAULT) + +#define M_MC_RESERVED1 _SB_MAKEMASK(8,32) + +#define S_MC_QUEUE_SIZE 40 +#define M_MC_QUEUE_SIZE _SB_MAKEMASK(4,S_MC_QUEUE_SIZE) +#define V_MC_QUEUE_SIZE(x) _SB_MAKEVALUE(x,S_MC_QUEUE_SIZE) +#define G_MC_QUEUE_SIZE(x) _SB_GETVALUE(x,S_MC_QUEUE_SIZE,M_MC_QUEUE_SIZE) +#define V_MC_QUEUE_SIZE_DEFAULT V_MC_QUEUE_SIZE(0x0A) + +#define S_MC_AGE_LIMIT 44 +#define M_MC_AGE_LIMIT _SB_MAKEMASK(4,S_MC_AGE_LIMIT) +#define V_MC_AGE_LIMIT(x) _SB_MAKEVALUE(x,S_MC_AGE_LIMIT) +#define G_MC_AGE_LIMIT(x) _SB_GETVALUE(x,S_MC_AGE_LIMIT,M_MC_AGE_LIMIT) +#define V_MC_AGE_LIMIT_DEFAULT V_MC_AGE_LIMIT(8) + +#define S_MC_WR_LIMIT 48 +#define M_MC_WR_LIMIT _SB_MAKEMASK(4,S_MC_WR_LIMIT) +#define V_MC_WR_LIMIT(x) _SB_MAKEVALUE(x,S_MC_WR_LIMIT) +#define G_MC_WR_LIMIT(x) _SB_GETVALUE(x,S_MC_WR_LIMIT,M_MC_WR_LIMIT) +#define V_MC_WR_LIMIT_DEFAULT V_MC_WR_LIMIT(5) + +#define M_MC_IOB1HIGHPRIORITY _SB_MAKEMASK1(52) + +#define M_MC_RESERVED2 _SB_MAKEMASK(3,53) + +#define S_MC_CS_MODE 56 +#define M_MC_CS_MODE _SB_MAKEMASK(4,S_MC_CS_MODE) +#define V_MC_CS_MODE(x) _SB_MAKEVALUE(x,S_MC_CS_MODE) +#define G_MC_CS_MODE(x) _SB_GETVALUE(x,S_MC_CS_MODE,M_MC_CS_MODE) + +#define K_MC_CS_MODE_MSB_CS 0 +#define K_MC_CS_MODE_INTLV_CS 15 +#define K_MC_CS_MODE_MIXED_CS_10 12 +#define K_MC_CS_MODE_MIXED_CS_30 6 +#define K_MC_CS_MODE_MIXED_CS_32 3 + +#define V_MC_CS_MODE_MSB_CS V_MC_CS_MODE(K_MC_CS_MODE_MSB_CS) +#define V_MC_CS_MODE_INTLV_CS V_MC_CS_MODE(K_MC_CS_MODE_INTLV_CS) +#define V_MC_CS_MODE_MIXED_CS_10 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_10) +#define V_MC_CS_MODE_MIXED_CS_30 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_30) +#define V_MC_CS_MODE_MIXED_CS_32 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_32) + +#define M_MC_ECC_DISABLE _SB_MAKEMASK1(60) +#define M_MC_BERR_DISABLE _SB_MAKEMASK1(61) +#define M_MC_FORCE_SEQ _SB_MAKEMASK1(62) +#define M_MC_DEBUG _SB_MAKEMASK1(63) + +#define V_MC_CONFIG_DEFAULT V_MC_WR_LIMIT_DEFAULT | V_MC_AGE_LIMIT_DEFAULT | \ + V_MC_BANK0_MAP_DEFAULT | V_MC_BANK1_MAP_DEFAULT | \ + V_MC_BANK2_MAP_DEFAULT | V_MC_BANK3_MAP_DEFAULT | V_MC_CHANNEL_SEL(0) | \ + M_MC_IOB1HIGHPRIORITY | V_MC_QUEUE_SIZE_DEFAULT + + +/* + * Memory clock config register (Table 6-15) + * + * Note: this field has been updated to be consistent with the errata to 0.2 + */ + +#define S_MC_CLK_RATIO 0 +#define M_MC_CLK_RATIO _SB_MAKEMASK(4,S_MC_CLK_RATIO) +#define V_MC_CLK_RATIO(x) _SB_MAKEVALUE(x,S_MC_CLK_RATIO) +#define G_MC_CLK_RATIO(x) _SB_GETVALUE(x,S_MC_CLK_RATIO,M_MC_CLK_RATIO) + +#define K_MC_CLK_RATIO_2X 4 +#define K_MC_CLK_RATIO_25X 5 +#define K_MC_CLK_RATIO_3X 6 +#define K_MC_CLK_RATIO_35X 7 +#define K_MC_CLK_RATIO_4X 8 +#define K_MC_CLK_RATIO_45X 9 + +#define V_MC_CLK_RATIO_2X V_MC_CLK_RATIO(K_MC_CLK_RATIO_2X) +#define V_MC_CLK_RATIO_25X V_MC_CLK_RATIO(K_MC_CLK_RATIO_25X) +#define V_MC_CLK_RATIO_3X V_MC_CLK_RATIO(K_MC_CLK_RATIO_3X) +#define V_MC_CLK_RATIO_35X V_MC_CLK_RATIO(K_MC_CLK_RATIO_35X) +#define V_MC_CLK_RATIO_4X V_MC_CLK_RATIO(K_MC_CLK_RATIO_4X) +#define V_MC_CLK_RATIO_45X V_MC_CLK_RATIO(K_MC_CLK_RATIO_45X) +#define V_MC_CLK_RATIO_DEFAULT V_MC_CLK_RATIO_25X + +#define S_MC_REF_RATE 8 +#define M_MC_REF_RATE _SB_MAKEMASK(8,S_MC_REF_RATE) +#define V_MC_REF_RATE(x) _SB_MAKEVALUE(x,S_MC_REF_RATE) +#define G_MC_REF_RATE(x) _SB_GETVALUE(x,S_MC_REF_RATE,M_MC_REF_RATE) + +#define K_MC_REF_RATE_100MHz 0x62 +#define K_MC_REF_RATE_133MHz 0x81 +#define K_MC_REF_RATE_200MHz 0xC4 + +#define V_MC_REF_RATE_100MHz V_MC_REF_RATE(K_MC_REF_RATE_100MHz) +#define V_MC_REF_RATE_133MHz V_MC_REF_RATE(K_MC_REF_RATE_133MHz) +#define V_MC_REF_RATE_200MHz V_MC_REF_RATE(K_MC_REF_RATE_200MHz) +#define V_MC_REF_RATE_DEFAULT V_MC_REF_RATE_100MHz + +#define S_MC_CLOCK_DRIVE 16 +#define M_MC_CLOCK_DRIVE _SB_MAKEMASK(4,S_MC_CLOCK_DRIVE) +#define V_MC_CLOCK_DRIVE(x) _SB_MAKEVALUE(x,S_MC_CLOCK_DRIVE) +#define G_MC_CLOCK_DRIVE(x) _SB_GETVALUE(x,S_MC_CLOCK_DRIVE,M_MC_CLOCK_DRIVE) +#define V_MC_CLOCK_DRIVE_DEFAULT V_MC_CLOCK_DRIVE(0xF) + +#define S_MC_DATA_DRIVE 20 +#define M_MC_DATA_DRIVE _SB_MAKEMASK(4,S_MC_DATA_DRIVE) +#define V_MC_DATA_DRIVE(x) _SB_MAKEVALUE(x,S_MC_DATA_DRIVE) +#define G_MC_DATA_DRIVE(x) _SB_GETVALUE(x,S_MC_DATA_DRIVE,M_MC_DATA_DRIVE) +#define V_MC_DATA_DRIVE_DEFAULT V_MC_DATA_DRIVE(0x0) + +#define S_MC_ADDR_DRIVE 24 +#define M_MC_ADDR_DRIVE _SB_MAKEMASK(4,S_MC_ADDR_DRIVE) +#define V_MC_ADDR_DRIVE(x) _SB_MAKEVALUE(x,S_MC_ADDR_DRIVE) +#define G_MC_ADDR_DRIVE(x) _SB_GETVALUE(x,S_MC_ADDR_DRIVE,M_MC_ADDR_DRIVE) +#define V_MC_ADDR_DRIVE_DEFAULT V_MC_ADDR_DRIVE(0x0) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MC_REF_DISABLE _SB_MAKEMASK1(30) +#endif /* 112x PASS1 */ + +#define M_MC_DLL_BYPASS _SB_MAKEMASK1(31) + +#define S_MC_DQI_SKEW 32 +#define M_MC_DQI_SKEW _SB_MAKEMASK(8,S_MC_DQI_SKEW) +#define V_MC_DQI_SKEW(x) _SB_MAKEVALUE(x,S_MC_DQI_SKEW) +#define G_MC_DQI_SKEW(x) _SB_GETVALUE(x,S_MC_DQI_SKEW,M_MC_DQI_SKEW) +#define V_MC_DQI_SKEW_DEFAULT V_MC_DQI_SKEW(0) + +#define S_MC_DQO_SKEW 40 +#define M_MC_DQO_SKEW _SB_MAKEMASK(8,S_MC_DQO_SKEW) +#define V_MC_DQO_SKEW(x) _SB_MAKEVALUE(x,S_MC_DQO_SKEW) +#define G_MC_DQO_SKEW(x) _SB_GETVALUE(x,S_MC_DQO_SKEW,M_MC_DQO_SKEW) +#define V_MC_DQO_SKEW_DEFAULT V_MC_DQO_SKEW(0) + +#define S_MC_ADDR_SKEW 48 +#define M_MC_ADDR_SKEW _SB_MAKEMASK(8,S_MC_ADDR_SKEW) +#define V_MC_ADDR_SKEW(x) _SB_MAKEVALUE(x,S_MC_ADDR_SKEW) +#define G_MC_ADDR_SKEW(x) _SB_GETVALUE(x,S_MC_ADDR_SKEW,M_MC_ADDR_SKEW) +#define V_MC_ADDR_SKEW_DEFAULT V_MC_ADDR_SKEW(0x0F) + +#define S_MC_DLL_DEFAULT 56 +#define M_MC_DLL_DEFAULT _SB_MAKEMASK(8,S_MC_DLL_DEFAULT) +#define V_MC_DLL_DEFAULT(x) _SB_MAKEVALUE(x,S_MC_DLL_DEFAULT) +#define G_MC_DLL_DEFAULT(x) _SB_GETVALUE(x,S_MC_DLL_DEFAULT,M_MC_DLL_DEFAULT) +#define V_MC_DLL_DEFAULT_DEFAULT V_MC_DLL_DEFAULT(0x10) + +#define V_MC_CLKCONFIG_DEFAULT V_MC_DLL_DEFAULT_DEFAULT | \ + V_MC_ADDR_SKEW_DEFAULT | \ + V_MC_DQO_SKEW_DEFAULT | \ + V_MC_DQI_SKEW_DEFAULT | \ + V_MC_ADDR_DRIVE_DEFAULT | \ + V_MC_DATA_DRIVE_DEFAULT | \ + V_MC_CLOCK_DRIVE_DEFAULT | \ + V_MC_REF_RATE_DEFAULT + + + +/* + * DRAM Command Register (Table 6-13) + */ + +#define S_MC_COMMAND 0 +#define M_MC_COMMAND _SB_MAKEMASK(4,S_MC_COMMAND) +#define V_MC_COMMAND(x) _SB_MAKEVALUE(x,S_MC_COMMAND) +#define G_MC_COMMAND(x) _SB_GETVALUE(x,S_MC_COMMAND,M_MC_COMMAND) + +#define K_MC_COMMAND_EMRS 0 +#define K_MC_COMMAND_MRS 1 +#define K_MC_COMMAND_PRE 2 +#define K_MC_COMMAND_AR 3 +#define K_MC_COMMAND_SETRFSH 4 +#define K_MC_COMMAND_CLRRFSH 5 +#define K_MC_COMMAND_SETPWRDN 6 +#define K_MC_COMMAND_CLRPWRDN 7 + +#define V_MC_COMMAND_EMRS V_MC_COMMAND(K_MC_COMMAND_EMRS) +#define V_MC_COMMAND_MRS V_MC_COMMAND(K_MC_COMMAND_MRS) +#define V_MC_COMMAND_PRE V_MC_COMMAND(K_MC_COMMAND_PRE) +#define V_MC_COMMAND_AR V_MC_COMMAND(K_MC_COMMAND_AR) +#define V_MC_COMMAND_SETRFSH V_MC_COMMAND(K_MC_COMMAND_SETRFSH) +#define V_MC_COMMAND_CLRRFSH V_MC_COMMAND(K_MC_COMMAND_CLRRFSH) +#define V_MC_COMMAND_SETPWRDN V_MC_COMMAND(K_MC_COMMAND_SETPWRDN) +#define V_MC_COMMAND_CLRPWRDN V_MC_COMMAND(K_MC_COMMAND_CLRPWRDN) + +#define M_MC_CS0 _SB_MAKEMASK1(4) +#define M_MC_CS1 _SB_MAKEMASK1(5) +#define M_MC_CS2 _SB_MAKEMASK1(6) +#define M_MC_CS3 _SB_MAKEMASK1(7) + +/* + * DRAM Mode Register (Table 6-14) + */ + +#define S_MC_EMODE 0 +#define M_MC_EMODE _SB_MAKEMASK(15,S_MC_EMODE) +#define V_MC_EMODE(x) _SB_MAKEVALUE(x,S_MC_EMODE) +#define G_MC_EMODE(x) _SB_GETVALUE(x,S_MC_EMODE,M_MC_EMODE) +#define V_MC_EMODE_DEFAULT V_MC_EMODE(0) + +#define S_MC_MODE 16 +#define M_MC_MODE _SB_MAKEMASK(15,S_MC_MODE) +#define V_MC_MODE(x) _SB_MAKEVALUE(x,S_MC_MODE) +#define G_MC_MODE(x) _SB_GETVALUE(x,S_MC_MODE,M_MC_MODE) +#define V_MC_MODE_DEFAULT V_MC_MODE(0x22) + +#define S_MC_DRAM_TYPE 32 +#define M_MC_DRAM_TYPE _SB_MAKEMASK(3,S_MC_DRAM_TYPE) +#define V_MC_DRAM_TYPE(x) _SB_MAKEVALUE(x,S_MC_DRAM_TYPE) +#define G_MC_DRAM_TYPE(x) _SB_GETVALUE(x,S_MC_DRAM_TYPE,M_MC_DRAM_TYPE) + +#define K_MC_DRAM_TYPE_JEDEC 0 +#define K_MC_DRAM_TYPE_FCRAM 1 +#define K_MC_DRAM_TYPE_SGRAM 2 + +#define V_MC_DRAM_TYPE_JEDEC V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_JEDEC) +#define V_MC_DRAM_TYPE_FCRAM V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_FCRAM) +#define V_MC_DRAM_TYPE_SGRAM V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_SGRAM) + +#define M_MC_EXTERNALDECODE _SB_MAKEMASK1(35) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MC_PRE_ON_A8 _SB_MAKEMASK1(36) +#define M_MC_RAM_WITH_A13 _SB_MAKEMASK1(38) +#endif /* 112x PASS1 */ + + + +/* + * SDRAM Timing Register (Table 6-15) + */ + +#define M_MC_w2rIDLE_TWOCYCLES _SB_MAKEMASK1(60) +#define M_MC_r2wIDLE_TWOCYCLES _SB_MAKEMASK1(61) +#define M_MC_r2rIDLE_TWOCYCLES _SB_MAKEMASK1(62) + +#define S_MC_tFIFO 56 +#define M_MC_tFIFO _SB_MAKEMASK(4,S_MC_tFIFO) +#define V_MC_tFIFO(x) _SB_MAKEVALUE(x,S_MC_tFIFO) +#define G_MC_tFIFO(x) _SB_GETVALUE(x,S_MC_tFIFO,M_MC_tFIFO) +#define K_MC_tFIFO_DEFAULT 1 +#define V_MC_tFIFO_DEFAULT V_MC_tFIFO(K_MC_tFIFO_DEFAULT) + +#define S_MC_tRFC 52 +#define M_MC_tRFC _SB_MAKEMASK(4,S_MC_tRFC) +#define V_MC_tRFC(x) _SB_MAKEVALUE(x,S_MC_tRFC) +#define G_MC_tRFC(x) _SB_GETVALUE(x,S_MC_tRFC,M_MC_tRFC) +#define K_MC_tRFC_DEFAULT 12 +#define V_MC_tRFC_DEFAULT V_MC_tRFC(K_MC_tRFC_DEFAULT) + +#define S_MC_tCwCr 40 +#define M_MC_tCwCr _SB_MAKEMASK(4,S_MC_tCwCr) +#define V_MC_tCwCr(x) _SB_MAKEVALUE(x,S_MC_tCwCr) +#define G_MC_tCwCr(x) _SB_GETVALUE(x,S_MC_tCwCr,M_MC_tCwCr) +#define K_MC_tCwCr_DEFAULT 4 +#define V_MC_tCwCr_DEFAULT V_MC_tCwCr(K_MC_tCwCr_DEFAULT) + +#define S_MC_tRCr 28 +#define M_MC_tRCr _SB_MAKEMASK(4,S_MC_tRCr) +#define V_MC_tRCr(x) _SB_MAKEVALUE(x,S_MC_tRCr) +#define G_MC_tRCr(x) _SB_GETVALUE(x,S_MC_tRCr,M_MC_tRCr) +#define K_MC_tRCr_DEFAULT 9 +#define V_MC_tRCr_DEFAULT V_MC_tRCr(K_MC_tRCr_DEFAULT) + +#define S_MC_tRCw 24 +#define M_MC_tRCw _SB_MAKEMASK(4,S_MC_tRCw) +#define V_MC_tRCw(x) _SB_MAKEVALUE(x,S_MC_tRCw) +#define G_MC_tRCw(x) _SB_GETVALUE(x,S_MC_tRCw,M_MC_tRCw) +#define K_MC_tRCw_DEFAULT 10 +#define V_MC_tRCw_DEFAULT V_MC_tRCw(K_MC_tRCw_DEFAULT) + +#define S_MC_tRRD 20 +#define M_MC_tRRD _SB_MAKEMASK(4,S_MC_tRRD) +#define V_MC_tRRD(x) _SB_MAKEVALUE(x,S_MC_tRRD) +#define G_MC_tRRD(x) _SB_GETVALUE(x,S_MC_tRRD,M_MC_tRRD) +#define K_MC_tRRD_DEFAULT 2 +#define V_MC_tRRD_DEFAULT V_MC_tRRD(K_MC_tRRD_DEFAULT) + +#define S_MC_tRP 16 +#define M_MC_tRP _SB_MAKEMASK(4,S_MC_tRP) +#define V_MC_tRP(x) _SB_MAKEVALUE(x,S_MC_tRP) +#define G_MC_tRP(x) _SB_GETVALUE(x,S_MC_tRP,M_MC_tRP) +#define K_MC_tRP_DEFAULT 4 +#define V_MC_tRP_DEFAULT V_MC_tRP(K_MC_tRP_DEFAULT) + +#define S_MC_tCwD 8 +#define M_MC_tCwD _SB_MAKEMASK(4,S_MC_tCwD) +#define V_MC_tCwD(x) _SB_MAKEVALUE(x,S_MC_tCwD) +#define G_MC_tCwD(x) _SB_GETVALUE(x,S_MC_tCwD,M_MC_tCwD) +#define K_MC_tCwD_DEFAULT 1 +#define V_MC_tCwD_DEFAULT V_MC_tCwD(K_MC_tCwD_DEFAULT) + +#define M_tCrDh _SB_MAKEMASK1(7) +#define M_MC_tCrDh M_tCrDh + +#define S_MC_tCrD 4 +#define M_MC_tCrD _SB_MAKEMASK(3,S_MC_tCrD) +#define V_MC_tCrD(x) _SB_MAKEVALUE(x,S_MC_tCrD) +#define G_MC_tCrD(x) _SB_GETVALUE(x,S_MC_tCrD,M_MC_tCrD) +#define K_MC_tCrD_DEFAULT 2 +#define V_MC_tCrD_DEFAULT V_MC_tCrD(K_MC_tCrD_DEFAULT) + +#define S_MC_tRCD 0 +#define M_MC_tRCD _SB_MAKEMASK(4,S_MC_tRCD) +#define V_MC_tRCD(x) _SB_MAKEVALUE(x,S_MC_tRCD) +#define G_MC_tRCD(x) _SB_GETVALUE(x,S_MC_tRCD,M_MC_tRCD) +#define K_MC_tRCD_DEFAULT 3 +#define V_MC_tRCD_DEFAULT V_MC_tRCD(K_MC_tRCD_DEFAULT) + +#define V_MC_TIMING_DEFAULT V_MC_tFIFO(K_MC_tFIFO_DEFAULT) | \ + V_MC_tRFC(K_MC_tRFC_DEFAULT) | \ + V_MC_tCwCr(K_MC_tCwCr_DEFAULT) | \ + V_MC_tRCr(K_MC_tRCr_DEFAULT) | \ + V_MC_tRCw(K_MC_tRCw_DEFAULT) | \ + V_MC_tRRD(K_MC_tRRD_DEFAULT) | \ + V_MC_tRP(K_MC_tRP_DEFAULT) | \ + V_MC_tCwD(K_MC_tCwD_DEFAULT) | \ + V_MC_tCrD(K_MC_tCrD_DEFAULT) | \ + V_MC_tRCD(K_MC_tRCD_DEFAULT) | \ + M_MC_r2rIDLE_TWOCYCLES + +/* + * Errata says these are not the default + * M_MC_w2rIDLE_TWOCYCLES | \ + * M_MC_r2wIDLE_TWOCYCLES | \ + */ + + +/* + * Chip Select Start Address Register (Table 6-17) + */ + +#define S_MC_CS0_START 0 +#define M_MC_CS0_START _SB_MAKEMASK(16,S_MC_CS0_START) +#define V_MC_CS0_START(x) _SB_MAKEVALUE(x,S_MC_CS0_START) +#define G_MC_CS0_START(x) _SB_GETVALUE(x,S_MC_CS0_START,M_MC_CS0_START) + +#define S_MC_CS1_START 16 +#define M_MC_CS1_START _SB_MAKEMASK(16,S_MC_CS1_START) +#define V_MC_CS1_START(x) _SB_MAKEVALUE(x,S_MC_CS1_START) +#define G_MC_CS1_START(x) _SB_GETVALUE(x,S_MC_CS1_START,M_MC_CS1_START) + +#define S_MC_CS2_START 32 +#define M_MC_CS2_START _SB_MAKEMASK(16,S_MC_CS2_START) +#define V_MC_CS2_START(x) _SB_MAKEVALUE(x,S_MC_CS2_START) +#define G_MC_CS2_START(x) _SB_GETVALUE(x,S_MC_CS2_START,M_MC_CS2_START) + +#define S_MC_CS3_START 48 +#define M_MC_CS3_START _SB_MAKEMASK(16,S_MC_CS3_START) +#define V_MC_CS3_START(x) _SB_MAKEVALUE(x,S_MC_CS3_START) +#define G_MC_CS3_START(x) _SB_GETVALUE(x,S_MC_CS3_START,M_MC_CS3_START) + +/* + * Chip Select End Address Register (Table 6-18) + */ + +#define S_MC_CS0_END 0 +#define M_MC_CS0_END _SB_MAKEMASK(16,S_MC_CS0_END) +#define V_MC_CS0_END(x) _SB_MAKEVALUE(x,S_MC_CS0_END) +#define G_MC_CS0_END(x) _SB_GETVALUE(x,S_MC_CS0_END,M_MC_CS0_END) + +#define S_MC_CS1_END 16 +#define M_MC_CS1_END _SB_MAKEMASK(16,S_MC_CS1_END) +#define V_MC_CS1_END(x) _SB_MAKEVALUE(x,S_MC_CS1_END) +#define G_MC_CS1_END(x) _SB_GETVALUE(x,S_MC_CS1_END,M_MC_CS1_END) + +#define S_MC_CS2_END 32 +#define M_MC_CS2_END _SB_MAKEMASK(16,S_MC_CS2_END) +#define V_MC_CS2_END(x) _SB_MAKEVALUE(x,S_MC_CS2_END) +#define G_MC_CS2_END(x) _SB_GETVALUE(x,S_MC_CS2_END,M_MC_CS2_END) + +#define S_MC_CS3_END 48 +#define M_MC_CS3_END _SB_MAKEMASK(16,S_MC_CS3_END) +#define V_MC_CS3_END(x) _SB_MAKEVALUE(x,S_MC_CS3_END) +#define G_MC_CS3_END(x) _SB_GETVALUE(x,S_MC_CS3_END,M_MC_CS3_END) + +/* + * Chip Select Interleave Register (Table 6-19) + */ + +#define S_MC_INTLV_RESERVED 0 +#define M_MC_INTLV_RESERVED _SB_MAKEMASK(5,S_MC_INTLV_RESERVED) + +#define S_MC_INTERLEAVE 7 +#define M_MC_INTERLEAVE _SB_MAKEMASK(18,S_MC_INTERLEAVE) +#define V_MC_INTERLEAVE(x) _SB_MAKEVALUE(x,S_MC_INTERLEAVE) + +#define S_MC_INTLV_MBZ 25 +#define M_MC_INTLV_MBZ _SB_MAKEMASK(39,S_MC_INTLV_MBZ) + +/* + * Row Address Bits Register (Table 6-20) + */ + +#define S_MC_RAS_RESERVED 0 +#define M_MC_RAS_RESERVED _SB_MAKEMASK(5,S_MC_RAS_RESERVED) + +#define S_MC_RAS_SELECT 12 +#define M_MC_RAS_SELECT _SB_MAKEMASK(25,S_MC_RAS_SELECT) +#define V_MC_RAS_SELECT(x) _SB_MAKEVALUE(x,S_MC_RAS_SELECT) + +#define S_MC_RAS_MBZ 37 +#define M_MC_RAS_MBZ _SB_MAKEMASK(27,S_MC_RAS_MBZ) + + +/* + * Column Address Bits Register (Table 6-21) + */ + +#define S_MC_CAS_RESERVED 0 +#define M_MC_CAS_RESERVED _SB_MAKEMASK(5,S_MC_CAS_RESERVED) + +#define S_MC_CAS_SELECT 5 +#define M_MC_CAS_SELECT _SB_MAKEMASK(18,S_MC_CAS_SELECT) +#define V_MC_CAS_SELECT(x) _SB_MAKEVALUE(x,S_MC_CAS_SELECT) + +#define S_MC_CAS_MBZ 23 +#define M_MC_CAS_MBZ _SB_MAKEMASK(41,S_MC_CAS_MBZ) + + +/* + * Bank Address Address Bits Register (Table 6-22) + */ + +#define S_MC_BA_RESERVED 0 +#define M_MC_BA_RESERVED _SB_MAKEMASK(5,S_MC_BA_RESERVED) + +#define S_MC_BA_SELECT 5 +#define M_MC_BA_SELECT _SB_MAKEMASK(20,S_MC_BA_SELECT) +#define V_MC_BA_SELECT(x) _SB_MAKEVALUE(x,S_MC_BA_SELECT) + +#define S_MC_BA_MBZ 25 +#define M_MC_BA_MBZ _SB_MAKEMASK(39,S_MC_BA_MBZ) + +/* + * Chip Select Attribute Register (Table 6-23) + */ + +#define K_MC_CS_ATTR_CLOSED 0 +#define K_MC_CS_ATTR_CASCHECK 1 +#define K_MC_CS_ATTR_HINT 2 +#define K_MC_CS_ATTR_OPEN 3 + +#define S_MC_CS0_PAGE 0 +#define M_MC_CS0_PAGE _SB_MAKEMASK(2,S_MC_CS0_PAGE) +#define V_MC_CS0_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS0_PAGE) +#define G_MC_CS0_PAGE(x) _SB_GETVALUE(x,S_MC_CS0_PAGE,M_MC_CS0_PAGE) + +#define S_MC_CS1_PAGE 16 +#define M_MC_CS1_PAGE _SB_MAKEMASK(2,S_MC_CS1_PAGE) +#define V_MC_CS1_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS1_PAGE) +#define G_MC_CS1_PAGE(x) _SB_GETVALUE(x,S_MC_CS1_PAGE,M_MC_CS1_PAGE) + +#define S_MC_CS2_PAGE 32 +#define M_MC_CS2_PAGE _SB_MAKEMASK(2,S_MC_CS2_PAGE) +#define V_MC_CS2_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS2_PAGE) +#define G_MC_CS2_PAGE(x) _SB_GETVALUE(x,S_MC_CS2_PAGE,M_MC_CS2_PAGE) + +#define S_MC_CS3_PAGE 48 +#define M_MC_CS3_PAGE _SB_MAKEMASK(2,S_MC_CS3_PAGE) +#define V_MC_CS3_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS3_PAGE) +#define G_MC_CS3_PAGE(x) _SB_GETVALUE(x,S_MC_CS3_PAGE,M_MC_CS3_PAGE) + +/* + * ECC Test ECC Register (Table 6-25) + */ + +#define S_MC_ECC_INVERT 0 +#define M_MC_ECC_INVERT _SB_MAKEMASK(8,S_MC_ECC_INVERT) + + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_regs.h b/include/asm-mips/sibyte/sb1250_regs.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_regs.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,835 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Register Definitions File: sb1250_regs.h + * + * This module contains the addresses of the on-chip peripherals + * on the SB1250. + * + * SB1250 specification level: 01/02/2002 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_REGS_H +#define _SB1250_REGS_H + +#include "sb1250_defs.h" + + +/* ********************************************************************* + * Some general notes: + * + * For the most part, when there is more than one peripheral + * of the same type on the SOC, the constants below will be + * offsets from the base of each peripheral. For example, + * the MAC registers are described as offsets from the first + * MAC register, and there will be a MAC_REGISTER() macro + * to calculate the base address of a given MAC. + * + * The information in this file is based on the SB1250 SOC + * manual version 0.2, July 2000. + ********************************************************************* */ + + +/* ********************************************************************* + * Memory Controller Registers + ********************************************************************* */ + +/* + * XXX: can't remove MC base 0 if 112x, since it's used by other macros, + * since there is one reg there (but it could get its addr/offset constant). + */ +#define A_MC_BASE_0 0x0010051000 +#define A_MC_BASE_1 0x0010052000 +#define MC_REGISTER_SPACING 0x1000 + +#define A_MC_BASE(ctlid) ((ctlid)*MC_REGISTER_SPACING+A_MC_BASE_0) +#define A_MC_REGISTER(ctlid,reg) (A_MC_BASE(ctlid)+(reg)) + +#define R_MC_CONFIG 0x0000000100 +#define R_MC_DRAMCMD 0x0000000120 +#define R_MC_DRAMMODE 0x0000000140 +#define R_MC_TIMING1 0x0000000160 +#define R_MC_TIMING2 0x0000000180 +#define R_MC_CS_START 0x00000001A0 +#define R_MC_CS_END 0x00000001C0 +#define R_MC_CS_INTERLEAVE 0x00000001E0 +#define S_MC_CS_STARTEND 16 + +#define R_MC_CSX_BASE 0x0000000200 +#define R_MC_CSX_ROW 0x0000000000 /* relative to CSX_BASE, above */ +#define R_MC_CSX_COL 0x0000000020 /* relative to CSX_BASE, above */ +#define R_MC_CSX_BA 0x0000000040 /* relative to CSX_BASE, above */ +#define MC_CSX_SPACING 0x0000000060 /* relative to CSX_BASE, above */ + +#define R_MC_CS0_ROW 0x0000000200 +#define R_MC_CS0_COL 0x0000000220 +#define R_MC_CS0_BA 0x0000000240 +#define R_MC_CS1_ROW 0x0000000260 +#define R_MC_CS1_COL 0x0000000280 +#define R_MC_CS1_BA 0x00000002A0 +#define R_MC_CS2_ROW 0x00000002C0 +#define R_MC_CS2_COL 0x00000002E0 +#define R_MC_CS2_BA 0x0000000300 +#define R_MC_CS3_ROW 0x0000000320 +#define R_MC_CS3_COL 0x0000000340 +#define R_MC_CS3_BA 0x0000000360 +#define R_MC_CS_ATTR 0x0000000380 +#define R_MC_TEST_DATA 0x0000000400 +#define R_MC_TEST_ECC 0x0000000420 +#define R_MC_MCLK_CFG 0x0000000500 + +/* ********************************************************************* + * L2 Cache Control Registers + ********************************************************************* */ + +#define A_L2_READ_TAG 0x0010040018 +#define A_L2_ECC_TAG 0x0010040038 +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_L2_READ_MISC 0x0010040058 +#endif /* 112x PASS1 */ +#define A_L2_WAY_DISABLE 0x0010041000 +#define A_L2_MAKEDISABLE(x) (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8)) +#define A_L2_MGMT_TAG_BASE 0x00D0000000 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_L2_CACHE_DISABLE 0x0010042000 +#define A_L2_MAKECACHEDISABLE(x) (A_L2_CACHE_DISABLE | (((x)&0x0F) << 8)) +#define A_L2_MISC_CONFIG 0x0010043000 +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* Backward-compatibility definitions. */ +/* XXX: discourage people from using these constants. */ +#define A_L2_READ_ADDRESS A_L2_READ_TAG +#define A_L2_EEC_ADDRESS A_L2_ECC_TAG + + +/* ********************************************************************* + * PCI Interface Registers + ********************************************************************* */ + +#define A_PCI_TYPE00_HEADER 0x00DE000000 +#define A_PCI_TYPE01_HEADER 0x00DE000800 + + +/* ********************************************************************* + * Ethernet DMA and MACs + ********************************************************************* */ + +#define A_MAC_BASE_0 0x0010064000 +#define A_MAC_BASE_1 0x0010065000 +#if SIBYTE_HDR_FEATURE_CHIP(1250) +#define A_MAC_BASE_2 0x0010066000 +#endif /* 1250 */ + +#define MAC_SPACING 0x1000 +#define MAC_DMA_TXRX_SPACING 0x0400 +#define MAC_DMA_CHANNEL_SPACING 0x0100 +#define DMA_RX 0 +#define DMA_TX 1 +#define MAC_NUM_DMACHAN 2 /* channels per direction */ + +/* XXX: not correct; depends on SOC type. */ +#define MAC_NUM_PORTS 3 + +#define A_MAC_CHANNEL_BASE(macnum) \ + (A_MAC_BASE_0 + \ + MAC_SPACING*(macnum)) + +#define A_MAC_REGISTER(macnum,reg) \ + (A_MAC_BASE_0 + \ + MAC_SPACING*(macnum) + (reg)) + + +#define R_MAC_DMA_CHANNELS 0x800 /* Relative to A_MAC_CHANNEL_BASE */ + +#define A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan) \ + ((A_MAC_CHANNEL_BASE(macnum)) + \ + R_MAC_DMA_CHANNELS + \ + (MAC_DMA_TXRX_SPACING*(txrx)) + \ + (MAC_DMA_CHANNEL_SPACING*(chan))) + +#define R_MAC_DMA_CHANNEL_BASE(txrx,chan) \ + (R_MAC_DMA_CHANNELS + \ + (MAC_DMA_TXRX_SPACING*(txrx)) + \ + (MAC_DMA_CHANNEL_SPACING*(chan))) + +#define A_MAC_DMA_REGISTER(macnum,txrx,chan,reg) \ + (A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan) + \ + (reg)) + +#define R_MAC_DMA_REGISTER(txrx,chan,reg) \ + (R_MAC_DMA_CHANNEL_BASE(txrx,chan) + \ + (reg)) + +/* + * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE + */ + +#define R_MAC_DMA_CONFIG0 0x00000000 +#define R_MAC_DMA_CONFIG1 0x00000008 +#define R_MAC_DMA_DSCR_BASE 0x00000010 +#define R_MAC_DMA_DSCR_CNT 0x00000018 +#define R_MAC_DMA_CUR_DSCRA 0x00000020 +#define R_MAC_DMA_CUR_DSCRB 0x00000028 +#define R_MAC_DMA_CUR_DSCRADDR 0x00000030 +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_MAC_DMA_OODPKTLOST_RX 0x00000038 /* rx only */ +#endif /* 112x PASS1 */ + +/* + * RMON Counters + */ + +#define R_MAC_RMON_TX_BYTES 0x00000000 +#define R_MAC_RMON_COLLISIONS 0x00000008 +#define R_MAC_RMON_LATE_COL 0x00000010 +#define R_MAC_RMON_EX_COL 0x00000018 +#define R_MAC_RMON_FCS_ERROR 0x00000020 +#define R_MAC_RMON_TX_ABORT 0x00000028 +/* Counter #6 (0x30) now reserved */ +#define R_MAC_RMON_TX_BAD 0x00000038 +#define R_MAC_RMON_TX_GOOD 0x00000040 +#define R_MAC_RMON_TX_RUNT 0x00000048 +#define R_MAC_RMON_TX_OVERSIZE 0x00000050 +#define R_MAC_RMON_RX_BYTES 0x00000080 +#define R_MAC_RMON_RX_MCAST 0x00000088 +#define R_MAC_RMON_RX_BCAST 0x00000090 +#define R_MAC_RMON_RX_BAD 0x00000098 +#define R_MAC_RMON_RX_GOOD 0x000000A0 +#define R_MAC_RMON_RX_RUNT 0x000000A8 +#define R_MAC_RMON_RX_OVERSIZE 0x000000B0 +#define R_MAC_RMON_RX_FCS_ERROR 0x000000B8 +#define R_MAC_RMON_RX_LENGTH_ERROR 0x000000C0 +#define R_MAC_RMON_RX_CODE_ERROR 0x000000C8 +#define R_MAC_RMON_RX_ALIGN_ERROR 0x000000D0 + +/* Updated to spec 0.2 */ +#define R_MAC_CFG 0x00000100 +#define R_MAC_THRSH_CFG 0x00000108 +#define R_MAC_VLANTAG 0x00000110 +#define R_MAC_FRAMECFG 0x00000118 +#define R_MAC_EOPCNT 0x00000120 +#define R_MAC_FIFO_PTRS 0x00000130 +#define R_MAC_ADFILTER_CFG 0x00000200 +#define R_MAC_ETHERNET_ADDR 0x00000208 +#define R_MAC_PKT_TYPE 0x00000210 +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_MAC_ADMASK0 0x00000218 +#define R_MAC_ADMASK1 0x00000220 +#endif /* 112x PASS1 */ +#define R_MAC_HASH_BASE 0x00000240 +#define R_MAC_ADDR_BASE 0x00000280 +#define R_MAC_CHLO0_BASE 0x00000300 +#define R_MAC_CHUP0_BASE 0x00000320 +#define R_MAC_ENABLE 0x00000400 +#define R_MAC_STATUS 0x00000408 +#define R_MAC_INT_MASK 0x00000410 +#define R_MAC_TXD_CTL 0x00000420 +#define R_MAC_MDIO 0x00000428 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_MAC_STATUS1 0x00000430 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define R_MAC_DEBUG_STATUS 0x00000448 + +#define MAC_HASH_COUNT 8 +#define MAC_ADDR_COUNT 8 +#define MAC_CHMAP_COUNT 4 + + +/* ********************************************************************* + * DUART Registers + ********************************************************************* */ + + +#define R_DUART_NUM_PORTS 2 + +#define A_DUART 0x0010060000 + +#define A_DUART_REG(r) + +#define DUART_CHANREG_SPACING 0x100 +#define A_DUART_CHANREG(chan,reg) (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg)) +#define R_DUART_CHANREG(chan,reg) (DUART_CHANREG_SPACING*(chan) + (reg)) + +#define R_DUART_MODE_REG_1 0x100 +#define R_DUART_MODE_REG_2 0x110 +#define R_DUART_STATUS 0x120 +#define R_DUART_CLK_SEL 0x130 +#define R_DUART_CMD 0x150 +#define R_DUART_RX_HOLD 0x160 +#define R_DUART_TX_HOLD 0x170 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_DUART_FULL_CTL 0x140 +#define R_DUART_OPCR_X 0x180 +#define R_DUART_AUXCTL_X 0x190 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* + * The IMR and ISR can't be addressed with A_DUART_CHANREG, + * so use this macro instead. + */ + +#define R_DUART_AUX_CTRL 0x310 +#define R_DUART_ISR_A 0x320 +#define R_DUART_IMR_A 0x330 +#define R_DUART_ISR_B 0x340 +#define R_DUART_IMR_B 0x350 +#define R_DUART_OUT_PORT 0x360 +#define R_DUART_OPCR 0x370 + +#define R_DUART_SET_OPR 0x3B0 +#define R_DUART_CLEAR_OPR 0x3C0 + +#define DUART_IMRISR_SPACING 0x20 + +#define R_DUART_IMRREG(chan) (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING) +#define R_DUART_ISRREG(chan) (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING) + +#define A_DUART_IMRREG(chan) (A_DUART + R_DUART_IMRREG(chan)) +#define A_DUART_ISRREG(chan) (A_DUART + R_DUART_ISRREG(chan)) + + + + +/* + * These constants are the absolute addresses. + */ + +#define A_DUART_MODE_REG_1_A 0x0010060100 +#define A_DUART_MODE_REG_2_A 0x0010060110 +#define A_DUART_STATUS_A 0x0010060120 +#define A_DUART_CLK_SEL_A 0x0010060130 +#define A_DUART_CMD_A 0x0010060150 +#define A_DUART_RX_HOLD_A 0x0010060160 +#define A_DUART_TX_HOLD_A 0x0010060170 + +#define A_DUART_MODE_REG_1_B 0x0010060200 +#define A_DUART_MODE_REG_2_B 0x0010060210 +#define A_DUART_STATUS_B 0x0010060220 +#define A_DUART_CLK_SEL_B 0x0010060230 +#define A_DUART_CMD_B 0x0010060250 +#define A_DUART_RX_HOLD_B 0x0010060260 +#define A_DUART_TX_HOLD_B 0x0010060270 + +#define A_DUART_INPORT_CHNG 0x0010060300 +#define A_DUART_AUX_CTRL 0x0010060310 +#define A_DUART_ISR_A 0x0010060320 +#define A_DUART_IMR_A 0x0010060330 +#define A_DUART_ISR_B 0x0010060340 +#define A_DUART_IMR_B 0x0010060350 +#define A_DUART_OUT_PORT 0x0010060360 +#define A_DUART_OPCR 0x0010060370 +#define A_DUART_IN_PORT 0x0010060380 +#define A_DUART_ISR 0x0010060390 +#define A_DUART_IMR 0x00100603A0 +#define A_DUART_SET_OPR 0x00100603B0 +#define A_DUART_CLEAR_OPR 0x00100603C0 +#define A_DUART_INPORT_CHNG_A 0x00100603D0 +#define A_DUART_INPORT_CHNG_B 0x00100603E0 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_DUART_FULL_CTL_A 0x0010060140 +#define A_DUART_FULL_CTL_B 0x0010060240 + +#define A_DUART_OPCR_A 0x0010060180 +#define A_DUART_OPCR_B 0x0010060280 + +#define A_DUART_INPORT_CHNG_DEBUG 0x00100603F0 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************* + * Synchronous Serial Registers + ********************************************************************* */ + + +#define A_SER_BASE_0 0x0010060400 +#define A_SER_BASE_1 0x0010060800 +#define SER_SPACING 0x400 + +#define SER_DMA_TXRX_SPACING 0x80 + +#define SER_NUM_PORTS 2 + +#define A_SER_CHANNEL_BASE(sernum) \ + (A_SER_BASE_0 + \ + SER_SPACING*(sernum)) + +#define A_SER_REGISTER(sernum,reg) \ + (A_SER_BASE_0 + \ + SER_SPACING*(sernum) + (reg)) + + +#define R_SER_DMA_CHANNELS 0 /* Relative to A_SER_BASE_x */ + +#define A_SER_DMA_CHANNEL_BASE(sernum,txrx) \ + ((A_SER_CHANNEL_BASE(sernum)) + \ + R_SER_DMA_CHANNELS + \ + (SER_DMA_TXRX_SPACING*(txrx))) + +#define A_SER_DMA_REGISTER(sernum,txrx,reg) \ + (A_SER_DMA_CHANNEL_BASE(sernum,txrx) + \ + (reg)) + + +/* + * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE + */ + +#define R_SER_DMA_CONFIG0 0x00000000 +#define R_SER_DMA_CONFIG1 0x00000008 +#define R_SER_DMA_DSCR_BASE 0x00000010 +#define R_SER_DMA_DSCR_CNT 0x00000018 +#define R_SER_DMA_CUR_DSCRA 0x00000020 +#define R_SER_DMA_CUR_DSCRB 0x00000028 +#define R_SER_DMA_CUR_DSCRADDR 0x00000030 + +#define R_SER_DMA_CONFIG0_RX 0x00000000 +#define R_SER_DMA_CONFIG1_RX 0x00000008 +#define R_SER_DMA_DSCR_BASE_RX 0x00000010 +#define R_SER_DMA_DSCR_COUNT_RX 0x00000018 +#define R_SER_DMA_CUR_DSCR_A_RX 0x00000020 +#define R_SER_DMA_CUR_DSCR_B_RX 0x00000028 +#define R_SER_DMA_CUR_DSCR_ADDR_RX 0x00000030 + +#define R_SER_DMA_CONFIG0_TX 0x00000080 +#define R_SER_DMA_CONFIG1_TX 0x00000088 +#define R_SER_DMA_DSCR_BASE_TX 0x00000090 +#define R_SER_DMA_DSCR_COUNT_TX 0x00000098 +#define R_SER_DMA_CUR_DSCR_A_TX 0x000000A0 +#define R_SER_DMA_CUR_DSCR_B_TX 0x000000A8 +#define R_SER_DMA_CUR_DSCR_ADDR_TX 0x000000B0 + +#define R_SER_MODE 0x00000100 +#define R_SER_MINFRM_SZ 0x00000108 +#define R_SER_MAXFRM_SZ 0x00000110 +#define R_SER_ADDR 0x00000118 +#define R_SER_USR0_ADDR 0x00000120 +#define R_SER_USR1_ADDR 0x00000128 +#define R_SER_USR2_ADDR 0x00000130 +#define R_SER_USR3_ADDR 0x00000138 +#define R_SER_CMD 0x00000140 +#define R_SER_TX_RD_THRSH 0x00000160 +#define R_SER_TX_WR_THRSH 0x00000168 +#define R_SER_RX_RD_THRSH 0x00000170 +#define R_SER_LINE_MODE 0x00000178 +#define R_SER_DMA_ENABLE 0x00000180 +#define R_SER_INT_MASK 0x00000190 +#define R_SER_STATUS 0x00000188 +#define R_SER_STATUS_DEBUG 0x000001A8 +#define R_SER_RX_TABLE_BASE 0x00000200 +#define SER_RX_TABLE_COUNT 16 +#define R_SER_TX_TABLE_BASE 0x00000300 +#define SER_TX_TABLE_COUNT 16 + +/* RMON Counters */ +#define R_SER_RMON_TX_BYTE_LO 0x000001C0 +#define R_SER_RMON_TX_BYTE_HI 0x000001C8 +#define R_SER_RMON_RX_BYTE_LO 0x000001D0 +#define R_SER_RMON_RX_BYTE_HI 0x000001D8 +#define R_SER_RMON_TX_UNDERRUN 0x000001E0 +#define R_SER_RMON_RX_OVERFLOW 0x000001E8 +#define R_SER_RMON_RX_ERRORS 0x000001F0 +#define R_SER_RMON_RX_BADADDR 0x000001F8 + +/* ********************************************************************* + * Generic Bus Registers + ********************************************************************* */ + +#define IO_EXT_CFG_COUNT 8 + +#define A_IO_EXT_BASE 0x0010061000 +#define A_IO_EXT_REG(r) (A_IO_EXT_BASE + (r)) + +#define A_IO_EXT_CFG_BASE 0x0010061000 +#define A_IO_EXT_MULT_SIZE_BASE 0x0010061100 +#define A_IO_EXT_START_ADDR_BASE 0x0010061200 +#define A_IO_EXT_TIME_CFG0_BASE 0x0010061600 +#define A_IO_EXT_TIME_CFG1_BASE 0x0010061700 + +#define IO_EXT_REGISTER_SPACING 8 +#define A_IO_EXT_CS_BASE(cs) (A_IO_EXT_CFG_BASE+IO_EXT_REGISTER_SPACING*(cs)) +#define R_IO_EXT_REG(reg,cs) ((cs)*IO_EXT_REGISTER_SPACING + (reg)) + +#define R_IO_EXT_CFG 0x0000 +#define R_IO_EXT_MULT_SIZE 0x0100 +#define R_IO_EXT_START_ADDR 0x0200 +#define R_IO_EXT_TIME_CFG0 0x0600 +#define R_IO_EXT_TIME_CFG1 0x0700 + + +#define A_IO_INTERRUPT_STATUS 0x0010061A00 +#define A_IO_INTERRUPT_DATA0 0x0010061A10 +#define A_IO_INTERRUPT_DATA1 0x0010061A18 +#define A_IO_INTERRUPT_DATA2 0x0010061A20 +#define A_IO_INTERRUPT_DATA3 0x0010061A28 +#define A_IO_INTERRUPT_ADDR0 0x0010061A30 +#define A_IO_INTERRUPT_ADDR1 0x0010061A40 +#define A_IO_INTERRUPT_PARITY 0x0010061A50 +#define A_IO_PCMCIA_CFG 0x0010061A60 +#define A_IO_PCMCIA_STATUS 0x0010061A70 +#define A_IO_DRIVE_0 0x0010061300 +#define A_IO_DRIVE_1 0x0010061308 +#define A_IO_DRIVE_2 0x0010061310 +#define A_IO_DRIVE_3 0x0010061318 +#define A_IO_DRIVE_BASE A_IO_DRIVE_0 +#define IO_DRIVE_REGISTER_SPACING 8 +#define R_IO_DRIVE(x) ((x)*IO_DRIVE_REGISTER_SPACING) +#define A_IO_DRIVE(x) (A_IO_DRIVE_BASE + R_IO_DRIVE(x)) + +#define R_IO_INTERRUPT_STATUS 0x0A00 +#define R_IO_INTERRUPT_DATA0 0x0A10 +#define R_IO_INTERRUPT_DATA1 0x0A18 +#define R_IO_INTERRUPT_DATA2 0x0A20 +#define R_IO_INTERRUPT_DATA3 0x0A28 +#define R_IO_INTERRUPT_ADDR0 0x0A30 +#define R_IO_INTERRUPT_ADDR1 0x0A40 +#define R_IO_INTERRUPT_PARITY 0x0A50 +#define R_IO_PCMCIA_CFG 0x0A60 +#define R_IO_PCMCIA_STATUS 0x0A70 + +/* ********************************************************************* + * GPIO Registers + ********************************************************************* */ + +#define A_GPIO_CLR_EDGE 0x0010061A80 +#define A_GPIO_INT_TYPE 0x0010061A88 +#define A_GPIO_INPUT_INVERT 0x0010061A90 +#define A_GPIO_GLITCH 0x0010061A98 +#define A_GPIO_READ 0x0010061AA0 +#define A_GPIO_DIRECTION 0x0010061AA8 +#define A_GPIO_PIN_CLR 0x0010061AB0 +#define A_GPIO_PIN_SET 0x0010061AB8 + +#define A_GPIO_BASE 0x0010061A80 + +#define R_GPIO_CLR_EDGE 0x00 +#define R_GPIO_INT_TYPE 0x08 +#define R_GPIO_INPUT_INVERT 0x10 +#define R_GPIO_GLITCH 0x18 +#define R_GPIO_READ 0x20 +#define R_GPIO_DIRECTION 0x28 +#define R_GPIO_PIN_CLR 0x30 +#define R_GPIO_PIN_SET 0x38 + +/* ********************************************************************* + * SMBus Registers + ********************************************************************* */ + +#define A_SMB_XTRA_0 0x0010060000 +#define A_SMB_XTRA_1 0x0010060008 +#define A_SMB_FREQ_0 0x0010060010 +#define A_SMB_FREQ_1 0x0010060018 +#define A_SMB_STATUS_0 0x0010060020 +#define A_SMB_STATUS_1 0x0010060028 +#define A_SMB_CMD_0 0x0010060030 +#define A_SMB_CMD_1 0x0010060038 +#define A_SMB_START_0 0x0010060040 +#define A_SMB_START_1 0x0010060048 +#define A_SMB_DATA_0 0x0010060050 +#define A_SMB_DATA_1 0x0010060058 +#define A_SMB_CONTROL_0 0x0010060060 +#define A_SMB_CONTROL_1 0x0010060068 +#define A_SMB_PEC_0 0x0010060070 +#define A_SMB_PEC_1 0x0010060078 + +#define A_SMB_0 0x0010060000 +#define A_SMB_1 0x0010060008 +#define SMB_REGISTER_SPACING 0x8 +#define A_SMB_BASE(idx) (A_SMB_0+(idx)*SMB_REGISTER_SPACING) +#define A_SMB_REGISTER(idx,reg) (A_SMB_BASE(idx)+(reg)) + +#define R_SMB_XTRA 0x0000000000 +#define R_SMB_FREQ 0x0000000010 +#define R_SMB_STATUS 0x0000000020 +#define R_SMB_CMD 0x0000000030 +#define R_SMB_START 0x0000000040 +#define R_SMB_DATA 0x0000000050 +#define R_SMB_CONTROL 0x0000000060 +#define R_SMB_PEC 0x0000000070 + +/* ********************************************************************* + * Timer Registers + ********************************************************************* */ + +/* + * Watchdog timers + */ + +#define A_SCD_WDOG_0 0x0010020050 +#define A_SCD_WDOG_1 0x0010020150 +#define SCD_WDOG_SPACING 0x100 +#define SCD_NUM_WDOGS 2 +#define A_SCD_WDOG_BASE(w) (A_SCD_WDOG_0+SCD_WDOG_SPACING*(w)) +#define A_SCD_WDOG_REGISTER(w,r) (A_SCD_WDOG_BASE(w) + (r)) + +#define R_SCD_WDOG_INIT 0x0000000000 +#define R_SCD_WDOG_CNT 0x0000000008 +#define R_SCD_WDOG_CFG 0x0000000010 + +#define A_SCD_WDOG_INIT_0 0x0010020050 +#define A_SCD_WDOG_CNT_0 0x0010020058 +#define A_SCD_WDOG_CFG_0 0x0010020060 + +#define A_SCD_WDOG_INIT_1 0x0010020150 +#define A_SCD_WDOG_CNT_1 0x0010020158 +#define A_SCD_WDOG_CFG_1 0x0010020160 + +/* + * Generic timers + */ + +#define A_SCD_TIMER_0 0x0010020070 +#define A_SCD_TIMER_1 0x0010020078 +#define A_SCD_TIMER_2 0x0010020170 +#define A_SCD_TIMER_3 0x0010020178 +#define SCD_NUM_TIMERS 4 +#define A_SCD_TIMER_BASE(w) (A_SCD_TIMER_0+0x08*((w)&1)+0x100*(((w)&2)>>1)) +#define A_SCD_TIMER_REGISTER(w,r) (A_SCD_TIMER_BASE(w) + (r)) + +#define R_SCD_TIMER_INIT 0x0000000000 +#define R_SCD_TIMER_CNT 0x0000000010 +#define R_SCD_TIMER_CFG 0x0000000020 + +#define A_SCD_TIMER_INIT_0 0x0010020070 +#define A_SCD_TIMER_CNT_0 0x0010020080 +#define A_SCD_TIMER_CFG_0 0x0010020090 + +#define A_SCD_TIMER_INIT_1 0x0010020078 +#define A_SCD_TIMER_CNT_1 0x0010020088 +#define A_SCD_TIMER_CFG_1 0x0010020098 + +#define A_SCD_TIMER_INIT_2 0x0010020170 +#define A_SCD_TIMER_CNT_2 0x0010020180 +#define A_SCD_TIMER_CFG_2 0x0010020190 + +#define A_SCD_TIMER_INIT_3 0x0010020178 +#define A_SCD_TIMER_CNT_3 0x0010020188 +#define A_SCD_TIMER_CFG_3 0x0010020198 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_SCD_SCRATCH 0x0010020C10 + +#define A_SCD_ZBBUS_CYCLE_COUNT 0x0010030000 +#define A_SCD_ZBBUS_CYCLE_CP0 0x0010020C00 +#define A_SCD_ZBBUS_CYCLE_CP1 0x0010020C08 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************* + * System Control Registers + ********************************************************************* */ + +#define A_SCD_SYSTEM_REVISION 0x0010020000 +#define A_SCD_SYSTEM_CFG 0x0010020008 + +/* ********************************************************************* + * System Address Trap Registers + ********************************************************************* */ + +#define A_ADDR_TRAP_INDEX 0x00100200B0 +#define A_ADDR_TRAP_REG 0x00100200B8 +#define A_ADDR_TRAP_UP_0 0x0010020400 +#define A_ADDR_TRAP_UP_1 0x0010020408 +#define A_ADDR_TRAP_UP_2 0x0010020410 +#define A_ADDR_TRAP_UP_3 0x0010020418 +#define A_ADDR_TRAP_DOWN_0 0x0010020420 +#define A_ADDR_TRAP_DOWN_1 0x0010020428 +#define A_ADDR_TRAP_DOWN_2 0x0010020430 +#define A_ADDR_TRAP_DOWN_3 0x0010020438 +#define A_ADDR_TRAP_CFG_0 0x0010020440 +#define A_ADDR_TRAP_CFG_1 0x0010020448 +#define A_ADDR_TRAP_CFG_2 0x0010020450 +#define A_ADDR_TRAP_CFG_3 0x0010020458 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_ADDR_TRAP_REG_DEBUG 0x0010020460 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************* + * System Interrupt Mapper Registers + ********************************************************************* */ + +#define A_IMR_CPU0_BASE 0x0010020000 +#define A_IMR_CPU1_BASE 0x0010022000 +#define IMR_REGISTER_SPACING 0x2000 +#define IMR_REGISTER_SPACING_SHIFT 13 + +#define A_IMR_MAPPER(cpu) (A_IMR_CPU0_BASE+(cpu)*IMR_REGISTER_SPACING) +#define A_IMR_REGISTER(cpu,reg) (A_IMR_MAPPER(cpu)+(reg)) + +#define R_IMR_INTERRUPT_DIAG 0x0010 +#define R_IMR_INTERRUPT_MASK 0x0028 +#define R_IMR_INTERRUPT_TRACE 0x0038 +#define R_IMR_INTERRUPT_SOURCE_STATUS 0x0040 +#define R_IMR_LDT_INTERRUPT_SET 0x0048 +#define R_IMR_LDT_INTERRUPT 0x0018 +#define R_IMR_LDT_INTERRUPT_CLR 0x0020 +#define R_IMR_MAILBOX_CPU 0x00c0 +#define R_IMR_ALIAS_MAILBOX_CPU 0x1000 +#define R_IMR_MAILBOX_SET_CPU 0x00C8 +#define R_IMR_ALIAS_MAILBOX_SET_CPU 0x1008 +#define R_IMR_MAILBOX_CLR_CPU 0x00D0 +#define R_IMR_INTERRUPT_STATUS_BASE 0x0100 +#define R_IMR_INTERRUPT_STATUS_COUNT 7 +#define R_IMR_INTERRUPT_MAP_BASE 0x0200 +#define R_IMR_INTERRUPT_MAP_COUNT 64 + +/* ********************************************************************* + * System Performance Counter Registers + ********************************************************************* */ + +#define A_SCD_PERF_CNT_CFG 0x00100204C0 +#define A_SCD_PERF_CNT_0 0x00100204D0 +#define A_SCD_PERF_CNT_1 0x00100204D8 +#define A_SCD_PERF_CNT_2 0x00100204E0 +#define A_SCD_PERF_CNT_3 0x00100204E8 + +/* ********************************************************************* + * System Bus Watcher Registers + ********************************************************************* */ + +#define A_SCD_BUS_ERR_STATUS 0x0010020880 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_SCD_BUS_ERR_STATUS_DEBUG 0x00100208D0 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define A_BUS_ERR_DATA_0 0x00100208A0 +#define A_BUS_ERR_DATA_1 0x00100208A8 +#define A_BUS_ERR_DATA_2 0x00100208B0 +#define A_BUS_ERR_DATA_3 0x00100208B8 +#define A_BUS_L2_ERRORS 0x00100208C0 +#define A_BUS_MEM_IO_ERRORS 0x00100208C8 + +/* ********************************************************************* + * System Debug Controller Registers + ********************************************************************* */ + +#define A_SCD_JTAG_BASE 0x0010000000 + +/* ********************************************************************* + * System Trace Buffer Registers + ********************************************************************* */ + +#define A_SCD_TRACE_CFG 0x0010020A00 +#define A_SCD_TRACE_READ 0x0010020A08 +#define A_SCD_TRACE_EVENT_0 0x0010020A20 +#define A_SCD_TRACE_EVENT_1 0x0010020A28 +#define A_SCD_TRACE_EVENT_2 0x0010020A30 +#define A_SCD_TRACE_EVENT_3 0x0010020A38 +#define A_SCD_TRACE_SEQUENCE_0 0x0010020A40 +#define A_SCD_TRACE_SEQUENCE_1 0x0010020A48 +#define A_SCD_TRACE_SEQUENCE_2 0x0010020A50 +#define A_SCD_TRACE_SEQUENCE_3 0x0010020A58 +#define A_SCD_TRACE_EVENT_4 0x0010020A60 +#define A_SCD_TRACE_EVENT_5 0x0010020A68 +#define A_SCD_TRACE_EVENT_6 0x0010020A70 +#define A_SCD_TRACE_EVENT_7 0x0010020A78 +#define A_SCD_TRACE_SEQUENCE_4 0x0010020A80 +#define A_SCD_TRACE_SEQUENCE_5 0x0010020A88 +#define A_SCD_TRACE_SEQUENCE_6 0x0010020A90 +#define A_SCD_TRACE_SEQUENCE_7 0x0010020A98 + +/* ********************************************************************* + * System Generic DMA Registers + ********************************************************************* */ + +#define A_DM_0 0x0010020B00 +#define A_DM_1 0x0010020B20 +#define A_DM_2 0x0010020B40 +#define A_DM_3 0x0010020B60 +#define DM_REGISTER_SPACING 0x20 +#define DM_NUM_CHANNELS 4 +#define A_DM_BASE(idx) (A_DM_0 + ((idx) * DM_REGISTER_SPACING)) +#define A_DM_REGISTER(idx,reg) (A_DM_BASE(idx) + (reg)) + +#define R_DM_DSCR_BASE 0x0000000000 +#define R_DM_DSCR_COUNT 0x0000000008 +#define R_DM_CUR_DSCR_ADDR 0x0000000010 +#define R_DM_DSCR_BASE_DEBUG 0x0000000018 + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_DM_PARTIAL_0 0x0010020ba0 +#define A_DM_PARTIAL_1 0x0010020ba8 +#define A_DM_PARTIAL_2 0x0010020bb0 +#define A_DM_PARTIAL_3 0x0010020bb8 +#define DM_PARTIAL_REGISTER_SPACING 0x8 +#define A_DM_PARTIAL(idx) (A_DM_PARTIAL_0 + ((idx) * DM_PARTIAL_REGISTER_SPACING)) +#endif /* 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_DM_CRC_0 0x0010020b80 +#define A_DM_CRC_1 0x0010020b90 +#define DM_CRC_REGISTER_SPACING 0x10 +#define DM_CRC_NUM_CHANNELS 2 +#define A_DM_CRC_BASE(idx) (A_DM_CRC_0 + ((idx) * DM_CRC_REGISTER_SPACING)) +#define A_DM_CRC_REGISTER(idx,reg) (A_DM_CRC_BASE(idx) + (reg)) + +#define R_CRC_DEF_0 0x00 +#define R_CTCP_DEF_0 0x08 +#endif /* 112x PASS1 */ + +/* ********************************************************************* + * Physical Address Map + ********************************************************************* */ + +#define A_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000) +#define A_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024)) +#define A_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000) +#define A_PHYS_IO_SYSTEM _SB_MAKE64(0x0010060000) +#define A_PHYS_GENBUS _SB_MAKE64(0x0010090000) +#define A_PHYS_GENBUS_END _SB_MAKE64(0x0040000000) +#define A_PHYS_LDTPCI_IO_MATCH_BYTES_32 _SB_MAKE64(0x0040000000) +#define A_PHYS_LDTPCI_IO_MATCH_BITS_32 _SB_MAKE64(0x0060000000) +#define A_PHYS_MEMORY_1 _SB_MAKE64(0x0080000000) +#define A_PHYS_MEMORY_2 _SB_MAKE64(0x0090000000) +#define A_PHYS_MEMORY_3 _SB_MAKE64(0x00C0000000) +#define A_PHYS_L2_CACHE_TEST _SB_MAKE64(0x00D0000000) +#define A_PHYS_LDT_SPECIAL_MATCH_BYTES _SB_MAKE64(0x00D8000000) +#define A_PHYS_LDTPCI_IO_MATCH_BYTES _SB_MAKE64(0x00DC000000) +#define A_PHYS_LDTPCI_CFG_MATCH_BYTES _SB_MAKE64(0x00DE000000) +#define A_PHYS_LDT_SPECIAL_MATCH_BITS _SB_MAKE64(0x00F8000000) +#define A_PHYS_LDTPCI_IO_MATCH_BITS _SB_MAKE64(0x00FC000000) +#define A_PHYS_LDTPCI_CFG_MATCH_BITS _SB_MAKE64(0x00FE000000) +#define A_PHYS_MEMORY_EXP _SB_MAKE64(0x0100000000) +#define A_PHYS_MEMORY_EXP_SIZE _SB_MAKE64((508*1024*1024*1024)) +#define A_PHYS_LDT_EXP _SB_MAKE64(0x8000000000) +#define A_PHYS_PCI_FULLACCESS_BYTES _SB_MAKE64(0xF000000000) +#define A_PHYS_PCI_FULLACCESS_BITS _SB_MAKE64(0xF100000000) +#define A_PHYS_RESERVED _SB_MAKE64(0xF200000000) +#define A_PHYS_RESERVED_SPECIAL_LDT _SB_MAKE64(0xFD00000000) + +#define A_PHYS_L2CACHE_WAY_SIZE _SB_MAKE64(0x0000020000) +#define PHYS_L2CACHE_NUM_WAYS 4 +#define A_PHYS_L2CACHE_TOTAL_SIZE _SB_MAKE64(0x0000080000) +#define A_PHYS_L2CACHE_WAY0 _SB_MAKE64(0x00D0180000) +#define A_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D01A0000) +#define A_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D01C0000) +#define A_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D01E0000) + + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_scd.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,525 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * SCD Constants and Macros File: sb1250_scd.h + * + * This module contains constants and macros useful for + * manipulating the System Control and Debug module on the 1250. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + +#ifndef _SB1250_SCD_H +#define _SB1250_SCD_H + +#include "sb1250_defs.h" + +/* ********************************************************************* + * System control/debug registers + ********************************************************************* */ + +/* + * System Revision Register (Table 4-1) + */ + +#define M_SYS_RESERVED _SB_MAKEMASK(8,0) + +#define S_SYS_REVISION _SB_MAKE64(8) +#define M_SYS_REVISION _SB_MAKEMASK(8,S_SYS_REVISION) +#define V_SYS_REVISION(x) _SB_MAKEVALUE(x,S_SYS_REVISION) +#define G_SYS_REVISION(x) _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION) + +#if SIBYTE_HDR_FEATURE_CHIP(1250) +#define K_SYS_REVISION_BCM1250_PASS1 1 +#define K_SYS_REVISION_BCM1250_PASS2 3 +#define K_SYS_REVISION_BCM1250_A10 11 +#define K_SYS_REVISION_BCM1250_PASS2_2 16 +#define K_SYS_REVISION_BCM1250_B2 17 +#define K_SYS_REVISION_BCM1250_PASS3 32 + +/* XXX: discourage people from using these constants. */ +#define K_SYS_REVISION_PASS1 K_SYS_REVISION_BCM1250_PASS1 +#define K_SYS_REVISION_PASS2 K_SYS_REVISION_BCM1250_PASS2 +#define K_SYS_REVISION_PASS2_2 K_SYS_REVISION_BCM1250_PASS2_2 +#define K_SYS_REVISION_PASS3 K_SYS_REVISION_BCM1250_PASS3 +#endif /* 1250 */ + +#if SIBYTE_HDR_FEATURE_CHIP(112x) +#define K_SYS_REVISION_BCM112x_A1 32 +#define K_SYS_REVISION_BCM112x_A2 33 +#endif /* 112x */ + +/* XXX: discourage people from using these constants. */ +#define S_SYS_PART _SB_MAKE64(16) +#define M_SYS_PART _SB_MAKEMASK(16,S_SYS_PART) +#define V_SYS_PART(x) _SB_MAKEVALUE(x,S_SYS_PART) +#define G_SYS_PART(x) _SB_GETVALUE(x,S_SYS_PART,M_SYS_PART) + +/* XXX: discourage people from using these constants. */ +#define K_SYS_PART_SB1250 0x1250 +#define K_SYS_PART_BCM1120 0x1121 +#define K_SYS_PART_BCM1125 0x1123 +#define K_SYS_PART_BCM1125H 0x1124 + +/* The "peripheral set" (SOC type) is the low 4 bits of the "part" field. */ +#define S_SYS_SOC_TYPE _SB_MAKE64(16) +#define M_SYS_SOC_TYPE _SB_MAKEMASK(4,S_SYS_SOC_TYPE) +#define V_SYS_SOC_TYPE(x) _SB_MAKEVALUE(x,S_SYS_SOC_TYPE) +#define G_SYS_SOC_TYPE(x) _SB_GETVALUE(x,S_SYS_SOC_TYPE,M_SYS_SOC_TYPE) + +#define K_SYS_SOC_TYPE_BCM1250 0x0 +#define K_SYS_SOC_TYPE_BCM1120 0x1 +#define K_SYS_SOC_TYPE_BCM1250_ALT 0x2 /* 1250pass2 w/ 1/4 L2. */ +#define K_SYS_SOC_TYPE_BCM1125 0x3 +#define K_SYS_SOC_TYPE_BCM1125H 0x4 +#define K_SYS_SOC_TYPE_BCM1250_ALT2 0x5 /* 1250pass2 w/ 1/2 L2. */ + +/* + * Calculate correct SOC type given a copy of system revision register. + * + * (For the assembler version, sysrev and dest may be the same register. + * Also, it clobbers AT.) + */ +#ifdef __ASSEMBLER__ +#define SYS_SOC_TYPE(dest, sysrev) \ + .set push ; \ + .set reorder ; \ + dsrl dest, sysrev, S_SYS_SOC_TYPE ; \ + andi dest, dest, (M_SYS_SOC_TYPE >> S_SYS_SOC_TYPE); \ + beq dest, K_SYS_SOC_TYPE_BCM1250_ALT, 991f ; \ + beq dest, K_SYS_SOC_TYPE_BCM1250_ALT2, 991f ; \ + b 992f ; \ +991: li dest, K_SYS_SOC_TYPE_BCM1250 ; \ +992: \ + .set pop +#else +#define SYS_SOC_TYPE(sysrev) \ + ((G_SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250_ALT \ + || G_SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250_ALT2) \ + ? K_SYS_SOC_TYPE_BCM1250 : G_SYS_SOC_TYPE(sysrev)) +#endif + +#define S_SYS_WID _SB_MAKE64(32) +#define M_SYS_WID _SB_MAKEMASK(32,S_SYS_WID) +#define V_SYS_WID(x) _SB_MAKEVALUE(x,S_SYS_WID) +#define G_SYS_WID(x) _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID) + +/* + * System Config Register (Table 4-2) + * Register: SCD_SYSTEM_CFG + */ + +#define M_SYS_LDT_PLL_BYP _SB_MAKEMASK1(3) +#define M_SYS_PCI_SYNC_TEST_MODE _SB_MAKEMASK1(4) +#define M_SYS_IOB0_DIV _SB_MAKEMASK1(5) +#define M_SYS_IOB1_DIV _SB_MAKEMASK1(6) + +#define S_SYS_PLL_DIV _SB_MAKE64(7) +#define M_SYS_PLL_DIV _SB_MAKEMASK(5,S_SYS_PLL_DIV) +#define V_SYS_PLL_DIV(x) _SB_MAKEVALUE(x,S_SYS_PLL_DIV) +#define G_SYS_PLL_DIV(x) _SB_GETVALUE(x,S_SYS_PLL_DIV,M_SYS_PLL_DIV) + +#define M_SYS_SER0_ENABLE _SB_MAKEMASK1(12) +#define M_SYS_SER0_RSTB_EN _SB_MAKEMASK1(13) +#define M_SYS_SER1_ENABLE _SB_MAKEMASK1(14) +#define M_SYS_SER1_RSTB_EN _SB_MAKEMASK1(15) +#define M_SYS_PCMCIA_ENABLE _SB_MAKEMASK1(16) + +#define S_SYS_BOOT_MODE _SB_MAKE64(17) +#define M_SYS_BOOT_MODE _SB_MAKEMASK(2,S_SYS_BOOT_MODE) +#define V_SYS_BOOT_MODE(x) _SB_MAKEVALUE(x,S_SYS_BOOT_MODE) +#define G_SYS_BOOT_MODE(x) _SB_GETVALUE(x,S_SYS_BOOT_MODE,M_SYS_BOOT_MODE) +#define K_SYS_BOOT_MODE_ROM32 0 +#define K_SYS_BOOT_MODE_ROM8 1 +#define K_SYS_BOOT_MODE_SMBUS_SMALL 2 +#define K_SYS_BOOT_MODE_SMBUS_BIG 3 + +#define M_SYS_PCI_HOST _SB_MAKEMASK1(19) +#define M_SYS_PCI_ARBITER _SB_MAKEMASK1(20) +#define M_SYS_SOUTH_ON_LDT _SB_MAKEMASK1(21) +#define M_SYS_BIG_ENDIAN _SB_MAKEMASK1(22) +#define M_SYS_GENCLK_EN _SB_MAKEMASK1(23) +#define M_SYS_LDT_TEST_EN _SB_MAKEMASK1(24) +#define M_SYS_GEN_PARITY_EN _SB_MAKEMASK1(25) + +#define S_SYS_CONFIG 26 +#define M_SYS_CONFIG _SB_MAKEMASK(6,S_SYS_CONFIG) +#define V_SYS_CONFIG(x) _SB_MAKEVALUE(x,S_SYS_CONFIG) +#define G_SYS_CONFIG(x) _SB_GETVALUE(x,S_SYS_CONFIG,M_SYS_CONFIG) + +/* The following bits are writeable by JTAG only. */ + +#define M_SYS_CLKSTOP _SB_MAKEMASK1(32) +#define M_SYS_CLKSTEP _SB_MAKEMASK1(33) + +#define S_SYS_CLKCOUNT 34 +#define M_SYS_CLKCOUNT _SB_MAKEMASK(8,S_SYS_CLKCOUNT) +#define V_SYS_CLKCOUNT(x) _SB_MAKEVALUE(x,S_SYS_CLKCOUNT) +#define G_SYS_CLKCOUNT(x) _SB_GETVALUE(x,S_SYS_CLKCOUNT,M_SYS_CLKCOUNT) + +#define M_SYS_PLL_BYPASS _SB_MAKEMASK1(42) + +#define S_SYS_PLL_IREF 43 +#define M_SYS_PLL_IREF _SB_MAKEMASK(2,S_SYS_PLL_IREF) + +#define S_SYS_PLL_VCO 45 +#define M_SYS_PLL_VCO _SB_MAKEMASK(2,S_SYS_PLL_VCO) + +#define S_SYS_PLL_VREG 47 +#define M_SYS_PLL_VREG _SB_MAKEMASK(2,S_SYS_PLL_VREG) + +#define M_SYS_MEM_RESET _SB_MAKEMASK1(49) +#define M_SYS_L2C_RESET _SB_MAKEMASK1(50) +#define M_SYS_IO_RESET_0 _SB_MAKEMASK1(51) +#define M_SYS_IO_RESET_1 _SB_MAKEMASK1(52) +#define M_SYS_SCD_RESET _SB_MAKEMASK1(53) + +/* End of bits writable by JTAG only. */ + +#define M_SYS_CPU_RESET_0 _SB_MAKEMASK1(54) +#define M_SYS_CPU_RESET_1 _SB_MAKEMASK1(55) + +#define M_SYS_UNICPU0 _SB_MAKEMASK1(56) +#define M_SYS_UNICPU1 _SB_MAKEMASK1(57) + +#define M_SYS_SB_SOFTRES _SB_MAKEMASK1(58) +#define M_SYS_EXT_RESET _SB_MAKEMASK1(59) +#define M_SYS_SYSTEM_RESET _SB_MAKEMASK1(60) + +#define M_SYS_MISR_MODE _SB_MAKEMASK1(61) +#define M_SYS_MISR_RESET _SB_MAKEMASK1(62) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_SYS_SW_FLAG _SB_MAKEMASK1(63) +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* + * Mailbox Registers (Table 4-3) + * Registers: SCD_MBOX_CPU_x + */ + +#define S_MBOX_INT_3 0 +#define M_MBOX_INT_3 _SB_MAKEMASK(16,S_MBOX_INT_3) +#define S_MBOX_INT_2 16 +#define M_MBOX_INT_2 _SB_MAKEMASK(16,S_MBOX_INT_2) +#define S_MBOX_INT_1 32 +#define M_MBOX_INT_1 _SB_MAKEMASK(16,S_MBOX_INT_1) +#define S_MBOX_INT_0 48 +#define M_MBOX_INT_0 _SB_MAKEMASK(16,S_MBOX_INT_0) + +/* + * Watchdog Registers (Table 4-8) (Table 4-9) (Table 4-10) + * Registers: SCD_WDOG_INIT_CNT_x + */ + +#define V_SCD_WDOG_FREQ 1000000 + +#define S_SCD_WDOG_INIT 0 +#define M_SCD_WDOG_INIT _SB_MAKEMASK(23,S_SCD_WDOG_INIT) + +#define S_SCD_WDOG_CNT 0 +#define M_SCD_WDOG_CNT _SB_MAKEMASK(23,S_SCD_WDOG_CNT) + +#define M_SCD_WDOG_ENABLE _SB_MAKEMASK1(0) + +/* + * Timer Registers (Table 4-11) (Table 4-12) (Table 4-13) + */ + +#define V_SCD_TIMER_FREQ 1000000 + +#define S_SCD_TIMER_INIT 0 +#define M_SCD_TIMER_INIT _SB_MAKEMASK(20,S_SCD_TIMER_INIT) +#define V_SCD_TIMER_INIT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_INIT) +#define G_SCD_TIMER_INIT(x) _SB_GETVALUE(x,S_SCD_TIMER_INIT,M_SCD_TIMER_INIT) + +#define S_SCD_TIMER_CNT 0 +#define M_SCD_TIMER_CNT _SB_MAKEMASK(20,S_SCD_TIMER_CNT) +#define V_SCD_TIMER_CNT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_CNT) +#define G_SCD_TIMER_CNT(x) _SB_GETVALUE(x,S_SCD_TIMER_CNT,M_SCD_TIMER_CNT) + +#define M_SCD_TIMER_ENABLE _SB_MAKEMASK1(0) +#define M_SCD_TIMER_MODE _SB_MAKEMASK1(1) +#define M_SCD_TIMER_MODE_CONTINUOUS M_SCD_TIMER_MODE + +/* + * System Performance Counters + */ + +#define S_SPC_CFG_SRC0 0 +#define M_SPC_CFG_SRC0 _SB_MAKEMASK(8,S_SPC_CFG_SRC0) +#define V_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC0) +#define G_SPC_CFG_SRC0(x) _SB_GETVALUE(x,S_SPC_CFG_SRC0,M_SPC_CFG_SRC0) + +#define S_SPC_CFG_SRC1 8 +#define M_SPC_CFG_SRC1 _SB_MAKEMASK(8,S_SPC_CFG_SRC1) +#define V_SPC_CFG_SRC1(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC1) +#define G_SPC_CFG_SRC1(x) _SB_GETVALUE(x,S_SPC_CFG_SRC1,M_SPC_CFG_SRC1) + +#define S_SPC_CFG_SRC2 16 +#define M_SPC_CFG_SRC2 _SB_MAKEMASK(8,S_SPC_CFG_SRC2) +#define V_SPC_CFG_SRC2(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC2) +#define G_SPC_CFG_SRC2(x) _SB_GETVALUE(x,S_SPC_CFG_SRC2,M_SPC_CFG_SRC2) + +#define S_SPC_CFG_SRC3 24 +#define M_SPC_CFG_SRC3 _SB_MAKEMASK(8,S_SPC_CFG_SRC3) +#define V_SPC_CFG_SRC3(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC3) +#define G_SPC_CFG_SRC3(x) _SB_GETVALUE(x,S_SPC_CFG_SRC3,M_SPC_CFG_SRC3) + +#define M_SPC_CFG_CLEAR _SB_MAKEMASK1(32) +#define M_SPC_CFG_ENABLE _SB_MAKEMASK1(33) + + +/* + * Bus Watcher + */ + +#define S_SCD_BERR_TID 8 +#define M_SCD_BERR_TID _SB_MAKEMASK(10,S_SCD_BERR_TID) +#define V_SCD_BERR_TID(x) _SB_MAKEVALUE(x,S_SCD_BERR_TID) +#define G_SCD_BERR_TID(x) _SB_GETVALUE(x,S_SCD_BERR_TID,M_SCD_BERR_TID) + +#define S_SCD_BERR_RID 18 +#define M_SCD_BERR_RID _SB_MAKEMASK(4,S_SCD_BERR_RID) +#define V_SCD_BERR_RID(x) _SB_MAKEVALUE(x,S_SCD_BERR_RID) +#define G_SCD_BERR_RID(x) _SB_GETVALUE(x,S_SCD_BERR_RID,M_SCD_BERR_RID) + +#define S_SCD_BERR_DCODE 22 +#define M_SCD_BERR_DCODE _SB_MAKEMASK(3,S_SCD_BERR_DCODE) +#define V_SCD_BERR_DCODE(x) _SB_MAKEVALUE(x,S_SCD_BERR_DCODE) +#define G_SCD_BERR_DCODE(x) _SB_GETVALUE(x,S_SCD_BERR_DCODE,M_SCD_BERR_DCODE) + +#define M_SCD_BERR_MULTERRS _SB_MAKEMASK1(30) + + +#define S_SCD_L2ECC_CORR_D 0 +#define M_SCD_L2ECC_CORR_D _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_D) +#define V_SCD_L2ECC_CORR_D(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_D) +#define G_SCD_L2ECC_CORR_D(x) _SB_GETVALUE(x,S_SCD_L2ECC_CORR_D,M_SCD_L2ECC_CORR_D) + +#define S_SCD_L2ECC_BAD_D 8 +#define M_SCD_L2ECC_BAD_D _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_D) +#define V_SCD_L2ECC_BAD_D(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_D) +#define G_SCD_L2ECC_BAD_D(x) _SB_GETVALUE(x,S_SCD_L2ECC_BAD_D,M_SCD_L2ECC_BAD_D) + +#define S_SCD_L2ECC_CORR_T 16 +#define M_SCD_L2ECC_CORR_T _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_T) +#define V_SCD_L2ECC_CORR_T(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_T) +#define G_SCD_L2ECC_CORR_T(x) _SB_GETVALUE(x,S_SCD_L2ECC_CORR_T,M_SCD_L2ECC_CORR_T) + +#define S_SCD_L2ECC_BAD_T 24 +#define M_SCD_L2ECC_BAD_T _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_T) +#define V_SCD_L2ECC_BAD_T(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_T) +#define G_SCD_L2ECC_BAD_T(x) _SB_GETVALUE(x,S_SCD_L2ECC_BAD_T,M_SCD_L2ECC_BAD_T) + +#define S_SCD_MEM_ECC_CORR 0 +#define M_SCD_MEM_ECC_CORR _SB_MAKEMASK(8,S_SCD_MEM_ECC_CORR) +#define V_SCD_MEM_ECC_CORR(x) _SB_MAKEVALUE(x,S_SCD_MEM_ECC_CORR) +#define G_SCD_MEM_ECC_CORR(x) _SB_GETVALUE(x,S_SCD_MEM_ECC_CORR,M_SCD_MEM_ECC_CORR) + +#define S_SCD_MEM_ECC_BAD 8 +#define M_SCD_MEM_ECC_BAD _SB_MAKEMASK(8,S_SCD_MEM_ECC_BAD) +#define V_SCD_MEM_ECC_BAD(x) _SB_MAKEVALUE(x,S_SCD_MEM_ECC_BAD) +#define G_SCD_MEM_ECC_BAD(x) _SB_GETVALUE(x,S_SCD_MEM_ECC_BAD,M_SCD_MEM_ECC_BAD) + +#define S_SCD_MEM_BUSERR 16 +#define M_SCD_MEM_BUSERR _SB_MAKEMASK(8,S_SCD_MEM_BUSERR) +#define V_SCD_MEM_BUSERR(x) _SB_MAKEVALUE(x,S_SCD_MEM_BUSERR) +#define G_SCD_MEM_BUSERR(x) _SB_GETVALUE(x,S_SCD_MEM_BUSERR,M_SCD_MEM_BUSERR) + + +/* + * Address Trap Registers + */ + +#define M_ATRAP_INDEX _SB_MAKEMASK(4,0) +#define M_ATRAP_ADDRESS _SB_MAKEMASK(40,0) + +#define S_ATRAP_CFG_CNT 0 +#define M_ATRAP_CFG_CNT _SB_MAKEMASK(3,S_ATRAP_CFG_CNT) +#define V_ATRAP_CFG_CNT(x) _SB_MAKEVALUE(x,S_ATRAP_CFG_CNT) +#define G_ATRAP_CFG_CNT(x) _SB_GETVALUE(x,S_ATRAP_CFG_CNT,M_ATRAP_CFG_CNT) + +#define M_ATRAP_CFG_WRITE _SB_MAKEMASK1(3) +#define M_ATRAP_CFG_ALL _SB_MAKEMASK1(4) +#define M_ATRAP_CFG_INV _SB_MAKEMASK1(5) +#define M_ATRAP_CFG_USESRC _SB_MAKEMASK1(6) +#define M_ATRAP_CFG_SRCINV _SB_MAKEMASK1(7) + +#define S_ATRAP_CFG_AGENTID 8 +#define M_ATRAP_CFG_AGENTID _SB_MAKEMASK(4,S_ATRAP_CFG_AGENTID) +#define V_ATRAP_CFG_AGENTID(x) _SB_MAKEVALUE(x,S_ATRAP_CFG_AGENTID) +#define G_ATRAP_CFG_AGENTID(x) _SB_GETVALUE(x,S_ATRAP_CFG_AGENTID,M_ATRAP_CFG_AGENTID) + +#define K_BUS_AGENT_CPU0 0 +#define K_BUS_AGENT_CPU1 1 +#define K_BUS_AGENT_IOB0 2 +#define K_BUS_AGENT_IOB1 3 +#define K_BUS_AGENT_SCD 4 +#define K_BUS_AGENT_RESERVED 5 +#define K_BUS_AGENT_L2C 6 +#define K_BUS_AGENT_MC 7 + +#define S_ATRAP_CFG_CATTR 12 +#define M_ATRAP_CFG_CATTR _SB_MAKEMASK(3,S_ATRAP_CFG_CATTR) +#define V_ATRAP_CFG_CATTR(x) _SB_MAKEVALUE(x,S_ATRAP_CFG_CATTR) +#define G_ATRAP_CFG_CATTR(x) _SB_GETVALUE(x,S_ATRAP_CFG_CATTR,M_ATRAP_CFG_CATTR) + +#define K_ATRAP_CFG_CATTR_IGNORE 0 +#define K_ATRAP_CFG_CATTR_UNC 1 +#define K_ATRAP_CFG_CATTR_CACHEABLE 2 +#define K_ATRAP_CFG_CATTR_NONCOH 3 +#define K_ATRAP_CFG_CATTR_COHERENT 4 +#define K_ATRAP_CFG_CATTR_NOTUNC 5 +#define K_ATRAP_CFG_CATTR_NOTNONCOH 6 +#define K_ATRAP_CFG_CATTR_NOTCOHERENT 7 + +/* + * Trace Buffer Config register + */ + +#define M_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0) +#define M_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1) +#define M_SCD_TRACE_CFG_START _SB_MAKEMASK1(2) +#define M_SCD_TRACE_CFG_STOP _SB_MAKEMASK1(3) +#define M_SCD_TRACE_CFG_FREEZE _SB_MAKEMASK1(4) +#define M_SCD_TRACE_CFG_FREEZE_FULL _SB_MAKEMASK1(5) +#define M_SCD_TRACE_CFG_DEBUG_FULL _SB_MAKEMASK1(6) +#define M_SCD_TRACE_CFG_FULL _SB_MAKEMASK1(7) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_SCD_TRACE_CFG_FORCECNT _SB_MAKEMASK1(8) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_SCD_TRACE_CFG_CUR_ADDR 10 +#define M_SCD_TRACE_CFG_CUR_ADDR _SB_MAKEMASK(8,S_SCD_TRACE_CFG_CUR_ADDR) +#define V_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR) +#define G_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR) + +/* + * Trace Event registers + */ + +#define S_SCD_TREVT_ADDR_MATCH 0 +#define M_SCD_TREVT_ADDR_MATCH _SB_MAKEMASK(4,S_SCD_TREVT_ADDR_MATCH) +#define V_SCD_TREVT_ADDR_MATCH(x) _SB_MAKEVALUE(x,S_SCD_TREVT_ADDR_MATCH) +#define G_SCD_TREVT_ADDR_MATCH(x) _SB_GETVALUE(x,S_SCD_TREVT_ADDR_MATCH,M_SCD_TREVT_ADDR_MATCH) + +#define M_SCD_TREVT_REQID_MATCH _SB_MAKEMASK1(4) +#define M_SCD_TREVT_DATAID_MATCH _SB_MAKEMASK1(5) +#define M_SCD_TREVT_RESPID_MATCH _SB_MAKEMASK1(6) +#define M_SCD_TREVT_INTERRUPT _SB_MAKEMASK1(7) +#define M_SCD_TREVT_DEBUG_PIN _SB_MAKEMASK1(9) +#define M_SCD_TREVT_WRITE _SB_MAKEMASK1(10) +#define M_SCD_TREVT_READ _SB_MAKEMASK1(11) + +#define S_SCD_TREVT_REQID 12 +#define M_SCD_TREVT_REQID _SB_MAKEMASK(4,S_SCD_TREVT_REQID) +#define V_SCD_TREVT_REQID(x) _SB_MAKEVALUE(x,S_SCD_TREVT_REQID) +#define G_SCD_TREVT_REQID(x) _SB_GETVALUE(x,S_SCD_TREVT_REQID,M_SCD_TREVT_REQID) + +#define S_SCD_TREVT_RESPID 16 +#define M_SCD_TREVT_RESPID _SB_MAKEMASK(4,S_SCD_TREVT_RESPID) +#define V_SCD_TREVT_RESPID(x) _SB_MAKEVALUE(x,S_SCD_TREVT_RESPID) +#define G_SCD_TREVT_RESPID(x) _SB_GETVALUE(x,S_SCD_TREVT_RESPID,M_SCD_TREVT_RESPID) + +#define S_SCD_TREVT_DATAID 20 +#define M_SCD_TREVT_DATAID _SB_MAKEMASK(4,S_SCD_TREVT_DATAID) +#define V_SCD_TREVT_DATAID(x) _SB_MAKEVALUE(x,S_SCD_TREVT_DATAID) +#define G_SCD_TREVT_DATAID(x) _SB_GETVALUE(x,S_SCD_TREVT_DATAID,M_SCD_TREVT_DATID) + +#define S_SCD_TREVT_COUNT 24 +#define M_SCD_TREVT_COUNT _SB_MAKEMASK(8,S_SCD_TREVT_COUNT) +#define V_SCD_TREVT_COUNT(x) _SB_MAKEVALUE(x,S_SCD_TREVT_COUNT) +#define G_SCD_TREVT_COUNT(x) _SB_GETVALUE(x,S_SCD_TREVT_COUNT,M_SCD_TREVT_COUNT) + +/* + * Trace Sequence registers + */ + +#define S_SCD_TRSEQ_EVENT4 0 +#define M_SCD_TRSEQ_EVENT4 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT4) +#define V_SCD_TRSEQ_EVENT4(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT4) +#define G_SCD_TRSEQ_EVENT4(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT4,M_SCD_TRSEQ_EVENT4) + +#define S_SCD_TRSEQ_EVENT3 4 +#define M_SCD_TRSEQ_EVENT3 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT3) +#define V_SCD_TRSEQ_EVENT3(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT3) +#define G_SCD_TRSEQ_EVENT3(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT3,M_SCD_TRSEQ_EVENT3) + +#define S_SCD_TRSEQ_EVENT2 8 +#define M_SCD_TRSEQ_EVENT2 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT2) +#define V_SCD_TRSEQ_EVENT2(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT2) +#define G_SCD_TRSEQ_EVENT2(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT2,M_SCD_TRSEQ_EVENT2) + +#define S_SCD_TRSEQ_EVENT1 12 +#define M_SCD_TRSEQ_EVENT1 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT1) +#define V_SCD_TRSEQ_EVENT1(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT1) +#define G_SCD_TRSEQ_EVENT1(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT1,M_SCD_TRSEQ_EVENT1) + +#define K_SCD_TRSEQ_E0 0 +#define K_SCD_TRSEQ_E1 1 +#define K_SCD_TRSEQ_E2 2 +#define K_SCD_TRSEQ_E3 3 +#define K_SCD_TRSEQ_E0_E1 4 +#define K_SCD_TRSEQ_E1_E2 5 +#define K_SCD_TRSEQ_E2_E3 6 +#define K_SCD_TRSEQ_E0_E1_E2 7 +#define K_SCD_TRSEQ_E0_E1_E2_E3 8 +#define K_SCD_TRSEQ_E0E1 9 +#define K_SCD_TRSEQ_E0E1E2 10 +#define K_SCD_TRSEQ_E0E1E2E3 11 +#define K_SCD_TRSEQ_E0E1_E2 12 +#define K_SCD_TRSEQ_E0E1_E2E3 13 +#define K_SCD_TRSEQ_E0E1_E2_E3 14 +#define K_SCD_TRSEQ_IGNORED 15 + +#define K_SCD_TRSEQ_TRIGGER_ALL (V_SCD_TRSEQ_EVENT1(K_SCD_TRSEQ_IGNORED) | \ + V_SCD_TRSEQ_EVENT2(K_SCD_TRSEQ_IGNORED) | \ + V_SCD_TRSEQ_EVENT3(K_SCD_TRSEQ_IGNORED) | \ + V_SCD_TRSEQ_EVENT4(K_SCD_TRSEQ_IGNORED)) + +#define S_SCD_TRSEQ_FUNCTION 16 +#define M_SCD_TRSEQ_FUNCTION _SB_MAKEMASK(4,S_SCD_TRSEQ_FUNCTION) +#define V_SCD_TRSEQ_FUNCTION(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_FUNCTION) +#define G_SCD_TRSEQ_FUNCTION(x) _SB_GETVALUE(x,S_SCD_TRSEQ_FUNCTION,M_SCD_TRSEQ_FUNCTION) + +#define K_SCD_TRSEQ_FUNC_NOP 0 +#define K_SCD_TRSEQ_FUNC_START 1 +#define K_SCD_TRSEQ_FUNC_STOP 2 +#define K_SCD_TRSEQ_FUNC_FREEZE 3 + +#define V_SCD_TRSEQ_FUNC_NOP V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_NOP) +#define V_SCD_TRSEQ_FUNC_START V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_START) +#define V_SCD_TRSEQ_FUNC_STOP V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_STOP) +#define V_SCD_TRSEQ_FUNC_FREEZE V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_FREEZE) + +#define M_SCD_TRSEQ_ASAMPLE _SB_MAKEMASK1(18) +#define M_SCD_TRSEQ_DSAMPLE _SB_MAKEMASK1(19) +#define M_SCD_TRSEQ_DEBUGPIN _SB_MAKEMASK1(20) +#define M_SCD_TRSEQ_DEBUGCPU _SB_MAKEMASK1(21) +#define M_SCD_TRSEQ_CLEARUSE _SB_MAKEMASK1(22) + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_smbus.h b/include/asm-mips/sibyte/sb1250_smbus.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_smbus.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,170 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * SMBUS Constants File: sb1250_smbus.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's SMbus devices. + * + * SB1250 specification level: 01/02/2002 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_SMBUS_H +#define _SB1250_SMBUS_H + +#include "sb1250_defs.h" + +/* + * SMBus Clock Frequency Register (Table 14-2) + */ + +#define S_SMB_FREQ_DIV 0 +#define M_SMB_FREQ_DIV _SB_MAKEMASK(13,S_SMB_FREQ_DIV) +#define V_SMB_FREQ_DIV(x) _SB_MAKEVALUE(x,S_SMB_FREQ_DIV) + +#define K_SMB_FREQ_400KHZ 0x1F +#define K_SMB_FREQ_100KHZ 0x7D + +#define S_SMB_CMD 0 +#define M_SMB_CMD _SB_MAKEMASK(8,S_SMB_CMD) +#define V_SMB_CMD(x) _SB_MAKEVALUE(x,S_SMB_CMD) + +/* + * SMBus control register (Table 14-4) + */ + +#define M_SMB_ERR_INTR _SB_MAKEMASK1(0) +#define M_SMB_FINISH_INTR _SB_MAKEMASK1(1) +#define M_SMB_DATA_OUT _SB_MAKEMASK1(4) +#define M_SMB_DATA_DIR _SB_MAKEMASK1(5) +#define M_SMB_DATA_DIR_OUTPUT M_SMB_DATA_DIR +#define M_SMB_CLK_OUT _SB_MAKEMASK1(6) +#define M_SMB_DIRECT_ENABLE _SB_MAKEMASK1(7) + +/* + * SMBus status registers (Table 14-5) + */ + +#define M_SMB_BUSY _SB_MAKEMASK1(0) +#define M_SMB_ERROR _SB_MAKEMASK1(1) +#define M_SMB_ERROR_TYPE _SB_MAKEMASK1(2) +#define M_SMB_REF _SB_MAKEMASK1(6) +#define M_SMB_DATA_IN _SB_MAKEMASK1(7) + +/* + * SMBus Start/Command registers (Table 14-9) + */ + +#define S_SMB_ADDR 0 +#define M_SMB_ADDR _SB_MAKEMASK(7,S_SMB_ADDR) +#define V_SMB_ADDR(x) _SB_MAKEVALUE(x,S_SMB_ADDR) +#define G_SMB_ADDR(x) _SB_GETVALUE(x,S_SMB_ADDR,M_SMB_ADDR) + +#define M_SMB_QDATA _SB_MAKEMASK1(7) + +#define S_SMB_TT 8 +#define M_SMB_TT _SB_MAKEMASK(3,S_SMB_TT) +#define V_SMB_TT(x) _SB_MAKEVALUE(x,S_SMB_TT) +#define G_SMB_TT(x) _SB_GETVALUE(x,S_SMB_TT,M_SMB_TT) + +#define K_SMB_TT_WR1BYTE 0 +#define K_SMB_TT_WR2BYTE 1 +#define K_SMB_TT_WR3BYTE 2 +#define K_SMB_TT_CMD_RD1BYTE 3 +#define K_SMB_TT_CMD_RD2BYTE 4 +#define K_SMB_TT_RD1BYTE 5 +#define K_SMB_TT_QUICKCMD 6 +#define K_SMB_TT_EEPROMREAD 7 + +#define V_SMB_TT_WR1BYTE V_SMB_TT(K_SMB_TT_WR1BYTE) +#define V_SMB_TT_WR2BYTE V_SMB_TT(K_SMB_TT_WR2BYTE) +#define V_SMB_TT_WR3BYTE V_SMB_TT(K_SMB_TT_WR3BYTE) +#define V_SMB_TT_CMD_RD1BYTE V_SMB_TT(K_SMB_TT_CMD_RD1BYTE) +#define V_SMB_TT_CMD_RD2BYTE V_SMB_TT(K_SMB_TT_CMD_RD2BYTE) +#define V_SMB_TT_RD1BYTE V_SMB_TT(K_SMB_TT_RD1BYTE) +#define V_SMB_TT_QUICKCMD V_SMB_TT(K_SMB_TT_QUICKCMD) +#define V_SMB_TT_EEPROMREAD V_SMB_TT(K_SMB_TT_EEPROMREAD) + +#define M_SMB_PEC _SB_MAKEMASK1(15) + +/* + * SMBus Data Register (Table 14-6) and SMBus Extra Register (Table 14-7) + */ + +#define S_SMB_LB 0 +#define M_SMB_LB _SB_MAKEMASK(8,S_SMB_LB) +#define V_SMB_LB(x) _SB_MAKEVALUE(x,S_SMB_LB) + +#define S_SMB_MB 8 +#define M_SMB_MB _SB_MAKEMASK(8,S_SMB_MB) +#define V_SMB_MB(x) _SB_MAKEVALUE(x,S_SMB_MB) + + +/* + * SMBus Packet Error Check register (Table 14-8) + */ + +#define S_SPEC_PEC 0 +#define M_SPEC_PEC _SB_MAKEMASK(8,S_SPEC_PEC) +#define V_SPEC_MB(x) _SB_MAKEVALUE(x,S_SPEC_PEC) + + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) + +#define S_SMB_CMDH 8 +#define M_SMB_CMDH _SB_MAKEMASK(8,S_SMBH_CMD) +#define V_SMB_CMDH(x) _SB_MAKEVALUE(x,S_SMBH_CMD) + +#define M_SMB_EXTEND _SB_MAKEMASK1(14) + +#define M_SMB_DIR _SB_MAKEMASK1(13) + +#define S_SMB_DFMT 8 +#define M_SMB_DFMT _SB_MAKEMASK(3,S_SMB_DFMT) +#define V_SMB_DFMT(x) _SB_MAKEVALUE(x,S_SMB_DFMT) +#define G_SMB_DFMT(x) _SB_GETVALUE(x,S_SMB_DFMT,M_SMB_DFMT) + +#define K_SMB_DFMT_1BYTE 0 +#define K_SMB_DFMT_2BYTE 1 +#define K_SMB_DFMT_3BYTE 2 +#define K_SMB_DFMT_4BYTE 3 +#define K_SMB_DFMT_NODATA 4 +#define K_SMB_DFMT_CMD4BYTE 5 +#define K_SMB_DFMT_CMD5BYTE 6 +#define K_SMB_DFMT_RESERVED 7 + +#define V_SMB_DFMT_1BYTE V_SMB_DFMT(K_SMB_DFMT_1BYTE) +#define V_SMB_DFMT_2BYTE V_SMB_DFMT(K_SMB_DFMT_2BYTE) +#define V_SMB_DFMT_3BYTE V_SMB_DFMT(K_SMB_DFMT_3BYTE) +#define V_SMB_DFMT_4BYTE V_SMB_DFMT(K_SMB_DFMT_4BYTE) +#define V_SMB_DFMT_NODATA V_SMB_DFMT(K_SMB_DFMT_NODATA) +#define V_SMB_DFMT_CMD4BYTE V_SMB_DFMT(K_SMB_DFMT_CMD4BYTE) +#define V_SMB_DFMT_CMD5BYTE V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE) +#define V_SMB_DFMT_RESERVED V_SMB_DFMT(K_SMB_DFMT_RESERVED) + +#endif /* 1250 PASS2 || 112x PASS1 */ + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_syncser.h b/include/asm-mips/sibyte/sb1250_syncser.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_syncser.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,148 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Synchronous Serial Constants File: sb1250_syncser.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's Synchronous Serial + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_SYNCSER_H +#define _SB1250_SYNCSER_H + +#include "sb1250_defs.h" + +/* + * Serial Mode Configuration Register + */ + +#define M_SYNCSER_CRC_MODE _SB_MAKEMASK1(0) +#define M_SYNCSER_MSB_FIRST _SB_MAKEMASK1(1) + +#define S_SYNCSER_FLAG_NUM 2 +#define M_SYNCSER_FLAG_NUM _SB_MAKEMASK(4,S_SYNCSER_FLAG_NUM) +#define V_SYNCSER_FLAG_NUM _SB_MAKEVALUE(x,S_SYNCSER_FLAG_NUM) + +#define M_SYNCSER_FLAG_EN _SB_MAKEMASK1(6) +#define M_SYNCSER_HDLC_EN _SB_MAKEMASK1(7) +#define M_SYNCSER_LOOP_MODE _SB_MAKEMASK1(8) +#define M_SYNCSER_LOOPBACK _SB_MAKEMASK1(9) + +/* + * Serial Clock Source and Line Interface Mode Register + */ + +#define M_SYNCSER_RXCLK_INV _SB_MAKEMASK1(0) +#define M_SYNCSER_RXCLK_EXT _SB_MAKEMASK1(1) + +#define S_SYNCSER_RXSYNC_DLY 2 +#define M_SYNCSER_RXSYNC_DLY _SB_MAKEMASK(2,S_SYNCSER_RXSYNC_DLY) +#define V_SYNCSER_RXSYNC_DLY(x) _SB_MAKEVALUE(x,S_SYNCSER_RXSYNC_DLY) + +#define M_SYNCSER_RXSYNC_LOW _SB_MAKEMASK1(4) +#define M_SYNCSER_RXSTRB_LOW _SB_MAKEMASK1(5) + +#define M_SYNCSER_RXSYNC_EDGE _SB_MAKEMASK1(6) +#define M_SYNCSER_RXSYNC_INT _SB_MAKEMASK1(7) + +#define M_SYNCSER_TXCLK_INV _SB_MAKEMASK1(8) +#define M_SYNCSER_TXCLK_EXT _SB_MAKEMASK1(9) + +#define S_SYNCSER_TXSYNC_DLY 10 +#define M_SYNCSER_TXSYNC_DLY _SB_MAKEMASK(2,S_SYNCSER_TXSYNC_DLY) +#define V_SYNCSER_TXSYNC_DLY(x) _SB_MAKEVALUE(x,S_SYNCSER_TXSYNC_DLY) + +#define M_SYNCSER_TXSYNC_LOW _SB_MAKEMASK1(12) +#define M_SYNCSER_TXSTRB_LOW _SB_MAKEMASK1(13) + +#define M_SYNCSER_TXSYNC_EDGE _SB_MAKEMASK1(14) +#define M_SYNCSER_TXSYNC_INT _SB_MAKEMASK1(15) + +/* + * Serial Command Register + */ + +#define M_SYNCSER_CMD_RX_EN _SB_MAKEMASK1(0) +#define M_SYNCSER_CMD_TX_EN _SB_MAKEMASK1(1) +#define M_SYNCSER_CMD_RX_RESET _SB_MAKEMASK1(2) +#define M_SYNCSER_CMD_TX_RESET _SB_MAKEMASK1(3) +#define M_SYNCSER_CMD_TX_PAUSE _SB_MAKEMASK1(5) + +/* + * Serial DMA Enable Register + */ + +#define M_SYNCSER_DMA_RX_EN _SB_MAKEMASK1(0) +#define M_SYNCSER_DMA_TX_EN _SB_MAKEMASK1(4) + +/* + * Serial Status Register + */ + +#define M_SYNCSER_RX_CRCERR _SB_MAKEMASK1(0) +#define M_SYNCSER_RX_ABORT _SB_MAKEMASK1(1) +#define M_SYNCSER_RX_OCTET _SB_MAKEMASK1(2) +#define M_SYNCSER_RX_LONGFRM _SB_MAKEMASK1(3) +#define M_SYNCSER_RX_SHORTFRM _SB_MAKEMASK1(4) +#define M_SYNCSER_RX_OVERRUN _SB_MAKEMASK1(5) +#define M_SYNCSER_RX_SYNC_ERR _SB_MAKEMASK1(6) +#define M_SYNCSER_TX_CRCERR _SB_MAKEMASK1(8) +#define M_SYNCSER_TX_UNDERRUN _SB_MAKEMASK1(9) +#define M_SYNCSER_TX_SYNC_ERR _SB_MAKEMASK1(10) +#define M_SYNCSER_TX_PAUSE_COMPLETE _SB_MAKEMASK1(11) +#define M_SYNCSER_RX_EOP_COUNT _SB_MAKEMASK1(16) +#define M_SYNCSER_RX_EOP_TIMER _SB_MAKEMASK1(17) +#define M_SYNCSER_RX_EOP_SEEN _SB_MAKEMASK1(18) +#define M_SYNCSER_RX_HWM _SB_MAKEMASK1(19) +#define M_SYNCSER_RX_LWM _SB_MAKEMASK1(20) +#define M_SYNCSER_RX_DSCR _SB_MAKEMASK1(21) +#define M_SYNCSER_RX_DERR _SB_MAKEMASK1(22) +#define M_SYNCSER_TX_EOP_COUNT _SB_MAKEMASK1(24) +#define M_SYNCSER_TX_EOP_TIMER _SB_MAKEMASK1(25) +#define M_SYNCSER_TX_EOP_SEEN _SB_MAKEMASK1(26) +#define M_SYNCSER_TX_HWM _SB_MAKEMASK1(27) +#define M_SYNCSER_TX_LWM _SB_MAKEMASK1(28) +#define M_SYNCSER_TX_DSCR _SB_MAKEMASK1(29) +#define M_SYNCSER_TX_DERR _SB_MAKEMASK1(30) +#define M_SYNCSER_TX_DZERO _SB_MAKEMASK1(31) + +/* + * Sequencer Table Entry format + */ + +#define M_SYNCSER_SEQ_LAST _SB_MAKEMASK1(0) +#define M_SYNCSER_SEQ_BYTE _SB_MAKEMASK1(1) + +#define S_SYNCSER_SEQ_COUNT 2 +#define M_SYNCSER_SEQ_COUNT _SB_MAKEMASK(4,S_SYNCSER_SEQ_COUNT) +#define V_SYNCSER_SEQ_COUNT(x) _SB_MAKEVALUE(x,S_SYNCSER_SEQ_COUNT) + +#define M_SYNCSER_SEQ_ENABLE _SB_MAKEMASK1(6) +#define M_SYNCSER_SEQ_STROBE _SB_MAKEMASK1(7) + +#endif diff -Nru a/include/asm-mips/sibyte/sb1250_uart.h b/include/asm-mips/sibyte/sb1250_uart.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sb1250_uart.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,354 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * UART Constants File: sb1250_uart.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's UARTs + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_UART_H +#define _SB1250_UART_H + +#include "sb1250_defs.h" + +/* ********************************************************************** + * DUART Registers + ********************************************************************** */ + +/* + * DUART Mode Register #1 (Table 10-3) + * Register: DUART_MODE_REG_1_A + * Register: DUART_MODE_REG_1_B + */ + +#define S_DUART_BITS_PER_CHAR 0 +#define M_DUART_BITS_PER_CHAR _SB_MAKEMASK(2,S_DUART_BITS_PER_CHAR) +#define V_DUART_BITS_PER_CHAR(x) _SB_MAKEVALUE(x,S_DUART_BITS_PER_CHAR) + +#define K_DUART_BITS_PER_CHAR_RSV0 0 +#define K_DUART_BITS_PER_CHAR_RSV1 1 +#define K_DUART_BITS_PER_CHAR_7 2 +#define K_DUART_BITS_PER_CHAR_8 3 + +#define V_DUART_BITS_PER_CHAR_RSV0 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV0) +#define V_DUART_BITS_PER_CHAR_RSV1 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV1) +#define V_DUART_BITS_PER_CHAR_7 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_7) +#define V_DUART_BITS_PER_CHAR_8 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_8) + + +#define M_DUART_PARITY_TYPE_EVEN 0x00 +#define M_DUART_PARITY_TYPE_ODD _SB_MAKEMASK1(2) + +#define S_DUART_PARITY_MODE 3 +#define M_DUART_PARITY_MODE _SB_MAKEMASK(2,S_DUART_PARITY_MODE) +#define V_DUART_PARITY_MODE(x) _SB_MAKEVALUE(x,S_DUART_PARITY_MODE) + +#define K_DUART_PARITY_MODE_ADD 0 +#define K_DUART_PARITY_MODE_ADD_FIXED 1 +#define K_DUART_PARITY_MODE_NONE 2 + +#define V_DUART_PARITY_MODE_ADD V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD) +#define V_DUART_PARITY_MODE_ADD_FIXED V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD_FIXED) +#define V_DUART_PARITY_MODE_NONE V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_NONE) + +#define M_DUART_ERR_MODE _SB_MAKEMASK1(5) /* must be zero */ + +#define M_DUART_RX_IRQ_SEL_RXRDY 0 +#define M_DUART_RX_IRQ_SEL_RXFULL _SB_MAKEMASK1(6) + +#define M_DUART_RX_RTS_ENA _SB_MAKEMASK1(7) + +/* + * DUART Mode Register #2 (Table 10-4) + * Register: DUART_MODE_REG_2_A + * Register: DUART_MODE_REG_2_B + */ + +#define M_DUART_MODE_RESERVED1 _SB_MAKEMASK(3,0) /* ignored */ + +#define M_DUART_STOP_BIT_LEN_2 _SB_MAKEMASK1(3) +#define M_DUART_STOP_BIT_LEN_1 0 + +#define M_DUART_TX_CTS_ENA _SB_MAKEMASK1(4) + + +#define M_DUART_MODE_RESERVED2 _SB_MAKEMASK1(5) /* must be zero */ + +#define S_DUART_CHAN_MODE 6 +#define M_DUART_CHAN_MODE _SB_MAKEMASK(2,S_DUART_CHAN_MODE) +#define V_DUART_CHAN_MODE(x) _SB_MAKEVALUE(x,S_DUART_CHAN_MODE) + +#define K_DUART_CHAN_MODE_NORMAL 0 +#define K_DUART_CHAN_MODE_LCL_LOOP 2 +#define K_DUART_CHAN_MODE_REM_LOOP 3 + +#define V_DUART_CHAN_MODE_NORMAL V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_NORMAL) +#define V_DUART_CHAN_MODE_LCL_LOOP V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_LCL_LOOP) +#define V_DUART_CHAN_MODE_REM_LOOP V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_REM_LOOP) + +/* + * DUART Command Register (Table 10-5) + * Register: DUART_CMD_A + * Register: DUART_CMD_B + */ + +#define M_DUART_RX_EN _SB_MAKEMASK1(0) +#define M_DUART_RX_DIS _SB_MAKEMASK1(1) +#define M_DUART_TX_EN _SB_MAKEMASK1(2) +#define M_DUART_TX_DIS _SB_MAKEMASK1(3) + +#define S_DUART_MISC_CMD 4 +#define M_DUART_MISC_CMD _SB_MAKEMASK(3,S_DUART_MISC_CMD) +#define V_DUART_MISC_CMD(x) _SB_MAKEVALUE(x,S_DUART_MISC_CMD) + +#define K_DUART_MISC_CMD_NOACTION0 0 +#define K_DUART_MISC_CMD_NOACTION1 1 +#define K_DUART_MISC_CMD_RESET_RX 2 +#define K_DUART_MISC_CMD_RESET_TX 3 +#define K_DUART_MISC_CMD_NOACTION4 4 +#define K_DUART_MISC_CMD_RESET_BREAK_INT 5 +#define K_DUART_MISC_CMD_START_BREAK 6 +#define K_DUART_MISC_CMD_STOP_BREAK 7 + +#define V_DUART_MISC_CMD_NOACTION0 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION0) +#define V_DUART_MISC_CMD_NOACTION1 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION1) +#define V_DUART_MISC_CMD_RESET_RX V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_RX) +#define V_DUART_MISC_CMD_RESET_TX V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_TX) +#define V_DUART_MISC_CMD_NOACTION4 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION4) +#define V_DUART_MISC_CMD_RESET_BREAK_INT V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_BREAK_INT) +#define V_DUART_MISC_CMD_START_BREAK V_DUART_MISC_CMD(K_DUART_MISC_CMD_START_BREAK) +#define V_DUART_MISC_CMD_STOP_BREAK V_DUART_MISC_CMD(K_DUART_MISC_CMD_STOP_BREAK) + +#define M_DUART_CMD_RESERVED _SB_MAKEMASK1(7) + +/* + * DUART Status Register (Table 10-6) + * Register: DUART_STATUS_A + * Register: DUART_STATUS_B + * READ-ONLY + */ + +#define M_DUART_RX_RDY _SB_MAKEMASK1(0) +#define M_DUART_RX_FFUL _SB_MAKEMASK1(1) +#define M_DUART_TX_RDY _SB_MAKEMASK1(2) +#define M_DUART_TX_EMT _SB_MAKEMASK1(3) +#define M_DUART_OVRUN_ERR _SB_MAKEMASK1(4) +#define M_DUART_PARITY_ERR _SB_MAKEMASK1(5) +#define M_DUART_FRM_ERR _SB_MAKEMASK1(6) +#define M_DUART_RCVD_BRK _SB_MAKEMASK1(7) + +/* + * DUART Baud Rate Register (Table 10-7) + * Register: DUART_CLK_SEL_A + * Register: DUART_CLK_SEL_B + */ + +#define M_DUART_CLK_COUNTER _SB_MAKEMASK(12,0) +#define V_DUART_BAUD_RATE(x) (100000000/((x)*20)-1) + +/* + * DUART Data Registers (Table 10-8 and 10-9) + * Register: DUART_RX_HOLD_A + * Register: DUART_RX_HOLD_B + * Register: DUART_TX_HOLD_A + * Register: DUART_TX_HOLD_B + */ + +#define M_DUART_RX_DATA _SB_MAKEMASK(8,0) +#define M_DUART_TX_DATA _SB_MAKEMASK(8,0) + +/* + * DUART Input Port Register (Table 10-10) + * Register: DUART_IN_PORT + */ + +#define M_DUART_IN_PIN0_VAL _SB_MAKEMASK1(0) +#define M_DUART_IN_PIN1_VAL _SB_MAKEMASK1(1) +#define M_DUART_IN_PIN2_VAL _SB_MAKEMASK1(2) +#define M_DUART_IN_PIN3_VAL _SB_MAKEMASK1(3) +#define M_DUART_IN_PIN4_VAL _SB_MAKEMASK1(4) +#define M_DUART_IN_PIN5_VAL _SB_MAKEMASK1(5) +#define M_DUART_RIN0_PIN _SB_MAKEMASK1(6) +#define M_DUART_RIN1_PIN _SB_MAKEMASK1(7) + +/* + * DUART Input Port Change Status Register (Tables 10-11, 10-12, and 10-13) + * Register: DUART_INPORT_CHNG + */ + +#define S_DUART_IN_PIN_VAL 0 +#define M_DUART_IN_PIN_VAL _SB_MAKEMASK(4,S_DUART_IN_PIN_VAL) + +#define S_DUART_IN_PIN_CHNG 4 +#define M_DUART_IN_PIN_CHNG _SB_MAKEMASK(4,S_DUART_IN_PIN_CHNG) + + +/* + * DUART Output port control register (Table 10-14) + * Register: DUART_OPCR + */ + +#define M_DUART_OPCR_RESERVED0 _SB_MAKEMASK1(0) /* must be zero */ +#define M_DUART_OPC2_SEL _SB_MAKEMASK1(1) +#define M_DUART_OPCR_RESERVED1 _SB_MAKEMASK1(2) /* must be zero */ +#define M_DUART_OPC3_SEL _SB_MAKEMASK1(3) +#define M_DUART_OPCR_RESERVED2 _SB_MAKEMASK(4,4) /* must be zero */ + +/* + * DUART Aux Control Register (Table 10-15) + * Register: DUART_AUX_CTRL + */ + +#define M_DUART_IP0_CHNG_ENA _SB_MAKEMASK1(0) +#define M_DUART_IP1_CHNG_ENA _SB_MAKEMASK1(1) +#define M_DUART_IP2_CHNG_ENA _SB_MAKEMASK1(2) +#define M_DUART_IP3_CHNG_ENA _SB_MAKEMASK1(3) +#define M_DUART_ACR_RESERVED _SB_MAKEMASK(4,4) + +#define M_DUART_CTS_CHNG_ENA _SB_MAKEMASK1(0) +#define M_DUART_CIN_CHNG_ENA _SB_MAKEMASK1(2) + +/* + * DUART Interrupt Status Register (Table 10-16) + * Register: DUART_ISR + */ + +#define M_DUART_ISR_TX_A _SB_MAKEMASK1(0) +#define M_DUART_ISR_RX_A _SB_MAKEMASK1(1) +#define M_DUART_ISR_BRK_A _SB_MAKEMASK1(2) +#define M_DUART_ISR_IN_A _SB_MAKEMASK1(3) +#define M_DUART_ISR_TX_B _SB_MAKEMASK1(4) +#define M_DUART_ISR_RX_B _SB_MAKEMASK1(5) +#define M_DUART_ISR_BRK_B _SB_MAKEMASK1(6) +#define M_DUART_ISR_IN_B _SB_MAKEMASK1(7) + +/* + * DUART Channel A Interrupt Status Register (Table 10-17) + * DUART Channel B Interrupt Status Register (Table 10-18) + * Register: DUART_ISR_A + * Register: DUART_ISR_B + */ + +#define M_DUART_ISR_TX _SB_MAKEMASK1(0) +#define M_DUART_ISR_RX _SB_MAKEMASK1(1) +#define M_DUART_ISR_BRK _SB_MAKEMASK1(2) +#define M_DUART_ISR_IN _SB_MAKEMASK1(3) +#define M_DUART_ISR_RESERVED _SB_MAKEMASK(4,4) + +/* + * DUART Interrupt Mask Register (Table 10-19) + * Register: DUART_IMR + */ + +#define M_DUART_IMR_TX_A _SB_MAKEMASK1(0) +#define M_DUART_IMR_RX_A _SB_MAKEMASK1(1) +#define M_DUART_IMR_BRK_A _SB_MAKEMASK1(2) +#define M_DUART_IMR_IN_A _SB_MAKEMASK1(3) +#define M_DUART_IMR_ALL_A _SB_MAKEMASK(4,0) + +#define M_DUART_IMR_TX_B _SB_MAKEMASK1(4) +#define M_DUART_IMR_RX_B _SB_MAKEMASK1(5) +#define M_DUART_IMR_BRK_B _SB_MAKEMASK1(6) +#define M_DUART_IMR_IN_B _SB_MAKEMASK1(7) +#define M_DUART_IMR_ALL_B _SB_MAKEMASK(4,4) + +/* + * DUART Channel A Interrupt Mask Register (Table 10-20) + * DUART Channel B Interrupt Mask Register (Table 10-21) + * Register: DUART_IMR_A + * Register: DUART_IMR_B + */ + +#define M_DUART_IMR_TX _SB_MAKEMASK1(0) +#define M_DUART_IMR_RX _SB_MAKEMASK1(1) +#define M_DUART_IMR_BRK _SB_MAKEMASK1(2) +#define M_DUART_IMR_IN _SB_MAKEMASK1(3) +#define M_DUART_IMR_ALL _SB_MAKEMASK(4,0) +#define M_DUART_IMR_RESERVED _SB_MAKEMASK(4,4) + + +/* + * DUART Output Port Set Register (Table 10-22) + * Register: DUART_SET_OPR + */ + +#define M_DUART_SET_OPR0 _SB_MAKEMASK1(0) +#define M_DUART_SET_OPR1 _SB_MAKEMASK1(1) +#define M_DUART_SET_OPR2 _SB_MAKEMASK1(2) +#define M_DUART_SET_OPR3 _SB_MAKEMASK1(3) +#define M_DUART_OPSR_RESERVED _SB_MAKEMASK(4,4) + +/* + * DUART Output Port Clear Register (Table 10-23) + * Register: DUART_CLEAR_OPR + */ + +#define M_DUART_CLR_OPR0 _SB_MAKEMASK1(0) +#define M_DUART_CLR_OPR1 _SB_MAKEMASK1(1) +#define M_DUART_CLR_OPR2 _SB_MAKEMASK1(2) +#define M_DUART_CLR_OPR3 _SB_MAKEMASK1(3) +#define M_DUART_OPCR_RESERVED _SB_MAKEMASK(4,4) + +/* + * DUART Output Port RTS Register (Table 10-24) + * Register: DUART_OUT_PORT + */ + +#define M_DUART_OUT_PIN_SET0 _SB_MAKEMASK1(0) +#define M_DUART_OUT_PIN_SET1 _SB_MAKEMASK1(1) +#define M_DUART_OUT_PIN_CLR0 _SB_MAKEMASK1(2) +#define M_DUART_OUT_PIN_CLR1 _SB_MAKEMASK1(3) +#define M_DUART_OPRR_RESERVED _SB_MAKEMASK(4,4) + +#define M_DUART_OUT_PIN_SET(chan) \ + (chan == 0 ? M_DUART_OUT_PIN_SET0 : M_DUART_OUT_PIN_SET1) +#define M_DUART_OUT_PIN_CLR(chan) \ + (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Full Interrupt Control Register + */ + +#define S_DUART_SIG_FULL _SB_MAKE64(0) +#define M_DUART_SIG_FULL _SB_MAKEMASK(4,S_DUART_SIG_FULL) +#define V_DUART_SIG_FULL(x) _SB_MAKEVALUE(x,S_DUART_SIG_FULL) +#define G_DUART_SIG_FULL(x) _SB_GETVALUE(x,S_DUART_SIG_FULL,M_DUART_SIG_FULL) + +#define S_DUART_INT_TIME _SB_MAKE64(4) +#define M_DUART_INT_TIME _SB_MAKEMASK(4,S_DUART_INT_TIME) +#define V_DUART_INT_TIME(x) _SB_MAKEVALUE(x,S_DUART_INT_TIME) +#define G_DUART_INT_TIME(x) _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME) +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************** */ + + +#endif diff -Nru a/include/asm-mips/sibyte/sentosa.h b/include/asm-mips/sibyte/sentosa.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/sentosa.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __ASM_SIBYTE_SENTOSA_H +#define __ASM_SIBYTE_SENTOSA_H + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_int.h> + +#ifdef CONFIG_SIBYTE_SENTOSA +#define SIBYTE_BOARD_NAME "BCM91250E (Sentosa)" +#endif +#ifdef CONFIG_SIBYTE_RHONE +#define SIBYTE_BOARD_NAME "BCM91125E (Rhone)" +#endif + +/* Generic bus chip selects */ +#ifdef CONFIG_SIBYTE_RHONE +#define LEDS_CS 6 +#define LEDS_PHYS 0x1d0a0000 +#endif + +/* GPIOs */ +#define K_GPIO_DBG_LED 0 + +#endif /* __ASM_SIBYTE_SENTOSA_H */ diff -Nru a/include/asm-mips/sibyte/swarm.h b/include/asm-mips/sibyte/swarm.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/swarm.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __ASM_SIBYTE_SWARM_H +#define __ASM_SIBYTE_SWARM_H + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_int.h> + +#ifdef CONFIG_SIBYTE_SWARM +#define SIBYTE_BOARD_NAME "BCM91250A (SWARM)" +#endif +#ifdef CONFIG_SIBYTE_PTSWARM +#define SIBYTE_BOARD_NAME "PTSWARM" +#endif +#ifdef CONFIG_SIBYTE_CRHONE +#define SIBYTE_BOARD_NAME "BCM91125C (CRhone)" +#endif +#ifdef CONFIG_SIBYTE_CRHINE +#define SIBYTE_BOARD_NAME "BCM91120C (CRhine)" +#endif + +/* Generic bus chip selects */ +#define LEDS_CS 3 +#define LEDS_PHYS 0x100a0000 +#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) +#define IDE_CS 4 +#define IDE_PHYS 0x100b0000 +#define PCMCIA_CS 6 +#define PCMCIA_PHYS 0x11000000 +#endif + +/* GPIOs */ +#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) +#define K_GPIO_GB_IDE 4 +#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE) +#define K_GPIO_PC_READY 9 +#define K_INT_PC_READY (K_INT_GPIO_0 + K_GPIO_PC_READY) +#endif + +#endif /* __ASM_SIBYTE_SWARM_H */ diff -Nru a/include/asm-mips/sibyte/trace_prof.h b/include/asm-mips/sibyte/trace_prof.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/sibyte/trace_prof.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ASM_SIBYTE_TRACE_PROF_H +#define __ASM_SIBYTE_TRACE_PROF_H + +#if SBPROF_TB_DEBUG +#define DBG(a) a +#else +#define DBG(a) +#endif + +#define SBPROF_TB_MAJOR 240 +#define DEVNAME "bcm1250_tbprof" + +typedef u_int64_t tb_sample_t[6*256]; + +struct sbprof_tb { + int open; + tb_sample_t *sbprof_tbbuf; + int next_tb_sample; + + volatile int tb_enable; + volatile int tb_armed; + + wait_queue_head_t tb_sync; + wait_queue_head_t tb_read; +}; + +#define MAX_SAMPLE_BYTES (24*1024*1024) +#define MAX_TBSAMPLE_BYTES (12*1024*1024) + +#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) +#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) +#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) + +/* IOCTLs */ +#define SBPROF_ZBSTART _IOW('s', 0, int) +#define SBPROF_ZBSTOP _IOW('s', 1, int) +#define SBPROF_ZBWAITFULL _IOW('s', 2, int) + +/*************************************************************************** + * Routines for gathering ZBbus profiles using trace buffer + ***************************************************************************/ + +/* Requires: Already called zclk_timer_init with a value that won't + saturate 40 bits. No subsequent use of SCD performance counters + or trace buffer. + Effect: Starts gathering random ZBbus profiles using trace buffer. */ +static int sbprof_zbprof_start(struct file *filp); + +/* Effect: Stops collection of ZBbus profiles */ +static int sbprof_zbprof_stop(void); + + +/*************************************************************************** + * Routines for using 40-bit SCD cycle counter + * + * Client responsible for either handling interrupts or making sure + * the cycles counter never saturates, e.g., by doing + * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. + ***************************************************************************/ + +/* Configures SCD counter 0 to count ZCLKs starting from val; + Configures SCD counters1,2,3 to count nothing. + Must not be called while gathering ZBbus profiles. + +unsigned long long val; */ +#define zclk_timer_init(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "sd %0, 0x10($8);" /* write val to counter0 */ \ + "sd %1, 0($8);" /* config counter0 for zclks*/ \ + ".set pop" \ + : /* no outputs */ \ + /* enable, counter0 */ \ + : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ + : /* modifies */ "$8" ) + + +/* Reads SCD counter 0 and puts result in value + unsigned long long val; */ +#define zclk_get(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "ld %0, 0x10($8);" /* write val to counter0 */ \ + ".set pop" \ + : /* outputs */ "=r"(val) \ + : /* inputs */ \ + : /* modifies */ "$8" ) + +#endif /* __ASM_SIBYTE_TRACE_PROF_H */ diff -Nru a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h --- a/include/asm-mips/sigcontext.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips/sigcontext.h Fri Jun 27 14:20:06 2003 @@ -1,5 +1,4 @@ -/* $Id: sigcontext.h,v 1.5 1997/12/16 05:36:43 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -18,10 +17,11 @@ unsigned int sc_status; unsigned long long sc_pc; unsigned long long sc_regs[32]; - unsigned long long sc_fpregs[32]; /* Unused */ - unsigned int sc_ownedfp; - unsigned int sc_fpc_csr; /* Unused */ + unsigned long long sc_fpregs[32]; + unsigned int sc_ownedfp; /* Unused */ + unsigned int sc_fpc_csr; unsigned int sc_fpc_eir; /* Unused */ + unsigned int sc_used_math; unsigned int sc_ssflags; /* Unused */ unsigned long long sc_mdhi; unsigned long long sc_mdlo; diff -Nru a/include/asm-mips/siginfo.h b/include/asm-mips/siginfo.h --- a/include/asm-mips/siginfo.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips/siginfo.h Fri Jun 27 14:19:57 2003 @@ -1,5 +1,4 @@ -/* $Id: siginfo.h,v 1.5 1999/08/18 23:37:49 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -13,7 +12,13 @@ #define HAVE_ARCH_SIGINFO_T #define HAVE_ARCH_SIGEVENT_T + +/* + * We duplicate the generic versions - <asm-generic/siginfo.h> is just borked + * by design ... + */ #define HAVE_ARCH_COPY_SIGINFO +struct siginfo; #include <asm-generic/siginfo.h> @@ -66,8 +71,11 @@ /* POSIX.1b timers */ struct { - unsigned int _timer1; - unsigned int _timer2; + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ } _timer; /* POSIX.1b signals */ @@ -93,8 +101,8 @@ /* * sigevent definitions - * - * It seems likely that SIGEV_THREAD will have to be handled from + * + * It seems likely that SIGEV_THREAD will have to be handled from * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the * thread manager then catches and does the appropriate nonsense. * However, everything is written out here so as to not get lost. @@ -109,21 +117,25 @@ /* XXX This one isn't yet IRIX / ABI compatible. */ typedef struct sigevent { - int sigev_notify; - sigval_t sigev_value; - int sigev_signo; + int sigev_notify; + sigval_t sigev_value; + int sigev_signo; union { - int _pad[SIGEV_PAD_SIZE]; + int _pad[SIGEV_PAD_SIZE]; + int _tid; struct { - void (*_function)(sigval_t); - void *_attribute; /* really pthread_attr_t */ + void (*_function)(sigval_t); + void *_attribute; /* really pthread_attr_t */ } _sigev_thread; } _sigev_un; } sigevent_t; #ifdef __KERNEL__ +/* + * Duplicated here because of <asm-generic/siginfo.h> braindamage ... + */ #include <linux/string.h> static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) diff -Nru a/include/asm-mips/signal.h b/include/asm-mips/signal.h --- a/include/asm-mips/signal.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/signal.h Fri Jun 27 14:19:55 2003 @@ -1,5 +1,4 @@ -/* $Id: signal.h,v 1.6 1999/08/18 23:37:49 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -10,6 +9,7 @@ #ifndef _ASM_SIGNAL_H #define _ASM_SIGNAL_H +#include <linux/config.h> #include <linux/types.h> #define _NSIG 128 @@ -89,7 +89,7 @@ #define SA_RESTORER 0x04000000 -/* +/* * sigaltstack controls */ #define SS_ONSTACK 1 @@ -131,12 +131,13 @@ unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; - void (*sa_restorer)(void); - int sa_resv[1]; /* reserved */ }; struct k_sigaction { struct sigaction sa; +#ifdef CONFIG_BINFMT_IRIX + void (*sa_restorer)(void); +#endif }; /* IRIX compatible stack_t */ @@ -168,9 +169,10 @@ #define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ #define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ #define BRK_MULOVF 1023 /* Multiply overflow */ +#define BRK_BUG 512 /* Used by BUG() */ #define ptrace_signal_deliver(regs, cookie) do { } while (0) -#endif /* defined (__KERNEL__) */ +#endif /* __KERNEL__ */ #endif /* _ASM_SIGNAL_H */ diff -Nru a/include/asm-mips/smp.h b/include/asm-mips/smp.h --- a/include/asm-mips/smp.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/smp.h Fri Jun 27 14:19:54 2003 @@ -1,37 +1,102 @@ -#ifndef __ASM_MIPS_SMP_H -#define __ASM_MIPS_SMP_H +/* + * 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) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com) + * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. + * Copyright (C) 2000, 2001, 2002 Ralf Baechle + * Copyright (C) 2000, 2001 Broadcom Corporation + */ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H #include <linux/config.h> #ifdef CONFIG_SMP -#include <asm/spinlock.h> +#include <linux/bitops.h> +#include <linux/threads.h> #include <asm/atomic.h> -#include <asm/current.h> +#define smp_processor_id() (current_thread_info()->cpu) -/* Mappings are straight across. If we want - to add support for disabling cpus and such, - we'll have to do what the mips64 port does here */ -#define cpu_logical_map(cpu) (cpu) -#define cpu_number_map(cpu) (cpu) +/* Map from cpu id to sequential logical cpu number. This will only + not be idempotent when cpus failed to come on-line. */ +extern int __cpu_number_map[NR_CPUS]; +#define cpu_number_map(cpu) __cpu_number_map[cpu] + +/* The reverse map from sequential logical cpu number to cpu id. */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] -#define smp_processor_id() (current->processor) +#define NO_PROC_ID (-1) +struct call_data_struct { + void (*func)(void *); + void *info; + atomic_t started; + atomic_t finished; + int wait; +}; -/* I've no idea what the real meaning of this is */ -#define PROC_CHANGE_PENALTY 20 +extern struct call_data_struct *call_data; -#define NO_PROC_ID (-1) +#define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ +#define SMP_CALL_FUNCTION 0x2 -struct smp_fn_call_struct { - spinlock_t lock; - atomic_t finished; - void (*fn)(void *); - void *data; -}; +#if (NR_CPUS <= _MIPS_SZLONG) + +typedef unsigned long cpumask_t; -extern struct smp_fn_call_struct smp_fn_call; +#define CPUMASK_CLRALL(p) (p) = 0 +#define CPUMASK_SETB(p, bit) (p) |= 1UL << (bit) +#define CPUMASK_CLRB(p, bit) (p) &= ~(1UL << (bit)) +#define CPUMASK_TSTB(p, bit) ((p) & (1UL << (bit))) + +#elif (NR_CPUS <= 128) + +/* + * The foll should work till 128 cpus. + */ +#define CPUMASK_SIZE (NR_CPUS/_MIPS_SZLONG) +#define CPUMASK_INDEX(bit) ((bit) >> 6) +#define CPUMASK_SHFT(bit) ((bit) & 0x3f) + +typedef struct { + unsigned long _bits[CPUMASK_SIZE]; +} cpumask_t; + +#define CPUMASK_CLRALL(p) (p)._bits[0] = 0, (p)._bits[1] = 0 +#define CPUMASK_SETB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] |= \ + (1UL << CPUMASK_SHFT(bit)) +#define CPUMASK_CLRB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] &= \ + ~(1UL << CPUMASK_SHFT(bit)) +#define CPUMASK_TSTB(p, bit) ((p)._bits[CPUMASK_INDEX(bit)] & \ + (1UL << CPUMASK_SHFT(bit))) + +#else +#error cpumask macros only defined for 128p kernels +#endif + +extern cpumask_t phys_cpu_present_map; +extern cpumask_t cpu_online_map; + +#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu))) +#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) + +extern inline unsigned int num_online_cpus(void) +{ + return hweight32(cpu_online_map); +} + +extern volatile unsigned long cpu_callout_map; +/* We don't mark CPUs online until __cpu_up(), so we need another measure */ +static inline int num_booting_cpus(void) +{ + return hweight32(cpu_callout_map); +} #endif /* CONFIG_SMP */ -#endif /* __ASM_MIPS_SMP_H */ + +#endif /* __ASM_SMP_H */ diff -Nru a/include/asm-mips/smplock.h b/include/asm-mips/smplock.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/smplock.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,67 @@ +/* + * 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. + * + * Default SMP lock implementation + */ +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> + +extern spinlock_t kernel_flag; + +#ifdef CONFIG_SMP +#define kernel_locked() spin_is_locked(&kernel_flag) +#else +#ifdef CONFIG_PREEMPT +#define kernel_locked() preempt_count() +#else +#define kernel_locked() 1 +#endif +#endif + +/* + * Release global kernel lock and global interrupt lock + */ +#define release_kernel_lock(task) \ +do { \ + if (unlikely(task->lock_depth >= 0)) \ + spin_unlock(&kernel_flag); \ +} while (0) + +/* + * Re-acquire the kernel lock + */ +#define reacquire_kernel_lock(task) \ +do { \ + if (unlikely(task->lock_depth >= 0)) \ + spin_lock(&kernel_flag); \ +} while (0) + + +/* + * Getting the big kernel lock. + * + * This cannot happen asynchronously, + * so we only need to worry about other + * CPU's. + */ +static __inline__ void lock_kernel(void) +{ +#ifdef CONFIG_PREEMPT + if (current->lock_depth == -1) + spin_lock(&kernel_flag); + ++current->lock_depth; +#else + + if (!++current->lock_depth) + spin_lock(&kernel_flag); +#endif +} + +static __inline__ void unlock_kernel(void) +{ + if (--current->lock_depth < 0) + spin_unlock(&kernel_flag); +} diff -Nru a/include/asm-mips/softirq.h b/include/asm-mips/softirq.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/softirq.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,20 @@ +#ifndef __ASM_SOFTIRQ_H +#define __ASM_SOFTIRQ_H + +#include <linux/preempt.h> +#include <asm/hardirq.h> + +#define local_bh_disable() \ + do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0) +#define __local_bh_enable() \ + do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0) + +#define local_bh_enable() \ +do { \ + __local_bh_enable(); \ + if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \ + do_softirq(); \ + preempt_check_resched(); \ +} while (0) + +#endif /* __ASM_SOFTIRQ_H */ diff -Nru a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h --- a/include/asm-mips/spinlock.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips/spinlock.h Fri Jun 27 14:20:05 2003 @@ -31,7 +31,7 @@ * We make no fairness assumptions. They have a cost. */ -static inline void spin_lock(spinlock_t *lock) +static inline void _raw_spin_lock(spinlock_t *lock) { unsigned int tmp; @@ -44,24 +44,41 @@ "beqz\t%1, 1b\n\t" " sync\n\t" ".set\treorder" - : "=o" (lock->lock), "=&r" (tmp) - : "o" (lock->lock) + : "=m" (lock->lock), "=&r" (tmp) + : "m" (lock->lock) : "memory"); } -static inline void spin_unlock(spinlock_t *lock) +static inline void _raw_spin_unlock(spinlock_t *lock) { __asm__ __volatile__( ".set\tnoreorder\t\t\t# spin_unlock\n\t" "sync\n\t" "sw\t$0, %0\n\t" - ".set\treorder" - : "=o" (lock->lock) - : "o" (lock->lock) + ".set\treorder" + : "=m" (lock->lock) + : "m" (lock->lock) : "memory"); } -#define spin_trylock(lock) (!test_and_set_bit(0,(lock))) +static inline unsigned int _raw_spin_trylock(spinlock_t *lock) +{ + unsigned int temp, res; + + __asm__ __volatile__( + ".set\tnoreorder\t\t\t# spin_trylock\n\t" + "1:\tll\t%0, %3\n\t" + "ori\t%2, %0, 1\n\t" + "sc\t%2, %1\n\t" + "beqz\t%2, 1b\n\t" + " andi\t%2, %0, 1\n\t" + ".set\treorder" + : "=&r" (temp), "=m" (lock->lock), "=&r" (res) + : "m" (lock->lock) + : "memory"); + + return res == 0; +} /* * Read-write spinlocks, allowing multiple readers but only one writer. @@ -78,7 +95,11 @@ #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } -static inline void read_lock(rwlock_t *rw) +#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) + +#define rwlock_is_locked(x) ((x)->lock) + +static inline void _raw_read_lock(rwlock_t *rw) { unsigned int tmp; @@ -90,16 +111,16 @@ "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" " sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } /* Note the use of sub, not subu which will make the kernel die with an overflow exception if we ever try to unlock an rwlock that is already unlocked or is being held by a writer. */ -static inline void read_unlock(rwlock_t *rw) +static inline void _raw_read_unlock(rwlock_t *rw) { unsigned int tmp; @@ -109,13 +130,14 @@ "sub\t%1, 1\n\t" "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + " sync\n\t" + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } -static inline void write_lock(rwlock_t *rw) +static inline void _raw_write_lock(rwlock_t *rw) { unsigned int tmp; @@ -127,21 +149,21 @@ "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" " sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } -static inline void write_unlock(rwlock_t *rw) +static inline void _raw_write_unlock(rwlock_t *rw) { __asm__ __volatile__( ".set\tnoreorder\t\t\t# write_unlock\n\t" "sync\n\t" "sw\t$0, %0\n\t" - ".set\treorder" - : "=o" (rw->lock) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock) + : "m" (rw->lock) : "memory"); } diff -Nru a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h --- a/include/asm-mips/stackframe.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/stackframe.h Fri Jun 27 14:19:52 2003 @@ -9,282 +9,287 @@ #ifndef __ASM_STACKFRAME_H #define __ASM_STACKFRAME_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/mipsregs.h> #include <asm/processor.h> #include <asm/asm.h> #include <asm/offset.h> -#include <linux/config.h> -#define SAVE_AT \ - .set push; \ - .set noat; \ - sw $1, PT_R1(sp); \ + .macro SAVE_AT + .set push + .set noat + sw $1, PT_R1(sp) .set pop + .endm -#define SAVE_TEMP \ - mfhi v1; \ - sw $8, PT_R8(sp); \ - sw $9, PT_R9(sp); \ - sw v1, PT_HI(sp); \ - mflo v1; \ - sw $10,PT_R10(sp); \ - sw $11, PT_R11(sp); \ - sw v1, PT_LO(sp); \ - sw $12, PT_R12(sp); \ - sw $13, PT_R13(sp); \ - sw $14, PT_R14(sp); \ - sw $15, PT_R15(sp); \ + .macro SAVE_TEMP + mfhi v1 + sw $8, PT_R8(sp) + sw $9, PT_R9(sp) + sw v1, PT_HI(sp) + mflo v1 + sw $10,PT_R10(sp) + sw $11, PT_R11(sp) + sw v1, PT_LO(sp) + sw $12, PT_R12(sp) + sw $13, PT_R13(sp) + sw $14, PT_R14(sp) + sw $15, PT_R15(sp) sw $24, PT_R24(sp) + .endm -#define SAVE_STATIC \ - sw $16, PT_R16(sp); \ - sw $17, PT_R17(sp); \ - sw $18, PT_R18(sp); \ - sw $19, PT_R19(sp); \ - sw $20, PT_R20(sp); \ - sw $21, PT_R21(sp); \ - sw $22, PT_R22(sp); \ - sw $23, PT_R23(sp); \ + .macro SAVE_STATIC + sw $16, PT_R16(sp) + sw $17, PT_R17(sp) + sw $18, PT_R18(sp) + sw $19, PT_R19(sp) + sw $20, PT_R20(sp) + sw $21, PT_R21(sp) + sw $22, PT_R22(sp) + sw $23, PT_R23(sp) sw $30, PT_R30(sp) - -#define __str2(x) #x -#define __str(x) __str2(x) - -#define save_static_function(symbol) \ -__asm__ ( \ - ".globl\t" #symbol "\n\t" \ - ".align\t2\n\t" \ - ".type\t" #symbol ", @function\n\t" \ - ".ent\t" #symbol ", 0\n" \ - #symbol":\n\t" \ - ".frame\t$29, 0, $31\n\t" \ - "sw\t$16,"__str(PT_R16)"($29)\t\t\t# save_static_function\n\t" \ - "sw\t$17,"__str(PT_R17)"($29)\n\t" \ - "sw\t$18,"__str(PT_R18)"($29)\n\t" \ - "sw\t$19,"__str(PT_R19)"($29)\n\t" \ - "sw\t$20,"__str(PT_R20)"($29)\n\t" \ - "sw\t$21,"__str(PT_R21)"($29)\n\t" \ - "sw\t$22,"__str(PT_R22)"($29)\n\t" \ - "sw\t$23,"__str(PT_R23)"($29)\n\t" \ - "sw\t$30,"__str(PT_R30)"($29)\n\t" \ - ".end\t" #symbol "\n\t" \ - ".size\t" #symbol",. - " #symbol) - -/* Used in declaration of save_static functions. */ -#define static_unused static __attribute__((unused)) - + .endm #ifdef CONFIG_SMP -# define GET_SAVED_SP \ - mfc0 k0, CP0_CONTEXT; \ - lui k1, %hi(kernelsp); \ - srl k0, k0, 23; \ - sll k0, k0, 2; \ - addu k1, k0; \ - lw k1, %lo(kernelsp)(k1); + .macro GET_SAVED_SP + mfc0 k0, CP0_CONTEXT + lui k1, %hi(kernelsp) + srl k0, k0, 23 + sll k0, k0, 2 + addu k1, k0 + lw k1, %lo(kernelsp)(k1) + .endm #else -# define GET_SAVED_SP \ - lui k1, %hi(kernelsp); \ - lw k1, %lo(kernelsp)(k1); + .macro GET_SAVED_SP + lui k1, %hi(kernelsp) + lw k1, %lo(kernelsp)(k1) + .endm #endif - -#define SAVE_SOME \ - .set push; \ - .set reorder; \ - mfc0 k0, CP0_STATUS; \ - sll k0, 3; /* extract cu0 bit */ \ - .set noreorder; \ - bltz k0, 8f; \ - move k1, sp; \ - .set reorder; \ - /* Called from user mode, new stack. */ \ - GET_SAVED_SP \ -8: \ - move k0, sp; \ - subu sp, k1, PT_SIZE; \ - sw k0, PT_R29(sp); \ - sw $3, PT_R3(sp); \ - sw $0, PT_R0(sp); \ - mfc0 v1, CP0_STATUS; \ - sw $2, PT_R2(sp); \ - sw v1, PT_STATUS(sp); \ - sw $4, PT_R4(sp); \ - mfc0 v1, CP0_CAUSE; \ - sw $5, PT_R5(sp); \ - sw v1, PT_CAUSE(sp); \ - sw $6, PT_R6(sp); \ - mfc0 v1, CP0_EPC; \ - sw $7, PT_R7(sp); \ - sw v1, PT_EPC(sp); \ - sw $25, PT_R25(sp); \ - sw $28, PT_R28(sp); \ - sw $31, PT_R31(sp); \ - ori $28, sp, 0x1fff; \ - xori $28, 0x1fff; \ + +#ifdef CONFIG_PREEMPT + .macro BUMP_LOCK_COUNT + lw t0, TI_PRE_COUNT($28) + addiu t0, t0, 1 + sw t0, TI_PRE_COUNT($28) + .endm +#else + .macro BUMP_LOCK_COUNT + .endm +#endif + + .macro SAVE_SOME + .set push + .set reorder + mfc0 k0, CP0_STATUS + sll k0, 3 /* extract cu0 bit */ + .set noreorder + bltz k0, 8f + move k1, sp + .set reorder + /* Called from user mode, new stack. */ + GET_SAVED_SP +8: + move k0, sp + subu sp, k1, PT_SIZE + sw k0, PT_R29(sp) + sw $3, PT_R3(sp) + sw $0, PT_R0(sp) + mfc0 v1, CP0_STATUS + sw $2, PT_R2(sp) + sw v1, PT_STATUS(sp) + sw $4, PT_R4(sp) + mfc0 v1, CP0_CAUSE + sw $5, PT_R5(sp) + sw v1, PT_CAUSE(sp) + sw $6, PT_R6(sp) + mfc0 v1, CP0_EPC + sw $7, PT_R7(sp) + sw v1, PT_EPC(sp) + sw $25, PT_R25(sp) + sw $28, PT_R28(sp) + sw $31, PT_R31(sp) + ori $28, sp, 0x1fff + xori $28, 0x1fff + BUMP_LOCK_COUNT .set pop + .endm -#define SAVE_ALL \ - SAVE_SOME; \ - SAVE_AT; \ - SAVE_TEMP; \ + .macro SAVE_ALL + SAVE_SOME + SAVE_AT + SAVE_TEMP SAVE_STATIC + .endm + + .macro RESTORE_AT + .set push + .set noat + lw $1, PT_R1(sp) + .set pop + .endm -#define RESTORE_AT \ - .set push; \ - .set noat; \ - lw $1, PT_R1(sp); \ - .set pop; - -#define RESTORE_TEMP \ - lw $24, PT_LO(sp); \ - lw $8, PT_R8(sp); \ - lw $9, PT_R9(sp); \ - mtlo $24; \ - lw $24, PT_HI(sp); \ - lw $10,PT_R10(sp); \ - lw $11, PT_R11(sp); \ - mthi $24; \ - lw $12, PT_R12(sp); \ - lw $13, PT_R13(sp); \ - lw $14, PT_R14(sp); \ - lw $15, PT_R15(sp); \ + .macro RESTORE_TEMP + lw $24, PT_LO(sp) + lw $8, PT_R8(sp) + lw $9, PT_R9(sp) + mtlo $24 + lw $24, PT_HI(sp) + lw $10,PT_R10(sp) + lw $11, PT_R11(sp) + mthi $24 + lw $12, PT_R12(sp) + lw $13, PT_R13(sp) + lw $14, PT_R14(sp) + lw $15, PT_R15(sp) lw $24, PT_R24(sp) + .endm -#define RESTORE_STATIC \ - lw $16, PT_R16(sp); \ - lw $17, PT_R17(sp); \ - lw $18, PT_R18(sp); \ - lw $19, PT_R19(sp); \ - lw $20, PT_R20(sp); \ - lw $21, PT_R21(sp); \ - lw $22, PT_R22(sp); \ - lw $23, PT_R23(sp); \ + .macro RESTORE_STATIC + lw $16, PT_R16(sp) + lw $17, PT_R17(sp) + lw $18, PT_R18(sp) + lw $19, PT_R19(sp) + lw $20, PT_R20(sp) + lw $21, PT_R21(sp) + lw $22, PT_R22(sp) + lw $23, PT_R23(sp) lw $30, PT_R30(sp) + .endm -#if defined(CONFIG_CPU_R3000) +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define RESTORE_SOME \ - .set push; \ - .set reorder; \ - mfc0 t0, CP0_STATUS; \ - .set pop; \ - ori t0, 0x1f; \ - xori t0, 0x1f; \ - mtc0 t0, CP0_STATUS; \ - li v1, 0xff00; \ - and t0, v1; \ - lw v0, PT_STATUS(sp); \ - nor v1, $0, v1; \ - and v0, v1; \ - or v0, t0; \ - mtc0 v0, CP0_STATUS; \ - lw $31, PT_R31(sp); \ - lw $28, PT_R28(sp); \ - lw $25, PT_R25(sp); \ - lw $7, PT_R7(sp); \ - lw $6, PT_R6(sp); \ - lw $5, PT_R5(sp); \ - lw $4, PT_R4(sp); \ - lw $3, PT_R3(sp); \ + .macro RESTORE_SOME + .set push + .set reorder + mfc0 t0, CP0_STATUS + .set pop + ori t0, 0x1f + xori t0, 0x1f + mtc0 t0, CP0_STATUS + li v1, 0xff00 + and t0, v1 + lw v0, PT_STATUS(sp) + nor v1, $0, v1 + and v0, v1 + or v0, t0 + mtc0 v0, CP0_STATUS + lw $31, PT_R31(sp) + lw $28, PT_R28(sp) + lw $25, PT_R25(sp) + lw $7, PT_R7(sp) + lw $6, PT_R6(sp) + lw $5, PT_R5(sp) + lw $4, PT_R4(sp) + lw $3, PT_R3(sp) lw $2, PT_R2(sp) + .endm -#define RESTORE_SP_AND_RET \ - .set push; \ - .set noreorder; \ - lw k0, PT_EPC(sp); \ - lw sp, PT_R29(sp); \ - jr k0; \ - rfe; \ + .macro RESTORE_SP_AND_RET + .set push + .set noreorder + lw k0, PT_EPC(sp) + lw sp, PT_R29(sp) + jr k0 + rfe .set pop + .endm #else -#define RESTORE_SOME \ - .set push; \ - .set reorder; \ - mfc0 t0, CP0_STATUS; \ - .set pop; \ - ori t0, 0x1f; \ - xori t0, 0x1f; \ - mtc0 t0, CP0_STATUS; \ - li v1, 0xff00; \ - and t0, v1; \ - lw v0, PT_STATUS(sp); \ - nor v1, $0, v1; \ - and v0, v1; \ - or v0, t0; \ - mtc0 v0, CP0_STATUS; \ - lw v1, PT_EPC(sp); \ - mtc0 v1, CP0_EPC; \ - lw $31, PT_R31(sp); \ - lw $28, PT_R28(sp); \ - lw $25, PT_R25(sp); \ - lw $7, PT_R7(sp); \ - lw $6, PT_R6(sp); \ - lw $5, PT_R5(sp); \ - lw $4, PT_R4(sp); \ - lw $3, PT_R3(sp); \ + .macro RESTORE_SOME + .set push + .set reorder + mfc0 t0, CP0_STATUS + .set pop + ori t0, 0x1f + xori t0, 0x1f + mtc0 t0, CP0_STATUS + li v1, 0xff00 + and t0, v1 + lw v0, PT_STATUS(sp) + nor v1, $0, v1 + and v0, v1 + or v0, t0 + mtc0 v0, CP0_STATUS + lw v1, PT_EPC(sp) + mtc0 v1, CP0_EPC + lw $31, PT_R31(sp) + lw $28, PT_R28(sp) + lw $25, PT_R25(sp) + lw $7, PT_R7(sp) + lw $6, PT_R6(sp) + lw $5, PT_R5(sp) + lw $4, PT_R4(sp) + lw $3, PT_R3(sp) lw $2, PT_R2(sp) + .endm -#define RESTORE_SP_AND_RET \ - lw sp, PT_R29(sp); \ - .set mips3; \ - eret; \ + .macro RESTORE_SP_AND_RET + lw sp, PT_R29(sp) + .set mips3 + eret .set mips0 + .endm #endif -#define RESTORE_SP \ - lw sp, PT_R29(sp); \ - -#define RESTORE_ALL \ - RESTORE_SOME; \ - RESTORE_AT; \ - RESTORE_TEMP; \ - RESTORE_STATIC; \ + .macro RESTORE_SP + lw sp, PT_R29(sp) + .endm + + .macro RESTORE_ALL + RESTORE_SOME + RESTORE_AT + RESTORE_TEMP + RESTORE_STATIC RESTORE_SP + .endm -#define RESTORE_ALL_AND_RET \ - RESTORE_SOME; \ - RESTORE_AT; \ - RESTORE_TEMP; \ - RESTORE_STATIC; \ + .macro RESTORE_ALL_AND_RET + RESTORE_SOME + RESTORE_AT + RESTORE_TEMP + RESTORE_STATIC RESTORE_SP_AND_RET + .endm /* * Move to kernel mode and disable interrupts. * Set cp0 enable bit as sign that we're running on the kernel stack */ -#define CLI \ - mfc0 t0,CP0_STATUS; \ - li t1,ST0_CU0|0x1f; \ - or t0,t1; \ - xori t0,0x1f; \ + .macro CLI + mfc0 t0,CP0_STATUS + li t1,ST0_CU0|0x1f + or t0,t1 + xori t0,0x1f mtc0 t0,CP0_STATUS + .endm /* * Move to kernel mode and enable interrupts. * Set cp0 enable bit as sign that we're running on the kernel stack */ -#define STI \ - mfc0 t0,CP0_STATUS; \ - li t1,ST0_CU0|0x1f; \ - or t0,t1; \ - xori t0,0x1e; \ + .macro STI + mfc0 t0,CP0_STATUS + li t1,ST0_CU0|0x1f + or t0,t1 + xori t0,0x1e mtc0 t0,CP0_STATUS + .endm /* * Just move to kernel mode and leave interrupts as they are. * Set cp0 enable bit as sign that we're running on the kernel stack */ -#define KMODE \ - mfc0 t0,CP0_STATUS; \ - li t1,ST0_CU0|0x1e; \ - or t0,t1; \ - xori t0,0x1e; \ + .macro KMODE + mfc0 t0,CP0_STATUS + li t1,ST0_CU0|0x1e + or t0,t1 + xori t0,0x1e mtc0 t0,CP0_STATUS + .endm #endif /* __ASM_STACKFRAME_H */ diff -Nru a/include/asm-mips/stat.h b/include/asm-mips/stat.h --- a/include/asm-mips/stat.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips/stat.h Fri Jun 27 14:20:05 2003 @@ -3,23 +3,6 @@ #include <linux/types.h> -struct __old_kernel_stat { - unsigned int st_dev; - unsigned int st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned int st_uid; - unsigned int st_gid; - unsigned int st_rdev; - long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; - unsigned int st_blksize; - int st_blocks; - unsigned int st_unused0[2]; -}; - struct stat { dev_t st_dev; long st_pad1[3]; /* Reserved for network id */ @@ -75,13 +58,13 @@ * but we don't have it under Linux. */ time_t st_atime; - unsigned long reserved0; /* Reserved for st_atime expansion */ + unsigned long st_atime_nsec; /* Reserved for st_atime expansion */ time_t st_mtime; - unsigned long reserved1; /* Reserved for st_mtime expansion */ + unsigned long st_mtime_nsec; /* Reserved for st_mtime expansion */ time_t st_ctime; - unsigned long reserved2; /* Reserved for st_ctime expansion */ + unsigned long st_ctime_nsec; /* Reserved for st_ctime expansion */ unsigned long st_blksize; unsigned long st_pad2; diff -Nru a/include/asm-mips/statfs.h b/include/asm-mips/statfs.h --- a/include/asm-mips/statfs.h Fri Jun 27 14:19:58 2003 +++ b/include/asm-mips/statfs.h Fri Jun 27 14:19:58 2003 @@ -1,14 +1,12 @@ /* - * Definitions for the statfs(2) call. - * * 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) 1995 by Ralf Baechle + * Copyright (C) 1995, 1999 by Ralf Baechle */ -#ifndef __ASM_MIPS_STATFS_H -#define __ASM_MIPS_STATFS_H +#ifndef _ASM_STATFS_H +#define _ASM_STATFS_H #include <linux/posix_types.h> @@ -37,4 +35,21 @@ long f_spare[6]; }; -#endif /* __ASM_MIPS_STATFS_H */ +/* + * Unlike the 32-bit version the 64-bit version has none of the ABI baggage. + */ +struct statfs64 { + __u32 f_type; + __u32 f_bsize; + __u64 f_blocks; + __u64 f_bfree; + __u64 f_bavail; + __u64 f_files; + __u64 f_ffree; + __kernel_fsid_t f_fsid; + __u32 f_namelen; + __u32 f_frsize; + __u32 f_spare[5]; +}; + +#endif /* _ASM_STATFS_H */ diff -Nru a/include/asm-mips/string.h b/include/asm-mips/string.h --- a/include/asm-mips/string.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips/string.h Fri Jun 27 14:19:30 2003 @@ -28,7 +28,7 @@ ".set\treorder" : "=r" (__dest), "=r" (__src) : "0" (__dest), "1" (__src) - : "$1","memory"); + : "memory"); return __xdest; } @@ -56,9 +56,9 @@ ".set\treorder" : "=r" (__dest), "=r" (__src), "=r" (__n) : "0" (__dest), "1" (__src), "2" (__n) - : "$1","memory"); + : "memory"); - return __dest; + return __xdest; } #define __HAVE_ARCH_STRCMP @@ -84,8 +84,7 @@ "3:\t.set\tat\n\t" ".set\treorder" : "=r" (__cs), "=r" (__ct), "=r" (__res) - : "0" (__cs), "1" (__ct) - : "$1"); + : "0" (__cs), "1" (__ct)); return __res; } @@ -110,14 +109,13 @@ "2:\n\t" #if defined(CONFIG_CPU_R3000) "nop\n\t" -#endif +#endif "move\t%3,$1\n" "3:\tsubu\t%3,$1\n\t" ".set\tat\n\t" ".set\treorder" : "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res) - : "0" (__cs), "1" (__ct), "2" (__count) - : "$1"); + : "0" (__cs), "1" (__ct), "2" (__count)); return __res; } @@ -138,18 +136,18 @@ extern __inline__ void *memscan(void *__addr, int __c, size_t __size) { char *__end = (char *)__addr + __size; + unsigned char __uc = (unsigned char) __c; __asm__(".set\tpush\n\t" ".set\tnoat\n\t" ".set\treorder\n\t" "1:\tbeq\t%0,%1,2f\n\t" "addiu\t%0,1\n\t" - "lb\t$1,-1(%0)\n\t" + "lbu\t$1,-1(%0)\n\t" "bne\t$1,%z4,1b\n" "2:\t.set\tpop" : "=r" (__addr), "=r" (__end) - : "0" (__addr), "1" (__end), "Jr" (__c) - : "$1"); + : "0" (__addr), "1" (__end), "Jr" (__uc)); return __addr; } diff -Nru a/include/asm-mips/suspend.h b/include/asm-mips/suspend.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/suspend.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +#ifndef __ASM_SUSPEND_H +#define __ASM_SUSPEND_H + +/* Somewhen... Maybe :-) */ + +#endif /* __ASM_SUSPEND_H */ diff -Nru a/include/asm-mips/system.h b/include/asm-mips/system.h --- a/include/asm-mips/system.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips/system.h Fri Jun 27 14:19:56 2003 @@ -8,7 +8,7 @@ * Copyright (C) 1994 - 1999 by Ralf Baechle * * Changed set_except_vector declaration to allow return of previous - * vector address value - necessary for "borrowing" vectors. + * vector address value - necessary for "borrowing" vectors. * * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. @@ -18,153 +18,240 @@ #include <linux/config.h> #include <asm/sgidefs.h> -#include <asm/ptrace.h> + #include <linux/kernel.h> -extern __inline__ void -local_irq_enable(void) +#include <asm/addrspace.h> +#include <asm/ptrace.h> + +__asm__ ( + ".macro\tlocal_irq_enable\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,0x1f\n\t" + "xori\t$1,0x1e\n\t" + "mtc0\t$1,$12\n\t" + ".set\tpop\n\t" + ".endm"); + +extern inline void local_irq_enable(void) { __asm__ __volatile__( - ".set\tpush\n\t" - ".set\treorder\n\t" - ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" - "ori\t$1,0x1f\n\t" - "xori\t$1,0x1e\n\t" - "mtc0\t$1,$12\n\t" - ".set\tpop\n\t" + "local_irq_enable" : /* no outputs */ : /* no inputs */ - : "$1", "memory"); + : "memory"); } /* - * For cli() we have to insert nops to make shure that the new value + * For cli() we have to insert nops to make sure that the new value * has actually arrived in the status register before the end of this * macro. * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs * no nops at all. */ -extern __inline__ void -local_irq_disable(void) +__asm__ ( + ".macro\tlocal_irq_disable\n\t" + ".set\tpush\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,1\n\t" + "xori\t$1,1\n\t" + ".set\tnoreorder\n\t" + "mtc0\t$1,$12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tpop\n\t" + ".endm"); + +extern inline void local_irq_disable(void) { __asm__ __volatile__( - ".set\tpush\n\t" - ".set\treorder\n\t" - ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" - "ori\t$1,1\n\t" - "xori\t$1,1\n\t" - ".set\tnoreorder\n\t" - "mtc0\t$1,$12\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\tpop\n\t" + "local_irq_disable" : /* no outputs */ : /* no inputs */ - : "$1", "memory"); + : "memory"); } +__asm__ ( + ".macro\tlocal_save_flags flags\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + "mfc0\t\\flags, $12\n\t" + ".set\tpop\n\t" + ".endm"); + #define local_save_flags(x) \ __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - "mfc0\t%0,$12\n\t" \ - ".set\tpop\n\t" \ + "local_save_flags %0" \ : "=r" (x)) +__asm__ ( + ".macro\tlocal_irq_save result\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + ".set\tnoat\n\t" + "mfc0\t\\result, $12\n\t" + "ori\t$1, \\result, 1\n\t" + "xori\t$1, 1\n\t" + ".set\tnoreorder\n\t" + "mtc0\t$1, $12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tpop\n\t" + ".endm"); + #define local_irq_save(x) \ __asm__ __volatile__( \ - ".set\tpush\n\t" \ - ".set\treorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t%0,$12\n\t" \ - "ori\t$1,%0,1\n\t" \ - "xori\t$1,1\n\t" \ - ".set\tnoreorder\n\t" \ - "mtc0\t$1,$12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tpop\n\t" \ + "local_irq_save\t%0" \ : "=r" (x) \ : /* no inputs */ \ - : "$1", "memory") + : "memory") + +__asm__(".macro\tlocal_irq_restore flags\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1, $12\n\t" + "andi\t\\flags, 1\n\t" + "ori\t$1, 1\n\t" + "xori\t$1, 1\n\t" + "or\t\\flags, $1\n\t" + "mtc0\t\\flags, $12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tat\n\t" + ".set\treorder\n\t" + ".endm"); #define local_irq_restore(flags) \ do { \ unsigned long __tmp1; \ \ __asm__ __volatile__( \ - ".set\tnoreorder\t\t\t# local_irq_restore\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1, $12\n\t" \ - "andi\t%0, 1\n\t" \ - "ori\t$1, 1\n\t" \ - "xori\t$1, 1\n\t" \ - "or\t%0, $1\n\t" \ - "mtc0\t%0, $12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ + "local_irq_restore\t%0" \ : "=r" (__tmp1) \ : "0" (flags) \ - : "$1", "memory"); \ + : "memory"); \ } while(0) -#ifdef CONFIG_SMP - -extern void __global_sti(void); -extern void __global_cli(void); -extern unsigned long __global_save_flags(void); -extern void __global_restore_flags(unsigned long); -# define sti() __global_sti() -# define cli() __global_cli() -# define save_flags(x) do { x = __global_save_flags(); } while (0) -# define restore_flags(x) __global_restore_flags(x) -# define save_and_cli(x) do { save_flags(x); cli(); } while(0) - -#else /* Single processor */ - -# define sti() local_irq_enable() -# define cli() local_irq_disable() -# define save_flags(x) local_save_flags(x) -# define save_and_cli(x) local_irq_save(x) -# define restore_flags(x) local_irq_restore(x) - -#endif /* SMP */ +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + !(flags & 1); \ +}) /* - * These are probably defined overly paranoid ... + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * <programlisting> + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * </programlisting> + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * <programlisting> + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * </programlisting> + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like thiswhere there are no data dependencies. */ -#ifdef CONFIG_CPU_HAS_WB -#include <asm/wbflush.h> -#define rmb() do { } while(0) -#define wmb() wbflush() -#define mb() wbflush() #define read_barrier_depends() do { } while(0) -#else /* CONFIG_CPU_HAS_WB */ +#ifdef CONFIG_CPU_HAS_SYNC +#define __sync() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + ".set mips2\n\t" \ + "sync\n\t" \ + ".set pop" \ + : /* no output */ \ + : /* no input */ \ + : "memory") +#else +#define __sync() do { } while(0) +#endif -#define mb() \ -__asm__ __volatile__( \ - "# prevent instructions being moved around\n\t" \ - ".set\tnoreorder\n\t" \ - "# 8 nops to fool the R4400 pipeline\n\t" \ - "nop;nop;nop;nop;nop;nop;nop;nop\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) +#define __fast_iob() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "lw $0,%0\n\t" \ + "nop\n\t" \ + ".set pop" \ + : /* no output */ \ + : "m" (*(int *)KSEG1) \ + : "memory") + +#define fast_wmb() __sync() +#define fast_rmb() __sync() +#define fast_mb() __sync() +#define fast_iob() \ + do { \ + __sync(); \ + __fast_iob(); \ + } while (0) -#endif /* CONFIG_CPU_HAS_WB */ +#ifdef CONFIG_CPU_HAS_WB + +#include <asm/wbflush.h> + +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() wbflush(); +#define iob() wbflush(); + +#else /* !CONFIG_CPU_HAS_WB */ + +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() fast_mb() +#define iob() fast_iob() + +#endif /* !CONFIG_CPU_HAS_WB */ #ifdef CONFIG_SMP #define smp_mb() mb() @@ -184,18 +271,17 @@ #define set_wmb(var, value) \ do { var = value; wmb(); } while (0) -#if !defined (_LANGUAGE_ASSEMBLY) /* * switch_to(n) should switch tasks to task nr n, first * checking that n isn't the current task, in which case it does nothing. */ -extern asmlinkage void *resume(void *last, void *next); -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +extern asmlinkage void *resume(void *last, void *next, void *next_ti); + +struct task_struct; -#define prepare_to_switch() do { } while(0) #define switch_to(prev,next,last) \ do { \ - (last) = resume(prev, next); \ + (last) = resume(prev, next, next->thread_info); \ } while(0) /* @@ -208,28 +294,28 @@ unsigned long dummy; __asm__ __volatile__( - ".set\tnoreorder\t\t\t# xchg_u32\n\t" - ".set\tnoat\n\t" + ".set\tpush\t\t\t\t# xchg_u32\n\t" + ".set\tnoreorder\n\t" + ".set\tnomacro\n\t" "ll\t%0, %3\n" - "1:\tmove\t$1, %2\n\t" - "sc\t$1, %1\n\t" - "beqzl\t$1, 1b\n\t" + "1:\tmove\t%2, %z4\n\t" + "sc\t%2, %1\n\t" + "beqzl\t%2, 1b\n\t" " ll\t%0, %3\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (val), "=o" (*m), "=r" (dummy) - : "o" (*m), "2" (val) + "sync\n\t" + ".set\tpop" + : "=&r" (val), "=m" (*m), "=&r" (dummy) + : "R" (*m), "Jr" (val) : "memory"); return val; #else unsigned long flags, retval; - save_flags(flags); - cli(); + local_irq_save(flags); retval = *m; *m = val; - restore_flags(flags); + local_irq_restore(flags); /* implies memory barrier */ return retval; #endif /* Processor-dependent optimization */ } @@ -248,15 +334,24 @@ } extern void *set_except_vector(int n, void *addr); +extern void per_cpu_trap_init(void); -extern void __die(const char *, struct pt_regs *, const char *where, - unsigned long line) __attribute__((noreturn)); -extern void __die_if_kernel(const char *, struct pt_regs *, const char *where, - unsigned long line); +extern void __die(const char *, struct pt_regs *, const char *file, + const char *func, unsigned long line) __attribute__((noreturn)); +extern void __die_if_kernel(const char *, struct pt_regs *, const char *file, + const char *func, unsigned long line); #define die(msg, regs) \ - __die(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__) + __die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) #define die_if_kernel(msg, regs) \ - __die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__) + __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) + +extern int serial_console; +extern int stop_a_enabled; + +static __inline__ int con_is_present(void) +{ + return serial_console ? 0 : 1; +} #endif /* _ASM_SYSTEM_H */ diff -Nru a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/thread_info.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,103 @@ +/* thread_info.h: i386 low-level thread information + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +#include <asm/processor.h> + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants + * must also be changed + */ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + struct restart_block restart_block; +}; + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* How to get the thread information struct from C. */ +register struct thread_info *__current_thread_info __asm__("$28"); +#define current_thread_info() __current_thread_info + +/* thread information allocation */ +#define THREAD_SIZE_ORDER (1) +#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define alloc_thread_info(tsk) ((struct thread_info *) \ + __get_free_pages(GFP_KERNEL,THREAD_SIZE_ORDER)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_SIZE_ORDER) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#endif /* !__ASSEMBLY__ */ + +/* + * thread information flags + * - these are process state flags that various assembly files may need to + * access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ +#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_SYSCALL_TRACE 31 /* syscall trace active */ + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_USEDFPU (1<<TIF_USEDFPU) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) + +#define _TIF_WORK_MASK 0x0000fffe /* work to do on + interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x8000fffe /* work to do on any return to + u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff -Nru a/include/asm-mips/time.h b/include/asm-mips/time.h --- a/include/asm-mips/time.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/time.h Fri Jun 27 14:19:54 2003 @@ -10,20 +10,17 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * + * Please refer to Documentation/mips/time.README. */ - -/* - * Please refer to Documentation/MIPS/time.README. - */ - #ifndef _ASM_TIME_H #define _ASM_TIME_H -#include <linux/ptrace.h> /* for struct pt_regs */ -#include <linux/linkage.h> /* for asmlinkage */ -#include <linux/rtc.h> /* for struct rtc_time */ +#include <linux/interrupt.h> +#include <linux/linkage.h> +#include <linux/ptrace.h> +#include <linux/rtc.h> -/* +/* * RTC ops. By default, they point a no-RTC functions. * rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds. * rtc_set_time - reverse the above translation and set time to RTC. @@ -39,7 +36,7 @@ extern void to_tm(unsigned long tim, struct rtc_time * tm); /* - * do_gettimeoffset(). By default, this func pointer points to + * do_gettimeoffset(). By default, this func pointer points to * do_null_gettimeoffset(), which leads to the same resolution as HZ. * Higher resolution versions are vailable, which gives ~1us resolution. */ @@ -53,7 +50,7 @@ /* * high-level timer interrupt routines. */ -extern void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); +extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); /* * the corresponding low-level timer interrupt routine. diff -Nru a/include/asm-mips/timex.h b/include/asm-mips/timex.h --- a/include/asm-mips/timex.h Fri Jun 27 14:20:03 2003 +++ b/include/asm-mips/timex.h Fri Jun 27 14:20:03 2003 @@ -1,5 +1,4 @@ -/* $Id: timex.h,v 1.1 1998/08/25 09:22:03 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -8,21 +7,22 @@ * * FIXME: For some of the supported machines this is dead wrong. */ -#ifndef __ASM_MIPS_TIMEX_H -#define __ASM_MIPS_TIMEX_H +#ifndef _ASM_TIMEX_H +#define _ASM_TIMEX_H + +#include <asm/mipsregs.h> -#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ << (SHIFT_SCALE-SHIFT_HZ)) / HZ) -#ifdef __KERNEL__ /* * Standard way to access the cycle counter. * Currently only used on SMP for scheduling. * - * Only the low 32 bits are available as a continuously counting entity. + * Only the low 32 bits are available as a continuously counting entity. * But this only means we'll force a reschedule every 8 seconds or so, * which isn't an evil thing. * @@ -34,8 +34,7 @@ static inline cycles_t get_cycles (void) { - return read_32bit_cp0_register(CP0_COUNT); + return read_c0_count(); } -#endif /* __KERNEL__ */ -#endif /* __ASM_MIPS_TIMEX_H */ +#endif /* _ASM_TIMEX_H */ diff -Nru a/include/asm-mips/tlb.h b/include/asm-mips/tlb.h --- a/include/asm-mips/tlb.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips/tlb.h Fri Jun 27 14:19:54 2003 @@ -1 +1,18 @@ +#ifndef __ASM_TLB_H +#define __ASM_TLB_H + +/* + * MIPS doesn't need any special per-pte or per-vma handling.. + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it fills up. + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + #include <asm-generic/tlb.h> + +#endif /* __ASM_TLB_H */ diff -Nru a/include/asm-mips/tlbdebug.h b/include/asm-mips/tlbdebug.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/tlbdebug.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,20 @@ +/* + * 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) 2002 by Ralf Baechle + */ +#ifndef __ASM_TLBDEBUG_H +#define __ASM_TLBDEBUG_H + +/* + * TLB debugging functions: + */ +extern void dump_tlb(int first, int last); +extern void dump_tlb_all(void); +extern void dump_tlb_wired(void); +extern void dump_tlb_addr(unsigned long addr); +extern void dump_tlb_nonwired(void); + +#endif /* __ASM_TLBDEBUG_H */ diff -Nru a/include/asm-mips/tlbflush.h b/include/asm-mips/tlbflush.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/tlbflush.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,55 @@ +#ifndef __ASM_TLBFLUSH_H +#define __ASM_TLBFLUSH_H + +#include <linux/config.h> +#include <linux/mm.h> + +/* + * TLB flushing: + * + * - flush_tlb_all() flushes all processes TLBs + * - flush_tlb_mm(mm) flushes the specified mm context TLB's + * - flush_tlb_page(vma, vmaddr) flushes one page + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + */ +extern void local_flush_tlb_all(void); +extern void local_flush_tlb_mm(struct mm_struct *mm); +extern void local_flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void local_flush_tlb_kernel_range(unsigned long start, + unsigned long end); +extern void local_flush_tlb_page(struct vm_area_struct *vma, + unsigned long page); +extern void local_flush_tlb_one(unsigned long vaddr); + +#ifdef CONFIG_SMP + +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *); +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long, + unsigned long); +extern void flush_tlb_kernel_range(unsigned long, unsigned long); +extern void flush_tlb_page(struct vm_area_struct *, unsigned long); +extern void flush_tlb_one(unsigned long vaddr); + +#else /* CONFIG_SMP */ + +#define flush_tlb_all() local_flush_tlb_all() +#define flush_tlb_mm(mm) local_flush_tlb_mm(mm) +#define flush_tlb_range(vma,vmaddr,end) local_flush_tlb_range(vma, vmaddr, end) +#define flush_tlb_kernel_range(vmaddr,end) \ + local_flush_tlb_kernel_range(vmaddr, end) +#define flush_tlb_page(vma,page) local_flush_tlb_page(vma, page) +#define flush_tlb_one(vaddr) local_flush_tlb_one(vaddr) + +#endif /* CONFIG_SMP */ + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Nothing to do on MIPS. */ +} + +#endif /* __ASM_TLBFLUSH_H */ diff -Nru a/include/asm-mips/topology.h b/include/asm-mips/topology.h --- a/include/asm-mips/topology.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips/topology.h Fri Jun 27 14:20:05 2003 @@ -1,6 +1,6 @@ -#ifndef _ASM_MIPS_TOPOLOGY_H -#define _ASM_MIPS_TOPOLOGY_H +#ifndef __ASM_TOPOLOGY_H +#define __ASM_TOPOLOGY_H #include <asm-generic/topology.h> -#endif /* _ASM_MIPS_TOPOLOGY_H */ +#endif /* __ASM_TOPOLOGY_H */ diff -Nru a/include/asm-mips/traps.h b/include/asm-mips/traps.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/traps.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,26 @@ +/* + * include/asm-mips/traps.h + * + * Trap handling definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_TRAPS_H +#define __ASM_MIPS_TRAPS_H + +/* + * Possible status responses for a board_be_handler backend. + */ +#define MIPS_BE_DISCARD 0 /* return with no action */ +#define MIPS_BE_FIXUP 1 /* return to the fixup code */ +#define MIPS_BE_FATAL 2 /* treat as an unrecoverable error */ + +extern void (*board_be_init)(void); +extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup); + +#endif /* __ASM_MIPS_TRAPS_H */ diff -Nru a/include/asm-mips/tx3912.h b/include/asm-mips/tx3912.h --- a/include/asm-mips/tx3912.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips/tx3912.h Fri Jun 27 14:20:05 2003 @@ -1,5 +1,5 @@ /* - * linux/include/asm-mips/tx3912.h + * include/asm-mips/tx3912.h * * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com) * @@ -7,562 +7,355 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * Register includes for TMPR3912/05 and PR31700 processors + * Registers for TMPR3912/05 and PR31700 processors */ -#ifndef __TX3912_H__ -#define __TX3912_H__ +#ifndef _TX3912_H_ +#define _TX3912_H_ -#include <asm/addrspace.h> +/***************************************************************************** + * Clock Subsystem * + * --------------- * + * Chapter 6 in Philips PR31700 and Toshiba TMPR3905/12 User Manuals * + *****************************************************************************/ +#define TX3912_CLK_CTRL 0x01c0 -/****************************************************************************** -* -* 01 General macro definitions -* -******************************************************************************/ - -#define REGISTER_BASE 0xb0c00000 - -#ifndef _LANGUAGE_ASSEMBLY - - #define REG_AT(x) (*((volatile unsigned long *)(REGISTER_BASE + x))) - -#else - - #define REG_AT(x) (REGISTER_BASE + x) - -#endif - -#define BIT(x) (1 << x) - -/****************************************************************************** -* -* 02 Bus Interface Unit -* -******************************************************************************/ - -#define MemConfig0 REG_AT(0x000) -#define MemConfig1 REG_AT(0x004) -#define MemConfig2 REG_AT(0x008) -#define MemConfig3 REG_AT(0x00c) -#define MemConfig4 REG_AT(0x010) -#define MemConfig5 REG_AT(0x014) -#define MemConfig6 REG_AT(0x018) -#define MemConfig7 REG_AT(0x01c) -#define MemConfig8 REG_AT(0x020) - -/* Memory config register 1 */ -#define MEM1_ENCS1USER BIT(21) - -/* Memory config register 3 */ -#define MEM3_CARD1ACCVAL_MASK (BIT(24) | BIT(25) | BIT(26) | BIT(27)) -#define MEM3_CARD1IOEN BIT(4) - -/* Memory config register 4 */ -#define MEM4_ARBITRATIONEN BIT(29) -#define MEM4_MEMPOWERDOWN BIT(16) -#define MEM4_ENREFRESH1 BIT(15) -#define MEM4_ENREFRESH0 BIT(14) -#define MEM4_ENWATCH BIT(24) -#define MEM4_WATCHTIMEVAL_MASK (0xf) -#define MEM4_WATCHTIMEVAL_SHIFT (20) -#define MEM4_WATCHTIME_VALUE (0xf) - -/* - *********************************************************************** - * * - * 06 Clock Module * - * * - *********************************************************************** - */ -#define TX3912_CLK_CTRL_BASE (REGISTER_BASE + 0x1c0) - -#define TX3912_CLK_CTRL_CHICLKDIV_MASK 0xff000000 -#define TX3912_CLK_CTRL_CHICLKDIV_SHIFT 24 -#define TX3912_CLK_CTRL_ENCLKTEST 0x00800000 -#define TX3912_CLK_CTRL_CLKTESTSELSIB 0x00400000 -#define TX3912_CLK_CTRL_CHIMCLKSEL 0x00200000 -#define TX3912_CLK_CTRL_CHICLKDIR 0x00100000 -#define TX3912_CLK_CTRL_ENCHIMCLK 0x00080000 -#define TX3912_CLK_CTRL_ENVIDCLK 0x00040000 -#define TX3912_CLK_CTRL_ENMBUSCLK 0x00020000 -#define TX3912_CLK_CTRL_ENSPICLK 0x00010000 -#define TX3912_CLK_CTRL_ENTIMERCLK 0x00008000 -#define TX3912_CLK_CTRL_ENFASTTIMERCLK 0x00004000 -#define TX3912_CLK_CTRL_SIBMCLKDIR 0x00002000 -#define TX3912_CLK_CTRL_RESERVED 0x00001000 -#define TX3912_CLK_CTRL_ENSIBMCLK 0x00000800 -#define TX3912_CLK_CTRL_SIBMCLKDIV_MASK 0x00000700 -#define TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT 8 -#define TX3912_CLK_CTRL_CSERSEL 0x00000080 -#define TX3912_CLK_CTRL_CSERDIV_MASK 0x00000070 -#define TX3912_CLK_CTRL_CSERDIV_SHIFT 4 -#define TX3912_CLK_CTRL_ENCSERCLK 0x00000008 -#define TX3912_CLK_CTRL_ENIRCLK 0x00000004 -#define TX3912_CLK_CTRL_ENUARTACLK 0x00000002 -#define TX3912_CLK_CTRL_ENUARTBCLK 0x00000001 - - - - -/****************************************************************************** -* -* 07 CHI module -* -******************************************************************************/ - -#define CHIControl REG_AT(0x1D8) -#define CHIPointerEnable REG_AT(0x1DC) -#define CHIReceivePtrA REG_AT(0x1E0) -#define CHIReceivePtrB REG_AT(0x1E4) -#define CHITransmitPtrA REG_AT(0x1E8) -#define CHITransmitPtrB REG_AT(0x1EC) -#define CHISize REG_AT(0x1F0) -#define CHIReceiveStart REG_AT(0x1F4) -#define CHITransmitStart REG_AT(0x1F8) -#define CHIHoldingReg REG_AT(0x1FC) - -/* CHI Control Register */ -/* <incomplete!> */ -#define CHI_RXEN BIT(2) -#define CHI_TXEN BIT(1) -#define CHI_ENCHI BIT(0) - -/****************************************************************************** -* -* 08 Interrupt module -* -******************************************************************************/ - -/* Register locations */ - -#define IntStatus1 REG_AT(0x100) -#define IntStatus2 REG_AT(0x104) -#define IntStatus3 REG_AT(0x108) -#define IntStatus4 REG_AT(0x10c) -#define IntStatus5 REG_AT(0x110) -#define IntStatus6 REG_AT(0x114) - -#define IntClear1 REG_AT(0x100) -#define IntClear2 REG_AT(0x104) -#define IntClear3 REG_AT(0x108) -#define IntClear4 REG_AT(0x10c) -#define IntClear5 REG_AT(0x110) -#define IntClear6 REG_AT(0x114) - -#define IntEnable1 REG_AT(0x118) -#define IntEnable2 REG_AT(0x11c) -#define IntEnable3 REG_AT(0x120) -#define IntEnable4 REG_AT(0x124) -#define IntEnable5 REG_AT(0x128) -#define IntEnable6 REG_AT(0x12c) - -/* Interrupt Status Register 1 at offset 100 */ -#define INT1_LCDINT BIT(31) -#define INT1_DFINT BIT(30) -#define INT1_CHIDMAHALF BIT(29) -#define INT1_CHIDMAFULL BIT(28) -#define INT1_CHIDMACNTINT BIT(27) -#define INT1_CHIRXAINT BIT(26) -#define INT1_CHIRXBINT BIT(25) -#define INT1_CHIACTINT BIT(24) -#define INT1_CHIERRINT BIT(23) -#define INT1_SND0_5INT BIT(22) -#define INT1_SND1_0INT BIT(21) -#define INT1_TEL0_5INT BIT(20) -#define INT1_TEL1_0INT BIT(19) -#define INT1_SNDDMACNTINT BIT(18) -#define INT1_TELDMACNTINT BIT(17) -#define INT1_LSNDCLIPINT BIT(16) -#define INT1_RSNDCLIPINT BIT(15) -#define INT1_VALSNDPOSINT BIT(14) -#define INT1_VALSNDNEGINT BIT(13) -#define INT1_VALTELPOSINT BIT(12) -#define INT1_VALTELNEGINT BIT(11) -#define INT1_SNDININT BIT(10) -#define INT1_TELININT BIT(9) -#define INT1_SIBSF0INT BIT(8) -#define INT1_SIBSF1INT BIT(7) -#define INT1_SIBIRQPOSINT BIT(6) -#define INT1_SIBIRQNEGINT BIT(5) - -/* Interrupt Status Register 2 at offset 104 */ -#define INT2_UARTARXINT BIT(31) -#define INT2_UARTARXOVERRUN BIT(30) -#define INT2_UARTAFRAMEINT BIT(29) -#define INT2_UARTABREAKINT BIT(28) -#define INT2_UARTATXINT BIT(26) -#define INT2_UARTATXOVERRUN BIT(25) -#define INT2_UARTAEMPTY BIT(24) - -#define INT2_UARTBRXINT BIT(21) -#define INT2_UARTBRXOVERRUN BIT(20) -#define INT2_UARTBFRAMEINT BIT(29) -#define INT2_UARTBBREAKINT BIT(18) -#define INT2_UARTBTXINT BIT(16) -#define INT2_UARTBTXOVERRUN BIT(15) -#define INT2_UARTBEMPTY BIT(14) - -#define INT2_UARTA_RX (BIT(31) | BIT(30) | BIT(29) | BIT(28) | BIT(27)) -#define INT2_UARTA_TX (BIT(26) | BIT(25) | BIT(24)) -#define INT2_UARTA_DMA (BIT(23) | BIT(22)) - -#define INT2_UARTB_RX (BIT(21) | BIT(20) | BIT(19) | BIT(18) | BIT(17)) -#define INT2_UARTB_TX (BIT(16) | BIT(15) | BIT(14)) -#define INT2_UARTB_DMA (BIT(13) | BIT(12)) - -/* Interrupt Status Register 5 */ -#define INT5_RTCINT BIT(31) -#define INT5_ALARMINT BIT(30) -#define INT5_PERIODICINT BIT(29) -#define INT5_POSPWRINT BIT(27) -#define INT5_NEGPWRINT BIT(26) -#define INT5_POSPWROKINT BIT(25) -#define INT5_NEGPWROKINT BIT(24) -#define INT5_POSONBUTINT BIT(23) -#define INT5_NEGONBUTINT BIT(22) -#define INT5_SPIAVAILINT BIT(21) /* 0x0020 0000 */ -#define INT5_SPIERRINT BIT(20) /* 0x0010 0000 */ -#define INT5_SPIRCVINT BIT(19) /* 0x0008 0000 */ -#define INT5_SPIEMPTYINT BIT(18) /* 0x0004 0000 */ -#define INT5_IOPOSINT6 BIT(13) -#define INT5_IOPOSINT5 BIT(12) -#define INT5_IOPOSINT4 BIT(11) -#define INT5_IOPOSINT3 BIT(10) -#define INT5_IOPOSINT2 BIT(9) -#define INT5_IOPOSINT1 BIT(8) -#define INT5_IOPOSINT0 BIT(7) -#define INT5_IONEGINT6 BIT(6) -#define INT5_IONEGINT5 BIT(5) -#define INT5_IONEGINT4 BIT(4) -#define INT5_IONEGINT3 BIT(3) -#define INT5_IONEGINT2 BIT(2) -#define INT5_IONEGINT1 BIT(1) -#define INT5_IONEGINT0 BIT(0) - -#define INT5_IONEGINT_SHIFT 0 -#define INT5_IONEGINT_MASK (0x7F<<INT5_IONEGINT_SHIFT) -#define INT5_IOPOSINT_SHIFT 7 -#define INT5_IOPOSINT_MASK (0x7F<<INT5_IOPOSINT_SHIFT) - -/* Interrupt Status Register 6 */ -#define INT6_IRQHIGH BIT(31) -#define INT6_IRQLOW BIT(30) -#define INT6_INTVECT (BIT(5) | BIT(4) | BIT(3) | BIT(2)) - - -/* Interrupt Enable Register 6 */ -#define INT6_GLOBALEN BIT(18) -#define INT6_PWROKINT BIT(15) -#define INT6_ALARMINT BIT(14) -#define INT6_PERIODICINT BIT(13) -#define INT6_MBUSINT BIT(12) -#define INT6_UARTARXINT BIT(11) -#define INT6_UARTBRXINT BIT(10) -#define INT6_MFIOPOSINT1619 BIT(9) -#define INT6_IOPOSINT56 BIT(8) -#define INT6_MFIONEGINT1619 BIT(7) -#define INT6_IONEGINT56 BIT(6) -#define INT6_MBUSDMAFULLINT BIT(5) -#define INT6_SNDDMACNTINT BIT(4) -#define INT6_TELDMACNTINT BIT(3) -#define INT6_CHIDMACNTINT BIT(2) -#define INT6_IOPOSNEGINT0 BIT(1) - -/****************************************************************************** -* -* 09 GPIO and MFIO modules -* -******************************************************************************/ - -#define IOControl REG_AT(0x180) -#define MFIOOutput REG_AT(0x184) -#define MFIODirection REG_AT(0x188) -#define MFIOInput REG_AT(0x18c) -#define MFIOSelect REG_AT(0x190) -#define IOPowerDown REG_AT(0x194) -#define MFIOPowerDown REG_AT(0x198) - -#define IODIN_MASK 0x0000007f -#define IODIN_SHIFT 0 -#define IODOUT_MASK 0x00007f00 -#define IODOUT_SHIFT 8 -#define IODIREC_MASK 0x007f0000 -#define IODIREC_SHIFT 16 -#define IODEBSEL_MASK 0x7f000000 -#define IODEBSEL_SHIFT 24 - -/****************************************************************************** -* -* 10 IR module -* -******************************************************************************/ - -#define IRControl1 REG_AT(0x0a0) -#define IRControl2 REG_AT(0x0a4) - -/* IR Control 1 Register */ -#define IR_CARDRET BIT(24) -#define IR_BAUDVAL_MASK 0x00ff0000 -#define IR_BAUDVAL_SHIFT 16 -#define IR_TESTIR BIT(4) -#define IR_DTINVERT BIT(3) -#define IR_RXPWR BIT(2) -#define IR_ENSTATE BIT(1) -#define IR_ENCONSM BIT(0) - -/* IR Control 2 Register */ -#define IR_PER_MASK 0xff000000 -#define IR_PER_SHIFT 24 -#define IR_ONTIME_MASK 0x00ff0000 -#define IR_ONTIME_SHIFT 16 -#define IR_DELAYVAL_MASK 0x0000ff00 -#define IR_DELAYVAL_SHIFT 8 -#define IR_WAITVAL_MASK 0x000000ff -#define IR_WAITVAL_SHIFT 0 - -/****************************************************************************** -* -* 11 Magicbus Module -* -******************************************************************************/ - -#define MbusCntrl1 REG_AT(0x0e0) -#define MbusCntrl2 REG_AT(0x0e4) -#define MbusDMACntrl1 REG_AT(0x0e8) -#define MbusDMACntrl2 REG_AT(0x0ec) -#define MbusDMACount REG_AT(0x0f0) -#define MbusTxReg REG_AT(0x0f4) -#define MbusRxReg REG_AT(0x0f8) - -#define MBUS_CLKPOL BIT(4) -#define MBUS_SLAVE BIT(3) -#define MBUS_FSLAVE BIT(2) -#define MBUS_LONG BIT(1) -#define MBUS_ENMBUS BIT(0) - -/****************************************************************************** -* -* 12 Power module -* -******************************************************************************/ - -#define PowerControl REG_AT(0x1C4) - -#define PWR_ONBUTN BIT(31) -#define PWR_PWRINT BIT(30) -#define PWR_PWROK BIT(29) -#define PWR_VIDRF_MASK (BIT(28) | BIT(27)) -#define PWR_VIDRF_SHIFT 27 -#define PWR_SLOWBUS BIT(26) -#define PWR_DIVMOD BIT(25) -#define PWR_STPTIMERVAL_MASK (BIT(15) | BIT(14) | BIT(13) | BIT(12)) -#define PWR_STPTIMERVAL_SHIFT 12 -#define PWR_ENSTPTIMER BIT(11) -#define PWR_ENFORCESHUTDWN BIT(10) -#define PWR_FORCESHUTDWN BIT(9) -#define PWR_FORCESHUTDWNOCC BIT(8) -#define PWR_SELC2MS BIT(7) -#define PWR_BPDBVCC3 BIT(5) -#define PWR_STOPCPU BIT(4) -#define PWR_DBNCONBUTN BIT(3) -#define PWR_COLDSTART BIT(2) -#define PWR_PWRCS BIT(1) -#define PWR_VCCON BIT(0) - -/****************************************************************************** -* -* 13 SIB (Serial Interconnect Bus) Module -* -******************************************************************************/ - -/* Register locations */ -#define SIBSize REG_AT(0x060) -#define SIBSoundRXStart REG_AT(0x064) -#define SIBSoundTXStart REG_AT(0x068) -#define SIBTelecomRXStart REG_AT(0x06C) -#define SIBTelecomTXStart REG_AT(0x070) -#define SIBControl REG_AT(0x074) -#define SIBSoundTXRXHolding REG_AT(0x078) -#define SIBTelecomTXRXHolding REG_AT(0x07C) -#define SIBSubFrame0Control REG_AT(0x080) -#define SIBSubFrame1Control REG_AT(0x084) -#define SIBSubFrame0Status REG_AT(0x088) -#define SIBSubFrame1Status REG_AT(0x08C) -#define SIBDMAControl REG_AT(0x090) - -/* SIB Size Register */ -#define SIB_SNDSIZE_MASK 0x3ffc0000 -#define SIB_SNDSIZE_SHIFT 18 -#define SIB_TELSIZE_MASK 0x00003ffc -#define SIB_TELSIZE_SHIFT 2 - -/* SIB Control Register */ -#define SIB_SIBIRQ BIT(31) -#define SIB_ENCNTTEST BIT(30) -#define SIB_ENDMATEST BIT(29) -#define SIB_SNDMONO BIT(28) -#define SIB_RMONOSNDIN BIT(27) -#define SIB_SIBSCLKDIV_MASK (BIT(26) | BIT(25) | BIT(24)) -#define SIB_SIBSCLKDIV_SHIFT 24 -#define SIB_TEL16 BIT(23) -#define SIB_TELFSDIV_MASK 0x007f0000 -#define SIB_TELFSDIV_SHIFT 16 -#define SIB_SND16 BIT(15) -#define SIB_SNDFSDIV_MASK 0x00007f00 -#define SIB_SNDFSDIV_SHIFT 8 -#define SIB_SELTELSF1 BIT(7) -#define SIB_SELSNDSF1 BIT(6) -#define SIB_ENTEL BIT(5) -#define SIB_ENSND BIT(4) -#define SIB_SIBLOOP BIT(3) -#define SIB_ENSF1 BIT(2) -#define SIB_ENSF0 BIT(1) -#define SIB_ENSIB BIT(0) - -/* SIB Frame Format (SIBSubFrame0Status and SIBSubFrame1Status) */ -#define SIB_REGISTER_EXT BIT(31) /* Must be zero */ -#define SIB_ADDRESS_MASK 0x78000000 -#define SIB_ADDRESS_SHIFT 27 -#define SIB_WRITE BIT(26) -#define SIB_AUD_VALID BIT(17) -#define SIB_TEL_VALID BIT(16) -#define SIB_DATA_MASK 0x00ff -#define SIB_DATA_SHIFT 0 - -/* SIB DMA Control Register */ -#define SIB_SNDBUFF1TIME BIT(31) -#define SIB_SNDDMALOOP BIT(30) -#define SIB_SNDDMAPTR_MASK 0x3ffc0000 -#define SIB_SNDDMAPTR_SHIFT 18 -#define SIB_ENDMARXSND BIT(17) -#define SIB_ENDMATXSND BIT(16) -#define SIB_TELBUFF1TIME BIT(15) -#define SIB_TELDMALOOP BIT(14) -#define SIB_TELDMAPTR_MASK 0x00003ffc -#define SIB_TELDMAPTR_SHIFT 2 -#define SIB_ENDMARXTEL BIT(1) -#define SIB_ENDMATXTEL BIT(0) - -/****************************************************************************** -* -* 14 SPI module -* -******************************************************************************/ - -#define SPIControl REG_AT(0x160) -#define SPITransmit REG_AT(0x164) -#define SPIReceive REG_AT(0x164) - -#define SPI_SPION BIT(17) -#define SPI_EMPTY BIT(16) -#define SPI_DELAYVAL_MASK (BIT(12) | BIT(13) | BIT(14) | BIT(15)) -#define SPI_DELAYVAL_SHIFT 12 -#define SPI_BAUDRATE_MASK (BIT(8) | BIT(9) | BIT(10) | BIT(11)) -#define SPI_BAUDRATE_SHIFT 8 -#define SPI_PHAPOL BIT(5) -#define SPI_CLKPOL BIT(4) -#define SPI_WORD BIT(2) -#define SPI_LSB BIT(1) -#define SPI_ENSPI BIT(0) - -/****************************************************************************** -* -* 15 Timer module -* -******************************************************************************/ - -#define RTChigh REG_AT(0x140) -#define RTClow REG_AT(0x144) -#define RTCalarmHigh REG_AT(0x148) -#define RTCalarmLow REG_AT(0x14c) -#define RTCtimerControl REG_AT(0x150) -#define RTCperiodTimer REG_AT(0x154) - -/* RTC Timer Control */ -#define TIM_FREEZEPRE BIT(7) -#define TIM_FREEZERTC BIT(6) -#define TIM_FREEZETIMER BIT(5) -#define TIM_ENPERTIMER BIT(4) -#define TIM_RTCCLEAR BIT(3) - -#define RTC_HIGHMASK (0xFF) - -/* RTC Periodic Timer */ -#define TIM_PERCNT 0xFFFF0000 -#define TIM_PERVAL 0x0000FFFF - -/* For a system clock frequency of 36.864MHz, the timer counts at one tick - every 868nS (ie CLK/32). Therefore 11520 counts gives a 10mS interval - */ -#define PER_TIMER_COUNT (1152000/HZ) - -/* - *********************************************************************** - * * - * 15 UART Module * - * * - *********************************************************************** - */ -#define TX3912_UARTA_BASE (REGISTER_BASE + 0x0b0) -#define TX3912_UARTB_BASE (REGISTER_BASE + 0x0c8) - -/* - * TX3912 UART register offsets - */ -#define TX3912_UART_CTRL1 0x00 -#define TX3912_UART_CTRL2 0x04 -#define TX3912_UART_DMA_CTRL1 0x08 -#define TX3912_UART_DMA_CTRL2 0x0c -#define TX3912_UART_DMA_CNT 0x10 -#define TX3912_UART_DATA 0x14 - -#define UartA_Ctrl1 REG_AT(0x0b0) -#define UartA_Data REG_AT(0x0c4) - -/* - * Defines for UART Control Register 1 - */ -#define TX3912_UART_CTRL1_UARTON 0x80000000 -#define UART_TX_EMPTY BIT(30) -#define UART_PRX_HOLD_FULL BIT(29) -#define UART_RX_HOLD_FULL BIT(28) -#define UART_EN_DMA_RX BIT(15) -#define UART_EN_DMA_TX BIT(14) -#define UART_BREAK_HALT BIT(12) -#define UART_DMA_LOOP BIT(10) -#define UART_PULSE_THREE BIT(9) -#define UART_PULSE_SIX BIT(8) -#define UART_DT_INVERT BIT(7) -#define UART_DIS_TXD BIT(6) -#define UART_LOOPBACK BIT(4) -#define TX3912_UART_CTRL1_ENUART 0x00000001 - -#define SER_SEVEN_BIT BIT(3) -#define SER_EIGHT_BIT 0 -#define SER_EVEN_PARITY (BIT(2) | BIT(1)) -#define SER_ODD_PARITY BIT(1) -#define SER_NO_PARITY 0 -#define SER_TWO_STOP BIT(5) -#define SER_ONE_STOP 0 +/* + * Clock control register values + */ +#define TX3912_CLK_CTRL_CHICLKDIV_MASK 0xff000000 +#define TX3912_CLK_CTRL_ENCLKTEST 0x00800000 +#define TX3912_CLK_CTRL_CLKTESTSELSIB 0x00400000 +#define TX3912_CLK_CTRL_CHIMCLKSEL 0x00200000 +#define TX3912_CLK_CTRL_CHICLKDIR 0x00100000 +#define TX3912_CLK_CTRL_ENCHIMCLK 0x00080000 +#define TX3912_CLK_CTRL_ENVIDCLK 0x00040000 +#define TX3912_CLK_CTRL_ENMBUSCLK 0x00020000 +#define TX3912_CLK_CTRL_ENSPICLK 0x00010000 +#define TX3912_CLK_CTRL_ENTIMERCLK 0x00008000 +#define TX3912_CLK_CTRL_ENFASTTIMERCLK 0x00004000 +#define TX3912_CLK_CTRL_SIBMCLKDIR 0x00002000 +#define TX3912_CLK_CTRL_reserved1 0x00001000 +#define TX3912_CLK_CTRL_ENSIBMCLK 0x00000800 +#define TX3912_CLK_CTRL_SIBMCLKDIV_6 0x00000600 +#define TX3912_CLK_CTRL_SIBMCLKDIV_5 0x00000500 +#define TX3912_CLK_CTRL_SIBMCLKDIV_4 0x00000400 +#define TX3912_CLK_CTRL_SIBMCLKDIV_3 0x00000300 +#define TX3912_CLK_CTRL_SIBMCLKDIV_2 0x00000200 +#define TX3912_CLK_CTRL_SIBMCLKDIV_1 0x00000100 +#define TX3912_CLK_CTRL_CSERSEL 0x00000080 +#define TX3912_CLK_CTRL_CSERDIV_6 0x00000060 +#define TX3912_CLK_CTRL_CSERDIV_5 0x00000050 +#define TX3912_CLK_CTRL_CSERDIV_4 0x00000040 +#define TX3912_CLK_CTRL_CSERDIV_3 0x00000030 +#define TX3912_CLK_CTRL_CSERDIV_2 0x00000020 +#define TX3912_CLK_CTRL_CSERDIV_1 0x00000010 +#define TX3912_CLK_CTRL_ENCSERCLK 0x00000008 +#define TX3912_CLK_CTRL_ENIRCLK 0x00000004 +#define TX3912_CLK_CTRL_ENUARTACLK 0x00000002 +#define TX3912_CLK_CTRL_ENUARTBCLK 0x00000001 + + +/***************************************************************************** + * Interrupt Subsystem * + * ------------------- * + * Chapter 8 in Philips PR31700 and Toshiba TMPR3905/12 User Manuals * + *****************************************************************************/ +#define TX3912_INT1_CLEAR 0x0100 +#define TX3912_INT2_CLEAR 0x0104 +#define TX3912_INT3_CLEAR 0x0108 +#define TX3912_INT4_CLEAR 0x010c +#define TX3912_INT5_CLEAR 0x0110 +#define TX3912_INT1_ENABLE 0x0118 +#define TX3912_INT2_ENABLE 0x011c +#define TX3912_INT3_ENABLE 0x0120 +#define TX3912_INT4_ENABLE 0x0124 +#define TX3912_INT5_ENABLE 0x0128 +#define TX3912_INT6_ENABLE 0x012c +#define TX3912_INT1_STATUS 0x0100 +#define TX3912_INT2_STATUS 0x0104 +#define TX3912_INT3_STATUS 0x0108 +#define TX3912_INT4_STATUS 0x010c +#define TX3912_INT5_STATUS 0x0110 +#define TX3912_INT6_STATUS 0x0114 /* - * Defines for UART Control Register 2 - * - * 3.6864MHz - * divisors = ----------- - 1 - * (baud * 16) - */ -#define TX3912_UART_CTRL2_B230400 0x000 /* 0 */ -#define TX3912_UART_CTRL2_B115200 0x001 /* 1 */ -#define TX3912_UART_CTRL2_B76800 0x002 /* 2 */ -#define TX3912_UART_CTRL2_B57600 0x003 /* 3 */ -#define TX3912_UART_CTRL2_B38400 0x005 /* 5 */ -#define TX3912_UART_CTRL2_B19200 0x00b /* 11 */ -#define TX3912_UART_CTRL2_B9600 0x016 /* 22 */ -#define TX3912_UART_CTRL2_B4800 0x02f /* 47 */ -#define TX3912_UART_CTRL2_B2400 0x05f /* 95 */ -#define TX3912_UART_CTRL2_B1200 0x0bf /* 191 */ -#define TX3912_UART_CTRL2_B600 0x17f /* 383 */ -#define TX3912_UART_CTRL2_B300 0x2ff /* 767 */ + * Interrupt 2 register values + */ +#define TX3912_INT2_UARTARXINT 0x80000000 +#define TX3912_INT2_UARTARXOVERRUNINT 0x40000000 +#define TX3912_INT2_UARTAFRAMEERRINT 0x20000000 +#define TX3912_INT2_UARTABREAKINT 0x10000000 +#define TX3912_INT2_UARTAPARITYINT 0x08000000 +#define TX3912_INT2_UARTATXINT 0x04000000 +#define TX3912_INT2_UARTATXOVERRUNINT 0x02000000 +#define TX3912_INT2_UARTAEMPTYINT 0x01000000 +#define TX3912_INT2_UARTADMAFULLINT 0x00800000 +#define TX3912_INT2_UARTADMAHALFINT 0x00400000 +#define TX3912_INT2_UARTBRXINT 0x00200000 +#define TX3912_INT2_UARTBRXOVERRUNINT 0x00100000 +#define TX3912_INT2_UARTBFRAMEERRINT 0x00080000 +#define TX3912_INT2_UARTBBREAKINT 0x00040000 +#define TX3912_INT2_UARTBPARITYINT 0x00020000 +#define TX3912_INT2_UARTBTXINT 0x00010000 +#define TX3912_INT2_UARTBTXOVERRUNINT 0x00008000 +#define TX3912_INT2_UARTBEMPTYINT 0x00004000 +#define TX3912_INT2_UARTBDMAFULLINT 0x00002000 +#define TX3912_INT2_UARTBDMAHALFINT 0x00001000 +#define TX3912_INT2_UARTA_RX_BITS 0xf8000000 +#define TX3912_INT2_UARTA_TX_BITS 0x07c00000 +#define TX3912_INT2_UARTB_RX_BITS 0x003e0000 +#define TX3912_INT2_UARTB_TX_BITS 0x0001f000 + +/* + * Interrupt 5 register values + */ +#define TX3912_INT5_RTCINT 0x80000000 +#define TX3912_INT5_ALARMINT 0x40000000 +#define TX3912_INT5_PERINT 0x20000000 +#define TX3912_INT5_STPTIMERINT 0x10000000 +#define TX3912_INT5_POSPWRINT 0x08000000 +#define TX3912_INT5_NEGPWRINT 0x04000000 +#define TX3912_INT5_POSPWROKINT 0x02000000 +#define TX3912_INT5_NEGPWROKINT 0x01000000 +#define TX3912_INT5_POSONBUTINT 0x00800000 +#define TX3912_INT5_NEGONBUTINT 0x00400000 +#define TX3912_INT5_SPIBUFAVAILINT 0x00200000 +#define TX3912_INT5_SPIERRINT 0x00100000 +#define TX3912_INT5_SPIRCVINT 0x00080000 +#define TX3912_INT5_SPIEMPTYINT 0x00040000 +#define TX3912_INT5_IRCONSMINT 0x00020000 +#define TX3912_INT5_CARSTINT 0x00010000 +#define TX3912_INT5_POSCARINT 0x00008000 +#define TX3912_INT5_NEGCARINT 0x00004000 +#define TX3912_INT5_IOPOSINT6 0x00002000 +#define TX3912_INT5_IOPOSINT5 0x00001000 +#define TX3912_INT5_IOPOSINT4 0x00000800 +#define TX3912_INT5_IOPOSINT3 0x00000400 +#define TX3912_INT5_IOPOSINT2 0x00000200 +#define TX3912_INT5_IOPOSINT1 0x00000100 +#define TX3912_INT5_IOPOSINT0 0x00000080 +#define TX3912_INT5_IONEGINT6 0x00000040 +#define TX3912_INT5_IONEGINT5 0x00000020 +#define TX3912_INT5_IONEGINT4 0x00000010 +#define TX3912_INT5_IONEGINT3 0x00000008 +#define TX3912_INT5_IONEGINT2 0x00000004 +#define TX3912_INT5_IONEGINT1 0x00000002 +#define TX3912_INT5_IONEGINT0 0x00000001 + +/* + * Interrupt 6 status register values + */ +#define TX3912_INT6_STATUS_IRQHIGH 0x80000000 +#define TX3912_INT6_STATUS_IRQLOW 0x40000000 +#define TX3912_INT6_STATUS_reserved6 0x3fffffc0 +#define TX3912_INT6_STATUS_INTVEC_POSNEGPWROKINT 0x0000003c +#define TX3912_INT6_STATUS_INTVEC_ALARMINT 0x00000038 +#define TX3912_INT6_STATUS_INTVEC_PERINT 0x00000034 +#define TX3912_INT6_STATUS_INTVEC_reserved5 0x00000030 +#define TX3912_INT6_STATUS_INTVEC_UARTARXINT 0x0000002c +#define TX3912_INT6_STATUS_INTVEC_UARTBRXINT 0x00000028 +#define TX3912_INT6_STATUS_INTVEC_reserved4 0x00000024 +#define TX3912_INT6_STATUS_INTVEC_IOPOSINT65 0x00000020 +#define TX3912_INT6_STATUS_INTVEC_reserved3 0x0000001c +#define TX3912_INT6_STATUS_INTVEC_IONEGINT65 0x00000018 +#define TX3912_INT6_STATUS_INTVEC_reserved2 0x00000014 +#define TX3912_INT6_STATUS_INTVEC_SNDDMACNTINT 0x00000010 +#define TX3912_INT6_STATUS_INTVEC_TELDMACNTINT 0x0000000c +#define TX3912_INT6_STATUS_INTVEC_CHIDMACNTINT 0x00000008 +#define TX3912_INT6_STATUS_INTVEC_IOPOSNEGINT0 0x00000004 +#define TX3912_INT6_STATUS_INTVEC_STDHANDLER 0x00000000 +#define TX3912_INT6_STATUS_reserved1 0x00000003 + +/* + * Interrupt 6 enable register values + */ +#define TX3912_INT6_ENABLE_reserved5 0xfff80000 +#define TX3912_INT6_ENABLE_GLOBALEN 0x00040000 +#define TX3912_INT6_ENABLE_IRQPRITEST 0x00020000 +#define TX3912_INT6_ENABLE_IRQTEST 0x00010000 +#define TX3912_INT6_ENABLE_PRIORITYMASK_POSNEGPWROKINT 0x00008000 +#define TX3912_INT6_ENABLE_PRIORITYMASK_ALARMINT 0x00004000 +#define TX3912_INT6_ENABLE_PRIORITYMASK_PERINT 0x00002000 +#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved4 0x00001000 +#define TX3912_INT6_ENABLE_PRIORITYMASK_UARTARXINT 0x00000800 +#define TX3912_INT6_ENABLE_PRIORITYMASK_UARTBRXINT 0x00000400 +#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved3 0x00000200 +#define TX3912_INT6_ENABLE_PRIORITYMASK_IOPOSINT65 0x00000100 +#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved2 0x00000080 +#define TX3912_INT6_ENABLE_PRIORITYMASK_IONEGINT65 0x00000040 +#define TX3912_INT6_ENABLE_PRIORITYMASK_reserved1 0x00000020 +#define TX3912_INT6_ENABLE_PRIORITYMASK_SNDDMACNTINT 0x00000010 +#define TX3912_INT6_ENABLE_PRIORITYMASK_TELDMACNTINT 0x00000008 +#define TX3912_INT6_ENABLE_PRIORITYMASK_CHIDMACNTINT 0x00000004 +#define TX3912_INT6_ENABLE_PRIORITYMASK_IOPOSNEGINT0 0x00000002 +#define TX3912_INT6_ENABLE_PRIORITYMASK_STDHANDLER 0x00000001 +#define TX3912_INT6_ENABLE_HIGH_PRIORITY 0x0000ffff + + +/***************************************************************************** + * Power Subsystem * + * --------------- * + * Chapter 11 in Philips PR31700 User Manual * + * Chapter 12 in Toshiba TMPR3905/12 User Manual * + *****************************************************************************/ +#define TX3912_POWER_CTRL 0x01c4 + +/* + * Power control register values + */ +#define TX3912_POWER_CTRL_ONBUTN 0x80000000 +#define TX3912_POWER_CTRL_PWRINT 0x40000000 +#define TX3912_POWER_CTRL_PWROK 0x20000000 +#define TX3912_POWER_CTRL_VIDRF_MASK 0x18000000 +#define TX3912_POWER_CTRL_SLOWBUS 0x04000000 +#define TX3912_POWER_CTRL_DIVMOD 0x02000000 +#define TX3912_POWER_CTRL_reserved2 0x01ff0000 +#define TX3912_POWER_CTRL_STPTIMERVAL_MASK 0x0000f000 +#define TX3912_POWER_CTRL_ENSTPTIMER 0x00000800 +#define TX3912_POWER_CTRL_ENFORCESHUTDWN 0x00000400 +#define TX3912_POWER_CTRL_FORCESHUTDWN 0x00000200 +#define TX3912_POWER_CTRL_FORCESHUTDWNOCC 0x00000100 +#define TX3912_POWER_CTRL_SELC2MS 0x00000080 +#define TX3912_POWER_CTRL_reserved1 0x00000040 +#define TX3912_POWER_CTRL_BPDBVCC3 0x00000020 +#define TX3912_POWER_CTRL_STOPCPU 0x00000010 +#define TX3912_POWER_CTRL_DBNCONBUTN 0x00000008 +#define TX3912_POWER_CTRL_COLDSTART 0x00000004 +#define TX3912_POWER_CTRL_PWRCS 0x00000002 +#define TX3912_POWER_CTRL_VCCON 0x00000001 + + +/***************************************************************************** + * Timer Subsystem * + * --------------- * + * Chapter 14 in Philips PR31700 User Manual * + * Chapter 15 in Toshiba TMPR3905/12 User Manual * + *****************************************************************************/ +#define TX3912_RTC_HIGH 0x0140 +#define TX3912_RTC_LOW 0x0144 +#define TX3912_RTC_ALARM_HIGH 0x0148 +#define TX3912_RTC_ALARM_LOW 0x014c +#define TX3912_TIMER_CTRL 0x0150 +#define TX3912_TIMER_PERIOD 0x0154 + +/* + * Timer control register values + */ +#define TX3912_TIMER_CTRL_FREEZEPRE 0x00000080 +#define TX3912_TIMER_CTRL_FREEZERTC 0x00000040 +#define TX3912_TIMER_CTRL_FREEZETIMER 0x00000020 +#define TX3912_TIMER_CTRL_ENPERTIMER 0x00000010 +#define TX3912_TIMER_CTRL_RTCCLEAR 0x00000008 +#define TX3912_TIMER_CTRL_TESTC8MS 0x00000004 +#define TX3912_TIMER_CTRL_ENTESTCLK 0x00000002 +#define TX3912_TIMER_CTRL_ENRTCTST 0x00000001 + +/* + * The periodic timer has granularity of 868 nanoseconds which + * results in a count of (1.152 x 10^6 / 100) in order to achieve + * a 10 millisecond periodic system clock. + */ +#define TX3912_SYS_TIMER_VALUE (1152000/HZ) + + +/***************************************************************************** + * UART Subsystem * + * -------------- * + * Chapter 15 in Philips PR31700 User Manual * + * Chapter 16 in Toshiba TMPR3905/12 User Manual * + *****************************************************************************/ +#define TX3912_UARTA_CTRL1 0x00b0 +#define TX3912_UARTA_CTRL2 0x00b4 +#define TX3912_UARTA_DMA_CTRL1 0x00b8 +#define TX3912_UARTA_DMA_CTRL2 0x00bc +#define TX3912_UARTA_DMA_CNT 0x00c0 +#define TX3912_UARTA_DATA 0x00c4 +#define TX3912_UARTB_CTRL1 0x00c8 +#define TX3912_UARTB_CTRL2 0x00cc +#define TX3912_UARTB_DMA_CTRL1 0x00d0 +#define TX3912_UARTB_DMA_CTRL2 0x00d4 +#define TX3912_UARTB_DMA_CNT 0x00d8 +#define TX3912_UARTB_DATA 0x00dc + +/* + * UART Control Register 1 values + */ +#define TX3912_UART_CTRL1_UARTON 0x80000000 +#define TX3912_UART_CTRL1_EMPTY 0x40000000 +#define TX3912_UART_CTRL1_PRXHOLDFULL 0x20000000 +#define TX3912_UART_CTRL1_RXHOLDFULL 0x10000000 +#define TX3912_UART_CTRL1_reserved1 0x0fff0000 +#define TX3912_UART_CTRL1_ENDMARX 0x00008000 +#define TX3912_UART_CTRL1_ENDMATX 0x00004000 +#define TX3912_UART_CTRL1_TESTMODE 0x00002000 +#define TX3912_UART_CTRL1_ENBREAKHALT 0x00001000 +#define TX3912_UART_CTRL1_ENDMATEST 0x00000800 +#define TX3912_UART_CTRL1_ENDMALOOP 0x00000400 +#define TX3912_UART_CTRL1_PULSEOPT1 0x00000200 +#define TX3912_UART_CTRL1_PULSEOPT1 0x00000100 +#define TX3912_UART_CTRL1_DTINVERT 0x00000080 +#define TX3912_UART_CTRL1_DISTXD 0x00000040 +#define TX3912_UART_CTRL1_TWOSTOP 0x00000020 +#define TX3912_UART_CTRL1_LOOPBACK 0x00000010 +#define TX3912_UART_CTRL1_BIT_7 0x00000008 +#define TX3912_UART_CTRL1_EVENPARITY 0x00000004 +#define TX3912_UART_CTRL1_ENPARITY 0x00000002 +#define TX3912_UART_CTRL1_ENUART 0x00000001 + +/* + * UART Control Register 2 values + */ +#define TX3912_UART_CTRL2_B230400 0x0000 /* 0 */ +#define TX3912_UART_CTRL2_B115200 0x0001 /* 1 */ +#define TX3912_UART_CTRL2_B76800 0x0002 /* 2 */ +#define TX3912_UART_CTRL2_B57600 0x0003 /* 3 */ +#define TX3912_UART_CTRL2_B38400 0x0005 /* 5 */ +#define TX3912_UART_CTRL2_B19200 0x000b /* 11 */ +#define TX3912_UART_CTRL2_B9600 0x0016 /* 22 */ +#define TX3912_UART_CTRL2_B4800 0x002f /* 47 */ +#define TX3912_UART_CTRL2_B2400 0x005f /* 95 */ +#define TX3912_UART_CTRL2_B1200 0x00bf /* 191 */ +#define TX3912_UART_CTRL2_B600 0x017f /* 383 */ +#define TX3912_UART_CTRL2_B300 0x02ff /* 767 */ + +/***************************************************************************** + * Video Subsystem * + * --------------- * + * Chapter 16 in Philips PR31700 User Manual * + * Chapter 17 in Toshiba TMPR3905/12 User Manual * + *****************************************************************************/ +#define TX3912_VIDEO_CTRL1 0x0028 +#define TX3912_VIDEO_CTRL2 0x002c +#define TX3912_VIDEO_CTRL3 0x0030 +#define TX3912_VIDEO_CTRL4 0x0034 +#define TX3912_VIDEO_CTRL5 0x0038 +#define TX3912_VIDEO_CTRL6 0x003c +#define TX3912_VIDEO_CTRL7 0x0040 +#define TX3912_VIDEO_CTRL8 0x0044 +#define TX3912_VIDEO_CTRL9 0x0048 +#define TX3912_VIDEO_CTRL10 0x004c +#define TX3912_VIDEO_CTRL11 0x0050 +#define TX3912_VIDEO_CTRL12 0x0054 +#define TX3912_VIDEO_CTRL13 0x0058 +#define TX3912_VIDEO_CTRL14 0x005c + +/* + * Video Control Register 1 values + */ +#define TX3912_VIDEO_CTRL1_LINECNT 0xffc00000 +#define TX3912_VIDEO_CTRL1_LOADDLY 0x00200000 +#define TX3912_VIDEO_CTRL1_BAUDVAL 0x001f0000 +#define TX3912_VIDEO_CTRL1_VIDDONEVAL 0x0000fe00 +#define TX3912_VIDEO_CTRL1_ENFREEZEFRAME 0x00000100 +#define TX3912_VIDEO_CTRL1_BITSEL_MASK 0x000000c0 +#define TX3912_VIDEO_CTRL1_BITSEL_8BIT_COLOR 0x000000c0 +#define TX3912_VIDEO_CTRL1_BITSEL_4BIT_GRAY 0x00000080 +#define TX3912_VIDEO_CTRL1_BITSEL_2BIT_GRAY 0x00000040 +#define TX3912_VIDEO_CTRL1_DISPSPLIT 0x00000020 +#define TX3912_VIDEO_CTRL1_DISP8 0x00000010 +#define TX3912_VIDEO_CTRL1_DFMODE 0x00000008 +#define TX3912_VIDEO_CTRL1_INVVID 0x00000004 +#define TX3912_VIDEO_CTRL1_DISPON 0x00000002 +#define TX3912_VIDEO_CTRL1_ENVID 0x00000001 -#endif /* __TX3912_H__ */ +#endif /* _TX3912_H_ */ diff -Nru a/include/asm-mips/tx4927/toshiba_rbtx4927.h b/include/asm-mips/tx4927/toshiba_rbtx4927.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/tx4927/toshiba_rbtx4927.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,55 @@ +/* + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ +#ifndef __ASM_TX4927_TOSHIBA_RBTX4927_H +#define __ASM_TX4927_TOSHIBA_RBTX4927_H + +#include <asm/tx4927/tx4927.h> +#include <asm/tx4927/tx4927_mips.h> +#ifdef CONFIG_PCI +#include <asm/tx4927/tx4927_pci.h> +#endif + +#define TOSHIBA_RBTX4927_WR08(a,b) do { TX4927_WR08(a,b); wbflush(); } while ( 0 ) + + +#ifdef CONFIG_PCI +#define TBTX4927_ISA_IO_OFFSET TX4927_PCIIO +#else +#define TBTX4927_ISA_IO_OFFSET 0 +#endif + +#define RBTX4927_SW_RESET_DO 0xbc00f000 +#define RBTX4927_SW_RESET_DO_SET 0x01 + +#define RBTX4927_SW_RESET_ENABLE 0xbc00f002 +#define RBTX4927_SW_RESET_ENABLE_SET 0x01 + + +#define RBTX4927_RTL_8019_BASE (0x1c020280-TBTX4927_ISA_IO_OFFSET) +#define RBTX4927_RTL_8019_IRQ (29) + +#endif /* __ASM_TX4927_TOSHIBA_RBTX4927_H */ diff -Nru a/include/asm-mips/tx4927/tx4927.h b/include/asm-mips/tx4927/tx4927.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/tx4927/tx4927.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,525 @@ +/* + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ +#ifndef __ASM_TX4927_TX4927_H +#define __ASM_TX4927_TX4927_H + +#include <asm/tx4927/tx4927_mips.h> + +/* + This register naming came from the intergrate cpu/controoler name TX4927 + followed by the device name from table 4.2.2 on page 4-3 and then followed + by the register name from table 4.2.3 on pages 4-4 to 4-8. The manaul + used is "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001". + */ + +#define TX4927_SIO_0_BASE + +/* TX4927 controller */ +#define TX4927_BASE 0xfff1f0000 +#define TX4927_BASE 0xfff1f0000 +#define TX4927_LIMIT 0xfff1fffff + + +/* TX4927 SDRAM controller (64-bit registers) */ +#define TX4927_SDRAMC_BASE 0x8000 +#define TX4927_SDRAMC_SDCCR0 0x8000 +#define TX4927_SDRAMC_SDCCR1 0x8008 +#define TX4927_SDRAMC_SDCCR2 0x8010 +#define TX4927_SDRAMC_SDCCR3 0x8018 +#define TX4927_SDRAMC_SDCTR 0x8040 +#define TX4927_SDRAMC_SDCMD 0x8058 +#define TX4927_SDRAMC_LIMIT 0x8fff + + +/* TX4927 external bus controller (64-bit registers) */ +#define TX4927_EBUSC_BASE 0x9000 +#define TX4927_EBUSC_EBCCR0 0x9000 +#define TX4927_EBUSC_EBCCR1 0x9008 +#define TX4927_EBUSC_EBCCR2 0x9010 +#define TX4927_EBUSC_EBCCR3 0x9018 +#define TX4927_EBUSC_EBCCR4 0x9020 +#define TX4927_EBUSC_EBCCR5 0x9028 +#define TX4927_EBUSC_EBCCR6 0x9030 +#define TX4927_EBUSC_EBCCR7 0x9008 +#define TX4927_EBUSC_LIMIT 0x9fff + + +/* TX4927 SDRRAM Error Check Correction (64-bit registers) */ +#define TX4927_ECC_BASE 0xa000 +#define TX4927_ECC_ECCCR 0xa000 +#define TX4927_ECC_ECCSR 0xa008 +#define TX4927_ECC_LIMIT 0xafff + + +/* TX4927 DMA Controller (64-bit registers) */ +#define TX4927_DMAC_BASE 0xb000 +#define TX4927_DMAC_TBD 0xb000 +#define TX4927_DMAC_LIMIT 0xbfff + + +/* TX4927 PCI Controller (32-bit registers) */ +#define TX4927_PCIC_BASE 0xd000 +#define TX4927_PCIC_TBD 0xb000 +#define TX4927_PCIC_LIMIT 0xdfff + + +/* TX4927 Configuration registers (64-bit registers) */ +#define TX4927_CONFIG_BASE 0xe300 +#define TX4927_CONFIG_CCFG 0xe300 +#define TX4927_CONFIG_CCFG_RESERVED_42_63 BM_63_42 +#define TX4927_CONFIG_CCFG_WDRST BM_41_41 +#define TX4927_CONFIG_CCFG_WDREXEN BM_40_40 +#define TX4927_CONFIG_CCFG_BCFG BM_39_32 +#define TX4927_CONFIG_CCFG_RESERVED_27_31 BM_31_27 +#define TX4927_CONFIG_CCFG_GTOT BM_26_25 +#define TX4927_CONFIG_CCFG_GTOT_4096 BM_26_25 +#define TX4927_CONFIG_CCFG_GTOT_2048 BM_26_26 +#define TX4927_CONFIG_CCFG_GTOT_1024 BM_25_25 +#define TX4927_CONFIG_CCFG_GTOT_0512 (~BM_26_25) +#define TX4927_CONFIG_CCFG_TINTDIS BM_24_24 +#define TX4927_CONFIG_CCFG_PCI66 BM_23_23 +#define TX4927_CONFIG_CCFG_PCIMODE BM_22_22 +#define TX4927_CONFIG_CCFG_RESERVED_20_21 BM_21_20 +#define TX4927_CONFIG_CCFG_DIVMODE BM_19_17 +#define TX4927_CONFIG_CCFG_DIVMODE_2_0 BM_19_19 +#define TX4927_CONFIG_CCFG_DIVMODE_3_0 (BM_19_19|BM_17_17) +#define TX4927_CONFIG_CCFG_DIVMODE_4_0 BM_19_18 +#define TX4927_CONFIG_CCFG_DIVMODE_2_5 BM_19_17 +#define TX4927_CONFIG_CCFG_DIVMODE_8_0 (~BM_19_17) +#define TX4927_CONFIG_CCFG_DIVMODE_12_0 BM_17_17 +#define TX4927_CONFIG_CCFG_DIVMODE_16_0 BM_18_18 +#define TX4927_CONFIG_CCFG_DIVMODE_10_0 BM_18_17 +#define TX4927_CONFIG_CCFG_BEOW BM_16_16 +#define TX4927_CONFIG_CCFG_WR BM_15_15 +#define TX4927_CONFIG_CCFG_TOE BM_14_14 +#define TX4927_CONFIG_CCFG_PCIARB BM_13_13 +#define TX4927_CONFIG_CCFG_PCIDIVMODE BM_12_11 +#define TX4927_CONFIG_CCFG_RESERVED_08_10 BM_10_08 +#define TX4927_CONFIG_CCFG_SYSSP BM_07_06 +#define TX4927_CONFIG_CCFG_RESERVED_03_05 BM_05_03 +#define TX4927_CONFIG_CCFG_ENDIAN BM_02_02 +#define TX4927_CONFIG_CCFG_ARMODE BM_01_01 +#define TX4927_CONFIG_CCFG_ACEHOLD BM_00_00 +#define TX4927_CONFIG_REVID 0xe308 +#define TX4927_CONFIG_REVID_RESERVED_32_63 BM_32_63 +#define TX4927_CONFIG_REVID_PCODE BM_16_31 +#define TX4927_CONFIG_REVID_MJERREV BM_12_15 +#define TX4927_CONFIG_REVID_MINEREV BM_08_11 +#define TX4927_CONFIG_REVID_MJREV BM_04_07 +#define TX4927_CONFIG_REVID_MINREV BM_00_03 +#define TX4927_CONFIG_PCFG 0xe310 +#define TX4927_CONFIG_PCFG_RESERVED_57_63 BM_57_63 +#define TX4927_CONFIG_PCFG_DRVDATA BM_56_56 +#define TX4927_CONFIG_PCFG_DRVCB BM_55_55 +#define TX4927_CONFIG_PCFG_DRVDQM BM_54_54 +#define TX4927_CONFIG_PCFG_DRVADDR BM_53_53 +#define TX4927_CONFIG_PCFG_DRVCKE BM_52_52 +#define TX4927_CONFIG_PCFG_DRVRAS BM_51_51 +#define TX4927_CONFIG_PCFG_DRVCAS BM_50_50 +#define TX4927_CONFIG_PCFG_DRVWE BM_49_49 +#define TX4927_CONFIG_PCFG_DRVCS3 BM_48_48 +#define TX4927_CONFIG_PCFG_DRVCS2 BM_47_47 +#define TX4927_CONFIG_PCFG_DRVCS1 BM_46_4k +#define TX4927_CONFIG_PCFG_DRVCS0 BM_45_45 +#define TX4927_CONFIG_PCFG_DRVCK3 BM_44_44 +#define TX4927_CONFIG_PCFG_DRVCK2 BM_43_43 +#define TX4927_CONFIG_PCFG_DRVCK1 BM_42_42 +#define TX4927_CONFIG_PCFG_DRVCK0 BM_41_41 +#define TX4927_CONFIG_PCFG_DRVCKIN BM_40_40 +#define TX4927_CONFIG_PCFG_RESERVED_33_39 BM_33_39 +#define TX4927_CONFIG_PCFG_BYPASS_PLL BM_32_32 +#define TX4927_CONFIG_PCFG_RESERVED_30_31 BM_30_31 +#define TX4927_CONFIG_PCFG_SDCLKDLY BM_28_29 +#define TX4927_CONFIG_PCFG_SDCLKDLY_DELAY_1 (~BM_28_29) +#define TX4927_CONFIG_PCFG_SDCLKDLY_DELAY_2 BM_28_28 +#define TX4927_CONFIG_PCFG_SDCLKDLY_DELAY_3 BM_29_29 +#define TX4927_CONFIG_PCFG_SDCLKDLY_DELAY_4 BM_28_29 +#define TX4927_CONFIG_PCFG_SYSCLKEN BM_27_27 +#define TX4927_CONFIG_PCFG_SDCLKEN3 BM_26_26 +#define TX4927_CONFIG_PCFG_SDCLKEN2 BM_25_25 +#define TX4927_CONFIG_PCFG_SDCLKEN1 BM_24_24 +#define TX4927_CONFIG_PCFG_SDCLKEN0 BM_23_23 +#define TX4927_CONFIG_PCFG_SDCLKINEN BM_22_22 +#define TX4927_CONFIG_PCFG_PCICLKEN5 BM_21_21 +#define TX4927_CONFIG_PCFG_PCICLKEN4 BM_20_20 +#define TX4927_CONFIG_PCFG_PCICLKEN3 BM_19_19 +#define TX4927_CONFIG_PCFG_PCICLKEN2 BM_18_18 +#define TX4927_CONFIG_PCFG_PCICLKEN1 BM_17_17 +#define TX4927_CONFIG_PCFG_PCICLKEN0 BM_16_16 +#define TX4927_CONFIG_PCFG_RESERVED_10_15 BM_10_15 +#define TX4927_CONFIG_PCFG_SEL2 BM_09_09 +#define TX4927_CONFIG_PCFG_SEL1 BM_08_08 +#define TX4927_CONFIG_PCFG_DMASEL3 BM_06_07 +#define TX4927_CONFIG_PCFG_DMASEL3_DMAREQ3 (~BM_06_07) +#define TX4927_CONFIG_PCFG_DMASEL3_SIO0 BM_06_06 +#define TX4927_CONFIG_PCFG_DMASEL3_ACLC3 BM_07_07 +#define TX4927_CONFIG_PCFG_DMASEL3_ACLC1 BM_06_07 +#define TX4927_CONFIG_PCFG_DMASEL2 BM_06_07 +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_0_DMAREQ2 (~BM_06_07) +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_0_SIO0 BM_06_06 +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_0_RESERVED_10 BM_07_07 +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_0_RESERVED_11 BM_06_07 +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_1_ACLC1 (~BM_06_07) +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_1_SIO0 BM_06_06 +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_1_ACLC2 BM_07_07 +#define TX4927_CONFIG_PCFG_DMASEL2_SEL2_1_ACLC0 BM_06_07 +#define TX4927_CONFIG_PCFG_DMASEL1 BM_02_03 +#define TX4927_CONFIG_PCFG_DMASEL1_DMAREQ1 (~BM_02_03) +#define TX4927_CONFIG_PCFG_DMASEL1_SIO1 BM_02_02 +#define TX4927_CONFIG_PCFG_DMASEL1_ACLC1 BM_03_03 +#define TX4927_CONFIG_PCFG_DMASEL1_ACLC3 BM_02_03 +#define TX4927_CONFIG_PCFG_DMASEL0 BM_00_01 +#define TX4927_CONFIG_PCFG_DMASEL0_DMAREQ0 (~BM_00_01) +#define TX4927_CONFIG_PCFG_DMASEL0_SIO1 BM_00_00 +#define TX4927_CONFIG_PCFG_DMASEL0_ACLC0 BM_01_01 +#define TX4927_CONFIG_PCFG_DMASEL0_ACLC2 BM_00_01 +#define TX4927_CONFIG_TOEA 0xe318 +#define TX4927_CONFIG_TOEA_RESERVED_36_63 BM_36_63 +#define TX4927_CONFIG_TOEA_TOEA BM_00_35 +#define TX4927_CONFIG_CLKCTR 0xe320 +#define TX4927_CONFIG_CLKCTR_RESERVED_26_63 BM_26_63 +#define TX4927_CONFIG_CLKCTR_ACLCKD BM_25_25 +#define TX4927_CONFIG_CLKCTR_PIOCKD BM_24_24 +#define TX4927_CONFIG_CLKCTR_DMACKD BM_23_23 +#define TX4927_CONFIG_CLKCTR_PCICKD BM_22_22 +#define TX4927_CONFIG_CLKCTR_SET_21 BM_21_21 +#define TX4927_CONFIG_CLKCTR_TM0CKD BM_20_20 +#define TX4927_CONFIG_CLKCTR_TM1CKD BM_19_19 +#define TX4927_CONFIG_CLKCTR_TM2CKD BM_18_18 +#define TX4927_CONFIG_CLKCTR_SIO0CKD BM_17_17 +#define TX4927_CONFIG_CLKCTR_SIO1CKD BM_16_16 +#define TX4927_CONFIG_CLKCTR_RESERVED_10_15 BM_10_15 +#define TX4927_CONFIG_CLKCTR_ACLRST BM_09_09 +#define TX4927_CONFIG_CLKCTR_PIORST BM_08_08 +#define TX4927_CONFIG_CLKCTR_DMARST BM_07_07 +#define TX4927_CONFIG_CLKCTR_PCIRST BM_06_06 +#define TX4927_CONFIG_CLKCTR_RESERVED_05_05 BM_05_05 +#define TX4927_CONFIG_CLKCTR_TM0RST BM_04_04 +#define TX4927_CONFIG_CLKCTR_TM1RST BM_03_03 +#define TX4927_CONFIG_CLKCTR_TM2RST BM_02_02 +#define TX4927_CONFIG_CLKCTR_SIO0RST BM_01_01 +#define TX4927_CONFIG_CLKCTR_SIO1RST BM_00_00 +#define TX4927_CONFIG_GARBC 0xe330 +#define TX4927_CONFIG_GARBC_RESERVED_10_63 BM_10_63 +#define TX4927_CONFIG_GARBC_SET_09 BM_09_09 +#define TX4927_CONFIG_GARBC_ARBMD BM_08_08 +#define TX4927_CONFIG_GARBC_RESERVED_06_07 BM_06_07 +#define TX4927_CONFIG_GARBC_PRIORITY_H1 BM_04_05 +#define TX4927_CONFIG_GARBC_PRIORITY_H1_PCI (~BM_04_05) +#define TX4927_CONFIG_GARBC_PRIORITY_H1_PDMAC BM_04_04 +#define TX4927_CONFIG_GARBC_PRIORITY_H1_DMAC BM_05_05 +#define TX4927_CONFIG_GARBC_PRIORITY_H1_BAD_VALUE BM_04_05 +#define TX4927_CONFIG_GARBC_PRIORITY_H2 BM_02_03 +#define TX4927_CONFIG_GARBC_PRIORITY_H2_PCI (~BM_02_03) +#define TX4927_CONFIG_GARBC_PRIORITY_H2_PDMAC BM_02_02 +#define TX4927_CONFIG_GARBC_PRIORITY_H2_DMAC BM_03_03 +#define TX4927_CONFIG_GARBC_PRIORITY_H2_BAD_VALUE BM_02_03 +#define TX4927_CONFIG_GARBC_PRIORITY_H3 BM_00_01 +#define TX4927_CONFIG_GARBC_PRIORITY_H3_PCI (~BM_00_01) +#define TX4927_CONFIG_GARBC_PRIORITY_H3_PDMAC BM_00_00 +#define TX4927_CONFIG_GARBC_PRIORITY_H3_DMAC BM_01_01 +#define TX4927_CONFIG_GARBC_PRIORITY_H3_BAD_VALUE BM_00_01 +#define TX4927_CONFIG_RAMP 0xe348 +#define TX4927_CONFIG_RAMP_RESERVED_20_63 BM_20_63 +#define TX4927_CONFIG_RAMP_RAMP BM_00_19 +#define TX4927_CONFIG_LIMIT 0xefff + + +/* TX4927 Timer 0 (32-bit registers) */ +#define TX4927_TMR0_BASE 0xf000 +#define TX4927_TMR0_TMTCR0 0xf004 +#define TX4927_TMR0_TMTISR0 0xf008 +#define TX4927_TMR0_TMCPRA0 0xf008 +#define TX4927_TMR0_TMCPRB0 0xf00c +#define TX4927_TMR0_TMITMR0 0xf010 +#define TX4927_TMR0_TMCCDR0 0xf020 +#define TX4927_TMR0_TMPGMR0 0xf030 +#define TX4927_TMR0_TMTRR0 0xf0f0 +#define TX4927_TMR0_LIMIT 0xf0ff + + +/* TX4927 Timer 1 (32-bit registers) */ +#define TX4927_TMR1_BASE 0xf100 +#define TX4927_TMR1_TMTCR1 0xf104 +#define TX4927_TMR1_TMTISR1 0xf108 +#define TX4927_TMR1_TMCPRA1 0xf108 +#define TX4927_TMR1_TMCPRB1 0xf10c +#define TX4927_TMR1_TMITMR1 0xf110 +#define TX4927_TMR1_TMCCDR1 0xf120 +#define TX4927_TMR1_TMPGMR1 0xf130 +#define TX4927_TMR1_TMTRR1 0xf1f0 +#define TX4927_TMR1_LIMIT 0xf1ff + + +/* TX4927 Timer 2 (32-bit registers) */ +#define TX4927_TMR2_BASE 0xf200 +#define TX4927_TMR2_TMTCR2 0xf104 +#define TX4927_TMR2_TMTISR2 0xf208 +#define TX4927_TMR2_TMCPRA2 0xf208 +#define TX4927_TMR2_TMCPRB2 0xf20c +#define TX4927_TMR2_TMITMR2 0xf210 +#define TX4927_TMR2_TMCCDR2 0xf220 +#define TX4927_TMR2_TMPGMR2 0xf230 +#define TX4927_TMR2_TMTRR2 0xf2f0 +#define TX4927_TMR2_LIMIT 0xf2ff + + +/* TX4927 serial port 0 (32-bit registers) */ +#define TX4927_SIO0_BASE 0xf300 +#define TX4927_SIO0_SILCR0 0xf300 +#define TX4927_SIO0_SILCR0_RESERVED_16_31 BM_16_31 +#define TX4927_SIO0_SILCR0_RWUB BM_15_15 +#define TX4927_SIO0_SILCR0_TWUB BM_14_14 +#define TX4927_SIO0_SILCR0_UODE BM_13_13 +#define TX4927_SIO0_SILCR0_RESERVED_07_12 BM_07_12 +#define TX4927_SIO0_SILCR0_SCS BM_05_06 +#define TX4927_SIO0_SILCR0_SCS_IMBUSCLK_IC (~BM_05_06) +#define TX4927_SIO0_SILCR0_SCS_IMBUSCLK_BRG BM_05_05 +#define TX4927_SIO0_SILCR0_SCS_SCLK_EC BM_06_06 +#define TX4927_SIO0_SILCR0_SCS_SCLK_BRG BM_05_06 +#define TX4927_SIO0_SILCR0_UEPS BM_04_04 +#define TX4927_SIO0_SILCR0_UPEN BM_03_03 +#define TX4927_SIO0_SILCR0_USBL BM_02_02 +#define TX4927_SIO0_SILCR0_UMODE BM_00_01 +#define TX4927_SIO0_SILCR0_UMODE_DATA_8_BIT BM_00_01 +#define TX4927_SIO0_SILCR0_UMODE_DATA_7_BIT (~BM_00_01) +#define TX4927_SIO0_SILCR0_UMODE_DATA_8_BIT_MC BM_01_01 +#define TX4927_SIO0_SILCR0_UMODE_DATA_7_BIT_MC BM_00_01 +#define TX4927_SIO0_SIDICR0 0xf304 +#define TX4927_SIO0_SIDICR0_RESERVED_16_31 BM_16_31 +#define TX4927_SIO0_SIDICR0_TDE BM_15_15 +#define TX4927_SIO0_SIDICR0_RDE BM_14_14 +#define TX4927_SIO0_SIDICR0_TIE BM_13_13 +#define TX4927_SIO0_SIDICR0_RIE BM_12_12 +#define TX4927_SIO0_SIDICR0_SPIE BM_11_11 +#define TX4927_SIO0_SIDICR0_CTSAC BM_09_10 +#define TX4927_SIO0_SIDICR0_CTSAC_NONE (~BM_09_10) +#define TX4927_SIO0_SIDICR0_CTSAC_RISE BM_09_09 +#define TX4927_SIO0_SIDICR0_CTSAC_FALL BM_10_10 +#define TX4927_SIO0_SIDICR0_CTSAC_BOTH BM_09_10 +#define TX4927_SIO0_SIDICR0_RESERVED_06_08 BM_06_08 +#define TX4927_SIO0_SIDICR0_STIE BM_00_05 +#define TX4927_SIO0_SIDICR0_STIE_NONE (~BM_00_05) +#define TX4927_SIO0_SIDICR0_STIE_OERS BM_05_05 +#define TX4927_SIO0_SIDICR0_STIE_CTSAC BM_04_04 +#define TX4927_SIO0_SIDICR0_STIE_RBRKD BM_03_03 +#define TX4927_SIO0_SIDICR0_STIE_TRDY BM_02_02 +#define TX4927_SIO0_SIDICR0_STIE_TXALS BM_01_01 +#define TX4927_SIO0_SIDICR0_STIE_UBRKD BM_00_00 +#define TX4927_SIO0_SIDISR0 0xf308 +#define TX4927_SIO0_SIDISR0_RESERVED_16_31 BM_16_31 +#define TX4927_SIO0_SIDISR0_UBRK BM_15_15 +#define TX4927_SIO0_SIDISR0_UVALID BM_14_14 +#define TX4927_SIO0_SIDISR0_UFER BM_13_13 +#define TX4927_SIO0_SIDISR0_UPER BM_12_12 +#define TX4927_SIO0_SIDISR0_UOER BM_11_11 +#define TX4927_SIO0_SIDISR0_ERI BM_10_10 +#define TX4927_SIO0_SIDISR0_TOUT BM_09_09 +#define TX4927_SIO0_SIDISR0_TDIS BM_08_08 +#define TX4927_SIO0_SIDISR0_RDIS BM_07_07 +#define TX4927_SIO0_SIDISR0_STIS BM_06_06 +#define TX4927_SIO0_SIDISR0_RESERVED_05_05 BM_05_05 +#define TX4927_SIO0_SIDISR0_RFDN BM_00_04 +#define TX4927_SIO0_SISCISR0 0xf30c +#define TX4927_SIO0_SISCISR0_RESERVED_06_31 BM_06_31 +#define TX4927_SIO0_SISCISR0_OERS BM_05_05 +#define TX4927_SIO0_SISCISR0_CTSS BM_04_04 +#define TX4927_SIO0_SISCISR0_RBRKD BM_03_03 +#define TX4927_SIO0_SISCISR0_TRDY BM_02_02 +#define TX4927_SIO0_SISCISR0_TXALS BM_01_01 +#define TX4927_SIO0_SISCISR0_UBRKD BM_00_00 +#define TX4927_SIO0_SIFCR0 0xf310 +#define TX4927_SIO0_SIFCR0_RESERVED_16_31 BM_16_31 +#define TX4927_SIO0_SIFCR0_SWRST BM_16_31 +#define TX4927_SIO0_SIFCR0_RESERVED_09_14 BM_09_14 +#define TX4927_SIO0_SIFCR0_RDIL BM_16_31 +#define TX4927_SIO0_SIFCR0_RDIL_BYTES_1 (~BM_07_08) +#define TX4927_SIO0_SIFCR0_RDIL_BYTES_4 BM_07_07 +#define TX4927_SIO0_SIFCR0_RDIL_BYTES_8 BM_08_08 +#define TX4927_SIO0_SIFCR0_RDIL_BYTES_12 BM_07_08 +#define TX4927_SIO0_SIFCR0_RESERVED_05_06 BM_05_06 +#define TX4927_SIO0_SIFCR0_TDIL BM_03_04 +#define TX4927_SIO0_SIFCR0_TDIL_BYTES_1 (~BM_03_04) +#define TX4927_SIO0_SIFCR0_TDIL_BYTES_4 BM_03_03 +#define TX4927_SIO0_SIFCR0_TDIL_BYTES_8 BM_04_04 +#define TX4927_SIO0_SIFCR0_TDIL_BYTES_0 BM_03_04 +#define TX4927_SIO0_SIFCR0_TFRST BM_02_02 +#define TX4927_SIO0_SIFCR0_RFRST BM_01_01 +#define TX4927_SIO0_SIFCR0_FRSTE BM_00_00 +#define TX4927_SIO0_SIFLCR0 0xf314 +#define TX4927_SIO0_SIFLCR0_RESERVED_13_31 BM_13_31 +#define TX4927_SIO0_SIFLCR0_RCS BM_12_12 +#define TX4927_SIO0_SIFLCR0_TES BM_11_11 +#define TX4927_SIO0_SIFLCR0_RESERVED_10_10 BM_10_10 +#define TX4927_SIO0_SIFLCR0_RTSSC BM_09_09 +#define TX4927_SIO0_SIFLCR0_RSDE BM_08_08 +#define TX4927_SIO0_SIFLCR0_TSDE BM_07_07 +#define TX4927_SIO0_SIFLCR0_RESERVED_05_06 BM_05_06 +#define TX4927_SIO0_SIFLCR0_RTSTL BM_01_04 +#define TX4927_SIO0_SIFLCR0_TBRK BM_00_00 +#define TX4927_SIO0_SIBGR0 0xf318 +#define TX4927_SIO0_SIBGR0_RESERVED_10_31 BM_10_31 +#define TX4927_SIO0_SIBGR0_BCLK BM_08_09 +#define TX4927_SIO0_SIBGR0_BCLK_T0 (~BM_08_09) +#define TX4927_SIO0_SIBGR0_BCLK_T2 BM_08_08 +#define TX4927_SIO0_SIBGR0_BCLK_T4 BM_09_09 +#define TX4927_SIO0_SIBGR0_BCLK_T6 BM_08_09 +#define TX4927_SIO0_SIBGR0_BRD BM_00_07 +#define TX4927_SIO0_SITFIF00 0xf31c +#define TX4927_SIO0_SITFIF00_RESERVED_08_31 BM_08_31 +#define TX4927_SIO0_SITFIF00_TXD BM_00_07 +#define TX4927_SIO0_SIRFIFO0 0xf320 +#define TX4927_SIO0_SIRFIFO0_RESERVED_08_31 BM_08_31 +#define TX4927_SIO0_SIRFIFO0_RXD BM_00_07 +#define TX4927_SIO0_SIRFIFO0 0xf320 +#define TX4927_SIO0_LIMIT 0xf3ff + + +/* TX4927 serial port 1 (32-bit registers) */ +#define TX4927_SIO1_BASE 0xf400 +#define TX4927_SIO1_SILCR1 0xf400 +#define TX4927_SIO1_SIDICR1 0xf404 +#define TX4927_SIO1_SIDISR1 0xf408 +#define TX4927_SIO1_SISCISR1 0xf40c +#define TX4927_SIO1_SIFCR1 0xf410 +#define TX4927_SIO1_SIFLCR1 0xf414 +#define TX4927_SIO1_SIBGR1 0xf418 +#define TX4927_SIO1_SITFIF01 0xf41c +#define TX4927_SIO1_SIRFIFO1 0xf420 +#define TX4927_SIO1_LIMIT 0xf4ff + + +/* TX4927 parallel port (32-bit registers) */ +#define TX4927_PIO_BASE 0xf500 +#define TX4927_PIO_PIOD0 0xf500 +#define TX4927_PIO_PIODI 0xf504 +#define TX4927_PIO_PIODIR 0xf508 +#define TX4927_PIO_PIOOD 0xf50c +#define TX4927_PIO_LIMIT 0xf50f + + +/* TX4927 Interrupt Controller (32-bit registers) */ +#define TX4927_IRC_BASE 0xf510 +#define TX4927_IRC_IRFLAG0 0xf510 +#define TX4927_IRC_IRFLAG1 0xf514 +#define TX4927_IRC_IRPOL 0xf518 +#define TX4927_IRC_IRRCNT 0xf51c +#define TX4927_IRC_IRMASKINT 0xf520 +#define TX4927_IRC_IRMASKEXT 0xf524 +#define TX4927_IRC_IRDEN 0xf600 +#define TX4927_IRC_IRDM0 0xf604 +#define TX4927_IRC_IRDM1 0xf608 +#define TX4927_IRC_IRLVL0 0xf610 +#define TX4927_IRC_IRLVL1 0xf614 +#define TX4927_IRC_IRLVL2 0xf618 +#define TX4927_IRC_IRLVL3 0xf61c +#define TX4927_IRC_IRLVL4 0xf620 +#define TX4927_IRC_IRLVL5 0xf624 +#define TX4927_IRC_IRLVL6 0xf628 +#define TX4927_IRC_IRLVL7 0xf62c +#define TX4927_IRC_IRMSK 0xf640 +#define TX4927_IRC_IREDC 0xf660 +#define TX4927_IRC_IRPND 0xf680 +#define TX4927_IRC_IRCS 0xf6a0 +#define TX4927_IRC_LIMIT 0xf6ff + + +/* TX4927 AC-link controller (32-bit registers) */ +#define TX4927_ACLC_BASE 0xf700 +#define TX4927_ACLC_ACCTLEN 0xf700 +#define TX4927_ACLC_ACCTLDIS 0xf704 +#define TX4927_ACLC_ACREGACC 0xf708 +#define TX4927_ACLC_ACINTSTS 0xf710 +#define TX4927_ACLC_ACINTMSTS 0xf714 +#define TX4927_ACLC_ACINTEN 0xf718 +#define TX4927_ACLC_ACINTDIS 0xfR71c +#define TX4927_ACLC_ACSEMAPH 0xf720 +#define TX4927_ACLC_ACGPIDAT 0xf740 +#define TX4927_ACLC_ACGPODAT 0xf744 +#define TX4927_ACLC_ACSLTEN 0xf748 +#define TX4927_ACLC_ACSLTDIS 0xf74c +#define TX4927_ACLC_ACFIFOSTS 0xf750 +#define TX4927_ACLC_ACDMASTS 0xf780 +#define TX4927_ACLC_ACDMASEL 0xf784 +#define TX4927_ACLC_ACAUDODAT 0xf7a0 +#define TX4927_ACLC_ACSURRDAT 0xf7a4 +#define TX4927_ACLC_ACCENTDAT 0xf7a8 +#define TX4927_ACLC_ACLFEDAT 0xf7ac +#define TX4927_ACLC_ACAUDIDAT 0xf7b0 +#define TX4927_ACLC_ACMODODAT 0xf7b8 +#define TX4927_ACLC_ACMODIDAT 0xf7bc +#define TX4927_ACLC_ACREVID 0xf7fc +#define TX4927_ACLC_LIMIT 0xf7ff + + +#define TX4927_REG(x) ((TX4927_BASE)+(x)) + +#define TX4927_RD08( reg ) (*(vu08*)(reg)) +#define TX4927_WR08( reg, val ) ((*(vu08*)(reg))=(val)) + +#define TX4927_RD16( reg ) (*(vu16*)(reg)) +#define TX4927_WR16( reg, val ) ((*(vu16*)(reg))=(val)) + +#define TX4927_RD32( reg ) (*(vu32*)(reg)) +#define TX4927_WR32( reg, val ) ((*(vu32*)(reg))=(val)) + +#define TX4927_RD64( reg ) (*(vu64*)(reg)) +#define TX4927_WR64( reg, val ) ((*(vu64*)(reg))=(val)) + +#define TX4927_RD( reg ) TX4927_RD32( reg ) +#define TX4927_WR( reg, val ) TX4927_WR32( reg, val ) + + + + + +#define MI8259_IRQ_ISA_RAW_BEG 0 /* optional backplane i8259 */ +#define MI8259_IRQ_ISA_RAW_END 15 +#define TX4927_IRQ_CP0_RAW_BEG 0 /* tx4927 cpu built-in cp0 */ +#define TX4927_IRQ_CP0_RAW_END 7 +#define TX4927_IRQ_PIC_RAW_BEG 0 /* tx4927 cpu build-in pic */ +#define TX4927_IRQ_PIC_RAW_END 31 + + +#define MI8259_IRQ_ISA_BEG MI8259_IRQ_ISA_RAW_BEG /* 0 */ +#define MI8259_IRQ_ISA_END MI8259_IRQ_ISA_RAW_END /* 15 */ + +#define TX4927_IRQ_CP0_BEG ((MI8259_IRQ_ISA_END+1)+TX4927_IRQ_CP0_RAW_BEG) /* 16 */ +#define TX4927_IRQ_CP0_END ((MI8259_IRQ_ISA_END+1)+TX4927_IRQ_CP0_RAW_END) /* 23 */ + +#define TX4927_IRQ_PIC_BEG ((TX4927_IRQ_CP0_END+1)+TX4927_IRQ_PIC_RAW_BEG) /* 24 */ +#define TX4927_IRQ_PIC_END ((TX4927_IRQ_CP0_END+1)+TX4927_IRQ_PIC_RAW_END) /* 55 */ + + +#define TX4927_IRQ_USER0 (TX4927_IRQ_CP0_BEG+0) +#define TX4927_IRQ_USER1 (TX4927_IRQ_CP0_BEG+1) +#define TX4927_IRQ_NEST_PIC_ON_CP0 (TX4927_IRQ_CP0_BEG+2) +#define TX4927_IRQ_CPU_TIMER (TX4927_IRQ_CP0_BEG+7) + +#define TX4927_IRQ_NEST_EXT_ON_PIC (TX4927_IRQ_PIC_BEG+3) + +#endif /* __ASM_TX4927_TX4927_H */ diff -Nru a/include/asm-mips/tx4927/tx4927_mips.h b/include/asm-mips/tx4927/tx4927_mips.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/tx4927/tx4927_mips.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,4177 @@ +/* + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2001-2002 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. + */ +#ifndef __ASM_TX4927_TX4927_MIPS_H +#define __ASM_TX4927_TX4927_MIPS_H + +#ifndef __ASSEMBLY__ + +static inline void asm_wait(void) +{ + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +#define reg_rd08(r) ((u8 )(*((vu8 *)(r)))) +#define reg_rd16(r) ((u16)(*((vu16*)(r)))) +#define reg_rd32(r) ((u32)(*((vu32*)(r)))) +#define reg_rd64(r) ((u64)(*((vu64*)(r)))) + +#define reg_wr08(r,v) ((*((vu8 *)(r)))=((u8 )(v))) +#define reg_wr16(r,v) ((*((vu16*)(r)))=((u16)(v))) +#define reg_wr32(r,v) ((*((vu32*)(r)))=((u32)(v))) +#define reg_wr64(r,v) ((*((vu64*)(r)))=((u64)(v))) + +typedef volatile __signed char vs8; +typedef volatile unsigned char vu8; + +typedef volatile __signed short vs16; +typedef volatile unsigned short vu16; + +typedef volatile __signed int vs32; +typedef volatile unsigned int vu32; + +typedef s8 s08; +typedef vs8 vs08; + +typedef u8 u08; +typedef vu8 vu08; + + +#if (_MIPS_SZLONG == 64) + +typedef volatile __signed__ long vs64; +typedef volatile unsigned long vu64; + +#else + +typedef volatile __signed__ long long vs64; +typedef volatile unsigned long long vu64; + +#endif + + +#define BM_00_00 0x0000000000000001 +#define BM_01_00 0x0000000000000003 +#define BM_00_01 BM_01_00 +#define BM_02_00 0x0000000000000007 +#define BM_00_02 BM_02_00 +#define BM_03_00 0x000000000000000f +#define BM_00_03 BM_03_00 +#define BM_04_00 0x000000000000001f +#define BM_00_04 BM_04_00 +#define BM_05_00 0x000000000000003f +#define BM_00_05 BM_05_00 +#define BM_06_00 0x000000000000007f +#define BM_00_06 BM_06_00 +#define BM_07_00 0x00000000000000ff +#define BM_00_07 BM_07_00 +#define BM_08_00 0x00000000000001ff +#define BM_00_08 BM_08_00 +#define BM_09_00 0x00000000000003ff +#define BM_00_09 BM_09_00 +#define BM_10_00 0x00000000000007ff +#define BM_00_10 BM_10_00 +#define BM_11_00 0x0000000000000fff +#define BM_00_11 BM_11_00 +#define BM_12_00 0x0000000000001fff +#define BM_00_12 BM_12_00 +#define BM_13_00 0x0000000000003fff +#define BM_00_13 BM_13_00 +#define BM_14_00 0x0000000000007fff +#define BM_00_14 BM_14_00 +#define BM_15_00 0x000000000000ffff +#define BM_00_15 BM_15_00 +#define BM_16_00 0x000000000001ffff +#define BM_00_16 BM_16_00 +#define BM_17_00 0x000000000003ffff +#define BM_00_17 BM_17_00 +#define BM_18_00 0x000000000007ffff +#define BM_00_18 BM_18_00 +#define BM_19_00 0x00000000000fffff +#define BM_00_19 BM_19_00 +#define BM_20_00 0x00000000001fffff +#define BM_00_20 BM_20_00 +#define BM_21_00 0x00000000003fffff +#define BM_00_21 BM_21_00 +#define BM_22_00 0x00000000007fffff +#define BM_00_22 BM_22_00 +#define BM_23_00 0x0000000000ffffff +#define BM_00_23 BM_23_00 +#define BM_24_00 0x0000000001ffffff +#define BM_00_24 BM_24_00 +#define BM_25_00 0x0000000003ffffff +#define BM_00_25 BM_25_00 +#define BM_26_00 0x0000000007ffffff +#define BM_00_26 BM_26_00 +#define BM_27_00 0x000000000fffffff +#define BM_00_27 BM_27_00 +#define BM_28_00 0x000000001fffffff +#define BM_00_28 BM_28_00 +#define BM_29_00 0x000000003fffffff +#define BM_00_29 BM_29_00 +#define BM_30_00 0x000000007fffffff +#define BM_00_30 BM_30_00 +#define BM_31_00 0x00000000ffffffff +#define BM_00_31 BM_31_00 +#define BM_32_00 0x00000001ffffffff +#define BM_00_32 BM_32_00 +#define BM_33_00 0x00000003ffffffff +#define BM_00_33 BM_33_00 +#define BM_34_00 0x00000007ffffffff +#define BM_00_34 BM_34_00 +#define BM_35_00 0x0000000fffffffff +#define BM_00_35 BM_35_00 +#define BM_36_00 0x0000001fffffffff +#define BM_00_36 BM_36_00 +#define BM_37_00 0x0000003fffffffff +#define BM_00_37 BM_37_00 +#define BM_38_00 0x0000007fffffffff +#define BM_00_38 BM_38_00 +#define BM_39_00 0x000000ffffffffff +#define BM_00_39 BM_39_00 +#define BM_40_00 0x000001ffffffffff +#define BM_00_40 BM_40_00 +#define BM_41_00 0x000003ffffffffff +#define BM_00_41 BM_41_00 +#define BM_42_00 0x000007ffffffffff +#define BM_00_42 BM_42_00 +#define BM_43_00 0x00000fffffffffff +#define BM_00_43 BM_43_00 +#define BM_44_00 0x00001fffffffffff +#define BM_00_44 BM_44_00 +#define BM_45_00 0x00003fffffffffff +#define BM_00_45 BM_45_00 +#define BM_46_00 0x00007fffffffffff +#define BM_00_46 BM_46_00 +#define BM_47_00 0x0000ffffffffffff +#define BM_00_47 BM_47_00 +#define BM_48_00 0x0001ffffffffffff +#define BM_00_48 BM_48_00 +#define BM_49_00 0x0003ffffffffffff +#define BM_00_49 BM_49_00 +#define BM_50_00 0x0007ffffffffffff +#define BM_00_50 BM_50_00 +#define BM_51_00 0x000fffffffffffff +#define BM_00_51 BM_51_00 +#define BM_52_00 0x001fffffffffffff +#define BM_00_52 BM_52_00 +#define BM_53_00 0x003fffffffffffff +#define BM_00_53 BM_53_00 +#define BM_54_00 0x007fffffffffffff +#define BM_00_54 BM_54_00 +#define BM_55_00 0x00ffffffffffffff +#define BM_00_55 BM_55_00 +#define BM_56_00 0x01ffffffffffffff +#define BM_00_56 BM_56_00 +#define BM_57_00 0x03ffffffffffffff +#define BM_00_57 BM_57_00 +#define BM_58_00 0x07ffffffffffffff +#define BM_00_58 BM_58_00 +#define BM_59_00 0x0fffffffffffffff +#define BM_00_59 BM_59_00 +#define BM_60_00 0x1fffffffffffffff +#define BM_00_60 BM_60_00 +#define BM_61_00 0x3fffffffffffffff +#define BM_00_61 BM_61_00 +#define BM_62_00 0x7fffffffffffffff +#define BM_00_62 BM_62_00 +#define BM_63_00 0xffffffffffffffff +#define BM_00_63 BM_63_00 +#define BM_01_01 0x0000000000000002 +#define BM_02_01 0x0000000000000006 +#define BM_01_02 BM_02_01 +#define BM_03_01 0x000000000000000e +#define BM_01_03 BM_03_01 +#define BM_04_01 0x000000000000001e +#define BM_01_04 BM_04_01 +#define BM_05_01 0x000000000000003e +#define BM_01_05 BM_05_01 +#define BM_06_01 0x000000000000007e +#define BM_01_06 BM_06_01 +#define BM_07_01 0x00000000000000fe +#define BM_01_07 BM_07_01 +#define BM_08_01 0x00000000000001fe +#define BM_01_08 BM_08_01 +#define BM_09_01 0x00000000000003fe +#define BM_01_09 BM_09_01 +#define BM_10_01 0x00000000000007fe +#define BM_01_10 BM_10_01 +#define BM_11_01 0x0000000000000ffe +#define BM_01_11 BM_11_01 +#define BM_12_01 0x0000000000001ffe +#define BM_01_12 BM_12_01 +#define BM_13_01 0x0000000000003ffe +#define BM_01_13 BM_13_01 +#define BM_14_01 0x0000000000007ffe +#define BM_01_14 BM_14_01 +#define BM_15_01 0x000000000000fffe +#define BM_01_15 BM_15_01 +#define BM_16_01 0x000000000001fffe +#define BM_01_16 BM_16_01 +#define BM_17_01 0x000000000003fffe +#define BM_01_17 BM_17_01 +#define BM_18_01 0x000000000007fffe +#define BM_01_18 BM_18_01 +#define BM_19_01 0x00000000000ffffe +#define BM_01_19 BM_19_01 +#define BM_20_01 0x00000000001ffffe +#define BM_01_20 BM_20_01 +#define BM_21_01 0x00000000003ffffe +#define BM_01_21 BM_21_01 +#define BM_22_01 0x00000000007ffffe +#define BM_01_22 BM_22_01 +#define BM_23_01 0x0000000000fffffe +#define BM_01_23 BM_23_01 +#define BM_24_01 0x0000000001fffffe +#define BM_01_24 BM_24_01 +#define BM_25_01 0x0000000003fffffe +#define BM_01_25 BM_25_01 +#define BM_26_01 0x0000000007fffffe +#define BM_01_26 BM_26_01 +#define BM_27_01 0x000000000ffffffe +#define BM_01_27 BM_27_01 +#define BM_28_01 0x000000001ffffffe +#define BM_01_28 BM_28_01 +#define BM_29_01 0x000000003ffffffe +#define BM_01_29 BM_29_01 +#define BM_30_01 0x000000007ffffffe +#define BM_01_30 BM_30_01 +#define BM_31_01 0x00000000fffffffe +#define BM_01_31 BM_31_01 +#define BM_32_01 0x00000001fffffffe +#define BM_01_32 BM_32_01 +#define BM_33_01 0x00000003fffffffe +#define BM_01_33 BM_33_01 +#define BM_34_01 0x00000007fffffffe +#define BM_01_34 BM_34_01 +#define BM_35_01 0x0000000ffffffffe +#define BM_01_35 BM_35_01 +#define BM_36_01 0x0000001ffffffffe +#define BM_01_36 BM_36_01 +#define BM_37_01 0x0000003ffffffffe +#define BM_01_37 BM_37_01 +#define BM_38_01 0x0000007ffffffffe +#define BM_01_38 BM_38_01 +#define BM_39_01 0x000000fffffffffe +#define BM_01_39 BM_39_01 +#define BM_40_01 0x000001fffffffffe +#define BM_01_40 BM_40_01 +#define BM_41_01 0x000003fffffffffe +#define BM_01_41 BM_41_01 +#define BM_42_01 0x000007fffffffffe +#define BM_01_42 BM_42_01 +#define BM_43_01 0x00000ffffffffffe +#define BM_01_43 BM_43_01 +#define BM_44_01 0x00001ffffffffffe +#define BM_01_44 BM_44_01 +#define BM_45_01 0x00003ffffffffffe +#define BM_01_45 BM_45_01 +#define BM_46_01 0x00007ffffffffffe +#define BM_01_46 BM_46_01 +#define BM_47_01 0x0000fffffffffffe +#define BM_01_47 BM_47_01 +#define BM_48_01 0x0001fffffffffffe +#define BM_01_48 BM_48_01 +#define BM_49_01 0x0003fffffffffffe +#define BM_01_49 BM_49_01 +#define BM_50_01 0x0007fffffffffffe +#define BM_01_50 BM_50_01 +#define BM_51_01 0x000ffffffffffffe +#define BM_01_51 BM_51_01 +#define BM_52_01 0x001ffffffffffffe +#define BM_01_52 BM_52_01 +#define BM_53_01 0x003ffffffffffffe +#define BM_01_53 BM_53_01 +#define BM_54_01 0x007ffffffffffffe +#define BM_01_54 BM_54_01 +#define BM_55_01 0x00fffffffffffffe +#define BM_01_55 BM_55_01 +#define BM_56_01 0x01fffffffffffffe +#define BM_01_56 BM_56_01 +#define BM_57_01 0x03fffffffffffffe +#define BM_01_57 BM_57_01 +#define BM_58_01 0x07fffffffffffffe +#define BM_01_58 BM_58_01 +#define BM_59_01 0x0ffffffffffffffe +#define BM_01_59 BM_59_01 +#define BM_60_01 0x1ffffffffffffffe +#define BM_01_60 BM_60_01 +#define BM_61_01 0x3ffffffffffffffe +#define BM_01_61 BM_61_01 +#define BM_62_01 0x7ffffffffffffffe +#define BM_01_62 BM_62_01 +#define BM_63_01 0xfffffffffffffffe +#define BM_01_63 BM_63_01 +#define BM_02_02 0x0000000000000004 +#define BM_03_02 0x000000000000000c +#define BM_02_03 BM_03_02 +#define BM_04_02 0x000000000000001c +#define BM_02_04 BM_04_02 +#define BM_05_02 0x000000000000003c +#define BM_02_05 BM_05_02 +#define BM_06_02 0x000000000000007c +#define BM_02_06 BM_06_02 +#define BM_07_02 0x00000000000000fc +#define BM_02_07 BM_07_02 +#define BM_08_02 0x00000000000001fc +#define BM_02_08 BM_08_02 +#define BM_09_02 0x00000000000003fc +#define BM_02_09 BM_09_02 +#define BM_10_02 0x00000000000007fc +#define BM_02_10 BM_10_02 +#define BM_11_02 0x0000000000000ffc +#define BM_02_11 BM_11_02 +#define BM_12_02 0x0000000000001ffc +#define BM_02_12 BM_12_02 +#define BM_13_02 0x0000000000003ffc +#define BM_02_13 BM_13_02 +#define BM_14_02 0x0000000000007ffc +#define BM_02_14 BM_14_02 +#define BM_15_02 0x000000000000fffc +#define BM_02_15 BM_15_02 +#define BM_16_02 0x000000000001fffc +#define BM_02_16 BM_16_02 +#define BM_17_02 0x000000000003fffc +#define BM_02_17 BM_17_02 +#define BM_18_02 0x000000000007fffc +#define BM_02_18 BM_18_02 +#define BM_19_02 0x00000000000ffffc +#define BM_02_19 BM_19_02 +#define BM_20_02 0x00000000001ffffc +#define BM_02_20 BM_20_02 +#define BM_21_02 0x00000000003ffffc +#define BM_02_21 BM_21_02 +#define BM_22_02 0x00000000007ffffc +#define BM_02_22 BM_22_02 +#define BM_23_02 0x0000000000fffffc +#define BM_02_23 BM_23_02 +#define BM_24_02 0x0000000001fffffc +#define BM_02_24 BM_24_02 +#define BM_25_02 0x0000000003fffffc +#define BM_02_25 BM_25_02 +#define BM_26_02 0x0000000007fffffc +#define BM_02_26 BM_26_02 +#define BM_27_02 0x000000000ffffffc +#define BM_02_27 BM_27_02 +#define BM_28_02 0x000000001ffffffc +#define BM_02_28 BM_28_02 +#define BM_29_02 0x000000003ffffffc +#define BM_02_29 BM_29_02 +#define BM_30_02 0x000000007ffffffc +#define BM_02_30 BM_30_02 +#define BM_31_02 0x00000000fffffffc +#define BM_02_31 BM_31_02 +#define BM_32_02 0x00000001fffffffc +#define BM_02_32 BM_32_02 +#define BM_33_02 0x00000003fffffffc +#define BM_02_33 BM_33_02 +#define BM_34_02 0x00000007fffffffc +#define BM_02_34 BM_34_02 +#define BM_35_02 0x0000000ffffffffc +#define BM_02_35 BM_35_02 +#define BM_36_02 0x0000001ffffffffc +#define BM_02_36 BM_36_02 +#define BM_37_02 0x0000003ffffffffc +#define BM_02_37 BM_37_02 +#define BM_38_02 0x0000007ffffffffc +#define BM_02_38 BM_38_02 +#define BM_39_02 0x000000fffffffffc +#define BM_02_39 BM_39_02 +#define BM_40_02 0x000001fffffffffc +#define BM_02_40 BM_40_02 +#define BM_41_02 0x000003fffffffffc +#define BM_02_41 BM_41_02 +#define BM_42_02 0x000007fffffffffc +#define BM_02_42 BM_42_02 +#define BM_43_02 0x00000ffffffffffc +#define BM_02_43 BM_43_02 +#define BM_44_02 0x00001ffffffffffc +#define BM_02_44 BM_44_02 +#define BM_45_02 0x00003ffffffffffc +#define BM_02_45 BM_45_02 +#define BM_46_02 0x00007ffffffffffc +#define BM_02_46 BM_46_02 +#define BM_47_02 0x0000fffffffffffc +#define BM_02_47 BM_47_02 +#define BM_48_02 0x0001fffffffffffc +#define BM_02_48 BM_48_02 +#define BM_49_02 0x0003fffffffffffc +#define BM_02_49 BM_49_02 +#define BM_50_02 0x0007fffffffffffc +#define BM_02_50 BM_50_02 +#define BM_51_02 0x000ffffffffffffc +#define BM_02_51 BM_51_02 +#define BM_52_02 0x001ffffffffffffc +#define BM_02_52 BM_52_02 +#define BM_53_02 0x003ffffffffffffc +#define BM_02_53 BM_53_02 +#define BM_54_02 0x007ffffffffffffc +#define BM_02_54 BM_54_02 +#define BM_55_02 0x00fffffffffffffc +#define BM_02_55 BM_55_02 +#define BM_56_02 0x01fffffffffffffc +#define BM_02_56 BM_56_02 +#define BM_57_02 0x03fffffffffffffc +#define BM_02_57 BM_57_02 +#define BM_58_02 0x07fffffffffffffc +#define BM_02_58 BM_58_02 +#define BM_59_02 0x0ffffffffffffffc +#define BM_02_59 BM_59_02 +#define BM_60_02 0x1ffffffffffffffc +#define BM_02_60 BM_60_02 +#define BM_61_02 0x3ffffffffffffffc +#define BM_02_61 BM_61_02 +#define BM_62_02 0x7ffffffffffffffc +#define BM_02_62 BM_62_02 +#define BM_63_02 0xfffffffffffffffc +#define BM_02_63 BM_63_02 +#define BM_03_03 0x0000000000000008 +#define BM_04_03 0x0000000000000018 +#define BM_03_04 BM_04_03 +#define BM_05_03 0x0000000000000038 +#define BM_03_05 BM_05_03 +#define BM_06_03 0x0000000000000078 +#define BM_03_06 BM_06_03 +#define BM_07_03 0x00000000000000f8 +#define BM_03_07 BM_07_03 +#define BM_08_03 0x00000000000001f8 +#define BM_03_08 BM_08_03 +#define BM_09_03 0x00000000000003f8 +#define BM_03_09 BM_09_03 +#define BM_10_03 0x00000000000007f8 +#define BM_03_10 BM_10_03 +#define BM_11_03 0x0000000000000ff8 +#define BM_03_11 BM_11_03 +#define BM_12_03 0x0000000000001ff8 +#define BM_03_12 BM_12_03 +#define BM_13_03 0x0000000000003ff8 +#define BM_03_13 BM_13_03 +#define BM_14_03 0x0000000000007ff8 +#define BM_03_14 BM_14_03 +#define BM_15_03 0x000000000000fff8 +#define BM_03_15 BM_15_03 +#define BM_16_03 0x000000000001fff8 +#define BM_03_16 BM_16_03 +#define BM_17_03 0x000000000003fff8 +#define BM_03_17 BM_17_03 +#define BM_18_03 0x000000000007fff8 +#define BM_03_18 BM_18_03 +#define BM_19_03 0x00000000000ffff8 +#define BM_03_19 BM_19_03 +#define BM_20_03 0x00000000001ffff8 +#define BM_03_20 BM_20_03 +#define BM_21_03 0x00000000003ffff8 +#define BM_03_21 BM_21_03 +#define BM_22_03 0x00000000007ffff8 +#define BM_03_22 BM_22_03 +#define BM_23_03 0x0000000000fffff8 +#define BM_03_23 BM_23_03 +#define BM_24_03 0x0000000001fffff8 +#define BM_03_24 BM_24_03 +#define BM_25_03 0x0000000003fffff8 +#define BM_03_25 BM_25_03 +#define BM_26_03 0x0000000007fffff8 +#define BM_03_26 BM_26_03 +#define BM_27_03 0x000000000ffffff8 +#define BM_03_27 BM_27_03 +#define BM_28_03 0x000000001ffffff8 +#define BM_03_28 BM_28_03 +#define BM_29_03 0x000000003ffffff8 +#define BM_03_29 BM_29_03 +#define BM_30_03 0x000000007ffffff8 +#define BM_03_30 BM_30_03 +#define BM_31_03 0x00000000fffffff8 +#define BM_03_31 BM_31_03 +#define BM_32_03 0x00000001fffffff8 +#define BM_03_32 BM_32_03 +#define BM_33_03 0x00000003fffffff8 +#define BM_03_33 BM_33_03 +#define BM_34_03 0x00000007fffffff8 +#define BM_03_34 BM_34_03 +#define BM_35_03 0x0000000ffffffff8 +#define BM_03_35 BM_35_03 +#define BM_36_03 0x0000001ffffffff8 +#define BM_03_36 BM_36_03 +#define BM_37_03 0x0000003ffffffff8 +#define BM_03_37 BM_37_03 +#define BM_38_03 0x0000007ffffffff8 +#define BM_03_38 BM_38_03 +#define BM_39_03 0x000000fffffffff8 +#define BM_03_39 BM_39_03 +#define BM_40_03 0x000001fffffffff8 +#define BM_03_40 BM_40_03 +#define BM_41_03 0x000003fffffffff8 +#define BM_03_41 BM_41_03 +#define BM_42_03 0x000007fffffffff8 +#define BM_03_42 BM_42_03 +#define BM_43_03 0x00000ffffffffff8 +#define BM_03_43 BM_43_03 +#define BM_44_03 0x00001ffffffffff8 +#define BM_03_44 BM_44_03 +#define BM_45_03 0x00003ffffffffff8 +#define BM_03_45 BM_45_03 +#define BM_46_03 0x00007ffffffffff8 +#define BM_03_46 BM_46_03 +#define BM_47_03 0x0000fffffffffff8 +#define BM_03_47 BM_47_03 +#define BM_48_03 0x0001fffffffffff8 +#define BM_03_48 BM_48_03 +#define BM_49_03 0x0003fffffffffff8 +#define BM_03_49 BM_49_03 +#define BM_50_03 0x0007fffffffffff8 +#define BM_03_50 BM_50_03 +#define BM_51_03 0x000ffffffffffff8 +#define BM_03_51 BM_51_03 +#define BM_52_03 0x001ffffffffffff8 +#define BM_03_52 BM_52_03 +#define BM_53_03 0x003ffffffffffff8 +#define BM_03_53 BM_53_03 +#define BM_54_03 0x007ffffffffffff8 +#define BM_03_54 BM_54_03 +#define BM_55_03 0x00fffffffffffff8 +#define BM_03_55 BM_55_03 +#define BM_56_03 0x01fffffffffffff8 +#define BM_03_56 BM_56_03 +#define BM_57_03 0x03fffffffffffff8 +#define BM_03_57 BM_57_03 +#define BM_58_03 0x07fffffffffffff8 +#define BM_03_58 BM_58_03 +#define BM_59_03 0x0ffffffffffffff8 +#define BM_03_59 BM_59_03 +#define BM_60_03 0x1ffffffffffffff8 +#define BM_03_60 BM_60_03 +#define BM_61_03 0x3ffffffffffffff8 +#define BM_03_61 BM_61_03 +#define BM_62_03 0x7ffffffffffffff8 +#define BM_03_62 BM_62_03 +#define BM_63_03 0xfffffffffffffff8 +#define BM_03_63 BM_63_03 +#define BM_04_04 0x0000000000000010 +#define BM_05_04 0x0000000000000030 +#define BM_04_05 BM_05_04 +#define BM_06_04 0x0000000000000070 +#define BM_04_06 BM_06_04 +#define BM_07_04 0x00000000000000f0 +#define BM_04_07 BM_07_04 +#define BM_08_04 0x00000000000001f0 +#define BM_04_08 BM_08_04 +#define BM_09_04 0x00000000000003f0 +#define BM_04_09 BM_09_04 +#define BM_10_04 0x00000000000007f0 +#define BM_04_10 BM_10_04 +#define BM_11_04 0x0000000000000ff0 +#define BM_04_11 BM_11_04 +#define BM_12_04 0x0000000000001ff0 +#define BM_04_12 BM_12_04 +#define BM_13_04 0x0000000000003ff0 +#define BM_04_13 BM_13_04 +#define BM_14_04 0x0000000000007ff0 +#define BM_04_14 BM_14_04 +#define BM_15_04 0x000000000000fff0 +#define BM_04_15 BM_15_04 +#define BM_16_04 0x000000000001fff0 +#define BM_04_16 BM_16_04 +#define BM_17_04 0x000000000003fff0 +#define BM_04_17 BM_17_04 +#define BM_18_04 0x000000000007fff0 +#define BM_04_18 BM_18_04 +#define BM_19_04 0x00000000000ffff0 +#define BM_04_19 BM_19_04 +#define BM_20_04 0x00000000001ffff0 +#define BM_04_20 BM_20_04 +#define BM_21_04 0x00000000003ffff0 +#define BM_04_21 BM_21_04 +#define BM_22_04 0x00000000007ffff0 +#define BM_04_22 BM_22_04 +#define BM_23_04 0x0000000000fffff0 +#define BM_04_23 BM_23_04 +#define BM_24_04 0x0000000001fffff0 +#define BM_04_24 BM_24_04 +#define BM_25_04 0x0000000003fffff0 +#define BM_04_25 BM_25_04 +#define BM_26_04 0x0000000007fffff0 +#define BM_04_26 BM_26_04 +#define BM_27_04 0x000000000ffffff0 +#define BM_04_27 BM_27_04 +#define BM_28_04 0x000000001ffffff0 +#define BM_04_28 BM_28_04 +#define BM_29_04 0x000000003ffffff0 +#define BM_04_29 BM_29_04 +#define BM_30_04 0x000000007ffffff0 +#define BM_04_30 BM_30_04 +#define BM_31_04 0x00000000fffffff0 +#define BM_04_31 BM_31_04 +#define BM_32_04 0x00000001fffffff0 +#define BM_04_32 BM_32_04 +#define BM_33_04 0x00000003fffffff0 +#define BM_04_33 BM_33_04 +#define BM_34_04 0x00000007fffffff0 +#define BM_04_34 BM_34_04 +#define BM_35_04 0x0000000ffffffff0 +#define BM_04_35 BM_35_04 +#define BM_36_04 0x0000001ffffffff0 +#define BM_04_36 BM_36_04 +#define BM_37_04 0x0000003ffffffff0 +#define BM_04_37 BM_37_04 +#define BM_38_04 0x0000007ffffffff0 +#define BM_04_38 BM_38_04 +#define BM_39_04 0x000000fffffffff0 +#define BM_04_39 BM_39_04 +#define BM_40_04 0x000001fffffffff0 +#define BM_04_40 BM_40_04 +#define BM_41_04 0x000003fffffffff0 +#define BM_04_41 BM_41_04 +#define BM_42_04 0x000007fffffffff0 +#define BM_04_42 BM_42_04 +#define BM_43_04 0x00000ffffffffff0 +#define BM_04_43 BM_43_04 +#define BM_44_04 0x00001ffffffffff0 +#define BM_04_44 BM_44_04 +#define BM_45_04 0x00003ffffffffff0 +#define BM_04_45 BM_45_04 +#define BM_46_04 0x00007ffffffffff0 +#define BM_04_46 BM_46_04 +#define BM_47_04 0x0000fffffffffff0 +#define BM_04_47 BM_47_04 +#define BM_48_04 0x0001fffffffffff0 +#define BM_04_48 BM_48_04 +#define BM_49_04 0x0003fffffffffff0 +#define BM_04_49 BM_49_04 +#define BM_50_04 0x0007fffffffffff0 +#define BM_04_50 BM_50_04 +#define BM_51_04 0x000ffffffffffff0 +#define BM_04_51 BM_51_04 +#define BM_52_04 0x001ffffffffffff0 +#define BM_04_52 BM_52_04 +#define BM_53_04 0x003ffffffffffff0 +#define BM_04_53 BM_53_04 +#define BM_54_04 0x007ffffffffffff0 +#define BM_04_54 BM_54_04 +#define BM_55_04 0x00fffffffffffff0 +#define BM_04_55 BM_55_04 +#define BM_56_04 0x01fffffffffffff0 +#define BM_04_56 BM_56_04 +#define BM_57_04 0x03fffffffffffff0 +#define BM_04_57 BM_57_04 +#define BM_58_04 0x07fffffffffffff0 +#define BM_04_58 BM_58_04 +#define BM_59_04 0x0ffffffffffffff0 +#define BM_04_59 BM_59_04 +#define BM_60_04 0x1ffffffffffffff0 +#define BM_04_60 BM_60_04 +#define BM_61_04 0x3ffffffffffffff0 +#define BM_04_61 BM_61_04 +#define BM_62_04 0x7ffffffffffffff0 +#define BM_04_62 BM_62_04 +#define BM_63_04 0xfffffffffffffff0 +#define BM_04_63 BM_63_04 +#define BM_05_05 0x0000000000000020 +#define BM_06_05 0x0000000000000060 +#define BM_05_06 BM_06_05 +#define BM_07_05 0x00000000000000e0 +#define BM_05_07 BM_07_05 +#define BM_08_05 0x00000000000001e0 +#define BM_05_08 BM_08_05 +#define BM_09_05 0x00000000000003e0 +#define BM_05_09 BM_09_05 +#define BM_10_05 0x00000000000007e0 +#define BM_05_10 BM_10_05 +#define BM_11_05 0x0000000000000fe0 +#define BM_05_11 BM_11_05 +#define BM_12_05 0x0000000000001fe0 +#define BM_05_12 BM_12_05 +#define BM_13_05 0x0000000000003fe0 +#define BM_05_13 BM_13_05 +#define BM_14_05 0x0000000000007fe0 +#define BM_05_14 BM_14_05 +#define BM_15_05 0x000000000000ffe0 +#define BM_05_15 BM_15_05 +#define BM_16_05 0x000000000001ffe0 +#define BM_05_16 BM_16_05 +#define BM_17_05 0x000000000003ffe0 +#define BM_05_17 BM_17_05 +#define BM_18_05 0x000000000007ffe0 +#define BM_05_18 BM_18_05 +#define BM_19_05 0x00000000000fffe0 +#define BM_05_19 BM_19_05 +#define BM_20_05 0x00000000001fffe0 +#define BM_05_20 BM_20_05 +#define BM_21_05 0x00000000003fffe0 +#define BM_05_21 BM_21_05 +#define BM_22_05 0x00000000007fffe0 +#define BM_05_22 BM_22_05 +#define BM_23_05 0x0000000000ffffe0 +#define BM_05_23 BM_23_05 +#define BM_24_05 0x0000000001ffffe0 +#define BM_05_24 BM_24_05 +#define BM_25_05 0x0000000003ffffe0 +#define BM_05_25 BM_25_05 +#define BM_26_05 0x0000000007ffffe0 +#define BM_05_26 BM_26_05 +#define BM_27_05 0x000000000fffffe0 +#define BM_05_27 BM_27_05 +#define BM_28_05 0x000000001fffffe0 +#define BM_05_28 BM_28_05 +#define BM_29_05 0x000000003fffffe0 +#define BM_05_29 BM_29_05 +#define BM_30_05 0x000000007fffffe0 +#define BM_05_30 BM_30_05 +#define BM_31_05 0x00000000ffffffe0 +#define BM_05_31 BM_31_05 +#define BM_32_05 0x00000001ffffffe0 +#define BM_05_32 BM_32_05 +#define BM_33_05 0x00000003ffffffe0 +#define BM_05_33 BM_33_05 +#define BM_34_05 0x00000007ffffffe0 +#define BM_05_34 BM_34_05 +#define BM_35_05 0x0000000fffffffe0 +#define BM_05_35 BM_35_05 +#define BM_36_05 0x0000001fffffffe0 +#define BM_05_36 BM_36_05 +#define BM_37_05 0x0000003fffffffe0 +#define BM_05_37 BM_37_05 +#define BM_38_05 0x0000007fffffffe0 +#define BM_05_38 BM_38_05 +#define BM_39_05 0x000000ffffffffe0 +#define BM_05_39 BM_39_05 +#define BM_40_05 0x000001ffffffffe0 +#define BM_05_40 BM_40_05 +#define BM_41_05 0x000003ffffffffe0 +#define BM_05_41 BM_41_05 +#define BM_42_05 0x000007ffffffffe0 +#define BM_05_42 BM_42_05 +#define BM_43_05 0x00000fffffffffe0 +#define BM_05_43 BM_43_05 +#define BM_44_05 0x00001fffffffffe0 +#define BM_05_44 BM_44_05 +#define BM_45_05 0x00003fffffffffe0 +#define BM_05_45 BM_45_05 +#define BM_46_05 0x00007fffffffffe0 +#define BM_05_46 BM_46_05 +#define BM_47_05 0x0000ffffffffffe0 +#define BM_05_47 BM_47_05 +#define BM_48_05 0x0001ffffffffffe0 +#define BM_05_48 BM_48_05 +#define BM_49_05 0x0003ffffffffffe0 +#define BM_05_49 BM_49_05 +#define BM_50_05 0x0007ffffffffffe0 +#define BM_05_50 BM_50_05 +#define BM_51_05 0x000fffffffffffe0 +#define BM_05_51 BM_51_05 +#define BM_52_05 0x001fffffffffffe0 +#define BM_05_52 BM_52_05 +#define BM_53_05 0x003fffffffffffe0 +#define BM_05_53 BM_53_05 +#define BM_54_05 0x007fffffffffffe0 +#define BM_05_54 BM_54_05 +#define BM_55_05 0x00ffffffffffffe0 +#define BM_05_55 BM_55_05 +#define BM_56_05 0x01ffffffffffffe0 +#define BM_05_56 BM_56_05 +#define BM_57_05 0x03ffffffffffffe0 +#define BM_05_57 BM_57_05 +#define BM_58_05 0x07ffffffffffffe0 +#define BM_05_58 BM_58_05 +#define BM_59_05 0x0fffffffffffffe0 +#define BM_05_59 BM_59_05 +#define BM_60_05 0x1fffffffffffffe0 +#define BM_05_60 BM_60_05 +#define BM_61_05 0x3fffffffffffffe0 +#define BM_05_61 BM_61_05 +#define BM_62_05 0x7fffffffffffffe0 +#define BM_05_62 BM_62_05 +#define BM_63_05 0xffffffffffffffe0 +#define BM_05_63 BM_63_05 +#define BM_06_06 0x0000000000000040 +#define BM_07_06 0x00000000000000c0 +#define BM_06_07 BM_07_06 +#define BM_08_06 0x00000000000001c0 +#define BM_06_08 BM_08_06 +#define BM_09_06 0x00000000000003c0 +#define BM_06_09 BM_09_06 +#define BM_10_06 0x00000000000007c0 +#define BM_06_10 BM_10_06 +#define BM_11_06 0x0000000000000fc0 +#define BM_06_11 BM_11_06 +#define BM_12_06 0x0000000000001fc0 +#define BM_06_12 BM_12_06 +#define BM_13_06 0x0000000000003fc0 +#define BM_06_13 BM_13_06 +#define BM_14_06 0x0000000000007fc0 +#define BM_06_14 BM_14_06 +#define BM_15_06 0x000000000000ffc0 +#define BM_06_15 BM_15_06 +#define BM_16_06 0x000000000001ffc0 +#define BM_06_16 BM_16_06 +#define BM_17_06 0x000000000003ffc0 +#define BM_06_17 BM_17_06 +#define BM_18_06 0x000000000007ffc0 +#define BM_06_18 BM_18_06 +#define BM_19_06 0x00000000000fffc0 +#define BM_06_19 BM_19_06 +#define BM_20_06 0x00000000001fffc0 +#define BM_06_20 BM_20_06 +#define BM_21_06 0x00000000003fffc0 +#define BM_06_21 BM_21_06 +#define BM_22_06 0x00000000007fffc0 +#define BM_06_22 BM_22_06 +#define BM_23_06 0x0000000000ffffc0 +#define BM_06_23 BM_23_06 +#define BM_24_06 0x0000000001ffffc0 +#define BM_06_24 BM_24_06 +#define BM_25_06 0x0000000003ffffc0 +#define BM_06_25 BM_25_06 +#define BM_26_06 0x0000000007ffffc0 +#define BM_06_26 BM_26_06 +#define BM_27_06 0x000000000fffffc0 +#define BM_06_27 BM_27_06 +#define BM_28_06 0x000000001fffffc0 +#define BM_06_28 BM_28_06 +#define BM_29_06 0x000000003fffffc0 +#define BM_06_29 BM_29_06 +#define BM_30_06 0x000000007fffffc0 +#define BM_06_30 BM_30_06 +#define BM_31_06 0x00000000ffffffc0 +#define BM_06_31 BM_31_06 +#define BM_32_06 0x00000001ffffffc0 +#define BM_06_32 BM_32_06 +#define BM_33_06 0x00000003ffffffc0 +#define BM_06_33 BM_33_06 +#define BM_34_06 0x00000007ffffffc0 +#define BM_06_34 BM_34_06 +#define BM_35_06 0x0000000fffffffc0 +#define BM_06_35 BM_35_06 +#define BM_36_06 0x0000001fffffffc0 +#define BM_06_36 BM_36_06 +#define BM_37_06 0x0000003fffffffc0 +#define BM_06_37 BM_37_06 +#define BM_38_06 0x0000007fffffffc0 +#define BM_06_38 BM_38_06 +#define BM_39_06 0x000000ffffffffc0 +#define BM_06_39 BM_39_06 +#define BM_40_06 0x000001ffffffffc0 +#define BM_06_40 BM_40_06 +#define BM_41_06 0x000003ffffffffc0 +#define BM_06_41 BM_41_06 +#define BM_42_06 0x000007ffffffffc0 +#define BM_06_42 BM_42_06 +#define BM_43_06 0x00000fffffffffc0 +#define BM_06_43 BM_43_06 +#define BM_44_06 0x00001fffffffffc0 +#define BM_06_44 BM_44_06 +#define BM_45_06 0x00003fffffffffc0 +#define BM_06_45 BM_45_06 +#define BM_46_06 0x00007fffffffffc0 +#define BM_06_46 BM_46_06 +#define BM_47_06 0x0000ffffffffffc0 +#define BM_06_47 BM_47_06 +#define BM_48_06 0x0001ffffffffffc0 +#define BM_06_48 BM_48_06 +#define BM_49_06 0x0003ffffffffffc0 +#define BM_06_49 BM_49_06 +#define BM_50_06 0x0007ffffffffffc0 +#define BM_06_50 BM_50_06 +#define BM_51_06 0x000fffffffffffc0 +#define BM_06_51 BM_51_06 +#define BM_52_06 0x001fffffffffffc0 +#define BM_06_52 BM_52_06 +#define BM_53_06 0x003fffffffffffc0 +#define BM_06_53 BM_53_06 +#define BM_54_06 0x007fffffffffffc0 +#define BM_06_54 BM_54_06 +#define BM_55_06 0x00ffffffffffffc0 +#define BM_06_55 BM_55_06 +#define BM_56_06 0x01ffffffffffffc0 +#define BM_06_56 BM_56_06 +#define BM_57_06 0x03ffffffffffffc0 +#define BM_06_57 BM_57_06 +#define BM_58_06 0x07ffffffffffffc0 +#define BM_06_58 BM_58_06 +#define BM_59_06 0x0fffffffffffffc0 +#define BM_06_59 BM_59_06 +#define BM_60_06 0x1fffffffffffffc0 +#define BM_06_60 BM_60_06 +#define BM_61_06 0x3fffffffffffffc0 +#define BM_06_61 BM_61_06 +#define BM_62_06 0x7fffffffffffffc0 +#define BM_06_62 BM_62_06 +#define BM_63_06 0xffffffffffffffc0 +#define BM_06_63 BM_63_06 +#define BM_07_07 0x0000000000000080 +#define BM_08_07 0x0000000000000180 +#define BM_07_08 BM_08_07 +#define BM_09_07 0x0000000000000380 +#define BM_07_09 BM_09_07 +#define BM_10_07 0x0000000000000780 +#define BM_07_10 BM_10_07 +#define BM_11_07 0x0000000000000f80 +#define BM_07_11 BM_11_07 +#define BM_12_07 0x0000000000001f80 +#define BM_07_12 BM_12_07 +#define BM_13_07 0x0000000000003f80 +#define BM_07_13 BM_13_07 +#define BM_14_07 0x0000000000007f80 +#define BM_07_14 BM_14_07 +#define BM_15_07 0x000000000000ff80 +#define BM_07_15 BM_15_07 +#define BM_16_07 0x000000000001ff80 +#define BM_07_16 BM_16_07 +#define BM_17_07 0x000000000003ff80 +#define BM_07_17 BM_17_07 +#define BM_18_07 0x000000000007ff80 +#define BM_07_18 BM_18_07 +#define BM_19_07 0x00000000000fff80 +#define BM_07_19 BM_19_07 +#define BM_20_07 0x00000000001fff80 +#define BM_07_20 BM_20_07 +#define BM_21_07 0x00000000003fff80 +#define BM_07_21 BM_21_07 +#define BM_22_07 0x00000000007fff80 +#define BM_07_22 BM_22_07 +#define BM_23_07 0x0000000000ffff80 +#define BM_07_23 BM_23_07 +#define BM_24_07 0x0000000001ffff80 +#define BM_07_24 BM_24_07 +#define BM_25_07 0x0000000003ffff80 +#define BM_07_25 BM_25_07 +#define BM_26_07 0x0000000007ffff80 +#define BM_07_26 BM_26_07 +#define BM_27_07 0x000000000fffff80 +#define BM_07_27 BM_27_07 +#define BM_28_07 0x000000001fffff80 +#define BM_07_28 BM_28_07 +#define BM_29_07 0x000000003fffff80 +#define BM_07_29 BM_29_07 +#define BM_30_07 0x000000007fffff80 +#define BM_07_30 BM_30_07 +#define BM_31_07 0x00000000ffffff80 +#define BM_07_31 BM_31_07 +#define BM_32_07 0x00000001ffffff80 +#define BM_07_32 BM_32_07 +#define BM_33_07 0x00000003ffffff80 +#define BM_07_33 BM_33_07 +#define BM_34_07 0x00000007ffffff80 +#define BM_07_34 BM_34_07 +#define BM_35_07 0x0000000fffffff80 +#define BM_07_35 BM_35_07 +#define BM_36_07 0x0000001fffffff80 +#define BM_07_36 BM_36_07 +#define BM_37_07 0x0000003fffffff80 +#define BM_07_37 BM_37_07 +#define BM_38_07 0x0000007fffffff80 +#define BM_07_38 BM_38_07 +#define BM_39_07 0x000000ffffffff80 +#define BM_07_39 BM_39_07 +#define BM_40_07 0x000001ffffffff80 +#define BM_07_40 BM_40_07 +#define BM_41_07 0x000003ffffffff80 +#define BM_07_41 BM_41_07 +#define BM_42_07 0x000007ffffffff80 +#define BM_07_42 BM_42_07 +#define BM_43_07 0x00000fffffffff80 +#define BM_07_43 BM_43_07 +#define BM_44_07 0x00001fffffffff80 +#define BM_07_44 BM_44_07 +#define BM_45_07 0x00003fffffffff80 +#define BM_07_45 BM_45_07 +#define BM_46_07 0x00007fffffffff80 +#define BM_07_46 BM_46_07 +#define BM_47_07 0x0000ffffffffff80 +#define BM_07_47 BM_47_07 +#define BM_48_07 0x0001ffffffffff80 +#define BM_07_48 BM_48_07 +#define BM_49_07 0x0003ffffffffff80 +#define BM_07_49 BM_49_07 +#define BM_50_07 0x0007ffffffffff80 +#define BM_07_50 BM_50_07 +#define BM_51_07 0x000fffffffffff80 +#define BM_07_51 BM_51_07 +#define BM_52_07 0x001fffffffffff80 +#define BM_07_52 BM_52_07 +#define BM_53_07 0x003fffffffffff80 +#define BM_07_53 BM_53_07 +#define BM_54_07 0x007fffffffffff80 +#define BM_07_54 BM_54_07 +#define BM_55_07 0x00ffffffffffff80 +#define BM_07_55 BM_55_07 +#define BM_56_07 0x01ffffffffffff80 +#define BM_07_56 BM_56_07 +#define BM_57_07 0x03ffffffffffff80 +#define BM_07_57 BM_57_07 +#define BM_58_07 0x07ffffffffffff80 +#define BM_07_58 BM_58_07 +#define BM_59_07 0x0fffffffffffff80 +#define BM_07_59 BM_59_07 +#define BM_60_07 0x1fffffffffffff80 +#define BM_07_60 BM_60_07 +#define BM_61_07 0x3fffffffffffff80 +#define BM_07_61 BM_61_07 +#define BM_62_07 0x7fffffffffffff80 +#define BM_07_62 BM_62_07 +#define BM_63_07 0xffffffffffffff80 +#define BM_07_63 BM_63_07 +#define BM_08_08 0x0000000000000100 +#define BM_09_08 0x0000000000000300 +#define BM_08_09 BM_09_08 +#define BM_10_08 0x0000000000000700 +#define BM_08_10 BM_10_08 +#define BM_11_08 0x0000000000000f00 +#define BM_08_11 BM_11_08 +#define BM_12_08 0x0000000000001f00 +#define BM_08_12 BM_12_08 +#define BM_13_08 0x0000000000003f00 +#define BM_08_13 BM_13_08 +#define BM_14_08 0x0000000000007f00 +#define BM_08_14 BM_14_08 +#define BM_15_08 0x000000000000ff00 +#define BM_08_15 BM_15_08 +#define BM_16_08 0x000000000001ff00 +#define BM_08_16 BM_16_08 +#define BM_17_08 0x000000000003ff00 +#define BM_08_17 BM_17_08 +#define BM_18_08 0x000000000007ff00 +#define BM_08_18 BM_18_08 +#define BM_19_08 0x00000000000fff00 +#define BM_08_19 BM_19_08 +#define BM_20_08 0x00000000001fff00 +#define BM_08_20 BM_20_08 +#define BM_21_08 0x00000000003fff00 +#define BM_08_21 BM_21_08 +#define BM_22_08 0x00000000007fff00 +#define BM_08_22 BM_22_08 +#define BM_23_08 0x0000000000ffff00 +#define BM_08_23 BM_23_08 +#define BM_24_08 0x0000000001ffff00 +#define BM_08_24 BM_24_08 +#define BM_25_08 0x0000000003ffff00 +#define BM_08_25 BM_25_08 +#define BM_26_08 0x0000000007ffff00 +#define BM_08_26 BM_26_08 +#define BM_27_08 0x000000000fffff00 +#define BM_08_27 BM_27_08 +#define BM_28_08 0x000000001fffff00 +#define BM_08_28 BM_28_08 +#define BM_29_08 0x000000003fffff00 +#define BM_08_29 BM_29_08 +#define BM_30_08 0x000000007fffff00 +#define BM_08_30 BM_30_08 +#define BM_31_08 0x00000000ffffff00 +#define BM_08_31 BM_31_08 +#define BM_32_08 0x00000001ffffff00 +#define BM_08_32 BM_32_08 +#define BM_33_08 0x00000003ffffff00 +#define BM_08_33 BM_33_08 +#define BM_34_08 0x00000007ffffff00 +#define BM_08_34 BM_34_08 +#define BM_35_08 0x0000000fffffff00 +#define BM_08_35 BM_35_08 +#define BM_36_08 0x0000001fffffff00 +#define BM_08_36 BM_36_08 +#define BM_37_08 0x0000003fffffff00 +#define BM_08_37 BM_37_08 +#define BM_38_08 0x0000007fffffff00 +#define BM_08_38 BM_38_08 +#define BM_39_08 0x000000ffffffff00 +#define BM_08_39 BM_39_08 +#define BM_40_08 0x000001ffffffff00 +#define BM_08_40 BM_40_08 +#define BM_41_08 0x000003ffffffff00 +#define BM_08_41 BM_41_08 +#define BM_42_08 0x000007ffffffff00 +#define BM_08_42 BM_42_08 +#define BM_43_08 0x00000fffffffff00 +#define BM_08_43 BM_43_08 +#define BM_44_08 0x00001fffffffff00 +#define BM_08_44 BM_44_08 +#define BM_45_08 0x00003fffffffff00 +#define BM_08_45 BM_45_08 +#define BM_46_08 0x00007fffffffff00 +#define BM_08_46 BM_46_08 +#define BM_47_08 0x0000ffffffffff00 +#define BM_08_47 BM_47_08 +#define BM_48_08 0x0001ffffffffff00 +#define BM_08_48 BM_48_08 +#define BM_49_08 0x0003ffffffffff00 +#define BM_08_49 BM_49_08 +#define BM_50_08 0x0007ffffffffff00 +#define BM_08_50 BM_50_08 +#define BM_51_08 0x000fffffffffff00 +#define BM_08_51 BM_51_08 +#define BM_52_08 0x001fffffffffff00 +#define BM_08_52 BM_52_08 +#define BM_53_08 0x003fffffffffff00 +#define BM_08_53 BM_53_08 +#define BM_54_08 0x007fffffffffff00 +#define BM_08_54 BM_54_08 +#define BM_55_08 0x00ffffffffffff00 +#define BM_08_55 BM_55_08 +#define BM_56_08 0x01ffffffffffff00 +#define BM_08_56 BM_56_08 +#define BM_57_08 0x03ffffffffffff00 +#define BM_08_57 BM_57_08 +#define BM_58_08 0x07ffffffffffff00 +#define BM_08_58 BM_58_08 +#define BM_59_08 0x0fffffffffffff00 +#define BM_08_59 BM_59_08 +#define BM_60_08 0x1fffffffffffff00 +#define BM_08_60 BM_60_08 +#define BM_61_08 0x3fffffffffffff00 +#define BM_08_61 BM_61_08 +#define BM_62_08 0x7fffffffffffff00 +#define BM_08_62 BM_62_08 +#define BM_63_08 0xffffffffffffff00 +#define BM_08_63 BM_63_08 +#define BM_09_09 0x0000000000000200 +#define BM_10_09 0x0000000000000600 +#define BM_09_10 BM_10_09 +#define BM_11_09 0x0000000000000e00 +#define BM_09_11 BM_11_09 +#define BM_12_09 0x0000000000001e00 +#define BM_09_12 BM_12_09 +#define BM_13_09 0x0000000000003e00 +#define BM_09_13 BM_13_09 +#define BM_14_09 0x0000000000007e00 +#define BM_09_14 BM_14_09 +#define BM_15_09 0x000000000000fe00 +#define BM_09_15 BM_15_09 +#define BM_16_09 0x000000000001fe00 +#define BM_09_16 BM_16_09 +#define BM_17_09 0x000000000003fe00 +#define BM_09_17 BM_17_09 +#define BM_18_09 0x000000000007fe00 +#define BM_09_18 BM_18_09 +#define BM_19_09 0x00000000000ffe00 +#define BM_09_19 BM_19_09 +#define BM_20_09 0x00000000001ffe00 +#define BM_09_20 BM_20_09 +#define BM_21_09 0x00000000003ffe00 +#define BM_09_21 BM_21_09 +#define BM_22_09 0x00000000007ffe00 +#define BM_09_22 BM_22_09 +#define BM_23_09 0x0000000000fffe00 +#define BM_09_23 BM_23_09 +#define BM_24_09 0x0000000001fffe00 +#define BM_09_24 BM_24_09 +#define BM_25_09 0x0000000003fffe00 +#define BM_09_25 BM_25_09 +#define BM_26_09 0x0000000007fffe00 +#define BM_09_26 BM_26_09 +#define BM_27_09 0x000000000ffffe00 +#define BM_09_27 BM_27_09 +#define BM_28_09 0x000000001ffffe00 +#define BM_09_28 BM_28_09 +#define BM_29_09 0x000000003ffffe00 +#define BM_09_29 BM_29_09 +#define BM_30_09 0x000000007ffffe00 +#define BM_09_30 BM_30_09 +#define BM_31_09 0x00000000fffffe00 +#define BM_09_31 BM_31_09 +#define BM_32_09 0x00000001fffffe00 +#define BM_09_32 BM_32_09 +#define BM_33_09 0x00000003fffffe00 +#define BM_09_33 BM_33_09 +#define BM_34_09 0x00000007fffffe00 +#define BM_09_34 BM_34_09 +#define BM_35_09 0x0000000ffffffe00 +#define BM_09_35 BM_35_09 +#define BM_36_09 0x0000001ffffffe00 +#define BM_09_36 BM_36_09 +#define BM_37_09 0x0000003ffffffe00 +#define BM_09_37 BM_37_09 +#define BM_38_09 0x0000007ffffffe00 +#define BM_09_38 BM_38_09 +#define BM_39_09 0x000000fffffffe00 +#define BM_09_39 BM_39_09 +#define BM_40_09 0x000001fffffffe00 +#define BM_09_40 BM_40_09 +#define BM_41_09 0x000003fffffffe00 +#define BM_09_41 BM_41_09 +#define BM_42_09 0x000007fffffffe00 +#define BM_09_42 BM_42_09 +#define BM_43_09 0x00000ffffffffe00 +#define BM_09_43 BM_43_09 +#define BM_44_09 0x00001ffffffffe00 +#define BM_09_44 BM_44_09 +#define BM_45_09 0x00003ffffffffe00 +#define BM_09_45 BM_45_09 +#define BM_46_09 0x00007ffffffffe00 +#define BM_09_46 BM_46_09 +#define BM_47_09 0x0000fffffffffe00 +#define BM_09_47 BM_47_09 +#define BM_48_09 0x0001fffffffffe00 +#define BM_09_48 BM_48_09 +#define BM_49_09 0x0003fffffffffe00 +#define BM_09_49 BM_49_09 +#define BM_50_09 0x0007fffffffffe00 +#define BM_09_50 BM_50_09 +#define BM_51_09 0x000ffffffffffe00 +#define BM_09_51 BM_51_09 +#define BM_52_09 0x001ffffffffffe00 +#define BM_09_52 BM_52_09 +#define BM_53_09 0x003ffffffffffe00 +#define BM_09_53 BM_53_09 +#define BM_54_09 0x007ffffffffffe00 +#define BM_09_54 BM_54_09 +#define BM_55_09 0x00fffffffffffe00 +#define BM_09_55 BM_55_09 +#define BM_56_09 0x01fffffffffffe00 +#define BM_09_56 BM_56_09 +#define BM_57_09 0x03fffffffffffe00 +#define BM_09_57 BM_57_09 +#define BM_58_09 0x07fffffffffffe00 +#define BM_09_58 BM_58_09 +#define BM_59_09 0x0ffffffffffffe00 +#define BM_09_59 BM_59_09 +#define BM_60_09 0x1ffffffffffffe00 +#define BM_09_60 BM_60_09 +#define BM_61_09 0x3ffffffffffffe00 +#define BM_09_61 BM_61_09 +#define BM_62_09 0x7ffffffffffffe00 +#define BM_09_62 BM_62_09 +#define BM_63_09 0xfffffffffffffe00 +#define BM_09_63 BM_63_09 +#define BM_10_10 0x0000000000000400 +#define BM_11_10 0x0000000000000c00 +#define BM_10_11 BM_11_10 +#define BM_12_10 0x0000000000001c00 +#define BM_10_12 BM_12_10 +#define BM_13_10 0x0000000000003c00 +#define BM_10_13 BM_13_10 +#define BM_14_10 0x0000000000007c00 +#define BM_10_14 BM_14_10 +#define BM_15_10 0x000000000000fc00 +#define BM_10_15 BM_15_10 +#define BM_16_10 0x000000000001fc00 +#define BM_10_16 BM_16_10 +#define BM_17_10 0x000000000003fc00 +#define BM_10_17 BM_17_10 +#define BM_18_10 0x000000000007fc00 +#define BM_10_18 BM_18_10 +#define BM_19_10 0x00000000000ffc00 +#define BM_10_19 BM_19_10 +#define BM_20_10 0x00000000001ffc00 +#define BM_10_20 BM_20_10 +#define BM_21_10 0x00000000003ffc00 +#define BM_10_21 BM_21_10 +#define BM_22_10 0x00000000007ffc00 +#define BM_10_22 BM_22_10 +#define BM_23_10 0x0000000000fffc00 +#define BM_10_23 BM_23_10 +#define BM_24_10 0x0000000001fffc00 +#define BM_10_24 BM_24_10 +#define BM_25_10 0x0000000003fffc00 +#define BM_10_25 BM_25_10 +#define BM_26_10 0x0000000007fffc00 +#define BM_10_26 BM_26_10 +#define BM_27_10 0x000000000ffffc00 +#define BM_10_27 BM_27_10 +#define BM_28_10 0x000000001ffffc00 +#define BM_10_28 BM_28_10 +#define BM_29_10 0x000000003ffffc00 +#define BM_10_29 BM_29_10 +#define BM_30_10 0x000000007ffffc00 +#define BM_10_30 BM_30_10 +#define BM_31_10 0x00000000fffffc00 +#define BM_10_31 BM_31_10 +#define BM_32_10 0x00000001fffffc00 +#define BM_10_32 BM_32_10 +#define BM_33_10 0x00000003fffffc00 +#define BM_10_33 BM_33_10 +#define BM_34_10 0x00000007fffffc00 +#define BM_10_34 BM_34_10 +#define BM_35_10 0x0000000ffffffc00 +#define BM_10_35 BM_35_10 +#define BM_36_10 0x0000001ffffffc00 +#define BM_10_36 BM_36_10 +#define BM_37_10 0x0000003ffffffc00 +#define BM_10_37 BM_37_10 +#define BM_38_10 0x0000007ffffffc00 +#define BM_10_38 BM_38_10 +#define BM_39_10 0x000000fffffffc00 +#define BM_10_39 BM_39_10 +#define BM_40_10 0x000001fffffffc00 +#define BM_10_40 BM_40_10 +#define BM_41_10 0x000003fffffffc00 +#define BM_10_41 BM_41_10 +#define BM_42_10 0x000007fffffffc00 +#define BM_10_42 BM_42_10 +#define BM_43_10 0x00000ffffffffc00 +#define BM_10_43 BM_43_10 +#define BM_44_10 0x00001ffffffffc00 +#define BM_10_44 BM_44_10 +#define BM_45_10 0x00003ffffffffc00 +#define BM_10_45 BM_45_10 +#define BM_46_10 0x00007ffffffffc00 +#define BM_10_46 BM_46_10 +#define BM_47_10 0x0000fffffffffc00 +#define BM_10_47 BM_47_10 +#define BM_48_10 0x0001fffffffffc00 +#define BM_10_48 BM_48_10 +#define BM_49_10 0x0003fffffffffc00 +#define BM_10_49 BM_49_10 +#define BM_50_10 0x0007fffffffffc00 +#define BM_10_50 BM_50_10 +#define BM_51_10 0x000ffffffffffc00 +#define BM_10_51 BM_51_10 +#define BM_52_10 0x001ffffffffffc00 +#define BM_10_52 BM_52_10 +#define BM_53_10 0x003ffffffffffc00 +#define BM_10_53 BM_53_10 +#define BM_54_10 0x007ffffffffffc00 +#define BM_10_54 BM_54_10 +#define BM_55_10 0x00fffffffffffc00 +#define BM_10_55 BM_55_10 +#define BM_56_10 0x01fffffffffffc00 +#define BM_10_56 BM_56_10 +#define BM_57_10 0x03fffffffffffc00 +#define BM_10_57 BM_57_10 +#define BM_58_10 0x07fffffffffffc00 +#define BM_10_58 BM_58_10 +#define BM_59_10 0x0ffffffffffffc00 +#define BM_10_59 BM_59_10 +#define BM_60_10 0x1ffffffffffffc00 +#define BM_10_60 BM_60_10 +#define BM_61_10 0x3ffffffffffffc00 +#define BM_10_61 BM_61_10 +#define BM_62_10 0x7ffffffffffffc00 +#define BM_10_62 BM_62_10 +#define BM_63_10 0xfffffffffffffc00 +#define BM_10_63 BM_63_10 +#define BM_11_11 0x0000000000000800 +#define BM_12_11 0x0000000000001800 +#define BM_11_12 BM_12_11 +#define BM_13_11 0x0000000000003800 +#define BM_11_13 BM_13_11 +#define BM_14_11 0x0000000000007800 +#define BM_11_14 BM_14_11 +#define BM_15_11 0x000000000000f800 +#define BM_11_15 BM_15_11 +#define BM_16_11 0x000000000001f800 +#define BM_11_16 BM_16_11 +#define BM_17_11 0x000000000003f800 +#define BM_11_17 BM_17_11 +#define BM_18_11 0x000000000007f800 +#define BM_11_18 BM_18_11 +#define BM_19_11 0x00000000000ff800 +#define BM_11_19 BM_19_11 +#define BM_20_11 0x00000000001ff800 +#define BM_11_20 BM_20_11 +#define BM_21_11 0x00000000003ff800 +#define BM_11_21 BM_21_11 +#define BM_22_11 0x00000000007ff800 +#define BM_11_22 BM_22_11 +#define BM_23_11 0x0000000000fff800 +#define BM_11_23 BM_23_11 +#define BM_24_11 0x0000000001fff800 +#define BM_11_24 BM_24_11 +#define BM_25_11 0x0000000003fff800 +#define BM_11_25 BM_25_11 +#define BM_26_11 0x0000000007fff800 +#define BM_11_26 BM_26_11 +#define BM_27_11 0x000000000ffff800 +#define BM_11_27 BM_27_11 +#define BM_28_11 0x000000001ffff800 +#define BM_11_28 BM_28_11 +#define BM_29_11 0x000000003ffff800 +#define BM_11_29 BM_29_11 +#define BM_30_11 0x000000007ffff800 +#define BM_11_30 BM_30_11 +#define BM_31_11 0x00000000fffff800 +#define BM_11_31 BM_31_11 +#define BM_32_11 0x00000001fffff800 +#define BM_11_32 BM_32_11 +#define BM_33_11 0x00000003fffff800 +#define BM_11_33 BM_33_11 +#define BM_34_11 0x00000007fffff800 +#define BM_11_34 BM_34_11 +#define BM_35_11 0x0000000ffffff800 +#define BM_11_35 BM_35_11 +#define BM_36_11 0x0000001ffffff800 +#define BM_11_36 BM_36_11 +#define BM_37_11 0x0000003ffffff800 +#define BM_11_37 BM_37_11 +#define BM_38_11 0x0000007ffffff800 +#define BM_11_38 BM_38_11 +#define BM_39_11 0x000000fffffff800 +#define BM_11_39 BM_39_11 +#define BM_40_11 0x000001fffffff800 +#define BM_11_40 BM_40_11 +#define BM_41_11 0x000003fffffff800 +#define BM_11_41 BM_41_11 +#define BM_42_11 0x000007fffffff800 +#define BM_11_42 BM_42_11 +#define BM_43_11 0x00000ffffffff800 +#define BM_11_43 BM_43_11 +#define BM_44_11 0x00001ffffffff800 +#define BM_11_44 BM_44_11 +#define BM_45_11 0x00003ffffffff800 +#define BM_11_45 BM_45_11 +#define BM_46_11 0x00007ffffffff800 +#define BM_11_46 BM_46_11 +#define BM_47_11 0x0000fffffffff800 +#define BM_11_47 BM_47_11 +#define BM_48_11 0x0001fffffffff800 +#define BM_11_48 BM_48_11 +#define BM_49_11 0x0003fffffffff800 +#define BM_11_49 BM_49_11 +#define BM_50_11 0x0007fffffffff800 +#define BM_11_50 BM_50_11 +#define BM_51_11 0x000ffffffffff800 +#define BM_11_51 BM_51_11 +#define BM_52_11 0x001ffffffffff800 +#define BM_11_52 BM_52_11 +#define BM_53_11 0x003ffffffffff800 +#define BM_11_53 BM_53_11 +#define BM_54_11 0x007ffffffffff800 +#define BM_11_54 BM_54_11 +#define BM_55_11 0x00fffffffffff800 +#define BM_11_55 BM_55_11 +#define BM_56_11 0x01fffffffffff800 +#define BM_11_56 BM_56_11 +#define BM_57_11 0x03fffffffffff800 +#define BM_11_57 BM_57_11 +#define BM_58_11 0x07fffffffffff800 +#define BM_11_58 BM_58_11 +#define BM_59_11 0x0ffffffffffff800 +#define BM_11_59 BM_59_11 +#define BM_60_11 0x1ffffffffffff800 +#define BM_11_60 BM_60_11 +#define BM_61_11 0x3ffffffffffff800 +#define BM_11_61 BM_61_11 +#define BM_62_11 0x7ffffffffffff800 +#define BM_11_62 BM_62_11 +#define BM_63_11 0xfffffffffffff800 +#define BM_11_63 BM_63_11 +#define BM_12_12 0x0000000000001000 +#define BM_13_12 0x0000000000003000 +#define BM_12_13 BM_13_12 +#define BM_14_12 0x0000000000007000 +#define BM_12_14 BM_14_12 +#define BM_15_12 0x000000000000f000 +#define BM_12_15 BM_15_12 +#define BM_16_12 0x000000000001f000 +#define BM_12_16 BM_16_12 +#define BM_17_12 0x000000000003f000 +#define BM_12_17 BM_17_12 +#define BM_18_12 0x000000000007f000 +#define BM_12_18 BM_18_12 +#define BM_19_12 0x00000000000ff000 +#define BM_12_19 BM_19_12 +#define BM_20_12 0x00000000001ff000 +#define BM_12_20 BM_20_12 +#define BM_21_12 0x00000000003ff000 +#define BM_12_21 BM_21_12 +#define BM_22_12 0x00000000007ff000 +#define BM_12_22 BM_22_12 +#define BM_23_12 0x0000000000fff000 +#define BM_12_23 BM_23_12 +#define BM_24_12 0x0000000001fff000 +#define BM_12_24 BM_24_12 +#define BM_25_12 0x0000000003fff000 +#define BM_12_25 BM_25_12 +#define BM_26_12 0x0000000007fff000 +#define BM_12_26 BM_26_12 +#define BM_27_12 0x000000000ffff000 +#define BM_12_27 BM_27_12 +#define BM_28_12 0x000000001ffff000 +#define BM_12_28 BM_28_12 +#define BM_29_12 0x000000003ffff000 +#define BM_12_29 BM_29_12 +#define BM_30_12 0x000000007ffff000 +#define BM_12_30 BM_30_12 +#define BM_31_12 0x00000000fffff000 +#define BM_12_31 BM_31_12 +#define BM_32_12 0x00000001fffff000 +#define BM_12_32 BM_32_12 +#define BM_33_12 0x00000003fffff000 +#define BM_12_33 BM_33_12 +#define BM_34_12 0x00000007fffff000 +#define BM_12_34 BM_34_12 +#define BM_35_12 0x0000000ffffff000 +#define BM_12_35 BM_35_12 +#define BM_36_12 0x0000001ffffff000 +#define BM_12_36 BM_36_12 +#define BM_37_12 0x0000003ffffff000 +#define BM_12_37 BM_37_12 +#define BM_38_12 0x0000007ffffff000 +#define BM_12_38 BM_38_12 +#define BM_39_12 0x000000fffffff000 +#define BM_12_39 BM_39_12 +#define BM_40_12 0x000001fffffff000 +#define BM_12_40 BM_40_12 +#define BM_41_12 0x000003fffffff000 +#define BM_12_41 BM_41_12 +#define BM_42_12 0x000007fffffff000 +#define BM_12_42 BM_42_12 +#define BM_43_12 0x00000ffffffff000 +#define BM_12_43 BM_43_12 +#define BM_44_12 0x00001ffffffff000 +#define BM_12_44 BM_44_12 +#define BM_45_12 0x00003ffffffff000 +#define BM_12_45 BM_45_12 +#define BM_46_12 0x00007ffffffff000 +#define BM_12_46 BM_46_12 +#define BM_47_12 0x0000fffffffff000 +#define BM_12_47 BM_47_12 +#define BM_48_12 0x0001fffffffff000 +#define BM_12_48 BM_48_12 +#define BM_49_12 0x0003fffffffff000 +#define BM_12_49 BM_49_12 +#define BM_50_12 0x0007fffffffff000 +#define BM_12_50 BM_50_12 +#define BM_51_12 0x000ffffffffff000 +#define BM_12_51 BM_51_12 +#define BM_52_12 0x001ffffffffff000 +#define BM_12_52 BM_52_12 +#define BM_53_12 0x003ffffffffff000 +#define BM_12_53 BM_53_12 +#define BM_54_12 0x007ffffffffff000 +#define BM_12_54 BM_54_12 +#define BM_55_12 0x00fffffffffff000 +#define BM_12_55 BM_55_12 +#define BM_56_12 0x01fffffffffff000 +#define BM_12_56 BM_56_12 +#define BM_57_12 0x03fffffffffff000 +#define BM_12_57 BM_57_12 +#define BM_58_12 0x07fffffffffff000 +#define BM_12_58 BM_58_12 +#define BM_59_12 0x0ffffffffffff000 +#define BM_12_59 BM_59_12 +#define BM_60_12 0x1ffffffffffff000 +#define BM_12_60 BM_60_12 +#define BM_61_12 0x3ffffffffffff000 +#define BM_12_61 BM_61_12 +#define BM_62_12 0x7ffffffffffff000 +#define BM_12_62 BM_62_12 +#define BM_63_12 0xfffffffffffff000 +#define BM_12_63 BM_63_12 +#define BM_13_13 0x0000000000002000 +#define BM_14_13 0x0000000000006000 +#define BM_13_14 BM_14_13 +#define BM_15_13 0x000000000000e000 +#define BM_13_15 BM_15_13 +#define BM_16_13 0x000000000001e000 +#define BM_13_16 BM_16_13 +#define BM_17_13 0x000000000003e000 +#define BM_13_17 BM_17_13 +#define BM_18_13 0x000000000007e000 +#define BM_13_18 BM_18_13 +#define BM_19_13 0x00000000000fe000 +#define BM_13_19 BM_19_13 +#define BM_20_13 0x00000000001fe000 +#define BM_13_20 BM_20_13 +#define BM_21_13 0x00000000003fe000 +#define BM_13_21 BM_21_13 +#define BM_22_13 0x00000000007fe000 +#define BM_13_22 BM_22_13 +#define BM_23_13 0x0000000000ffe000 +#define BM_13_23 BM_23_13 +#define BM_24_13 0x0000000001ffe000 +#define BM_13_24 BM_24_13 +#define BM_25_13 0x0000000003ffe000 +#define BM_13_25 BM_25_13 +#define BM_26_13 0x0000000007ffe000 +#define BM_13_26 BM_26_13 +#define BM_27_13 0x000000000fffe000 +#define BM_13_27 BM_27_13 +#define BM_28_13 0x000000001fffe000 +#define BM_13_28 BM_28_13 +#define BM_29_13 0x000000003fffe000 +#define BM_13_29 BM_29_13 +#define BM_30_13 0x000000007fffe000 +#define BM_13_30 BM_30_13 +#define BM_31_13 0x00000000ffffe000 +#define BM_13_31 BM_31_13 +#define BM_32_13 0x00000001ffffe000 +#define BM_13_32 BM_32_13 +#define BM_33_13 0x00000003ffffe000 +#define BM_13_33 BM_33_13 +#define BM_34_13 0x00000007ffffe000 +#define BM_13_34 BM_34_13 +#define BM_35_13 0x0000000fffffe000 +#define BM_13_35 BM_35_13 +#define BM_36_13 0x0000001fffffe000 +#define BM_13_36 BM_36_13 +#define BM_37_13 0x0000003fffffe000 +#define BM_13_37 BM_37_13 +#define BM_38_13 0x0000007fffffe000 +#define BM_13_38 BM_38_13 +#define BM_39_13 0x000000ffffffe000 +#define BM_13_39 BM_39_13 +#define BM_40_13 0x000001ffffffe000 +#define BM_13_40 BM_40_13 +#define BM_41_13 0x000003ffffffe000 +#define BM_13_41 BM_41_13 +#define BM_42_13 0x000007ffffffe000 +#define BM_13_42 BM_42_13 +#define BM_43_13 0x00000fffffffe000 +#define BM_13_43 BM_43_13 +#define BM_44_13 0x00001fffffffe000 +#define BM_13_44 BM_44_13 +#define BM_45_13 0x00003fffffffe000 +#define BM_13_45 BM_45_13 +#define BM_46_13 0x00007fffffffe000 +#define BM_13_46 BM_46_13 +#define BM_47_13 0x0000ffffffffe000 +#define BM_13_47 BM_47_13 +#define BM_48_13 0x0001ffffffffe000 +#define BM_13_48 BM_48_13 +#define BM_49_13 0x0003ffffffffe000 +#define BM_13_49 BM_49_13 +#define BM_50_13 0x0007ffffffffe000 +#define BM_13_50 BM_50_13 +#define BM_51_13 0x000fffffffffe000 +#define BM_13_51 BM_51_13 +#define BM_52_13 0x001fffffffffe000 +#define BM_13_52 BM_52_13 +#define BM_53_13 0x003fffffffffe000 +#define BM_13_53 BM_53_13 +#define BM_54_13 0x007fffffffffe000 +#define BM_13_54 BM_54_13 +#define BM_55_13 0x00ffffffffffe000 +#define BM_13_55 BM_55_13 +#define BM_56_13 0x01ffffffffffe000 +#define BM_13_56 BM_56_13 +#define BM_57_13 0x03ffffffffffe000 +#define BM_13_57 BM_57_13 +#define BM_58_13 0x07ffffffffffe000 +#define BM_13_58 BM_58_13 +#define BM_59_13 0x0fffffffffffe000 +#define BM_13_59 BM_59_13 +#define BM_60_13 0x1fffffffffffe000 +#define BM_13_60 BM_60_13 +#define BM_61_13 0x3fffffffffffe000 +#define BM_13_61 BM_61_13 +#define BM_62_13 0x7fffffffffffe000 +#define BM_13_62 BM_62_13 +#define BM_63_13 0xffffffffffffe000 +#define BM_13_63 BM_63_13 +#define BM_14_14 0x0000000000004000 +#define BM_15_14 0x000000000000c000 +#define BM_14_15 BM_15_14 +#define BM_16_14 0x000000000001c000 +#define BM_14_16 BM_16_14 +#define BM_17_14 0x000000000003c000 +#define BM_14_17 BM_17_14 +#define BM_18_14 0x000000000007c000 +#define BM_14_18 BM_18_14 +#define BM_19_14 0x00000000000fc000 +#define BM_14_19 BM_19_14 +#define BM_20_14 0x00000000001fc000 +#define BM_14_20 BM_20_14 +#define BM_21_14 0x00000000003fc000 +#define BM_14_21 BM_21_14 +#define BM_22_14 0x00000000007fc000 +#define BM_14_22 BM_22_14 +#define BM_23_14 0x0000000000ffc000 +#define BM_14_23 BM_23_14 +#define BM_24_14 0x0000000001ffc000 +#define BM_14_24 BM_24_14 +#define BM_25_14 0x0000000003ffc000 +#define BM_14_25 BM_25_14 +#define BM_26_14 0x0000000007ffc000 +#define BM_14_26 BM_26_14 +#define BM_27_14 0x000000000fffc000 +#define BM_14_27 BM_27_14 +#define BM_28_14 0x000000001fffc000 +#define BM_14_28 BM_28_14 +#define BM_29_14 0x000000003fffc000 +#define BM_14_29 BM_29_14 +#define BM_30_14 0x000000007fffc000 +#define BM_14_30 BM_30_14 +#define BM_31_14 0x00000000ffffc000 +#define BM_14_31 BM_31_14 +#define BM_32_14 0x00000001ffffc000 +#define BM_14_32 BM_32_14 +#define BM_33_14 0x00000003ffffc000 +#define BM_14_33 BM_33_14 +#define BM_34_14 0x00000007ffffc000 +#define BM_14_34 BM_34_14 +#define BM_35_14 0x0000000fffffc000 +#define BM_14_35 BM_35_14 +#define BM_36_14 0x0000001fffffc000 +#define BM_14_36 BM_36_14 +#define BM_37_14 0x0000003fffffc000 +#define BM_14_37 BM_37_14 +#define BM_38_14 0x0000007fffffc000 +#define BM_14_38 BM_38_14 +#define BM_39_14 0x000000ffffffc000 +#define BM_14_39 BM_39_14 +#define BM_40_14 0x000001ffffffc000 +#define BM_14_40 BM_40_14 +#define BM_41_14 0x000003ffffffc000 +#define BM_14_41 BM_41_14 +#define BM_42_14 0x000007ffffffc000 +#define BM_14_42 BM_42_14 +#define BM_43_14 0x00000fffffffc000 +#define BM_14_43 BM_43_14 +#define BM_44_14 0x00001fffffffc000 +#define BM_14_44 BM_44_14 +#define BM_45_14 0x00003fffffffc000 +#define BM_14_45 BM_45_14 +#define BM_46_14 0x00007fffffffc000 +#define BM_14_46 BM_46_14 +#define BM_47_14 0x0000ffffffffc000 +#define BM_14_47 BM_47_14 +#define BM_48_14 0x0001ffffffffc000 +#define BM_14_48 BM_48_14 +#define BM_49_14 0x0003ffffffffc000 +#define BM_14_49 BM_49_14 +#define BM_50_14 0x0007ffffffffc000 +#define BM_14_50 BM_50_14 +#define BM_51_14 0x000fffffffffc000 +#define BM_14_51 BM_51_14 +#define BM_52_14 0x001fffffffffc000 +#define BM_14_52 BM_52_14 +#define BM_53_14 0x003fffffffffc000 +#define BM_14_53 BM_53_14 +#define BM_54_14 0x007fffffffffc000 +#define BM_14_54 BM_54_14 +#define BM_55_14 0x00ffffffffffc000 +#define BM_14_55 BM_55_14 +#define BM_56_14 0x01ffffffffffc000 +#define BM_14_56 BM_56_14 +#define BM_57_14 0x03ffffffffffc000 +#define BM_14_57 BM_57_14 +#define BM_58_14 0x07ffffffffffc000 +#define BM_14_58 BM_58_14 +#define BM_59_14 0x0fffffffffffc000 +#define BM_14_59 BM_59_14 +#define BM_60_14 0x1fffffffffffc000 +#define BM_14_60 BM_60_14 +#define BM_61_14 0x3fffffffffffc000 +#define BM_14_61 BM_61_14 +#define BM_62_14 0x7fffffffffffc000 +#define BM_14_62 BM_62_14 +#define BM_63_14 0xffffffffffffc000 +#define BM_14_63 BM_63_14 +#define BM_15_15 0x0000000000008000 +#define BM_16_15 0x0000000000018000 +#define BM_15_16 BM_16_15 +#define BM_17_15 0x0000000000038000 +#define BM_15_17 BM_17_15 +#define BM_18_15 0x0000000000078000 +#define BM_15_18 BM_18_15 +#define BM_19_15 0x00000000000f8000 +#define BM_15_19 BM_19_15 +#define BM_20_15 0x00000000001f8000 +#define BM_15_20 BM_20_15 +#define BM_21_15 0x00000000003f8000 +#define BM_15_21 BM_21_15 +#define BM_22_15 0x00000000007f8000 +#define BM_15_22 BM_22_15 +#define BM_23_15 0x0000000000ff8000 +#define BM_15_23 BM_23_15 +#define BM_24_15 0x0000000001ff8000 +#define BM_15_24 BM_24_15 +#define BM_25_15 0x0000000003ff8000 +#define BM_15_25 BM_25_15 +#define BM_26_15 0x0000000007ff8000 +#define BM_15_26 BM_26_15 +#define BM_27_15 0x000000000fff8000 +#define BM_15_27 BM_27_15 +#define BM_28_15 0x000000001fff8000 +#define BM_15_28 BM_28_15 +#define BM_29_15 0x000000003fff8000 +#define BM_15_29 BM_29_15 +#define BM_30_15 0x000000007fff8000 +#define BM_15_30 BM_30_15 +#define BM_31_15 0x00000000ffff8000 +#define BM_15_31 BM_31_15 +#define BM_32_15 0x00000001ffff8000 +#define BM_15_32 BM_32_15 +#define BM_33_15 0x00000003ffff8000 +#define BM_15_33 BM_33_15 +#define BM_34_15 0x00000007ffff8000 +#define BM_15_34 BM_34_15 +#define BM_35_15 0x0000000fffff8000 +#define BM_15_35 BM_35_15 +#define BM_36_15 0x0000001fffff8000 +#define BM_15_36 BM_36_15 +#define BM_37_15 0x0000003fffff8000 +#define BM_15_37 BM_37_15 +#define BM_38_15 0x0000007fffff8000 +#define BM_15_38 BM_38_15 +#define BM_39_15 0x000000ffffff8000 +#define BM_15_39 BM_39_15 +#define BM_40_15 0x000001ffffff8000 +#define BM_15_40 BM_40_15 +#define BM_41_15 0x000003ffffff8000 +#define BM_15_41 BM_41_15 +#define BM_42_15 0x000007ffffff8000 +#define BM_15_42 BM_42_15 +#define BM_43_15 0x00000fffffff8000 +#define BM_15_43 BM_43_15 +#define BM_44_15 0x00001fffffff8000 +#define BM_15_44 BM_44_15 +#define BM_45_15 0x00003fffffff8000 +#define BM_15_45 BM_45_15 +#define BM_46_15 0x00007fffffff8000 +#define BM_15_46 BM_46_15 +#define BM_47_15 0x0000ffffffff8000 +#define BM_15_47 BM_47_15 +#define BM_48_15 0x0001ffffffff8000 +#define BM_15_48 BM_48_15 +#define BM_49_15 0x0003ffffffff8000 +#define BM_15_49 BM_49_15 +#define BM_50_15 0x0007ffffffff8000 +#define BM_15_50 BM_50_15 +#define BM_51_15 0x000fffffffff8000 +#define BM_15_51 BM_51_15 +#define BM_52_15 0x001fffffffff8000 +#define BM_15_52 BM_52_15 +#define BM_53_15 0x003fffffffff8000 +#define BM_15_53 BM_53_15 +#define BM_54_15 0x007fffffffff8000 +#define BM_15_54 BM_54_15 +#define BM_55_15 0x00ffffffffff8000 +#define BM_15_55 BM_55_15 +#define BM_56_15 0x01ffffffffff8000 +#define BM_15_56 BM_56_15 +#define BM_57_15 0x03ffffffffff8000 +#define BM_15_57 BM_57_15 +#define BM_58_15 0x07ffffffffff8000 +#define BM_15_58 BM_58_15 +#define BM_59_15 0x0fffffffffff8000 +#define BM_15_59 BM_59_15 +#define BM_60_15 0x1fffffffffff8000 +#define BM_15_60 BM_60_15 +#define BM_61_15 0x3fffffffffff8000 +#define BM_15_61 BM_61_15 +#define BM_62_15 0x7fffffffffff8000 +#define BM_15_62 BM_62_15 +#define BM_63_15 0xffffffffffff8000 +#define BM_15_63 BM_63_15 +#define BM_16_16 0x0000000000010000 +#define BM_17_16 0x0000000000030000 +#define BM_16_17 BM_17_16 +#define BM_18_16 0x0000000000070000 +#define BM_16_18 BM_18_16 +#define BM_19_16 0x00000000000f0000 +#define BM_16_19 BM_19_16 +#define BM_20_16 0x00000000001f0000 +#define BM_16_20 BM_20_16 +#define BM_21_16 0x00000000003f0000 +#define BM_16_21 BM_21_16 +#define BM_22_16 0x00000000007f0000 +#define BM_16_22 BM_22_16 +#define BM_23_16 0x0000000000ff0000 +#define BM_16_23 BM_23_16 +#define BM_24_16 0x0000000001ff0000 +#define BM_16_24 BM_24_16 +#define BM_25_16 0x0000000003ff0000 +#define BM_16_25 BM_25_16 +#define BM_26_16 0x0000000007ff0000 +#define BM_16_26 BM_26_16 +#define BM_27_16 0x000000000fff0000 +#define BM_16_27 BM_27_16 +#define BM_28_16 0x000000001fff0000 +#define BM_16_28 BM_28_16 +#define BM_29_16 0x000000003fff0000 +#define BM_16_29 BM_29_16 +#define BM_30_16 0x000000007fff0000 +#define BM_16_30 BM_30_16 +#define BM_31_16 0x00000000ffff0000 +#define BM_16_31 BM_31_16 +#define BM_32_16 0x00000001ffff0000 +#define BM_16_32 BM_32_16 +#define BM_33_16 0x00000003ffff0000 +#define BM_16_33 BM_33_16 +#define BM_34_16 0x00000007ffff0000 +#define BM_16_34 BM_34_16 +#define BM_35_16 0x0000000fffff0000 +#define BM_16_35 BM_35_16 +#define BM_36_16 0x0000001fffff0000 +#define BM_16_36 BM_36_16 +#define BM_37_16 0x0000003fffff0000 +#define BM_16_37 BM_37_16 +#define BM_38_16 0x0000007fffff0000 +#define BM_16_38 BM_38_16 +#define BM_39_16 0x000000ffffff0000 +#define BM_16_39 BM_39_16 +#define BM_40_16 0x000001ffffff0000 +#define BM_16_40 BM_40_16 +#define BM_41_16 0x000003ffffff0000 +#define BM_16_41 BM_41_16 +#define BM_42_16 0x000007ffffff0000 +#define BM_16_42 BM_42_16 +#define BM_43_16 0x00000fffffff0000 +#define BM_16_43 BM_43_16 +#define BM_44_16 0x00001fffffff0000 +#define BM_16_44 BM_44_16 +#define BM_45_16 0x00003fffffff0000 +#define BM_16_45 BM_45_16 +#define BM_46_16 0x00007fffffff0000 +#define BM_16_46 BM_46_16 +#define BM_47_16 0x0000ffffffff0000 +#define BM_16_47 BM_47_16 +#define BM_48_16 0x0001ffffffff0000 +#define BM_16_48 BM_48_16 +#define BM_49_16 0x0003ffffffff0000 +#define BM_16_49 BM_49_16 +#define BM_50_16 0x0007ffffffff0000 +#define BM_16_50 BM_50_16 +#define BM_51_16 0x000fffffffff0000 +#define BM_16_51 BM_51_16 +#define BM_52_16 0x001fffffffff0000 +#define BM_16_52 BM_52_16 +#define BM_53_16 0x003fffffffff0000 +#define BM_16_53 BM_53_16 +#define BM_54_16 0x007fffffffff0000 +#define BM_16_54 BM_54_16 +#define BM_55_16 0x00ffffffffff0000 +#define BM_16_55 BM_55_16 +#define BM_56_16 0x01ffffffffff0000 +#define BM_16_56 BM_56_16 +#define BM_57_16 0x03ffffffffff0000 +#define BM_16_57 BM_57_16 +#define BM_58_16 0x07ffffffffff0000 +#define BM_16_58 BM_58_16 +#define BM_59_16 0x0fffffffffff0000 +#define BM_16_59 BM_59_16 +#define BM_60_16 0x1fffffffffff0000 +#define BM_16_60 BM_60_16 +#define BM_61_16 0x3fffffffffff0000 +#define BM_16_61 BM_61_16 +#define BM_62_16 0x7fffffffffff0000 +#define BM_16_62 BM_62_16 +#define BM_63_16 0xffffffffffff0000 +#define BM_16_63 BM_63_16 +#define BM_17_17 0x0000000000020000 +#define BM_18_17 0x0000000000060000 +#define BM_17_18 BM_18_17 +#define BM_19_17 0x00000000000e0000 +#define BM_17_19 BM_19_17 +#define BM_20_17 0x00000000001e0000 +#define BM_17_20 BM_20_17 +#define BM_21_17 0x00000000003e0000 +#define BM_17_21 BM_21_17 +#define BM_22_17 0x00000000007e0000 +#define BM_17_22 BM_22_17 +#define BM_23_17 0x0000000000fe0000 +#define BM_17_23 BM_23_17 +#define BM_24_17 0x0000000001fe0000 +#define BM_17_24 BM_24_17 +#define BM_25_17 0x0000000003fe0000 +#define BM_17_25 BM_25_17 +#define BM_26_17 0x0000000007fe0000 +#define BM_17_26 BM_26_17 +#define BM_27_17 0x000000000ffe0000 +#define BM_17_27 BM_27_17 +#define BM_28_17 0x000000001ffe0000 +#define BM_17_28 BM_28_17 +#define BM_29_17 0x000000003ffe0000 +#define BM_17_29 BM_29_17 +#define BM_30_17 0x000000007ffe0000 +#define BM_17_30 BM_30_17 +#define BM_31_17 0x00000000fffe0000 +#define BM_17_31 BM_31_17 +#define BM_32_17 0x00000001fffe0000 +#define BM_17_32 BM_32_17 +#define BM_33_17 0x00000003fffe0000 +#define BM_17_33 BM_33_17 +#define BM_34_17 0x00000007fffe0000 +#define BM_17_34 BM_34_17 +#define BM_35_17 0x0000000ffffe0000 +#define BM_17_35 BM_35_17 +#define BM_36_17 0x0000001ffffe0000 +#define BM_17_36 BM_36_17 +#define BM_37_17 0x0000003ffffe0000 +#define BM_17_37 BM_37_17 +#define BM_38_17 0x0000007ffffe0000 +#define BM_17_38 BM_38_17 +#define BM_39_17 0x000000fffffe0000 +#define BM_17_39 BM_39_17 +#define BM_40_17 0x000001fffffe0000 +#define BM_17_40 BM_40_17 +#define BM_41_17 0x000003fffffe0000 +#define BM_17_41 BM_41_17 +#define BM_42_17 0x000007fffffe0000 +#define BM_17_42 BM_42_17 +#define BM_43_17 0x00000ffffffe0000 +#define BM_17_43 BM_43_17 +#define BM_44_17 0x00001ffffffe0000 +#define BM_17_44 BM_44_17 +#define BM_45_17 0x00003ffffffe0000 +#define BM_17_45 BM_45_17 +#define BM_46_17 0x00007ffffffe0000 +#define BM_17_46 BM_46_17 +#define BM_47_17 0x0000fffffffe0000 +#define BM_17_47 BM_47_17 +#define BM_48_17 0x0001fffffffe0000 +#define BM_17_48 BM_48_17 +#define BM_49_17 0x0003fffffffe0000 +#define BM_17_49 BM_49_17 +#define BM_50_17 0x0007fffffffe0000 +#define BM_17_50 BM_50_17 +#define BM_51_17 0x000ffffffffe0000 +#define BM_17_51 BM_51_17 +#define BM_52_17 0x001ffffffffe0000 +#define BM_17_52 BM_52_17 +#define BM_53_17 0x003ffffffffe0000 +#define BM_17_53 BM_53_17 +#define BM_54_17 0x007ffffffffe0000 +#define BM_17_54 BM_54_17 +#define BM_55_17 0x00fffffffffe0000 +#define BM_17_55 BM_55_17 +#define BM_56_17 0x01fffffffffe0000 +#define BM_17_56 BM_56_17 +#define BM_57_17 0x03fffffffffe0000 +#define BM_17_57 BM_57_17 +#define BM_58_17 0x07fffffffffe0000 +#define BM_17_58 BM_58_17 +#define BM_59_17 0x0ffffffffffe0000 +#define BM_17_59 BM_59_17 +#define BM_60_17 0x1ffffffffffe0000 +#define BM_17_60 BM_60_17 +#define BM_61_17 0x3ffffffffffe0000 +#define BM_17_61 BM_61_17 +#define BM_62_17 0x7ffffffffffe0000 +#define BM_17_62 BM_62_17 +#define BM_63_17 0xfffffffffffe0000 +#define BM_17_63 BM_63_17 +#define BM_18_18 0x0000000000040000 +#define BM_19_18 0x00000000000c0000 +#define BM_18_19 BM_19_18 +#define BM_20_18 0x00000000001c0000 +#define BM_18_20 BM_20_18 +#define BM_21_18 0x00000000003c0000 +#define BM_18_21 BM_21_18 +#define BM_22_18 0x00000000007c0000 +#define BM_18_22 BM_22_18 +#define BM_23_18 0x0000000000fc0000 +#define BM_18_23 BM_23_18 +#define BM_24_18 0x0000000001fc0000 +#define BM_18_24 BM_24_18 +#define BM_25_18 0x0000000003fc0000 +#define BM_18_25 BM_25_18 +#define BM_26_18 0x0000000007fc0000 +#define BM_18_26 BM_26_18 +#define BM_27_18 0x000000000ffc0000 +#define BM_18_27 BM_27_18 +#define BM_28_18 0x000000001ffc0000 +#define BM_18_28 BM_28_18 +#define BM_29_18 0x000000003ffc0000 +#define BM_18_29 BM_29_18 +#define BM_30_18 0x000000007ffc0000 +#define BM_18_30 BM_30_18 +#define BM_31_18 0x00000000fffc0000 +#define BM_18_31 BM_31_18 +#define BM_32_18 0x00000001fffc0000 +#define BM_18_32 BM_32_18 +#define BM_33_18 0x00000003fffc0000 +#define BM_18_33 BM_33_18 +#define BM_34_18 0x00000007fffc0000 +#define BM_18_34 BM_34_18 +#define BM_35_18 0x0000000ffffc0000 +#define BM_18_35 BM_35_18 +#define BM_36_18 0x0000001ffffc0000 +#define BM_18_36 BM_36_18 +#define BM_37_18 0x0000003ffffc0000 +#define BM_18_37 BM_37_18 +#define BM_38_18 0x0000007ffffc0000 +#define BM_18_38 BM_38_18 +#define BM_39_18 0x000000fffffc0000 +#define BM_18_39 BM_39_18 +#define BM_40_18 0x000001fffffc0000 +#define BM_18_40 BM_40_18 +#define BM_41_18 0x000003fffffc0000 +#define BM_18_41 BM_41_18 +#define BM_42_18 0x000007fffffc0000 +#define BM_18_42 BM_42_18 +#define BM_43_18 0x00000ffffffc0000 +#define BM_18_43 BM_43_18 +#define BM_44_18 0x00001ffffffc0000 +#define BM_18_44 BM_44_18 +#define BM_45_18 0x00003ffffffc0000 +#define BM_18_45 BM_45_18 +#define BM_46_18 0x00007ffffffc0000 +#define BM_18_46 BM_46_18 +#define BM_47_18 0x0000fffffffc0000 +#define BM_18_47 BM_47_18 +#define BM_48_18 0x0001fffffffc0000 +#define BM_18_48 BM_48_18 +#define BM_49_18 0x0003fffffffc0000 +#define BM_18_49 BM_49_18 +#define BM_50_18 0x0007fffffffc0000 +#define BM_18_50 BM_50_18 +#define BM_51_18 0x000ffffffffc0000 +#define BM_18_51 BM_51_18 +#define BM_52_18 0x001ffffffffc0000 +#define BM_18_52 BM_52_18 +#define BM_53_18 0x003ffffffffc0000 +#define BM_18_53 BM_53_18 +#define BM_54_18 0x007ffffffffc0000 +#define BM_18_54 BM_54_18 +#define BM_55_18 0x00fffffffffc0000 +#define BM_18_55 BM_55_18 +#define BM_56_18 0x01fffffffffc0000 +#define BM_18_56 BM_56_18 +#define BM_57_18 0x03fffffffffc0000 +#define BM_18_57 BM_57_18 +#define BM_58_18 0x07fffffffffc0000 +#define BM_18_58 BM_58_18 +#define BM_59_18 0x0ffffffffffc0000 +#define BM_18_59 BM_59_18 +#define BM_60_18 0x1ffffffffffc0000 +#define BM_18_60 BM_60_18 +#define BM_61_18 0x3ffffffffffc0000 +#define BM_18_61 BM_61_18 +#define BM_62_18 0x7ffffffffffc0000 +#define BM_18_62 BM_62_18 +#define BM_63_18 0xfffffffffffc0000 +#define BM_18_63 BM_63_18 +#define BM_19_19 0x0000000000080000 +#define BM_20_19 0x0000000000180000 +#define BM_19_20 BM_20_19 +#define BM_21_19 0x0000000000380000 +#define BM_19_21 BM_21_19 +#define BM_22_19 0x0000000000780000 +#define BM_19_22 BM_22_19 +#define BM_23_19 0x0000000000f80000 +#define BM_19_23 BM_23_19 +#define BM_24_19 0x0000000001f80000 +#define BM_19_24 BM_24_19 +#define BM_25_19 0x0000000003f80000 +#define BM_19_25 BM_25_19 +#define BM_26_19 0x0000000007f80000 +#define BM_19_26 BM_26_19 +#define BM_27_19 0x000000000ff80000 +#define BM_19_27 BM_27_19 +#define BM_28_19 0x000000001ff80000 +#define BM_19_28 BM_28_19 +#define BM_29_19 0x000000003ff80000 +#define BM_19_29 BM_29_19 +#define BM_30_19 0x000000007ff80000 +#define BM_19_30 BM_30_19 +#define BM_31_19 0x00000000fff80000 +#define BM_19_31 BM_31_19 +#define BM_32_19 0x00000001fff80000 +#define BM_19_32 BM_32_19 +#define BM_33_19 0x00000003fff80000 +#define BM_19_33 BM_33_19 +#define BM_34_19 0x00000007fff80000 +#define BM_19_34 BM_34_19 +#define BM_35_19 0x0000000ffff80000 +#define BM_19_35 BM_35_19 +#define BM_36_19 0x0000001ffff80000 +#define BM_19_36 BM_36_19 +#define BM_37_19 0x0000003ffff80000 +#define BM_19_37 BM_37_19 +#define BM_38_19 0x0000007ffff80000 +#define BM_19_38 BM_38_19 +#define BM_39_19 0x000000fffff80000 +#define BM_19_39 BM_39_19 +#define BM_40_19 0x000001fffff80000 +#define BM_19_40 BM_40_19 +#define BM_41_19 0x000003fffff80000 +#define BM_19_41 BM_41_19 +#define BM_42_19 0x000007fffff80000 +#define BM_19_42 BM_42_19 +#define BM_43_19 0x00000ffffff80000 +#define BM_19_43 BM_43_19 +#define BM_44_19 0x00001ffffff80000 +#define BM_19_44 BM_44_19 +#define BM_45_19 0x00003ffffff80000 +#define BM_19_45 BM_45_19 +#define BM_46_19 0x00007ffffff80000 +#define BM_19_46 BM_46_19 +#define BM_47_19 0x0000fffffff80000 +#define BM_19_47 BM_47_19 +#define BM_48_19 0x0001fffffff80000 +#define BM_19_48 BM_48_19 +#define BM_49_19 0x0003fffffff80000 +#define BM_19_49 BM_49_19 +#define BM_50_19 0x0007fffffff80000 +#define BM_19_50 BM_50_19 +#define BM_51_19 0x000ffffffff80000 +#define BM_19_51 BM_51_19 +#define BM_52_19 0x001ffffffff80000 +#define BM_19_52 BM_52_19 +#define BM_53_19 0x003ffffffff80000 +#define BM_19_53 BM_53_19 +#define BM_54_19 0x007ffffffff80000 +#define BM_19_54 BM_54_19 +#define BM_55_19 0x00fffffffff80000 +#define BM_19_55 BM_55_19 +#define BM_56_19 0x01fffffffff80000 +#define BM_19_56 BM_56_19 +#define BM_57_19 0x03fffffffff80000 +#define BM_19_57 BM_57_19 +#define BM_58_19 0x07fffffffff80000 +#define BM_19_58 BM_58_19 +#define BM_59_19 0x0ffffffffff80000 +#define BM_19_59 BM_59_19 +#define BM_60_19 0x1ffffffffff80000 +#define BM_19_60 BM_60_19 +#define BM_61_19 0x3ffffffffff80000 +#define BM_19_61 BM_61_19 +#define BM_62_19 0x7ffffffffff80000 +#define BM_19_62 BM_62_19 +#define BM_63_19 0xfffffffffff80000 +#define BM_19_63 BM_63_19 +#define BM_20_20 0x0000000000100000 +#define BM_21_20 0x0000000000300000 +#define BM_20_21 BM_21_20 +#define BM_22_20 0x0000000000700000 +#define BM_20_22 BM_22_20 +#define BM_23_20 0x0000000000f00000 +#define BM_20_23 BM_23_20 +#define BM_24_20 0x0000000001f00000 +#define BM_20_24 BM_24_20 +#define BM_25_20 0x0000000003f00000 +#define BM_20_25 BM_25_20 +#define BM_26_20 0x0000000007f00000 +#define BM_20_26 BM_26_20 +#define BM_27_20 0x000000000ff00000 +#define BM_20_27 BM_27_20 +#define BM_28_20 0x000000001ff00000 +#define BM_20_28 BM_28_20 +#define BM_29_20 0x000000003ff00000 +#define BM_20_29 BM_29_20 +#define BM_30_20 0x000000007ff00000 +#define BM_20_30 BM_30_20 +#define BM_31_20 0x00000000fff00000 +#define BM_20_31 BM_31_20 +#define BM_32_20 0x00000001fff00000 +#define BM_20_32 BM_32_20 +#define BM_33_20 0x00000003fff00000 +#define BM_20_33 BM_33_20 +#define BM_34_20 0x00000007fff00000 +#define BM_20_34 BM_34_20 +#define BM_35_20 0x0000000ffff00000 +#define BM_20_35 BM_35_20 +#define BM_36_20 0x0000001ffff00000 +#define BM_20_36 BM_36_20 +#define BM_37_20 0x0000003ffff00000 +#define BM_20_37 BM_37_20 +#define BM_38_20 0x0000007ffff00000 +#define BM_20_38 BM_38_20 +#define BM_39_20 0x000000fffff00000 +#define BM_20_39 BM_39_20 +#define BM_40_20 0x000001fffff00000 +#define BM_20_40 BM_40_20 +#define BM_41_20 0x000003fffff00000 +#define BM_20_41 BM_41_20 +#define BM_42_20 0x000007fffff00000 +#define BM_20_42 BM_42_20 +#define BM_43_20 0x00000ffffff00000 +#define BM_20_43 BM_43_20 +#define BM_44_20 0x00001ffffff00000 +#define BM_20_44 BM_44_20 +#define BM_45_20 0x00003ffffff00000 +#define BM_20_45 BM_45_20 +#define BM_46_20 0x00007ffffff00000 +#define BM_20_46 BM_46_20 +#define BM_47_20 0x0000fffffff00000 +#define BM_20_47 BM_47_20 +#define BM_48_20 0x0001fffffff00000 +#define BM_20_48 BM_48_20 +#define BM_49_20 0x0003fffffff00000 +#define BM_20_49 BM_49_20 +#define BM_50_20 0x0007fffffff00000 +#define BM_20_50 BM_50_20 +#define BM_51_20 0x000ffffffff00000 +#define BM_20_51 BM_51_20 +#define BM_52_20 0x001ffffffff00000 +#define BM_20_52 BM_52_20 +#define BM_53_20 0x003ffffffff00000 +#define BM_20_53 BM_53_20 +#define BM_54_20 0x007ffffffff00000 +#define BM_20_54 BM_54_20 +#define BM_55_20 0x00fffffffff00000 +#define BM_20_55 BM_55_20 +#define BM_56_20 0x01fffffffff00000 +#define BM_20_56 BM_56_20 +#define BM_57_20 0x03fffffffff00000 +#define BM_20_57 BM_57_20 +#define BM_58_20 0x07fffffffff00000 +#define BM_20_58 BM_58_20 +#define BM_59_20 0x0ffffffffff00000 +#define BM_20_59 BM_59_20 +#define BM_60_20 0x1ffffffffff00000 +#define BM_20_60 BM_60_20 +#define BM_61_20 0x3ffffffffff00000 +#define BM_20_61 BM_61_20 +#define BM_62_20 0x7ffffffffff00000 +#define BM_20_62 BM_62_20 +#define BM_63_20 0xfffffffffff00000 +#define BM_20_63 BM_63_20 +#define BM_21_21 0x0000000000200000 +#define BM_22_21 0x0000000000600000 +#define BM_21_22 BM_22_21 +#define BM_23_21 0x0000000000e00000 +#define BM_21_23 BM_23_21 +#define BM_24_21 0x0000000001e00000 +#define BM_21_24 BM_24_21 +#define BM_25_21 0x0000000003e00000 +#define BM_21_25 BM_25_21 +#define BM_26_21 0x0000000007e00000 +#define BM_21_26 BM_26_21 +#define BM_27_21 0x000000000fe00000 +#define BM_21_27 BM_27_21 +#define BM_28_21 0x000000001fe00000 +#define BM_21_28 BM_28_21 +#define BM_29_21 0x000000003fe00000 +#define BM_21_29 BM_29_21 +#define BM_30_21 0x000000007fe00000 +#define BM_21_30 BM_30_21 +#define BM_31_21 0x00000000ffe00000 +#define BM_21_31 BM_31_21 +#define BM_32_21 0x00000001ffe00000 +#define BM_21_32 BM_32_21 +#define BM_33_21 0x00000003ffe00000 +#define BM_21_33 BM_33_21 +#define BM_34_21 0x00000007ffe00000 +#define BM_21_34 BM_34_21 +#define BM_35_21 0x0000000fffe00000 +#define BM_21_35 BM_35_21 +#define BM_36_21 0x0000001fffe00000 +#define BM_21_36 BM_36_21 +#define BM_37_21 0x0000003fffe00000 +#define BM_21_37 BM_37_21 +#define BM_38_21 0x0000007fffe00000 +#define BM_21_38 BM_38_21 +#define BM_39_21 0x000000ffffe00000 +#define BM_21_39 BM_39_21 +#define BM_40_21 0x000001ffffe00000 +#define BM_21_40 BM_40_21 +#define BM_41_21 0x000003ffffe00000 +#define BM_21_41 BM_41_21 +#define BM_42_21 0x000007ffffe00000 +#define BM_21_42 BM_42_21 +#define BM_43_21 0x00000fffffe00000 +#define BM_21_43 BM_43_21 +#define BM_44_21 0x00001fffffe00000 +#define BM_21_44 BM_44_21 +#define BM_45_21 0x00003fffffe00000 +#define BM_21_45 BM_45_21 +#define BM_46_21 0x00007fffffe00000 +#define BM_21_46 BM_46_21 +#define BM_47_21 0x0000ffffffe00000 +#define BM_21_47 BM_47_21 +#define BM_48_21 0x0001ffffffe00000 +#define BM_21_48 BM_48_21 +#define BM_49_21 0x0003ffffffe00000 +#define BM_21_49 BM_49_21 +#define BM_50_21 0x0007ffffffe00000 +#define BM_21_50 BM_50_21 +#define BM_51_21 0x000fffffffe00000 +#define BM_21_51 BM_51_21 +#define BM_52_21 0x001fffffffe00000 +#define BM_21_52 BM_52_21 +#define BM_53_21 0x003fffffffe00000 +#define BM_21_53 BM_53_21 +#define BM_54_21 0x007fffffffe00000 +#define BM_21_54 BM_54_21 +#define BM_55_21 0x00ffffffffe00000 +#define BM_21_55 BM_55_21 +#define BM_56_21 0x01ffffffffe00000 +#define BM_21_56 BM_56_21 +#define BM_57_21 0x03ffffffffe00000 +#define BM_21_57 BM_57_21 +#define BM_58_21 0x07ffffffffe00000 +#define BM_21_58 BM_58_21 +#define BM_59_21 0x0fffffffffe00000 +#define BM_21_59 BM_59_21 +#define BM_60_21 0x1fffffffffe00000 +#define BM_21_60 BM_60_21 +#define BM_61_21 0x3fffffffffe00000 +#define BM_21_61 BM_61_21 +#define BM_62_21 0x7fffffffffe00000 +#define BM_21_62 BM_62_21 +#define BM_63_21 0xffffffffffe00000 +#define BM_21_63 BM_63_21 +#define BM_22_22 0x0000000000400000 +#define BM_23_22 0x0000000000c00000 +#define BM_22_23 BM_23_22 +#define BM_24_22 0x0000000001c00000 +#define BM_22_24 BM_24_22 +#define BM_25_22 0x0000000003c00000 +#define BM_22_25 BM_25_22 +#define BM_26_22 0x0000000007c00000 +#define BM_22_26 BM_26_22 +#define BM_27_22 0x000000000fc00000 +#define BM_22_27 BM_27_22 +#define BM_28_22 0x000000001fc00000 +#define BM_22_28 BM_28_22 +#define BM_29_22 0x000000003fc00000 +#define BM_22_29 BM_29_22 +#define BM_30_22 0x000000007fc00000 +#define BM_22_30 BM_30_22 +#define BM_31_22 0x00000000ffc00000 +#define BM_22_31 BM_31_22 +#define BM_32_22 0x00000001ffc00000 +#define BM_22_32 BM_32_22 +#define BM_33_22 0x00000003ffc00000 +#define BM_22_33 BM_33_22 +#define BM_34_22 0x00000007ffc00000 +#define BM_22_34 BM_34_22 +#define BM_35_22 0x0000000fffc00000 +#define BM_22_35 BM_35_22 +#define BM_36_22 0x0000001fffc00000 +#define BM_22_36 BM_36_22 +#define BM_37_22 0x0000003fffc00000 +#define BM_22_37 BM_37_22 +#define BM_38_22 0x0000007fffc00000 +#define BM_22_38 BM_38_22 +#define BM_39_22 0x000000ffffc00000 +#define BM_22_39 BM_39_22 +#define BM_40_22 0x000001ffffc00000 +#define BM_22_40 BM_40_22 +#define BM_41_22 0x000003ffffc00000 +#define BM_22_41 BM_41_22 +#define BM_42_22 0x000007ffffc00000 +#define BM_22_42 BM_42_22 +#define BM_43_22 0x00000fffffc00000 +#define BM_22_43 BM_43_22 +#define BM_44_22 0x00001fffffc00000 +#define BM_22_44 BM_44_22 +#define BM_45_22 0x00003fffffc00000 +#define BM_22_45 BM_45_22 +#define BM_46_22 0x00007fffffc00000 +#define BM_22_46 BM_46_22 +#define BM_47_22 0x0000ffffffc00000 +#define BM_22_47 BM_47_22 +#define BM_48_22 0x0001ffffffc00000 +#define BM_22_48 BM_48_22 +#define BM_49_22 0x0003ffffffc00000 +#define BM_22_49 BM_49_22 +#define BM_50_22 0x0007ffffffc00000 +#define BM_22_50 BM_50_22 +#define BM_51_22 0x000fffffffc00000 +#define BM_22_51 BM_51_22 +#define BM_52_22 0x001fffffffc00000 +#define BM_22_52 BM_52_22 +#define BM_53_22 0x003fffffffc00000 +#define BM_22_53 BM_53_22 +#define BM_54_22 0x007fffffffc00000 +#define BM_22_54 BM_54_22 +#define BM_55_22 0x00ffffffffc00000 +#define BM_22_55 BM_55_22 +#define BM_56_22 0x01ffffffffc00000 +#define BM_22_56 BM_56_22 +#define BM_57_22 0x03ffffffffc00000 +#define BM_22_57 BM_57_22 +#define BM_58_22 0x07ffffffffc00000 +#define BM_22_58 BM_58_22 +#define BM_59_22 0x0fffffffffc00000 +#define BM_22_59 BM_59_22 +#define BM_60_22 0x1fffffffffc00000 +#define BM_22_60 BM_60_22 +#define BM_61_22 0x3fffffffffc00000 +#define BM_22_61 BM_61_22 +#define BM_62_22 0x7fffffffffc00000 +#define BM_22_62 BM_62_22 +#define BM_63_22 0xffffffffffc00000 +#define BM_22_63 BM_63_22 +#define BM_23_23 0x0000000000800000 +#define BM_24_23 0x0000000001800000 +#define BM_23_24 BM_24_23 +#define BM_25_23 0x0000000003800000 +#define BM_23_25 BM_25_23 +#define BM_26_23 0x0000000007800000 +#define BM_23_26 BM_26_23 +#define BM_27_23 0x000000000f800000 +#define BM_23_27 BM_27_23 +#define BM_28_23 0x000000001f800000 +#define BM_23_28 BM_28_23 +#define BM_29_23 0x000000003f800000 +#define BM_23_29 BM_29_23 +#define BM_30_23 0x000000007f800000 +#define BM_23_30 BM_30_23 +#define BM_31_23 0x00000000ff800000 +#define BM_23_31 BM_31_23 +#define BM_32_23 0x00000001ff800000 +#define BM_23_32 BM_32_23 +#define BM_33_23 0x00000003ff800000 +#define BM_23_33 BM_33_23 +#define BM_34_23 0x00000007ff800000 +#define BM_23_34 BM_34_23 +#define BM_35_23 0x0000000fff800000 +#define BM_23_35 BM_35_23 +#define BM_36_23 0x0000001fff800000 +#define BM_23_36 BM_36_23 +#define BM_37_23 0x0000003fff800000 +#define BM_23_37 BM_37_23 +#define BM_38_23 0x0000007fff800000 +#define BM_23_38 BM_38_23 +#define BM_39_23 0x000000ffff800000 +#define BM_23_39 BM_39_23 +#define BM_40_23 0x000001ffff800000 +#define BM_23_40 BM_40_23 +#define BM_41_23 0x000003ffff800000 +#define BM_23_41 BM_41_23 +#define BM_42_23 0x000007ffff800000 +#define BM_23_42 BM_42_23 +#define BM_43_23 0x00000fffff800000 +#define BM_23_43 BM_43_23 +#define BM_44_23 0x00001fffff800000 +#define BM_23_44 BM_44_23 +#define BM_45_23 0x00003fffff800000 +#define BM_23_45 BM_45_23 +#define BM_46_23 0x00007fffff800000 +#define BM_23_46 BM_46_23 +#define BM_47_23 0x0000ffffff800000 +#define BM_23_47 BM_47_23 +#define BM_48_23 0x0001ffffff800000 +#define BM_23_48 BM_48_23 +#define BM_49_23 0x0003ffffff800000 +#define BM_23_49 BM_49_23 +#define BM_50_23 0x0007ffffff800000 +#define BM_23_50 BM_50_23 +#define BM_51_23 0x000fffffff800000 +#define BM_23_51 BM_51_23 +#define BM_52_23 0x001fffffff800000 +#define BM_23_52 BM_52_23 +#define BM_53_23 0x003fffffff800000 +#define BM_23_53 BM_53_23 +#define BM_54_23 0x007fffffff800000 +#define BM_23_54 BM_54_23 +#define BM_55_23 0x00ffffffff800000 +#define BM_23_55 BM_55_23 +#define BM_56_23 0x01ffffffff800000 +#define BM_23_56 BM_56_23 +#define BM_57_23 0x03ffffffff800000 +#define BM_23_57 BM_57_23 +#define BM_58_23 0x07ffffffff800000 +#define BM_23_58 BM_58_23 +#define BM_59_23 0x0fffffffff800000 +#define BM_23_59 BM_59_23 +#define BM_60_23 0x1fffffffff800000 +#define BM_23_60 BM_60_23 +#define BM_61_23 0x3fffffffff800000 +#define BM_23_61 BM_61_23 +#define BM_62_23 0x7fffffffff800000 +#define BM_23_62 BM_62_23 +#define BM_63_23 0xffffffffff800000 +#define BM_23_63 BM_63_23 +#define BM_24_24 0x0000000001000000 +#define BM_25_24 0x0000000003000000 +#define BM_24_25 BM_25_24 +#define BM_26_24 0x0000000007000000 +#define BM_24_26 BM_26_24 +#define BM_27_24 0x000000000f000000 +#define BM_24_27 BM_27_24 +#define BM_28_24 0x000000001f000000 +#define BM_24_28 BM_28_24 +#define BM_29_24 0x000000003f000000 +#define BM_24_29 BM_29_24 +#define BM_30_24 0x000000007f000000 +#define BM_24_30 BM_30_24 +#define BM_31_24 0x00000000ff000000 +#define BM_24_31 BM_31_24 +#define BM_32_24 0x00000001ff000000 +#define BM_24_32 BM_32_24 +#define BM_33_24 0x00000003ff000000 +#define BM_24_33 BM_33_24 +#define BM_34_24 0x00000007ff000000 +#define BM_24_34 BM_34_24 +#define BM_35_24 0x0000000fff000000 +#define BM_24_35 BM_35_24 +#define BM_36_24 0x0000001fff000000 +#define BM_24_36 BM_36_24 +#define BM_37_24 0x0000003fff000000 +#define BM_24_37 BM_37_24 +#define BM_38_24 0x0000007fff000000 +#define BM_24_38 BM_38_24 +#define BM_39_24 0x000000ffff000000 +#define BM_24_39 BM_39_24 +#define BM_40_24 0x000001ffff000000 +#define BM_24_40 BM_40_24 +#define BM_41_24 0x000003ffff000000 +#define BM_24_41 BM_41_24 +#define BM_42_24 0x000007ffff000000 +#define BM_24_42 BM_42_24 +#define BM_43_24 0x00000fffff000000 +#define BM_24_43 BM_43_24 +#define BM_44_24 0x00001fffff000000 +#define BM_24_44 BM_44_24 +#define BM_45_24 0x00003fffff000000 +#define BM_24_45 BM_45_24 +#define BM_46_24 0x00007fffff000000 +#define BM_24_46 BM_46_24 +#define BM_47_24 0x0000ffffff000000 +#define BM_24_47 BM_47_24 +#define BM_48_24 0x0001ffffff000000 +#define BM_24_48 BM_48_24 +#define BM_49_24 0x0003ffffff000000 +#define BM_24_49 BM_49_24 +#define BM_50_24 0x0007ffffff000000 +#define BM_24_50 BM_50_24 +#define BM_51_24 0x000fffffff000000 +#define BM_24_51 BM_51_24 +#define BM_52_24 0x001fffffff000000 +#define BM_24_52 BM_52_24 +#define BM_53_24 0x003fffffff000000 +#define BM_24_53 BM_53_24 +#define BM_54_24 0x007fffffff000000 +#define BM_24_54 BM_54_24 +#define BM_55_24 0x00ffffffff000000 +#define BM_24_55 BM_55_24 +#define BM_56_24 0x01ffffffff000000 +#define BM_24_56 BM_56_24 +#define BM_57_24 0x03ffffffff000000 +#define BM_24_57 BM_57_24 +#define BM_58_24 0x07ffffffff000000 +#define BM_24_58 BM_58_24 +#define BM_59_24 0x0fffffffff000000 +#define BM_24_59 BM_59_24 +#define BM_60_24 0x1fffffffff000000 +#define BM_24_60 BM_60_24 +#define BM_61_24 0x3fffffffff000000 +#define BM_24_61 BM_61_24 +#define BM_62_24 0x7fffffffff000000 +#define BM_24_62 BM_62_24 +#define BM_63_24 0xffffffffff000000 +#define BM_24_63 BM_63_24 +#define BM_25_25 0x0000000002000000 +#define BM_26_25 0x0000000006000000 +#define BM_25_26 BM_26_25 +#define BM_27_25 0x000000000e000000 +#define BM_25_27 BM_27_25 +#define BM_28_25 0x000000001e000000 +#define BM_25_28 BM_28_25 +#define BM_29_25 0x000000003e000000 +#define BM_25_29 BM_29_25 +#define BM_30_25 0x000000007e000000 +#define BM_25_30 BM_30_25 +#define BM_31_25 0x00000000fe000000 +#define BM_25_31 BM_31_25 +#define BM_32_25 0x00000001fe000000 +#define BM_25_32 BM_32_25 +#define BM_33_25 0x00000003fe000000 +#define BM_25_33 BM_33_25 +#define BM_34_25 0x00000007fe000000 +#define BM_25_34 BM_34_25 +#define BM_35_25 0x0000000ffe000000 +#define BM_25_35 BM_35_25 +#define BM_36_25 0x0000001ffe000000 +#define BM_25_36 BM_36_25 +#define BM_37_25 0x0000003ffe000000 +#define BM_25_37 BM_37_25 +#define BM_38_25 0x0000007ffe000000 +#define BM_25_38 BM_38_25 +#define BM_39_25 0x000000fffe000000 +#define BM_25_39 BM_39_25 +#define BM_40_25 0x000001fffe000000 +#define BM_25_40 BM_40_25 +#define BM_41_25 0x000003fffe000000 +#define BM_25_41 BM_41_25 +#define BM_42_25 0x000007fffe000000 +#define BM_25_42 BM_42_25 +#define BM_43_25 0x00000ffffe000000 +#define BM_25_43 BM_43_25 +#define BM_44_25 0x00001ffffe000000 +#define BM_25_44 BM_44_25 +#define BM_45_25 0x00003ffffe000000 +#define BM_25_45 BM_45_25 +#define BM_46_25 0x00007ffffe000000 +#define BM_25_46 BM_46_25 +#define BM_47_25 0x0000fffffe000000 +#define BM_25_47 BM_47_25 +#define BM_48_25 0x0001fffffe000000 +#define BM_25_48 BM_48_25 +#define BM_49_25 0x0003fffffe000000 +#define BM_25_49 BM_49_25 +#define BM_50_25 0x0007fffffe000000 +#define BM_25_50 BM_50_25 +#define BM_51_25 0x000ffffffe000000 +#define BM_25_51 BM_51_25 +#define BM_52_25 0x001ffffffe000000 +#define BM_25_52 BM_52_25 +#define BM_53_25 0x003ffffffe000000 +#define BM_25_53 BM_53_25 +#define BM_54_25 0x007ffffffe000000 +#define BM_25_54 BM_54_25 +#define BM_55_25 0x00fffffffe000000 +#define BM_25_55 BM_55_25 +#define BM_56_25 0x01fffffffe000000 +#define BM_25_56 BM_56_25 +#define BM_57_25 0x03fffffffe000000 +#define BM_25_57 BM_57_25 +#define BM_58_25 0x07fffffffe000000 +#define BM_25_58 BM_58_25 +#define BM_59_25 0x0ffffffffe000000 +#define BM_25_59 BM_59_25 +#define BM_60_25 0x1ffffffffe000000 +#define BM_25_60 BM_60_25 +#define BM_61_25 0x3ffffffffe000000 +#define BM_25_61 BM_61_25 +#define BM_62_25 0x7ffffffffe000000 +#define BM_25_62 BM_62_25 +#define BM_63_25 0xfffffffffe000000 +#define BM_25_63 BM_63_25 +#define BM_26_26 0x0000000004000000 +#define BM_27_26 0x000000000c000000 +#define BM_26_27 BM_27_26 +#define BM_28_26 0x000000001c000000 +#define BM_26_28 BM_28_26 +#define BM_29_26 0x000000003c000000 +#define BM_26_29 BM_29_26 +#define BM_30_26 0x000000007c000000 +#define BM_26_30 BM_30_26 +#define BM_31_26 0x00000000fc000000 +#define BM_26_31 BM_31_26 +#define BM_32_26 0x00000001fc000000 +#define BM_26_32 BM_32_26 +#define BM_33_26 0x00000003fc000000 +#define BM_26_33 BM_33_26 +#define BM_34_26 0x00000007fc000000 +#define BM_26_34 BM_34_26 +#define BM_35_26 0x0000000ffc000000 +#define BM_26_35 BM_35_26 +#define BM_36_26 0x0000001ffc000000 +#define BM_26_36 BM_36_26 +#define BM_37_26 0x0000003ffc000000 +#define BM_26_37 BM_37_26 +#define BM_38_26 0x0000007ffc000000 +#define BM_26_38 BM_38_26 +#define BM_39_26 0x000000fffc000000 +#define BM_26_39 BM_39_26 +#define BM_40_26 0x000001fffc000000 +#define BM_26_40 BM_40_26 +#define BM_41_26 0x000003fffc000000 +#define BM_26_41 BM_41_26 +#define BM_42_26 0x000007fffc000000 +#define BM_26_42 BM_42_26 +#define BM_43_26 0x00000ffffc000000 +#define BM_26_43 BM_43_26 +#define BM_44_26 0x00001ffffc000000 +#define BM_26_44 BM_44_26 +#define BM_45_26 0x00003ffffc000000 +#define BM_26_45 BM_45_26 +#define BM_46_26 0x00007ffffc000000 +#define BM_26_46 BM_46_26 +#define BM_47_26 0x0000fffffc000000 +#define BM_26_47 BM_47_26 +#define BM_48_26 0x0001fffffc000000 +#define BM_26_48 BM_48_26 +#define BM_49_26 0x0003fffffc000000 +#define BM_26_49 BM_49_26 +#define BM_50_26 0x0007fffffc000000 +#define BM_26_50 BM_50_26 +#define BM_51_26 0x000ffffffc000000 +#define BM_26_51 BM_51_26 +#define BM_52_26 0x001ffffffc000000 +#define BM_26_52 BM_52_26 +#define BM_53_26 0x003ffffffc000000 +#define BM_26_53 BM_53_26 +#define BM_54_26 0x007ffffffc000000 +#define BM_26_54 BM_54_26 +#define BM_55_26 0x00fffffffc000000 +#define BM_26_55 BM_55_26 +#define BM_56_26 0x01fffffffc000000 +#define BM_26_56 BM_56_26 +#define BM_57_26 0x03fffffffc000000 +#define BM_26_57 BM_57_26 +#define BM_58_26 0x07fffffffc000000 +#define BM_26_58 BM_58_26 +#define BM_59_26 0x0ffffffffc000000 +#define BM_26_59 BM_59_26 +#define BM_60_26 0x1ffffffffc000000 +#define BM_26_60 BM_60_26 +#define BM_61_26 0x3ffffffffc000000 +#define BM_26_61 BM_61_26 +#define BM_62_26 0x7ffffffffc000000 +#define BM_26_62 BM_62_26 +#define BM_63_26 0xfffffffffc000000 +#define BM_26_63 BM_63_26 +#define BM_27_27 0x0000000008000000 +#define BM_28_27 0x0000000018000000 +#define BM_27_28 BM_28_27 +#define BM_29_27 0x0000000038000000 +#define BM_27_29 BM_29_27 +#define BM_30_27 0x0000000078000000 +#define BM_27_30 BM_30_27 +#define BM_31_27 0x00000000f8000000 +#define BM_27_31 BM_31_27 +#define BM_32_27 0x00000001f8000000 +#define BM_27_32 BM_32_27 +#define BM_33_27 0x00000003f8000000 +#define BM_27_33 BM_33_27 +#define BM_34_27 0x00000007f8000000 +#define BM_27_34 BM_34_27 +#define BM_35_27 0x0000000ff8000000 +#define BM_27_35 BM_35_27 +#define BM_36_27 0x0000001ff8000000 +#define BM_27_36 BM_36_27 +#define BM_37_27 0x0000003ff8000000 +#define BM_27_37 BM_37_27 +#define BM_38_27 0x0000007ff8000000 +#define BM_27_38 BM_38_27 +#define BM_39_27 0x000000fff8000000 +#define BM_27_39 BM_39_27 +#define BM_40_27 0x000001fff8000000 +#define BM_27_40 BM_40_27 +#define BM_41_27 0x000003fff8000000 +#define BM_27_41 BM_41_27 +#define BM_42_27 0x000007fff8000000 +#define BM_27_42 BM_42_27 +#define BM_43_27 0x00000ffff8000000 +#define BM_27_43 BM_43_27 +#define BM_44_27 0x00001ffff8000000 +#define BM_27_44 BM_44_27 +#define BM_45_27 0x00003ffff8000000 +#define BM_27_45 BM_45_27 +#define BM_46_27 0x00007ffff8000000 +#define BM_27_46 BM_46_27 +#define BM_47_27 0x0000fffff8000000 +#define BM_27_47 BM_47_27 +#define BM_48_27 0x0001fffff8000000 +#define BM_27_48 BM_48_27 +#define BM_49_27 0x0003fffff8000000 +#define BM_27_49 BM_49_27 +#define BM_50_27 0x0007fffff8000000 +#define BM_27_50 BM_50_27 +#define BM_51_27 0x000ffffff8000000 +#define BM_27_51 BM_51_27 +#define BM_52_27 0x001ffffff8000000 +#define BM_27_52 BM_52_27 +#define BM_53_27 0x003ffffff8000000 +#define BM_27_53 BM_53_27 +#define BM_54_27 0x007ffffff8000000 +#define BM_27_54 BM_54_27 +#define BM_55_27 0x00fffffff8000000 +#define BM_27_55 BM_55_27 +#define BM_56_27 0x01fffffff8000000 +#define BM_27_56 BM_56_27 +#define BM_57_27 0x03fffffff8000000 +#define BM_27_57 BM_57_27 +#define BM_58_27 0x07fffffff8000000 +#define BM_27_58 BM_58_27 +#define BM_59_27 0x0ffffffff8000000 +#define BM_27_59 BM_59_27 +#define BM_60_27 0x1ffffffff8000000 +#define BM_27_60 BM_60_27 +#define BM_61_27 0x3ffffffff8000000 +#define BM_27_61 BM_61_27 +#define BM_62_27 0x7ffffffff8000000 +#define BM_27_62 BM_62_27 +#define BM_63_27 0xfffffffff8000000 +#define BM_27_63 BM_63_27 +#define BM_28_28 0x0000000010000000 +#define BM_29_28 0x0000000030000000 +#define BM_28_29 BM_29_28 +#define BM_30_28 0x0000000070000000 +#define BM_28_30 BM_30_28 +#define BM_31_28 0x00000000f0000000 +#define BM_28_31 BM_31_28 +#define BM_32_28 0x00000001f0000000 +#define BM_28_32 BM_32_28 +#define BM_33_28 0x00000003f0000000 +#define BM_28_33 BM_33_28 +#define BM_34_28 0x00000007f0000000 +#define BM_28_34 BM_34_28 +#define BM_35_28 0x0000000ff0000000 +#define BM_28_35 BM_35_28 +#define BM_36_28 0x0000001ff0000000 +#define BM_28_36 BM_36_28 +#define BM_37_28 0x0000003ff0000000 +#define BM_28_37 BM_37_28 +#define BM_38_28 0x0000007ff0000000 +#define BM_28_38 BM_38_28 +#define BM_39_28 0x000000fff0000000 +#define BM_28_39 BM_39_28 +#define BM_40_28 0x000001fff0000000 +#define BM_28_40 BM_40_28 +#define BM_41_28 0x000003fff0000000 +#define BM_28_41 BM_41_28 +#define BM_42_28 0x000007fff0000000 +#define BM_28_42 BM_42_28 +#define BM_43_28 0x00000ffff0000000 +#define BM_28_43 BM_43_28 +#define BM_44_28 0x00001ffff0000000 +#define BM_28_44 BM_44_28 +#define BM_45_28 0x00003ffff0000000 +#define BM_28_45 BM_45_28 +#define BM_46_28 0x00007ffff0000000 +#define BM_28_46 BM_46_28 +#define BM_47_28 0x0000fffff0000000 +#define BM_28_47 BM_47_28 +#define BM_48_28 0x0001fffff0000000 +#define BM_28_48 BM_48_28 +#define BM_49_28 0x0003fffff0000000 +#define BM_28_49 BM_49_28 +#define BM_50_28 0x0007fffff0000000 +#define BM_28_50 BM_50_28 +#define BM_51_28 0x000ffffff0000000 +#define BM_28_51 BM_51_28 +#define BM_52_28 0x001ffffff0000000 +#define BM_28_52 BM_52_28 +#define BM_53_28 0x003ffffff0000000 +#define BM_28_53 BM_53_28 +#define BM_54_28 0x007ffffff0000000 +#define BM_28_54 BM_54_28 +#define BM_55_28 0x00fffffff0000000 +#define BM_28_55 BM_55_28 +#define BM_56_28 0x01fffffff0000000 +#define BM_28_56 BM_56_28 +#define BM_57_28 0x03fffffff0000000 +#define BM_28_57 BM_57_28 +#define BM_58_28 0x07fffffff0000000 +#define BM_28_58 BM_58_28 +#define BM_59_28 0x0ffffffff0000000 +#define BM_28_59 BM_59_28 +#define BM_60_28 0x1ffffffff0000000 +#define BM_28_60 BM_60_28 +#define BM_61_28 0x3ffffffff0000000 +#define BM_28_61 BM_61_28 +#define BM_62_28 0x7ffffffff0000000 +#define BM_28_62 BM_62_28 +#define BM_63_28 0xfffffffff0000000 +#define BM_28_63 BM_63_28 +#define BM_29_29 0x0000000020000000 +#define BM_30_29 0x0000000060000000 +#define BM_29_30 BM_30_29 +#define BM_31_29 0x00000000e0000000 +#define BM_29_31 BM_31_29 +#define BM_32_29 0x00000001e0000000 +#define BM_29_32 BM_32_29 +#define BM_33_29 0x00000003e0000000 +#define BM_29_33 BM_33_29 +#define BM_34_29 0x00000007e0000000 +#define BM_29_34 BM_34_29 +#define BM_35_29 0x0000000fe0000000 +#define BM_29_35 BM_35_29 +#define BM_36_29 0x0000001fe0000000 +#define BM_29_36 BM_36_29 +#define BM_37_29 0x0000003fe0000000 +#define BM_29_37 BM_37_29 +#define BM_38_29 0x0000007fe0000000 +#define BM_29_38 BM_38_29 +#define BM_39_29 0x000000ffe0000000 +#define BM_29_39 BM_39_29 +#define BM_40_29 0x000001ffe0000000 +#define BM_29_40 BM_40_29 +#define BM_41_29 0x000003ffe0000000 +#define BM_29_41 BM_41_29 +#define BM_42_29 0x000007ffe0000000 +#define BM_29_42 BM_42_29 +#define BM_43_29 0x00000fffe0000000 +#define BM_29_43 BM_43_29 +#define BM_44_29 0x00001fffe0000000 +#define BM_29_44 BM_44_29 +#define BM_45_29 0x00003fffe0000000 +#define BM_29_45 BM_45_29 +#define BM_46_29 0x00007fffe0000000 +#define BM_29_46 BM_46_29 +#define BM_47_29 0x0000ffffe0000000 +#define BM_29_47 BM_47_29 +#define BM_48_29 0x0001ffffe0000000 +#define BM_29_48 BM_48_29 +#define BM_49_29 0x0003ffffe0000000 +#define BM_29_49 BM_49_29 +#define BM_50_29 0x0007ffffe0000000 +#define BM_29_50 BM_50_29 +#define BM_51_29 0x000fffffe0000000 +#define BM_29_51 BM_51_29 +#define BM_52_29 0x001fffffe0000000 +#define BM_29_52 BM_52_29 +#define BM_53_29 0x003fffffe0000000 +#define BM_29_53 BM_53_29 +#define BM_54_29 0x007fffffe0000000 +#define BM_29_54 BM_54_29 +#define BM_55_29 0x00ffffffe0000000 +#define BM_29_55 BM_55_29 +#define BM_56_29 0x01ffffffe0000000 +#define BM_29_56 BM_56_29 +#define BM_57_29 0x03ffffffe0000000 +#define BM_29_57 BM_57_29 +#define BM_58_29 0x07ffffffe0000000 +#define BM_29_58 BM_58_29 +#define BM_59_29 0x0fffffffe0000000 +#define BM_29_59 BM_59_29 +#define BM_60_29 0x1fffffffe0000000 +#define BM_29_60 BM_60_29 +#define BM_61_29 0x3fffffffe0000000 +#define BM_29_61 BM_61_29 +#define BM_62_29 0x7fffffffe0000000 +#define BM_29_62 BM_62_29 +#define BM_63_29 0xffffffffe0000000 +#define BM_29_63 BM_63_29 +#define BM_30_30 0x0000000040000000 +#define BM_31_30 0x00000000c0000000 +#define BM_30_31 BM_31_30 +#define BM_32_30 0x00000001c0000000 +#define BM_30_32 BM_32_30 +#define BM_33_30 0x00000003c0000000 +#define BM_30_33 BM_33_30 +#define BM_34_30 0x00000007c0000000 +#define BM_30_34 BM_34_30 +#define BM_35_30 0x0000000fc0000000 +#define BM_30_35 BM_35_30 +#define BM_36_30 0x0000001fc0000000 +#define BM_30_36 BM_36_30 +#define BM_37_30 0x0000003fc0000000 +#define BM_30_37 BM_37_30 +#define BM_38_30 0x0000007fc0000000 +#define BM_30_38 BM_38_30 +#define BM_39_30 0x000000ffc0000000 +#define BM_30_39 BM_39_30 +#define BM_40_30 0x000001ffc0000000 +#define BM_30_40 BM_40_30 +#define BM_41_30 0x000003ffc0000000 +#define BM_30_41 BM_41_30 +#define BM_42_30 0x000007ffc0000000 +#define BM_30_42 BM_42_30 +#define BM_43_30 0x00000fffc0000000 +#define BM_30_43 BM_43_30 +#define BM_44_30 0x00001fffc0000000 +#define BM_30_44 BM_44_30 +#define BM_45_30 0x00003fffc0000000 +#define BM_30_45 BM_45_30 +#define BM_46_30 0x00007fffc0000000 +#define BM_30_46 BM_46_30 +#define BM_47_30 0x0000ffffc0000000 +#define BM_30_47 BM_47_30 +#define BM_48_30 0x0001ffffc0000000 +#define BM_30_48 BM_48_30 +#define BM_49_30 0x0003ffffc0000000 +#define BM_30_49 BM_49_30 +#define BM_50_30 0x0007ffffc0000000 +#define BM_30_50 BM_50_30 +#define BM_51_30 0x000fffffc0000000 +#define BM_30_51 BM_51_30 +#define BM_52_30 0x001fffffc0000000 +#define BM_30_52 BM_52_30 +#define BM_53_30 0x003fffffc0000000 +#define BM_30_53 BM_53_30 +#define BM_54_30 0x007fffffc0000000 +#define BM_30_54 BM_54_30 +#define BM_55_30 0x00ffffffc0000000 +#define BM_30_55 BM_55_30 +#define BM_56_30 0x01ffffffc0000000 +#define BM_30_56 BM_56_30 +#define BM_57_30 0x03ffffffc0000000 +#define BM_30_57 BM_57_30 +#define BM_58_30 0x07ffffffc0000000 +#define BM_30_58 BM_58_30 +#define BM_59_30 0x0fffffffc0000000 +#define BM_30_59 BM_59_30 +#define BM_60_30 0x1fffffffc0000000 +#define BM_30_60 BM_60_30 +#define BM_61_30 0x3fffffffc0000000 +#define BM_30_61 BM_61_30 +#define BM_62_30 0x7fffffffc0000000 +#define BM_30_62 BM_62_30 +#define BM_63_30 0xffffffffc0000000 +#define BM_30_63 BM_63_30 +#define BM_31_31 0x0000000080000000 +#define BM_32_31 0x0000000180000000 +#define BM_31_32 BM_32_31 +#define BM_33_31 0x0000000380000000 +#define BM_31_33 BM_33_31 +#define BM_34_31 0x0000000780000000 +#define BM_31_34 BM_34_31 +#define BM_35_31 0x0000000f80000000 +#define BM_31_35 BM_35_31 +#define BM_36_31 0x0000001f80000000 +#define BM_31_36 BM_36_31 +#define BM_37_31 0x0000003f80000000 +#define BM_31_37 BM_37_31 +#define BM_38_31 0x0000007f80000000 +#define BM_31_38 BM_38_31 +#define BM_39_31 0x000000ff80000000 +#define BM_31_39 BM_39_31 +#define BM_40_31 0x000001ff80000000 +#define BM_31_40 BM_40_31 +#define BM_41_31 0x000003ff80000000 +#define BM_31_41 BM_41_31 +#define BM_42_31 0x000007ff80000000 +#define BM_31_42 BM_42_31 +#define BM_43_31 0x00000fff80000000 +#define BM_31_43 BM_43_31 +#define BM_44_31 0x00001fff80000000 +#define BM_31_44 BM_44_31 +#define BM_45_31 0x00003fff80000000 +#define BM_31_45 BM_45_31 +#define BM_46_31 0x00007fff80000000 +#define BM_31_46 BM_46_31 +#define BM_47_31 0x0000ffff80000000 +#define BM_31_47 BM_47_31 +#define BM_48_31 0x0001ffff80000000 +#define BM_31_48 BM_48_31 +#define BM_49_31 0x0003ffff80000000 +#define BM_31_49 BM_49_31 +#define BM_50_31 0x0007ffff80000000 +#define BM_31_50 BM_50_31 +#define BM_51_31 0x000fffff80000000 +#define BM_31_51 BM_51_31 +#define BM_52_31 0x001fffff80000000 +#define BM_31_52 BM_52_31 +#define BM_53_31 0x003fffff80000000 +#define BM_31_53 BM_53_31 +#define BM_54_31 0x007fffff80000000 +#define BM_31_54 BM_54_31 +#define BM_55_31 0x00ffffff80000000 +#define BM_31_55 BM_55_31 +#define BM_56_31 0x01ffffff80000000 +#define BM_31_56 BM_56_31 +#define BM_57_31 0x03ffffff80000000 +#define BM_31_57 BM_57_31 +#define BM_58_31 0x07ffffff80000000 +#define BM_31_58 BM_58_31 +#define BM_59_31 0x0fffffff80000000 +#define BM_31_59 BM_59_31 +#define BM_60_31 0x1fffffff80000000 +#define BM_31_60 BM_60_31 +#define BM_61_31 0x3fffffff80000000 +#define BM_31_61 BM_61_31 +#define BM_62_31 0x7fffffff80000000 +#define BM_31_62 BM_62_31 +#define BM_63_31 0xffffffff80000000 +#define BM_31_63 BM_63_31 +#define BM_32_32 0x0000000100000000 +#define BM_33_32 0x0000000300000000 +#define BM_32_33 BM_33_32 +#define BM_34_32 0x0000000700000000 +#define BM_32_34 BM_34_32 +#define BM_35_32 0x0000000f00000000 +#define BM_32_35 BM_35_32 +#define BM_36_32 0x0000001f00000000 +#define BM_32_36 BM_36_32 +#define BM_37_32 0x0000003f00000000 +#define BM_32_37 BM_37_32 +#define BM_38_32 0x0000007f00000000 +#define BM_32_38 BM_38_32 +#define BM_39_32 0x000000ff00000000 +#define BM_32_39 BM_39_32 +#define BM_40_32 0x000001ff00000000 +#define BM_32_40 BM_40_32 +#define BM_41_32 0x000003ff00000000 +#define BM_32_41 BM_41_32 +#define BM_42_32 0x000007ff00000000 +#define BM_32_42 BM_42_32 +#define BM_43_32 0x00000fff00000000 +#define BM_32_43 BM_43_32 +#define BM_44_32 0x00001fff00000000 +#define BM_32_44 BM_44_32 +#define BM_45_32 0x00003fff00000000 +#define BM_32_45 BM_45_32 +#define BM_46_32 0x00007fff00000000 +#define BM_32_46 BM_46_32 +#define BM_47_32 0x0000ffff00000000 +#define BM_32_47 BM_47_32 +#define BM_48_32 0x0001ffff00000000 +#define BM_32_48 BM_48_32 +#define BM_49_32 0x0003ffff00000000 +#define BM_32_49 BM_49_32 +#define BM_50_32 0x0007ffff00000000 +#define BM_32_50 BM_50_32 +#define BM_51_32 0x000fffff00000000 +#define BM_32_51 BM_51_32 +#define BM_52_32 0x001fffff00000000 +#define BM_32_52 BM_52_32 +#define BM_53_32 0x003fffff00000000 +#define BM_32_53 BM_53_32 +#define BM_54_32 0x007fffff00000000 +#define BM_32_54 BM_54_32 +#define BM_55_32 0x00ffffff00000000 +#define BM_32_55 BM_55_32 +#define BM_56_32 0x01ffffff00000000 +#define BM_32_56 BM_56_32 +#define BM_57_32 0x03ffffff00000000 +#define BM_32_57 BM_57_32 +#define BM_58_32 0x07ffffff00000000 +#define BM_32_58 BM_58_32 +#define BM_59_32 0x0fffffff00000000 +#define BM_32_59 BM_59_32 +#define BM_60_32 0x1fffffff00000000 +#define BM_32_60 BM_60_32 +#define BM_61_32 0x3fffffff00000000 +#define BM_32_61 BM_61_32 +#define BM_62_32 0x7fffffff00000000 +#define BM_32_62 BM_62_32 +#define BM_63_32 0xffffffff00000000 +#define BM_32_63 BM_63_32 +#define BM_33_33 0x0000000200000000 +#define BM_34_33 0x0000000600000000 +#define BM_33_34 BM_34_33 +#define BM_35_33 0x0000000e00000000 +#define BM_33_35 BM_35_33 +#define BM_36_33 0x0000001e00000000 +#define BM_33_36 BM_36_33 +#define BM_37_33 0x0000003e00000000 +#define BM_33_37 BM_37_33 +#define BM_38_33 0x0000007e00000000 +#define BM_33_38 BM_38_33 +#define BM_39_33 0x000000fe00000000 +#define BM_33_39 BM_39_33 +#define BM_40_33 0x000001fe00000000 +#define BM_33_40 BM_40_33 +#define BM_41_33 0x000003fe00000000 +#define BM_33_41 BM_41_33 +#define BM_42_33 0x000007fe00000000 +#define BM_33_42 BM_42_33 +#define BM_43_33 0x00000ffe00000000 +#define BM_33_43 BM_43_33 +#define BM_44_33 0x00001ffe00000000 +#define BM_33_44 BM_44_33 +#define BM_45_33 0x00003ffe00000000 +#define BM_33_45 BM_45_33 +#define BM_46_33 0x00007ffe00000000 +#define BM_33_46 BM_46_33 +#define BM_47_33 0x0000fffe00000000 +#define BM_33_47 BM_47_33 +#define BM_48_33 0x0001fffe00000000 +#define BM_33_48 BM_48_33 +#define BM_49_33 0x0003fffe00000000 +#define BM_33_49 BM_49_33 +#define BM_50_33 0x0007fffe00000000 +#define BM_33_50 BM_50_33 +#define BM_51_33 0x000ffffe00000000 +#define BM_33_51 BM_51_33 +#define BM_52_33 0x001ffffe00000000 +#define BM_33_52 BM_52_33 +#define BM_53_33 0x003ffffe00000000 +#define BM_33_53 BM_53_33 +#define BM_54_33 0x007ffffe00000000 +#define BM_33_54 BM_54_33 +#define BM_55_33 0x00fffffe00000000 +#define BM_33_55 BM_55_33 +#define BM_56_33 0x01fffffe00000000 +#define BM_33_56 BM_56_33 +#define BM_57_33 0x03fffffe00000000 +#define BM_33_57 BM_57_33 +#define BM_58_33 0x07fffffe00000000 +#define BM_33_58 BM_58_33 +#define BM_59_33 0x0ffffffe00000000 +#define BM_33_59 BM_59_33 +#define BM_60_33 0x1ffffffe00000000 +#define BM_33_60 BM_60_33 +#define BM_61_33 0x3ffffffe00000000 +#define BM_33_61 BM_61_33 +#define BM_62_33 0x7ffffffe00000000 +#define BM_33_62 BM_62_33 +#define BM_63_33 0xfffffffe00000000 +#define BM_33_63 BM_63_33 +#define BM_34_34 0x0000000400000000 +#define BM_35_34 0x0000000c00000000 +#define BM_34_35 BM_35_34 +#define BM_36_34 0x0000001c00000000 +#define BM_34_36 BM_36_34 +#define BM_37_34 0x0000003c00000000 +#define BM_34_37 BM_37_34 +#define BM_38_34 0x0000007c00000000 +#define BM_34_38 BM_38_34 +#define BM_39_34 0x000000fc00000000 +#define BM_34_39 BM_39_34 +#define BM_40_34 0x000001fc00000000 +#define BM_34_40 BM_40_34 +#define BM_41_34 0x000003fc00000000 +#define BM_34_41 BM_41_34 +#define BM_42_34 0x000007fc00000000 +#define BM_34_42 BM_42_34 +#define BM_43_34 0x00000ffc00000000 +#define BM_34_43 BM_43_34 +#define BM_44_34 0x00001ffc00000000 +#define BM_34_44 BM_44_34 +#define BM_45_34 0x00003ffc00000000 +#define BM_34_45 BM_45_34 +#define BM_46_34 0x00007ffc00000000 +#define BM_34_46 BM_46_34 +#define BM_47_34 0x0000fffc00000000 +#define BM_34_47 BM_47_34 +#define BM_48_34 0x0001fffc00000000 +#define BM_34_48 BM_48_34 +#define BM_49_34 0x0003fffc00000000 +#define BM_34_49 BM_49_34 +#define BM_50_34 0x0007fffc00000000 +#define BM_34_50 BM_50_34 +#define BM_51_34 0x000ffffc00000000 +#define BM_34_51 BM_51_34 +#define BM_52_34 0x001ffffc00000000 +#define BM_34_52 BM_52_34 +#define BM_53_34 0x003ffffc00000000 +#define BM_34_53 BM_53_34 +#define BM_54_34 0x007ffffc00000000 +#define BM_34_54 BM_54_34 +#define BM_55_34 0x00fffffc00000000 +#define BM_34_55 BM_55_34 +#define BM_56_34 0x01fffffc00000000 +#define BM_34_56 BM_56_34 +#define BM_57_34 0x03fffffc00000000 +#define BM_34_57 BM_57_34 +#define BM_58_34 0x07fffffc00000000 +#define BM_34_58 BM_58_34 +#define BM_59_34 0x0ffffffc00000000 +#define BM_34_59 BM_59_34 +#define BM_60_34 0x1ffffffc00000000 +#define BM_34_60 BM_60_34 +#define BM_61_34 0x3ffffffc00000000 +#define BM_34_61 BM_61_34 +#define BM_62_34 0x7ffffffc00000000 +#define BM_34_62 BM_62_34 +#define BM_63_34 0xfffffffc00000000 +#define BM_34_63 BM_63_34 +#define BM_35_35 0x0000000800000000 +#define BM_36_35 0x0000001800000000 +#define BM_35_36 BM_36_35 +#define BM_37_35 0x0000003800000000 +#define BM_35_37 BM_37_35 +#define BM_38_35 0x0000007800000000 +#define BM_35_38 BM_38_35 +#define BM_39_35 0x000000f800000000 +#define BM_35_39 BM_39_35 +#define BM_40_35 0x000001f800000000 +#define BM_35_40 BM_40_35 +#define BM_41_35 0x000003f800000000 +#define BM_35_41 BM_41_35 +#define BM_42_35 0x000007f800000000 +#define BM_35_42 BM_42_35 +#define BM_43_35 0x00000ff800000000 +#define BM_35_43 BM_43_35 +#define BM_44_35 0x00001ff800000000 +#define BM_35_44 BM_44_35 +#define BM_45_35 0x00003ff800000000 +#define BM_35_45 BM_45_35 +#define BM_46_35 0x00007ff800000000 +#define BM_35_46 BM_46_35 +#define BM_47_35 0x0000fff800000000 +#define BM_35_47 BM_47_35 +#define BM_48_35 0x0001fff800000000 +#define BM_35_48 BM_48_35 +#define BM_49_35 0x0003fff800000000 +#define BM_35_49 BM_49_35 +#define BM_50_35 0x0007fff800000000 +#define BM_35_50 BM_50_35 +#define BM_51_35 0x000ffff800000000 +#define BM_35_51 BM_51_35 +#define BM_52_35 0x001ffff800000000 +#define BM_35_52 BM_52_35 +#define BM_53_35 0x003ffff800000000 +#define BM_35_53 BM_53_35 +#define BM_54_35 0x007ffff800000000 +#define BM_35_54 BM_54_35 +#define BM_55_35 0x00fffff800000000 +#define BM_35_55 BM_55_35 +#define BM_56_35 0x01fffff800000000 +#define BM_35_56 BM_56_35 +#define BM_57_35 0x03fffff800000000 +#define BM_35_57 BM_57_35 +#define BM_58_35 0x07fffff800000000 +#define BM_35_58 BM_58_35 +#define BM_59_35 0x0ffffff800000000 +#define BM_35_59 BM_59_35 +#define BM_60_35 0x1ffffff800000000 +#define BM_35_60 BM_60_35 +#define BM_61_35 0x3ffffff800000000 +#define BM_35_61 BM_61_35 +#define BM_62_35 0x7ffffff800000000 +#define BM_35_62 BM_62_35 +#define BM_63_35 0xfffffff800000000 +#define BM_35_63 BM_63_35 +#define BM_36_36 0x0000001000000000 +#define BM_37_36 0x0000003000000000 +#define BM_36_37 BM_37_36 +#define BM_38_36 0x0000007000000000 +#define BM_36_38 BM_38_36 +#define BM_39_36 0x000000f000000000 +#define BM_36_39 BM_39_36 +#define BM_40_36 0x000001f000000000 +#define BM_36_40 BM_40_36 +#define BM_41_36 0x000003f000000000 +#define BM_36_41 BM_41_36 +#define BM_42_36 0x000007f000000000 +#define BM_36_42 BM_42_36 +#define BM_43_36 0x00000ff000000000 +#define BM_36_43 BM_43_36 +#define BM_44_36 0x00001ff000000000 +#define BM_36_44 BM_44_36 +#define BM_45_36 0x00003ff000000000 +#define BM_36_45 BM_45_36 +#define BM_46_36 0x00007ff000000000 +#define BM_36_46 BM_46_36 +#define BM_47_36 0x0000fff000000000 +#define BM_36_47 BM_47_36 +#define BM_48_36 0x0001fff000000000 +#define BM_36_48 BM_48_36 +#define BM_49_36 0x0003fff000000000 +#define BM_36_49 BM_49_36 +#define BM_50_36 0x0007fff000000000 +#define BM_36_50 BM_50_36 +#define BM_51_36 0x000ffff000000000 +#define BM_36_51 BM_51_36 +#define BM_52_36 0x001ffff000000000 +#define BM_36_52 BM_52_36 +#define BM_53_36 0x003ffff000000000 +#define BM_36_53 BM_53_36 +#define BM_54_36 0x007ffff000000000 +#define BM_36_54 BM_54_36 +#define BM_55_36 0x00fffff000000000 +#define BM_36_55 BM_55_36 +#define BM_56_36 0x01fffff000000000 +#define BM_36_56 BM_56_36 +#define BM_57_36 0x03fffff000000000 +#define BM_36_57 BM_57_36 +#define BM_58_36 0x07fffff000000000 +#define BM_36_58 BM_58_36 +#define BM_59_36 0x0ffffff000000000 +#define BM_36_59 BM_59_36 +#define BM_60_36 0x1ffffff000000000 +#define BM_36_60 BM_60_36 +#define BM_61_36 0x3ffffff000000000 +#define BM_36_61 BM_61_36 +#define BM_62_36 0x7ffffff000000000 +#define BM_36_62 BM_62_36 +#define BM_63_36 0xfffffff000000000 +#define BM_36_63 BM_63_36 +#define BM_37_37 0x0000002000000000 +#define BM_38_37 0x0000006000000000 +#define BM_37_38 BM_38_37 +#define BM_39_37 0x000000e000000000 +#define BM_37_39 BM_39_37 +#define BM_40_37 0x000001e000000000 +#define BM_37_40 BM_40_37 +#define BM_41_37 0x000003e000000000 +#define BM_37_41 BM_41_37 +#define BM_42_37 0x000007e000000000 +#define BM_37_42 BM_42_37 +#define BM_43_37 0x00000fe000000000 +#define BM_37_43 BM_43_37 +#define BM_44_37 0x00001fe000000000 +#define BM_37_44 BM_44_37 +#define BM_45_37 0x00003fe000000000 +#define BM_37_45 BM_45_37 +#define BM_46_37 0x00007fe000000000 +#define BM_37_46 BM_46_37 +#define BM_47_37 0x0000ffe000000000 +#define BM_37_47 BM_47_37 +#define BM_48_37 0x0001ffe000000000 +#define BM_37_48 BM_48_37 +#define BM_49_37 0x0003ffe000000000 +#define BM_37_49 BM_49_37 +#define BM_50_37 0x0007ffe000000000 +#define BM_37_50 BM_50_37 +#define BM_51_37 0x000fffe000000000 +#define BM_37_51 BM_51_37 +#define BM_52_37 0x001fffe000000000 +#define BM_37_52 BM_52_37 +#define BM_53_37 0x003fffe000000000 +#define BM_37_53 BM_53_37 +#define BM_54_37 0x007fffe000000000 +#define BM_37_54 BM_54_37 +#define BM_55_37 0x00ffffe000000000 +#define BM_37_55 BM_55_37 +#define BM_56_37 0x01ffffe000000000 +#define BM_37_56 BM_56_37 +#define BM_57_37 0x03ffffe000000000 +#define BM_37_57 BM_57_37 +#define BM_58_37 0x07ffffe000000000 +#define BM_37_58 BM_58_37 +#define BM_59_37 0x0fffffe000000000 +#define BM_37_59 BM_59_37 +#define BM_60_37 0x1fffffe000000000 +#define BM_37_60 BM_60_37 +#define BM_61_37 0x3fffffe000000000 +#define BM_37_61 BM_61_37 +#define BM_62_37 0x7fffffe000000000 +#define BM_37_62 BM_62_37 +#define BM_63_37 0xffffffe000000000 +#define BM_37_63 BM_63_37 +#define BM_38_38 0x0000004000000000 +#define BM_39_38 0x000000c000000000 +#define BM_38_39 BM_39_38 +#define BM_40_38 0x000001c000000000 +#define BM_38_40 BM_40_38 +#define BM_41_38 0x000003c000000000 +#define BM_38_41 BM_41_38 +#define BM_42_38 0x000007c000000000 +#define BM_38_42 BM_42_38 +#define BM_43_38 0x00000fc000000000 +#define BM_38_43 BM_43_38 +#define BM_44_38 0x00001fc000000000 +#define BM_38_44 BM_44_38 +#define BM_45_38 0x00003fc000000000 +#define BM_38_45 BM_45_38 +#define BM_46_38 0x00007fc000000000 +#define BM_38_46 BM_46_38 +#define BM_47_38 0x0000ffc000000000 +#define BM_38_47 BM_47_38 +#define BM_48_38 0x0001ffc000000000 +#define BM_38_48 BM_48_38 +#define BM_49_38 0x0003ffc000000000 +#define BM_38_49 BM_49_38 +#define BM_50_38 0x0007ffc000000000 +#define BM_38_50 BM_50_38 +#define BM_51_38 0x000fffc000000000 +#define BM_38_51 BM_51_38 +#define BM_52_38 0x001fffc000000000 +#define BM_38_52 BM_52_38 +#define BM_53_38 0x003fffc000000000 +#define BM_38_53 BM_53_38 +#define BM_54_38 0x007fffc000000000 +#define BM_38_54 BM_54_38 +#define BM_55_38 0x00ffffc000000000 +#define BM_38_55 BM_55_38 +#define BM_56_38 0x01ffffc000000000 +#define BM_38_56 BM_56_38 +#define BM_57_38 0x03ffffc000000000 +#define BM_38_57 BM_57_38 +#define BM_58_38 0x07ffffc000000000 +#define BM_38_58 BM_58_38 +#define BM_59_38 0x0fffffc000000000 +#define BM_38_59 BM_59_38 +#define BM_60_38 0x1fffffc000000000 +#define BM_38_60 BM_60_38 +#define BM_61_38 0x3fffffc000000000 +#define BM_38_61 BM_61_38 +#define BM_62_38 0x7fffffc000000000 +#define BM_38_62 BM_62_38 +#define BM_63_38 0xffffffc000000000 +#define BM_38_63 BM_63_38 +#define BM_39_39 0x0000008000000000 +#define BM_40_39 0x0000018000000000 +#define BM_39_40 BM_40_39 +#define BM_41_39 0x0000038000000000 +#define BM_39_41 BM_41_39 +#define BM_42_39 0x0000078000000000 +#define BM_39_42 BM_42_39 +#define BM_43_39 0x00000f8000000000 +#define BM_39_43 BM_43_39 +#define BM_44_39 0x00001f8000000000 +#define BM_39_44 BM_44_39 +#define BM_45_39 0x00003f8000000000 +#define BM_39_45 BM_45_39 +#define BM_46_39 0x00007f8000000000 +#define BM_39_46 BM_46_39 +#define BM_47_39 0x0000ff8000000000 +#define BM_39_47 BM_47_39 +#define BM_48_39 0x0001ff8000000000 +#define BM_39_48 BM_48_39 +#define BM_49_39 0x0003ff8000000000 +#define BM_39_49 BM_49_39 +#define BM_50_39 0x0007ff8000000000 +#define BM_39_50 BM_50_39 +#define BM_51_39 0x000fff8000000000 +#define BM_39_51 BM_51_39 +#define BM_52_39 0x001fff8000000000 +#define BM_39_52 BM_52_39 +#define BM_53_39 0x003fff8000000000 +#define BM_39_53 BM_53_39 +#define BM_54_39 0x007fff8000000000 +#define BM_39_54 BM_54_39 +#define BM_55_39 0x00ffff8000000000 +#define BM_39_55 BM_55_39 +#define BM_56_39 0x01ffff8000000000 +#define BM_39_56 BM_56_39 +#define BM_57_39 0x03ffff8000000000 +#define BM_39_57 BM_57_39 +#define BM_58_39 0x07ffff8000000000 +#define BM_39_58 BM_58_39 +#define BM_59_39 0x0fffff8000000000 +#define BM_39_59 BM_59_39 +#define BM_60_39 0x1fffff8000000000 +#define BM_39_60 BM_60_39 +#define BM_61_39 0x3fffff8000000000 +#define BM_39_61 BM_61_39 +#define BM_62_39 0x7fffff8000000000 +#define BM_39_62 BM_62_39 +#define BM_63_39 0xffffff8000000000 +#define BM_39_63 BM_63_39 +#define BM_40_40 0x0000010000000000 +#define BM_41_40 0x0000030000000000 +#define BM_40_41 BM_41_40 +#define BM_42_40 0x0000070000000000 +#define BM_40_42 BM_42_40 +#define BM_43_40 0x00000f0000000000 +#define BM_40_43 BM_43_40 +#define BM_44_40 0x00001f0000000000 +#define BM_40_44 BM_44_40 +#define BM_45_40 0x00003f0000000000 +#define BM_40_45 BM_45_40 +#define BM_46_40 0x00007f0000000000 +#define BM_40_46 BM_46_40 +#define BM_47_40 0x0000ff0000000000 +#define BM_40_47 BM_47_40 +#define BM_48_40 0x0001ff0000000000 +#define BM_40_48 BM_48_40 +#define BM_49_40 0x0003ff0000000000 +#define BM_40_49 BM_49_40 +#define BM_50_40 0x0007ff0000000000 +#define BM_40_50 BM_50_40 +#define BM_51_40 0x000fff0000000000 +#define BM_40_51 BM_51_40 +#define BM_52_40 0x001fff0000000000 +#define BM_40_52 BM_52_40 +#define BM_53_40 0x003fff0000000000 +#define BM_40_53 BM_53_40 +#define BM_54_40 0x007fff0000000000 +#define BM_40_54 BM_54_40 +#define BM_55_40 0x00ffff0000000000 +#define BM_40_55 BM_55_40 +#define BM_56_40 0x01ffff0000000000 +#define BM_40_56 BM_56_40 +#define BM_57_40 0x03ffff0000000000 +#define BM_40_57 BM_57_40 +#define BM_58_40 0x07ffff0000000000 +#define BM_40_58 BM_58_40 +#define BM_59_40 0x0fffff0000000000 +#define BM_40_59 BM_59_40 +#define BM_60_40 0x1fffff0000000000 +#define BM_40_60 BM_60_40 +#define BM_61_40 0x3fffff0000000000 +#define BM_40_61 BM_61_40 +#define BM_62_40 0x7fffff0000000000 +#define BM_40_62 BM_62_40 +#define BM_63_40 0xffffff0000000000 +#define BM_40_63 BM_63_40 +#define BM_41_41 0x0000020000000000 +#define BM_42_41 0x0000060000000000 +#define BM_41_42 BM_42_41 +#define BM_43_41 0x00000e0000000000 +#define BM_41_43 BM_43_41 +#define BM_44_41 0x00001e0000000000 +#define BM_41_44 BM_44_41 +#define BM_45_41 0x00003e0000000000 +#define BM_41_45 BM_45_41 +#define BM_46_41 0x00007e0000000000 +#define BM_41_46 BM_46_41 +#define BM_47_41 0x0000fe0000000000 +#define BM_41_47 BM_47_41 +#define BM_48_41 0x0001fe0000000000 +#define BM_41_48 BM_48_41 +#define BM_49_41 0x0003fe0000000000 +#define BM_41_49 BM_49_41 +#define BM_50_41 0x0007fe0000000000 +#define BM_41_50 BM_50_41 +#define BM_51_41 0x000ffe0000000000 +#define BM_41_51 BM_51_41 +#define BM_52_41 0x001ffe0000000000 +#define BM_41_52 BM_52_41 +#define BM_53_41 0x003ffe0000000000 +#define BM_41_53 BM_53_41 +#define BM_54_41 0x007ffe0000000000 +#define BM_41_54 BM_54_41 +#define BM_55_41 0x00fffe0000000000 +#define BM_41_55 BM_55_41 +#define BM_56_41 0x01fffe0000000000 +#define BM_41_56 BM_56_41 +#define BM_57_41 0x03fffe0000000000 +#define BM_41_57 BM_57_41 +#define BM_58_41 0x07fffe0000000000 +#define BM_41_58 BM_58_41 +#define BM_59_41 0x0ffffe0000000000 +#define BM_41_59 BM_59_41 +#define BM_60_41 0x1ffffe0000000000 +#define BM_41_60 BM_60_41 +#define BM_61_41 0x3ffffe0000000000 +#define BM_41_61 BM_61_41 +#define BM_62_41 0x7ffffe0000000000 +#define BM_41_62 BM_62_41 +#define BM_63_41 0xfffffe0000000000 +#define BM_41_63 BM_63_41 +#define BM_42_42 0x0000040000000000 +#define BM_43_42 0x00000c0000000000 +#define BM_42_43 BM_43_42 +#define BM_44_42 0x00001c0000000000 +#define BM_42_44 BM_44_42 +#define BM_45_42 0x00003c0000000000 +#define BM_42_45 BM_45_42 +#define BM_46_42 0x00007c0000000000 +#define BM_42_46 BM_46_42 +#define BM_47_42 0x0000fc0000000000 +#define BM_42_47 BM_47_42 +#define BM_48_42 0x0001fc0000000000 +#define BM_42_48 BM_48_42 +#define BM_49_42 0x0003fc0000000000 +#define BM_42_49 BM_49_42 +#define BM_50_42 0x0007fc0000000000 +#define BM_42_50 BM_50_42 +#define BM_51_42 0x000ffc0000000000 +#define BM_42_51 BM_51_42 +#define BM_52_42 0x001ffc0000000000 +#define BM_42_52 BM_52_42 +#define BM_53_42 0x003ffc0000000000 +#define BM_42_53 BM_53_42 +#define BM_54_42 0x007ffc0000000000 +#define BM_42_54 BM_54_42 +#define BM_55_42 0x00fffc0000000000 +#define BM_42_55 BM_55_42 +#define BM_56_42 0x01fffc0000000000 +#define BM_42_56 BM_56_42 +#define BM_57_42 0x03fffc0000000000 +#define BM_42_57 BM_57_42 +#define BM_58_42 0x07fffc0000000000 +#define BM_42_58 BM_58_42 +#define BM_59_42 0x0ffffc0000000000 +#define BM_42_59 BM_59_42 +#define BM_60_42 0x1ffffc0000000000 +#define BM_42_60 BM_60_42 +#define BM_61_42 0x3ffffc0000000000 +#define BM_42_61 BM_61_42 +#define BM_62_42 0x7ffffc0000000000 +#define BM_42_62 BM_62_42 +#define BM_63_42 0xfffffc0000000000 +#define BM_42_63 BM_63_42 +#define BM_43_43 0x0000080000000000 +#define BM_44_43 0x0000180000000000 +#define BM_43_44 BM_44_43 +#define BM_45_43 0x0000380000000000 +#define BM_43_45 BM_45_43 +#define BM_46_43 0x0000780000000000 +#define BM_43_46 BM_46_43 +#define BM_47_43 0x0000f80000000000 +#define BM_43_47 BM_47_43 +#define BM_48_43 0x0001f80000000000 +#define BM_43_48 BM_48_43 +#define BM_49_43 0x0003f80000000000 +#define BM_43_49 BM_49_43 +#define BM_50_43 0x0007f80000000000 +#define BM_43_50 BM_50_43 +#define BM_51_43 0x000ff80000000000 +#define BM_43_51 BM_51_43 +#define BM_52_43 0x001ff80000000000 +#define BM_43_52 BM_52_43 +#define BM_53_43 0x003ff80000000000 +#define BM_43_53 BM_53_43 +#define BM_54_43 0x007ff80000000000 +#define BM_43_54 BM_54_43 +#define BM_55_43 0x00fff80000000000 +#define BM_43_55 BM_55_43 +#define BM_56_43 0x01fff80000000000 +#define BM_43_56 BM_56_43 +#define BM_57_43 0x03fff80000000000 +#define BM_43_57 BM_57_43 +#define BM_58_43 0x07fff80000000000 +#define BM_43_58 BM_58_43 +#define BM_59_43 0x0ffff80000000000 +#define BM_43_59 BM_59_43 +#define BM_60_43 0x1ffff80000000000 +#define BM_43_60 BM_60_43 +#define BM_61_43 0x3ffff80000000000 +#define BM_43_61 BM_61_43 +#define BM_62_43 0x7ffff80000000000 +#define BM_43_62 BM_62_43 +#define BM_63_43 0xfffff80000000000 +#define BM_43_63 BM_63_43 +#define BM_44_44 0x0000100000000000 +#define BM_45_44 0x0000300000000000 +#define BM_44_45 BM_45_44 +#define BM_46_44 0x0000700000000000 +#define BM_44_46 BM_46_44 +#define BM_47_44 0x0000f00000000000 +#define BM_44_47 BM_47_44 +#define BM_48_44 0x0001f00000000000 +#define BM_44_48 BM_48_44 +#define BM_49_44 0x0003f00000000000 +#define BM_44_49 BM_49_44 +#define BM_50_44 0x0007f00000000000 +#define BM_44_50 BM_50_44 +#define BM_51_44 0x000ff00000000000 +#define BM_44_51 BM_51_44 +#define BM_52_44 0x001ff00000000000 +#define BM_44_52 BM_52_44 +#define BM_53_44 0x003ff00000000000 +#define BM_44_53 BM_53_44 +#define BM_54_44 0x007ff00000000000 +#define BM_44_54 BM_54_44 +#define BM_55_44 0x00fff00000000000 +#define BM_44_55 BM_55_44 +#define BM_56_44 0x01fff00000000000 +#define BM_44_56 BM_56_44 +#define BM_57_44 0x03fff00000000000 +#define BM_44_57 BM_57_44 +#define BM_58_44 0x07fff00000000000 +#define BM_44_58 BM_58_44 +#define BM_59_44 0x0ffff00000000000 +#define BM_44_59 BM_59_44 +#define BM_60_44 0x1ffff00000000000 +#define BM_44_60 BM_60_44 +#define BM_61_44 0x3ffff00000000000 +#define BM_44_61 BM_61_44 +#define BM_62_44 0x7ffff00000000000 +#define BM_44_62 BM_62_44 +#define BM_63_44 0xfffff00000000000 +#define BM_44_63 BM_63_44 +#define BM_45_45 0x0000200000000000 +#define BM_46_45 0x0000600000000000 +#define BM_45_46 BM_46_45 +#define BM_47_45 0x0000e00000000000 +#define BM_45_47 BM_47_45 +#define BM_48_45 0x0001e00000000000 +#define BM_45_48 BM_48_45 +#define BM_49_45 0x0003e00000000000 +#define BM_45_49 BM_49_45 +#define BM_50_45 0x0007e00000000000 +#define BM_45_50 BM_50_45 +#define BM_51_45 0x000fe00000000000 +#define BM_45_51 BM_51_45 +#define BM_52_45 0x001fe00000000000 +#define BM_45_52 BM_52_45 +#define BM_53_45 0x003fe00000000000 +#define BM_45_53 BM_53_45 +#define BM_54_45 0x007fe00000000000 +#define BM_45_54 BM_54_45 +#define BM_55_45 0x00ffe00000000000 +#define BM_45_55 BM_55_45 +#define BM_56_45 0x01ffe00000000000 +#define BM_45_56 BM_56_45 +#define BM_57_45 0x03ffe00000000000 +#define BM_45_57 BM_57_45 +#define BM_58_45 0x07ffe00000000000 +#define BM_45_58 BM_58_45 +#define BM_59_45 0x0fffe00000000000 +#define BM_45_59 BM_59_45 +#define BM_60_45 0x1fffe00000000000 +#define BM_45_60 BM_60_45 +#define BM_61_45 0x3fffe00000000000 +#define BM_45_61 BM_61_45 +#define BM_62_45 0x7fffe00000000000 +#define BM_45_62 BM_62_45 +#define BM_63_45 0xffffe00000000000 +#define BM_45_63 BM_63_45 +#define BM_46_46 0x0000400000000000 +#define BM_47_46 0x0000c00000000000 +#define BM_46_47 BM_47_46 +#define BM_48_46 0x0001c00000000000 +#define BM_46_48 BM_48_46 +#define BM_49_46 0x0003c00000000000 +#define BM_46_49 BM_49_46 +#define BM_50_46 0x0007c00000000000 +#define BM_46_50 BM_50_46 +#define BM_51_46 0x000fc00000000000 +#define BM_46_51 BM_51_46 +#define BM_52_46 0x001fc00000000000 +#define BM_46_52 BM_52_46 +#define BM_53_46 0x003fc00000000000 +#define BM_46_53 BM_53_46 +#define BM_54_46 0x007fc00000000000 +#define BM_46_54 BM_54_46 +#define BM_55_46 0x00ffc00000000000 +#define BM_46_55 BM_55_46 +#define BM_56_46 0x01ffc00000000000 +#define BM_46_56 BM_56_46 +#define BM_57_46 0x03ffc00000000000 +#define BM_46_57 BM_57_46 +#define BM_58_46 0x07ffc00000000000 +#define BM_46_58 BM_58_46 +#define BM_59_46 0x0fffc00000000000 +#define BM_46_59 BM_59_46 +#define BM_60_46 0x1fffc00000000000 +#define BM_46_60 BM_60_46 +#define BM_61_46 0x3fffc00000000000 +#define BM_46_61 BM_61_46 +#define BM_62_46 0x7fffc00000000000 +#define BM_46_62 BM_62_46 +#define BM_63_46 0xffffc00000000000 +#define BM_46_63 BM_63_46 +#define BM_47_47 0x0000800000000000 +#define BM_48_47 0x0001800000000000 +#define BM_47_48 BM_48_47 +#define BM_49_47 0x0003800000000000 +#define BM_47_49 BM_49_47 +#define BM_50_47 0x0007800000000000 +#define BM_47_50 BM_50_47 +#define BM_51_47 0x000f800000000000 +#define BM_47_51 BM_51_47 +#define BM_52_47 0x001f800000000000 +#define BM_47_52 BM_52_47 +#define BM_53_47 0x003f800000000000 +#define BM_47_53 BM_53_47 +#define BM_54_47 0x007f800000000000 +#define BM_47_54 BM_54_47 +#define BM_55_47 0x00ff800000000000 +#define BM_47_55 BM_55_47 +#define BM_56_47 0x01ff800000000000 +#define BM_47_56 BM_56_47 +#define BM_57_47 0x03ff800000000000 +#define BM_47_57 BM_57_47 +#define BM_58_47 0x07ff800000000000 +#define BM_47_58 BM_58_47 +#define BM_59_47 0x0fff800000000000 +#define BM_47_59 BM_59_47 +#define BM_60_47 0x1fff800000000000 +#define BM_47_60 BM_60_47 +#define BM_61_47 0x3fff800000000000 +#define BM_47_61 BM_61_47 +#define BM_62_47 0x7fff800000000000 +#define BM_47_62 BM_62_47 +#define BM_63_47 0xffff800000000000 +#define BM_47_63 BM_63_47 +#define BM_48_48 0x0001000000000000 +#define BM_49_48 0x0003000000000000 +#define BM_48_49 BM_49_48 +#define BM_50_48 0x0007000000000000 +#define BM_48_50 BM_50_48 +#define BM_51_48 0x000f000000000000 +#define BM_48_51 BM_51_48 +#define BM_52_48 0x001f000000000000 +#define BM_48_52 BM_52_48 +#define BM_53_48 0x003f000000000000 +#define BM_48_53 BM_53_48 +#define BM_54_48 0x007f000000000000 +#define BM_48_54 BM_54_48 +#define BM_55_48 0x00ff000000000000 +#define BM_48_55 BM_55_48 +#define BM_56_48 0x01ff000000000000 +#define BM_48_56 BM_56_48 +#define BM_57_48 0x03ff000000000000 +#define BM_48_57 BM_57_48 +#define BM_58_48 0x07ff000000000000 +#define BM_48_58 BM_58_48 +#define BM_59_48 0x0fff000000000000 +#define BM_48_59 BM_59_48 +#define BM_60_48 0x1fff000000000000 +#define BM_48_60 BM_60_48 +#define BM_61_48 0x3fff000000000000 +#define BM_48_61 BM_61_48 +#define BM_62_48 0x7fff000000000000 +#define BM_48_62 BM_62_48 +#define BM_63_48 0xffff000000000000 +#define BM_48_63 BM_63_48 +#define BM_49_49 0x0002000000000000 +#define BM_50_49 0x0006000000000000 +#define BM_49_50 BM_50_49 +#define BM_51_49 0x000e000000000000 +#define BM_49_51 BM_51_49 +#define BM_52_49 0x001e000000000000 +#define BM_49_52 BM_52_49 +#define BM_53_49 0x003e000000000000 +#define BM_49_53 BM_53_49 +#define BM_54_49 0x007e000000000000 +#define BM_49_54 BM_54_49 +#define BM_55_49 0x00fe000000000000 +#define BM_49_55 BM_55_49 +#define BM_56_49 0x01fe000000000000 +#define BM_49_56 BM_56_49 +#define BM_57_49 0x03fe000000000000 +#define BM_49_57 BM_57_49 +#define BM_58_49 0x07fe000000000000 +#define BM_49_58 BM_58_49 +#define BM_59_49 0x0ffe000000000000 +#define BM_49_59 BM_59_49 +#define BM_60_49 0x1ffe000000000000 +#define BM_49_60 BM_60_49 +#define BM_61_49 0x3ffe000000000000 +#define BM_49_61 BM_61_49 +#define BM_62_49 0x7ffe000000000000 +#define BM_49_62 BM_62_49 +#define BM_63_49 0xfffe000000000000 +#define BM_49_63 BM_63_49 +#define BM_50_50 0x0004000000000000 +#define BM_51_50 0x000c000000000000 +#define BM_50_51 BM_51_50 +#define BM_52_50 0x001c000000000000 +#define BM_50_52 BM_52_50 +#define BM_53_50 0x003c000000000000 +#define BM_50_53 BM_53_50 +#define BM_54_50 0x007c000000000000 +#define BM_50_54 BM_54_50 +#define BM_55_50 0x00fc000000000000 +#define BM_50_55 BM_55_50 +#define BM_56_50 0x01fc000000000000 +#define BM_50_56 BM_56_50 +#define BM_57_50 0x03fc000000000000 +#define BM_50_57 BM_57_50 +#define BM_58_50 0x07fc000000000000 +#define BM_50_58 BM_58_50 +#define BM_59_50 0x0ffc000000000000 +#define BM_50_59 BM_59_50 +#define BM_60_50 0x1ffc000000000000 +#define BM_50_60 BM_60_50 +#define BM_61_50 0x3ffc000000000000 +#define BM_50_61 BM_61_50 +#define BM_62_50 0x7ffc000000000000 +#define BM_50_62 BM_62_50 +#define BM_63_50 0xfffc000000000000 +#define BM_50_63 BM_63_50 +#define BM_51_51 0x0008000000000000 +#define BM_52_51 0x0018000000000000 +#define BM_51_52 BM_52_51 +#define BM_53_51 0x0038000000000000 +#define BM_51_53 BM_53_51 +#define BM_54_51 0x0078000000000000 +#define BM_51_54 BM_54_51 +#define BM_55_51 0x00f8000000000000 +#define BM_51_55 BM_55_51 +#define BM_56_51 0x01f8000000000000 +#define BM_51_56 BM_56_51 +#define BM_57_51 0x03f8000000000000 +#define BM_51_57 BM_57_51 +#define BM_58_51 0x07f8000000000000 +#define BM_51_58 BM_58_51 +#define BM_59_51 0x0ff8000000000000 +#define BM_51_59 BM_59_51 +#define BM_60_51 0x1ff8000000000000 +#define BM_51_60 BM_60_51 +#define BM_61_51 0x3ff8000000000000 +#define BM_51_61 BM_61_51 +#define BM_62_51 0x7ff8000000000000 +#define BM_51_62 BM_62_51 +#define BM_63_51 0xfff8000000000000 +#define BM_51_63 BM_63_51 +#define BM_52_52 0x0010000000000000 +#define BM_53_52 0x0030000000000000 +#define BM_52_53 BM_53_52 +#define BM_54_52 0x0070000000000000 +#define BM_52_54 BM_54_52 +#define BM_55_52 0x00f0000000000000 +#define BM_52_55 BM_55_52 +#define BM_56_52 0x01f0000000000000 +#define BM_52_56 BM_56_52 +#define BM_57_52 0x03f0000000000000 +#define BM_52_57 BM_57_52 +#define BM_58_52 0x07f0000000000000 +#define BM_52_58 BM_58_52 +#define BM_59_52 0x0ff0000000000000 +#define BM_52_59 BM_59_52 +#define BM_60_52 0x1ff0000000000000 +#define BM_52_60 BM_60_52 +#define BM_61_52 0x3ff0000000000000 +#define BM_52_61 BM_61_52 +#define BM_62_52 0x7ff0000000000000 +#define BM_52_62 BM_62_52 +#define BM_63_52 0xfff0000000000000 +#define BM_52_63 BM_63_52 +#define BM_53_53 0x0020000000000000 +#define BM_54_53 0x0060000000000000 +#define BM_53_54 BM_54_53 +#define BM_55_53 0x00e0000000000000 +#define BM_53_55 BM_55_53 +#define BM_56_53 0x01e0000000000000 +#define BM_53_56 BM_56_53 +#define BM_57_53 0x03e0000000000000 +#define BM_53_57 BM_57_53 +#define BM_58_53 0x07e0000000000000 +#define BM_53_58 BM_58_53 +#define BM_59_53 0x0fe0000000000000 +#define BM_53_59 BM_59_53 +#define BM_60_53 0x1fe0000000000000 +#define BM_53_60 BM_60_53 +#define BM_61_53 0x3fe0000000000000 +#define BM_53_61 BM_61_53 +#define BM_62_53 0x7fe0000000000000 +#define BM_53_62 BM_62_53 +#define BM_63_53 0xffe0000000000000 +#define BM_53_63 BM_63_53 +#define BM_54_54 0x0040000000000000 +#define BM_55_54 0x00c0000000000000 +#define BM_54_55 BM_55_54 +#define BM_56_54 0x01c0000000000000 +#define BM_54_56 BM_56_54 +#define BM_57_54 0x03c0000000000000 +#define BM_54_57 BM_57_54 +#define BM_58_54 0x07c0000000000000 +#define BM_54_58 BM_58_54 +#define BM_59_54 0x0fc0000000000000 +#define BM_54_59 BM_59_54 +#define BM_60_54 0x1fc0000000000000 +#define BM_54_60 BM_60_54 +#define BM_61_54 0x3fc0000000000000 +#define BM_54_61 BM_61_54 +#define BM_62_54 0x7fc0000000000000 +#define BM_54_62 BM_62_54 +#define BM_63_54 0xffc0000000000000 +#define BM_54_63 BM_63_54 +#define BM_55_55 0x0080000000000000 +#define BM_56_55 0x0180000000000000 +#define BM_55_56 BM_56_55 +#define BM_57_55 0x0380000000000000 +#define BM_55_57 BM_57_55 +#define BM_58_55 0x0780000000000000 +#define BM_55_58 BM_58_55 +#define BM_59_55 0x0f80000000000000 +#define BM_55_59 BM_59_55 +#define BM_60_55 0x1f80000000000000 +#define BM_55_60 BM_60_55 +#define BM_61_55 0x3f80000000000000 +#define BM_55_61 BM_61_55 +#define BM_62_55 0x7f80000000000000 +#define BM_55_62 BM_62_55 +#define BM_63_55 0xff80000000000000 +#define BM_55_63 BM_63_55 +#define BM_56_56 0x0100000000000000 +#define BM_57_56 0x0300000000000000 +#define BM_56_57 BM_57_56 +#define BM_58_56 0x0700000000000000 +#define BM_56_58 BM_58_56 +#define BM_59_56 0x0f00000000000000 +#define BM_56_59 BM_59_56 +#define BM_60_56 0x1f00000000000000 +#define BM_56_60 BM_60_56 +#define BM_61_56 0x3f00000000000000 +#define BM_56_61 BM_61_56 +#define BM_62_56 0x7f00000000000000 +#define BM_56_62 BM_62_56 +#define BM_63_56 0xff00000000000000 +#define BM_56_63 BM_63_56 +#define BM_57_57 0x0200000000000000 +#define BM_58_57 0x0600000000000000 +#define BM_57_58 BM_58_57 +#define BM_59_57 0x0e00000000000000 +#define BM_57_59 BM_59_57 +#define BM_60_57 0x1e00000000000000 +#define BM_57_60 BM_60_57 +#define BM_61_57 0x3e00000000000000 +#define BM_57_61 BM_61_57 +#define BM_62_57 0x7e00000000000000 +#define BM_57_62 BM_62_57 +#define BM_63_57 0xfe00000000000000 +#define BM_57_63 BM_63_57 +#define BM_58_58 0x0400000000000000 +#define BM_59_58 0x0c00000000000000 +#define BM_58_59 BM_59_58 +#define BM_60_58 0x1c00000000000000 +#define BM_58_60 BM_60_58 +#define BM_61_58 0x3c00000000000000 +#define BM_58_61 BM_61_58 +#define BM_62_58 0x7c00000000000000 +#define BM_58_62 BM_62_58 +#define BM_63_58 0xfc00000000000000 +#define BM_58_63 BM_63_58 +#define BM_59_59 0x0800000000000000 +#define BM_60_59 0x1800000000000000 +#define BM_59_60 BM_60_59 +#define BM_61_59 0x3800000000000000 +#define BM_59_61 BM_61_59 +#define BM_62_59 0x7800000000000000 +#define BM_59_62 BM_62_59 +#define BM_63_59 0xf800000000000000 +#define BM_59_63 BM_63_59 +#define BM_60_60 0x1000000000000000 +#define BM_61_60 0x3000000000000000 +#define BM_60_61 BM_61_60 +#define BM_62_60 0x7000000000000000 +#define BM_60_62 BM_62_60 +#define BM_63_60 0xf000000000000000 +#define BM_60_63 BM_63_60 +#define BM_61_61 0x2000000000000000 +#define BM_62_61 0x6000000000000000 +#define BM_61_62 BM_62_61 +#define BM_63_61 0xe000000000000000 +#define BM_61_63 BM_63_61 +#define BM_62_62 0x4000000000000000 +#define BM_63_62 0xc000000000000000 +#define BM_62_63 BM_63_62 +#define BM_63_63 0x8000000000000000 + +#endif + +#endif /* __ASM_TX4927_TX4927_MIPS_H */ diff -Nru a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/tx4927/tx4927_pci.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,275 @@ +/* + * 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) 2000-2001 Toshiba Corporation + */ +#ifndef __ASM_TX4927_TX4927_PCI_H +#define __ASM_TX4927_TX4927_PCI_H + +#define TX4927_CCFG_TOE 0x00004000 + +#define TX4927_PCIMEM 0x08000000 +#define TX4927_PCIMEM_SIZE 0x08000000 +#define TX4927_PCIIO 0x16000000 +#define TX4927_PCIIO_SIZE 0x01000000 + +#define TX4927_SDRAMC_REG 0xff1f8000 +#define TX4927_EBUSC_REG 0xff1f9000 +#define TX4927_PCIC_REG 0xff1fd000 +#define TX4927_CCFG_REG 0xff1fe000 +#define TX4927_IRC_REG 0xff1ff600 +#define TX4927_CE3 0x17f00000 /* 1M */ +#define TX4927_PCIRESET_ADDR 0x1c00f006 +#define TX4927_PCI_CLK_ADDR (KSEG1 + TX4927_CE3 + 0x00040020) + +#define TX4927_IMSTAT_ADDR(n) (KSEG1 + TX4927_CE3 + 0x0004001a + (n)) +#define tx4927_imstat_ptr(n) \ + ((volatile unsigned char *)TX4927_IMSTAT_ADDR(n)) + +/* bits for ISTAT3/IMASK3/IMSTAT3 */ +#define TX4927_INT3B_PCID 0 +#define TX4927_INT3B_PCIC 1 +#define TX4927_INT3B_PCIB 2 +#define TX4927_INT3B_PCIA 3 +#define TX4927_INT3F_PCID (1 << TX4927_INT3B_PCID) +#define TX4927_INT3F_PCIC (1 << TX4927_INT3B_PCIC) +#define TX4927_INT3F_PCIB (1 << TX4927_INT3B_PCIB) +#define TX4927_INT3F_PCIA (1 << TX4927_INT3B_PCIA) + +/* bits for PCI_CLK (S6) */ +#define TX4927_PCI_CLK_HOST 0x80 +#define TX4927_PCI_CLK_MASK (0x0f << 3) +#define TX4927_PCI_CLK_33 (0x01 << 3) +#define TX4927_PCI_CLK_25 (0x04 << 3) +#define TX4927_PCI_CLK_66 (0x09 << 3) +#define TX4927_PCI_CLK_50 (0x0c << 3) +#define TX4927_PCI_CLK_ACK 0x04 +#define TX4927_PCI_CLK_ACE 0x02 +#define TX4927_PCI_CLK_ENDIAN 0x01 +#define TX4927_NR_IRQ_LOCAL (8+16) +#define TX4927_NR_IRQ_IRC 32 /* On-Chip IRC */ + +#define TX4927_IR_PCIC 16 +#define TX4927_IR_PCIERR 22 +#define TX4927_IR_PCIPMA 23 +#define TX4927_IRQ_IRC_PCIC (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIC) +#define TX4927_IRQ_IRC_PCIERR (TX4927_NR_IRQ_LOCAL + TX4927_IR_PCIERR) +#define TX4927_IRQ_IOC1 (TX4927_NR_IRQ_LOCAL + TX4927_NR_IRQ_IRC) +#define TX4927_IRQ_IOC_PCID (TX4927_IRQ_IOC1 + TX4927_INT3B_PCID) +#define TX4927_IRQ_IOC_PCIC (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIC) +#define TX4927_IRQ_IOC_PCIB (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIB) +#define TX4927_IRQ_IOC_PCIA (TX4927_IRQ_IOC1 + TX4927_INT3B_PCIA) + +#ifdef _LANGUAGE_ASSEMBLY +#define _CONST64(c) c +#else +#define _CONST64(c) c##ull + +#include <asm/byteorder.h> + +#define tx4927_pcireset_ptr \ + ((volatile unsigned char *)TX4927_PCIRESET_ADDR) +#define tx4927_pci_clk_ptr \ + ((volatile unsigned char *)TX4927_PCI_CLK_ADDR) + +struct tx4927_sdramc_reg { + volatile unsigned long long cr[4]; + volatile unsigned long long unused0[4]; + volatile unsigned long long tr; + volatile unsigned long long unused1[2]; + volatile unsigned long long cmd; +}; + +struct tx4927_ebusc_reg { + volatile unsigned long long cr[8]; +}; + +struct tx4927_ccfg_reg { + volatile unsigned long long ccfg; + volatile unsigned long long crir; + volatile unsigned long long pcfg; + volatile unsigned long long tear; + volatile unsigned long long clkctr; + volatile unsigned long long unused0; + volatile unsigned long long garbc; + volatile unsigned long long unused1; + volatile unsigned long long unused2; + volatile unsigned long long ramp; +}; + +struct tx4927_irc_reg { + volatile unsigned long cer; + volatile unsigned long cr[2]; + volatile unsigned long unused0; + volatile unsigned long ilr[8]; + volatile unsigned long unused1[4]; + volatile unsigned long imr; + volatile unsigned long unused2[7]; + volatile unsigned long scr; + volatile unsigned long unused3[7]; + volatile unsigned long ssr; + volatile unsigned long unused4[7]; + volatile unsigned long csr; +}; + +struct tx4927_pcic_reg { + volatile unsigned long pciid; + volatile unsigned long pcistatus; + volatile unsigned long pciccrev; + volatile unsigned long pcicfg1; + volatile unsigned long p2gm0plbase; /* +10 */ + volatile unsigned long p2gm0pubase; + volatile unsigned long p2gm1plbase; + volatile unsigned long p2gm1pubase; + volatile unsigned long p2gm2pbase; /* +20 */ + volatile unsigned long p2giopbase; + volatile unsigned long unused0; + volatile unsigned long pcisid; + volatile unsigned long unused1; /* +30 */ + volatile unsigned long pcicapptr; + volatile unsigned long unused2; + volatile unsigned long pcicfg2; + volatile unsigned long g2ptocnt; /* +40 */ + volatile unsigned long unused3[15]; + volatile unsigned long g2pstatus; /* +80 */ + volatile unsigned long g2pmask; + volatile unsigned long pcisstatus; + volatile unsigned long pcimask; + volatile unsigned long p2gcfg; /* +90 */ + volatile unsigned long p2gstatus; + volatile unsigned long p2gmask; + volatile unsigned long p2gccmd; + volatile unsigned long unused4[24]; /* +a0 */ + volatile unsigned long pbareqport; /* +100 */ + volatile unsigned long pbacfg; + volatile unsigned long pbastatus; + volatile unsigned long pbamask; + volatile unsigned long pbabm; /* +110 */ + volatile unsigned long pbacreq; + volatile unsigned long pbacgnt; + volatile unsigned long pbacstate; + volatile unsigned long long g2pmgbase[3]; /* +120 */ + volatile unsigned long long g2piogbase; + volatile unsigned long g2pmmask[3]; /* +140 */ + volatile unsigned long g2piomask; + volatile unsigned long long g2pmpbase[3]; /* +150 */ + volatile unsigned long long g2piopbase; + volatile unsigned long pciccfg; /* +170 */ + volatile unsigned long pcicstatus; + volatile unsigned long pcicmask; + volatile unsigned long unused5; + volatile unsigned long long p2gmgbase[3]; /* +180 */ + volatile unsigned long long p2giogbase; + volatile unsigned long g2pcfgadrs; /* +1a0 */ + volatile unsigned long g2pcfgdata; + volatile unsigned long unused6[8]; + volatile unsigned long g2pintack; + volatile unsigned long g2pspc; + volatile unsigned long unused7[12]; /* +1d0 */ + volatile unsigned long long pdmca; /* +200 */ + volatile unsigned long long pdmga; + volatile unsigned long long pdmpa; + volatile unsigned long long pdmcut; + volatile unsigned long long pdmcnt; /* +220 */ + volatile unsigned long long pdmsts; + volatile unsigned long long unused8[2]; + volatile unsigned long long pdmdb[4]; /* +240 */ + volatile unsigned long long pdmtdh; /* +260 */ + volatile unsigned long long pdmdms; +}; + +#endif /* _LANGUAGE_ASSEMBLY */ + +/* IRCSR : Int. Current Status */ +#define TX4927_IRCSR_IF 0x00010000 +#define TX4927_IRCSR_ILV_MASK 0x00000700 +#define TX4927_IRCSR_IVL_MASK 0x0000001f + +/* + * PCIC + */ + +/* bits for G2PSTATUS/G2PMASK */ +#define TX4927_PCIC_G2PSTATUS_ALL 0x00000003 +#define TX4927_PCIC_G2PSTATUS_TTOE 0x00000002 +#define TX4927_PCIC_G2PSTATUS_RTOE 0x00000001 + +/* bits for PCIMASK (see also PCI_STATUS_XXX in linux/pci.h */ +#define TX4927_PCIC_PCISTATUS_ALL 0x0000f900 + +/* bits for PBACFG */ +#define TX4927_PCIC_PBACFG_RPBA 0x00000004 +#define TX4927_PCIC_PBACFG_PBAEN 0x00000002 +#define TX4927_PCIC_PBACFG_BMCEN 0x00000001 + +/* bits for G2PMnGBASE */ +#define TX4927_PCIC_G2PMnGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_G2PMnGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for G2PIOGBASE */ +#define TX4927_PCIC_G2PIOGBASE_BSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_G2PIOGBASE_ECHG _CONST64(0x0000001000000000) + +/* bits for PCICSTATUS/PCICMASK */ +#define TX4927_PCIC_PCICSTATUS_ALL 0x000007dc + +/* bits for PCICCFG */ +#define TX4927_PCIC_PCICCFG_LBWC_MASK 0x0fff0000 +#define TX4927_PCIC_PCICCFG_HRST 0x00000800 +#define TX4927_PCIC_PCICCFG_SRST 0x00000400 +#define TX4927_PCIC_PCICCFG_IRBER 0x00000200 +#define TX4927_PCIC_PCICCFG_IMSE0 0x00000100 +#define TX4927_PCIC_PCICCFG_IMSE1 0x00000080 +#define TX4927_PCIC_PCICCFG_IMSE2 0x00000040 +#define TX4927_PCIC_PCICCFG_IISE 0x00000020 +#define TX4927_PCIC_PCICCFG_ATR 0x00000010 +#define TX4927_PCIC_PCICCFG_ICAE 0x00000008 + +/* bits for P2GMnGBASE */ +#define TX4927_PCIC_P2GMnGBASE_TMEMEN _CONST64(0x0000004000000000) +#define TX4927_PCIC_P2GMnGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_P2GMnGBASE_TECHG _CONST64(0x0000001000000000) + +/* bits for P2GIOGBASE */ +#define TX4927_PCIC_P2GIOGBASE_TIOEN _CONST64(0x0000004000000000) +#define TX4927_PCIC_P2GIOGBASE_TBSDIS _CONST64(0x0000002000000000) +#define TX4927_PCIC_P2GIOGBASE_TECHG _CONST64(0x0000001000000000) + +#define TX4927_PCIC_IDSEL_AD_TO_SLOT(ad) ((ad) - 11) +#define TX4927_PCIC_MAX_DEVNU TX4927_PCIC_IDSEL_AD_TO_SLOT(32) + +/* + * CCFG + */ +/* CCFG : Chip Configuration */ +#define TX4927_CCFG_PCI66 0x00800000 +#define TX4927_CCFG_PCIMIDE 0x00400000 +#define TX4927_CCFG_PCIXARB 0x00002000 +#define TX4927_CCFG_PCIDIVMODE_MASK 0x00001800 +#define TX4927_CCFG_PCIDIVMODE_2_5 0x00000000 +#define TX4927_CCFG_PCIDIVMODE_3 0x00000800 +#define TX4927_CCFG_PCIDIVMODE_5 0x00001000 +#define TX4927_CCFG_PCIDIVMODE_6 0x00001800 + +/* PCFG : Pin Configuration */ +#define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 +#define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) + +/* CLKCTR : Clock Control */ +#define TX4927_CLKCTR_PCICKD 0x00400000 +#define TX4927_CLKCTR_PCIRST 0x00000040 + + +#ifndef _LANGUAGE_ASSEMBLY + +#define tx4927_sdramcptr ((struct tx4927_sdramc_reg *)TX4927_SDRAMC_REG) +#define tx4927_pcicptr ((struct tx4927_pcic_reg *)TX4927_PCIC_REG) +#define tx4927_ccfgptr ((struct tx4927_ccfg_reg *)TX4927_CCFG_REG) +#define tx4927_ebuscptr ((struct tx4927_ebusc_reg *)TX4927_EBUSC_REG) +#define tx4927_ircptr ((struct tx4927_irc_reg *)TX4927_IRC_REG) + +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* __ASM_TX4927_TX4927_PCI_H */ diff -Nru a/include/asm-mips/types.h b/include/asm-mips/types.h --- a/include/asm-mips/types.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips/types.h Fri Jun 27 14:19:53 2003 @@ -1,5 +1,4 @@ -/* $Id: types.h,v 1.3 1999/08/18 23:37:50 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -10,6 +9,8 @@ #ifndef _ASM_TYPES_H #define _ASM_TYPES_H +#include <linux/config.h> + #ifndef __ASSEMBLY__ typedef unsigned short umode_t; @@ -34,12 +35,12 @@ typedef unsigned long __u64; #else - + #if defined(__GNUC__) && !defined(__STRICT_ANSI__) typedef __signed__ long long __s64; typedef unsigned long long __u64; #endif - + #endif #endif /* __ASSEMBLY__ */ @@ -76,7 +77,23 @@ #endif -typedef unsigned long dma_addr_t; +#if defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR) +typedef u64 dma_addr_t; +#else +typedef u32 dma_addr_t; +#endif +typedef u64 dma64_addr_t; + +#ifdef CONFIG_64BIT_PHYS_ADDR +typedef unsigned long long phys_t; +#else +typedef unsigned long phys_t; +#endif + +#ifdef CONFIG_LBD +typedef u64 sector_t; +#define HAVE_SECTOR_T +#endif #endif /* __ASSEMBLY__ */ diff -Nru a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h --- a/include/asm-mips/uaccess.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/uaccess.h Fri Jun 27 14:19:52 2003 @@ -10,7 +10,7 @@ #define _ASM_UACCESS_H #include <linux/errno.h> -#include <linux/sched.h> +#include <linux/thread_info.h> #define STR(x) __STR(x) #define __STR(x) #x @@ -28,9 +28,9 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define get_fs() (current->thread.current_ds) #define get_ds() (KERNEL_DS) -#define set_fs(x) (current->thread.current_ds=(x)) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) #define segment_eq(a,b) ((a).seg == (b).seg) @@ -56,7 +56,7 @@ #define access_ok(type,addr,size) \ __access_ok(((unsigned long)(addr)),(size),__access_mask) -extern inline int verify_area(int type, const void * addr, unsigned long size) +static inline int verify_area(int type, const void * addr, unsigned long size) { return access_ok(type,addr,size) ? 0 : -EFAULT; } @@ -269,103 +269,99 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); -#define __copy_to_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - __MODULE_JAL(__copy_user) \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \ - "$24", "$31","memory"); \ - __cu_len; \ +#define __invoke_copy_to_user(to,from,n) ({ \ + register void *__cu_to_r __asm__ ("$4"); \ + register const void *__cu_from_r __asm__ ("$5"); \ + register long __cu_len_r __asm__ ("$6"); \ + \ + __cu_to_r = (to); \ + __cu_from_r = (from); \ + __cu_len_r = (n); \ + __asm__ __volatile__( \ + __MODULE_JAL(__copy_user) \ + : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ + : \ + : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ + "memory"); \ + __cu_len_r; \ }) -#define __copy_from_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ - ".set\tnoat\n\t" \ - "addu\t$1, %2, %3\n\t" \ - ".set\tat\n\t" \ - ".set\treorder\n\t" \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", "$15", \ - "$24", "$31","memory"); \ - __cu_len; \ +#define __copy_to_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \ + __cu_len; \ }) -#define copy_to_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - __MODULE_JAL(__copy_user) \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \ - "$15", "$24", "$31","memory"); \ - __cu_len; \ +#define copy_to_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \ + __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ }) -#define copy_from_user(to,from,n) ({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ - ".set\tnoat\n\t" \ - "addu\t$1, %2, %3\n\t" \ - ".set\tat\n\t" \ - ".set\treorder\n\t" \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \ - "$15", "$24", "$31","memory"); \ - __cu_len; \ +#define __invoke_copy_from_user(to,from,n) ({ \ + register void *__cu_to_r __asm__ ("$4"); \ + register const void *__cu_from_r __asm__ ("$5"); \ + register long __cu_len_r __asm__ ("$6"); \ + \ + __cu_to_r = (to); \ + __cu_from_r = (from); \ + __cu_len_r = (n); \ + __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + __MODULE_JAL(__copy_user) \ + ".set\tnoat\n\t" \ + "addu\t$1, %1, %2\n\t" \ + ".set\tat\n\t" \ + ".set\treorder\n\t" \ + : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ + : \ + : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ + "memory"); \ + __cu_len_r; \ }) -extern inline __kernel_size_t +#define __copy_from_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ +}) + +#define copy_from_user(to,from,n) ({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ +}) + +static inline __kernel_size_t __clear_user(void *addr, __kernel_size_t size) { __kernel_size_t res; @@ -394,7 +390,7 @@ * Returns: -EFAULT if exception before terminator, N if the entire * buffer filled, else strlen. */ -extern inline long +static inline long __strncpy_from_user(char *__to, const char *__from, long __len) { long res; @@ -412,7 +408,7 @@ return res; } -extern inline long +static inline long strncpy_from_user(char *__to, const char *__from, long __len) { long res; @@ -431,7 +427,7 @@ } /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -extern inline long __strlen_user(const char *s) +static inline long __strlen_user(const char *s) { long res; @@ -446,7 +442,7 @@ return res; } -extern inline long strlen_user(const char *s) +static inline long strlen_user(const char *s) { long res; @@ -462,7 +458,7 @@ } /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -extern inline long __strnlen_user(const char *s, long n) +static inline long __strnlen_user(const char *s, long n) { long res; @@ -478,7 +474,7 @@ return res; } -extern inline long strnlen_user(const char *s, long n) +static inline long strnlen_user(const char *s, long n) { long res; @@ -499,14 +495,5 @@ unsigned long insn; unsigned long nextinsn; }; - -/* Returns 0 if exception not found and fixup.unit otherwise. */ -extern unsigned long search_exception_table(unsigned long addr); - -/* Returns the new pc */ -#define fixup_exception(map_reg, fixup_unit, pc) \ -({ \ - fixup_unit; \ -}) #endif /* _ASM_UACCESS_H */ diff -Nru a/include/asm-mips/ucontext.h b/include/asm-mips/ucontext.h --- a/include/asm-mips/ucontext.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/ucontext.h Fri Jun 27 14:19:59 2003 @@ -1,5 +1,4 @@ -/* $Id: ucontext.h,v 1.2 1999/09/27 16:01:40 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff -Nru a/include/asm-mips/umap.h b/include/asm-mips/umap.h --- a/include/asm-mips/umap.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,8 +0,0 @@ -#ifndef __MIPS_UMAP_H -#define __MIPS_UMAP_H - -void remove_mapping (struct vm_area_struct *vma, struct task_struct *task, unsigned long start, -unsigned long end); - -#endif - diff -Nru a/include/asm-mips/unaligned.h b/include/asm-mips/unaligned.h --- a/include/asm-mips/unaligned.h Fri Jun 27 14:20:03 2003 +++ b/include/asm-mips/unaligned.h Fri Jun 27 14:20:03 2003 @@ -18,7 +18,7 @@ * This could have been implemented in plain C like IA64 but egcs 1.0.3a * inflates this to 23 instructions ... */ -extern inline unsigned long long __ldq_u(const unsigned long long * __addr) +static inline unsigned long long __ldq_u(const unsigned long long * __addr) { unsigned long long __res; @@ -33,7 +33,7 @@ /* * Load word unaligned. */ -extern inline unsigned long __ldl_u(const unsigned int * __addr) +static inline unsigned long __ldl_u(const unsigned int * __addr) { unsigned long __res; @@ -47,7 +47,7 @@ /* * Load halfword unaligned. */ -extern inline unsigned long __ldw_u(const unsigned short * __addr) +static inline unsigned long __ldw_u(const unsigned short * __addr) { unsigned long __res; @@ -61,7 +61,7 @@ /* * Store doubleword ununaligned. */ -extern inline void __stq_u(unsigned long __val, unsigned long long * __addr) +static inline void __stq_u(unsigned long __val, unsigned long long * __addr) { __asm__("usw\t%1, %0\n\t" "usw\t%D1, 4+%0" @@ -72,7 +72,7 @@ /* * Store long ununaligned. */ -extern inline void __stl_u(unsigned long __val, unsigned int * __addr) +static inline void __stl_u(unsigned long __val, unsigned int * __addr) { __asm__("usw\t%1, %0" : "=m" (*__addr) @@ -82,7 +82,7 @@ /* * Store word ununaligned. */ -extern inline void __stw_u(unsigned long __val, unsigned short * __addr) +static inline void __stw_u(unsigned long __val, unsigned short * __addr) { __asm__("ush\t%1, %0" : "=m" (*__addr) @@ -93,8 +93,8 @@ * get_unaligned - get value from possibly mis-aligned location * @ptr: pointer to value * - * This macro should be used for accessing values larger in size than - * single bytes at locations that are expected to be improperly aligned, + * This macro should be used for accessing values larger in size than + * single bytes at locations that are expected to be improperly aligned, * e.g. retrieving a u16 value from a location not u16-aligned. * * Note that unaligned accesses can be very expensive on some architectures. @@ -129,8 +129,8 @@ * @val: value to place * @ptr: pointer to location * - * This macro should be used for placing values larger in size than - * single bytes at locations that are expected to be improperly aligned, + * This macro should be used for placing values larger in size than + * single bytes at locations that are expected to be improperly aligned, * e.g. writing a u16 value to a location not u16-aligned. * * Note that unaligned accesses can be very expensive on some architectures. diff -Nru a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h --- a/include/asm-mips/unistd.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/unistd.h Fri Jun 27 14:19:52 2003 @@ -4,9 +4,6 @@ * for more details. * * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle - * - * Changed system calls macros _syscall5 - _syscall7 to push args 5 to 7 onto - * the stack. Robin Farine for ACN S.A, Copyright (C) 1996 by ACN S.A */ #ifndef _ASM_UNISTD_H #define _ASM_UNISTD_H @@ -30,7 +27,7 @@ #define __NR_chmod (__NR_Linux + 15) #define __NR_lchown (__NR_Linux + 16) #define __NR_break (__NR_Linux + 17) -#define __NR_oldstat (__NR_Linux + 18) +#define __NR_unused18 (__NR_Linux + 18) #define __NR_lseek (__NR_Linux + 19) #define __NR_getpid (__NR_Linux + 20) #define __NR_mount (__NR_Linux + 21) @@ -40,7 +37,7 @@ #define __NR_stime (__NR_Linux + 25) #define __NR_ptrace (__NR_Linux + 26) #define __NR_alarm (__NR_Linux + 27) -#define __NR_oldfstat (__NR_Linux + 28) +#define __NR_unused28 (__NR_Linux + 28) #define __NR_pause (__NR_Linux + 29) #define __NR_utime (__NR_Linux + 30) #define __NR_stty (__NR_Linux + 31) @@ -96,7 +93,7 @@ #define __NR_setgroups (__NR_Linux + 81) #define __NR_reserved82 (__NR_Linux + 82) #define __NR_symlink (__NR_Linux + 83) -#define __NR_oldlstat (__NR_Linux + 84) +#define __NR_unused84 (__NR_Linux + 84) #define __NR_readlink (__NR_Linux + 85) #define __NR_uselib (__NR_Linux + 86) #define __NR_swapon (__NR_Linux + 87) @@ -233,33 +230,70 @@ #define __NR_madvise (__NR_Linux + 218) #define __NR_getdents64 (__NR_Linux + 219) #define __NR_fcntl64 (__NR_Linux + 220) -#define __NR_gettid (__NR_Linux + 221) -#define __NR_tkill (__NR_Linux + 222) +#define __NR_reserved221 (__NR_Linux + 221) +#define __NR_gettid (__NR_Linux + 222) +#define __NR_readahead (__NR_Linux + 223) +#define __NR_setxattr (__NR_Linux + 224) +#define __NR_lsetxattr (__NR_Linux + 225) +#define __NR_fsetxattr (__NR_Linux + 226) +#define __NR_getxattr (__NR_Linux + 227) +#define __NR_lgetxattr (__NR_Linux + 228) +#define __NR_fgetxattr (__NR_Linux + 229) +#define __NR_listxattr (__NR_Linux + 230) +#define __NR_llistxattr (__NR_Linux + 231) +#define __NR_flistxattr (__NR_Linux + 232) +#define __NR_removexattr (__NR_Linux + 233) +#define __NR_lremovexattr (__NR_Linux + 234) +#define __NR_fremovexattr (__NR_Linux + 235) +#define __NR_tkill (__NR_Linux + 236) +#define __NR_sendfile64 (__NR_Linux + 237) +#define __NR_futex (__NR_Linux + 238) +#define __NR_sched_setaffinity (__NR_Linux + 239) +#define __NR_sched_getaffinity (__NR_Linux + 240) +#define __NR_io_setup (__NR_Linux + 241) +#define __NR_io_destroy (__NR_Linux + 242) +#define __NR_io_getevents (__NR_Linux + 243) +#define __NR_io_submit (__NR_Linux + 244) +#define __NR_io_cancel (__NR_Linux + 245) +#define __NR_exit_group (__NR_Linux + 246) +#define __NR_lookup_dcookie (__NR_Linux + 247) +#define __NR_epoll_create (__NR_Linux + 248) +#define __NR_epoll_ctl (__NR_Linux + 249) +#define __NR_epoll_wait (__NR_Linux + 250) +#define __NR_remap_file_pages (__NR_Linux + 251) +#define __NR_set_tid_address (__NR_Linux + 252) +#define __NR_restart_syscall (__NR_Linux + 253) +#define __NR_fadvise64 (__NR_Linux + 254) +#define __NR_statfs64 (__NR_Linux + 255) +#define __NR_fstatfs64 (__NR_Linux + 256) /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 220 +#define __NR_Linux_syscalls 256 -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ -long __res, __err; \ -__asm__ volatile ("li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name) \ - : "$2","$7","$8","$9","$10","$11","$12","$13","$14","$15", \ - "$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %2\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } /* @@ -269,189 +303,195 @@ #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)) \ - : "$2","$4","$7","$8","$9","$10","$11","$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %3\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall2(type,name,atype,a,btype,b) \ -type name(atype a,btype b) \ +type name(atype a, btype b) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)) \ - : "$2","$4","$5","$7","$8","$9","$10","$11","$12","$13", \ - "$14","$15", "$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %4\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ -type name (atype a, btype b, ctype c) \ +type name(atype a, btype b, ctype c) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name (atype a, btype b, ctype c, dtype d) \ +type name(atype a, btype b, ctype c, dtype d) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "move\t$7,%6\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } +/* + * Using those means your brain needs more than an oil change ;-) + */ + #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name (atype a,btype b,ctype c,dtype d,etype e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "lw\t$2,%7\n\t" \ - "move\t$7,%6\n\t" \ - "subu\t$29,24\n\t" \ - "sw\t$2,16($29)\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7\n\t" \ - "addiu\t$29,24" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "lw\t$2,%7\n\t" \ - "lw\t$3,%8\n\t" \ - "move\t$7,%6\n\t" \ - "subu\t$29,24\n\t" \ - "sw\t$2,16($29)\n\t" \ - "sw\t$3,20($29)\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7\n\t" \ - "addiu\t$29,24" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f, gtype g) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4,%3\n\t" \ - "move\t$5,%4\n\t" \ - "move\t$6,%5\n\t" \ - "lw\t$2,%7\n\t" \ - "lw\t$3,%8\n\t" \ - "move\t$7,%6\n\t" \ - "subu\t$29,32\n\t" \ - "sw\t$2,16($29)\n\t" \ - "lw\t$2,%9\n\t" \ - "sw\t$3,20($29)\n\t" \ - "sw\t$2,24($29)\n\t" \ - "li\t$2,%2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7\n\t" \ - "addiu\t$29,32" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)), \ - "m" ((long)(g)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "lw\t$9, %8\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "sw\t$9, 24($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f), \ + "m" ((unsigned long)g), \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } + #ifdef __KERNEL_SYSCALLS__ /* @@ -478,8 +518,8 @@ static inline _syscall1(int,_exit,int,exitcode) static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) -#endif /* !defined (__KERNEL_SYSCALLS__) */ -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* __KERNEL_SYSCALLS__ */ +#endif /* !__ASSEMBLY__ */ /* * "Conditional" syscalls @@ -487,6 +527,6 @@ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), * but it doesn't work on all toolchains, so we just do it by hand */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); +#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall"); #endif /* _ASM_UNISTD_H */ diff -Nru a/include/asm-mips/user.h b/include/asm-mips/user.h --- a/include/asm-mips/user.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips/user.h Fri Jun 27 14:19:55 2003 @@ -1,8 +1,6 @@ #ifndef __ASM_MIPS_USER_H #define __ASM_MIPS_USER_H -#include <linux/ptrace.h> - #include <asm/page.h> #include <asm/reg.h> diff -Nru a/include/asm-mips/vga.h b/include/asm-mips/vga.h --- a/include/asm-mips/vga.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips/vga.h Fri Jun 27 14:19:52 2003 @@ -3,18 +3,17 @@ * * (c) 1998 Martin Mares <mj@ucw.cz> */ - -#ifndef _LINUX_ASM_VGA_H_ -#define _LINUX_ASM_VGA_H_ +#ifndef _ASM_VGA_H +#define _ASM_VGA_H /* * On the PC, we can just recalculate addresses and then * access the videoram directly without any black magic. */ -#define VGA_MAP_MEM(x) ((unsigned long)0xb0000000 + (unsigned long)(x)) +#define VGA_MAP_MEM(x) (0xb0000000L + (unsigned long)(x)) -#define vga_readb(x) (*(x)) -#define vga_writeb(x,y) (*(y) = (x)) +#define vga_readb(x) (*(x)) +#define vga_writeb(x,y) (*(y) = (x)) -#endif +#endif /* _ASM_VGA_H */ diff -Nru a/include/asm-mips/vr41xx/capcella.h b/include/asm-mips/vr41xx/capcella.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/capcella.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,69 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/capcella.h + * + * BRIEF MODULE DESCRIPTION + * Include file for ZAO Networks Capcella. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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 __ZAO_CAPCELLA_H +#define __ZAO_CAPCELLA_H + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_PCI_MEM1_BASE 0x10000000 +#define VR41XX_PCI_MEM1_SIZE 0x04000000 +#define VR41XX_PCI_MEM1_MASK 0x7c000000 + +#define VR41XX_PCI_MEM2_BASE 0x14000000 +#define VR41XX_PCI_MEM2_SIZE 0x02000000 +#define VR41XX_PCI_MEM2_MASK 0x7e000000 + +#define VR41XX_PCI_IO_BASE 0x16000000 +#define VR41XX_PCI_IO_SIZE 0x02000000 +#define VR41XX_PCI_IO_MASK 0x7e000000 + +#define VR41XX_PCI_IO_START 0x01000000 +#define VR41XX_PCI_IO_END 0x01ffffff + +#define VR41XX_PCI_MEM_START 0x12000000 +#define VR41XX_PCI_MEM_END 0x15ffffff + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE +#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE +#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) +#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE +#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) + +/* + * General-Purpose I/O Pin Number + */ +#define PC104PLUS_INTA_PIN 2 +#define PC104PLUS_INTB_PIN 3 +#define PC104PLUS_INTC_PIN 4 +#define PC104PLUS_INTD_PIN 5 + +/* + * Interrupt Number + */ +#define RTL8139_1_IRQ GIU_IRQ(PC104PLUS_INTC_PIN) +#define RTL8139_2_IRQ GIU_IRQ(PC104PLUS_INTD_PIN) +#define PC104PLUS_INTA_IRQ GIU_IRQ(PC104PLUS_INTA_PIN) +#define PC104PLUS_INTB_IRQ GIU_IRQ(PC104PLUS_INTB_PIN) +#define PC104PLUS_INTC_IRQ GIU_IRQ(PC104PLUS_INTC_PIN) +#define PC104PLUS_INTD_IRQ GIU_IRQ(PC104PLUS_INTD_PIN) + +#endif /* __ZAO_CAPCELLA_H */ diff -Nru a/include/asm-mips/vr41xx/e55.h b/include/asm-mips/vr41xx/e55.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/e55.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,37 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/e55.h + * + * BRIEF MODULE DESCRIPTION + * Include file for CASIO CASSIOPEIA E-10/15/55/65. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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 __CASIO_E55_H +#define __CASIO_E55_H + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_ISA_MEM_BASE 0x10000000 +#define VR41XX_ISA_MEM_SIZE 0x04000000 + +#define VR41XX_ISA_IO_BASE 0x14000000 +#define VR41XX_ISA_IO_SIZE 0x04000000 + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_ISA_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_ISA_IO_SIZE +#define IO_MEM_RESOURCE_START VR41XX_ISA_MEM_BASE +#define IO_MEM_RESOURCE_END (VR41XX_ISA_MEM_BASE + VR41XX_ISA_MEM_SIZE) + +#endif /* __CASIO_E55_H */ diff -Nru a/include/asm-mips/vr41xx/eagle.h b/include/asm-mips/vr41xx/eagle.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/eagle.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,265 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/eagle.h + * + * BRIEF MODULE DESCRIPTION + * Include file for NEC Eagle board. + * + * Author: MontaVista Software, Inc. + * yyuasa@mvista.com or source@mvista.com + * + * Copyright 2001-2003 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. + */ +#ifndef __NEC_EAGLE_H +#define __NEC_EAGLE_H + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_PCI_MEM1_BASE 0x10000000 +#define VR41XX_PCI_MEM1_SIZE 0x04000000 +#define VR41XX_PCI_MEM1_MASK 0x7c000000 + +#define VR41XX_PCI_MEM2_BASE 0x14000000 +#define VR41XX_PCI_MEM2_SIZE 0x02000000 +#define VR41XX_PCI_MEM2_MASK 0x7e000000 + +#define VR41XX_PCI_IO_BASE 0x16000000 +#define VR41XX_PCI_IO_SIZE 0x02000000 +#define VR41XX_PCI_IO_MASK 0x7e000000 + +#define VR41XX_PCI_IO_START 0x01000000 +#define VR41XX_PCI_IO_END 0x01ffffff + +#define VR41XX_PCI_MEM_START 0x12000000 +#define VR41XX_PCI_MEM_END 0x15ffffff + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE +#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE +#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) +#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE +#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) + +/* + * General-Purpose I/O Pin Number + */ +#define VRC4173_PIN 1 +#define PCISLOT_PIN 4 +#define FPGA_PIN 5 +#define DCD_PIN 15 + +/* + * Interrupt Number + */ +#define VRC4173_CASCADE_IRQ GIU_IRQ(VRC4173_PIN) +#define PCISLOT_IRQ GIU_IRQ(PCISLOT_PIN) +#define FPGA_CASCADE_IRQ GIU_IRQ(FPGA_PIN) +#define DCD_IRQ GIU_IRQ(DCD_PIN) + +#define SDBINT_IRQ_BASE 88 +#define SDBINT_IRQ(x) (SDBINT_IRQ_BASE + (x)) +/* RFU */ +#define DEG_IRQ SDBINT_IRQ(1) +#define ENUM_IRQ SDBINT_IRQ(2) +#define SIO1INT_IRQ SDBINT_IRQ(3) +#define SIO2INT_IRQ SDBINT_IRQ(4) +#define PARINT_IRQ SDBINT_IRQ(5) +#define SDBINT_IRQ_LAST PARINT_IRQ + +#define PCIINT_IRQ_BASE 96 +#define PCIINT_IRQ(x) (PCIINT_IRQ_BASE + (x)) +#define CP_INTA_IRQ PCIINT_IRQ(0) +#define CP_INTB_IRQ PCIINT_IRQ(1) +#define CP_INTC_IRQ PCIINT_IRQ(2) +#define CP_INTD_IRQ PCIINT_IRQ(3) +#define LANINTA_IRQ PCIINT_IRQ(4) +#define PCIINT_IRQ_LAST LANINTA_IRQ + +/* + * On board Devices I/O Mapping + */ +#define NEC_EAGLE_SIO1RB KSEG1ADDR(0x0DFFFEC0) +#define NEC_EAGLE_SIO1TH KSEG1ADDR(0x0DFFFEC0) +#define NEC_EAGLE_SIO1IE KSEG1ADDR(0x0DFFFEC2) +#define NEC_EAGLE_SIO1IID KSEG1ADDR(0x0DFFFEC4) +#define NEC_EAGLE_SIO1FC KSEG1ADDR(0x0DFFFEC4) +#define NEC_EAGLE_SIO1LC KSEG1ADDR(0x0DFFFEC6) +#define NEC_EAGLE_SIO1MC KSEG1ADDR(0x0DFFFEC8) +#define NEC_EAGLE_SIO1LS KSEG1ADDR(0x0DFFFECA) +#define NEC_EAGLE_SIO1MS KSEG1ADDR(0x0DFFFECC) +#define NEC_EAGLE_SIO1SC KSEG1ADDR(0x0DFFFECE) + +#define NEC_EAGLE_SIO2TH KSEG1ADDR(0x0DFFFED0) +#define NEC_EAGLE_SIO2IE KSEG1ADDR(0x0DFFFED2) +#define NEC_EAGLE_SIO2IID KSEG1ADDR(0x0DFFFED4) +#define NEC_EAGLE_SIO2FC KSEG1ADDR(0x0DFFFED4) +#define NEC_EAGLE_SIO2LC KSEG1ADDR(0x0DFFFED6) +#define NEC_EAGLE_SIO2MC KSEG1ADDR(0x0DFFFED8) +#define NEC_EAGLE_SIO2LS KSEG1ADDR(0x0DFFFEDA) +#define NEC_EAGLE_SIO2MS KSEG1ADDR(0x0DFFFEDC) +#define NEC_EAGLE_SIO2SC KSEG1ADDR(0x0DFFFEDE) + +#define NEC_EAGLE_PIOPP_DATA KSEG1ADDR(0x0DFFFEE0) +#define NEC_EAGLE_PIOPP_STATUS KSEG1ADDR(0x0DFFFEE2) +#define NEC_EAGLE_PIOPP_CNT KSEG1ADDR(0x0DFFFEE4) +#define NEC_EAGLE_PIOPP_EPPADDR KSEG1ADDR(0x0DFFFEE6) +#define NEC_EAGLE_PIOPP_EPPDATA0 KSEG1ADDR(0x0DFFFEE8) +#define NEC_EAGLE_PIOPP_EPPDATA1 KSEG1ADDR(0x0DFFFEEA) +#define NEC_EAGLE_PIOPP_EPPDATA2 KSEG1ADDR(0x0DFFFEEC) + +#define NEC_EAGLE_PIOECP_DATA KSEG1ADDR(0x0DFFFEF0) +#define NEC_EAGLE_PIOECP_CONFIG KSEG1ADDR(0x0DFFFEF2) +#define NEC_EAGLE_PIOECP_EXTCNT KSEG1ADDR(0x0DFFFEF4) + +/* + * FLSHCNT Register + */ +#define NEC_EAGLE_FLSHCNT KSEG1ADDR(0x0DFFFFA0) +#define NEC_EAGLE_FLSHCNT_FRDY 0x80 +#define NEC_EAGLE_FLSHCNT_VPPE 0x40 +#define NEC_EAGLE_FLSHCNT_WP2 0x01 + +/* + * FLSHBANK Register + */ +#define NEC_EAGLE_FLSHBANK KSEG1ADDR(0x0DFFFFA4) +#define NEC_EAGLE_FLSHBANK_S_BANK2 0x40 +#define NEC_EAGLE_FLSHBANK_S_BANK1 0x20 +#define NEC_EAGLE_FLSHBANK_BNKQ4 0x10 +#define NEC_EAGLE_FLSHBANK_BNKQ3 0x08 +#define NEC_EAGLE_FLSHBANK_BNKQ2 0x04 +#define NEC_EAGLE_FLSHBANK_BNKQ1 0x02 +#define NEC_EAGLE_FLSHBANK_BNKQ0 0x01 + +/* + * SWITCH Setting Register + */ +#define NEC_EAGLE_SWTCHSET KSEG1ADDR(0x0DFFFFA8) +#define NEC_EAGLE_SWTCHSET_DP2SW4 0x80 +#define NEC_EAGLE_SWTCHSET_DP2SW3 0x40 +#define NEC_EAGLE_SWTCHSET_DP2SW2 0x20 +#define NEC_EAGLE_SWTCHSET_DP2SW1 0x10 +#define NEC_EAGLE_SWTCHSET_DP1SW4 0x08 +#define NEC_EAGLE_SWTCHSET_DP1SW3 0x04 +#define NEC_EAGLE_SWTCHSET_DP1SW2 0x02 +#define NEC_EAGLE_SWTCHSET_DP1SW1 0x01 + +/* + * PPT Parallel Port Device Controller + */ +#define NEC_EAGLE_PPT_WRITE_DATA KSEG1ADDR(0x0DFFFFB0) +#define NEC_EAGLE_PPT_READ_DATA KSEG1ADDR(0x0DFFFFB2) +#define NEC_EAGLE_PPT_CNT KSEG1ADDR(0x0DFFFFB4) +#define NEC_EAGLE_PPT_CNT2 KSEG1ADDR(0x0DFFFFB4) + +/* Control Register */ +#define NEC_EAGLE_PPT_INTMSK 0x20 +#define NEC_EAGLE_PPT_PARIINT 0x10 +#define NEC_EAGLE_PPT_SELECTIN 0x08 +#define NEC_EAGLE_PPT_INIT 0x04 +#define NEC_EAGLE_PPT_AUTOFD 0x02 +#define NEC_EAGLE_PPT_STROBE 0x01 + +/* Control Rgister 2 */ +#define NEC_EAGLE_PPT_PAREN 0x80 +#define NEC_EAGLE_PPT_AUTOEN 0x20 +#define NEC_EAGLE_PPT_BUSY 0x10 +#define NEC_EAGLE_PPT_ACK 0x08 +#define NEC_EAGLE_PPT_PE 0x04 +#define NEC_EAGLE_PPT_SELECT 0x02 +#define NEC_EAGLE_PPT_FAULT 0x01 + +/* + * LEDWR Register + */ +#define NEC_EAGLE_LEDWR1 KSEG1ADDR(0x0DFFFFC0) +#define NEC_EAGLE_LEDWR2 KSEG1ADDR(0x0DFFFFC4) + +/* + * SDBINT Register + */ +#define NEC_EAGLE_SDBINT KSEG1ADDR(0x0DFFFFD0) +#define NEC_EAGLE_SDBINT_PARINT 0x20 +#define NEC_EAGLE_SDBINT_SIO2INT 0x10 +#define NEC_EAGLE_SDBINT_SIO1INT 0x08 +#define NEC_EAGLE_SDBINT_ENUM 0x04 +#define NEC_EAGLE_SDBINT_DEG 0x02 + +/* + * SDB INTMSK Register + */ +#define NEC_EAGLE_SDBINTMSK KSEG1ADDR(0x0DFFFFD4) +#define NEC_EAGLE_SDBINTMSK_MSKPAR 0x20 +#define NEC_EAGLE_SDBINTMSK_MSKSIO2 0x10 +#define NEC_EAGLE_SDBINTMSK_MSKSIO1 0x08 +#define NEC_EAGLE_SDBINTMSK_MSKENUM 0x04 +#define NEC_EAGLE_SDBINTMSK_MSKDEG 0x02 + +/* + * RSTREG Register + */ +#define NEC_EAGLE_RSTREG KSEG1ADDR(0x0DFFFFD8) +#define NEC_EAGLE_RST_RSTSW 0x02 +#define NEC_EAGLE_RST_LEDOFF 0x01 + +/* + * PCI INT Rgister + */ +#define NEC_EAGLE_PCIINTREG KSEG1ADDR(0x0DFFFFDC) +#define NEC_EAGLE_PCIINT_LANINT 0x10 +#define NEC_EAGLE_PCIINT_CP_INTD 0x08 +#define NEC_EAGLE_PCIINT_CP_INTC 0x04 +#define NEC_EAGLE_PCIINT_CP_INTB 0x02 +#define NEC_EAGLE_PCIINT_CP_INTA 0x01 + +/* + * PCI INT Mask Register + */ +#define NEC_EAGLE_PCIINTMSKREG KSEG1ADDR(0x0DFFFFE0) +#define NEC_EAGLE_PCIINTMSK_MSKLANINT 0x10 +#define NEC_EAGLE_PCIINTMSK_MSKCP_INTD 0x08 +#define NEC_EAGLE_PCIINTMSK_MSKCP_INTC 0x04 +#define NEC_EAGLE_PCIINTMSK_MSKCP_INTB 0x02 +#define NEC_EAGLE_PCIINTMSK_MSKCP_INTA 0x01 + +/* + * CLK Division Register + */ +#define NEC_EAGLE_CLKDIV KSEG1ADDR(0x0DFFFFE4) +#define NEC_EAGLE_CLKDIV_PCIDIV1 0x10 +#define NEC_EAGLE_CLKDIV_PCIDIV0 0x08 +#define NEC_EAGLE_CLKDIV_VTDIV2 0x04 +#define NEC_EAGLE_CLKDIV_VTDIV1 0x02 +#define NEC_EAGLE_CLKDIV_VTDIV0 0x01 + +/* + * Source Revision Register + */ +#define NEC_EAGLE_REVISION KSEG1ADDR(0x0DFFFFE8) + +#endif /* __NEC_EAGLE_H */ diff -Nru a/include/asm-mips/vr41xx/mpc30x.h b/include/asm-mips/vr41xx/mpc30x.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/mpc30x.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,65 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/mpc30x.h + * + * BRIEF MODULE DESCRIPTION + * Include file for Victor MP-C303/304. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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 __VICTOR_MPC30X_H +#define __VICTOR_MPC30X_H + +#include <linux/config.h> + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_PCI_MEM1_BASE 0x10000000 +#define VR41XX_PCI_MEM1_SIZE 0x04000000 +#define VR41XX_PCI_MEM1_MASK 0x7c000000 + +#define VR41XX_PCI_MEM2_BASE 0x14000000 +#define VR41XX_PCI_MEM2_SIZE 0x02000000 +#define VR41XX_PCI_MEM2_MASK 0x7e000000 + +#define VR41XX_PCI_IO_BASE 0x16000000 +#define VR41XX_PCI_IO_SIZE 0x02000000 +#define VR41XX_PCI_IO_MASK 0x7e000000 + +#define VR41XX_PCI_IO_START 0x01000000 +#define VR41XX_PCI_IO_END 0x01ffffff + +#define VR41XX_PCI_MEM_START 0x12000000 +#define VR41XX_PCI_MEM_END 0x15ffffff + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE +#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE +#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) +#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE +#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) + +/* + * General-Purpose I/O Pin Number + */ +#define VRC4173_PIN 1 +#define MQ200_PIN 4 + +/* + * Interrupt Number + */ +#define VRC4173_CASCADE_IRQ GIU_IRQ(VRC4173_PIN) +#define MQ200_IRQ GIU_IRQ(MQ200_PIN) + +#endif /* __VICTOR_MPC30X_H */ diff -Nru a/include/asm-mips/vr41xx/tb0226.h b/include/asm-mips/vr41xx/tb0226.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/tb0226.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,69 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/tb0226.h + * + * BRIEF MODULE DESCRIPTION + * Include file for TANBAC TB0226. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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 __TANBAC_TB0226_H +#define __TANBAC_TB0226_H + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_PCI_MEM1_BASE 0x10000000 +#define VR41XX_PCI_MEM1_SIZE 0x04000000 +#define VR41XX_PCI_MEM1_MASK 0x7c000000 + +#define VR41XX_PCI_MEM2_BASE 0x14000000 +#define VR41XX_PCI_MEM2_SIZE 0x02000000 +#define VR41XX_PCI_MEM2_MASK 0x7e000000 + +#define VR41XX_PCI_IO_BASE 0x16000000 +#define VR41XX_PCI_IO_SIZE 0x02000000 +#define VR41XX_PCI_IO_MASK 0x7e000000 + +#define VR41XX_PCI_IO_START 0x01000000 +#define VR41XX_PCI_IO_END 0x01ffffff + +#define VR41XX_PCI_MEM_START 0x12000000 +#define VR41XX_PCI_MEM_END 0x15ffffff + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE +#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE +#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) +#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE +#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) + +/* + * General-Purpose I/O Pin Number + */ +#define GD82559_1_PIN 2 +#define GD82559_2_PIN 3 +#define UPD720100_INTA_PIN 4 +#define UPD720100_INTB_PIN 8 +#define UPD720100_INTC_PIN 13 + +/* + * Interrupt Number + */ +#define GD82559_1_IRQ GIU_IRQ(GD82559_1_PIN) +#define GD82559_2_IRQ GIU_IRQ(GD82559_2_PIN) +#define UPD720100_INTA_IRQ GIU_IRQ(UPD720100_INTA_PIN) +#define UPD720100_INTB_IRQ GIU_IRQ(UPD720100_INTB_PIN) +#define UPD720100_INTC_IRQ GIU_IRQ(UPD720100_INTC_PIN) + +#endif /* __TANBAC_TB0226_H */ diff -Nru a/include/asm-mips/vr41xx/tb0229.h b/include/asm-mips/vr41xx/tb0229.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/tb0229.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,73 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/tb0229.h + * + * BRIEF MODULE DESCRIPTION + * Include file for TANBAC TB0229 and TB0219. + * + * Copyright 2002,2003 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * Modified for TANBAC TB0229: + * Copyright 2003 Megasolution Inc. + * matsu@megasolution.jp + * + * 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 __TANBAC_TB0229_H +#define __TANBAC_TB0229_H + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_PCI_MEM1_BASE 0x10000000 +#define VR41XX_PCI_MEM1_SIZE 0x04000000 +#define VR41XX_PCI_MEM1_MASK 0x7c000000 + +#define VR41XX_PCI_MEM2_BASE 0x14000000 +#define VR41XX_PCI_MEM2_SIZE 0x02000000 +#define VR41XX_PCI_MEM2_MASK 0x7e000000 + +#define VR41XX_PCI_IO_BASE 0x16000000 +#define VR41XX_PCI_IO_SIZE 0x02000000 +#define VR41XX_PCI_IO_MASK 0x7e000000 + +#define VR41XX_PCI_IO_START 0x01000000 +#define VR41XX_PCI_IO_END 0x01ffffff + +#define VR41XX_PCI_MEM_START 0x12000000 +#define VR41XX_PCI_MEM_END 0x15ffffff + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_PCI_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_PCI_IO_SIZE +#define IO_MEM1_RESOURCE_START VR41XX_PCI_MEM1_BASE +#define IO_MEM1_RESOURCE_END (VR41XX_PCI_MEM1_BASE + VR41XX_PCI_MEM1_SIZE) +#define IO_MEM2_RESOURCE_START VR41XX_PCI_MEM2_BASE +#define IO_MEM2_RESOURCE_END (VR41XX_PCI_MEM2_BASE + VR41XX_PCI_MEM2_SIZE) + +/* + * General-Purpose I/O Pin Number + */ +#define TB0219_PCI_SLOT1_PIN 2 +#define TB0219_PCI_SLOT2_PIN 3 +#define TB0219_PCI_SLOT3_PIN 4 + +/* + * Interrupt Number + */ +#define TB0219_PCI_SLOT1_IRQ GIU_IRQ(TB0219_PCI_SLOT1_PIN) +#define TB0219_PCI_SLOT2_IRQ GIU_IRQ(TB0219_PCI_SLOT2_PIN) +#define TB0219_PCI_SLOT3_IRQ GIU_IRQ(TB0219_PCI_SLOT3_PIN) + +#define TB0219_RESET_REGS KSEG1ADDR(0x0a00000e) + +extern void tanbac_tb0229_restart(char *command); + +#endif /* __TANBAC_TB0229_H */ diff -Nru a/include/asm-mips/vr41xx/vr41xx.h b/include/asm-mips/vr41xx/vr41xx.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/vr41xx.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,192 @@ +/* + * include/asm-mips/vr41xx/vr41xx.h + * + * Include file for NEC VR4100 series. + * + * Copyright (C) 1999 Michael Klar + * Copyright (C) 2001, 2002 Paul Mundt + * Copyright (C) 2002 MontaVista Software, Inc. + * Copyright (C) 2002 TimeSys Corp. + * + * 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 __NEC_VR41XX_H +#define __NEC_VR41XX_H + +#include <linux/interrupt.h> + +/* + * CPU Revision + */ +/* VR4122 0x00000c70-0x00000c72 */ +#define PRID_VR4122_REV1_0 0x00000c70 +#define PRID_VR4122_REV2_0 0x00000c70 +#define PRID_VR4122_REV2_1 0x00000c70 +#define PRID_VR4122_REV3_0 0x00000c71 +#define PRID_VR4122_REV3_1 0x00000c72 + +/* VR4181A 0x00000c73-0x00000c7f */ +#define PRID_VR4181A_REV1_0 0x00000c73 +#define PRID_VR4181A_REV1_1 0x00000c74 + +/* VR4131 0x00000c80-0x00000c8f */ +#define PRID_VR4131_REV1_2 0x00000c80 +#define PRID_VR4131_REV2_0 0x00000c81 +#define PRID_VR4131_REV2_1 0x00000c82 +#define PRID_VR4131_REV2_2 0x00000c83 + +/* + * Bus Control Uint + */ +extern void vr41xx_bcu_init(void); + +/* + * Clock Mask Unit + */ +extern void vr41xx_cmu_init(u16 mask); +extern void vr41xx_clock_supply(u16 mask); +extern void vr41xx_clock_mask(u16 mask); + +/* + * Interrupt Control Unit + */ +/* CPU core Interrupt Numbers */ +#define MIPS_CPU_IRQ_BASE 0 +#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x)) +#define MIPS_SOFTINT0_IRQ MIPS_CPU_IRQ(0) +#define MIPS_SOFTINT1_IRQ MIPS_CPU_IRQ(1) +#define ICU_CASCADE_IRQ MIPS_CPU_IRQ(2) +#define RTC_LONG1_IRQ MIPS_CPU_IRQ(3) +#define RTC_LONG2_IRQ MIPS_CPU_IRQ(4) +/* RFU */ +#define BATTERY_IRQ MIPS_CPU_IRQ(6) +#define MIPS_COUNTER_IRQ MIPS_CPU_IRQ(7) + +/* SYINT1 Interrupt Numbers */ +#define SYSINT1_IRQ_BASE 8 +#define SYSINT1_IRQ(x) (SYSINT1_IRQ_BASE + (x)) +/* RFU */ +#define POWER_IRQ SYSINT1_IRQ(1) +/* RFU */ +#define GIUINT_CASCADE_IRQ SYSINT1_IRQ(8) +#define SIU_IRQ SYSINT1_IRQ(9) +/* RFU */ +#define SOFTINT_IRQ SYSINT1_IRQ(11) +#define CLKRUN_IRQ SYSINT1_IRQ(12) +#define SYSINT1_IRQ_LAST CLKRUN_IRQ + +/* SYSINT2 Interrupt Numbers */ +#define SYSINT2_IRQ_BASE 24 +#define SYSINT2_IRQ(x) (SYSINT2_IRQ_BASE + (x)) +/* RFU */ +#define LED_IRQ SYSINT2_IRQ(1) +/* RFU */ +#define VTCLOCK_IRQ SYSINT2_IRQ(3) +#define FIR_IRQ SYSINT2_IRQ(4) +#define DSIU_IRQ SYSINT2_IRQ(5) +#define PCI_IRQ SYSINT2_IRQ(6) +#define SCU_IRQ SYSINT2_IRQ(7) +#define CSI_IRQ SYSINT2_IRQ(8) +#define BCU_IRQ SYSINT2_IRQ(9) +#define SYSINT2_IRQ_LAST BCU_IRQ + +/* GIU Interrupt Numbers */ +#define GIU_IRQ_BASE 40 +#define GIU_IRQ(x) (GIU_IRQ_BASE + (x)) /* IRQ 40-71 */ +#define GIU_IRQ_LAST GIU_IRQ(31) + +extern void (*board_irq_init)(void); +extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq)); + +/* + * Gegeral-Purpose I/O Unit + */ +extern void vr41xx_enable_giuint(int pin); +extern void vr41xx_disable_giuint(int pin); +extern void vr41xx_clear_giuint(int pin); + +enum { + TRIGGER_LEVEL, + TRIGGER_EDGE +}; + +enum { + SIGNAL_THROUGH, + SIGNAL_HOLD +}; + +extern void vr41xx_set_irq_trigger(int pin, int trigger, int hold); + +enum { + LEVEL_LOW, + LEVEL_HIGH +}; + +extern void vr41xx_set_irq_level(int pin, int level); + +enum { + PIO_INPUT, + PIO_OUTPUT +}; + +enum { + DATA_LOW, + DATA_HIGH +}; + +/* + * Serial Interface Unit + */ +extern void vr41xx_siu_init(int interface, int module); +extern void vr41xx_siu_ifselect(int interface, int module); +extern int vr41xx_serial_ports; + +/* SIU interfaces */ +enum { + SIU_RS232C, + SIU_IRDA +}; + +/* IrDA interfaces */ +enum { + IRDA_SHARP = 1, + IRDA_TEMIC, + IRDA_HP +}; + +/* + * Debug Serial Interface Unit + */ +extern void vr41xx_dsiu_init(void); + +/* + * PCI Control Unit + */ +struct vr41xx_pci_address_space { + u32 internal_base; + u32 address_mask; + u32 pci_base; +}; + +struct vr41xx_pci_address_map { + struct vr41xx_pci_address_space *mem1; + struct vr41xx_pci_address_space *mem2; + struct vr41xx_pci_address_space *io; +}; + +extern void vr41xx_pciu_init(struct vr41xx_pci_address_map *map); + +/* + * MISC + */ +extern void vr41xx_time_init(void); +extern void vr41xx_timer_setup(struct irqaction *irq); + +extern void vr41xx_restart(char *command); +extern void vr41xx_halt(void); +extern void vr41xx_power_off(void); + +#endif /* __NEC_VR41XX_H */ diff -Nru a/include/asm-mips/vr41xx/vrc4173.h b/include/asm-mips/vr41xx/vrc4173.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/vrc4173.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,93 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/vrc4173.h + * + * BRIEF MODULE DESCRIPTION + * Include file for NEC VRC4173. + * + * 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) 2000 by Michael R. McDonald + * + * Copyright 2001-2003 Montavista Software Inc. + * Author: Yoichi Yuasa + * yyuasa@mvista.com or source@mvista.com + */ +#ifndef __NEC_VRC4173_H +#define __NEC_VRC4173_H + +#include <asm/io.h> + +/* + * Interrupt Number + */ +#define VRC4173_IRQ_BASE 72 +#define VRC4173_IRQ(x) (VRC4173_IRQ_BASE + (x)) +#define VRC4173_USB_IRQ VRC4173_IRQ(0) +#define VRC4173_PCMCIA2_IRQ VRC4173_IRQ(1) +#define VRC4173_PCMCIA1_IRQ VRC4173_IRQ(2) +#define VRC4173_PS2CH2_IRQ VRC4173_IRQ(3) +#define VRC4173_PS2CH1_IRQ VRC4173_IRQ(4) +#define VRC4173_PIU_IRQ VRC4173_IRQ(5) +#define VRC4173_AIU_IRQ VRC4173_IRQ(6) +#define VRC4173_KIU_IRQ VRC4173_IRQ(7) +#define VRC4173_GIU_IRQ VRC4173_IRQ(8) +#define VRC4173_AC97_IRQ VRC4173_IRQ(9) +#define VRC4173_AC97INT1_IRQ VRC4173_IRQ(10) +/* RFU */ +#define VRC4173_DOZEPIU_IRQ VRC4173_IRQ(13) +#define VRC4173_IRQ_LAST VRC4173_DOZEPIU_IRQ + +/* + * PCI I/O accesses + */ +extern unsigned long vrc4173_io_offset; + +#define set_vrc4173_io_offset(offset) do { vrc4173_io_offset = (offset); } while (0) + +#define vrc4173_outb(val,port) outb((val), vrc4173_io_offset+(port)) +#define vrc4173_outw(val,port) outw((val), vrc4173_io_offset+(port)) +#define vrc4173_outl(val,port) outl((val), vrc4173_io_offset+(port)) +#define vrc4173_outb_p(val,port) outb_p((val), vrc4173_io_offset+(port)) +#define vrc4173_outw_p(val,port) outw_p((val), vrc4173_io_offset+(port)) +#define vrc4173_outl_p(val,port) outl_p((val), vrc4173_io_offset+(port)) + +#define vrc4173_inb(port) inb(vrc4173_io_offset+(port)) +#define vrc4173_inw(port) inw(vrc4173_io_offset+(port)) +#define vrc4173_inl(port) inl(vrc4173_io_offset+(port)) +#define vrc4173_inb_p(port) inb_p(vrc4173_io_offset+(port)) +#define vrc4173_inw_p(port) inw_p(vrc4173_io_offset+(port)) +#define vrc4173_inl_p(port) inl_p(vrc4173_io_offset+(port)) + +#define vrc4173_outsb(port,addr,count) outsb(vrc4173_io_offset+(port),(addr),(count)) +#define vrc4173_outsw(port,addr,count) outsw(vrc4173_io_offset+(port),(addr),(count)) +#define vrc4173_outsl(port,addr,count) outsl(vrc4173_io_offset+(port),(addr),(count)) + +#define vrc4173_insb(port,addr,count) insb(vrc4173_io_offset+(port),(addr),(count)) +#define vrc4173_insw(port,addr,count) insw(vrc4173_io_offset+(port),(addr),(count)) +#define vrc4173_insl(port,addr,count) insl(vrc4173_io_offset+(port),(addr),(count)) + +/* + * Clock Mask Unit + */ +extern void vrc4173_clock_supply(u16 mask); +extern void vrc4173_clock_mask(u16 mask); + +/* + * General-Purpose I/O Unit + */ +enum { + PS2CH1_SELECT, + PS2CH2_SELECT, + TOUCHPANEL_SELECT, + KIU8_SELECT, + KIU10_SELECT, + KIU12_SELECT, + GPIO_SELECT +}; + +extern void vrc4173_select_function(int func); + +#endif /* __NEC_VRC4173_H */ diff -Nru a/include/asm-mips/vr41xx/workpad.h b/include/asm-mips/vr41xx/workpad.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/vr41xx/workpad.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,38 @@ +/* + * FILE NAME + * include/asm-mips/vr41xx/workpad.h + * + * BRIEF MODULE DESCRIPTION + * Include file for IBM WorkPad z50. + * + * Copyright 2002 Yoichi Yuasa + * yuasa@hh.iij4u.or.jp + * + * 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 __IBM_WORKPAD_H +#define __IBM_WORKPAD_H + +#include <asm/addrspace.h> +#include <asm/vr41xx/vr41xx.h> + +/* + * Board specific address mapping + */ +#define VR41XX_ISA_MEM_BASE 0x100000000 +#define VR41XX_ISA_MEM_SIZE 0x04000000 + +/* VR41XX_ISA_IO_BASE includes offset from real base. */ +#define VR41XX_ISA_IO_BASE 0x15000000 +#define VR41XX_ISA_IO_SIZE 0x03000000 + +#define IO_PORT_BASE KSEG1ADDR(VR41XX_ISA_IO_BASE) +#define IO_PORT_RESOURCE_START 0 +#define IO_PORT_RESOURCE_END VR41XX_ISA_IO_SIZE +#define IO_MEM_RESOURCE_START VR41XX_ISA_MEM_BASE +#define IO_MEM_RESOURCE_END (VR41XX_ISA_MEM_BASE + VR41XX_ISA_MEM_SIZE) + +#endif /* __IBM_WORKPAD_H */ diff -Nru a/include/asm-mips/war.h b/include/asm-mips/war.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips/war.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,132 @@ +/* + * 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) 2002 by Ralf Baechle + */ +#ifndef _ASM_WAR_H +#define _ASM_WAR_H + +#include <linux/config.h> + +/* + * Pleassures of the R4600 V1.x. Cite from the IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * #define R4600_V1_HIT_CACHEOP_WAR 1 + */ + + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * + * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, + * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only + * operate correctly if the internal data cache refill buffer is empty. These + * CACHE instructions should be separated from any potential data cache miss + * by a load instruction to an uncached address to empty the response buffer." + * (Revision 2.0 device errata from IDT available on http://www.idt.com/ + * in .pdf format.) + * + * #define R4600_V2_HIT_CACHEOP_WAR 1 + */ + +/* + * R4600 CPU modules for the Indy come with both V1.7 and V2.0 processors. + */ +#ifdef CONFIG_SGI_IP22 + +#define R4600_V1_HIT_CACHEOP_WAR 1 +#define R4600_V2_HIT_CACHEOP_WAR 1 + +#endif + +/* + * But the RM200C seems to have been shipped only with V2.0 R4600s + */ +#ifdef CONFIG_SNI_RM200_PCI + +#define R4600_V2_HIT_CACHEOP_WAR 1 + +#endif + +#ifdef CONFIG_CPU_R5432 + +/* + * When an interrupt happens on a CP0 register read instruction, CPU may + * lock up or read corrupted values of CP0 registers after it enters + * the exception handler. + * + * This workaround makes sure that we read a "safe" CP0 register as the + * first thing in the exception handler, which breaks one of the + * pre-conditions for this problem. + */ +#define R5432_CP0_INTERRUPT_WAR 1 + +#endif + +#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ + defined(CONFIG_SB1_PASS_2_WORKAROUNDS) + +/* + * Workaround for the Sibyte M3 errata the text of which can be found at + * + * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt + * + * This will enable the use of a special TLB refill handler which does a + * consistency check on the information in c0_badvaddr and c0_entryhi and + * will just return and take the exception again if the information was + * found to be inconsistent. + */ +#define BCM1250_M3_WAR 1 + +/* + * This is a DUART workaround related to glitches around register accesses + */ +#define SIBYTE_1956_WAR 1 + +#endif + +/* + * Workarounds default to off + */ +#ifndef R4600_V1_HIT_CACHEOP_WAR +#define R4600_V1_HIT_CACHEOP_WAR 0 +#endif +#ifndef R4600_V2_HIT_CACHEOP_WAR +#define R4600_V2_HIT_CACHEOP_WAR 0 +#endif +#ifndef R5432_CP0_INTERRUPT_WAR +#define R5432_CP0_INTERRUPT_WAR 0 +#endif +#ifndef BCM1250_M3_WAR +#define BCM1250_M3_WAR 0 +#endif +#ifndef SIBYTE_1956_WAR +#define SIBYTE_1956_WAR 0 +#endif + +#endif /* _ASM_WAR_H */ diff -Nru a/include/asm-mips/watch.h b/include/asm-mips/watch.h --- a/include/asm-mips/watch.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips/watch.h Fri Jun 27 14:20:06 2003 @@ -18,20 +18,18 @@ wr_load = 2 }; -extern char watch_available; - extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref); extern asmlinkage void __watch_clear(void); extern asmlinkage void __watch_reenable(void); #define watch_set(addr, ref) \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_set(addr, ref) #define watch_clear() \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_clear() #define watch_reenable() \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_reenable() #endif /* __ASM_WATCH_H */ diff -Nru a/include/asm-mips/wbflush.h b/include/asm-mips/wbflush.h --- a/include/asm-mips/wbflush.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips/wbflush.h Fri Jun 27 14:19:59 2003 @@ -6,31 +6,30 @@ * for more details. * * Copyright (c) 1998 Harald Koerfgen - * - * $Id: wbflush.h,v 1.2 1999/08/13 17:07:28 harald Exp $ + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef __ASM_MIPS_WBFLUSH_H #define __ASM_MIPS_WBFLUSH_H #include <linux/config.h> -#if defined(CONFIG_CPU_HAS_WB) -/* - * R2000 or R3000 - */ -extern void (*__wbflush) (void); +#ifdef CONFIG_CPU_HAS_WB -#define wbflush() __wbflush() +extern void (*__wbflush)(void); +extern void wbflush_setup(void); -#else -/* - * we don't need no stinkin' wbflush - */ +#define wbflush() \ + do { \ + __sync(); \ + __wbflush(); \ + } while (0) -#define wbflush() do { } while(0) +#else /* !CONFIG_CPU_HAS_WB */ -#endif +#define wbflush_setup() do { } while (0) -extern void wbflush_setup(void); +#define wbflush() fast_iob() + +#endif /* !CONFIG_CPU_HAS_WB */ #endif /* __ASM_MIPS_WBFLUSH_H */ diff -Nru a/include/asm-mips64/a.out.h b/include/asm-mips64/a.out.h --- a/include/asm-mips64/a.out.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/a.out.h Fri Jun 27 14:19:53 2003 @@ -26,7 +26,7 @@ #ifdef __KERNEL__ -#define STACK_TOP (current->thread.mflags & MF_32BIT ? 0x7fff8000 : TASK_SIZE) +#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE) #endif diff -Nru a/include/asm-mips64/addrspace.h b/include/asm-mips64/addrspace.h --- a/include/asm-mips64/addrspace.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/addrspace.h Fri Jun 27 14:19:52 2003 @@ -5,110 +5,142 @@ * * Copyright (C) 1996, 1999 by Ralf Baechle * Copyright (C) 1990, 1999 by Silicon Graphics, Inc. + * Copyright (C) 2002 Maciej W. Rozycki */ -#ifndef _ASM_ADDRSPACE_H -#define _ASM_ADDRSPACE_H +#ifndef __ASM_ADDRSPACE_H +#define __ASM_ADDRSPACE_H #include <linux/config.h> /* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ATYPE_ +#define _ATYPE32_ +#define _ATYPE64_ +#else +#define _ATYPE_ __PTRDIFF_TYPE__ +#define _ATYPE32_ int +#define _ATYPE64_ long long +#endif + +/* + * 32-bit MIPS address spaces + */ +#ifdef __ASSEMBLY__ +#define _ACAST32_ +#define _ACAST64_ +#else +#define _ACAST32_ (_ATYPE_)(_ATYPE32_) /* widen if necessary */ +#define _ACAST64_ (_ATYPE64_) /* do _not_ narrow */ +#endif + +/* * Memory segments (32bit kernel mode addresses) */ -#define KUSEG 0x0000000000000000 -#define KSEG0 0xffffffff80000000 -#define KSEG1 0xffffffffa0000000 -#define KSEG2 0xffffffffc0000000 -#define KSEG3 0xffffffffe0000000 +#define KUSEG 0x0000000000000000 +#define KSEG0 0xffffffff80000000 +#define KSEG1 0xffffffffa0000000 +#define KSEG2 0xffffffffc0000000 +#define KSEG3 0xffffffffe0000000 /* * Returns the kernel segment base of a given address */ -#define KSEGX(a) (((unsigned long)(a)) & 0xe0000000) +#define KSEGX(a) ((_ACAST64_ (a)) & 0xffffffffe0000000) /* * Returns the physical address of a KSEG0/KSEG1 address */ -#define CPHYSADDR(a) (((unsigned long)(a)) & 0x000000001fffffffUL) -#define PHYSADDR(a) (((unsigned long)(a)) & 0x000000ffffffffffUL) +#define XPHYSADDR(a) ((_ACAST64_ (a)) & 0x000000ffffffffff) +#define CPHYSADDR(a) ((_ACAST64_ (a)) & 0x000000001fffffff) + +#define PHYSADDR(a) ({ \ + const _ATYPE64_ _a = _ACAST64_ (a); \ + _a == _ACAST32_ _a ? CPHYSADDR(_a) : XPHYSADDR(_a); }) /* * Map an address to a certain kernel segment */ -#define KSEG0ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG0)) -#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG1)) -#define KSEG2ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG2)) -#define KSEG3ADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x000000ffffffffffUL) | KSEG3)) +#define KSEG0ADDR(a) (CPHYSADDR(a) | KSEG0) +#define KSEG1ADDR(a) (CPHYSADDR(a) | KSEG1) +#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2) +#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3) /* * Memory segments (64bit kernel mode addresses) */ -#define XKUSEG 0x0000000000000000 -#define XKSSEG 0x4000000000000000 -#define XKPHYS 0x8000000000000000 -#define XKSEG 0xc000000000000000 -#define CKSEG0 0xffffffff80000000 -#define CKSEG1 0xffffffffa0000000 -#define CKSSEG 0xffffffffc0000000 -#define CKSEG3 0xffffffffe0000000 +#define XKUSEG 0x0000000000000000 +#define XKSSEG 0x4000000000000000 +#define XKPHYS 0x8000000000000000 +#define XKSEG 0xc000000000000000 +#define CKSEG0 0xffffffff80000000 +#define CKSEG1 0xffffffffa0000000 +#define CKSSEG 0xffffffffc0000000 +#define CKSEG3 0xffffffffe0000000 #if defined (CONFIG_CPU_R4300) \ || defined (CONFIG_CPU_R4X00) \ || defined (CONFIG_CPU_R5000) \ - || defined (CONFIG_CPU_NEVADA) -#define KUSIZE 0x0000010000000000 /* 2^^40 */ -#define KUSIZE_64 0x0000010000000000 /* 2^^40 */ -#define K0SIZE 0x0000001000000000 /* 2^^36 */ -#define K1SIZE 0x0000001000000000 /* 2^^36 */ -#define K2SIZE 0x000000ff80000000 -#define KSEGSIZE 0x000000ff80000000 /* max syssegsz */ -#define TO_PHYS_MASK 0x0000000fffffffff /* 2^^36 - 1 */ + || defined (CONFIG_CPU_NEVADA) \ + || defined (CONFIG_CPU_MIPS64) +#define KUSIZE 0x0000010000000000 /* 2^^40 */ +#define KUSIZE_64 0x0000010000000000 /* 2^^40 */ +#define K0SIZE 0x0000001000000000 /* 2^^36 */ +#define K1SIZE 0x0000001000000000 /* 2^^36 */ +#define K2SIZE 0x000000ff80000000 +#define KSEGSIZE 0x000000ff80000000 /* max syssegsz */ +#define TO_PHYS_MASK 0x0000000fffffffff /* 2^^36 - 1 */ #endif #if defined (CONFIG_CPU_R8000) /* We keep KUSIZE consistent with R4000 for now (2^^40) instead of (2^^48) */ -#define KUSIZE 0x0000010000000000 /* 2^^40 */ -#define KUSIZE_64 0x0000010000000000 /* 2^^40 */ -#define K0SIZE 0x0000010000000000 /* 2^^40 */ -#define K1SIZE 0x0000010000000000 /* 2^^40 */ -#define K2SIZE 0x0001000000000000 -#define KSEGSIZE 0x0000010000000000 /* max syssegsz */ -#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */ +#define KUSIZE 0x0000010000000000 /* 2^^40 */ +#define KUSIZE_64 0x0000010000000000 /* 2^^40 */ +#define K0SIZE 0x0000010000000000 /* 2^^40 */ +#define K1SIZE 0x0000010000000000 /* 2^^40 */ +#define K2SIZE 0x0001000000000000 +#define KSEGSIZE 0x0000010000000000 /* max syssegsz */ +#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */ #endif #if defined (CONFIG_CPU_R10000) -#define KUSIZE 0x0000010000000000 /* 2^^40 */ -#define KUSIZE_64 0x0000010000000000 /* 2^^40 */ -#define K0SIZE 0x0000010000000000 /* 2^^40 */ -#define K1SIZE 0x0000010000000000 /* 2^^40 */ -#define K2SIZE 0x00000fff80000000 -#define KSEGSIZE 0x00000fff80000000 /* max syssegsz */ -#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */ +#define KUSIZE 0x0000010000000000 /* 2^^40 */ +#define KUSIZE_64 0x0000010000000000 /* 2^^40 */ +#define K0SIZE 0x0000010000000000 /* 2^^40 */ +#define K1SIZE 0x0000010000000000 /* 2^^40 */ +#define K2SIZE 0x00000fff80000000 +#define KSEGSIZE 0x00000fff80000000 /* max syssegsz */ +#define TO_PHYS_MASK 0x000000ffffffffff /* 2^^40 - 1 */ #endif /* * Further names for SGI source compatibility. These are stolen from * IRIX's <sys/mips_addrspace.h>. */ -#define KUBASE 0 -#define KUSIZE_32 0x0000000080000000 /* KUSIZE for a 32 bit proc */ -#define K0BASE 0xa800000000000000 -#define K0BASE_EXL_WR K0BASE /* exclusive on write */ -#define K0BASE_NONCOH 0x9800000000000000 /* noncoherent */ -#define K0BASE_EXL 0xa000000000000000 /* exclusive */ +#define KUBASE 0 +#define KUSIZE_32 0x0000000080000000 /* KUSIZE + for a 32 bit proc */ +#define K0BASE 0xa800000000000000 +#define K0BASE_EXL_WR K0BASE /* exclusive on write */ +#define K0BASE_NONCOH 0x9800000000000000 /* noncoherent */ +#define K0BASE_EXL 0xa000000000000000 /* exclusive */ #ifdef CONFIG_SGI_IP27 -#define K1BASE 0x9600000000000000 /* Uncached attr 3, uncac */ +#define K1BASE 0x9600000000000000 /* uncached attr 3, + uncac */ #else -#define K1BASE 0x9000000000000000 +#define K1BASE 0x9000000000000000 #endif -#define K2BASE 0xc000000000000000 +#define K2BASE 0xc000000000000000 #if !defined (CONFIG_CPU_R8000) #define COMPAT_K1BASE32 0xffffffffa0000000 #define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */ #endif -#define KDM_TO_PHYS(x) ((unsigned long)(x) & TO_PHYS_MASK) -#define PHYS_TO_K0(x) ((unsigned long)(x) | K0BASE) +#define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK) +#define PHYS_TO_K0(x) (_ACAST64_ (x) | K0BASE) -#endif /* _ASM_ADDRSPACE_H */ +#endif /* __ASM_ADDRSPACE_H */ diff -Nru a/include/asm-mips64/asm.h b/include/asm-mips64/asm.h --- a/include/asm-mips64/asm.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips64/asm.h Fri Jun 27 14:19:30 2003 @@ -6,6 +6,7 @@ * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle * Copyright (C) 1999 by Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 2002 Maciej W. Rozycki * * Some useful macros for MIPS assembler code * @@ -87,7 +88,7 @@ #define PANIC(msg) \ .set push; \ .set reorder; \ - la a0,8f; \ + PTR_LA a0,8f; \ jal panic; \ 9: b 9b; \ .set pop; \ @@ -99,26 +100,26 @@ #define PRINT(string) \ .set push; \ .set reorder; \ - la a0,8f; \ + PTR_LA a0,8f; \ jal printk; \ .set pop; \ TEXT(string) #define TEXT(msg) \ - .data; \ + .pushsection .data; \ 8: .asciiz msg; \ - .previous; + .popsection; /* * Build text tables */ #define TTABLE(string) \ - .text; \ + .pushsection .text; \ .word 1f; \ - .previous; \ - .data; \ -1: .asciz string; \ - .previous + .popsection \ + .pushsection .data; \ +1: .asciiz string; \ + .popsection /* * MIPS IV pref instruction. @@ -127,21 +128,25 @@ * MIPS IV implementations are free to treat this as a nop. The R5000 * is one of them. So we should have an option not to use this instruction. */ -#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS64) +#ifdef CONFIG_CPU_HAS_PREFETCH + #define PREF(hint,addr) \ pref hint,addr + #define PREFX(hint,addr) \ prefx hint,addr -#else -#define PREF -#define PREFX -#endif + +#else /* !CONFIG_CPU_HAS_PREFETCH */ + +#define PREF(hint,addr) +#define PREFX(hint,addr) + +#endif /* !CONFIG_CPU_HAS_PREFETCH */ /* * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. */ -#if _MIPS_ISA == _MIPS_ISA_MIPS1 +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) #define MOVN(rd,rs,rt) \ .set push; \ .set reorder; \ @@ -153,7 +158,7 @@ .set push; \ .set reorder; \ bnez rt,9f; \ - move rd,rt; \ + move rd,rs; \ .set pop; \ 9: #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ @@ -162,24 +167,24 @@ .set push; \ .set noreorder; \ bnezl rt,9f; \ - move rd,rs; \ + move rd,rs; \ .set pop; \ 9: #define MOVZ(rd,rs,rt) \ .set push; \ .set noreorder; \ beqzl rt,9f; \ - movz rd,rs; \ + move rd,rs; \ .set pop; \ 9: #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS64) + (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) #define MOVN(rd,rs,rt) \ movn rd,rs,rt #define MOVZ(rd,rs,rt) \ movz rd,rs,rt -#endif /* MIPS IV, MIPS V or MIPS64 */ +#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ /* * Stack alignment @@ -196,6 +201,10 @@ #endif /* + * Macros to handle different pointer/register sizes for 32/64-bit code + */ + +/* * Size of a register */ #ifdef __mips64 @@ -210,47 +219,54 @@ */ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ (_MIPS_ISA == _MIPS_ISA_MIPS32) -#define REG_S sw -#define REG_L lw -#define PTR_SUBU dsubu -#define PTR_ADDU daddu +#define REG_S sw +#define REG_L lw +#define REG_SUBU subu +#define REG_ADDU addu #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) -#define REG_S sd -#define REG_L ld -/* We still live in a 32 bit address space ... */ -#define PTR_SUBU dsubu -#define PTR_ADDU daddu +#define REG_S sd +#define REG_L ld +#define REG_SUBU dsubu +#define REG_ADDU daddu #endif /* * How to add/sub/load/store/shift C int variables. */ #if (_MIPS_SZINT == 32) -#define INT_ADD add -#define INT_ADDI addi +#define INT_ADD add #define INT_ADDU addu +#define INT_ADDI addi #define INT_ADDIU addiu -#define INT_SUB add -#define INT_SUBI subi +#define INT_SUB sub #define INT_SUBU subu -#define INT_SUBIU subu #define INT_L lw #define INT_S sw +#define INT_SLL sll +#define INT_SLLV sllv +#define INT_SRL srl +#define INT_SRLV srlv +#define INT_SRA sra +#define INT_SRAV srav #endif #if (_MIPS_SZINT == 64) -#define INT_ADD dadd -#define INT_ADDI daddi +#define INT_ADD dadd #define INT_ADDU daddu +#define INT_ADDI daddi #define INT_ADDIU daddiu -#define INT_SUB dadd -#define INT_SUBI dsubi +#define INT_SUB dsub #define INT_SUBU dsubu -#define INT_SUBIU dsubu #define INT_L ld #define INT_S sd +#define INT_SLL dsll +#define INT_SLLV dsllv +#define INT_SRL dsrl +#define INT_SRLV dsrlv +#define INT_SRA dsra +#define INT_SRAV dsrav #endif /* @@ -258,13 +274,11 @@ */ #if (_MIPS_SZLONG == 32) #define LONG_ADD add -#define LONG_ADDI addi #define LONG_ADDU addu +#define LONG_ADDI addi #define LONG_ADDIU addiu -#define LONG_SUB add -#define LONG_SUBI subi +#define LONG_SUB sub #define LONG_SUBU subu -#define LONG_SUBIU subu #define LONG_L lw #define LONG_S sw #define LONG_SLL sll @@ -277,13 +291,11 @@ #if (_MIPS_SZLONG == 64) #define LONG_ADD dadd -#define LONG_ADDI daddi #define LONG_ADDU daddu +#define LONG_ADDI daddi #define LONG_ADDIU daddiu -#define LONG_SUB dadd -#define LONG_SUBI dsubi +#define LONG_SUB dsub #define LONG_SUBU dsubu -#define LONG_SUBIU dsubu #define LONG_L ld #define LONG_S sd #define LONG_SLL dsll @@ -298,16 +310,15 @@ * How to add/sub/load/store/shift pointers. */ #if (_MIPS_SZPTR == 32) -#define PTR_ADD add -#define PTR_ADDI addi +#define PTR_ADD add #define PTR_ADDU addu +#define PTR_ADDI addi #define PTR_ADDIU addiu -#define PTR_SUB add -#define PTR_SUBI subi +#define PTR_SUB sub #define PTR_SUBU subu -#define PTR_SUBIU subu #define PTR_L lw #define PTR_S sw +#define PTR_LA la #define PTR_SLL sll #define PTR_SLLV sllv #define PTR_SRL srl @@ -323,16 +334,15 @@ #endif #if (_MIPS_SZPTR == 64) -#define PTR_ADD dadd -#define PTR_ADDI daddi +#define PTR_ADD dadd #define PTR_ADDU daddu +#define PTR_ADDI daddi #define PTR_ADDIU daddiu -#define PTR_SUB dadd -#define PTR_SUBI dsubi +#define PTR_SUB dsub #define PTR_SUBU dsubu -#define PTR_SUBIU dsubu #define PTR_L ld #define PTR_S sd +#define PTR_LA dla #define PTR_SLL dsll #define PTR_SLLV dsllv #define PTR_SRL dsrl @@ -352,13 +362,15 @@ */ #if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \ (_MIPS_ISA == _MIPS_ISA_MIPS32) -#define MFC0 mfc0 -#define MTC0 mtc0 +#define MFC0 mfc0 +#define MTC0 mtc0 #endif #if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \ (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64) -#define MFC0 dmfc0 -#define MTC0 dmtc0 +#define MFC0 dmfc0 +#define MTC0 dmtc0 #endif + +#define SSNOP sll zero,zero,1 #endif /* __ASM_ASM_H */ diff -Nru a/include/asm-mips64/asmmacro.h b/include/asm-mips64/asmmacro.h --- a/include/asm-mips64/asmmacro.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/asmmacro.h Fri Jun 27 14:19:54 2003 @@ -8,7 +8,21 @@ #ifndef _ASM_ASMMACRO_H #define _ASM_ASMMACRO_H +#include <linux/config.h> #include <asm/offset.h> + +#ifdef CONFIG_CPU_SB1 +#define FPU_ENABLE_HAZARD \ + .set push; \ + .set noreorder; \ + .set mips2; \ + SSNOP; \ + bnezl $0, .+4; \ + SSNOP; \ + .set pop +#else +#define FPU_ENABLE_HAZARD +#endif .macro fpu_save_16even thread tmp cfc1 \tmp, fcr31 diff -Nru a/include/asm-mips64/atomic.h b/include/asm-mips64/atomic.h --- a/include/asm-mips64/atomic.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/atomic.h Fri Jun 27 14:19:53 2003 @@ -88,6 +88,7 @@ "sc\t%0,%2\n\t" "beqz\t%0,1b\n\t" "addu\t%0,%1,%3\n\t" + "sync\n\t" ".set\treorder" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -107,6 +108,7 @@ "sc\t%0,%2\n\t" "beqz\t%0,1b\n\t" "subu\t%0,%1,%3\n\t" + "sync\n\t" ".set\treorder" : "=&r" (result), "=&r" (temp), "=m" (v->counter) : "Ir" (i), "m" (v->counter) @@ -138,8 +140,8 @@ * and returns true if the result is zero, or false for all * other cases. Note that the guaranteed * useful range of an atomic_t is only 24 bits. - * atomic_inc_and_test is currently not implemented for mips64. */ +#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) /* * atomic_dec_and_test - decrement by 1 and test @@ -179,15 +181,14 @@ * if the result is negative, or false when * result is greater than or equal to zero. Note that the guaranteed * useful range of an atomic_t is only 24 bits. - * - * atomic_add_negative is currently not implemented for mips64. */ +#define atomic_add_negative(i,v) (atomic_add_return(i, (v)) < 0) /* Atomic operations are already serializing */ -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() +#define smp_mb__before_atomic_dec() smp_mb() +#define smp_mb__after_atomic_dec() smp_mb() +#define smp_mb__before_atomic_inc() smp_mb() +#define smp_mb__after_atomic_inc() smp_mb() #endif /* defined(__KERNEL__) */ diff -Nru a/include/asm-mips64/bcache.h b/include/asm-mips64/bcache.h --- a/include/asm-mips64/bcache.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/bcache.h Fri Jun 27 14:20:05 2003 @@ -11,10 +11,8 @@ #include <linux/config.h> -#ifdef CONFIG_BOARD_SCACHE - /* Some R4000 / R4400 / R4600 / R5000 machines may have a non-dma-coherent, - chipset implemented caches. On machines with other CPUs the CPU does the + chipset implemented caches. On machines with other CPUs the CPU does the cache thing itself. */ struct bcache_ops { void (*bc_enable)(void); @@ -26,24 +24,26 @@ extern void indy_sc_init(void); extern void sni_pcimt_sc_init(void); +#ifdef CONFIG_BOARD_SCACHE + extern struct bcache_ops *bcops; -extern inline void bc_enable(void) +static inline void bc_enable(void) { bcops->bc_enable(); } -extern inline void bc_disable(void) +static inline void bc_disable(void) { bcops->bc_disable(); } -extern inline void bc_wback_inv(unsigned long page, unsigned long size) +static inline void bc_wback_inv(unsigned long page, unsigned long size) { bcops->bc_wback_inv(page, size); } -extern inline void bc_inv(unsigned long page, unsigned long size) +static inline void bc_inv(unsigned long page, unsigned long size) { bcops->bc_inv(page, size); } diff -Nru a/include/asm-mips64/bitops.h b/include/asm-mips64/bitops.h --- a/include/asm-mips64/bitops.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-mips64/bitops.h Fri Jun 27 14:20:01 2003 @@ -9,8 +9,18 @@ #ifndef _ASM_BITOPS_H #define _ASM_BITOPS_H +#include <linux/config.h> +#include <linux/compiler.h> #include <linux/types.h> -#include <linux/byteorder/swab.h> /* sigh ... */ +#include <asm/byteorder.h> /* sigh ... */ + +#if (_MIPS_SZLONG == 32) +#define SZLONG_LOG 5 +#define SZLONG_MASK 31UL +#elif (_MIPS_SZLONG == 64) +#define SZLONG_LOG 6 +#define SZLONG_MASK 63UL +#endif #ifndef __KERNEL__ #error "Don't do this, sucker ..." @@ -18,7 +28,12 @@ #include <asm/system.h> #include <asm/sgidefs.h> -#include <asm/mipsregs.h> + +/* + * clear_bit() doesn't provide any barrier for the compiler. + */ +#define smp_mb__before_clear_bit() smp_mb() +#define smp_mb__after_clear_bit() smp_mb() /* * set_bit - Atomically set a bit in memory @@ -30,8 +45,7 @@ * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void -set_bit(unsigned long nr, volatile void *addr) +static inline void set_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 6); unsigned long temp; @@ -55,7 +69,7 @@ * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __set_bit(int nr, volatile void * addr) +static inline void __set_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 6); @@ -72,8 +86,7 @@ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() * in order to ensure changes are visible on other processors. */ -extern __inline__ void -clear_bit(unsigned long nr, volatile void *addr) +static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 6); unsigned long temp; @@ -87,20 +100,32 @@ : "ir" (~(1UL << (nr & 0x3f))), "m" (*m)); } -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() +/* + * __clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * Unlike clear_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static inline void __clear_bit(int nr, volatile unsigned long * addr) +{ + unsigned long * m = ((unsigned long *) addr) + (nr >> 6); + + *m &= ~(1UL << (nr & 0x3f)); +} /* * change_bit - Toggle a bit in memory - * @nr: Bit to clear + * @nr: Bit to change * @addr: Address to start counting from * * change_bit() is atomic and may not be reordered. * Note that @nr may be almost arbitrarily large; this function is not * restricted to acting on a single-word quantity. */ -extern __inline__ void -change_bit(unsigned long nr, volatile void *addr) +static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 6); unsigned long temp; @@ -116,14 +141,14 @@ /* * __change_bit - Toggle a bit in memory - * @nr: the bit to set + * @nr: the bit to change * @addr: the address to start counting from * * Unlike change_bit(), this function is non-atomic and may be reordered. * If it's called on the same region of memory simultaneously, the effect * may be that only one operation succeeds. */ -extern __inline__ void __change_bit(int nr, volatile void * addr) +static inline void __change_bit(int nr, volatile unsigned long * addr) { unsigned long * m = ((unsigned long *) addr) + (nr >> 6); @@ -135,11 +160,11 @@ * @nr: Bit to set * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ unsigned long -test_and_set_bit(unsigned long nr, volatile void *addr) +static inline unsigned long test_and_set_bit(unsigned long nr, + volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 6); unsigned long temp, res; @@ -151,6 +176,9 @@ "scd\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x3f)), "m" (*m) @@ -164,12 +192,11 @@ * @nr: Bit to set * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int -__test_and_set_bit(int nr, volatile void * addr) +static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) { unsigned long mask, retval; long *a = (unsigned long *) addr; @@ -184,14 +211,14 @@ /* * test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ unsigned long -test_and_clear_bit(unsigned long nr, volatile void *addr) +static inline unsigned long test_and_clear_bit(unsigned long nr, + volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 6); unsigned long temp, res; @@ -204,6 +231,9 @@ "scd\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x3f)), "m" (*m) @@ -214,15 +244,14 @@ /* * __test_and_clear_bit - Clear a bit and return its old value - * @nr: Bit to set + * @nr: Bit to clear * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int -__test_and_clear_bit(int nr, volatile void * addr) +static inline int __test_and_clear_bit(int nr, volatile unsigned long * addr) { unsigned long mask, retval; unsigned long *a = (unsigned long *) addr; @@ -237,14 +266,14 @@ /* * test_and_change_bit - Change a bit and return its new value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is atomic and cannot be reordered. + * This operation is atomic and cannot be reordered. * It also implies a memory barrier. */ -extern __inline__ unsigned long -test_and_change_bit(unsigned long nr, volatile void *addr) +static inline unsigned long test_and_change_bit(unsigned long nr, + volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> 6); unsigned long temp, res; @@ -256,6 +285,9 @@ "scd\t%2, %1\n\t" "beqz\t%2, 1b\n\t" " and\t%2, %0, %3\n\t" +#ifdef CONFIG_SMP + "sync\n\t" +#endif ".set\treorder" : "=&r" (temp), "=m" (*m), "=&r" (res) : "r" (1UL << (nr & 0x3f)), "m" (*m) @@ -266,15 +298,14 @@ /* * __test_and_change_bit - Change a bit and return its old value - * @nr: Bit to set + * @nr: Bit to change * @addr: Address to count from * - * This operation is non-atomic and can be reordered. + * This operation is non-atomic and can be reordered. * If two examples of this operation race, one can appear to succeed * but actually fail. You must protect multiple accesses with a lock. */ -extern __inline__ int -__test_and_change_bit(int nr, volatile void * addr) +static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) { unsigned long mask, retval; unsigned long *a = (unsigned long *) addr; @@ -291,161 +322,48 @@ * @nr: bit number to test * @addr: Address to start counting from */ -extern __inline__ unsigned long -test_bit(int nr, volatile void * addr) +static inline int test_bit(int nr, const volatile unsigned long * addr) { - return 1UL & (((volatile unsigned long *) addr)[nr >> 6] >> (nr & 0x3f)); + return 1UL & (((const volatile unsigned long *) addr)[nr >> SZLONG_LOG] >> (nr & SZLONG_MASK)); } -#ifndef __MIPSEB__ - -/* Little endian versions. */ - -/* - * find_first_zero_bit - find the first zero bit in a memory region - * @addr: The address to start the search at - * @size: The maximum size to search - * - * Returns the bit-number of the first zero bit, not the number of the byte - * containing a bit. - */ -extern __inline__ int -find_first_zero_bit (void *addr, unsigned size) -{ - unsigned long dummy; - int res; - - if (!size) - return 0; - - __asm__ (".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tsubu\t$1,%6,%0\n\t" - "blez\t$1,2f\n\t" - "lw\t$1,(%5)\n\t" - "addiu\t%5,4\n\t" -#if (_MIPS_ISA == _MIPS_ISA_MIPS2 ) || (_MIPS_ISA == _MIPS_ISA_MIPS3 ) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5 ) || \ - (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) - "beql\t%1,$1,1b\n\t" - "addiu\t%0,32\n\t" -#else - "addiu\t%0,32\n\t" - "beq\t%1,$1,1b\n\t" - "nop\n\t" - "subu\t%0,32\n\t" -#endif - "li\t%1,1\n" - "1:\tand\t%2,$1,%1\n\t" - "beqz\t%2,2f\n\t" - "sll\t%1,%1,1\n\t" - "bnez\t%1,1b\n\t" - "add\t%0,%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "2:" - : "=r" (res), "=r" (dummy), "=r" (addr) - : "0" ((signed int) 0), "1" ((unsigned int) 0xffffffff), - "2" (addr), "r" (size) - : "$1"); - - return res; -} - -/* - * find_next_zero_bit - find the first zero bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -extern __inline__ int -find_next_zero_bit (void * addr, int size, int offset) -{ - unsigned int *p = ((unsigned int *) addr) + (offset >> 5); - int set = 0, bit = offset & 31, res; - unsigned long dummy; - - if (bit) { - /* - * Look for zero in first byte - */ - __asm__(".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tand\t$1,%4,%1\n\t" - "beqz\t$1,1f\n\t" - "sll\t%1,%1,1\n\t" - "bnez\t%1,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder\n" - "1:" - : "=r" (set), "=r" (dummy) - : "0" (0), "1" (1 << bit), "r" (*p) - : "$1"); - if (set < (32 - bit)) - return set + offset; - set = 32 - bit; - p++; - } - /* - * No zero yet, search remaining full bytes for a zero - */ - res = find_first_zero_bit(p, size - 32 * (p - (unsigned int *) addr)); - return offset + set + res; -} - -#endif /* !(__MIPSEB__) */ - /* * ffz - find first zero in word. * @word: The word to search * * Undefined if no zero exists, so code should check against ~0UL first. */ -extern __inline__ unsigned long ffz(unsigned long word) +static __inline__ unsigned long ffz(unsigned long word) { - unsigned long k; + int b = 0, s; word = ~word; - k = 63; - if (word & 0x00000000ffffffffUL) { k -= 32; word <<= 32; } - if (word & 0x0000ffff00000000UL) { k -= 16; word <<= 16; } - if (word & 0x00ff000000000000UL) { k -= 8; word <<= 8; } - if (word & 0x0f00000000000000UL) { k -= 4; word <<= 4; } - if (word & 0x3000000000000000UL) { k -= 2; word <<= 2; } - if (word & 0x4000000000000000UL) { k -= 1; } + s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s; + s = 16; if (word << 48 != 0) s = 0; b += s; word >>= s; + s = 8; if (word << 56 != 0) s = 0; b += s; word >>= s; + s = 4; if (word << 60 != 0) s = 0; b += s; word >>= s; + s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s; + s = 1; if (word << 63 != 0) s = 0; b += s; - return k; + return b; } -#ifdef __KERNEL__ - - /* - * ffs - find first bit set - * @x: the word to search + * __ffs - find first bit in word. + * @word: The word to search * - * This is defined the same way as - * the libc and compiler builtin ffs routines, therefore - * differs in spirit from the above ffz (man ffs). + * Undefined if no bit exists, so code should check against 0 first. */ - -#define ffs(x) generic_ffs(x) +static __inline__ unsigned long __ffs(unsigned long word) +{ + return ffz(~word); +} /* - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * - * The Hamming Weight of a number is the total number of bits set in it. + * fls: find last bit set. */ -#define hweight32(x) generic_hweight32(x) -#define hweight16(x) generic_hweight16(x) -#define hweight8(x) generic_hweight8(x) - -#endif /* __KERNEL__ */ - -#ifdef __MIPSEB__ +#define fls(x) generic_fls(x) /* * find_next_zero_bit - find the first zero bit in a memory region @@ -453,32 +371,32 @@ * @offset: The bitnumber to start searching at * @size: The maximum size to search */ -extern __inline__ unsigned long -find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +static inline unsigned long find_next_zero_bit(unsigned long *addr, + unsigned long size, unsigned long offset) { - unsigned long *p = ((unsigned long *) addr) + (offset >> 6); - unsigned long result = offset & ~63UL; + unsigned long *p = ((unsigned long *) addr) + (offset >> SZLONG_LOG); + unsigned long result = offset & ~SZLONG_MASK; unsigned long tmp; if (offset >= size) return size; size -= result; - offset &= 63UL; + offset &= SZLONG_MASK; if (offset) { tmp = *(p++); - tmp |= ~0UL >> (64-offset); - if (size < 64) + tmp |= ~0UL >> (_MIPS_SZLONG-offset); + if (size < _MIPS_SZLONG) goto found_first; if (~tmp) goto found_middle; - size -= 64; - result += 64; + size -= _MIPS_SZLONG; + result += _MIPS_SZLONG; } - while (size & ~63UL) { + while (size & ~SZLONG_MASK) { if (~(tmp = *(p++))) goto found_middle; - result += 64; - size -= 64; + result += _MIPS_SZLONG; + size -= _MIPS_SZLONG; } if (!size) return result; @@ -486,149 +404,235 @@ found_first: tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ found_middle: return result + ffz(tmp); } #define find_first_zero_bit(addr, size) \ - find_next_zero_bit((addr), (size), 0) + find_next_zero_bit((addr), (size), 0) + +/* + * find_next_bit - find the next set bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static inline unsigned long find_next_bit(unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned long *p = addr + (offset >> SZLONG_LOG); + unsigned long result = offset & ~SZLONG_MASK; + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; + offset &= SZLONG_MASK; + if (offset) { + tmp = *(p++); + tmp &= ~0UL << offset; + if (size < _MIPS_SZLONG) + goto found_first; + if (tmp) + goto found_middle; + size -= _MIPS_SZLONG; + result += _MIPS_SZLONG; + } + while (size & ~SZLONG_MASK) { + if ((tmp = *(p++))) + goto found_middle; + result += _MIPS_SZLONG; + size -= _MIPS_SZLONG; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= ~0UL >> (_MIPS_SZLONG - size); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + __ffs(tmp); +} -#endif /* (__MIPSEB__) */ +/* + * find_first_bit - find the first set bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first set bit, not the number of the byte + * containing a bit. + */ +#define find_first_bit(addr, size) \ + find_next_bit((addr), (size), 0) #ifdef __KERNEL__ -/* Now for the ext2 filesystem bit operations and helper routines. */ +/* + * Every architecture must define this function. It's the fastest + * way of searching a 168-bit bitmap where the first 128 bits are + * unlikely to be set. It's guaranteed that at least one of the 168 + * bits is cleared. + */ +static inline int sched_find_first_bit(unsigned long *b) +{ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 64; + return __ffs(b[2]) + 128; +} -#ifdef __MIPSEB__ +/* + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ + +#define ffs(x) generic_ffs(x) + +/* + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ -extern inline int -ext2_set_bit(int nr,void * addr) +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +static inline int __test_and_set_le_bit(unsigned long nr, unsigned long *addr) { - int mask, retval, flags; unsigned char *ADDR = (unsigned char *) addr; + int mask, retval; ADDR += nr >> 3; mask = 1 << (nr & 0x07); - save_and_cli(flags); retval = (mask & *ADDR) != 0; *ADDR |= mask; - restore_flags(flags); + return retval; } -extern inline int -ext2_clear_bit(int nr, void * addr) +static inline int __test_and_clear_le_bit(unsigned long nr, unsigned long *addr) { - int mask, retval, flags; unsigned char *ADDR = (unsigned char *) addr; + int mask, retval; ADDR += nr >> 3; mask = 1 << (nr & 0x07); - save_and_cli(flags); retval = (mask & *ADDR) != 0; *ADDR &= ~mask; - restore_flags(flags); + return retval; } -#define ext2_set_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_set_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -#define ext2_clear_bit_atomic(lock, nr, addr) \ - ({ \ - int ret; \ - spin_lock(lock); \ - ret = ext2_clear_bit((nr), (addr)); \ - spin_unlock(lock); \ - ret; \ - }) - -extern inline int -ext2_test_bit(int nr, const void * addr) +static inline int test_le_bit(unsigned long nr, const unsigned long * addr) { - int mask; const unsigned char *ADDR = (const unsigned char *) addr; + int mask; ADDR += nr >> 3; mask = 1 << (nr & 0x07); + return ((mask & *ADDR) != 0); } -#define ext2_find_first_zero_bit(addr, size) \ - ext2_find_next_zero_bit((addr), (size), 0) +static inline unsigned long ext2_ffz(unsigned int word) +{ + int b = 0, s; + + word = ~word; + s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; + s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; + s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; + s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; + s = 1; if (word << 31 != 0) s = 0; b += s; + + return b; +} -extern inline unsigned int -ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +static inline unsigned long find_next_zero_le_bit(unsigned long *addr, + unsigned long size, unsigned long offset) { unsigned int *p = ((unsigned int *) addr) + (offset >> 5); - unsigned int result = offset & ~31UL; + unsigned int result = offset & ~31; unsigned int tmp; if (offset >= size) return size; + size -= result; - offset &= 31UL; - if(offset) { - /* We hold the little endian value in tmp, but then the - * shift is illegal. So we could keep a big endian value - * in tmp, like this: - * - * tmp = __swab32(*(p++)); - * tmp |= ~0UL >> (32-offset); - * - * but this would decrease preformance, so we change the - * shift: - */ - tmp = *(p++); - tmp |= __swab32(~0UL >> (32-offset)); - if(size < 32) + offset &= 31; + if (offset) { + tmp = cpu_to_le32p(p++); + tmp |= ~0U >> (32-offset); /* bug or feature ? */ + if (size < 32) goto found_first; - if(~tmp) + if (tmp != ~0U) goto found_middle; size -= 32; result += 32; } - while(size & ~31UL) { - if(~(tmp = *(p++))) + while (size >= 32) { + if ((tmp = cpu_to_le32p(p++)) != ~0U) goto found_middle; result += 32; size -= 32; } - if(!size) + if (!size) return result; - tmp = *p; + tmp = cpu_to_le32p(p); found_first: - /* tmp is little endian, so we would have to swab the shift, - * see above. But then we have to swab tmp below for ffz, so - * we might as well do this here. - */ - return result + ffz(__swab32(tmp) | (~0UL << size)); + tmp |= ~0 << size; + if (tmp == ~0U) /* Are any bits zero? */ + return result + size; /* Nope. */ + found_middle: - return result + ffz(__swab32(tmp)); + return result + ext2_ffz(tmp); } -#else /* !(__MIPSEB__) */ -/* Native ext2 byte ordering, just collapse using defines. */ -#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr)) -#define ext2_set_bit_atomic(lock, nr, addr) test_and_set_bit((nr), (addr)) -#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr)) -#define ext2_clear_bit_atomic(lock, nr, addr) test_and_clear_bit((nr), (addr)) -#define ext2_test_bit(nr, addr) test_bit((nr), (addr)) -#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size)) -#define ext2_find_next_zero_bit(addr, size, offset) \ - find_next_zero_bit((addr), (size), (offset)) - -#endif /* !(__MIPSEB__) */ +#define find_first_zero_le_bit(addr, size) \ + find_next_zero_le_bit((addr), (size), 0) + +#define ext2_set_bit(nr,addr) \ + __test_and_set_le_bit((nr),(unsigned long*)addr) +#define ext2_clear_bit(nr, addr) \ + __test_and_clear_le_bit((nr),(unsigned long*)addr) + #define ext2_set_bit_atomic(lock, nr, addr) \ +({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_set_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ +}) + +#define ext2_clear_bit_atomic(lock, nr, addr) \ +({ \ + int ret; \ + spin_lock(lock); \ + ret = ext2_clear_bit((nr), (addr)); \ + spin_unlock(lock); \ + ret; \ +}) +#define ext2_test_bit(nr, addr) test_le_bit((nr),(unsigned long*)addr) +#define ext2_find_first_zero_bit(addr, size) \ + find_first_zero_le_bit((unsigned long*)addr, size) +#define ext2_find_next_zero_bit(addr, size, off) \ + find_next_zero_le_bit((unsigned long*)addr, size, off) /* * Bitmap functions for the minix filesystem. + * * FIXME: These assume that Minix uses the native byte/bitorder. * This limits the Minix filesystem's value for data exchange very much. */ diff -Nru a/include/asm-mips64/bootinfo.h b/include/asm-mips64/bootinfo.h --- a/include/asm-mips64/bootinfo.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/bootinfo.h Fri Jun 27 14:19:53 2003 @@ -1,39 +1,47 @@ /* - * bootinfo.h -- Definition of the Linux/MIPS boot information structure - * - * Copyright (C) 1995 - 1999 by Ralf Baechle - * Copyright (C) 1995, 1996 by Stoned Elipot and Paul M. Antoine. - * Copyright (C) 1999 Ralf Baechle - * * 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) 1995, 1996 by Ralf Baechle, Andreas Busse, + * Stoned Elipot and Paul M. Antoine. */ #ifndef _ASM_BOOTINFO_H #define _ASM_BOOTINFO_H +#include <linux/types.h> + /* * Values for machgroup */ -#define MACH_GROUP_UNKNOWN 0 /* whatever... */ -#define MACH_GROUP_JAZZ 1 /* Jazz */ -#define MACH_GROUP_DEC 2 /* Digital Equipment */ +#define MACH_GROUP_UNKNOWN 0 /* whatever... */ +#define MACH_GROUP_JAZZ 1 /* Jazz */ +#define MACH_GROUP_DEC 2 /* Digital Equipment */ #define MACH_GROUP_ARC 3 /* Wreckstation Tyne, rPC44, possibly other */ -#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ +#define MACH_GROUP_SNI_RM 4 /* Siemens Nixdorf RM series */ #define MACH_GROUP_ACN 5 -#define MACH_GROUP_SGI 6 /* Silicon Graphics workstations and servers */ -#define MACH_GROUP_COBALT 7 /* Cobalt servers */ - -#define GROUP_NAMES { "unknown", "Jazz", "Digital", "ARC", \ - "SNI", "ACN", "SGI", "Cobalt" } +#define MACH_GROUP_SGI 6 /* Silicon Graphics */ +#define MACH_GROUP_COBALT 7 /* Cobalt servers */ +#define MACH_GROUP_NEC_DDB 8 /* NEC DDB */ +#define MACH_GROUP_BAGET 9 /* Baget */ +#define MACH_GROUP_COSINE 10 /* CoSine Orion */ +#define MACH_GROUP_GALILEO 11 /* Galileo Eval Boards */ +#define MACH_GROUP_MOMENCO 12 /* Momentum Boards */ +#define MACH_GROUP_ITE 13 /* ITE Semi Eval Boards */ +#define MACH_GROUP_PHILIPS 14 +#define MACH_GROUP_GLOBESPAN 15 /* Globespan PVR Referrence Board */ +#define MACH_GROUP_SIBYTE 16 /* Sibyte Eval Boards */ +#define MACH_GROUP_TOSHIBA 17 /* Toshiba Reference Systems TSBREF */ +#define MACH_GROUP_ALCHEMY 18 /* Alchemy Semi Eval Boards */ +#define MACH_GROUP_NEC_VR41XX 19 /* NEC Vr41xx based boards/gadgets */ +#define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ +#define MACH_GROUP_LASAT 21 /* * Valid machtype values for group unknown (low order halfword of mips_machtype) */ #define MACH_UNKNOWN 0 /* whatever... */ -#define GROUP_UNKNOWN_NAMES { "unknown" } - /* * Valid machtype values for group JAZZ */ @@ -41,26 +49,20 @@ #define MACH_MIPS_MAGNUM_4000 1 /* Mips Magnum 4000 "RC4030" */ #define MACH_OLIVETTI_M700 2 /* Olivetti M700-10 (-15 ??) */ -#define GROUP_JAZZ_NAMES { "Acer PICA 61", "Mips Magnum 4000", "Olivetti M700" } - /* - * Valid machtype for group DEC + * Valid machtype for group DEC */ #define MACH_DSUNKNOWN 0 #define MACH_DS23100 1 /* DECstation 2100 or 3100 */ -#define MACH_DS5100 2 /* DECstation 5100 */ +#define MACH_DS5100 2 /* DECsystem 5100 */ #define MACH_DS5000_200 3 /* DECstation 5000/200 */ #define MACH_DS5000_1XX 4 /* DECstation 5000/120, 125, 133, 150 */ #define MACH_DS5000_XX 5 /* DECstation 5000/20, 25, 33, 50 */ #define MACH_DS5000_2X0 6 /* DECstation 5000/240, 260 */ -#define MACH_DS5400 7 /* DECstation 5400 */ -#define MACH_DS5500 8 /* DECstation 5500 */ -#define MACH_DS5800 9 /* DECstation 5800 */ - -#define GROUP_DEC_NAMES { "unknown", "DECstation 2100/3100", "DECstation 5100", \ - "DECstation 5000/200", "DECstation 5000/1xx", "Personal DECstation 5000/xx", \ - "DECstation 5000/2x0", "DECstation 5400", "DECstation 5500", \ - "DECstation 5800" } +#define MACH_DS5400 7 /* DECsystem 5400 */ +#define MACH_DS5500 8 /* DECsystem 5500 */ +#define MACH_DS5800 9 /* DECsystem 5800 */ +#define MACH_DS5900 10 /* DECsystem 5900 */ /* * Valid machtype for group ARC @@ -68,120 +70,150 @@ #define MACH_DESKSTATION_RPC44 0 /* Deskstation rPC44 */ #define MACH_DESKSTATION_TYNE 1 /* Deskstation Tyne */ -#define GROUP_ARC_NAMES { "Deskstation rPC44", "Deskstation Tyne" } - /* * Valid machtype for group SNI_RM */ #define MACH_SNI_RM200_PCI 0 /* RM200/RM300/RM400 PCI series */ -#define GROUP_SNI_RM_NAMES { "RM200 PCI" } - /* * Valid machtype for group ACN */ #define MACH_ACN_MIPS_BOARD 0 /* ACN MIPS single board */ -#define GROUP_ACN_NAMES { "ACN" } - /* * Valid machtype for group SGI */ -#define MACH_SGI_INDY 0 /* R4?K and R5K Indy workstations */ -#define MACH_SGI_CHALLENGE_S 1 /* The Challenge S server */ -#define MACH_SGI_INDIGO2 2 /* The Indigo2 system */ -#define MACH_SGI_IP27 3 /* Origin 200, Origin 2000, Onyx 2 */ +#define MACH_SGI_IP22 0 /* Indy, Indigo2, Challenge S */ +#define MACH_SGI_IP27 1 /* Origin 200, Origin 2000, Onyx 2 */ +#define MACH_SGI_IP28 2 /* Indigo2 Impact */ +#define MACH_SGI_IP32 3 /* O2 */ -#define GROUP_SGI_NAMES { "Indy", "Challenge S", "Indigo2", "IP27" } +/* + * Valid machtype for group COBALT + */ +#define MACH_COBALT_27 0 /* Proto "27" hardware */ +/* + * Valid machtype for group NEC DDB + */ +#define MACH_NEC_DDB5074 0 /* NEC DDB Vrc-5074 */ +#define MACH_NEC_DDB5476 1 /* NEC DDB Vrc-5476 */ +#define MACH_NEC_DDB5477 2 /* NEC DDB Vrc-5477 */ +#define MACH_NEC_ROCKHOPPER 3 /* Rockhopper base board */ +#define MACH_NEC_ROCKHOPPERII 4 /* Rockhopper II base board */ /* - * Valid machtype for group COBALT + * Valid machtype for group BAGET */ -#define MACH_COBALT_27 0 /* Proto "27" hardware */ +#define MACH_BAGET201 0 /* BT23-201 */ +#define MACH_BAGET202 1 /* BT23-202 */ -#define GROUP_COBALT_NAMES { "Microserver 27" } +/* + * Cosine boards. + */ +#define MACH_COSINE_ORION 0 /* - * Valid cputype values + * Valid machtype for group GALILEO */ -#define CPU_UNKNOWN 0 -#define CPU_R2000 1 -#define CPU_R3000 2 -#define CPU_R3000A 3 -#define CPU_R3041 4 -#define CPU_R3051 5 -#define CPU_R3052 6 -#define CPU_R3081 7 -#define CPU_R3081E 8 -#define CPU_R4000PC 9 -#define CPU_R4000SC 10 -#define CPU_R4000MC 11 -#define CPU_R4200 12 -#define CPU_R4400PC 13 -#define CPU_R4400SC 14 -#define CPU_R4400MC 15 -#define CPU_R4600 16 -#define CPU_R6000 17 -#define CPU_R6000A 18 -#define CPU_R8000 19 -#define CPU_R10000 20 -#define CPU_R4300 21 -#define CPU_R4650 22 -#define CPU_R4700 23 -#define CPU_R5000 24 -#define CPU_R5000A 25 -#define CPU_R4640 26 -#define CPU_NEVADA 27 /* RM5230, RM5260 */ -#define CPU_LAST 27 - -#define CPU_NAMES { "unknown", "R2000", "R3000", "R3000A", "R3041", "R3051", \ - "R3052", "R3081", "R3081E", "R4000PC", "R4000SC", "R4000MC", \ - "R4200", "R4400PC", "R4400SC", "R4400MC", "R4600", "R6000", \ - "R6000A", "R8000", "R10000", "R4300", "R4650", "R4700", "R5000", \ - "R5000A", "R4640", "Nevada" } - -#define CL_SIZE (80) - -#define BOOT_MEM_MAP_MAX 32 -#define BOOT_MEM_RAM 1 -#define BOOT_MEM_ROM_DATA 2 -#define BOOT_MEM_RESERVED 3 +#define MACH_EV96100 0 /* EV96100 */ +#define MACH_EV64120A 1 /* EV64120A */ -#ifndef _LANGUAGE_ASSEMBLY +/* + * Valid machtype for group MOMENCO + */ +#define MACH_MOMENCO_OCELOT 0 +#define MACH_MOMENCO_OCELOT_G 1 +#define MACH_MOMENCO_OCELOT_C 2 /* - * Some machine parameters passed by the bootloaders. + * Valid machtype for group ITE */ +#define MACH_QED_4N_S01B 0 /* ITE8172 based eval board */ -struct drive_info_struct { - char dummy[32]; -}; +/* + * Valid machtype for group Globespan + */ +#define MACH_IVR 0 /* IVR eval board */ + +/* + * Valid machtype for group PHILIPS + */ +#define MACH_PHILIPS_NINO 0 /* Nino */ +#define MACH_PHILIPS_VELO 1 /* Velo */ + +/* + * Valid machtype for group SIBYTE + */ +#define MACH_SWARM 0 + +/* + * Valid machtypes for group Toshiba + */ +#define MACH_PALLAS 0 +#define MACH_TOPAS 1 +#define MACH_JMR 2 +#define MACH_TOSHIBA_JMR3927 3 /* JMR-TX3927 CPU/IO board */ +#define MACH_TOSHIBA_RBTX4927 4 +#define MACH_TOSHIBA_RBTX4937 5 +#define GROUP_TOSHIBA_NAMES { "Pallas", "TopasCE", "JMR", "JMR TX3927", \ + "RBTX4927", "RBTX4937" } + +/* + * Valid machtype for group LASAT + */ +#define MACH_LASAT_100 0 /* Masquerade II/SP100/SP50/SP25 */ +#define MACH_LASAT_200 1 /* Masquerade PRO/SP200 */ + +/* + * Valid machtype for group Alchemy + */ +#define MACH_PB1000 0 /* Au1000-based eval board */ +#define MACH_PB1100 1 /* Au1100-based eval board */ +#define MACH_PB1500 2 /* Au1500-based eval board */ +#define MACH_DB1000 3 /* Au1000-based eval board */ +#define MACH_DB1100 4 /* Au1100-based eval board */ +#define MACH_DB1500 5 /* Au1500-based eval board */ + +/* + * Valid machtype for group NEC_VR41XX + */ +#define MACH_NEC_OSPREY 0 /* Osprey eval board */ +#define MACH_NEC_EAGLE 1 /* NEC Eagle/Hawk board */ +#define MACH_ZAO_CAPCELLA 2 /* ZAO Networks Capcella */ +#define MACH_VICTOR_MPC30X 3 /* Victor MP-C303/304 */ +#define MACH_IBM_WORKPAD 4 /* IBM WorkPad z50 */ +#define MACH_CASIO_E55 5 /* CASIO CASSIOPEIA E-10/15/55/65 */ +#define MACH_TANBAC_TB0226 6 /* TANBAC TB0226 (Mbase) */ +#define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ + +#define CL_SIZE (256) + +const char *get_system_type(void); -extern unsigned long mips_memory_upper; -extern unsigned long mips_cputype; extern unsigned long mips_machtype; extern unsigned long mips_machgroup; -extern unsigned long mips_tlb_entries; + +#define BOOT_MEM_MAP_MAX 32 +#define BOOT_MEM_RAM 1 +#define BOOT_MEM_ROM_DATA 2 +#define BOOT_MEM_RESERVED 3 /* * A memory map that's built upon what was determined * or specified on the command line. */ struct boot_mem_map { - int nr_map; - struct { - unsigned long addr; /* start of memory segment */ - unsigned long size; /* size of memory segment */ - long type; /* type of memory segment */ - } map[BOOT_MEM_MAP_MAX]; + int nr_map; + struct { + phys_t addr; /* start of memory segment */ + phys_t size; /* size of memory segment */ + long type; /* type of memory segment */ + } map[BOOT_MEM_MAP_MAX]; }; extern struct boot_mem_map boot_mem_map; -extern void add_memory_region(unsigned long start, unsigned long size, - long type); - -#endif /* _LANGUAGE_ASSEMBLY */ +extern void add_memory_region(phys_t start, phys_t size, long type); #endif /* _ASM_BOOTINFO_H */ diff -Nru a/include/asm-mips64/branch.h b/include/asm-mips64/branch.h --- a/include/asm-mips64/branch.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/branch.h Fri Jun 27 14:19:59 2003 @@ -3,20 +3,29 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Branch and jump emulation. - * - * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle + * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle */ +#ifndef _ASM_BRANCH_H +#define _ASM_BRANCH_H + #include <asm/ptrace.h> -extern inline int delay_slot(struct pt_regs *regs) +static inline int delay_slot(struct pt_regs *regs) { return regs->cp0_cause & CAUSEF_BD; } +static inline unsigned long exception_epc(struct pt_regs *regs) +{ + if (!delay_slot(regs)) + return regs->cp0_epc; + + return regs->cp0_epc + 4; +} + extern int __compute_return_epc(struct pt_regs *regs); -extern inline int compute_return_epc(struct pt_regs *regs) +static inline int compute_return_epc(struct pt_regs *regs) { if (!delay_slot(regs)) { regs->cp0_epc += 4; @@ -25,3 +34,5 @@ return __compute_return_epc(regs); } + +#endif /* _ASM_BRANCH_H */ diff -Nru a/include/asm-mips64/break.h b/include/asm-mips64/break.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/break.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,33 @@ +/* + * 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) 1995, 2003 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_BREAK_H +#define __ASM_BREAK_H + +/* + * The following break codes are or were in use for specific purposes in + * other MIPS operating systems. Linux/MIPS doesn't use all of them. The + * unused ones are here as placeholders; we might encounter them in + * non-Linux/MIPS object files or make use of them in the future. + */ +#define BRK_USERBP 0 /* User bp (used by debuggers) */ +#define BRK_KERNELBP 1 /* Break in the kernel */ +#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */ +#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */ +#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */ +#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */ +#define BRK_OVERFLOW 6 /* Overflow check */ +#define BRK_DIVZERO 7 /* Divide by zero check */ +#define BRK_RANGE 8 /* Range error check */ +#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */ +#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ +#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ +#define BRK_MULOVF 1023 /* Multiply overflow */ +#define BRK_BUG 512 /* Used by BUG() */ + +#endif /* __ASM_BREAK_H */ diff -Nru a/include/asm-mips64/bug.h b/include/asm-mips64/bug.h --- a/include/asm-mips64/bug.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/bug.h Fri Jun 27 14:20:05 2003 @@ -1,14 +1,20 @@ -#ifndef _ASM_BUG_H -#define _ASM_BUG_H +#ifndef __ASM_BUG_H +#define __ASM_BUG_H -#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) +#include <asm/break.h> + +#define BUG() \ +do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ + __asm__ __volatile__("break %0" : : "i" (BRK_BUG)); \ +} while (0) #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) #define PAGE_BUG(page) do { BUG(); } while (0) #define WARN_ON(condition) do { \ if (unlikely((condition)!=0)) { \ printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \ - dump_stack(); \ + dump_stack(); \ } \ } while (0) diff -Nru a/include/asm-mips64/bugs.h b/include/asm-mips64/bugs.h --- a/include/asm-mips64/bugs.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/bugs.h Fri Jun 27 14:19:54 2003 @@ -1,38 +1,12 @@ /* - * Copyright (C) 1995 Waldorf Electronics - * Copyright (C) 1997, 1999 Ralf Baechle - */ -#include <asm/bootinfo.h> - -/* * This is included by init/main.c to check for architecture-dependent bugs. * * Needs: * void check_bugs(void); */ +#ifndef __ASM_BUGS_H +#define __ASM_BUGS_H +extern void check_bugs(void); -static inline void check_wait(void) -{ - printk("Checking for 'wait' instruction... "); - switch(mips_cputype) { - case CPU_R4200: - case CPU_R4300: - case CPU_R4600: - case CPU_R4700: - case CPU_R5000: - case CPU_NEVADA: - wait_available = 1; - printk(" available.\n"); - break; - default: - printk(" unavailable.\n"); - break; - } -} - -static void __init -check_bugs(void) -{ - check_wait(); -} +#endif /* __ASM_BUGS_H */ diff -Nru a/include/asm-mips64/cache.h b/include/asm-mips64/cache.h --- a/include/asm-mips64/cache.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/cache.h Fri Jun 27 14:20:05 2003 @@ -3,14 +3,23 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997, 1998, 1999 Ralf Baechle + * Copyright (C) 1997, 98, 99, 2000, 2003 Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CACHE_H #define _ASM_CACHE_H -/* bytes per L1 cache line */ -#define L1_CACHE_BYTES (1 << CONFIG_L1_CACHE_SHIFT) -#define L1_CACHE_SHIFT_MAX 7 /* largest L1 which this arch supports */ +#include <linux/config.h> + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_R6000) || \ + defined(CONFIG_CPU_TX39XX) +#define L1_CACHE_BYTES 16 +#define L1_CACHE_SHIFT_MAX 4 /* largest L1 which this arch supports */ +#else +#define L1_CACHE_BYTES 32 /* A guess */ +#define L1_CACHE_SHIFT_MAX 6 /* largest L1 which this arch supports */ +#endif + +#define SMP_CACHE_BYTES L1_CACHE_BYTES #endif /* _ASM_CACHE_H */ diff -Nru a/include/asm-mips64/cacheflush.h b/include/asm-mips64/cacheflush.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/cacheflush.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,65 @@ +/* + * 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, 95, 96, 97, 98, 99, 2000, 01, 02, 03 by Ralf Baechle + * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEFLUSH_H +#define __ASM_CACHEFLUSH_H + +#include <linux/config.h> + +/* Keep includes the same across arches. */ +#include <linux/mm.h> + +/* Cache flushing: + * + * - flush_cache_all() flushes entire cache + * - flush_cache_mm(mm) flushes the specified mm context's cache lines + * - flush_cache_page(mm, vmaddr) flushes a single page + * - flush_cache_range(vma, start, end) flushes a range of pages + * - flush_icache_range(start, end) flush a range of instructions + * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache + * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache + * + * MIPS specific flush operations: + * + * - flush_cache_sigtramp() flush signal trampoline + * - flush_icache_all() flush the entire instruction cache + * - flush_data_cache_page() flushes a page from the data cache + */ +extern void (*flush_cache_all)(void); +extern void (*__flush_cache_all)(void); +extern void (*flush_cache_mm)(struct mm_struct *mm); +extern void (*flush_cache_range)(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void (*flush_cache_page)(struct vm_area_struct *vma, + unsigned long page); +extern void flush_dcache_page(struct page *page); +extern void (*flush_icache_page)(struct vm_area_struct *vma, + struct page *page); +extern void (*flush_icache_range)(unsigned long start, unsigned long end); +#define flush_icache_user_range(vma, page, addr, len) \ + flush_icache_page(vma, page) + + +extern void (*flush_cache_sigtramp)(unsigned long addr); +extern void (*flush_icache_all)(void); +extern void (*flush_data_cache_page)(unsigned long addr); + +/* + * This flag is used to indicate that the page pointed to by a pte + * is dirty and requires cleaning before returning it to the user. + */ +#define PG_dcache_dirty PG_arch_1 + +#define Page_dcache_dirty(page) \ + test_bit(PG_dcache_dirty, &(page)->flags) +#define SetPageDcacheDirty(page) \ + set_bit(PG_dcache_dirty, &(page)->flags) +#define ClearPageDcacheDirty(page) \ + clear_bit(PG_dcache_dirty, &(page)->flags) + +#endif /* __ASM_CACHEFLUSH_H */ diff -Nru a/include/asm-mips64/cacheops.h b/include/asm-mips64/cacheops.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/cacheops.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,81 @@ +/* + * Cache operations for the cache instruction. + * + * 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. + * + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H + +/* + * Cache Operations available on all MIPS processors with R4000-style caches + */ +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 +#define Index_Load_Tag_I 0x04 +#define Index_Load_Tag_D 0x05 +#define Index_Store_Tag_I 0x08 +#define Index_Store_Tag_D 0x09 +#define Hit_Invalidate_I 0x10 +#define Hit_Invalidate_D 0x11 +#define Hit_Writeback_Inv_D 0x15 + +/* + * R4000-specific cacheops + */ +#define Create_Dirty_Excl_D 0x0d +#define Fill 0x14 +#define Hit_Writeback_I 0x18 +#define Hit_Writeback_D 0x19 + +/* + * R4000SC and R4400SC-specific cacheops + */ +#define Index_Invalidate_SI 0x02 +#define Index_Writeback_Inv_SD 0x03 +#define Index_Load_Tag_SI 0x06 +#define Index_Load_Tag_SD 0x07 +#define Index_Store_Tag_SI 0x0A +#define Index_Store_Tag_SD 0x0B +#define Create_Dirty_Excl_SD 0x0f +#define Hit_Invalidate_SI 0x12 +#define Hit_Invalidate_SD 0x13 +#define Hit_Writeback_Inv_SD 0x17 +#define Hit_Writeback_SD 0x1b +#define Hit_Set_Virtual_SI 0x1e +#define Hit_Set_Virtual_SD 0x1f + +/* + * R5000-specific cacheops + */ +#define R5K_Page_Invalidate_S 0x17 + +/* + * RM7000-specific cacheops + */ +#define Page_Invalidate_T 0x16 + +/* + * R1000-specific cacheops + * + * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused. + * Most of the _S cacheops are identical to the R4000SC _SD cacheops. + */ +#define Index_Writeback_Inv_S 0x03 +#define Index_Load_Tag_S 0x07 +#define Index_Store_Tag_S 0x0B +#define Hit_Invalidate_S 0x13 +#define Cache_Barrier 0x14 +#define Hit_Writeback_Inv_S 0x17 +#define Index_Load_Data_I 0x18 +#define Index_Load_Data_D 0x19 +#define Index_Load_Data_S 0x1b +#define Index_Store_Data_I 0x1c +#define Index_Store_Data_D 0x1d +#define Index_Store_Data_S 0x1f + +#endif /* __ASM_CACHEOPS_H */ diff -Nru a/include/asm-mips64/checksum.h b/include/asm-mips64/checksum.h --- a/include/asm-mips64/checksum.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/checksum.h Fri Jun 27 14:19:54 2003 @@ -6,11 +6,13 @@ * Copyright (C) 1995, 1996, 1997, 1998, 1999 by Ralf Baechle * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2001 Thiemo Seufer. + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef _ASM_CHECKSUM_H #define _ASM_CHECKSUM_H #include <asm/uaccess.h> +#include <linux/in6.h> /* * computes the checksum of a memory block at buff, length len, @@ -37,7 +39,7 @@ * Copy and checksum to user */ #define HAVE_CSUM_COPY_USER -extern inline unsigned int csum_and_copy_to_user (const char *src, char *dst, +static inline unsigned int csum_and_copy_to_user (const char *src, char *dst, int len, int sum, int *err_ptr) { @@ -73,12 +75,11 @@ "xori\t%0,0xffff\n\t" ".set\tat" : "=r" (sum) - : "0" (sum) - : "$1"); + : "0" (sum)); return sum; } - + /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -126,8 +127,7 @@ "2:\t.set\tat\n\t" ".set\treorder" : "=&r" (sum), "=&r" (iph), "=&r" (ihl), "=&r" (dummy) - : "1" (iph), "2" (ihl) - : "$1"); + : "1" (iph), "2" (ihl)); return csum_fold(sum); } @@ -135,6 +135,10 @@ /* * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented + * + * Cast unsigned short expressions to unsigned long explicitly + * to avoid surprises resulting from implicit promotions to + * signed int. --macro */ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, @@ -151,15 +155,14 @@ "daddu\t%0, $1\n\t" "dsrl32\t%0, %0, 0\n\t" ".set\tat" - : "=r" (sum) + : "=&r" (sum) : "0" (daddr), "r"(saddr), #ifdef __MIPSEL__ - "r" ((ntohs(len)<<16)+proto*256), + "r" (((unsigned long)ntohs(len)<<16)+proto*256), #else - "r" (((proto)<<16)+len), + "r" (((unsigned long)(proto)<<16)+len), #endif - "r" (sum) - : "$1"); + "r" (sum)); return sum; } @@ -187,14 +190,15 @@ } #define _HAVE_ARCH_IPV6_CSUM -static inline unsigned short int csum_ipv6_magic(struct in6_addr *saddr, - struct in6_addr *daddr, - __u32 len, - unsigned short proto, - unsigned int sum) +static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, + struct in6_addr *daddr, + __u32 len, + unsigned short proto, + unsigned int sum) { __asm__( - ".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t" + ".set\tpush\t\t\t# csum_ipv6_magic\n\t" + ".set\tnoreorder\n\t" ".set\tnoat\n\t" "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t" "sltu\t$1, %0, %5\n\t" @@ -205,48 +209,48 @@ "lw\t%1, 0(%2)\t\t\t# four words source address\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 4(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 8(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 12(%2)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 0(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 4(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 8(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" + "sltu\t$1, %0, %1\n\t" "lw\t%1, 12(%3)\n\t" "addu\t%0, $1\n\t" "addu\t%0, %1\n\t" - "sltu\t$1, %0, $1\n\t" - ".set\tnoat\n\t" - ".set\tnoreorder" - : "=r" (sum), "=r" (proto) + "sltu\t$1, %0, %1\n\t" + + "addu\t%0, $1\t\t\t# Add final carry\n\t" + ".set\tpop" + : "=&r" (sum), "=&r" (proto) : "r" (saddr), "r" (daddr), - "0" (htonl(len)), "1" (htonl(proto)), "r" (sum) - : "$1"); + "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); return csum_fold(sum); } diff -Nru a/include/asm-mips64/compat.h b/include/asm-mips64/compat.h --- a/include/asm-mips64/compat.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/compat.h Fri Jun 27 14:19:59 2003 @@ -1,18 +1,140 @@ -#ifndef _ASM_MIPS64_COMPAT_H -#define _ASM_MIPS64_COMPAT_H +#ifndef _ASM_COMPAT_H +#define _ASM_COMPAT_H /* * Architecture specific compatibility types */ #include <linux/types.h> +#define COMPAT_USER_HZ 100 + typedef u32 compat_size_t; typedef s32 compat_ssize_t; typedef s32 compat_time_t; +typedef s32 compat_clock_t; typedef s32 compat_suseconds_t; +typedef s32 compat_pid_t; +typedef s32 compat_uid_t; +typedef s32 compat_gid_t; +typedef u32 compat_mode_t; +typedef u32 compat_ino_t; +typedef u32 compat_dev_t; +typedef s32 compat_off_t; +typedef s64 compat_loff_t; +typedef u32 compat_nlink_t; +typedef s32 compat_ipc_pid_t; +typedef s32 compat_daddr_t; +typedef s32 compat_caddr_t; +typedef struct { + s32 val[2]; +} compat_fsid_t; + +typedef s32 compat_int_t; +typedef s32 compat_long_t; +typedef u32 compat_uint_t; +typedef u32 compat_ulong_t; + struct compat_timespec { compat_time_t tv_sec; s32 tv_nsec; }; -#endif /* _ASM_MIPS64_COMPAT_H */ +struct compat_timeval { + compat_time_t tv_sec; + s32 tv_usec; +}; + +struct compat_stat { + compat_dev_t st_dev; + s32 st_pad1[3]; + compat_ino_t st_ino; + compat_mode_t st_mode; + compat_nlink_t st_nlink; + compat_uid_t st_uid; + compat_gid_t st_gid; + compat_dev_t st_rdev; + s32 st_pad2[2]; + compat_off_t st_size; + s32 st_pad3; + compat_time_t st_atime; + s32 st_atime_nsec; + compat_time_t st_mtime; + s32 st_mtime_nsec; + compat_time_t st_ctime; + s32 st_ctime_nsec; + s32 st_blksize; + s32 st_blocks; + s32 st_pad4[14]; +}; + +struct compat_flock { + short l_type; + short l_whence; + compat_off_t l_start; + compat_off_t l_len; + s32 l_sysid; + compat_pid_t l_pid; + short __unused; + s32 pad[4]; +}; + +#define F_GETLK64 33 +#define F_SETLK64 34 +#define F_SETLKW64 35 + +struct compat_flock64 { + short l_type; + short l_whence; + compat_loff_t l_start; + compat_loff_t l_len; + compat_pid_t l_pid; +}; + +struct compat_statfs { + int f_type; + int f_bsize; + int f_frsize; + int f_blocks; + int f_bfree; + int f_files; + int f_ffree; + int f_bavail; + compat_fsid_t f_fsid; + int f_namelen; + int f_spare[6]; +}; + +#define COMPAT_RLIM_INFINITY 0x7fffffffUL + +typedef u32 compat_old_sigset_t; /* at least 32 bits */ + +#define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */ +#define _COMPAT_NSIG_BPW 32 + +typedef u32 compat_sigset_word; + +#define COMPAT_OFF_T_MAX 0x7fffffff +#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL + +/* + * A pointer passed in from user mode. This should not + * be used for syscall parameters, just declare them + * as pointers because the syscall entry code will have + * appropriately comverted them already. + */ +typedef u32 compat_uptr_t; + +static inline void *compat_ptr(compat_uptr_t uptr) +{ + return (void *)(long)uptr; +} + +static inline void *compat_alloc_user_space(long len) +{ + unsigned long sp = (unsigned long) current_thread_info() + + KERNEL_STACK_SIZE - 32; + + return (void *) (sp - len); +} + +#endif /* _ASM_COMPAT_H */ diff -Nru a/include/asm-mips64/cpu.h b/include/asm-mips64/cpu.h --- a/include/asm-mips64/cpu.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/cpu.h Fri Jun 27 14:19:53 2003 @@ -1,8 +1,4 @@ /* - * 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. - * * cpu.h: Values of the PRId register used to match up * various MIPS cpu types. * @@ -11,35 +7,205 @@ #ifndef _ASM_CPU_H #define _ASM_CPU_H +#include <linux/cpu.h> + +/* Assigned Company values for bits 23:16 of the PRId Register + (CP0 register 15, select 0). As of the MIPS32 and MIPS64 specs from + MTI, the PRId register is defined in this (backwards compatible) + way: + + +----------------+----------------+----------------+----------------+ + | Company Options| Company ID | Processor ID | Revision | + +----------------+----------------+----------------+----------------+ + 31 24 23 16 15 8 7 + + I don't have docs for all the previous processors, but my impression is + that bits 16-23 have been 0 for all MIPS processors before the MIPS32/64 + spec. +*/ + +#define PRID_COMP_LEGACY 0x000000 +#define PRID_COMP_MIPS 0x010000 +#define PRID_COMP_BROADCOM 0x020000 +#define PRID_COMP_ALCHEMY 0x030000 +#define PRID_COMP_SIBYTE 0x040000 +#define PRID_COMP_SANDCRAFT 0x050000 + /* * Assigned values for the product ID register. In order to detect a * certain CPU type exactly eventually additional registers may need to - * be examined. + * be examined. These are valid when 23:16 == PRID_COMP_LEGACY + */ +#define PRID_IMP_R2000 0x0100 +#define PRID_IMP_AU1_REV1 0x0100 +#define PRID_IMP_AU1_REV2 0x0200 +#define PRID_IMP_R3000 0x0200 /* Same as R2000A */ +#define PRID_IMP_R6000 0x0300 /* Same as R3000A */ +#define PRID_IMP_R4000 0x0400 +#define PRID_IMP_R6000A 0x0600 +#define PRID_IMP_R10000 0x0900 +#define PRID_IMP_R4300 0x0b00 +#define PRID_IMP_VR41XX 0x0c00 +#define PRID_IMP_R12000 0x0e00 +#define PRID_IMP_R8000 0x1000 +#define PRID_IMP_R4600 0x2000 +#define PRID_IMP_R4700 0x2100 +#define PRID_IMP_TX39 0x2200 +#define PRID_IMP_R4640 0x2200 +#define PRID_IMP_R4650 0x2200 /* Same as R4640 */ +#define PRID_IMP_R5000 0x2300 +#define PRID_IMP_TX49 0x2d00 +#define PRID_IMP_SONIC 0x2400 +#define PRID_IMP_MAGIC 0x2500 +#define PRID_IMP_RM7000 0x2700 +#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ +#define PRID_IMP_R5432 0x5400 +#define PRID_IMP_R5500 0x5500 +#define PRID_IMP_4KC 0x8000 +#define PRID_IMP_5KC 0x8100 +#define PRID_IMP_20KC 0x8200 +#define PRID_IMP_4KEC 0x8400 +#define PRID_IMP_4KSC 0x8600 + + +#define PRID_IMP_UNKNOWN 0xff00 + +/* + * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE + */ + +#define PRID_IMP_SB1 0x0100 + +/* + * These are the PRID's for when 23:16 == PRID_COMP_SANDCRAFT + */ + +#define PRID_IMP_SR71000 0x0400 + +/* + * Definitions for 7:0 on legacy processors + */ + + +#define PRID_REV_TX4927 0x0022 +#define PRID_REV_TX4937 0x0030 +#define PRID_REV_R4400 0x0040 +#define PRID_REV_R3000A 0x0030 +#define PRID_REV_R3000 0x0020 +#define PRID_REV_R2000A 0x0010 +#define PRID_REV_TX3912 0x0010 +#define PRID_REV_TX3922 0x0030 +#define PRID_REV_TX3927 0x0040 +#define PRID_REV_VR4111 0x0050 +#define PRID_REV_VR4181 0x0050 /* Same as VR4111 */ +#define PRID_REV_VR4121 0x0060 +#define PRID_REV_VR4122 0x0070 +#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */ +#define PRID_REV_VR4131 0x0080 + +/* + * FPU implementation/revision register (CP1 control register 0). + * + * +---------------------------------+----------------+----------------+ + * | 0 | Implementation | Revision | + * +---------------------------------+----------------+----------------+ + * 31 16 15 8 7 0 + */ + +#define FPIR_IMP_NONE 0x0000 + +#define CPU_UNKNOWN 0 +#define CPU_R2000 1 +#define CPU_R3000 2 +#define CPU_R3000A 3 +#define CPU_R3041 4 +#define CPU_R3051 5 +#define CPU_R3052 6 +#define CPU_R3081 7 +#define CPU_R3081E 8 +#define CPU_R4000PC 9 +#define CPU_R4000SC 10 +#define CPU_R4000MC 11 +#define CPU_R4200 12 +#define CPU_R4400PC 13 +#define CPU_R4400SC 14 +#define CPU_R4400MC 15 +#define CPU_R4600 16 +#define CPU_R6000 17 +#define CPU_R6000A 18 +#define CPU_R8000 19 +#define CPU_R10000 20 +#define CPU_R12000 21 +#define CPU_R4300 22 +#define CPU_R4650 23 +#define CPU_R4700 24 +#define CPU_R5000 25 +#define CPU_R5000A 26 +#define CPU_R4640 27 +#define CPU_NEVADA 28 +#define CPU_RM7000 29 +#define CPU_R5432 30 +#define CPU_4KC 31 +#define CPU_5KC 32 +#define CPU_R4310 33 +#define CPU_SB1 34 +#define CPU_TX3912 35 +#define CPU_TX3922 36 +#define CPU_TX3927 37 +#define CPU_AU1000 38 +#define CPU_4KEC 39 +#define CPU_4KSC 40 +#define CPU_VR41XX 41 +#define CPU_R5500 42 +#define CPU_TX49XX 43 +#define CPU_AU1500 44 +#define CPU_20KC 45 +#define CPU_VR4111 46 +#define CPU_VR4121 47 +#define CPU_VR4122 48 +#define CPU_VR4131 49 +#define CPU_VR4181 50 +#define CPU_VR4181A 51 +#define CPU_AU1100 52 +#define CPU_SR71000 53 +#define CPU_LAST 53 + +/* + * ISA Level encodings + * + */ +#define MIPS_CPU_ISA_I 0x00000001 +#define MIPS_CPU_ISA_II 0x00000002 +#define MIPS_CPU_ISA_III 0x00008003 +#define MIPS_CPU_ISA_IV 0x00008004 +#define MIPS_CPU_ISA_V 0x00008005 +#define MIPS_CPU_ISA_M32 0x00000020 +#define MIPS_CPU_ISA_M64 0x00008040 + +/* + * Bit 15 encodes if an ISA level supports 64-bit operations. + */ +#define MIPS_CPU_ISA_64BIT 0x00008000 + +/* + * CPU Option encodings */ -#define PRID_IMP_R2000 0x0100 -#define PRID_IMP_R3000 0x0200 /* Same as R2000A */ -#define PRID_IMP_R6000 0x0300 /* Same as R3000A */ -#define PRID_IMP_R4000 0x0400 -#define PRID_IMP_R6000A 0x0600 -#define PRID_IMP_R10000 0x0900 -#define PRID_IMP_R4300 0x0b00 -#define PRID_IMP_R12000 0x0e00 -#define PRID_IMP_R8000 0x1000 -#define PRID_IMP_R4600 0x2000 -#define PRID_IMP_R4700 0x2100 -#define PRID_IMP_R4640 0x2200 -#define PRID_IMP_R4650 0x2200 /* Same as R4640 */ -#define PRID_IMP_R5000 0x2300 -#define PRID_IMP_SONIC 0x2400 -#define PRID_IMP_MAGIC 0x2500 -#define PRID_IMP_RM7000 0x2700 -#define PRID_IMP_NEVADA 0x2800 - -#define PRID_IMP_UNKNOWN 0xff00 - -#define PRID_REV_R4400 0x0040 -#define PRID_REV_R3000A 0x0030 -#define PRID_REV_R3000 0x0020 -#define PRID_REV_R2000A 0x0010 +#define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ +/* Leave a spare bit for variant MMU types... */ +#define MIPS_CPU_4KEX 0x00000004 /* "R4K" exception model */ +#define MIPS_CPU_4KTLB 0x00000008 /* "R4K" TLB handler */ +#define MIPS_CPU_FPU 0x00000010 /* CPU has FPU */ +#define MIPS_CPU_32FPR 0x00000020 /* 32 dbl. prec. FP registers */ +#define MIPS_CPU_COUNTER 0x00000040 /* Cycle count/compare */ +#define MIPS_CPU_WATCH 0x00000080 /* watchpoint registers */ +#define MIPS_CPU_MIPS16 0x00000100 /* code compression */ +#define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ +#define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ +#define MIPS_CPU_CACHE_CDEX 0x00000800 /* Create_Dirty_Exclusive CACHE op */ +#define MIPS_CPU_MCHECK 0x00001000 /* Machine check exception */ +#define MIPS_CPU_EJTAG 0x00002000 /* EJTAG exception */ +#define MIPS_CPU_NOFPUEX 0x00000000 /* no FPU exception; never set */ +#define MIPS_CPU_LLSC 0x00008000 /* CPU has ll/sc instructions */ +#define MIPS_CPU_SUBSET_CACHES 0x00010000 /* P-cache subset enforced */ #endif /* _ASM_CPU_H */ diff -Nru a/include/asm-mips64/current.h b/include/asm-mips64/current.h --- a/include/asm-mips64/current.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/current.h Fri Jun 27 14:19:53 2003 @@ -3,15 +3,21 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1998, 1999 Ralf Baechle + * Copyright (C) 1998, 2002 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_CURRENT_H #define _ASM_CURRENT_H -#ifdef _LANGUAGE_C +#include <linux/thread_info.h> -/* MIPS rules... */ -register struct task_struct *current asm("$28"); +struct task_struct; + +static inline struct task_struct * get_current(void) +{ + return current_thread_info()->task; +} + +#define current get_current() -#endif /* _LANGUAGE_C */ #endif /* _ASM_CURRENT_H */ diff -Nru a/include/asm-mips64/dec/ecc.h b/include/asm-mips64/dec/ecc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/ecc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,51 @@ +/* + * include/asm-mips/dec/ecc.h + * + * ECC handling logic definitions common to DECstation/DECsystem + * 5000/200 (KN02), 5000/240 (KN03), 5000/260 (KN05) and + * DECsystem 5900 (KN03), 5900/260 (KN05) systems. + * + * Copyright (C) 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_ECC_H +#define __ASM_MIPS_DEC_ECC_H + +/* + * Error Address Register bits. + * The register is r/wc -- any write clears it. + */ +#define KN0X_EAR_VALID (1<<31) /* error data valid, bus IRQ */ +#define KN0X_EAR_CPU (1<<30) /* CPU/DMA transaction */ +#define KN0X_EAR_WRITE (1<<29) /* write/read transaction */ +#define KN0X_EAR_ECCERR (1<<28) /* ECC/timeout or overrun */ +#define KN0X_EAR_RES_27 (1<<27) /* unused */ +#define KN0X_EAR_ADDRESS (0x7ffffff<<0) /* address involved */ + +/* + * Error Syndrome Register bits. + * The register is frozen when EAR.VALID is set, otherwise it records bits + * from the last memory read. The register is r/wc -- any write clears it. + */ +#define KN0X_ESR_VLDHI (1<<31) /* error data valid hi word */ +#define KN0X_ESR_CHKHI (0x7f<<24) /* check bits read from mem */ +#define KN0X_ESR_SNGHI (1<<23) /* single/double bit error */ +#define KN0X_ESR_SYNHI (0x7f<<16) /* syndrome from ECC logic */ +#define KN0X_ESR_VLDLO (1<<15) /* error data valid lo word */ +#define KN0X_ESR_CHKLO (0x7f<<8) /* check bits read from mem */ +#define KN0X_ESR_SNGLO (1<<7) /* single/double bit error */ +#define KN0X_ESR_SYNLO (0x7f<<0) /* syndrome from ECC logic */ + + +#ifndef __ASSEMBLY__ +struct pt_regs; +extern void dec_ecc_be_init(void); +extern int dec_ecc_be_handler(struct pt_regs *regs, int is_fixup); +extern void dec_ecc_be_interrupt(int irq, void *dev_id, struct pt_regs *regs); +#endif + +#endif /* __ASM_MIPS_DEC_ECC_H */ diff -Nru a/include/asm-mips64/dec/interrupts.h b/include/asm-mips64/dec/interrupts.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/interrupts.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,125 @@ +/* + * Miscellaneous definitions used to initialise the interrupt vector table + * with the machine-specific interrupt routines. + * + * 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) 1997 by Paul M. Antoine. + * reworked 1998 by Harald Koerfgen. + * Copyright (C) 2001, 2002, 2003 Maciej W. Rozycki + */ + +#ifndef __ASM_DEC_INTERRUPTS_H +#define __ASM_DEC_INTERRUPTS_H + +#include <asm/mipsregs.h> + + +/* + * The list of possible system devices which provide an + * interrupt. Not all devices exist on a given system. + */ +#define DEC_IRQ_CASCADE 0 /* cascade from CSR or I/O ASIC */ + +/* Ordinary interrupts */ +#define DEC_IRQ_AB_RECV 1 /* ACCESS.bus receive */ +#define DEC_IRQ_AB_XMIT 2 /* ACCESS.bus transmit */ +#define DEC_IRQ_DZ11 3 /* DZ11 (DC7085) serial */ +#define DEC_IRQ_ASC 4 /* ASC (NCR53C94) SCSI */ +#define DEC_IRQ_FLOPPY 5 /* 82077 FDC */ +#define DEC_IRQ_FPU 6 /* R3k FPU */ +#define DEC_IRQ_HALT 7 /* HALT button or from ACCESS.Bus */ +#define DEC_IRQ_ISDN 8 /* Am79C30A ISDN */ +#define DEC_IRQ_LANCE 9 /* LANCE (Am7990) Ethernet */ +#define DEC_IRQ_BUS 10 /* memory, I/O bus read/write errors */ +#define DEC_IRQ_PSU 11 /* power supply unit warning */ +#define DEC_IRQ_RTC 12 /* DS1287 RTC */ +#define DEC_IRQ_SCC0 13 /* SCC (Z85C30) serial #0 */ +#define DEC_IRQ_SCC1 14 /* SCC (Z85C30) serial #1 */ +#define DEC_IRQ_SII 15 /* SII (DC7061) SCSI */ +#define DEC_IRQ_TC0 16 /* TURBOchannel slot #0 */ +#define DEC_IRQ_TC1 17 /* TURBOchannel slot #1 */ +#define DEC_IRQ_TC2 18 /* TURBOchannel slot #2 */ +#define DEC_IRQ_TIMER 19 /* ARC periodic timer */ +#define DEC_IRQ_VIDEO 20 /* framebuffer */ + +/* I/O ASIC DMA interrupts */ +#define DEC_IRQ_ASC_MERR 21 /* ASC memory read error */ +#define DEC_IRQ_ASC_ERR 22 /* ASC page overrun */ +#define DEC_IRQ_ASC_DMA 23 /* ASC buffer pointer loaded */ +#define DEC_IRQ_FLOPPY_ERR 24 /* FDC error */ +#define DEC_IRQ_ISDN_ERR 25 /* ISDN memory read/overrun error */ +#define DEC_IRQ_ISDN_RXDMA 26 /* ISDN recv buffer pointer loaded */ +#define DEC_IRQ_ISDN_TXDMA 27 /* ISDN xmit buffer pointer loaded */ +#define DEC_IRQ_LANCE_MERR 28 /* LANCE memory read error */ +#define DEC_IRQ_SCC0A_RXERR 29 /* SCC0A (printer) receive overrun */ +#define DEC_IRQ_SCC0A_RXDMA 30 /* SCC0A receive half page */ +#define DEC_IRQ_SCC0A_TXERR 31 /* SCC0A xmit memory read/overrun */ +#define DEC_IRQ_SCC0A_TXDMA 32 /* SCC0A transmit page end */ +#define DEC_IRQ_AB_RXERR 33 /* ACCESS.bus receive overrun */ +#define DEC_IRQ_AB_RXDMA 34 /* ACCESS.bus receive half page */ +#define DEC_IRQ_AB_TXERR 35 /* ACCESS.bus xmit memory read/ovrn */ +#define DEC_IRQ_AB_TXDMA 36 /* ACCESS.bus transmit page end */ +#define DEC_IRQ_SCC1A_RXERR 37 /* SCC1A (modem) receive overrun */ +#define DEC_IRQ_SCC1A_RXDMA 38 /* SCC1A receive half page */ +#define DEC_IRQ_SCC1A_TXERR 39 /* SCC1A xmit memory read/overrun */ +#define DEC_IRQ_SCC1A_TXDMA 40 /* SCC1A transmit page end */ + +/* TC5 & TC6 are virtual slots for KN02's onboard devices */ +#define DEC_IRQ_TC5 DEC_IRQ_ASC /* virtual PMAZ-AA */ +#define DEC_IRQ_TC6 DEC_IRQ_LANCE /* virtual PMAD-AA */ + +#define DEC_NR_INTS 41 + + +/* Largest of cpu mask_nr tables. */ +#define DEC_MAX_CPU_INTS 6 +/* Largest of asic mask_nr tables. */ +#define DEC_MAX_ASIC_INTS 9 + + +/* + * CPU interrupt bits common to all systems. + */ +#define DEC_CPU_INR_FPU 7 /* R3k FPU */ +#define DEC_CPU_INR_SW1 1 /* software #1 */ +#define DEC_CPU_INR_SW0 0 /* software #0 */ + +#define DEC_CPU_IRQ_BASE 0 /* first IRQ assigned to CPU */ + +#define DEC_CPU_IRQ_NR(n) ((n) + DEC_CPU_IRQ_BASE) +#define DEC_CPU_IRQ_MASK(n) (1 << ((n) + CAUSEB_IP)) +#define DEC_CPU_IRQ_ALL (0xff << CAUSEB_IP) + + +#ifndef __ASSEMBLY__ + +/* + * Interrupt table structures to hide differences between systems. + */ +typedef union { int i; void *p; } int_ptr; +extern int dec_interrupt[DEC_NR_INTS]; +extern int_ptr cpu_mask_nr_tbl[DEC_MAX_CPU_INTS][2]; +extern int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2]; +extern int cpu_fpu_mask; + + +/* + * Common interrupt routine prototypes for all DECStations + */ +extern void kn02_io_int(void); +extern void kn02xa_io_int(void); +extern void kn03_io_int(void); +extern void asic_dma_int(void); +extern void asic_all_int(void); +extern void kn02_all_int(void); +extern void cpu_all_int(void); + +extern void dec_intr_unimplemented(void); +extern void asic_intr_unimplemented(void); + +#endif /* __ASSEMBLY__ */ + +#endif diff -Nru a/include/asm-mips64/dec/io.h b/include/asm-mips64/dec/io.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/io.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,20 @@ +/* + * include/asm-mips64/dec/io.h + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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 __ASM_MIPS64_DEC_IO_H +#define __ASM_MIPS64_DEC_IO_H + +#include <asm/addrspace.h> + +#define IO_SPACE_BASE K1BASE + +#define IO_SPACE_LIMIT 0xffffffff + +#endif /* __ASM_MIPS64_DEC_IO_H */ diff -Nru a/include/asm-mips64/dec/ioasic.h b/include/asm-mips64/dec/ioasic.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/ioasic.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,36 @@ +/* + * include/asm-mips/dec/ioasic.h + * + * DEC I/O ASIC access operations. + * + * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_DEC_IOASIC_H +#define __ASM_DEC_IOASIC_H + +#include <linux/spinlock.h> +#include <linux/types.h> + +extern spinlock_t ioasic_ssr_lock; + +extern volatile u32 *ioasic_base; + +static inline void ioasic_write(unsigned int reg, u32 v) +{ + ioasic_base[reg / 4] = v; +} + +static inline u32 ioasic_read(unsigned int reg) +{ + return ioasic_base[reg / 4]; +} + +extern void init_ioasic_irqs(int base); + +#endif /* __ASM_DEC_IOASIC_H */ diff -Nru a/include/asm-mips64/dec/ioasic_addrs.h b/include/asm-mips64/dec/ioasic_addrs.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/ioasic_addrs.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,151 @@ +/* + * 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. + * + * Definitions for the address map in the JUNKIO Asic + * + * Created with Information from: + * + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * and the Mach Sources + * + * Copyright (C) 199x the Anonymous + * Copyright (C) 2002, 2003 Maciej W. Rozycki + */ + +#ifndef __ASM_MIPS_DEC_IOASIC_ADDRS_H +#define __ASM_MIPS_DEC_IOASIC_ADDRS_H + +#define IOASIC_SLOT_SIZE 0x00040000 + +/* + * Address ranges decoded by the I/O ASIC for onboard devices. + */ +#define IOASIC_SYS_ROM (0*IOASIC_SLOT_SIZE) /* system board ROM */ +#define IOASIC_IOCTL (1*IOASIC_SLOT_SIZE) /* I/O ASIC */ +#define IOASIC_ESAR (2*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */ +#define IOASIC_LANCE (3*IOASIC_SLOT_SIZE) /* LANCE Ethernet */ +#define IOASIC_SCC0 (4*IOASIC_SLOT_SIZE) /* SCC #0 */ +#define IOASIC_VDAC_HI (5*IOASIC_SLOT_SIZE) /* VDAC (maxine) */ +#define IOASIC_SCC1 (6*IOASIC_SLOT_SIZE) /* SCC #1 (3min, 3max+) */ +#define IOASIC_VDAC_LO (7*IOASIC_SLOT_SIZE) /* VDAC (maxine) */ +#define IOASIC_TOY (8*IOASIC_SLOT_SIZE) /* RTC */ +#define IOASIC_ISDN (9*IOASIC_SLOT_SIZE) /* ISDN (maxine) */ +#define IOASIC_ERRADDR (9*IOASIC_SLOT_SIZE) /* bus error address (3max+) */ +#define IOASIC_CHKSYN (10*IOASIC_SLOT_SIZE) /* ECC syndrome (3max+) */ +#define IOASIC_ACC_BUS (10*IOASIC_SLOT_SIZE) /* ACCESS.bus (maxine) */ +#define IOASIC_MCR (11*IOASIC_SLOT_SIZE) /* memory control (3max+) */ +#define IOASIC_FLOPPY (11*IOASIC_SLOT_SIZE) /* FDC (maxine) */ +#define IOASIC_SCSI (12*IOASIC_SLOT_SIZE) /* ASC SCSI */ +#define IOASIC_FDC_DMA (13*IOASIC_SLOT_SIZE) /* FDC DMA (maxine) */ +#define IOASIC_SCSI_DMA (14*IOASIC_SLOT_SIZE) /* ??? */ +#define IOASIC_RES_15 (15*IOASIC_SLOT_SIZE) /* unused? */ + + +/* + * Offsets for I/O ASIC registers (relative to (system_base + IOASIC_IOCTL)). + */ + /* all systems */ +#define IO_REG_SCSI_DMA_P 0x00 /* SCSI DMA Pointer */ +#define IO_REG_SCSI_DMA_BP 0x10 /* SCSI DMA Buffer Pointer */ +#define IO_REG_LANCE_DMA_P 0x20 /* LANCE DMA Pointer */ +#define IO_REG_SCC0A_T_DMA_P 0x30 /* SCC0A Transmit DMA Pointer */ +#define IO_REG_SCC0A_R_DMA_P 0x40 /* SCC0A Receive DMA Pointer */ + + /* except Maxine */ +#define IO_REG_SCC1A_T_DMA_P 0x50 /* SCC1A Transmit DMA Pointer */ +#define IO_REG_SCC1A_R_DMA_P 0x60 /* SCC1A Receive DMA Pointer */ + + /* Maxine */ +#define IO_REG_AB_T_DMA_P 0x50 /* ACCESS.bus Transmit DMA Pointer */ +#define IO_REG_AB_R_DMA_P 0x60 /* ACCESS.bus Receive DMA Pointer */ +#define IO_REG_FLOPPY_DMA_P 0x70 /* Floppy DMA Pointer */ +#define IO_REG_ISDN_T_DMA_P 0x80 /* ISDN Transmit DMA Pointer */ +#define IO_REG_ISDN_T_DMA_BP 0x90 /* ISDN Transmit DMA Buffer Pointer */ +#define IO_REG_ISDN_R_DMA_P 0xa0 /* ISDN Receive DMA Pointer */ +#define IO_REG_ISDN_R_DMA_BP 0xb0 /* ISDN Receive DMA Buffer Pointer */ + + /* all systems */ +#define IO_REG_DATA_0 0xc0 /* System Data Buffer 0 */ +#define IO_REG_DATA_1 0xd0 /* System Data Buffer 1 */ +#define IO_REG_DATA_2 0xe0 /* System Data Buffer 2 */ +#define IO_REG_DATA_3 0xf0 /* System Data Buffer 3 */ + + /* all systems */ +#define IO_REG_SSR 0x100 /* System Support Register */ +#define IO_REG_SIR 0x110 /* System Interrupt Register */ +#define IO_REG_SIMR 0x120 /* System Interrupt Mask Reg. */ +#define IO_REG_SAR 0x130 /* System Address Register */ + + /* Maxine */ +#define IO_REG_ISDN_T_DATA 0x140 /* ISDN Xmit Data Register */ +#define IO_REG_ISDN_R_DATA 0x150 /* ISDN Receive Data Register */ + + /* all systems */ +#define IO_REG_LANCE_SLOT 0x160 /* LANCE I/O Slot Register */ +#define IO_REG_SCSI_SLOT 0x170 /* SCSI Slot Register */ +#define IO_REG_SCC0A_SLOT 0x180 /* SCC0A DMA Slot Register */ + + /* except Maxine */ +#define IO_REG_SCC1A_SLOT 0x190 /* SCC1A DMA Slot Register */ + + /* Maxine */ +#define IO_REG_AB_SLOT 0x190 /* ACCESS.bus DMA Slot Register */ +#define IO_REG_FLOPPY_SLOT 0x1a0 /* Floppy Slot Register */ + + /* all systems */ +#define IO_REG_SCSI_SCR 0x1b0 /* SCSI Partial-Word DMA Control */ +#define IO_REG_SCSI_SDR0 0x1c0 /* SCSI DMA Partial Word 0 */ +#define IO_REG_SCSI_SDR1 0x1d0 /* SCSI DMA Partial Word 1 */ +#define IO_REG_FCTR 0x1e0 /* Free-Running Counter */ +#define IO_REG_RES_31 0x1f0 /* unused */ + + +/* + * The upper 16 bits of the System Support Register are a part of the + * I/O ASIC's internal DMA engine and thus are common to all I/O ASIC + * machines. The exception is the Maxine, which makes use of the + * FLOPPY and ISDN bits (otherwise unused) and has a different SCC + * wiring. + */ + /* all systems */ +#define IO_SSR_SCC0A_TX_DMA_EN (1<<31) /* SCC0A transmit DMA enable */ +#define IO_SSR_SCC0A_RX_DMA_EN (1<<30) /* SCC0A receive DMA enable */ +#define IO_SSR_RES_27 (1<<27) /* unused */ +#define IO_SSR_RES_26 (1<<26) /* unused */ +#define IO_SSR_RES_25 (1<<25) /* unused */ +#define IO_SSR_RES_24 (1<<24) /* unused */ +#define IO_SSR_RES_23 (1<<23) /* unused */ +#define IO_SSR_SCSI_DMA_DIR (1<<18) /* SCSI DMA direction */ +#define IO_SSR_SCSI_DMA_EN (1<<17) /* SCSI DMA enable */ +#define IO_SSR_LANCE_DMA_EN (1<<16) /* LANCE DMA enable */ + + /* except Maxine */ +#define IO_SSR_SCC1A_TX_DMA_EN (1<<29) /* SCC1A transmit DMA enable */ +#define IO_SSR_SCC1A_RX_DMA_EN (1<<28) /* SCC1A receive DMA enable */ +#define IO_SSR_RES_22 (1<<22) /* unused */ +#define IO_SSR_RES_21 (1<<21) /* unused */ +#define IO_SSR_RES_20 (1<<20) /* unused */ +#define IO_SSR_RES_19 (1<<19) /* unused */ + + /* Maxine */ +#define IO_SSR_AB_TX_DMA_EN (1<<29) /* ACCESS.bus xmit DMA enable */ +#define IO_SSR_AB_RX_DMA_EN (1<<28) /* ACCESS.bus recv DMA enable */ +#define IO_SSR_FLOPPY_DMA_DIR (1<<22) /* Floppy DMA direction */ +#define IO_SSR_FLOPPY_DMA_EN (1<<21) /* Floppy DMA enable */ +#define IO_SSR_ISDN_TX_DMA_EN (1<<20) /* ISDN transmit DMA enable */ +#define IO_SSR_ISDN_RX_DMA_EN (1<<19) /* ISDN receive DMA enable */ + +/* + * The lower 16 bits are system-specific. Bits 15,11:8 are common and + * defined here. The rest is defined in system-specific headers. + */ +#define KN0X_IO_SSR_DIAGDN (1<<15) /* diagnostic jumper */ +#define KN0X_IO_SSR_SCC_RST (1<<11) /* ~SCC0,1 (Z85C30) reset */ +#define KN0X_IO_SSR_RTC_RST (1<<10) /* ~RTC (DS1287) reset */ +#define KN0X_IO_SSR_ASC_RST (1<<9) /* ~ASC (NCR53C94) reset */ +#define KN0X_IO_SSR_LANCE_RST (1<<8) /* ~LANCE (Am7990) reset */ + +#endif /* __ASM_MIPS_DEC_IOASIC_ADDRS_H */ diff -Nru a/include/asm-mips64/dec/ioasic_ints.h b/include/asm-mips64/dec/ioasic_ints.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/ioasic_ints.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,74 @@ +/* + * 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. + * + * Definitions for the interrupt related bits in the I/O ASIC + * interrupt status register (and the interrupt mask register, of course) + * + * Created with Information from: + * + * "DEC 3000 300/400/500/600/700/800/900 AXP Models System Programmer's Manual" + * + * and the Mach Sources + * + * Copyright (C) 199x the Anonymous + * Copyright (C) 2002 Maciej W. Rozycki + */ + +#ifndef __ASM_DEC_IOASIC_INTS_H +#define __ASM_DEC_IOASIC_INTS_H + +/* + * The upper 16 bits are a part of the I/O ASIC's internal DMA engine + * and thus are common to all I/O ASIC machines. The exception is + * the Maxine, which makes use of the FLOPPY and ISDN bits (otherwise + * unused) and has a different SCC wiring. + */ + /* all systems */ +#define IO_INR_SCC0A_TXDMA 31 /* SCC0A transmit page end */ +#define IO_INR_SCC0A_TXERR 30 /* SCC0A transmit memory read error */ +#define IO_INR_SCC0A_RXDMA 29 /* SCC0A receive half page */ +#define IO_INR_SCC0A_RXERR 28 /* SCC0A receive overrun */ +#define IO_INR_ASC_DMA 19 /* ASC buffer pointer loaded */ +#define IO_INR_ASC_ERR 18 /* ASC page overrun */ +#define IO_INR_ASC_MERR 17 /* ASC memory read error */ +#define IO_INR_LANCE_MERR 16 /* LANCE memory read error */ + + /* except Maxine */ +#define IO_INR_SCC1A_TXDMA 27 /* SCC1A transmit page end */ +#define IO_INR_SCC1A_TXERR 26 /* SCC1A transmit memory read error */ +#define IO_INR_SCC1A_RXDMA 25 /* SCC1A receive half page */ +#define IO_INR_SCC1A_RXERR 24 /* SCC1A receive overrun */ +#define IO_INR_RES_23 23 /* unused */ +#define IO_INR_RES_22 22 /* unused */ +#define IO_INR_RES_21 21 /* unused */ +#define IO_INR_RES_20 20 /* unused */ + + /* Maxine */ +#define IO_INR_AB_TXDMA 27 /* ACCESS.bus transmit page end */ +#define IO_INR_AB_TXERR 26 /* ACCESS.bus xmit memory read error */ +#define IO_INR_AB_RXDMA 25 /* ACCESS.bus receive half page */ +#define IO_INR_AB_RXERR 24 /* ACCESS.bus receive overrun */ +#define IO_INR_FLOPPY_ERR 23 /* FDC error */ +#define IO_INR_ISDN_TXDMA 22 /* ISDN xmit buffer pointer loaded */ +#define IO_INR_ISDN_RXDMA 21 /* ISDN recv buffer pointer loaded */ +#define IO_INR_ISDN_ERR 20 /* ISDN memory read/overrun error */ + +#define IO_INR_DMA 16 /* first DMA IRQ */ + +/* + * The lower 16 bits are system-specific and thus defined in + * system-specific headers. + */ + + +#define IO_IRQ_BASE 8 /* first IRQ assigned to I/O ASIC */ +#define IO_IRQ_LINES 32 /* number of I/O ASIC interrupts */ + +#define IO_IRQ_NR(n) ((n) + IO_IRQ_BASE) +#define IO_IRQ_MASK(n) (1 << (n)) +#define IO_IRQ_ALL 0x0000ffff +#define IO_IRQ_DMA 0xffff0000 + +#endif /* __ASM_DEC_IOASIC_INTS_H */ diff -Nru a/include/asm-mips64/dec/kn01.h b/include/asm-mips64/dec/kn01.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn01.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,83 @@ +/* + * Hardware info about DECstation DS2100/3100 systems (otherwise known as + * pmin/pmax or KN01). + * + * 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) 1995,1996 by Paul M. Antoine, some code and definitions + * are by courtesy of Chris Fraser. + * Copyright (C) 2002, 2003 Maciej W. Rozycki + */ +#ifndef __ASM_MIPS_DEC_KN01_H +#define __ASM_MIPS_DEC_KN01_H + +#include <asm/addrspace.h> + +#define KN01_SLOT_BASE KSEG1ADDR(0x10000000) +#define KN01_SLOT_SIZE 0x01000000 + +/* + * Address ranges for devices. + */ +#define KN01_PMASK (0*KN01_SLOT_SIZE) /* color plane mask */ +#define KN01_PCC (1*KN01_SLOT_SIZE) /* PCC (DC503) cursor */ +#define KN01_VDAC (2*KN01_SLOT_SIZE) /* color map */ +#define KN01_RES_3 (3*KN01_SLOT_SIZE) /* unused */ +#define KN01_RES_4 (4*KN01_SLOT_SIZE) /* unused */ +#define KN01_RES_5 (5*KN01_SLOT_SIZE) /* unused */ +#define KN01_RES_6 (6*KN01_SLOT_SIZE) /* unused */ +#define KN01_ERRADDR (7*KN01_SLOT_SIZE) /* write error address */ +#define KN01_LANCE (8*KN01_SLOT_SIZE) /* LANCE (Am7990) Ethernet */ +#define KN01_LANCE_MEM (9*KN01_SLOT_SIZE) /* LANCE buffer memory */ +#define KN01_SII (10*KN01_SLOT_SIZE) /* SII (DC7061) SCSI */ +#define KN01_SII_MEM (11*KN01_SLOT_SIZE) /* SII buffer memory */ +#define KN01_DZ11 (12*KN01_SLOT_SIZE) /* DZ11 (DC7085) serial */ +#define KN01_RTC (13*KN01_SLOT_SIZE) /* DS1287 RTC (bytes #0) */ +#define KN01_ESAR (13*KN01_SLOT_SIZE) /* MAC address (bytes #1) */ +#define KN01_CSR (14*KN01_SLOT_SIZE) /* system ctrl & status reg */ +#define KN01_SYS_ROM (15*KN01_SLOT_SIZE) /* system board ROM */ + + +/* + * Some port addresses... + */ +#define KN01_LANCE_BASE (KN01_SLOT_BASE + KN01_LANCE) /* 0xB8000000 */ +#define KN01_DZ11_BASE (KN01_SLOT_BASE + KN01_DZ11) /* 0xBC000000 */ +#define KN01_RTC_BASE (KN01_SLOT_BASE + KN01_RTC) /* 0xBD000000 */ + + +/* + * Frame buffer memory address. + */ +#define KN01_VFB_MEM KSEG1ADDR(0x0fc00000) + +/* + * CPU interrupt bits. + */ +#define KN01_CPU_INR_BUS 6 /* memory, I/O bus read/write errors */ +#define KN01_CPU_INR_VIDEO 6 /* PCC area detect #2 */ +#define KN01_CPU_INR_RTC 5 /* DS1287 RTC */ +#define KN01_CPU_INR_DZ11 4 /* DZ11 (DC7085) serial */ +#define KN01_CPU_INR_LANCE 3 /* LANCE (Am7990) Ethernet */ +#define KN01_CPU_INR_SII 2 /* SII (DC7061) SCSI */ + + +/* + * System Control & Status Register bits. + */ +#define KN01_CSR_MNFMOD (1<<15) /* MNFMOD manufacturing jumper */ +#define KN01_CSR_STATUS (1<<14) /* self-test result status output */ +#define KN01_CSR_PARDIS (1<<13) /* parity error disable */ +#define KN01_CSR_CRSRTST (1<<12) /* PCC test output */ +#define KN01_CSR_MONO (1<<11) /* mono/color fb SIMM installed */ +#define KN01_CSR_MEMERR (1<<10) /* write timeout error status & ack*/ +#define KN01_CSR_VINT (1<<9) /* PCC area detect #2 status & ack */ +#define KN01_CSR_TXDIS (1<<8) /* DZ11 transmit disable */ +#define KN01_CSR_VBGTRG (1<<2) /* blue DAC voltage over green (r/o) */ +#define KN01_CSR_VRGTRG (1<<1) /* red DAC voltage over green (r/o) */ +#define KN01_CSR_VRGTRB (1<<0) /* red DAC voltage over blue (r/o) */ +#define KN01_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */ + +#endif /* __ASM_MIPS_DEC_KN01_H */ diff -Nru a/include/asm-mips64/dec/kn02.h b/include/asm-mips64/dec/kn02.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn02.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,106 @@ +/* + * Hardware info about DECstation 5000/200 systems (otherwise known as + * 3max or KN02). + * + * 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) 1995,1996 by Paul M. Antoine, some code and definitions + * are by courtesy of Chris Fraser. + * Copyright (C) 2002, 2003 Maciej W. Rozycki + */ +#ifndef __ASM_MIPS_DEC_KN02_H +#define __ASM_MIPS_DEC_KN02_H + +#ifndef __ASSEMBLY__ +#include <linux/spinlock.h> +#include <linux/types.h> +#endif + +#include <asm/addrspace.h> +#include <asm/dec/ecc.h> + + +#define KN02_SLOT_BASE KSEG1ADDR(0x1fc00000) +#define KN02_SLOT_SIZE 0x00080000 + +/* + * Address ranges decoded by the "system slot" logic for onboard devices. + */ +#define KN02_SYS_ROM (0*KN02_SLOT_SIZE) /* system board ROM */ +#define KN02_RES_1 (1*KN02_SLOT_SIZE) /* unused */ +#define KN02_CHKSYN (2*KN02_SLOT_SIZE) /* ECC syndrome */ +#define KN02_ERRADDR (3*KN02_SLOT_SIZE) /* bus error address */ +#define KN02_DZ11 (4*KN02_SLOT_SIZE) /* DZ11 (DC7085) serial */ +#define KN02_RTC (5*KN02_SLOT_SIZE) /* DS1287 RTC */ +#define KN02_CSR (6*KN02_SLOT_SIZE) /* system ctrl & status reg */ +#define KN02_SYS_ROM_7 (7*KN02_SLOT_SIZE) /* system board ROM (alias) */ + + +/* + * Some port addresses... + */ +#define KN02_DZ11_BASE (KN02_SLOT_BASE + KN02_DZ11) /* DZ11 */ +#define KN02_RTC_BASE (KN02_SLOT_BASE + KN02_RTC) /* RTC */ +#define KN02_CSR_BASE (KN02_SLOT_BASE + KN02_CSR) /* CSR */ + + +/* + * System Control & Status Register bits. + */ +#define KN02_CSR_RES_28 (0xf<<28) /* unused */ +#define KN02_CSR_PSU (1<<27) /* power supply unit warning */ +#define KN02_CSR_NVRAM (1<<26) /* ~NVRAM clear jumper */ +#define KN02_CSR_REFEVEN (1<<25) /* mem refresh bank toggle */ +#define KN03_CSR_NRMOD (1<<24) /* ~NRMOD manufact. jumper */ +#define KN03_CSR_IOINTEN (0xff<<16) /* IRQ mask bits */ +#define KN02_CSR_DIAGCHK (1<<15) /* diagn/norml ECC reads */ +#define KN02_CSR_DIAGGEN (1<<14) /* diagn/norml ECC writes */ +#define KN02_CSR_CORRECT (1<<13) /* ECC correct/check */ +#define KN02_CSR_LEDIAG (1<<12) /* ECC diagn. latch strobe */ +#define KN02_CSR_TXDIS (1<<11) /* DZ11 transmit disable */ +#define KN02_CSR_BNK32M (1<<10) /* 32M/8M stride */ +#define KN02_CSR_DIAGDN (1<<9) /* DIAGDN manufact. jumper */ +#define KN02_CSR_BAUD38 (1<<8) /* DZ11 38/19kbps ext. rate */ +#define KN03_CSR_IOINT (0xff<<0) /* IRQ status bits (r/o) */ +#define KN03_CSR_LEDS (0xff<<0) /* ~diagnostic LEDs (w/o) */ + + +/* + * CPU interrupt bits. + */ +#define KN02_CPU_INR_RES_6 6 /* unused */ +#define KN02_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */ +#define KN02_CPU_INR_RES_4 4 /* unused */ +#define KN02_CPU_INR_RTC 3 /* DS1287 RTC */ +#define KN02_CPU_INR_CASCADE 2 /* CSR cascade */ + +/* + * CSR interrupt bits. + */ +#define KN02_CSR_INR_DZ11 7 /* DZ11 (DC7085) serial */ +#define KN02_CSR_INR_LANCE 6 /* LANCE (Am7990) Ethernet */ +#define KN02_CSR_INR_ASC 5 /* ASC (NCR53C94) SCSI */ +#define KN02_CSR_INR_RES_4 4 /* unused */ +#define KN02_CSR_INR_RES_3 3 /* unused */ +#define KN02_CSR_INR_TC2 2 /* TURBOchannel slot #2 */ +#define KN02_CSR_INR_TC1 1 /* TURBOchannel slot #1 */ +#define KN02_CSR_INR_TC0 0 /* TURBOchannel slot #0 */ + + +#define KN02_IRQ_BASE 8 /* first IRQ assigned to CSR */ +#define KN02_IRQ_LINES 8 /* number of CSR interrupts */ + +#define KN02_IRQ_NR(n) ((n) + KN02_IRQ_BASE) +#define KN02_IRQ_MASK(n) (1 << (n)) +#define KN02_IRQ_ALL 0xff + + +#ifndef __ASSEMBLY__ +extern u32 cached_kn02_csr; +extern spinlock_t kn02_lock; +extern void init_kn02_irqs(int base); +#endif + +#endif /* __ASM_MIPS_DEC_KN02_H */ diff -Nru a/include/asm-mips64/dec/kn02ba.h b/include/asm-mips64/dec/kn02ba.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn02ba.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,67 @@ +/* + * include/asm-mips/dec/kn02ba.h + * + * DECstation 5000/1xx (3min or KN02-BA) definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_KN02BA_H +#define __ASM_MIPS_DEC_KN02BA_H + +#include <asm/dec/kn02xa.h> /* For common definitions. */ + +/* + * CPU interrupt bits. + */ +#define KN02BA_CPU_INR_HALT 6 /* HALT button */ +#define KN02BA_CPU_INR_CASCADE 5 /* I/O ASIC cascade */ +#define KN02BA_CPU_INR_TC2 4 /* TURBOchannel slot #2 */ +#define KN02BA_CPU_INR_TC1 3 /* TURBOchannel slot #1 */ +#define KN02BA_CPU_INR_TC0 2 /* TURBOchannel slot #0 */ + +/* + * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits. + */ +#define KN02BA_IO_INR_RES_15 15 /* unused */ +#define KN02BA_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */ +#define KN02BA_IO_INR_RES_13 13 /* unused */ +#define KN02BA_IO_INR_BUS 12 /* memory, I/O bus read/write errors */ +#define KN02BA_IO_INR_RES_11 11 /* unused */ +#define KN02BA_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */ +#define KN02BA_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */ +#define KN02BA_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */ +#define KN02BA_IO_INR_SCC1 7 /* SCC (Z85C30) serial #1 */ +#define KN02BA_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */ +#define KN02BA_IO_INR_RTC 5 /* DS1287 RTC */ +#define KN02BA_IO_INR_PSU 4 /* power supply unit warning */ +#define KN02BA_IO_INR_RES_3 3 /* unused */ +#define KN02BA_IO_INR_ASC_DATA 2 /* SCSI data ready (for PIO) */ +#define KN02BA_IO_INR_PBNC 1 /* ~HALT button debouncer */ +#define KN02BA_IO_INR_PBNO 0 /* HALT button debouncer */ + + +/* + * Memory Error Register bits. + */ +#define KN02BA_MER_RES_27 (1<<27) /* unused */ + +/* + * Memory Size Register bits. + */ +#define KN02BA_MSR_RES_17 (0x3ff<<17) /* unused */ + +/* + * I/O ASIC System Support Register bits. + */ +#define KN02BA_IO_SSR_TXDIS1 (1<<14) /* SCC1 transmit disable */ +#define KN02BA_IO_SSR_TXDIS0 (1<<13) /* SCC0 transmit disable */ +#define KN02BA_IO_SSR_RES_12 (1<<12) /* unused */ + +#define KN02BA_IO_SSR_LEDS (0xff<<0) /* ~diagnostic LEDs */ + +#endif /* __ASM_MIPS_DEC_KN02BA_H */ diff -Nru a/include/asm-mips64/dec/kn02ca.h b/include/asm-mips64/dec/kn02ca.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn02ca.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,79 @@ +/* + * include/asm-mips/dec/kn02ca.h + * + * Personal DECstation 5000/xx (Maxine or KN02-CA) definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_KN02CA_H +#define __ASM_MIPS_DEC_KN02CA_H + +#include <asm/dec/kn02xa.h> /* For common definitions. */ + +/* + * CPU interrupt bits. + */ +#define KN02CA_CPU_INR_HALT 6 /* HALT from ACCESS.Bus */ +#define KN02CA_CPU_INR_CASCADE 5 /* I/O ASIC cascade */ +#define KN02CA_CPU_INR_BUS 4 /* memory, I/O bus read/write errors */ +#define KN02CA_CPU_INR_RTC 3 /* DS1287 RTC */ +#define KN02CA_CPU_INR_TIMER 2 /* ARC periodic timer */ + +/* + * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits. + */ +#define KN02CA_IO_INR_FLOPPY 15 /* 82077 FDC */ +#define KN02CA_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */ +#define KN02CA_IO_INR_POWERON 13 /* (*) ACCESS.Bus/power-on reset */ +#define KN02CA_IO_INR_TC0 12 /* TURBOchannel slot #0 */ +#define KN02CA_IO_INR_TIMER 12 /* ARC periodic timer (?) */ +#define KN02CA_IO_INR_ISDN 11 /* Am79C30A ISDN */ +#define KN02CA_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */ +#define KN02CA_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */ +#define KN02CA_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */ +#define KN02CA_IO_INR_HDFLOPPY 7 /* (*) HD (1.44MB) floppy status */ +#define KN02CA_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */ +#define KN02CA_IO_INR_TC1 5 /* TURBOchannel slot #1 */ +#define KN02CA_IO_INR_XDFLOPPY 4 /* (*) XD (2.88MB) floppy status */ +#define KN02CA_IO_INR_VIDEO 3 /* framebuffer */ +#define KN02CA_IO_INR_XVIDEO 2 /* ~framebuffer */ +#define KN02CA_IO_INR_AB_XMIT 1 /* ACCESS.bus transmit */ +#define KN02CA_IO_INR_AB_RECV 0 /* ACCESS.bus receive */ + + +/* + * Memory Error Register bits. + */ +#define KN02CA_MER_INTR (1<<27) /* ARC IRQ status & ack */ + +/* + * Memory Size Register bits. + */ +#define KN02CA_MSR_INTREN (1<<26) /* ARC periodic IRQ enable */ +#define KN02CA_MSR_MS10EN (1<<25) /* 10/1ms IRQ period select */ +#define KN02CA_MSR_PFORCE (0xf<<21) /* byte lane error force */ +#define KN02CA_MSR_MABEN (1<<20) /* A side VFB address enable */ +#define KN02CA_MSR_LASTBANK (0x7<<17) /* onboard RAM bank # */ + +/* + * I/O ASIC System Support Register bits. + */ +#define KN03CA_IO_SSR_RES_14 (1<<14) /* unused */ +#define KN03CA_IO_SSR_RES_13 (1<<13) /* unused */ +#define KN03CA_IO_SSR_ISDN_RST (1<<12) /* ~ISDN (Am79C30A) reset */ + +#define KN03CA_IO_SSR_FLOPPY_RST (1<<7) /* ~FDC (82077) reset */ +#define KN03CA_IO_SSR_VIDEO_RST (1<<6) /* ~framebuffer reset */ +#define KN03CA_IO_SSR_AB_RST (1<<5) /* ACCESS.bus reset */ +#define KN03CA_IO_SSR_RES_4 (1<<4) /* unused */ +#define KN03CA_IO_SSR_RES_3 (1<<4) /* unused */ +#define KN03CA_IO_SSR_RES_2 (1<<2) /* unused */ +#define KN03CA_IO_SSR_RES_1 (1<<1) /* unused */ +#define KN03CA_IO_SSR_LED (1<<0) /* power LED */ + +#endif /* __ASM_MIPS_DEC_KN02CA_H */ diff -Nru a/include/asm-mips64/dec/kn02xa.h b/include/asm-mips64/dec/kn02xa.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn02xa.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,75 @@ +/* + * Hardware info common to DECstation 5000/1xx systems (otherwise + * known as 3min or kn02ba) and Personal DECstations 5000/xx ones + * (otherwise known as maxine or kn02ca). + * + * 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) 1995,1996 by Paul M. Antoine, some code and definitions + * are by courtesy of Chris Fraser. + * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki + * + * These are addresses which have to be known early in the boot process. + * For other addresses refer to tc.h, ioasic_addrs.h and friends. + */ +#ifndef __ASM_MIPS_DEC_KN02XA_H +#define __ASM_MIPS_DEC_KN02XA_H + +#include <asm/addrspace.h> +#include <asm/dec/ioasic_addrs.h> + +#define KN02XA_SLOT_BASE KSEG1ADDR(0x1c000000) + +/* + * Some port addresses... + */ +#define KN02XA_IOASIC_BASE (KN02XA_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */ +#define KN02XA_RTC_BASE (KN02XA_SLOT_BASE + IOASIC_TOY) /* RTC */ + + +/* + * Memory control ASIC registers. + */ +#define KN02XA_MER KSEG1ADDR(0x0c400000) /* memory error register */ +#define KN02XA_MSR KSEG1ADDR(0x0c800000) /* memory size register */ + +/* + * CPU control ASIC registers. + */ +#define KN02XA_MEM_CONF KSEG1ADDR(0x0e000000) /* write timeout config */ +#define KN02XA_EAR KSEG1ADDR(0x0e000004) /* error address register */ +#define KN02XA_BOOT0 KSEG1ADDR(0x0e000008) /* boot 0 register */ +#define KN02XA_MEM_INTR KSEG1ADDR(0x0e00000c) /* write err IRQ stat & ack */ + +/* + * Memory Error Register bits, common definitions. + * The rest is defined in system-specific headers. + */ +#define KN02XA_MER_RES_28 (0xf<<28) /* unused */ +#define KN02XA_MER_RES_17 (0x3ff<<17) /* unused */ +#define KN02XA_MER_PAGERR (1<<16) /* 2k page boundary error */ +#define KN02XA_MER_TRANSERR (1<<15) /* transfer length error */ +#define KN02XA_MER_PARDIS (1<<14) /* parity error disable */ +#define KN02XA_MER_RES_12 (0x3<<12) /* unused */ +#define KN02XA_MER_BYTERR (0xf<<8) /* byte lane error bitmask */ +#define KN02XA_MER_RES_0 (0xff<<0) /* unused */ + +/* + * Memory Size Register bits, common definitions. + * The rest is defined in system-specific headers. + */ +#define KN02XA_MSR_RES_27 (0x1f<<27) /* unused */ +#define KN02XA_MSR_RES_14 (0x7<<14) /* unused */ +#define KN02XA_MSR_SIZE (1<<13) /* 16M/4M stride */ +#define KN02XA_MSR_RES_0 (0x1fff<<0) /* unused */ + +/* + * Error Address Register bits. + */ +#define KN02XA_EAR_RES_29 (0x7<<29) /* unused */ +#define KN02XA_EAR_ADDRESS (0x7ffffff<<2) /* address involved */ +#define KN02XA_EAR_RES_0 (0x3<<0) /* unused */ + +#endif /* __ASM_MIPS_DEC_KN02XA_H */ diff -Nru a/include/asm-mips64/dec/kn03.h b/include/asm-mips64/dec/kn03.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn03.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,83 @@ +/* + * Hardware info about DECstation 5000/2x0 systems (otherwise known as + * 3max+) and DECsystem 5900 systems (otherwise known as bigmax) which + * differ mechanically but are otherwise identical (both are known as + * KN03). + * + * 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) 1995,1996 by Paul M. Antoine, some code and definitions + * are by courtesy of Chris Fraser. + * Copyright (C) 2000, 2002, 2003 Maciej W. Rozycki + */ +#ifndef __ASM_MIPS_DEC_KN03_H +#define __ASM_MIPS_DEC_KN03_H + +#include <asm/addrspace.h> +#include <asm/dec/ecc.h> +#include <asm/dec/ioasic_addrs.h> + +#define KN03_SLOT_BASE KSEG1ADDR(0x1f800000) + +/* + * Some port addresses... + */ +#define KN03_IOASIC_BASE (KN03_SLOT_BASE + IOASIC_IOCTL) /* I/O ASIC */ +#define KN03_RTC_BASE (KN03_SLOT_BASE + IOASIC_TOY) /* RTC */ +#define KN03_MCR_BASE (KN03_SLOT_BASE + IOASIC_MCR) /* MCR */ + + +/* + * CPU interrupt bits. + */ +#define KN03_CPU_INR_HALT 6 /* HALT button */ +#define KN03_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */ +#define KN03_CPU_INR_RES_4 4 /* unused */ +#define KN03_CPU_INR_RTC 3 /* DS1287 RTC */ +#define KN03_CPU_INR_CASCADE 2 /* I/O ASIC cascade */ + +/* + * I/O ASIC interrupt bits. Star marks denote non-IRQ status bits. + */ +#define KN03_IO_INR_3MAXP 15 /* (*) 3max+/bigmax ID */ +#define KN03_IO_INR_NVRAM 14 /* (*) NVRAM clear jumper */ +#define KN03_IO_INR_TC2 13 /* TURBOchannel slot #2 */ +#define KN03_IO_INR_TC1 12 /* TURBOchannel slot #1 */ +#define KN03_IO_INR_TC0 11 /* TURBOchannel slot #0 */ +#define KN03_IO_INR_NRMOD 10 /* (*) NRMOD manufacturing jumper */ +#define KN03_IO_INR_ASC 9 /* ASC (NCR53C94) SCSI */ +#define KN03_IO_INR_LANCE 8 /* LANCE (Am7990) Ethernet */ +#define KN03_IO_INR_SCC1 7 /* SCC (Z85C30) serial #1 */ +#define KN03_IO_INR_SCC0 6 /* SCC (Z85C30) serial #0 */ +#define KN03_IO_INR_RTC 5 /* DS1287 RTC */ +#define KN03_IO_INR_PSU 4 /* power supply unit warning */ +#define KN03_IO_INR_RES_3 3 /* unused */ +#define KN03_IO_INR_ASC_DATA 2 /* SCSI data ready (for PIO) */ +#define KN03_IO_INR_PBNC 1 /* ~HALT button debouncer */ +#define KN03_IO_INR_PBNO 0 /* HALT button debouncer */ + + +/* + * Memory Control Register bits. + */ +#define KN03_MCR_RES_16 (0xffff<<16) /* unused */ +#define KN03_MCR_DIAGCHK (1<<15) /* diagn/norml ECC reads */ +#define KN03_MCR_DIAGGEN (1<<14) /* diagn/norml ECC writes */ +#define KN03_MCR_CORRECT (1<<13) /* ECC correct/check */ +#define KN03_MCR_RES_11 (0x3<<12) /* unused */ +#define KN03_MCR_BNK32M (1<<10) /* 32M/8M stride */ +#define KN03_MCR_RES_7 (0x7<<7) /* unused */ +#define KN03_MCR_CHECK (0x7f<<0) /* diagnostic check bits */ + +/* + * I/O ASIC System Support Register bits. + */ +#define KN03_IO_SSR_TXDIS1 (1<<14) /* SCC1 transmit disable */ +#define KN03_IO_SSR_TXDIS0 (1<<13) /* SCC0 transmit disable */ +#define KN03_IO_SSR_RES_12 (1<<12) /* unused */ + +#define KN03_IO_SSR_LEDS (0xff<<0) /* ~diagnostic LEDs */ + +#endif /* __ASM_MIPS_DEC_KN03_H */ diff -Nru a/include/asm-mips64/dec/kn05.h b/include/asm-mips64/dec/kn05.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn05.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,70 @@ +/* + * include/asm-mips/dec/kn05.h + * + * DECstation 5000/260 (4max+ or KN05) and DECsystem 5900/260 + * definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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! All this information is pure guesswork based on the + * ROM. It is provided here in hope it will give someone some + * food for thought. No documentation for the KN05 module has + * been located so far. + */ +#ifndef __ASM_MIPS_DEC_KN05_H +#define __ASM_MIPS_DEC_KN05_H + +#include <asm/dec/ioasic_addrs.h> + +/* + * The oncard MB (Memory Buffer) ASIC provides an additional address + * decoder. Certain address ranges within the "high" 16 slots are + * passed to the I/O ASIC's decoder like with the KN03. Others are + * handled locally. "Low" slots are always passed. + */ +#define KN05_MB_ROM (16*IOASIC_SLOT_SIZE) /* KN05 card ROM */ +#define KN05_IOCTL (17*IOASIC_SLOT_SIZE) /* I/O ASIC */ +#define KN05_ESAR (18*IOASIC_SLOT_SIZE) /* LANCE MAC address chip */ +#define KN05_LANCE (19*IOASIC_SLOT_SIZE) /* LANCE Ethernet */ +#define KN05_MB_INT (20*IOASIC_SLOT_SIZE) /* MB interrupt register */ +#define KN05_MB_EA (21*IOASIC_SLOT_SIZE) /* MB error address? */ +#define KN05_MB_EC (22*IOASIC_SLOT_SIZE) /* MB error ??? */ +#define KN05_MB_CSR (23*IOASIC_SLOT_SIZE) /* MB control & status */ +#define KN05_RES_24 (24*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_25 (25*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_26 (26*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_27 (27*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_SCSI (28*IOASIC_SLOT_SIZE) /* ASC SCSI */ +#define KN05_RES_29 (29*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_30 (30*IOASIC_SLOT_SIZE) /* unused? */ +#define KN05_RES_31 (31*IOASIC_SLOT_SIZE) /* unused? */ + +/* + * Bits for the MB interrupt register. + * The register appears read-only. + */ +#define KN05_MB_INT_TC (1<<0) /* TURBOchannel? */ +#define KN05_MB_INT_RTC (1<<1) /* RTC? */ + +/* + * Bits for the MB control & status register. + * Set to 0x00bf8001 on my system by the ROM. + */ +#define KN05_MB_CSR_PF (1<<0) /* PreFetching enable? */ +#define KN05_MB_CSR_F (1<<1) /* ??? */ +#define KN05_MB_CSR_ECC (0xff<<2) /* ??? */ +#define KN05_MB_CSR_OD (1<<10) /* ??? */ +#define KN05_MB_CSR_CP (1<<11) /* ??? */ +#define KN05_MB_CSR_UNC (1<<12) /* ??? */ +#define KN05_MB_CSR_IM (1<<13) /* ??? */ +#define KN05_MB_CSR_NC (1<<14) /* ??? */ +#define KN05_MB_CSR_EE (1<<15) /* (bus) Exception Enable? */ +#define KN05_MB_CSR_MSK (0x1f<<16) /* ??? */ +#define KN05_MB_CSR_FW (1<<21) /* ??? */ + +#endif /* __ASM_MIPS_DEC_KN05_H */ diff -Nru a/include/asm-mips64/dec/kn230.h b/include/asm-mips64/dec/kn230.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/kn230.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,26 @@ +/* + * include/asm-mips/dec/kn230.h + * + * DECsystem 5100 (MIPSmate or KN230) definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_KN230_H +#define __ASM_MIPS_DEC_KN230_H + +/* + * CPU interrupt bits. + */ +#define KN230_CPU_INR_HALT 6 /* HALT button */ +#define KN230_CPU_INR_BUS 5 /* memory, I/O bus read/write errors */ +#define KN230_CPU_INR_RTC 4 /* DS1287 RTC */ +#define KN230_CPU_INR_SII 3 /* SII (DC7061) SCSI */ +#define KN230_CPU_INR_LANCE 3 /* LANCE (Am7990) Ethernet */ +#define KN230_CPU_INR_DZ11 2 /* DZ11 (DC7085) serial */ + +#endif /* __ASM_MIPS_DEC_KN230_H */ diff -Nru a/include/asm-mips64/dec/machtype.h b/include/asm-mips64/dec/machtype.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/machtype.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,27 @@ +/* + * Various machine type macros + * + * 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) 1998, 2000 Harald Koerfgen + */ + +#ifndef __ASM_DEC_MACHTYPE_H +#define __ASM_DEC_MACHTYPE_H + +#include <asm/bootinfo.h> + +#define TURBOCHANNEL (mips_machtype == MACH_DS5000_200 || \ + mips_machtype == MACH_DS5000_1XX || \ + mips_machtype == MACH_DS5000_XX || \ + mips_machtype == MACH_DS5000_2X0 || \ + mips_machtype == MACH_DS5900) + +#define IOASIC (mips_machtype == MACH_DS5000_1XX || \ + mips_machtype == MACH_DS5000_XX || \ + mips_machtype == MACH_DS5000_2X0 || \ + mips_machtype == MACH_DS5900) + +#endif diff -Nru a/include/asm-mips64/dec/prom.h b/include/asm-mips64/dec/prom.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/prom.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,169 @@ +/* + * include/asm-mips64/dec/prom.h + * + * DECstation PROM interface. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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. + * + * Based on arch/mips/dec/prom/prom.h by the Anonymous. + */ +#ifndef __ASM_MIPS64_DEC_PROM_H +#define __ASM_MIPS64_DEC_PROM_H + +#include <linux/types.h> + +#include <asm/addrspace.h> + +/* + * PMAX/3MAX PROM entry points for DS2100/3100's and DS5000/2xx's. + * Many of these will work for MIPSen as well! + */ +#define VEC_RESET (u64 *)KSEG1ADDR(0x1fc00000) + /* Prom base address */ + +#define PMAX_PROM_ENTRY(x) (VEC_RESET + (x)) /* Prom jump table */ + +#define PMAX_PROM_HALT PMAX_PROM_ENTRY(2) /* valid on MIPSen */ +#define PMAX_PROM_AUTOBOOT PMAX_PROM_ENTRY(5) /* valid on MIPSen */ +#define PMAX_PROM_OPEN PMAX_PROM_ENTRY(6) +#define PMAX_PROM_READ PMAX_PROM_ENTRY(7) +#define PMAX_PROM_CLOSE PMAX_PROM_ENTRY(10) +#define PMAX_PROM_LSEEK PMAX_PROM_ENTRY(11) +#define PMAX_PROM_GETCHAR PMAX_PROM_ENTRY(12) +#define PMAX_PROM_PUTCHAR PMAX_PROM_ENTRY(13) /* 12 on MIPSen */ +#define PMAX_PROM_GETS PMAX_PROM_ENTRY(15) +#define PMAX_PROM_PRINTF PMAX_PROM_ENTRY(17) +#define PMAX_PROM_GETENV PMAX_PROM_ENTRY(33) /* valid on MIPSen */ + + +/* + * Magic number indicating REX PROM available on DECstation. Found in + * register a2 on transfer of control to program from PROM. + */ +#define REX_PROM_MAGIC 0x30464354 + +#ifdef CONFIG_MIPS64 + +#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */ + +#else /* !CONFIG_MIPS64 */ + +#define prom_is_rex(magic) ((magic) == REX_PROM_MAGIC) + +#endif /* !CONFIG_MIPS64 */ + + +/* + * 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's and + * DS5000/2x0. + */ +#define REX_PROM_GETBITMAP 0x84/4 /* get mem bitmap */ +#define REX_PROM_GETCHAR 0x24/4 /* getch() */ +#define REX_PROM_GETENV 0x64/4 /* get env. variable */ +#define REX_PROM_GETSYSID 0x80/4 /* get system id */ +#define REX_PROM_GETTCINFO 0xa4/4 +#define REX_PROM_PRINTF 0x30/4 /* printf() */ +#define REX_PROM_SLOTADDR 0x6c/4 /* slotaddr */ +#define REX_PROM_BOOTINIT 0x54/4 /* open() */ +#define REX_PROM_BOOTREAD 0x58/4 /* read() */ +#define REX_PROM_CLEARCACHE 0x7c/4 + + +/* + * Used by rex_getbitmap(). + */ +typedef struct { + int pagesize; + unsigned char bitmap[0]; +} memmap; + + +/* + * Function pointers as read from a PROM's callback vector. + */ +extern int (*__rex_bootinit)(void); +extern int (*__rex_bootread)(void); +extern int (*__rex_getbitmap)(memmap *); +extern unsigned long *(*__rex_slot_address)(int); +extern void *(*__rex_gettcinfo)(void); +extern int (*__rex_getsysid)(void); +extern void (*__rex_clear_cache)(void); + +extern int (*__prom_getchar)(void); +extern char *(*__prom_getenv)(char *); +extern int (*__prom_printf)(char *, ...); + +extern int (*__pmax_open)(char*, int); +extern int (*__pmax_lseek)(int, long, int); +extern int (*__pmax_read)(int, void *, int); +extern int (*__pmax_close)(int); + + +#ifdef CONFIG_MIPS64 + +/* + * On MIPS64 we have to call PROM functions via a helper + * dispatcher to accomodate ABI incompatibilities. + */ +#define __DEC_PROM_O32 __attribute__((alias("call_o32"))) + +int _rex_bootinit(int (*)(void)) __DEC_PROM_O32; +int _rex_bootread(int (*)(void)) __DEC_PROM_O32; +int _rex_getbitmap(int (*)(memmap *), memmap *) __DEC_PROM_O32; +unsigned long *_rex_slot_address(unsigned long *(*)(int), int) __DEC_PROM_O32; +void *_rex_gettcinfo(void *(*)(void)) __DEC_PROM_O32; +int _rex_getsysid(int (*)(void)) __DEC_PROM_O32; +void _rex_clear_cache(void (*)(void)) __DEC_PROM_O32; + +int _prom_getchar(int (*)(void)) __DEC_PROM_O32; +char *_prom_getenv(char *(*)(char *), char *) __DEC_PROM_O32; +int _prom_printf(int (*)(char *, ...), char *, ...) __DEC_PROM_O32; + + +#define rex_bootinit() _rex_bootinit(__rex_bootinit) +#define rex_bootread() _rex_bootread(__rex_bootread) +#define rex_getbitmap(x) _rex_getbitmap(__rex_getbitmap, x) +#define rex_slot_address(x) _rex_slot_address(__rex_slot_address, x) +#define rex_gettcinfo() _rex_gettcinfo(__rex_gettcinfo) +#define rex_getsysid() _rex_getsysid(__rex_getsysid) +#define rex_clear_cache() _rex_clear_cache(__rex_clear_cache) + +#define prom_getchar() _prom_getchar(__prom_getchar) +#define prom_getenv(x) _prom_getenv(__prom_getenv, x) +#define prom_printf(x...) _prom_printf(__prom_printf, x) + +#else /* !CONFIG_MIPS64 */ + +/* + * On plain MIPS we just call PROM functions directly. + */ +#define rex_bootinit __rex_bootinit +#define rex_bootread __rex_bootread +#define rex_getbitmap __rex_getbitmap +#define rex_slot_address __rex_slot_address +#define rex_gettcinfo __rex_gettcinfo +#define rex_getsysid __rex_getsysid +#define rex_clear_cache __rex_clear_cache + +#define prom_getchar __prom_getchar +#define prom_getenv __prom_getenv +#define prom_printf __prom_printf + +#define pmax_open __pmax_open +#define pmax_lseek __pmax_lseek +#define pmax_read __pmax_read +#define pmax_close __pmax_close + +#endif /* !CONFIG_MIPS64 */ + + +extern void prom_meminit(u32); +extern void prom_identify_arch(u32); +extern void prom_init_cmdline(s32, s32 *, u32); + +#endif /* __ASM_MIPS64_DEC_PROM_H */ diff -Nru a/include/asm-mips64/dec/rtc-dec.h b/include/asm-mips64/dec/rtc-dec.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/rtc-dec.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,32 @@ +/* + * include/asm-mips/dec/rtc-dec.h + * + * RTC definitions for DECstation style attached Dallas DS1287 chip. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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 __ASM_MIPS_DEC_RTC_DEC_H +#define __ASM_MIPS_DEC_RTC_DEC_H + +#include <linux/types.h> + +#include <asm/addrspace.h> + +extern volatile u8 *dec_rtc_base; +extern unsigned long dec_kn_slot_size; + +extern struct rtc_ops dec_rtc_ops; + +#define RTC_PORT(x) CPHYSADDR(dec_rtc_base) +#define RTC_IO_EXTENT dec_kn_slot_size +#define RTC_IOMAPPED 0 +#define RTC_IRQ 0 + +#define RTC_DEC_YEAR 0x3f /* Where we store the real year on DECs. */ + +#endif /* __ASM_MIPS_DEC_RTC_DEC_H */ diff -Nru a/include/asm-mips64/dec/tc.h b/include/asm-mips64/dec/tc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/tc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,43 @@ +/* + * Interface to the TURBOchannel related routines + * + * 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) 1998 Harald Koerfgen + */ +#ifndef ASM_TC_H +#define ASM_TC_H + +extern unsigned long system_base; + +/* + * Search for a TURBOchannel Option Module + * with a certain name. Returns slot number + * of the first card not in use or -ENODEV + * if none found. + */ +extern int search_tc_card(const char *); +/* + * Marks the card in slot as used + */ +extern void claim_tc_card(int); +/* + * Marks the card in slot as free + */ +extern void release_tc_card(int); +/* + * Return base address of card in slot + */ +extern unsigned long get_tc_base_addr(int); +/* + * Return interrupt number of slot + */ +extern unsigned long get_tc_irq_nr(int); +/* + * Return TURBOchannel clock frequency in hz + */ +extern unsigned long get_tc_speed(void); + +#endif diff -Nru a/include/asm-mips64/dec/tcinfo.h b/include/asm-mips64/dec/tcinfo.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/tcinfo.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,47 @@ +/* + * Various TURBOchannel related stuff + * + * 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. + * + * Information obtained through the get_tcinfo prom call + * created from: + * + * TURBOchannel Firmware Specification + * + * EK-TCAAD-FS-004 + * from Digital Equipment Corporation + * + * Copyright (c) 1998 Harald Koerfgen + */ + +typedef struct { + int revision; + int clk_period; + int slot_size; + int io_timeout; + int dma_range; + int max_dma_burst; + int parity; + int reserved[4]; +} tcinfo; + +#define MAX_SLOT 7 + +typedef struct { + unsigned long base_addr; + unsigned char name[9]; + unsigned char vendor[9]; + unsigned char firmware[9]; + int interrupt; + int flags; +} slot_info; + +/* + * Values for flags + */ +#define FREE 1<<0 +#define IN_USE 1<<1 + + diff -Nru a/include/asm-mips64/dec/tcmodule.h b/include/asm-mips64/dec/tcmodule.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/dec/tcmodule.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,39 @@ +/* + * 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. + * + * Offsets for the ROM header locations for + * TURBOchannel cards + * + * created from: + * + * TURBOchannel Firmware Specification + * + * EK-TCAAD-FS-004 + * from Digital Equipment Corporation + * + * Jan.1998 Harald Koerfgen + */ +#ifndef __ASM_DEC_TCMODULE_H +#define __ASM_DEC_TCMODULE_H + +#define OLDCARD 0x3c0000 +#define NEWCARD 0x000000 + +#define TC_ROM_WIDTH 0x3e0 +#define TC_ROM_STRIDE 0x3e4 +#define TC_ROM_SIZE 0x3e8 +#define TC_SLOT_SIZE 0x3ec +#define TC_PATTERN0 0x3f0 +#define TC_PATTERN1 0x3f4 +#define TC_PATTERN2 0x3f8 +#define TC_PATTERN3 0x3fc +#define TC_FIRM_VER 0x400 +#define TC_VENDOR 0x420 +#define TC_MODULE 0x440 +#define TC_FIRM_TYPE 0x460 +#define TC_FLAGS 0x470 +#define TC_ROM_OBJECTS 0x480 + +#endif /* __ASM_DEC_TCMODULE_H */ diff -Nru a/include/asm-mips64/delay.h b/include/asm-mips64/delay.h --- a/include/asm-mips64/delay.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips64/delay.h Fri Jun 27 14:20:04 2003 @@ -11,6 +11,7 @@ #define _ASM_DELAY_H #include <linux/config.h> +#include <linux/param.h> extern unsigned long loops_per_jiffy; @@ -40,7 +41,17 @@ { unsigned long lo; - usecs *= 0x00068db8bac710cbUL; /* 2**64 / (1000000 / HZ) */ + /* + * The common rates of 1000 and 128 are rounded wrongly by the + * catchall case. Excessive precission? Probably ... + */ +#if (HZ == 128) + usecs *= 0x0008637bd05af6c7UL; /* 2**64 / (1000000 / HZ) */ +#elif (HZ == 1000) + usecs *= 0x004189374BC6A7f0UL; /* 2**64 / (1000000 / HZ) */ +#else + usecs *= (0x8000000000000000UL / (500000 / HZ)); +#endif __asm__("dmultu\t%2,%3" :"=h" (usecs), "=l" (lo) :"r" (usecs),"r" (lpj)); diff -Nru a/include/asm-mips64/div64.h b/include/asm-mips64/div64.h --- a/include/asm-mips64/div64.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/div64.h Fri Jun 27 14:19:56 2003 @@ -7,13 +7,43 @@ #define _ASM_DIV64_H /* + * Don't use this one in new code + */ +#define do_div64_32(res, high, low, base) ({ \ + unsigned int __quot, __mod; \ + unsigned long __div; \ + unsigned int __low, __high, __base; \ + \ + __high = (high); \ + __low = (low); \ + __div = __high; \ + __div = __div << 32 | __low; \ + __base = (base); \ + \ + __mod = __div % __base; \ + __div = __div / __base; \ + \ + __quot = __div; \ + (res) = __quot; \ + __mod; }) + +/* * Hey, we're already 64-bit, no * need to play games.. */ -#define do_div(n,base) ({ \ - int __res; \ - __res = ((unsigned long) n) % (unsigned) base; \ - n = ((unsigned long) n) / (unsigned) base; \ - __res; }) +#define do_div(n, base) ({ \ + unsigned long __quot; \ + unsigned int __mod; \ + unsigned long __div; \ + unsigned int __base; \ + \ + __div = (n); \ + __base = (base); \ + \ + __mod = __div % __base; \ + __quot = __div / __base; \ + \ + (n) = __quot; \ + __mod; }) #endif /* _ASM_DIV64_H */ diff -Nru a/include/asm-mips64/dma.h b/include/asm-mips64/dma.h --- a/include/asm-mips64/dma.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/dma.h Fri Jun 27 14:19:53 2003 @@ -43,7 +43,7 @@ * - page registers for 5-7 don't use data bit 0, represent 128K pages * - page registers for 0-3 use bit 0, represent 64K pages * - * DMA transfers are limited to the lower 16MB of _physical_ memory. + * DMA transfers are limited to the lower 16MB of _physical_ memory. * Note that addresses loaded into registers must be _physical_ addresses, * not logical addresses (which may differ if paging is active). * @@ -53,7 +53,7 @@ * | ... | | ... | | ... | * | ... | | ... | | ... | * | ... | | ... | | ... | - * P7 ... P0 A7 ... A0 A7 ... A0 + * P7 ... P0 A7 ... A0 A7 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Address mapping for channels 5-7: @@ -62,7 +62,7 @@ * | ... | \ \ ... \ \ \ ... \ \ * | ... | \ \ ... \ \ \ ... \ (not used) * | ... | \ \ ... \ \ \ ... \ - * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 + * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 * | Page | Addr MSB | Addr LSB | (DMA registers) * * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses @@ -71,7 +71,7 @@ * * Transfer count (_not # bytes_) is limited to 64K, represented as actual * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, - * and up to 128K bytes may be transferred on channels 5-7 in one operation. + * and up to 128K bytes may be transferred on channels 5-7 in one operation. * */ @@ -83,7 +83,13 @@ * Deskstations or Acer PICA but not the much more versatile DMA logic used * for the local devices on Acer PICA or Magnums. */ +#ifdef CONFIG_SGI_IP22 +/* Horrible hack to have a correct DMA window on IP22 */ +#include <asm/sgi/mc.h> +#define MAX_DMA_ADDRESS (PAGE_OFFSET + SGIMC_SEG0_BADDR + 0x01000000) +#else #define MAX_DMA_ADDRESS (PAGE_OFFSET + 0x01000000) +#endif /* 8237 DMA controllers */ #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ @@ -142,6 +148,7 @@ #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ +#define DMA_AUTOINIT 0x10 extern spinlock_t dma_spin_lock; @@ -247,7 +254,7 @@ } -/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for +/* Set transfer size (max 64k for DMA0..3, 128k for DMA5..7) for * a specific DMA channel. * You must ensure the parameters are valid. * NOTE: from a manual: "the number of transfers is one more @@ -286,7 +293,7 @@ count = 1 + dma_inb(io_port); count += dma_inb(io_port) << 8; - + return (dmanr<=3)? count : (count<<1); } diff -Nru a/include/asm-mips64/elf.h b/include/asm-mips64/elf.h --- a/include/asm-mips64/elf.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/elf.h Fri Jun 27 14:19:52 2003 @@ -3,19 +3,38 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#ifndef _ASM_ELF_H -#define _ASM_ELF_H +#ifndef __ASM_ELF_H +#define __ASM_ELF_H #include <asm/ptrace.h> #include <asm/user.h> +/* ELF header e_flags defines. */ +/* MIPS architecture level. */ +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ + +/* The ABI of a file. */ +#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */ +#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ + #define PT_MIPS_REGINFO 0x70000000 +#define PT_MIPS_OPTIONS 0x70000001 /* Flags in the e_flags field of the header */ -#define EF_MIPS_NOREORDER 0x00000001 -#define EF_MIPS_PIC 0x00000002 -#define EF_MIPS_CPIC 0x00000004 -#define EF_MIPS_ARCH 0xf0000000 +#define EF_MIPS_NOREORDER 0x00000001 +#define EF_MIPS_PIC 0x00000002 +#define EF_MIPS_CPIC 0x00000004 +#define EF_MIPS_ABI2 0x00000020 +#define EF_MIPS_OPTIONS_FIRST 0x00000080 +#define EF_MIPS_32BITMODE 0x00000100 +#define EF_MIPS_ABI 0x0000f000 +#define EF_MIPS_ARCH 0xf0000000 #define DT_MIPS_RLD_VERSION 0x70000001 #define DT_MIPS_TIME_STAMP 0x70000002 @@ -106,8 +125,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; /* - * This is used to ensure we don't load something for the wrong - * architecture or OS. + * This is used to ensure we don't load something for the wrong architecture. */ #define elf_check_arch(hdr) \ ({ \ @@ -116,9 +134,8 @@ \ if (__h->e_machine != EM_MIPS) \ __res = 0; \ - if (sizeof(elf_addr_t) == 8 && \ - __h->e_ident[EI_CLASS] == ELFCLASS32) \ - __res = 0; \ + if (__h->e_ident[EI_CLASS] == ELFCLASS32) \ + __res = 0; \ \ __res; \ }) @@ -183,10 +200,15 @@ #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) \ -do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ - current->thread.mflags |= MF_32BIT; \ - else \ - current->thread.mflags &= ~MF_32BIT; \ +do { current->thread.mflags &= ~MF_ABI_MASK; \ + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ + if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ + ((ex).e_flags & EF_MIPS_ABI) == 0) \ + current->thread.mflags |= MF_N32; \ + else \ + current->thread.mflags |= MF_O32; \ + } else \ + current->thread.mflags |= MF_N64; \ if (ibcs2) \ set_personality(PER_SVR4); \ else if (current->personality != PER_LINUX32) \ @@ -194,4 +216,4 @@ } while (0) #endif -#endif /* _ASM_ELF_H */ +#endif /* __ASM_ELF_H */ diff -Nru a/include/asm-mips64/errno.h b/include/asm-mips64/errno.h --- a/include/asm-mips64/errno.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/errno.h Fri Jun 27 14:20:05 2003 @@ -3,8 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 2001 by Ralf Baechle - * Copyright (C) 2001 Silicon Graphics, Inc. + * Copyright (C) 1995, 1999, 2001, 2002 by Ralf Baechle */ #ifndef _ASM_ERRNO_H #define _ASM_ERRNO_H diff -Nru a/include/asm-mips64/exception.h b/include/asm-mips64/exception.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/exception.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,76 @@ +/* + * 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 - 1999 by Ralf Baechle + * Copyright (C) 1999 Silicon Graphics + * + * Low level exception handling + */ +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/fpregdef.h> +#include <asm/mipsregs.h> +#include <asm/stackframe.h> + + .macro __build_clear_none + .endm + + .macro __build_clear_sti + STI + .endm + + .macro __build_clear_cli + CLI + .endm + + .macro __build_clear_fpe + cfc1 a1, fcr31 + li a2, ~(0x3f << 12) + and a2, a1 + ctc1 a2, fcr31 + STI + .endm + + .macro __build_clear_ade + dmfc0 t0, CP0_BADVADDR + sd t0, PT_BVADDR(sp) + KMODE + .endm + + .macro __BUILD_silent exception + .endm + + /* Gas tries to parse the PRINT argument as a string containing + string escapes and emits bogus warnings if it believes to + recognize an unknown escape code. So make the arguments + start with an n and gas will believe \n is ok ... */ + .macro __BUILD_verbose nexception + ld a1, PT_EPC(sp) + PRINT("Got \nexception at %016lx\012") + .endm + + .macro __BUILD_count exception + .set reorder + ld t0,exception_count_\exception + daddiu t0, 1 + sd t0,exception_count_\exception + .set noreorder + .comm exception_count\exception, 8, 8 + .endm + + .macro BUILD_HANDLER exception handler clear verbose + .align 5 + NESTED(handle_\exception, PT_SIZE, sp) + .set noat + SAVE_ALL + __BUILD_clear_\clear + .set at + __BUILD_\verbose \exception + move a0, sp + jal do_\handler + j ret_from_exception + nop + END(handle_\exception) + .endm diff -Nru a/include/asm-mips64/fcntl.h b/include/asm-mips64/fcntl.h --- a/include/asm-mips64/fcntl.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/fcntl.h Fri Jun 27 14:19:52 2003 @@ -22,8 +22,8 @@ #define O_EXCL 0x0400 /* not fcntl */ #define O_NOCTTY 0x0800 /* not fcntl */ #define FASYNC 0x1000 /* fcntl, for BSD compatibility */ -#define O_LARGEFILE 0x2000 /* allow large file opens - currently ignored */ -#define O_DIRECT 0x8000 /* direct disk access hint - currently ignored */ +#define O_LARGEFILE 0x2000 /* allow large file opens */ +#define O_DIRECT 0x8000 /* direct disk access hint */ #define O_DIRECTORY 0x10000 /* must be a directory */ #define O_NOFOLLOW 0x20000 /* don't follow links */ @@ -67,7 +67,7 @@ /* operations for bsd flock(), also used by the kernel implementation */ #define LOCK_SH 1 /* shared lock */ #define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* or'd with one of the above to prevent XXXXXXXXXXXXXXXXXX +#define LOCK_NB 4 /* or'd with one of the above to prevent blocking */ #define LOCK_UN 8 /* remove lock */ @@ -81,9 +81,7 @@ short l_whence; __kernel_off_t l_start; __kernel_off_t l_len; - long l_sysid; /* XXXXXXXXXXXXXXXXXXXXXXXXX */ __kernel_pid_t l_pid; - long pad[4]; /* ZZZZZZZZZZZZZZZZZZZZZZZZZZ */ } flock_t; #ifdef __KERNEL__ diff -Nru a/include/asm-mips64/floppy.h b/include/asm-mips64/floppy.h --- a/include/asm-mips64/floppy.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/floppy.h Fri Jun 27 14:19:54 2003 @@ -10,8 +10,6 @@ #ifndef _ASM_FLOPPY_H #define _ASM_FLOPPY_H -#include <asm/bootinfo.h> - struct fd_ops { unsigned char (*fd_inb)(unsigned int port); void (*fd_outb)(unsigned char value, unsigned int port); @@ -48,7 +46,7 @@ #define fd_clear_dma_ff() fd_ops->fd_clear_dma_ff(FLOPPY_DMA) #define fd_set_dma_mode(mode) fd_ops->fd_set_dma_mode(FLOPPY_DMA, mode) #define fd_set_dma_addr(addr) fd_ops->fd_set_dma_addr(FLOPPY_DMA, \ - virt_to_bus(addr)) + isa_virt_to_bus(addr)) #define fd_set_dma_count(count) fd_ops->fd_set_dma_count(FLOPPY_DMA,count) #define fd_get_dma_residue() fd_ops->fd_get_dma_residue(FLOPPY_DMA) @@ -61,7 +59,8 @@ #define fd_dma_mem_alloc(size) fd_ops->fd_dma_mem_alloc(size) #define fd_dma_mem_free(mem,size) fd_ops->fd_dma_mem_free(mem,size) #define fd_drive_type(n) fd_ops->fd_drive_type(n) -#define fd_cacheflush(addr,size) dma_cache_wback_inv(addr,size) +#define fd_cacheflush(addr,size) \ + dma_cache_wback_inv((unsigned long)(addr),(size)) #define MAX_BUFFER_SECTORS 24 diff -Nru a/include/asm-mips64/fpu.h b/include/asm-mips64/fpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/fpu.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * 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 _ASM_FPU_H +#define _ASM_FPU_H + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/thread_info.h> + +#include <asm/mipsregs.h> +#include <asm/cpu.h> +#include <asm/bitops.h> +#include <asm/processor.h> +#include <asm/current.h> + +struct sigcontext; + +extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); +extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); + +extern void fpu_emulator_init_fpu(void); +extern void _init_fpu(void); +extern void _save_fp(struct task_struct *); +extern void _restore_fp(struct task_struct *); + +#if defined(CONFIG_CPU_SB1) +#define __enable_fpu_hazard() \ +do { \ + asm(".set push \n\t" \ + ".set mips64 \n\t" \ + ".set noreorder \n\t" \ + "ssnop \n\t" \ + "bnezl $0, .+4 \n\t" \ + "ssnop \n\t" \ + ".set pop"); \ +} while (0) +#else +#define __enable_fpu_hazard() \ +do { \ + asm("nop;nop;nop;nop"); /* max. hazard */ \ +} while (0) +#endif + +#define __enable_fpu() \ +do { \ + set_c0_status(ST0_CU1); \ + __enable_fpu_hazard(); \ +} while (0) + +#define __disable_fpu() \ +do { \ + clear_c0_status(ST0_CU1); \ + /* We don't care about the c0 hazard here */ \ +} while (0) + +#define enable_fpu() \ +do { \ + if (cpu_has_fpu) \ + __enable_fpu(); \ +} while (0) + +#define disable_fpu() \ +do { \ + if (cpu_has_fpu) \ + __disable_fpu(); \ +} while (0) + + +#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) + +static inline int is_fpu_owner(void) +{ + return cpu_has_fpu && test_thread_flag(TIF_USEDFPU); +} + +static inline void own_fpu(void) +{ + if (cpu_has_fpu) { + __enable_fpu(); + KSTK_STATUS(current) |= ST0_CU1; + set_thread_flag(TIF_USEDFPU); + } +} + +static inline void loose_fpu(void) +{ + if (cpu_has_fpu) { + KSTK_STATUS(current) &= ~ST0_CU1; + clear_thread_flag(TIF_USEDFPU); + __disable_fpu(); + } +} + +static inline void init_fpu(void) +{ + if (cpu_has_fpu) { + _init_fpu(); + } else { + fpu_emulator_init_fpu(); + } +} + +static inline void save_fp(struct task_struct *tsk) +{ + if (cpu_has_fpu) + _save_fp(tsk); +} + +static inline void restore_fp(struct task_struct *tsk) +{ + if (cpu_has_fpu) + _restore_fp(tsk); +} + +static inline unsigned long *get_fpu_regs(struct task_struct *tsk) +{ + if (cpu_has_fpu) { + if ((tsk == current) && is_fpu_owner()) + _save_fp(current); + return (unsigned long *)&tsk->thread.fpu.hard.fp_regs[0]; + } else { + return (unsigned long *)tsk->thread.fpu.soft.regs; + } +} + +#endif /* _ASM_FPU_H */ diff -Nru a/include/asm-mips64/fpu_emulator.h b/include/asm-mips64/fpu_emulator.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/fpu_emulator.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,38 @@ +/* + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Further private data for which no space exists in mips_fpu_soft_struct. + * This should be subsumed into the mips_fpu_soft_struct structure as + * defined in processor.h as soon as the absurd wired absolute assembler + * offsets become dynamic at compile time. + * + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + */ +#ifndef _ASM_FPU_EMULATOR_H +#define _ASM_FPU_EMULATOR_H + +struct mips_fpu_emulator_private { + unsigned int eir; + struct { + unsigned int emulated; + unsigned int loads; + unsigned int stores; + unsigned int cp1ops; + unsigned int cp1xops; + unsigned int errors; + } stats; +}; + +#endif /* _ASM_FPU_EMULATOR_H */ diff -Nru a/include/asm-mips64/gdb-stub.h b/include/asm-mips64/gdb-stub.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/gdb-stub.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,212 @@ +/* + * 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) 1995 Andreas Busse + */ +#ifndef __ASM_MIPS_GDB_STUB_H +#define __ASM_MIPS_GDB_STUB_H + + +/* + * important register numbers + */ + +#define REG_EPC 37 +#define REG_FP 72 +#define REG_SP 29 + +/* + * Stack layout for the GDB exception handler + * Derived from the stack layout described in asm-mips/stackframe.h + * + * The first PTRSIZE*5 bytes are argument save space for C subroutines. + */ +#define NUMREGS 90 + +#define GDB_FR_REG0 (PTRSIZE*5) /* 0 */ +#define GDB_FR_REG1 ((GDB_FR_REG0) + 4) /* 1 */ +#define GDB_FR_REG2 ((GDB_FR_REG1) + 4) /* 2 */ +#define GDB_FR_REG3 ((GDB_FR_REG2) + 4) /* 3 */ +#define GDB_FR_REG4 ((GDB_FR_REG3) + 4) /* 4 */ +#define GDB_FR_REG5 ((GDB_FR_REG4) + 4) /* 5 */ +#define GDB_FR_REG6 ((GDB_FR_REG5) + 4) /* 6 */ +#define GDB_FR_REG7 ((GDB_FR_REG6) + 4) /* 7 */ +#define GDB_FR_REG8 ((GDB_FR_REG7) + 4) /* 8 */ +#define GDB_FR_REG9 ((GDB_FR_REG8) + 4) /* 9 */ +#define GDB_FR_REG10 ((GDB_FR_REG9) + 4) /* 10 */ +#define GDB_FR_REG11 ((GDB_FR_REG10) + 4) /* 11 */ +#define GDB_FR_REG12 ((GDB_FR_REG11) + 4) /* 12 */ +#define GDB_FR_REG13 ((GDB_FR_REG12) + 4) /* 13 */ +#define GDB_FR_REG14 ((GDB_FR_REG13) + 4) /* 14 */ +#define GDB_FR_REG15 ((GDB_FR_REG14) + 4) /* 15 */ +#define GDB_FR_REG16 ((GDB_FR_REG15) + 4) /* 16 */ +#define GDB_FR_REG17 ((GDB_FR_REG16) + 4) /* 17 */ +#define GDB_FR_REG18 ((GDB_FR_REG17) + 4) /* 18 */ +#define GDB_FR_REG19 ((GDB_FR_REG18) + 4) /* 19 */ +#define GDB_FR_REG20 ((GDB_FR_REG19) + 4) /* 20 */ +#define GDB_FR_REG21 ((GDB_FR_REG20) + 4) /* 21 */ +#define GDB_FR_REG22 ((GDB_FR_REG21) + 4) /* 22 */ +#define GDB_FR_REG23 ((GDB_FR_REG22) + 4) /* 23 */ +#define GDB_FR_REG24 ((GDB_FR_REG23) + 4) /* 24 */ +#define GDB_FR_REG25 ((GDB_FR_REG24) + 4) /* 25 */ +#define GDB_FR_REG26 ((GDB_FR_REG25) + 4) /* 26 */ +#define GDB_FR_REG27 ((GDB_FR_REG26) + 4) /* 27 */ +#define GDB_FR_REG28 ((GDB_FR_REG27) + 4) /* 28 */ +#define GDB_FR_REG29 ((GDB_FR_REG28) + 4) /* 29 */ +#define GDB_FR_REG30 ((GDB_FR_REG29) + 4) /* 30 */ +#define GDB_FR_REG31 ((GDB_FR_REG30) + 4) /* 31 */ + +/* + * Saved special registers + */ +#define GDB_FR_STATUS ((GDB_FR_REG31) + 4) /* 32 */ +#define GDB_FR_LO ((GDB_FR_STATUS) + 4) /* 33 */ +#define GDB_FR_HI ((GDB_FR_LO) + 4) /* 34 */ +#define GDB_FR_BADVADDR ((GDB_FR_HI) + 4) /* 35 */ +#define GDB_FR_CAUSE ((GDB_FR_BADVADDR) + 4) /* 36 */ +#define GDB_FR_EPC ((GDB_FR_CAUSE) + 4) /* 37 */ + +/* + * Saved floating point registers + */ +#define GDB_FR_FPR0 ((GDB_FR_EPC) + 4) /* 38 */ +#define GDB_FR_FPR1 ((GDB_FR_FPR0) + 4) /* 39 */ +#define GDB_FR_FPR2 ((GDB_FR_FPR1) + 4) /* 40 */ +#define GDB_FR_FPR3 ((GDB_FR_FPR2) + 4) /* 41 */ +#define GDB_FR_FPR4 ((GDB_FR_FPR3) + 4) /* 42 */ +#define GDB_FR_FPR5 ((GDB_FR_FPR4) + 4) /* 43 */ +#define GDB_FR_FPR6 ((GDB_FR_FPR5) + 4) /* 44 */ +#define GDB_FR_FPR7 ((GDB_FR_FPR6) + 4) /* 45 */ +#define GDB_FR_FPR8 ((GDB_FR_FPR7) + 4) /* 46 */ +#define GDB_FR_FPR9 ((GDB_FR_FPR8) + 4) /* 47 */ +#define GDB_FR_FPR10 ((GDB_FR_FPR9) + 4) /* 48 */ +#define GDB_FR_FPR11 ((GDB_FR_FPR10) + 4) /* 49 */ +#define GDB_FR_FPR12 ((GDB_FR_FPR11) + 4) /* 50 */ +#define GDB_FR_FPR13 ((GDB_FR_FPR12) + 4) /* 51 */ +#define GDB_FR_FPR14 ((GDB_FR_FPR13) + 4) /* 52 */ +#define GDB_FR_FPR15 ((GDB_FR_FPR14) + 4) /* 53 */ +#define GDB_FR_FPR16 ((GDB_FR_FPR15) + 4) /* 54 */ +#define GDB_FR_FPR17 ((GDB_FR_FPR16) + 4) /* 55 */ +#define GDB_FR_FPR18 ((GDB_FR_FPR17) + 4) /* 56 */ +#define GDB_FR_FPR19 ((GDB_FR_FPR18) + 4) /* 57 */ +#define GDB_FR_FPR20 ((GDB_FR_FPR19) + 4) /* 58 */ +#define GDB_FR_FPR21 ((GDB_FR_FPR20) + 4) /* 59 */ +#define GDB_FR_FPR22 ((GDB_FR_FPR21) + 4) /* 60 */ +#define GDB_FR_FPR23 ((GDB_FR_FPR22) + 4) /* 61 */ +#define GDB_FR_FPR24 ((GDB_FR_FPR23) + 4) /* 62 */ +#define GDB_FR_FPR25 ((GDB_FR_FPR24) + 4) /* 63 */ +#define GDB_FR_FPR26 ((GDB_FR_FPR25) + 4) /* 64 */ +#define GDB_FR_FPR27 ((GDB_FR_FPR26) + 4) /* 65 */ +#define GDB_FR_FPR28 ((GDB_FR_FPR27) + 4) /* 66 */ +#define GDB_FR_FPR29 ((GDB_FR_FPR28) + 4) /* 67 */ +#define GDB_FR_FPR30 ((GDB_FR_FPR29) + 4) /* 68 */ +#define GDB_FR_FPR31 ((GDB_FR_FPR30) + 4) /* 69 */ + +#define GDB_FR_FSR ((GDB_FR_FPR31) + 4) /* 70 */ +#define GDB_FR_FIR ((GDB_FR_FSR) + 4) /* 71 */ +#define GDB_FR_FRP ((GDB_FR_FIR) + 4) /* 72 */ + +#define GDB_FR_DUMMY ((GDB_FR_FRP) + 4) /* 73, unused ??? */ + +/* + * Again, CP0 registers + */ +#define GDB_FR_CP0_INDEX ((GDB_FR_DUMMY) + 4) /* 74 */ +#define GDB_FR_CP0_RANDOM ((GDB_FR_CP0_INDEX) + 4) /* 75 */ +#define GDB_FR_CP0_ENTRYLO0 ((GDB_FR_CP0_RANDOM) + 4) /* 76 */ +#define GDB_FR_CP0_ENTRYLO1 ((GDB_FR_CP0_ENTRYLO0) + 4) /* 77 */ +#define GDB_FR_CP0_CONTEXT ((GDB_FR_CP0_ENTRYLO1) + 4) /* 78 */ +#define GDB_FR_CP0_PAGEMASK ((GDB_FR_CP0_CONTEXT) + 4) /* 79 */ +#define GDB_FR_CP0_WIRED ((GDB_FR_CP0_PAGEMASK) + 4) /* 80 */ +#define GDB_FR_CP0_REG7 ((GDB_FR_CP0_WIRED) + 4) /* 81 */ +#define GDB_FR_CP0_REG8 ((GDB_FR_CP0_REG7) + 4) /* 82 */ +#define GDB_FR_CP0_REG9 ((GDB_FR_CP0_REG8) + 4) /* 83 */ +#define GDB_FR_CP0_ENTRYHI ((GDB_FR_CP0_REG9) + 4) /* 84 */ +#define GDB_FR_CP0_REG11 ((GDB_FR_CP0_ENTRYHI) + 4) /* 85 */ +#define GDB_FR_CP0_REG12 ((GDB_FR_CP0_REG11) + 4) /* 86 */ +#define GDB_FR_CP0_REG13 ((GDB_FR_CP0_REG12) + 4) /* 87 */ +#define GDB_FR_CP0_REG14 ((GDB_FR_CP0_REG13) + 4) /* 88 */ +#define GDB_FR_CP0_PRID ((GDB_FR_CP0_REG14) + 4) /* 89 */ + +#define GDB_FR_SIZE ((((GDB_FR_CP0_PRID) + 4) + (PTRSIZE-1)) & ~(PTRSIZE-1)) + +#ifndef __ASSEMBLY__ + +/* + * This is the same as above, but for the high-level + * part of the GDB stub. + */ + +struct gdb_regs { + /* + * Pad bytes for argument save space on the stack + * 20/40 Bytes for 32/64 bit code + */ + unsigned long pad0[5]; + + /* + * saved main processor registers + */ + long reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7; + long reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15; + long reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23; + long reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31; + + /* + * Saved special registers + */ + long cp0_status; + long lo; + long hi; + long cp0_badvaddr; + long cp0_cause; + long cp0_epc; + + /* + * Saved floating point registers + */ + long fpr0, fpr1, fpr2, fpr3, fpr4, fpr5, fpr6, fpr7; + long fpr8, fpr9, fpr10, fpr11, fpr12, fpr13, fpr14, fpr15; + long fpr16, fpr17, fpr18, fpr19, fpr20, fpr21, fpr22, fpr23; + long fpr24, fpr25, fpr26, fpr27, fpr28, fpr29, fpr30, fpr31; + + long cp1_fsr; + long cp1_fir; + + /* + * Frame pointer + */ + long frame_ptr; + long dummy; /* unused */ + + /* + * saved cp0 registers + */ + long cp0_index; + long cp0_random; + long cp0_entrylo0; + long cp0_entrylo1; + long cp0_context; + long cp0_pagemask; + long cp0_wired; + long cp0_reg7; + long cp0_reg8; + long cp0_reg9; + long cp0_entryhi; + long cp0_reg11; + long cp0_reg12; + long cp0_reg13; + long cp0_reg14; + long cp0_prid; +}; + +/* + * Prototypes + */ + +void set_debug_traps(void); + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_MIPS_GDB_STUB_H */ diff -Nru a/include/asm-mips64/gfx.h b/include/asm-mips64/gfx.h --- a/include/asm-mips64/gfx.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/gfx.h Fri Jun 27 14:19:53 2003 @@ -6,7 +6,7 @@ * This is the user-visible SGI GFX interface. * * This must be used verbatim into the GNU libc. It does not include - * any kernel-only bits on it. + * any kernel-only bits on it. * * miguel@nuclecu.unam.mx */ diff -Nru a/include/asm-mips64/gt64120.h b/include/asm-mips64/gt64120.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/gt64120.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,399 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + */ +#ifndef _ASM_GT64120_H +#define _ASM_GT64120_H + +#define MSK(n) ((1 << (n)) - 1) + +/* + * Register offset addresses + */ +#define GT_CPU_OFS 0x000 + +/* + * Interrupt Registers + */ +#define GT_SCS10LD_OFS 0x008 +#define GT_SCS10HD_OFS 0x010 +#define GT_SCS32LD_OFS 0x018 +#define GT_SCS32HD_OFS 0x020 +#define GT_CS20LD_OFS 0x028 +#define GT_CS20HD_OFS 0x030 +#define GT_CS3BOOTLD_OFS 0x038 +#define GT_CS3BOOTHD_OFS 0x040 +#define GT_PCI0IOLD_OFS 0x048 +#define GT_PCI0IOHD_OFS 0x050 +#define GT_PCI0M0LD_OFS 0x058 +#define GT_PCI0M0HD_OFS 0x060 +#define GT_ISD_OFS 0x068 +#define GT_PCI0M1LD_OFS 0x080 +#define GT_PCI0M1HD_OFS 0x088 +#define GT_PCI1IOLD_OFS 0x090 +#define GT_PCI1IOHD_OFS 0x098 +#define GT_PCI1M0LD_OFS 0x0a0 +#define GT_PCI1M0HD_OFS 0x0a8 +#define GT_PCI1M1LD_OFS 0x0b0 +#define GT_PCI1M1HD_OFS 0x0b8 + +/* + * GT64120A only + */ +#define GT_PCI0IOREMAP_OFS 0x0f0 +#define GT_PCI0M0REMAP_OFS 0x0f8 +#define GT_PCI0M1REMAP_OFS 0x100 +#define GT_PCI1IOREMAP_OFS 0x108 +#define GT_PCI1M0REMAP_OFS 0x110 +#define GT_PCI1M1REMAP_OFS 0x118 + +#define GT_SCS0LD_OFS 0x400 +#define GT_SCS0HD_OFS 0x404 +#define GT_SCS1LD_OFS 0x408 +#define GT_SCS1HD_OFS 0x40c +#define GT_SCS2LD_OFS 0x410 +#define GT_SCS2HD_OFS 0x414 +#define GT_SCS3LD_OFS 0x418 +#define GT_SCS3HD_OFS 0x41c +#define GT_CS0LD_OFS 0x420 +#define GT_CS0HD_OFS 0x424 +#define GT_CS1LD_OFS 0x428 +#define GT_CS1HD_OFS 0x42c +#define GT_CS2LD_OFS 0x430 +#define GT_CS2HD_OFS 0x434 +#define GT_CS3LD_OFS 0x438 +#define GT_CS3HD_OFS 0x43c +#define GT_BOOTLD_OFS 0x440 +#define GT_BOOTHD_OFS 0x444 + +#define GT_SDRAM_B0_OFS 0x44c +#define GT_SDRAM_CFG_OFS 0x448 +#define GT_SDRAM_B2_OFS 0x454 +#define GT_SDRAM_OPMODE_OFS 0x474 +#define GT_SDRAM_BM_OFS 0x478 +#define GT_SDRAM_ADDRDECODE_OFS 0x47c + +#define GT_PCI0_CMD_OFS 0xc00 /* GT64120A only */ +#define GT_PCI0_TOR_OFS 0xc04 +#define GT_PCI0_BS_SCS10_OFS 0xc08 +#define GT_PCI0_BS_SCS32_OFS 0xc0c +#define GT_INTRCAUSE_OFS 0xc18 +#define GT_INTRMASK_OFS 0xc1c /* GT64120A only */ +#define GT_PCI0_IACK_OFS 0xc34 +#define GT_PCI0_BARE_OFS 0xc3c +#define GT_HINTRCAUSE_OFS 0xc98 /* GT64120A only */ +#define GT_HINTRMASK_OFS 0xc9c /* GT64120A only */ +#define GT_PCI1_CFGADDR_OFS 0xcf0 /* GT64120A only */ +#define GT_PCI1_CFGDATA_OFS 0xcf4 /* GT64120A only */ +#define GT_PCI0_CFGADDR_OFS 0xcf8 +#define GT_PCI0_CFGDATA_OFS 0xcfc + + +/* + * Timer/Counter. GT64120A only. + */ +#define GT_TC0_OFS 0x850 +#define GT_TC1_OFS 0x854 +#define GT_TC2_OFS 0x858 +#define GT_TC3_OFS 0x85C +#define GT_TC_CONTROL_OFS 0x864 + +/* + * I2O Support Registers + */ +#define INBOUND_MESSAGE_REGISTER0_PCI_SIDE 0x010 +#define INBOUND_MESSAGE_REGISTER1_PCI_SIDE 0x014 +#define OUTBOUND_MESSAGE_REGISTER0_PCI_SIDE 0x018 +#define OUTBOUND_MESSAGE_REGISTER1_PCI_SIDE 0x01c +#define INBOUND_DOORBELL_REGISTER_PCI_SIDE 0x020 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE 0x024 +#define INBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE 0x028 +#define OUTBOUND_DOORBELL_REGISTER_PCI_SIDE 0x02c +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_PCI_SIDE 0x030 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_PCI_SIDE 0x034 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE 0x040 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_PCI_SIDE 0x044 +#define QUEUE_CONTROL_REGISTER_PCI_SIDE 0x050 +#define QUEUE_BASE_ADDRESS_REGISTER_PCI_SIDE 0x054 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE 0x060 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE 0x064 +#define INBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE 0x068 +#define INBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE 0x06c +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_PCI_SIDE 0x070 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_PCI_SIDE 0x074 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_PCI_SIDE 0x078 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_PCI_SIDE 0x07c + +#define INBOUND_MESSAGE_REGISTER0_CPU_SIDE 0x1c10 +#define INBOUND_MESSAGE_REGISTER1_CPU_SIDE 0x1c14 +#define OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE 0x1c18 +#define OUTBOUND_MESSAGE_REGISTER1_CPU_SIDE 0x1c1c +#define INBOUND_DOORBELL_REGISTER_CPU_SIDE 0x1c20 +#define INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE 0x1c24 +#define INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE 0x1c28 +#define OUTBOUND_DOORBELL_REGISTER_CPU_SIDE 0x1c2c +#define OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE 0x1c30 +#define OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE 0x1c34 +#define INBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE 0x1c40 +#define OUTBOUND_QUEUE_PORT_VIRTUAL_REGISTER_CPU_SIDE 0x1c44 +#define QUEUE_CONTROL_REGISTER_CPU_SIDE 0x1c50 +#define QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE 0x1c54 +#define INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c60 +#define INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c64 +#define INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c68 +#define INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c6c +#define OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c70 +#define OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c74 +#define OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE 0x1c78 +#define OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE 0x1c7c + +/* + * Register encodings + */ +#define GT_CPU_ENDIAN_SHF 12 +#define GT_CPU_ENDIAN_MSK (MSK(1) << GT_CPU_ENDIAN_SHF) +#define GT_CPU_ENDIAN_BIT GT_CPU_ENDIAN_MSK +#define GT_CPU_WR_SHF 16 +#define GT_CPU_WR_MSK (MSK(1) << GT_CPU_WR_SHF) +#define GT_CPU_WR_BIT GT_CPU_WR_MSK +#define GT_CPU_WR_DXDXDXDX 0 +#define GT_CPU_WR_DDDD 1 + + +#define GT_CFGADDR_CFGEN_SHF 31 +#define GT_CFGADDR_CFGEN_MSK (MSK(1) << GT_CFGADDR_CFGEN_SHF) +#define GT_CFGADDR_CFGEN_BIT GT_CFGADDR_CFGEN_MSK + +#define GT_CFGADDR_BUSNUM_SHF 16 +#define GT_CFGADDR_BUSNUM_MSK (MSK(8) << GT_CFGADDR_BUSNUM_SHF) + +#define GT_CFGADDR_DEVNUM_SHF 11 +#define GT_CFGADDR_DEVNUM_MSK (MSK(5) << GT_CFGADDR_DEVNUM_SHF) + +#define GT_CFGADDR_FUNCNUM_SHF 8 +#define GT_CFGADDR_FUNCNUM_MSK (MSK(3) << GT_CFGADDR_FUNCNUM_SHF) + +#define GT_CFGADDR_REGNUM_SHF 2 +#define GT_CFGADDR_REGNUM_MSK (MSK(6) << GT_CFGADDR_REGNUM_SHF) + + +#define GT_SDRAM_BM_ORDER_SHF 2 +#define GT_SDRAM_BM_ORDER_MSK (MSK(1) << GT_SDRAM_BM_ORDER_SHF) +#define GT_SDRAM_BM_ORDER_BIT GT_SDRAM_BM_ORDER_MSK +#define GT_SDRAM_BM_ORDER_SUB 1 +#define GT_SDRAM_BM_ORDER_LIN 0 + +#define GT_SDRAM_BM_RSVD_ALL1 0xffb + + +#define GT_SDRAM_ADDRDECODE_ADDR_SHF 0 +#define GT_SDRAM_ADDRDECODE_ADDR_MSK (MSK(3) << GT_SDRAM_ADDRDECODE_ADDR_SHF) +#define GT_SDRAM_ADDRDECODE_ADDR_0 0 +#define GT_SDRAM_ADDRDECODE_ADDR_1 1 +#define GT_SDRAM_ADDRDECODE_ADDR_2 2 +#define GT_SDRAM_ADDRDECODE_ADDR_3 3 +#define GT_SDRAM_ADDRDECODE_ADDR_4 4 +#define GT_SDRAM_ADDRDECODE_ADDR_5 5 +#define GT_SDRAM_ADDRDECODE_ADDR_6 6 +#define GT_SDRAM_ADDRDECODE_ADDR_7 7 + + +#define GT_SDRAM_B0_CASLAT_SHF 0 +#define GT_SDRAM_B0_CASLAT_MSK (MSK(2) << GT_SDRAM_B0__SHF) +#define GT_SDRAM_B0_CASLAT_2 1 +#define GT_SDRAM_B0_CASLAT_3 2 + +#define GT_SDRAM_B0_FTDIS_SHF 2 +#define GT_SDRAM_B0_FTDIS_MSK (MSK(1) << GT_SDRAM_B0_FTDIS_SHF) +#define GT_SDRAM_B0_FTDIS_BIT GT_SDRAM_B0_FTDIS_MSK + +#define GT_SDRAM_B0_SRASPRCHG_SHF 3 +#define GT_SDRAM_B0_SRASPRCHG_MSK (MSK(1) << GT_SDRAM_B0_SRASPRCHG_SHF) +#define GT_SDRAM_B0_SRASPRCHG_BIT GT_SDRAM_B0_SRASPRCHG_MSK +#define GT_SDRAM_B0_SRASPRCHG_2 0 +#define GT_SDRAM_B0_SRASPRCHG_3 1 + +#define GT_SDRAM_B0_B0COMPAB_SHF 4 +#define GT_SDRAM_B0_B0COMPAB_MSK (MSK(1) << GT_SDRAM_B0_B0COMPAB_SHF) +#define GT_SDRAM_B0_B0COMPAB_BIT GT_SDRAM_B0_B0COMPAB_MSK + +#define GT_SDRAM_B0_64BITINT_SHF 5 +#define GT_SDRAM_B0_64BITINT_MSK (MSK(1) << GT_SDRAM_B0_64BITINT_SHF) +#define GT_SDRAM_B0_64BITINT_BIT GT_SDRAM_B0_64BITINT_MSK +#define GT_SDRAM_B0_64BITINT_2 0 +#define GT_SDRAM_B0_64BITINT_4 1 + +#define GT_SDRAM_B0_BW_SHF 6 +#define GT_SDRAM_B0_BW_MSK (MSK(1) << GT_SDRAM_B0_BW_SHF) +#define GT_SDRAM_B0_BW_BIT GT_SDRAM_B0_BW_MSK +#define GT_SDRAM_B0_BW_32 0 +#define GT_SDRAM_B0_BW_64 1 + +#define GT_SDRAM_B0_BLODD_SHF 7 +#define GT_SDRAM_B0_BLODD_MSK (MSK(1) << GT_SDRAM_B0_BLODD_SHF) +#define GT_SDRAM_B0_BLODD_BIT GT_SDRAM_B0_BLODD_MSK + +#define GT_SDRAM_B0_PAR_SHF 8 +#define GT_SDRAM_B0_PAR_MSK (MSK(1) << GT_SDRAM_B0_PAR_SHF) +#define GT_SDRAM_B0_PAR_BIT GT_SDRAM_B0_PAR_MSK + +#define GT_SDRAM_B0_BYPASS_SHF 9 +#define GT_SDRAM_B0_BYPASS_MSK (MSK(1) << GT_SDRAM_B0_BYPASS_SHF) +#define GT_SDRAM_B0_BYPASS_BIT GT_SDRAM_B0_BYPASS_MSK + +#define GT_SDRAM_B0_SRAS2SCAS_SHF 10 +#define GT_SDRAM_B0_SRAS2SCAS_MSK (MSK(1) << GT_SDRAM_B0_SRAS2SCAS_SHF) +#define GT_SDRAM_B0_SRAS2SCAS_BIT GT_SDRAM_B0_SRAS2SCAS_MSK +#define GT_SDRAM_B0_SRAS2SCAS_2 0 +#define GT_SDRAM_B0_SRAS2SCAS_3 1 + +#define GT_SDRAM_B0_SIZE_SHF 11 +#define GT_SDRAM_B0_SIZE_MSK (MSK(1) << GT_SDRAM_B0_SIZE_SHF) +#define GT_SDRAM_B0_SIZE_BIT GT_SDRAM_B0_SIZE_MSK +#define GT_SDRAM_B0_SIZE_16M 0 +#define GT_SDRAM_B0_SIZE_64M 1 + +#define GT_SDRAM_B0_EXTPAR_SHF 12 +#define GT_SDRAM_B0_EXTPAR_MSK (MSK(1) << GT_SDRAM_B0_EXTPAR_SHF) +#define GT_SDRAM_B0_EXTPAR_BIT GT_SDRAM_B0_EXTPAR_MSK + +#define GT_SDRAM_B0_BLEN_SHF 13 +#define GT_SDRAM_B0_BLEN_MSK (MSK(1) << GT_SDRAM_B0_BLEN_SHF) +#define GT_SDRAM_B0_BLEN_BIT GT_SDRAM_B0_BLEN_MSK +#define GT_SDRAM_B0_BLEN_8 0 +#define GT_SDRAM_B0_BLEN_4 1 + + +#define GT_SDRAM_CFG_REFINT_SHF 0 +#define GT_SDRAM_CFG_REFINT_MSK (MSK(14) << GT_SDRAM_CFG_REFINT_SHF) + +#define GT_SDRAM_CFG_NINTERLEAVE_SHF 14 +#define GT_SDRAM_CFG_NINTERLEAVE_MSK (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF) +#define GT_SDRAM_CFG_NINTERLEAVE_BIT GT_SDRAM_CFG_NINTERLEAVE_MSK + +#define GT_SDRAM_CFG_RMW_SHF 15 +#define GT_SDRAM_CFG_RMW_MSK (MSK(1) << GT_SDRAM_CFG_RMW_SHF) +#define GT_SDRAM_CFG_RMW_BIT GT_SDRAM_CFG_RMW_MSK + +#define GT_SDRAM_CFG_NONSTAGREF_SHF 16 +#define GT_SDRAM_CFG_NONSTAGREF_MSK (MSK(1) << GT_SDRAM_CFG_NONSTAGREF_SHF) +#define GT_SDRAM_CFG_NONSTAGREF_BIT GT_SDRAM_CFG_NONSTAGREF_MSK + +#define GT_SDRAM_CFG_DUPCNTL_SHF 19 +#define GT_SDRAM_CFG_DUPCNTL_MSK (MSK(1) << GT_SDRAM_CFG_DUPCNTL_SHF) +#define GT_SDRAM_CFG_DUPCNTL_BIT GT_SDRAM_CFG_DUPCNTL_MSK + +#define GT_SDRAM_CFG_DUPBA_SHF 20 +#define GT_SDRAM_CFG_DUPBA_MSK (MSK(1) << GT_SDRAM_CFG_DUPBA_SHF) +#define GT_SDRAM_CFG_DUPBA_BIT GT_SDRAM_CFG_DUPBA_MSK + +#define GT_SDRAM_CFG_DUPEOT0_SHF 21 +#define GT_SDRAM_CFG_DUPEOT0_MSK (MSK(1) << GT_SDRAM_CFG_DUPEOT0_SHF) +#define GT_SDRAM_CFG_DUPEOT0_BIT GT_SDRAM_CFG_DUPEOT0_MSK + +#define GT_SDRAM_CFG_DUPEOT1_SHF 22 +#define GT_SDRAM_CFG_DUPEOT1_MSK (MSK(1) << GT_SDRAM_CFG_DUPEOT1_SHF) +#define GT_SDRAM_CFG_DUPEOT1_BIT GT_SDRAM_CFG_DUPEOT1_MSK + +#define GT_SDRAM_OPMODE_OP_SHF 0 +#define GT_SDRAM_OPMODE_OP_MSK (MSK(3) << GT_SDRAM_OPMODE_OP_SHF) +#define GT_SDRAM_OPMODE_OP_NORMAL 0 +#define GT_SDRAM_OPMODE_OP_NOP 1 +#define GT_SDRAM_OPMODE_OP_PRCHG 2 +#define GT_SDRAM_OPMODE_OP_MODE 3 +#define GT_SDRAM_OPMODE_OP_CBR 4 + + +#define GT_PCI0_BARE_SWSCS3BOOTDIS_SHF 0 +#define GT_PCI0_BARE_SWSCS3BOOTDIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS3BOOTDIS_SHF) +#define GT_PCI0_BARE_SWSCS3BOOTDIS_BIT GT_PCI0_BARE_SWSCS3BOOTDIS_MSK + +#define GT_PCI0_BARE_SWSCS32DIS_SHF 1 +#define GT_PCI0_BARE_SWSCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF) +#define GT_PCI0_BARE_SWSCS32DIS_BIT GT_PCI0_BARE_SWSCS32DIS_MSK + +#define GT_PCI0_BARE_SWSCS10DIS_SHF 2 +#define GT_PCI0_BARE_SWSCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF) +#define GT_PCI0_BARE_SWSCS10DIS_BIT GT_PCI0_BARE_SWSCS10DIS_MSK + +#define GT_PCI0_BARE_INTIODIS_SHF 3 +#define GT_PCI0_BARE_INTIODIS_MSK (MSK(1) << GT_PCI0_BARE_INTIODIS_SHF) +#define GT_PCI0_BARE_INTIODIS_BIT GT_PCI0_BARE_INTIODIS_MSK + +#define GT_PCI0_BARE_INTMEMDIS_SHF 4 +#define GT_PCI0_BARE_INTMEMDIS_MSK (MSK(1) << GT_PCI0_BARE_INTMEMDIS_SHF) +#define GT_PCI0_BARE_INTMEMDIS_BIT GT_PCI0_BARE_INTMEMDIS_MSK + +#define GT_PCI0_BARE_CS3BOOTDIS_SHF 5 +#define GT_PCI0_BARE_CS3BOOTDIS_MSK (MSK(1) << GT_PCI0_BARE_CS3BOOTDIS_SHF) +#define GT_PCI0_BARE_CS3BOOTDIS_BIT GT_PCI0_BARE_CS3BOOTDIS_MSK + +#define GT_PCI0_BARE_CS20DIS_SHF 6 +#define GT_PCI0_BARE_CS20DIS_MSK (MSK(1) << GT_PCI0_BARE_CS20DIS_SHF) +#define GT_PCI0_BARE_CS20DIS_BIT GT_PCI0_BARE_CS20DIS_MSK + +#define GT_PCI0_BARE_SCS32DIS_SHF 7 +#define GT_PCI0_BARE_SCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SCS32DIS_SHF) +#define GT_PCI0_BARE_SCS32DIS_BIT GT_PCI0_BARE_SCS32DIS_MSK + +#define GT_PCI0_BARE_SCS10DIS_SHF 8 +#define GT_PCI0_BARE_SCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SCS10DIS_SHF) +#define GT_PCI0_BARE_SCS10DIS_BIT GT_PCI0_BARE_SCS10DIS_MSK + + +#define GT_INTRCAUSE_MASABORT0_SHF 18 +#define GT_INTRCAUSE_MASABORT0_MSK (MSK(1) << GT_INTRCAUSE_MASABORT0_SHF) +#define GT_INTRCAUSE_MASABORT0_BIT GT_INTRCAUSE_MASABORT0_MSK + +#define GT_INTRCAUSE_TARABORT0_SHF 19 +#define GT_INTRCAUSE_TARABORT0_MSK (MSK(1) << GT_INTRCAUSE_TARABORT0_SHF) +#define GT_INTRCAUSE_TARABORT0_BIT GT_INTRCAUSE_TARABORT0_MSK + + +#define GT_PCI0_CFGADDR_REGNUM_SHF 2 +#define GT_PCI0_CFGADDR_REGNUM_MSK (MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF) +#define GT_PCI0_CFGADDR_FUNCTNUM_SHF 8 +#define GT_PCI0_CFGADDR_FUNCTNUM_MSK (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF) +#define GT_PCI0_CFGADDR_DEVNUM_SHF 11 +#define GT_PCI0_CFGADDR_DEVNUM_MSK (MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF) +#define GT_PCI0_CFGADDR_BUSNUM_SHF 16 +#define GT_PCI0_CFGADDR_BUSNUM_MSK (MSK(8) << GT_PCI0_CFGADDR_BUSNUM_SHF) +#define GT_PCI0_CFGADDR_CONFIGEN_SHF 31 +#define GT_PCI0_CFGADDR_CONFIGEN_MSK (MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF) +#define GT_PCI0_CFGADDR_CONFIGEN_BIT GT_PCI0_CFGADDR_CONFIGEN_MSK + +#define GT_PCI0_CMD_MBYTESWAP_SHF 0 +#define GT_PCI0_CMD_MBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF) +#define GT_PCI0_CMD_MBYTESWAP_BIT GT_PCI0_CMD_MBYTESWAP_MSK +#define GT_PCI0_CMD_MWORDSWAP_SHF 10 +#define GT_PCI0_CMD_MWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF) +#define GT_PCI0_CMD_MWORDSWAP_BIT GT_PCI0_CMD_MWORDSWAP_MSK +#define GT_PCI0_CMD_SBYTESWAP_SHF 16 +#define GT_PCI0_CMD_SBYTESWAP_MSK (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF) +#define GT_PCI0_CMD_SBYTESWAP_BIT GT_PCI0_CMD_SBYTESWAP_MSK +#define GT_PCI0_CMD_SWORDSWAP_SHF 11 +#define GT_PCI0_CMD_SWORDSWAP_MSK (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF) +#define GT_PCI0_CMD_SWORDSWAP_BIT GT_PCI0_CMD_SWORDSWAP_MSK + +/* + * Misc + */ +#define GT_DEF_BASE 0x14000000 +#define GT_DEF_PCI0_MEM0_BASE 0x12000000 +#define GT_MAX_BANKSIZE (256 * 1024 * 1024) /* Max 256MB bank */ +#define GT_LATTIM_MIN 6 /* Minimum lat */ + +#endif /* _ASM_GT64120_H */ diff -Nru a/include/asm-mips64/hardirq.h b/include/asm-mips64/hardirq.h --- a/include/asm-mips64/hardirq.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/hardirq.h Fri Jun 27 14:19:55 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1997 - 2000, 2001 by Ralf Baechle + * Copyright (C) 1997, 1998, 1999, 2000, 2001 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 MIPS Technologies, Inc. */ @@ -16,8 +16,6 @@ typedef struct { unsigned int __softirq_pending; - unsigned int __local_irq_count; - unsigned int __local_bh_count; unsigned int __syscall_count; struct task_struct * __ksoftirqd_task; /* waitqueue is too large */ } ____cacheline_aligned irq_cpustat_t; @@ -25,73 +23,83 @@ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ /* - * Are we in an interrupt context? Either doing bottom half - * or hardware interrupt processing? + * We put the hardirq and softirq counter into the preemption + * counter. The bitmask has the following meaning: + * + * - bits 0-7 are the preemption count (max preemption depth: 256) + * - bits 8-15 are the softirq count (max # of softirqs: 256) + * - bits 16-23 are the hardirq count (max # of hardirqs: 256) + * + * - ( bit 26 is the PREEMPT_ACTIVE flag. ) + * + * PREEMPT_MASK: 0x000000ff + * SOFTIRQ_MASK: 0x0000ff00 + * HARDIRQ_MASK: 0x00ff0000 */ -#define in_interrupt() ({ int __cpu = smp_processor_id(); \ - (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }) -#define in_irq() (local_irq_count(smp_processor_id()) != 0) -#ifndef CONFIG_SMP - -#define hardirq_trylock(cpu) (local_irq_count(cpu) == 0) -#define hardirq_endlock(cpu) do { } while (0) - -#define irq_enter(cpu, irq) (local_irq_count(cpu)++) -#define irq_exit(cpu, irq) (local_irq_count(cpu)--) +#define PREEMPT_BITS 8 +#define SOFTIRQ_BITS 8 +#define HARDIRQ_BITS 8 + +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) + +#define __MASK(x) ((1UL << (x))-1) + +#define PREEMPT_MASK (__MASK(PREEMPT_BITS) << PREEMPT_SHIFT) +#define HARDIRQ_MASK (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) +#define SOFTIRQ_MASK (__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) + +#define hardirq_count() (preempt_count() & HARDIRQ_MASK) +#define softirq_count() (preempt_count() & SOFTIRQ_MASK) +#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) + +#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) +#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) +#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) -#define synchronize_irq() barrier(); +/* + * The hardirq mask has to be large enough to have + * space for potentially all IRQ sources in the system + * nesting on a single CPU: + */ +#if (1 << HARDIRQ_BITS) < NR_IRQS +# error HARDIRQ_BITS is too low! +#endif +/* + * Are we doing bottom half or hardware interrupt processing? + * Are we in a softirq context? Interrupt context? + */ +#define in_irq() (hardirq_count()) +#define in_softirq() (softirq_count()) +#define in_interrupt() (irq_count()) + +#define hardirq_trylock() (!in_interrupt()) +#define hardirq_endlock() do { } while (0) + +#define irq_enter() (preempt_count() += HARDIRQ_OFFSET) + +#if CONFIG_PREEMPT +# define in_atomic() (preempt_count() != kernel_locked()) +# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) #else +# define in_atomic() (preempt_count() != 0) +# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET +#endif +#define irq_exit() \ +do { \ + preempt_count() -= IRQ_EXIT_OFFSET; \ + if (!in_interrupt() && softirq_pending(smp_processor_id())) \ + do_softirq(); \ + preempt_enable_no_resched(); \ +} while (0) -#include <asm/atomic.h> -#include <linux/spinlock.h> -#include <asm/smp.h> - -extern int global_irq_holder; -extern spinlock_t global_irq_lock; - -static inline int irqs_running (void) -{ - int i; - - for (i = 0; i < smp_num_cpus; i++) - if (local_irq_count(i)) - return 1; - return 0; -} - -static inline void release_irqlock(int cpu) -{ - /* if we didn't own the irq lock, just ignore.. */ - if (global_irq_holder == cpu) { - global_irq_holder = NO_PROC_ID; - spin_unlock(&global_irq_lock); - } -} - -static inline int hardirq_trylock(int cpu) -{ - return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock); -} - -#define hardirq_endlock(cpu) do { } while (0) - -static inline void irq_enter(int cpu, int irq) -{ - ++local_irq_count(cpu); - - while (spin_is_locked(&global_irq_lock)) - barrier(); -} - -static inline void irq_exit(int cpu, int irq) -{ - --local_irq_count(cpu); -} - -extern void synchronize_irq(void); - +#ifndef CONFIG_SMP +# define synchronize_irq(irq) barrier() +#else + extern void synchronize_irq(unsigned int irq); #endif /* CONFIG_SMP */ #endif /* _ASM_HARDIRQ_H */ diff -Nru a/include/asm-mips64/hw_irq.h b/include/asm-mips64/hw_irq.h --- a/include/asm-mips64/hw_irq.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/hw_irq.h Fri Jun 27 14:19:54 2003 @@ -1,5 +1,31 @@ -/* This exists merely to satisfy <linux/irq.h>. There is - nothing that would go here of general interest. +/* + * 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) 2000, 2001, 2002 by Ralf Baechle + */ +#ifndef __ASM_HW_IRQ_H +#define __ASM_HW_IRQ_H - Everything of consequence is in arch/alpha/kernel/irq_impl.h, - to be used only in arch/alpha/kernel/. */ +#include <linux/profile.h> +#include <asm/atomic.h> + +extern void mask_irq(unsigned int irq); +extern void unmask_irq(unsigned int irq); +extern void disable_8259A_irq(unsigned int irq); +extern void enable_8259A_irq(unsigned int irq); +extern int i8259A_irq_pending(unsigned int irq); +extern void make_8259A_irq(unsigned int irq); +extern void init_8259A(int aeoi); + +#include <asm/atomic.h> + +extern atomic_t irq_err_count; + +/* This may not be apropriate for all machines, we'll see ... */ +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) +{ +} + +#endif /* __ASM_HW_IRQ_H */ diff -Nru a/include/asm-mips64/i8259.h b/include/asm-mips64/i8259.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/i8259.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,23 @@ +/* + * include/asm-mips/i8259.h + * + * i8259A interrupt definitions. + * + * Copyright (C) 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS64_I8259_H +#define __ASM_MIPS64_I8259_H + +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/system.h> + +extern void init_i8259_irqs(void); + +#endif /* __ASM_MIPS64_I8259_H */ diff -Nru a/include/asm-mips64/ide.h b/include/asm-mips64/ide.h --- a/include/asm-mips64/ide.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/ide.h Fri Jun 27 14:19:52 2003 @@ -8,22 +8,20 @@ * Copyright (C) 1994-1996 Linus Torvalds & authors */ -/* - * This file contains the MIPS architecture specific IDE code. - */ - #ifndef __ASM_IDE_H #define __ASM_IDE_H #ifdef __KERNEL__ #include <linux/config.h> +#include <asm/byteorder.h> +#include <asm/io.h> #ifndef MAX_HWIFS # ifdef CONFIG_PCI -# define MAX_HWIFS 10 +#define MAX_HWIFS 10 # else -# define MAX_HWIFS 6 +#define MAX_HWIFS 6 # endif #endif @@ -61,10 +59,15 @@ for(index = 0; index < MAX_HWIFS; index++) { ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL); hw.irq = ide_default_irq(ide_default_io_base(index)); - ide_register_hw(&hw); + ide_register_hw(&hw, NULL); } #endif } + +#define __ide_mm_insw ide_insw +#define __ide_mm_insl ide_insl +#define __ide_mm_outsw ide_outsw +#define __ide_mm_outsl ide_outsl #endif /* __KERNEL__ */ diff -Nru a/include/asm-mips64/inst.h b/include/asm-mips64/inst.h --- a/include/asm-mips64/inst.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/inst.h Fri Jun 27 14:19:56 2003 @@ -1,11 +1,11 @@ /* + * Format of an instruction in memory. + * * 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. * - * Format of an instruction in memory. - * - * Copyright (C) 1996 by Ralf Baechle + * Copyright (C) 1996, 2000 by Ralf Baechle */ #ifndef _ASM_INST_H #define _ASM_INST_H @@ -21,7 +21,7 @@ cop0_op, cop1_op, cop2_op, cop1x_op, beql_op, bnel_op, blezl_op, bgtzl_op, daddi_op, daddiu_op, ldl_op, ldr_op, - major_1c_op, major_1d_op, major_1e_op, major_1f_op, + major_1c_op, jalx_op, major_1e_op, major_1f_op, lb_op, lh_op, lwl_op, lw_op, lbu_op, lhu_op, lwr_op, lwu_op, sb_op, sh_op, swl_op, sw_op, @@ -80,6 +80,13 @@ }; /* + * rt field of cop.bc_op opcodes + */ +enum bcop_op { + bcf_op, bct_op, bcfl_op, bctl_op +}; + +/* * func field of cop0 coi opcodes. */ enum cop0_coi_func { @@ -300,5 +307,65 @@ struct f_format f_format; struct ma_format ma_format; }; + +/* HACHACHAHCAHC ... */ + +/* In case some other massaging is needed, keep MIPSInst as wrapper */ + +#define MIPSInst(x) x + +#define I_OPCODE_SFT 26 +#define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT) + +#define I_JTARGET_SFT 0 +#define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff) + +#define I_RS_SFT 21 +#define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT) + +#define I_RT_SFT 16 +#define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT) + +#define I_IMM_SFT 0 +#define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff))) +#define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff) + +#define I_CACHEOP_SFT 18 +#define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT) + +#define I_CACHESEL_SFT 16 +#define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT) + +#define I_RD_SFT 11 +#define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT) + +#define I_RE_SFT 6 +#define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT) + +#define I_FUNC_SFT 0 +#define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f) + +#define I_FFMT_SFT 21 +#define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT) + +#define I_FT_SFT 16 +#define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT) + +#define I_FS_SFT 11 +#define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT) + +#define I_FD_SFT 6 +#define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT) + +#define I_FR_SFT 21 +#define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT) + +#define I_FMA_FUNC_SFT 2 +#define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT) + +#define I_FMA_FFMT_SFT 0 +#define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003) + +typedef unsigned int mips_instruction; #endif /* _ASM_INST_H */ diff -Nru a/include/asm-mips64/io.h b/include/asm-mips64/io.h --- a/include/asm-mips64/io.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/io.h Fri Jun 27 14:19:52 2003 @@ -13,6 +13,23 @@ #include <linux/config.h> #include <asm/addrspace.h> #include <asm/page.h> +#include <asm/byteorder.h> + +#ifdef CONFIG_DECSTATION +#include <asm/dec/io.h> +#endif + +#ifdef CONFIG_MIPS_ATLAS +#include <asm/mips-boards/io.h> +#endif + +#ifdef CONFIG_MIPS_MALTA +#include <asm/mips-boards/io.h> +#endif + +#ifdef CONFIG_MIPS_SEAD +#include <asm/mips-boards/io.h> +#endif #ifdef CONFIG_SGI_IP22 #include <asm/sgi/io.h> @@ -22,52 +39,126 @@ #include <asm/sn/io.h> #endif +#ifdef CONFIG_SGI_IP32 +#include <asm/ip32/io.h> +#endif + +#ifdef CONFIG_SIBYTE_SB1xxx_SOC +#include <asm/sibyte/io.h> +#endif + +#ifdef CONFIG_SNI_RM200_PCI +#include <asm/sni.h> +#endif + +#ifdef CONFIG_SGI_IP27 extern unsigned long bus_to_baddr[256]; +#define bus_to_baddr(bus, addr) (bus_to_baddr[(bus)->number] + (addr)) +#define baddr_to_bus(bus, addr) ((addr) - bus_to_baddr[(bus)->number]) +#else +#define bus_to_baddr(bus, addr) (addr) +#define baddr_to_bus(bus, addr) (addr) +#endif + /* * Slowdown I/O port space accesses for antique hardware. */ #undef CONF_SLOWDOWN_IO /* - * On MIPS, we have the whole physical address space mapped at all - * times, so "ioremap()" and "iounmap()" do not need to do anything. + * Sane hardware offers swapping of I/O space accesses in hardware; less + * sane hardware forces software to fiddle with this ... + */ +#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__) + +#define __ioswab8(x) (x) + +#ifdef CONFIG_SGI_IP22 +/* + * IP22 seems braindead enough to swap 16bits values in hardware, but + * not 32bits. Go figure... Can't tell without documentation. + */ +#define __ioswab16(x) (x) +#else +#define __ioswab16(x) swab16(x) +#endif +#define __ioswab32(x) swab32(x) + +#else + +#define __ioswab8(x) (x) +#define __ioswab16(x) (x) +#define __ioswab32(x) (x) + +#endif + +/* + * Change "struct page" to physical address. + */ +#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) + +/* + * ioremap - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map * - * We cheat a bit and always return uncachable areas until we've fixed - * the drivers to handle caching properly. + * ioremap performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. */ -extern inline void * -ioremap(unsigned long offset, unsigned long size) +static inline void * ioremap(unsigned long offset, unsigned long size) { return (void *) (IO_SPACE_BASE | offset); } -/* This one maps high address device memory and turns off caching for that - * area. It's useful if some control registers are in such an area and write - * combining or read caching is not desirable. +/* + * ioremap_nocache - map bus memory into CPU space + * @offset: bus address of the memory + * @size: size of the resource to map + * + * ioremap_nocache performs a platform specific sequence of operations to + * make bus memory CPU accessible via the readb/readw/readl/writeb/ + * writew/writel functions and the other mmio helpers. The returned + * address is not guaranteed to be usable directly as a virtual + * address. + * + * This version of ioremap ensures that the memory is marked uncachable + * on the CPU as well as honouring existing caching rules from things like + * the PCI bus. Note that there are other caches and buffers on many + * busses. In paticular driver authors should read up on PCI writes + * + * It's useful if some control registers are in such an area and + * write combining or read caching is not desirable: */ -extern inline void * -ioremap_nocache (unsigned long offset, unsigned long size) +static inline void * ioremap_nocache (unsigned long offset, unsigned long size) { return (void *) (IO_SPACE_BASE | offset); } -extern inline void iounmap(void *addr) +static inline void iounmap(void *addr) { } -/* - * This assumes sane hardware. The Origin is. - */ -#define readb(addr) (*(volatile unsigned char *) (addr)) -#define readw(addr) (*(volatile unsigned short *) (addr)) -#define readl(addr) (*(volatile unsigned int *) (addr)) - -#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b)) -#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b)) -#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b)) +#define readb(addr) (*(volatile unsigned char *)(addr)) +#define readw(addr) __ioswab16((*(volatile unsigned short *)(addr))) +#define readl(addr) __ioswab32((*(volatile unsigned int *)(addr))) + +#define __raw_readb(addr) (*(volatile unsigned char *)(addr)) +#define __raw_readw(addr) (*(volatile unsigned short *)(addr)) +#define __raw_readl(addr) (*(volatile unsigned int *)(addr)) + +#define writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (__ioswab8(b))) +#define writew(b,addr) ((*(volatile unsigned short *)(addr)) = (__ioswab16(b))) +#define writel(b,addr) ((*(volatile unsigned int *)(addr)) = (__ioswab32(b))) + +#define __raw_writeb(b,addr) ((*(volatile unsigned char *)(addr)) = (b)) +#define __raw_writew(w,addr) ((*(volatile unsigned short *)(addr)) = (w)) +#define __raw_writel(l,addr) ((*(volatile unsigned int *)(addr)) = (l)) -#define memset_io(a,b,c) memset((void *) a,(b),(c)) +#define memset_io(a,b,c) memset((void *)(a),(b),(c)) #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) @@ -81,7 +172,10 @@ * instruction, so the lower 16 bits must be zero. Should be true on * on any sane architecture; generic code does not use this assumption. */ -extern unsigned long mips_io_port_base; +extern const unsigned long mips_io_port_base; + +#define set_io_port_base(base) \ + do { * (unsigned long *) &mips_io_port_base = (base); } while (0) #define __SLOW_DOWN_IO \ __asm__ __volatile__( \ @@ -99,20 +193,65 @@ #endif /* - * Change virtual addresses to physical addresses and vv. - * These are trivial on the 1:1 Linux/MIPS mapping + * virt_to_phys - map virtual addresses to physical + * @address: address to remap + * + * The returned physical address is the physical (CPU) mapping for + * the memory address given. It is only valid to use this function on + * addresses directly mapped or allocated via kmalloc. + * + * This function does not give bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function */ -extern inline unsigned long virt_to_phys(volatile void * address) +static inline unsigned long virt_to_phys(volatile void * address) { return (unsigned long)address - PAGE_OFFSET; } -extern inline void * phys_to_virt(unsigned long address) +/* + * phys_to_virt - map physical address to virtual + * @address: address to remap + * + * The returned virtual address is a current CPU mapping for + * the memory address given. It is only valid to use this function on + * addresses that have a kernel mapping + * + * This function does not handle bus mappings for DMA transfers. In + * almost all conceivable cases a device driver should not be using + * this function + */ +static inline void * phys_to_virt(unsigned long address) { return (void *)(address + PAGE_OFFSET); } /* + * ISA I/O bus memory addresses are 1:1 with the physical address. + */ +static inline unsigned long isa_virt_to_bus(volatile void * address) +{ + return PHYSADDR(address); +} + +static inline void * isa_bus_to_virt(unsigned long address) +{ + return (void *)KSEG0ADDR(address); +} + +/* + * However PCI ones are not necessarily 1:1 and therefore these interfaces + * are forbidden in portable PCI drivers. + * + * Allow them for x86 for legacy drivers, though. + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* This is too simpleminded for more sophisticated than dumb hardware ... */ +#define page_to_bus page_to_phys + +/* * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped * for the processor. This implies the assumption that there is only * one of these busses. @@ -120,14 +259,43 @@ extern unsigned long isa_slot_offset; /* + * ISA space is 'always mapped' on currently supported MIPS systems, no need + * to explicitly ioremap() it. The fact that the ISA IO space is mapped + * to PAGE_OFFSET is pure coincidence - it does not mean ISA values + * are physical addresses. The following constant pointer can be + * used as the IO-area pointer (it can be iounmapped as well, so the + * analogy with PCI is quite large): + */ +#define __ISA_IO_base ((char *)(isa_slot_offset)) + +#define isa_readb(a) readb(__ISA_IO_base + (a)) +#define isa_readw(a) readw(__ISA_IO_base + (a)) +#define isa_readl(a) readl(__ISA_IO_base + (a)) +#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a)) +#define isa_writew(w,a) writew(w,__ISA_IO_base + (a)) +#define isa_writel(l,a) writel(l,__ISA_IO_base + (a)) +#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c)) + +/* * We don't have csum_partial_copy_fromio() yet, so we cheat here and * just copy it. The net code will then do the checksum later. */ #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len)) -static inline int -check_signature(unsigned long io_addr, const unsigned char *signature, - int length) +/** + * check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the mmio address io_addr. This + * address should have been obtained by ioremap. + * Returns 1 on a match. + */ +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) { int retval = 0; do { @@ -143,201 +311,143 @@ } /* - * Talk about misusing macros.. + * isa_check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. */ +#define isa_check_signature(io, s, l) check_signature(i,s,l) -#define __OUT1(s) \ -extern inline void __out##s(unsigned int value, unsigned long port) { +#define outb(val,port) \ +do { \ + *(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val); \ +} while(0) + +#define outw(val,port) \ +do { \ + *(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val);\ +} while(0) + +#define outl(val,port) \ +do { \ + *(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\ +} while(0) + +#define outb_p(val,port) \ +do { \ + *(volatile u8 *)(mips_io_port_base + (port)) = __ioswab8(val); \ + SLOW_DOWN_IO; \ +} while(0) + +#define outw_p(val,port) \ +do { \ + *(volatile u16 *)(mips_io_port_base + (port)) = __ioswab16(val);\ + SLOW_DOWN_IO; \ +} while(0) + +#define outl_p(val,port) \ +do { \ + *(volatile u32 *)(mips_io_port_base + (port)) = __ioswab32(val);\ + SLOW_DOWN_IO; \ +} while(0) -#define __OUT2(m) \ -__asm__ __volatile__ ("s" #m "\t%0,%1(%2)" +static inline unsigned char inb(unsigned long port) +{ + return __ioswab8(*(volatile u8 *)(mips_io_port_base + port)); +} + +static inline unsigned short inw(unsigned long port) +{ + return __ioswab16(*(volatile u16 *)(mips_io_port_base + port)); +} -#define __OUT(m,s) \ -__OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); } \ -__OUT1(s##c) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); } \ -__OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); \ - SLOW_DOWN_IO; } \ -__OUT1(s##c_p) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); \ - SLOW_DOWN_IO; } - -#define __IN1(t,s) \ -extern __inline__ t __in##s(unsigned long port) { t _v; - -/* - * Required nops will be inserted by the assembler - */ -#define __IN2(m) \ -__asm__ __volatile__ ("l" #m "\t%0,%1(%2)" - -#define __IN(t,m,s) \ -__IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return _v; } \ -__IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return _v; } \ -__IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return _v; } \ -__IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return _v; } - -#define __INS1(s) \ -extern inline void __ins##s(unsigned long port, void * addr, unsigned long count) { - -#define __INS2(m) \ -if (count) \ -__asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n" \ - "1:\tl" #m "\t$1, %4(%5)\n\t" \ - "dsubu\t%1, 1\n\t" \ - "s" #m "\t$1,(%0)\n\t" \ - "bnez\t%1, 1b\n\t" \ - "daddiu\t%0, %6\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" - -#define __INS(m,s,i) \ -__INS1(s) __INS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \ - : "$1");} \ -__INS1(s##c) __INS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \ - : "$1");} - -#define __OUTS1(s) \ -extern inline void __outs##s(unsigned long port, const void * addr, unsigned long count) { - -#define __OUTS2(m) \ -if (count) \ -__asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n" \ - "1:\tl" #m "\t$1, (%0)\n\t" \ - "dsubu\t%1, 1\n\t" \ - "s" #m "\t$1, %4(%5)\n\t" \ - "bnez\t%1, 1b\n\t" \ - "daddiu\t%0, %6\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" - -#define __OUTS(m,s,i) \ -__OUTS1(s) __OUTS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \ - : "$1");} \ -__OUTS1(s##c) __OUTS2(m) \ - : "=r" (addr), "=r" (count) \ - : "0" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \ - : "$1");} - -__IN(unsigned char,b,b) -__IN(unsigned short,h,w) -__IN(unsigned int,w,l) - -__OUT(b,b) -__OUT(h,w) -__OUT(w,l) - -__INS(b,b,1) -__INS(h,w,2) -__INS(w,l,4) - -__OUTS(b,b,1) -__OUTS(h,w,2) -__OUTS(w,l,4) - -/* - * Note that due to the way __builtin_constant_p() works, you - * - can't use it inside an inline function (it will never be true) - * - you don't have to worry about side effects within the __builtin.. - */ -#define outb(val,port) \ -((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \ - __outbc((val),(port)^(3)) : \ - __outb((val),(port)^(3))) - -#define inb(port) \ -((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \ - __inbc((port)^(3)) : \ - __inb((port)^(3))) - -#define outb_p(val,port) \ -((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \ - __outbc_p((val),(port)^(3)) : \ - __outb_p((val),(port)^(3))) - -#define inb_p(port) \ -((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \ - __inbc_p((port)^(3)) : \ - __inb_p((port)^(3))) - -#define outw(val,port) \ -((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \ - __outwc((val),((port)^(2))) : \ - __outw((val),((port)^(2)))) - -#define inw(port) \ -((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \ - __inwc((port)^(2)) : \ - __inw((port)^(2))) - -#define outw_p(val,port) \ -((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \ - __outwc_p((val),(port)^(2)) : \ - __outw_p((val),(port)^(2))) - -#define inw_p(port) \ -((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \ - __inwc_p((port)^(2)) : \ - __inw_p((port)^(2))) - -#define outl(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outlc((val),(port)) : \ - __outl((val),(port))) - -#define inl(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inlc(port) : \ - __inl(port)) - -#define outl_p(val,port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outlc_p((val),(port)) : \ - __outl_p((val),(port))) - -#define inl_p(port) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inlc_p(port) : \ - __inl_p(port)) - - -#define outsb(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outsbc((port),(addr),(count)) : \ - __outsb ((port),(addr),(count))) - -#define insb(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __insbc((port),(addr),(count)) : \ - __insb((port),(addr),(count))) - -#define outsw(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outswc((port),(addr),(count)) : \ - __outsw ((port),(addr),(count))) - -#define insw(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inswc((port),(addr),(count)) : \ - __insw((port),(addr),(count))) - -#define outsl(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __outslc((port),(addr),(count)) : \ - __outsl ((port),(addr),(count))) - -#define insl(port,addr,count) \ -((__builtin_constant_p((port)) && (port) < 32768) ? \ - __inslc((port),(addr),(count)) : \ - __insl((port),(addr),(count))) +static inline unsigned int inl(unsigned long port) +{ + return __ioswab32(*(volatile u32 *)(mips_io_port_base + port)); +} + +static inline unsigned char inb_p(unsigned long port) +{ + u8 __val; + + __val = *(volatile u8 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + + return __ioswab8(__val); +} + +static inline unsigned short inw_p(unsigned long port) +{ + u16 __val; + + __val = *(volatile u16 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + + return __ioswab16(__val); +} + +static inline unsigned int inl_p(unsigned long port) +{ + u32 __val; + + __val = *(volatile u32 *)(mips_io_port_base + port); + SLOW_DOWN_IO; + return __ioswab32(__val); +} + +static inline void outsb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outb(*(u8 *)addr, port); + addr++; + } +} + +static inline void insb(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u8 *)addr = inb(port); + addr++; + } +} + +static inline void outsw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outw(*(u16 *)addr, port); + addr += 2; + } +} + +static inline void insw(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u16 *)addr = inw(port); + addr += 2; + } +} + +static inline void outsl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + outl(*(u32 *)addr, port); + addr += 4; + } +} + +static inline void insl(unsigned long port, void *addr, unsigned int count) +{ + while (count--) { + *(u32 *)addr = inl(port); + addr += 4; + } +} /* * The caches on some architectures aren't dma-coherent and have need to @@ -357,22 +467,7 @@ * be discarded. This operation is necessary before dma operations * to the memory. */ -#ifdef CONFIG_COHERENT_IO - -/* This is for example for IP27. */ -extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size) -{ -} - -extern inline void dma_cache_wback(unsigned long start, unsigned long size) -{ -} - -extern inline void dma_cache_inv(unsigned long start, unsigned long size) -{ -} - -#else +#ifdef CONFIG_NONCOHERENT_IO extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); extern void (*_dma_cache_wback)(unsigned long start, unsigned long size); @@ -382,6 +477,15 @@ #define dma_cache_wback(start,size) _dma_cache_wback(start,size) #define dma_cache_inv(start,size) _dma_cache_inv(start,size) -#endif +#else /* Sane hardware */ + +#define dma_cache_wback_inv(start,size) \ + do { (void) (start); (void) (size); } while (0) +#define dma_cache_wback(start,size) \ + do { (void) (start); (void) (size); } while (0) +#define dma_cache_inv(start,size) \ + do { (void) (start); (void) (size); } while (0) + +#endif /* CONFIG_NONCOHERENT_IO */ #endif /* _ASM_IO_H */ diff -Nru a/include/asm-mips64/ioctls.h b/include/asm-mips64/ioctls.h --- a/include/asm-mips64/ioctls.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/ioctls.h Fri Jun 27 14:19:59 2003 @@ -12,7 +12,7 @@ #include <asm/ioctl.h> #define TCGETA 0x5401 -#define TCSETA 0x5402 +#define TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */ #define TCSETAW 0x5403 #define TCSETAF 0x5404 @@ -49,7 +49,7 @@ #define TIOCGETD 0x7400 #define FIOCLEX 0x6601 -#define FIONCLEX 0x6602 /* these numbers need to be adjusted. */ +#define FIONCLEX 0x6602 #define FIOASYNC 0x667d #define FIONBIO 0x667e #define FIOQSIZE 0x667f @@ -66,7 +66,7 @@ #define TIOCGETP 0x7408 #define TIOCSETP 0x7409 #define TIOCSETN 0x740a /* TIOCSETP wo flush */ - + /* #define TIOCSETA _IOW('t', 20, struct termios) set termios struct */ /* #define TIOCSETAW _IOW('t', 21, struct termios) drain output, set */ /* #define TIOCSETAF _IOW('t', 22, struct termios) drn out, fls in, set */ diff -Nru a/include/asm-mips64/ip32/crime.h b/include/asm-mips64/ip32/crime.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/ip32/crime.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,227 @@ +/* + * Definitions for the SGI O2 Crime chip. + * + * 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) 2000 Harald Koerfgen + */ + +#ifndef __ASM_CRIME_H__ +#define __ASM_CRIME_H__ + +#include <asm/addrspace.h> + +/* + * Address map + */ +#ifndef __ASSEMBLY__ +#define CRIME_BASE KSEG1ADDR(0x14000000) +#else +#define CRIME_BASE 0xffffffffb4000000 +#endif + +#ifndef __ASSEMBLY__ +static inline u64 crime_read_64 (unsigned long __offset) { + return *((volatile u64 *) (CRIME_BASE + __offset)); +} +static inline void crime_write_64 (unsigned long __offset, u64 __val) { + *((volatile u64 *) (CRIME_BASE + __offset)) = __val; +} +#endif + +#undef BIT +#define BIT(x) (1UL << (x)) + +/* All CRIME registers are 64 bits */ +#define CRIME_ID 0 + +#define CRIME_ID_MASK 0xff +#define CRIME_ID_IDBITS 0xf0 +#define CRIME_ID_IDVALUE 0xa0 +#define CRIME_ID_REV 0x0f + +#define CRIME_REV_PETTY 0x00 +#define CRIME_REV_11 0x11 +#define CRIME_REV_13 0x13 +#define CRIME_REV_14 0x14 + +#define CRIME_CONTROL (0x00000008) +#define CRIME_CONTROL_MASK 0x3fff /* 14-bit registers */ + +/* CRIME_CONTROL register bits */ +#define CRIME_CONTROL_TRITON_SYSADC 0x2000 +#define CRIME_CONTROL_CRIME_SYSADC 0x1000 +#define CRIME_CONTROL_HARD_RESET 0x0800 +#define CRIME_CONTROL_SOFT_RESET 0x0400 +#define CRIME_CONTROL_DOG_ENA 0x0200 +#define CRIME_CONTROL_ENDIANESS 0x0100 + +#define CRIME_CONTROL_ENDIAN_BIG 0x0100 +#define CRIME_CONTROL_ENDIAN_LITTLE 0x0000 + +#define CRIME_CONTROL_CQUEUE_HWM 0x000f +#define CRIME_CONTROL_CQUEUE_SHFT 0 +#define CRIME_CONTROL_WBUF_HWM 0x00f0 +#define CRIME_CONTROL_WBUF_SHFT 8 + +#define CRIME_INT_STAT (0x00000010) +#define CRIME_INT_MASK (0x00000018) +#define CRIME_SOFT_INT (0x00000020) +#define CRIME_HARD_INT (0x00000028) + +/* Bits in CRIME_INT_XXX and CRIME_HARD_INT */ +#define MACE_VID_IN1_INT BIT (0) +#define MACE_VID_IN2_INT BIT (1) +#define MACE_VID_OUT_INT BIT (2) +#define MACE_ETHERNET_INT BIT (3) +#define MACE_SUPERIO_INT BIT (4) +#define MACE_MISC_INT BIT (5) +#define MACE_AUDIO_INT BIT (6) +#define MACE_PCI_BRIDGE_INT BIT (7) +#define MACEPCI_SCSI0_INT BIT (8) +#define MACEPCI_SCSI1_INT BIT (9) +#define MACEPCI_SLOT0_INT BIT (10) +#define MACEPCI_SLOT1_INT BIT (11) +#define MACEPCI_SLOT2_INT BIT (12) +#define MACEPCI_SHARED0_INT BIT (13) +#define MACEPCI_SHARED1_INT BIT (14) +#define MACEPCI_SHARED2_INT BIT (15) +#define CRIME_GBE0_INT BIT (16) +#define CRIME_GBE1_INT BIT (17) +#define CRIME_GBE2_INT BIT (18) +#define CRIME_GBE3_INT BIT (19) +#define CRIME_CPUERR_INT BIT (20) +#define CRIME_MEMERR_INT BIT (21) +#define CRIME_RE_EMPTY_E_INT BIT (22) +#define CRIME_RE_FULL_E_INT BIT (23) +#define CRIME_RE_IDLE_E_INT BIT (24) +#define CRIME_RE_EMPTY_L_INT BIT (25) +#define CRIME_RE_FULL_L_INT BIT (26) +#define CRIME_RE_IDLE_L_INT BIT (27) +#define CRIME_SOFT0_INT BIT (28) +#define CRIME_SOFT1_INT BIT (29) +#define CRIME_SOFT2_INT BIT (30) +#define CRIME_SYSCORERR_INT CRIME_SOFT2_INT +#define CRIME_VICE_INT BIT (31) + +/* Masks for deciding who handles the interrupt */ +#define CRIME_MACE_INT_MASK 0x8f +#define CRIME_MACEISA_INT_MASK 0x70 +#define CRIME_MACEPCI_INT_MASK 0xff00 +#define CRIME_CRIME_INT_MASK 0xffff0000 + +/* + * XXX Todo + */ +#define CRIME_DOG (0x00000030) +/* We are word-play compatible but not misspelling compatible */ +#define MC_GRUFF CRIME_DOG +#define CRIME_DOG_MASK (0x001fffff) + +/* CRIME_DOG register bits */ +#define CRIME_DOG_POWER_ON_RESET (0x00010000) +#define CRIME_DOG_WARM_RESET (0x00080000) +#define CRIME_DOG_TIMEOUT (CRIME_DOG_POWER_ON_RESET|CRIME_DOG_WARM_RESET) +#define CRIME_DOG_VALUE (0x00007fff) /* ??? */ + +#define CRIME_TIME (0x00000038) +#define CRIME_TIME_MASK (0x0000ffffffffffff) + +#ifdef MASTER_FREQ +#undef MASTER_FREQ +#endif +#define CRIME_MASTER_FREQ 66666500 /* Crime upcounter frequency */ +#define CRIME_NS_PER_TICK 15 /* for delay_calibrate */ + +#define CRIME_CPU_ERROR_ADDR (0x00000040) +#define CRIME_CPU_ERROR_ADDR_MASK (0x3ffffffff) + +#define CRIME_CPU_ERROR_STAT (0x00000048) +/* REV_PETTY only! */ +#define CRIME_CPU_ERROR_ENA (0x00000050) + +/* + * bit definitions for CRIME/VICE error status and enable registers + */ +#define CRIME_CPU_ERROR_MASK 0x7UL /* cpu error stat is 3 bits */ +#define CRIME_CPU_ERROR_CPU_ILL_ADDR 0x4 +#define CRIME_CPU_ERROR_VICE_WRT_PRTY 0x2 +#define CRIME_CPU_ERROR_CPU_WRT_PRTY 0x1 + +/* + * these are the definitions for the error status/enable register in + * petty crime. Note that the enable register does not exist in crime + * rev 1 and above. + */ +#define CRIME_CPU_ERROR_MASK_REV0 0x3ff /* cpu error stat is 9 bits */ +#define CRIME_CPU_ERROR_CPU_INV_ADDR_RD 0x200 +#define CRIME_CPU_ERROR_VICE_II 0x100 +#define CRIME_CPU_ERROR_VICE_SYSAD 0x80 +#define CRIME_CPU_ERROR_VICE_SYSCMD 0x40 +#define CRIME_CPU_ERROR_VICE_INV_ADDR 0x20 +#define CRIME_CPU_ERROR_CPU_II 0x10 +#define CRIME_CPU_ERROR_CPU_SYSAD 0x8 +#define CRIME_CPU_ERROR_CPU_SYSCMD 0x4 +#define CRIME_CPU_ERROR_CPU_INV_ADDR_WR 0x2 +#define CRIME_CPU_ERROR_CPU_INV_REG_ADDR 0x1 + +#define CRIME_VICE_ERROR_ADDR (0x00000058) +#define CRIME_VICE_ERROR_ADDR_MASK (0x3fffffff) + +#define CRIME_MEM_CONTROL (0x00000200) +#define CRIME_MEM_CONTROL_MASK 0x3 /* 25 cent register */ +#define CRIME_MEM_CONTROL_ECC_ENA 0x1 +#define CRIME_MEM_CONTROL_USE_ECC_REPL 0x2 + +/* + * macros for CRIME memory bank control registers. + */ +#define CRIME_MEM_BANK_CONTROL(__bank) (0x00000208 + ((__bank) << 3)) +#define CRIME_MEM_BANK_CONTROL_MSK 0x11f /* 9 bits 7:5 reserved */ +#define CRIME_MEM_BANK_CONTROL_ADDR 0x01f +#define CRIME_MEM_BANK_CONTROL_SDRAM_SIZE 0x100 +#define CRIME_MEM_BANK_CONTROL_BANK_TO_ADDR(__bank) \ + (((__bank) & CRIME_MEM_BANK_CONTROL_ADDR) << 25) + +#define CRIME_MEM_REFRESH_COUNTER (0x00000248) +#define CRIME_MEM_REFRESH_COUNTER_MASK 0x7ff /* 11-bit register */ + +#define CRIME_MAXBANKS 8 + +/* + * CRIME Memory error status register bit definitions + */ +#define CRIME_MEM_ERROR_STAT (0x00000250) +#define CRIME_MEM_ERROR_STAT_MASK 0x0ff7ffff /* 28-bit register */ +#define CRIME_MEM_ERROR_MACE_ID 0x0000007f +#define CRIME_MEM_ERROR_MACE_ACCESS 0x00000080 +#define CRIME_MEM_ERROR_RE_ID 0x00007f00 +#define CRIME_MEM_ERROR_RE_ACCESS 0x00008000 +#define CRIME_MEM_ERROR_GBE_ACCESS 0x00010000 +#define CRIME_MEM_ERROR_VICE_ACCESS 0x00020000 +#define CRIME_MEM_ERROR_CPU_ACCESS 0x00040000 +#define CRIME_MEM_ERROR_RESERVED 0x00080000 +#define CRIME_MEM_ERROR_SOFT_ERR 0x00100000 +#define CRIME_MEM_ERROR_HARD_ERR 0x00200000 +#define CRIME_MEM_ERROR_MULTIPLE 0x00400000 +#define CRIME_MEM_ERROR_MEM_ECC_RD 0x00800000 +#define CRIME_MEM_ERROR_MEM_ECC_RMW 0x01000000 +#define CRIME_MEM_ERROR_INV_MEM_ADDR_RD 0x02000000 +#define CRIME_MEM_ERROR_INV_MEM_ADDR_WR 0x04000000 +#define CRIME_MEM_ERROR_INV_MEM_ADDR_RMW 0x08000000 + +#define CRIME_MEM_ERROR_ADDR (0x00000258) +#define CRIME_MEM_ERROR_ADDR_MASK 0x3fffffff + +#define CRIME_MEM_ERROR_ECC_SYN (0x00000260) +#define CRIME_MEM_ERROR_ECC_SYN_MASK 0xffffffff + +#define CRIME_MEM_ERROR_ECC_CHK (0x00000268) +#define CRIME_MEM_ERROR_ECC_CHK_MASK 0xffffffff + +#define CRIME_MEM_ERROR_ECC_REPL (0x00000270) +#define CRIME_MEM_ERROR_ECC_REPL_MASK 0xffffffff + +#endif /* __ASM_CRIME_H__ */ diff -Nru a/include/asm-mips64/ip32/io.h b/include/asm-mips64/ip32/io.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/ip32/io.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,15 @@ +#ifndef __ASM_IP32_IO_H__ +#define __ASM_IP32_IO_H__ + +#include <asm/ip32/mace.h> + +/*#ifdef CONFIG_MIPS_UNCACHED*/ +#define UNCACHEDADDR(x) (0x9000000000000000UL | (u64)(x)) +/*#else +#define UNCACHEDADDR(x) (x) +#endif*/ +/*#define UNCACHEDADDR(x) (KSEG1ADDR (x)) */ +#define IO_SPACE_BASE UNCACHEDADDR (MACEPCI_HI_MEMORY) +#define IO_SPACE_LIMIT 0xffffffffUL + +#endif diff -Nru a/include/asm-mips64/ip32/ip32_ints.h b/include/asm-mips64/ip32/ip32_ints.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/ip32/ip32_ints.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,94 @@ +/* + * 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) 2000 Harald Koerfgen + */ + +#ifndef __ASM_IP32_INTS_H +#define __ASM_IP32_INTS_H + +/* + * This list reflects the assignment of interrupt numbers to + * interrupting events. Order is fairly irrelevant to handling + * priority. This differs from irix. + */ + +/* CPU */ +#define CLOCK_IRQ 0 + +/* MACE */ +#define MACE_VID_IN1_IRQ 1 +#define MACE_VID_IN2_IRQ 2 +#define MACE_VID_OUT_IRQ 3 +#define MACE_ETHERNET_IRQ 4 +/* SUPERIO, MISC, and AUDIO are MACEISA */ +#define MACE_PCI_BRIDGE_IRQ 8 + +/* MACEPCI */ +#define MACEPCI_SCSI0_IRQ 9 +#define MACEPCI_SCSI1_IRQ 10 +#define MACEPCI_SLOT0_IRQ 11 +#define MACEPCI_SLOT1_IRQ 12 +#define MACEPCI_SLOT2_IRQ 13 +#define MACEPCI_SHARED0_IRQ 14 +#define MACEPCI_SHARED1_IRQ 15 +#define MACEPCI_SHARED2_IRQ 16 + +/* CRIME */ +#define CRIME_GBE0_IRQ 17 +#define CRIME_GBE1_IRQ 18 +#define CRIME_GBE2_IRQ 19 +#define CRIME_GBE3_IRQ 20 +#define CRIME_CPUERR_IRQ 21 +#define CRIME_MEMERR_IRQ 22 +#define CRIME_RE_EMPTY_E_IRQ 23 +#define CRIME_RE_FULL_E_IRQ 24 +#define CRIME_RE_IDLE_E_IRQ 25 +#define CRIME_RE_EMPTY_L_IRQ 26 +#define CRIME_RE_FULL_L_IRQ 27 +#define CRIME_RE_IDLE_L_IRQ 28 +#define CRIME_SOFT0_IRQ 29 +#define CRIME_SOFT1_IRQ 30 +#define CRIME_SOFT2_IRQ 31 +#define CRIME_SYSCORERR_IRQ CRIME_SOFT2_IRQ +#define CRIME_VICE_IRQ 32 + +/* MACEISA */ +#define MACEISA_AUDIO_SW_IRQ 33 +#define MACEISA_AUDIO_SC_IRQ 34 +#define MACEISA_AUDIO1_DMAT_IRQ 35 +#define MACEISA_AUDIO1_OF_IRQ 36 +#define MACEISA_AUDIO2_DMAT_IRQ 37 +#define MACEISA_AUDIO2_MERR_IRQ 38 +#define MACEISA_AUDIO3_DMAT_IRQ 39 +#define MACEISA_AUDIO3_MERR_IRQ 40 +#define MACEISA_RTC_IRQ 41 +#define MACEISA_KEYB_IRQ 42 +/* MACEISA_KEYB_POLL is not an IRQ */ +#define MACEISA_MOUSE_IRQ 44 +/* MACEISA_MOUSE_POLL is not an IRQ */ +#define MACEISA_TIMER0_IRQ 46 +#define MACEISA_TIMER1_IRQ 47 +#define MACEISA_TIMER2_IRQ 48 +#define MACEISA_PARALLEL_IRQ 49 +#define MACEISA_PAR_CTXA_IRQ 50 +#define MACEISA_PAR_CTXB_IRQ 51 +#define MACEISA_PAR_MERR_IRQ 52 +#define MACEISA_SERIAL1_IRQ 53 +#define MACEISA_SERIAL1_TDMAT_IRQ 54 +#define MACEISA_SERIAL1_TDMAPR_IRQ 55 +#define MACEISA_SERIAL1_TDMAME_IRQ 56 +#define MACEISA_SERIAL1_RDMAT_IRQ 57 +#define MACEISA_SERIAL1_RDMAOR_IRQ 58 +#define MACEISA_SERIAL2_IRQ 59 +#define MACEISA_SERIAL2_TDMAT_IRQ 60 +#define MACEISA_SERIAL2_TDMAPR_IRQ 61 +#define MACEISA_SERIAL2_TDMAME_IRQ 62 +#define MACEISA_SERIAL2_RDMAT_IRQ 63 +#define MACEISA_SERIAL2_RDMAOR_IRQ 64 + +#define IP32_IRQ_MAX MACEISA_SERIAL2_RDMAOR_IRQ + +#endif /* __ASM_IP32_INTS_H */ diff -Nru a/include/asm-mips64/ip32/mace.h b/include/asm-mips64/ip32/mace.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/ip32/mace.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,254 @@ +/* + * Definitions for the SGI O2 Mace chip. + * + * 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) 2000 Harald Koerfgen + */ + +#ifndef __ASM_MACE_H__ +#define __ASM_MACE_H__ + +#include <asm/addrspace.h> + +/* + * Address map + */ +#define MACE_BASE KSEG1ADDR(0x1f000000) +#define MACE_PCI (0x00080000) +#define MACE_VIN1 (0x00100000) +#define MACE_VIN2 (0x00180000) +#define MACE_VOUT (0x00200000) +#define MACE_ENET (0x00280000) +#define MACE_PERIF (0x00300000) +#define MACE_ISA_EXT (0x00380000) + +#define MACE_AUDIO_BASE (MACE_PERIF ) +#define MACE_ISA_BASE (MACE_PERIF + 0x00010000) +#define MACE_KBDMS_BASE (MACE_PERIF + 0x00020000) +#define MACE_I2C_BASE (MACE_PERIF + 0x00030000) +#define MACE_UST_BASE (MACE_PERIF + 0x00040000) + + +#undef BIT +#define BIT(__bit_offset) (1UL << (__bit_offset)) + +/* + * Mace MACEPCI interface, 32 bit regs + */ +#define MACEPCI_ERROR_ADDR (MACE_PCI ) +#define MACEPCI_ERROR_FLAGS (MACE_PCI + 0x00000004) +#define MACEPCI_CONTROL (MACE_PCI + 0x00000008) +#define MACEPCI_REV (MACE_PCI + 0x0000000c) +#define MACEPCI_WFLUSH (MACE_PCI + 0x0000000c) /* ??? --IV !!! It's for flushing read buffers on PCI MEMORY accesses!!! */ +#define MACEPCI_CONFIG_ADDR (MACE_PCI + 0x00000cf8) +#define MACEPCI_CONFIG_DATA (MACE_PCI + 0x00000cfc) +#define MACEPCI_LOW_MEMORY 0x1a000000 +#define MACEPCI_LOW_IO 0x18000000 +#define MACEPCI_SWAPPED_VIEW 0 +#define MACEPCI_NATIVE_VIEW 0x40000000 +#define MACEPCI_IO 0x80000000 +/*#define MACEPCI_HI_MEMORY 0x0000000280000000UL * This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */ +#define MACEPCI_HI_MEMORY 0x0000000200000000UL /* This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */ +#define MACEPCI_HI_IO 0x0000000100000000UL + +/* + * Bits in the MACEPCI_CONTROL register + */ +#define MACEPCI_CONTROL_INT(x) BIT(x) +#define MACEPCI_CONTROL_INT_MASK 0xff +#define MACEPCI_CONTROL_SERR_ENA BIT(8) +#define MACEPCI_CONTROL_ARB_N6 BIT(9) +#define MACEPCI_CONTROL_PARITY_ERR BIT(10) +#define MACEPCI_CONTROL_MRMRA_ENA BIT(11) +#define MACEPCI_CONTROL_ARB_N3 BIT(12) +#define MACEPCI_CONTROL_ARB_N4 BIT(13) +#define MACEPCI_CONTROL_ARB_N5 BIT(14) +#define MACEPCI_CONTROL_PARK_LIU BIT(15) +#define MACEPCI_CONTROL_INV_INT(x) BIT(16+x) +#define MACEPCI_CONTROL_INV_INT_MASK 0x00ff0000 +#define MACEPCI_CONTROL_OVERRUN_INT BIT(24) +#define MACEPCI_CONTROL_PARITY_INT BIT(25) +#define MACEPCI_CONTROL_SERR_INT BIT(26) +#define MACEPCI_CONTROL_IT_INT BIT(27) +#define MACEPCI_CONTROL_RE_INT BIT(28) +#define MACEPCI_CONTROL_DPED_INT BIT(29) +#define MACEPCI_CONTROL_TAR_INT BIT(30) +#define MACEPCI_CONTROL_MAR_INT BIT(31) + +/* + * Bits in the MACE_PCI error register + */ +#define MACEPCI_ERROR_MASTER_ABORT BIT(31) +#define MACEPCI_ERROR_TARGET_ABORT BIT(30) +#define MACEPCI_ERROR_DATA_PARITY_ERR BIT(29) +#define MACEPCI_ERROR_RETRY_ERR BIT(28) +#define MACEPCI_ERROR_ILLEGAL_CMD BIT(27) +#define MACEPCI_ERROR_SYSTEM_ERR BIT(26) +#define MACEPCI_ERROR_INTERRUPT_TEST BIT(25) +#define MACEPCI_ERROR_PARITY_ERR BIT(24) +#define MACEPCI_ERROR_OVERRUN BIT(23) +#define MACEPCI_ERROR_RSVD BIT(22) +#define MACEPCI_ERROR_MEMORY_ADDR BIT(21) +#define MACEPCI_ERROR_CONFIG_ADDR BIT(20) +#define MACEPCI_ERROR_MASTER_ABORT_ADDR_VALID BIT(19) +#define MACEPCI_ERROR_TARGET_ABORT_ADDR_VALID BIT(18) +#define MACEPCI_ERROR_DATA_PARITY_ADDR_VALID BIT(17) +#define MACEPCI_ERROR_RETRY_ADDR_VALID BIT(16) +#define MACEPCI_ERROR_SIG_TABORT BIT(4) +#define MACEPCI_ERROR_DEVSEL_MASK 0xc0 +#define MACEPCI_ERROR_DEVSEL_FAST 0 +#define MACEPCI_ERROR_DEVSEL_MED 0x40 +#define MACEPCI_ERROR_DEVSEL_SLOW 0x80 +#define MACEPCI_ERROR_FBB BIT(1) +#define MACEPCI_ERROR_66MHZ BIT(0) + +/* + * Mace timer registers - 64 bit regs (63:32 are UST, 31:0 are MSC) + */ +#define MSC_PART(__reg) ((__reg) & 0x00000000ffffffff) +#define UST_PART(__reg) (((__reg) & 0xffffffff00000000) >> 32) + +#define MACE_UST_UST (MACE_UST_BASE ) /* Universial system time */ +#define MACE_UST_COMPARE1 (MACE_UST_BASE + 0x00000008) /* Interrupt compare reg 1 */ +#define MACE_UST_COMPARE2 (MACE_UST_BASE + 0x00000010) /* Interrupt compare reg 2 */ +#define MACE_UST_COMPARE3 (MACE_UST_BASE + 0x00000018) /* Interrupt compare reg 3 */ +#define MACE_UST_PERIOD_NS 960 /* UST Period in ns */ + +#define MACE_UST_AIN_MSC (MACE_UST_BASE + 0x00000020) /* Audio in MSC/UST pair */ +#define MACE_UST_AOUT1_MSC (MACE_UST_BASE + 0x00000028) /* Audio out 1 MSC/UST pair */ +#define MACE_UST_AOUT2_MSC (MACE_UST_BASE + 0x00000030) /* Audio out 2 MSC/UST pair */ +#define MACE_VIN1_MSC_UST (MACE_UST_BASE + 0x00000038) /* Video In 1 MSC/UST pair */ +#define MACE_VIN2_MSC_UST (MACE_UST_BASE + 0x00000040) /* Video In 2 MSC/UST pair */ +#define MACE_VOUT_MSC_UST (MACE_UST_BASE + 0x00000048) /* Video out MSC/UST pair */ + +/* + * Mace "ISA" peripherals + */ +#define MACEISA_EPP_BASE (MACE_ISA_EXT ) +#define MACEISA_ECP_BASE (MACE_ISA_EXT + 0x00008000) +#define MACEISA_SER1_BASE (MACE_ISA_EXT + 0x00010000) +#define MACEISA_SER2_BASE (MACE_ISA_EXT + 0x00018000) +#define MACEISA_RTC_BASE (MACE_ISA_EXT + 0x00020000) +#define MACEISA_GAME_BASE (MACE_ISA_EXT + 0x00030000) + +/* + * Ringbase address and reset register - 64 bits + */ +#define MACEISA_RINGBASE MACE_ISA_BASE + +/* + * Flash-ROM/LED/DP-RAM/NIC Controller Register - 64 bits (?) + */ +#define MACEISA_FLASH_NIC_REG (MACE_ISA_BASE + 0x00000008) + +/* + * Bit definitions for that + */ +#define MACEISA_FLASH_WE BIT(0) /* 1=> Enable FLASH writes */ +#define MACEISA_PWD_CLEAR BIT(1) /* 1=> PWD CLEAR jumper detected */ +#define MACEISA_NIC_DEASSERT BIT(2) +#define MACEISA_NIC_DATA BIT(3) +#define MACEISA_LED_RED BIT(4) /* 0=> Illuminate RED LED */ +#define MACEISA_LED_GREEN BIT(5) /* 0=> Illuminate GREEN LED */ +#define MACEISA_DP_RAM_ENABLE BIT(6) + +/* + * ISA interrupt and status registers - 32 bit + */ +#define MACEISA_INT_STAT (MACE_ISA_BASE + 0x00000014) +#define MACEISA_INT_MASK (MACE_ISA_BASE + 0x0000001c) + +/* + * Bits in the status/mask registers + */ +#define MACEISA_AUDIO_SW_INT BIT (0) +#define MACEISA_AUDIO_SC_INT BIT (1) +#define MACEISA_AUDIO1_DMAT_INT BIT (2) +#define MACEISA_AUDIO1_OF_INT BIT (3) +#define MACEISA_AUDIO2_DMAT_INT BIT (4) +#define MACEISA_AUDIO2_MERR_INT BIT (5) +#define MACEISA_AUDIO3_DMAT_INT BIT (6) +#define MACEISA_AUDIO3_MERR_INT BIT (7) +#define MACEISA_RTC_INT BIT (8) +#define MACEISA_KEYB_INT BIT (9) +#define MACEISA_KEYB_POLL_INT BIT (10) +#define MACEISA_MOUSE_INT BIT (11) +#define MACEISA_MOUSE_POLL_INT BIT (12) +#define MACEISA_TIMER0_INT BIT (13) +#define MACEISA_TIMER1_INT BIT (14) +#define MACEISA_TIMER2_INT BIT (15) +#define MACEISA_PARALLEL_INT BIT (16) +#define MACEISA_PAR_CTXA_INT BIT (17) +#define MACEISA_PAR_CTXB_INT BIT (18) +#define MACEISA_PAR_MERR_INT BIT (19) +#define MACEISA_SERIAL1_INT BIT (20) +#define MACEISA_SERIAL1_TDMAT_INT BIT (21) +#define MACEISA_SERIAL1_TDMAPR_INT BIT (22) +#define MACEISA_SERIAL1_TDMAME_INT BIT (23) +#define MACEISA_SERIAL1_RDMAT_INT BIT (24) +#define MACEISA_SERIAL1_RDMAOR_INT BIT (25) +#define MACEISA_SERIAL2_INT BIT (26) +#define MACEISA_SERIAL2_TDMAT_INT BIT (27) +#define MACEISA_SERIAL2_TDMAPR_INT BIT (28) +#define MACEISA_SERIAL2_TDMAME_INT BIT (29) +#define MACEISA_SERIAL2_RDMAT_INT BIT (30) +#define MACEISA_SERIAL2_RDMAOR_INT BIT (31) + +#ifndef __ASSEMBLY__ +#include <asm/types.h> + +/* + * XXX Some of these are probably not needed (or even legal?) + */ +static inline u8 mace_read_8 (unsigned long __offset) +{ + return *((volatile u8 *) (MACE_BASE + __offset)); +} + +static inline u16 mace_read_16 (unsigned long __offset) +{ + return *((volatile u16 *) (MACE_BASE + __offset)); +} + +static inline u32 mace_read_32 (unsigned long __offset) +{ + return *((volatile u32 *) (MACE_BASE + __offset)); +} + +static inline u64 mace_read_64 (unsigned long __offset) +{ + return *((volatile u64 *) (MACE_BASE + __offset)); +} + +static inline void mace_write_8 (unsigned long __offset, u8 __val) +{ + *((volatile u8 *) (MACE_BASE + __offset)) = __val; +} + +static inline void mace_write_16 (unsigned long __offset, u16 __val) +{ + *((volatile u16 *) (MACE_BASE + __offset)) = __val; +} + +static inline void mace_write_32 (unsigned long __offset, u32 __val) +{ + *((volatile u32 *) (MACE_BASE + __offset)) = __val; +} + +static inline void mace_write_64 (unsigned long __offset, u64 __val) +{ + *((volatile u64 *) (MACE_BASE + __offset)) = __val; +} + +/* Call it whenever device needs to read data from main memory coherently */ +static inline void mace_inv_read_buffers(void) +{ +/* mace_write_32(MACEPCI_WFLUSH,0xffffffff);*/ +} +#endif /* !__ASSEMBLY__ */ + + +#endif /* __ASM_MACE_H__ */ diff -Nru a/include/asm-mips64/ip32/machine.h b/include/asm-mips64/ip32/machine.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/ip32/machine.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,21 @@ +/* + * machine.h -- Machine/group probing for ip32 + * + * Copyright (C) 2001 Keith M Wesolowski + * + * 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. + */ +#ifndef _ASM_IP32_MACHINE_H +#define _ASM_IP32_MACHINE_H + +#include <linux/config.h> + +#ifdef CONFIG_SGI_IP32 + +#define SGI_MACH_O2 0x3201 + +#endif /* CONFIG_SGI_IP32 */ + +#endif /* _ASM_SGI_MACHINE_H */ diff -Nru a/include/asm-mips64/ipc.h b/include/asm-mips64/ipc.h --- a/include/asm-mips64/ipc.h Fri Jun 27 14:20:03 2003 +++ b/include/asm-mips64/ipc.h Fri Jun 27 14:20:03 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_IPC_H #define _ASM_IPC_H -/* +/* * These are used to wrap system calls on MIPS32. * * See arch/mips/kernel/sysmips.c for ugly details.. @@ -15,6 +15,7 @@ #define SEMOP 1 #define SEMGET 2 #define SEMCTL 3 +#define SEMTIMEDOP 4 #define MSGSND 11 #define MSGRCV 12 #define MSGGET 13 diff -Nru a/include/asm-mips64/ipcbuf.h b/include/asm-mips64/ipcbuf.h --- a/include/asm-mips64/ipcbuf.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/ipcbuf.h Fri Jun 27 14:19:57 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_IPCBUF_H #define _ASM_IPCBUF_H -/* +/* * The ipc64_perm structure for alpha architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. @@ -18,7 +18,7 @@ __kernel_gid_t gid; __kernel_uid_t cuid; __kernel_gid_t cgid; - __kernel_mode_t mode; + __kernel_mode_t mode; unsigned short seq; unsigned short __pad1; unsigned long __unused1; diff -Nru a/include/asm-mips64/irq.h b/include/asm-mips64/irq.h --- a/include/asm-mips64/irq.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/irq.h Fri Jun 27 14:19:55 2003 @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle - * Copyright (C) 1995, 96, 97, 98, 1999, 2000 by Ralf Baechle + * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2001 Kanoj Sarcar */ @@ -12,6 +12,7 @@ #define _ASM_IRQ_H #include <linux/config.h> +#include <linux/linkage.h> #include <asm/sn/arch.h> #define NR_IRQS 256 @@ -42,13 +43,16 @@ #define irq_canonicalize(irq) (irq) /* Sane hardware, sane code ... */ #endif - -struct irqaction; -extern int i8259_setup_irq(int irq, struct irqaction * new); extern void disable_irq(unsigned int); +extern void disable_irq_nosync(unsigned int); extern void enable_irq(unsigned int); +struct pt_regs; +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); + /* Machine specific interrupt initialization */ extern void (*irq_setup)(void); + +extern void init_generic_irq(void); #endif /* _ASM_IRQ_H */ diff -Nru a/include/asm-mips64/irq_cpu.h b/include/asm-mips64/irq_cpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/irq_cpu.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,18 @@ +/* + * include/asm-mips/irq_cpu.h + * + * MIPS CPU interrupt definitions. + * + * Copyright (C) 2002 Maciej W. Rozycki + * + * 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 __ASM_MIPS64_IRQ_CPU_H +#define __ASM_MIPS64_IRQ_CPU_H + +extern void mips_cpu_irq_init(int irq_base); + +#endif /* __ASM_MIPS64_IRQ_CPU_H */ diff -Nru a/include/asm-mips64/keyboard.h b/include/asm-mips64/keyboard.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/keyboard.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,96 @@ +/* + * 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 - 1999 Ralf Baechle + */ +#ifndef _ASM_KEYBOARD_H +#define _ASM_KEYBOARD_H + +#ifdef __KERNEL__ + +#include <linux/config.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/kd.h> +#include <linux/pm.h> + +#define DISABLE_KBD_DURING_INTERRUPTS 0 + +#ifdef CONFIG_PC_KEYB + +extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int pckbd_getkeycode(unsigned int scancode); +extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char pckbd_unexpected_up(unsigned char keycode); +extern void pckbd_leds(unsigned char leds); +extern void pckbd_init_hw(void); +extern int pckbd_pm_resume(struct pm_dev *, pm_request_t, void *); +extern pm_callback pm_kbd_request_override; +extern unsigned char pckbd_sysrq_xlate[128]; +extern void kbd_forward_char (int ch); + +#define kbd_setkeycode pckbd_setkeycode +#define kbd_getkeycode pckbd_getkeycode +#define kbd_translate pckbd_translate +#define kbd_unexpected_up pckbd_unexpected_up +#define kbd_leds pckbd_leds +#define kbd_init_hw pckbd_init_hw +#define kbd_sysrq_xlate pckbd_sysrq_xlate + +#define SYSRQ_KEY 0x54 + +/* Some stoneage hardware needs delays after some operations. */ +#define kbd_pause() do { } while(0) + +struct kbd_ops { + /* Keyboard driver resource allocation */ + void (*kbd_request_region)(void); + int (*kbd_request_irq)(void (*handler)(int, void *, struct pt_regs *)); + + /* PSaux driver resource management */ + int (*aux_request_irq)(void (*handler)(int, void *, struct pt_regs *)); + void (*aux_free_irq)(void); + + /* Methods to access the keyboard processor's I/O registers */ + unsigned char (*kbd_read_input)(void); + void (*kbd_write_output)(unsigned char val); + void (*kbd_write_command)(unsigned char val); + unsigned char (*kbd_read_status)(void); +}; + +extern struct kbd_ops *kbd_ops; + +/* Do the actual calls via kbd_ops vector */ +#define kbd_request_region() kbd_ops->kbd_request_region() +#define kbd_request_irq(handler) kbd_ops->kbd_request_irq(handler) + +#define aux_request_irq(hand, dev_id) kbd_ops->aux_request_irq(hand) +#define aux_free_irq(dev_id) kbd_ops->aux_free_irq() + +#define kbd_read_input() kbd_ops->kbd_read_input() +#define kbd_write_output(val) kbd_ops->kbd_write_output(val) +#define kbd_write_command(val) kbd_ops->kbd_write_command(val) +#define kbd_read_status() kbd_ops->kbd_read_status() + +#else + +extern int kbd_setkeycode(unsigned int scancode, unsigned int keycode); +extern int kbd_getkeycode(unsigned int scancode); +extern int kbd_translate(unsigned char scancode, unsigned char *keycode, + char raw_mode); +extern char kbd_unexpected_up(unsigned char keycode); +extern void kbd_leds(unsigned char leds); +extern void kbd_init_hw(void); +extern unsigned char *kbd_sysrq_xlate; + +extern unsigned char kbd_sysrq_key; +#define SYSRQ_KEY kbd_sysrq_key + +#endif + +#endif /* __KERNEL */ + +#endif /* _ASM_KEYBOARD_H */ diff -Nru a/include/asm-mips64/kmap_types.h b/include/asm-mips64/kmap_types.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/kmap_types.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,35 @@ +/* + * Copy of the 32-bit kmap_types.h file just to keep things building ... + */ +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H + +#include <linux/config.h> + +#ifdef CONFIG_DEBUG_HIGHMEM +# define D(n) __KM_FENCE_##n , +#else +# define D(n) +#endif + +enum km_type { +D(0) KM_BOUNCE_READ, +D(1) KM_SKB_SUNRPC_DATA, +D(2) KM_SKB_DATA_SOFTIRQ, +D(3) KM_USER0, +D(4) KM_USER1, +D(5) KM_BIO_SRC_IRQ, +D(6) KM_BIO_DST_IRQ, +D(7) KM_PTE0, +D(8) KM_PTE1, +D(9) KM_PTE2, +D(10) KM_IRQ0, +D(11) KM_IRQ1, +D(12) KM_SOFTIRQ0, +D(13) KM_SOFTIRQ1, +D(14) KM_TYPE_NR +}; + +#undef D + +#endif diff -Nru a/include/asm-mips64/m48t35.h b/include/asm-mips64/m48t35.h --- a/include/asm-mips64/m48t35.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips64/m48t35.h Fri Jun 27 14:20:06 2003 @@ -1,24 +1,27 @@ /* * Registers for the SGS-Thomson M48T35 Timekeeper RAM chip */ - #ifndef _ASM_M48T35_H #define _ASM_M48T35_H +#include <linux/spinlock.h> + +extern spinlock_t rtc_lock; + struct m48t35_rtc { - volatile u8 pad[0x7ff8]; /* starts at 0x7ff8 */ - volatile u8 control; - volatile u8 sec; - volatile u8 min; - volatile u8 hour; - volatile u8 day; - volatile u8 date; - volatile u8 month; - volatile u8 year; + volatile u8 pad[0x7ff8]; /* starts at 0x7ff8 */ + volatile u8 control; + volatile u8 sec; + volatile u8 min; + volatile u8 hour; + volatile u8 day; + volatile u8 date; + volatile u8 month; + volatile u8 year; }; -#define M48T35_RTC_SET 0x80 -#define M48T35_RTC_STOPPED 0x80 -#define M48T35_RTC_READ 0x40 +#define M48T35_RTC_SET 0x80 +#define M48T35_RTC_STOPPED 0x80 +#define M48T35_RTC_READ 0x40 -#endif +#endif /* _ASM_M48T35_H */ diff -Nru a/include/asm-mips64/mc146818rtc.h b/include/asm-mips64/mc146818rtc.h --- a/include/asm-mips64/mc146818rtc.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/mc146818rtc.h Fri Jun 27 14:19:59 2003 @@ -6,28 +6,15 @@ * Machine dependent access functions for RTC registers. * * Copyright (C) 1996, 1997, 1998 Ralf Baechle + * Copyright (C) 2002 Maciej W. Rozycki */ #ifndef _ASM_MC146818RTC_H #define _ASM_MC146818RTC_H -#include <asm/io.h> +#include <linux/config.h> -#ifndef RTC_PORT -#define RTC_PORT(x) (0x70 + (x)) -#endif +#include <asm/io.h> -/* - * The yet supported machines all access the RTC index register via - * an ISA port access but the way to access the date register differs ... - */ -#define CMOS_READ(addr) ({ \ -rtc_ops->rtc_read_data(addr); \ -}) -#define CMOS_WRITE(val, addr) ({ \ -rtc_ops->rtc_write_data(val, addr); \ -}) -#define RTC_ALWAYS_BCD \ -rtc_ops->rtc_bcd_mode() /* * This structure defines how to access various features of @@ -42,6 +29,32 @@ extern struct rtc_ops *rtc_ops; -#define RTC_IRQ 8 +/* + * Most supported machines access the RTC index register via an ISA + * port access but the way to access the date register differs ... + * The DECstation directly maps the RTC memory in the CPU's address + * space with the chipset generating necessary index write/data access + * cycles automagically. + */ +#define CMOS_READ(addr) ({ \ +rtc_ops->rtc_read_data(addr); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +rtc_ops->rtc_write_data(val, addr); \ +}) +#define RTC_ALWAYS_BCD \ +rtc_ops->rtc_bcd_mode() + + +#ifdef CONFIG_DECSTATION + +#include <asm/dec/rtc-dec.h> + +#else + +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_IRQ 8 + +#endif #endif /* _ASM_MC146818RTC_H */ diff -Nru a/include/asm-mips64/mips-boards/atlas.h b/include/asm-mips64/mips-boards/atlas.h --- a/include/asm-mips64/mips-boards/atlas.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/mips-boards/atlas.h Fri Jun 27 14:19:56 2003 @@ -27,7 +27,7 @@ #include <asm/addrspace.h> -/* +/* * Atlas RTC-device indirect register access. */ #define ATLAS_RTC_ADR_REG (KSEG1ADDR(0x1f000800)) @@ -43,7 +43,7 @@ * Atlas UART register base. */ #define ATLAS_UART_REGS_BASE (0x1f000900) -#define ATLAS_BASE_BAUD ( 3686400 / 16 ) +#define ATLAS_BASE_BAUD ( 3686400 / 16 ) /* * Atlas PSU standby register. @@ -54,7 +54,7 @@ /* * We make a universal assumption about the way the bootloader (YAMON) * have located the Philips SAA9730 chip. - * This is not ideal, but is needed for setting up remote debugging as + * This is not ideal, but is needed for setting up remote debugging as * soon as possible. */ #define ATLAS_SAA9730_REG (KSEG1ADDR(0x08800000)) diff -Nru a/include/asm-mips64/mips-boards/atlasint.h b/include/asm-mips64/mips-boards/atlasint.h --- a/include/asm-mips64/mips-boards/atlasint.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/mips-boards/atlasint.h Fri Jun 27 14:20:05 2003 @@ -29,8 +29,8 @@ #define ATLASINT_UART 0 #define ATLASINT_END 32 -/* - * Atlas registers are memory mapped on 64-bit aligned boundaries and +/* + * Atlas registers are memory mapped on 64-bit aligned boundaries and * only word access are allowed. */ struct atlas_ictrl_regs { diff -Nru a/include/asm-mips64/mips-boards/bonito64.h b/include/asm-mips64/mips-boards/bonito64.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/mips-boards/bonito64.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,432 @@ +/* + * bonito.h + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2001 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This file is the original bonito.h from Algorithmics with minor changes + * to fit into linux. + */ + +/* + * Bonito Register Map + * Copyright (c) 1999 Algorithmics Ltd + * + * Algorithmics gives permission for anyone to use and modify this file + * without any obligation or license condition except that you retain + * this copyright message in any source redistribution in whole or part. + * + * Updated copies of this and other files can be found at + * ftp://ftp.algor.co.uk/pub/bonito/ + * + * Users of the Bonito controller are warmly recommended to contribute + * any useful changes back to Algorithmics (mail to bonito@algor.co.uk). + */ + +/* Revision 1.48 autogenerated on 08/17/99 15:20:01 */ +/* This bonito64 version editted from bonito.h Revision 1.48 on 11/09/00 */ + +#ifndef _ASM_MIPS_BOARDS_BONITO64_H +#define _ASM_MIPS_BOARDS_BONITO64_H + +#ifdef __ASSEMBLY__ + +/* offsets from base register */ +#define BONITO(x) (x) + +#else /* !__ASSEMBLY__ */ + +/* offsets from base pointer, this construct allows optimisation */ +/* static char * const _bonito = PA_TO_KVA1(BONITO_BASE); */ +#define BONITO(x) *(volatile u32 *)(_bonito + (x)) + +#endif /* __ASSEMBLY__ */ + + +#define BONITO_BOOT_BASE 0x1fc00000 +#define BONITO_BOOT_SIZE 0x00100000 +#define BONITO_BOOT_TOP (BONITO_BOOT_BASE+BONITO_BOOT_SIZE-1) +#define BONITO_FLASH_BASE 0x1c000000 +#define BONITO_FLASH_SIZE 0x03000000 +#define BONITO_FLASH_TOP (BONITO_FLASH_BASE+BONITO_FLASH_SIZE-1) +#define BONITO_SOCKET_BASE 0x1f800000 +#define BONITO_SOCKET_SIZE 0x00400000 +#define BONITO_SOCKET_TOP (BONITO_SOCKET_BASE+BONITO_SOCKET_SIZE-1) +#define BONITO_REG_BASE 0x1fe00000 +#define BONITO_REG_SIZE 0x00040000 +#define BONITO_REG_TOP (BONITO_REG_BASE+BONITO_REG_SIZE-1) +#define BONITO_DEV_BASE 0x1ff00000 +#define BONITO_DEV_SIZE 0x00100000 +#define BONITO_DEV_TOP (BONITO_DEV_BASE+BONITO_DEV_SIZE-1) +#define BONITO_PCILO_BASE 0x10000000 +#define BONITO_PCILO_SIZE 0x0c000000 +#define BONITO_PCILO_TOP (BONITO_PCILO_BASE+BONITO_PCILO_SIZE-1) +#define BONITO_PCILO0_BASE 0x10000000 +#define BONITO_PCILO1_BASE 0x14000000 +#define BONITO_PCILO2_BASE 0x18000000 +#define BONITO_PCIHI_BASE 0x20000000 +#define BONITO_PCIHI_SIZE 0x20000000 +#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1) +#define BONITO_PCIIO_BASE 0x1fd00000 +#define BONITO_PCIIO_SIZE 0x00100000 +#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1) +#define BONITO_PCICFG_BASE 0x1fe80000 +#define BONITO_PCICFG_SIZE 0x00080000 +#define BONITO_PCICFG_TOP (BONITO_PCICFG_BASE+BONITO_PCICFG_SIZE-1) + + +/* Bonito Register Bases */ + +#define BONITO_PCICONFIGBASE 0x00 +#define BONITO_REGBASE 0x100 + + +/* PCI Configuration Registers */ + +#define BONITO_PCI_REG(x) BONITO(BONITO_PCICONFIGBASE + (x)) +#define BONITO_PCIDID BONITO_PCI_REG(0x00) +#define BONITO_PCICMD BONITO_PCI_REG(0x04) +#define BONITO_PCICLASS BONITO_PCI_REG(0x08) +#define BONITO_PCILTIMER BONITO_PCI_REG(0x0c) +#define BONITO_PCIBASE0 BONITO_PCI_REG(0x10) +#define BONITO_PCIBASE1 BONITO_PCI_REG(0x14) +#define BONITO_PCIBASE2 BONITO_PCI_REG(0x18) +#define BONITO_PCIEXPRBASE BONITO_PCI_REG(0x30) +#define BONITO_PCIINT BONITO_PCI_REG(0x3c) + +#define BONITO_PCICMD_PERR_CLR 0x80000000 +#define BONITO_PCICMD_SERR_CLR 0x40000000 +#define BONITO_PCICMD_MABORT_CLR 0x20000000 +#define BONITO_PCICMD_MTABORT_CLR 0x10000000 +#define BONITO_PCICMD_TABORT_CLR 0x08000000 +#define BONITO_PCICMD_MPERR_CLR 0x01000000 +#define BONITO_PCICMD_PERRRESPEN 0x00000040 +#define BONITO_PCICMD_ASTEPEN 0x00000080 +#define BONITO_PCICMD_SERREN 0x00000100 +#define BONITO_PCILTIMER_BUSLATENCY 0x0000ff00 +#define BONITO_PCILTIMER_BUSLATENCY_SHIFT 8 + + + + +/* 1. Bonito h/w Configuration */ +/* Power on register */ + +#define BONITO_BONPONCFG BONITO(BONITO_REGBASE + 0x00) + +#define BONITO_BONPONCFG_SYSCONTROLLERRD 0x00040000 +#define BONITO_BONPONCFG_ROMCS1SAMP 0x00020000 +#define BONITO_BONPONCFG_ROMCS0SAMP 0x00010000 +#define BONITO_BONPONCFG_CPUBIGEND 0x00004000 +/* Added by RPF 11-9-00 */ +#define BONITO_BONPONCFG_BURSTORDER 0x00001000 +/* --- */ +#define BONITO_BONPONCFG_CPUPARITY 0x00002000 +#define BONITO_BONPONCFG_CPUTYPE 0x00000007 +#define BONITO_BONPONCFG_CPUTYPE_SHIFT 0 +#define BONITO_BONPONCFG_PCIRESET_OUT 0x00000008 +#define BONITO_BONPONCFG_IS_ARBITER 0x00000010 +#define BONITO_BONPONCFG_ROMBOOT 0x000000c0 +#define BONITO_BONPONCFG_ROMBOOT_SHIFT 6 + +#define BONITO_BONPONCFG_ROMBOOT_FLASH (0x0<<BONITO_BONPONCFG_ROMBOOT_SHIFT) +#define BONITO_BONPONCFG_ROMBOOT_SOCKET (0x1<<BONITO_BONPONCFG_ROMBOOT_SHIFT) +#define BONITO_BONPONCFG_ROMBOOT_SDRAM (0x2<<BONITO_BONPONCFG_ROMBOOT_SHIFT) +#define BONITO_BONPONCFG_ROMBOOT_CPURESET (0x3<<BONITO_BONPONCFG_ROMBOOT_SHIFT) + +#define BONITO_BONPONCFG_ROMCS0WIDTH 0x00000100 +#define BONITO_BONPONCFG_ROMCS1WIDTH 0x00000200 +#define BONITO_BONPONCFG_ROMCS0FAST 0x00000400 +#define BONITO_BONPONCFG_ROMCS1FAST 0x00000800 +#define BONITO_BONPONCFG_CONFIG_DIS 0x00000020 + + +/* Other Bonito configuration */ + +#define BONITO_BONGENCFG_OFFSET 0x4 +#define BONITO_BONGENCFG BONITO(BONITO_REGBASE + BONITO_BONGENCFG_OFFSET) + +#define BONITO_BONGENCFG_DEBUGMODE 0x00000001 +#define BONITO_BONGENCFG_SNOOPEN 0x00000002 +#define BONITO_BONGENCFG_CPUSELFRESET 0x00000004 + +#define BONITO_BONGENCFG_FORCE_IRQA 0x00000008 +#define BONITO_BONGENCFG_IRQA_ISOUT 0x00000010 +#define BONITO_BONGENCFG_IRQA_FROM_INT1 0x00000020 +#define BONITO_BONGENCFG_BYTESWAP 0x00000040 + +#define BONITO_BONGENCFG_UNCACHED 0x00000080 +#define BONITO_BONGENCFG_PREFETCHEN 0x00000100 +#define BONITO_BONGENCFG_WBEHINDEN 0x00000200 +#define BONITO_BONGENCFG_CACHEALG 0x00000c00 +#define BONITO_BONGENCFG_CACHEALG_SHIFT 10 +#define BONITO_BONGENCFG_PCIQUEUE 0x00001000 +#define BONITO_BONGENCFG_CACHESTOP 0x00002000 +#define BONITO_BONGENCFG_MSTRBYTESWAP 0x00004000 +#define BONITO_BONGENCFG_BUSERREN 0x00008000 +#define BONITO_BONGENCFG_NORETRYTIMEOUT 0x00010000 +#define BONITO_BONGENCFG_SHORTCOPYTIMEOUT 0x00020000 + +/* 2. IO & IDE configuration */ + +#define BONITO_IODEVCFG BONITO(BONITO_REGBASE + 0x08) + +/* 3. IO & IDE configuration */ + +#define BONITO_SDCFG BONITO(BONITO_REGBASE + 0x0c) + +/* 4. PCI address map control */ + +#define BONITO_PCIMAP BONITO(BONITO_REGBASE + 0x10) +#define BONITO_PCIMEMBASECFG BONITO(BONITO_REGBASE + 0x14) +#define BONITO_PCIMAP_CFG BONITO(BONITO_REGBASE + 0x18) + +/* 5. ICU & GPIO regs */ + +/* GPIO Regs - r/w */ + +#define BONITO_GPIODATA_OFFSET 0x1c +#define BONITO_GPIODATA BONITO(BONITO_REGBASE + BONITO_GPIODATA_OFFSET) +#define BONITO_GPIOIE BONITO(BONITO_REGBASE + 0x20) + +/* ICU Configuration Regs - r/w */ + +#define BONITO_INTEDGE BONITO(BONITO_REGBASE + 0x24) +#define BONITO_INTSTEER BONITO(BONITO_REGBASE + 0x28) +#define BONITO_INTPOL BONITO(BONITO_REGBASE + 0x2c) + +/* ICU Enable Regs - IntEn & IntISR are r/o. */ + +#define BONITO_INTENSET BONITO(BONITO_REGBASE + 0x30) +#define BONITO_INTENCLR BONITO(BONITO_REGBASE + 0x34) +#define BONITO_INTEN BONITO(BONITO_REGBASE + 0x38) +#define BONITO_INTISR BONITO(BONITO_REGBASE + 0x3c) + +/* PCI mail boxes */ + +#define BONITO_PCIMAIL0_OFFSET 0x40 +#define BONITO_PCIMAIL1_OFFSET 0x44 +#define BONITO_PCIMAIL2_OFFSET 0x48 +#define BONITO_PCIMAIL3_OFFSET 0x4c +#define BONITO_PCIMAIL0 BONITO(BONITO_REGBASE + 0x40) +#define BONITO_PCIMAIL1 BONITO(BONITO_REGBASE + 0x44) +#define BONITO_PCIMAIL2 BONITO(BONITO_REGBASE + 0x48) +#define BONITO_PCIMAIL3 BONITO(BONITO_REGBASE + 0x4c) + + +/* 6. PCI cache */ + +#define BONITO_PCICACHECTRL BONITO(BONITO_REGBASE + 0x50) +#define BONITO_PCICACHETAG BONITO(BONITO_REGBASE + 0x54) + +#define BONITO_PCIBADADDR BONITO(BONITO_REGBASE + 0x58) +#define BONITO_PCIMSTAT BONITO(BONITO_REGBASE + 0x5c) + + +/* +#define BONITO_PCIRDPOST BONITO(BONITO_REGBASE + 0x60) +#define BONITO_PCIDATA BONITO(BONITO_REGBASE + 0x64) +*/ + +/* 7. IDE DMA & Copier */ + +#define BONITO_CONFIGBASE 0x000 +#define BONITO_BONITOBASE 0x100 +#define BONITO_LDMABASE 0x200 +#define BONITO_COPBASE 0x300 +#define BONITO_REG_BLOCKMASK 0x300 + +#define BONITO_LDMACTRL BONITO(BONITO_LDMABASE + 0x0) +#define BONITO_LDMASTAT BONITO(BONITO_LDMABASE + 0x0) +#define BONITO_LDMAADDR BONITO(BONITO_LDMABASE + 0x4) +#define BONITO_LDMAGO BONITO(BONITO_LDMABASE + 0x8) +#define BONITO_LDMADATA BONITO(BONITO_LDMABASE + 0xc) + +#define BONITO_COPCTRL BONITO(BONITO_COPBASE + 0x0) +#define BONITO_COPSTAT BONITO(BONITO_COPBASE + 0x0) +#define BONITO_COPPADDR BONITO(BONITO_COPBASE + 0x4) +#define BONITO_COPDADDR BONITO(BONITO_COPBASE + 0x8) +#define BONITO_COPGO BONITO(BONITO_COPBASE + 0xc) + + +/* ###### Bit Definitions for individual Registers #### */ + +/* Gen DMA. */ + +#define BONITO_IDECOPDADDR_DMA_DADDR 0x0ffffffc +#define BONITO_IDECOPDADDR_DMA_DADDR_SHIFT 2 +#define BONITO_IDECOPPADDR_DMA_PADDR 0xfffffffc +#define BONITO_IDECOPPADDR_DMA_PADDR_SHIFT 2 +#define BONITO_IDECOPGO_DMA_SIZE 0x0000fffe +#define BONITO_IDECOPGO_DMA_SIZE_SHIFT 0 +#define BONITO_IDECOPGO_DMA_WRITE 0x00010000 +#define BONITO_IDECOPGO_DMAWCOUNT 0x000f0000 +#define BONITO_IDECOPGO_DMAWCOUNT_SHIFT 16 + +#define BONITO_IDECOPCTRL_DMA_STARTBIT 0x80000000 +#define BONITO_IDECOPCTRL_DMA_RSTBIT 0x40000000 + +/* DRAM - sdCfg */ + +#define BONITO_SDCFG_AROWBITS 0x00000003 +#define BONITO_SDCFG_AROWBITS_SHIFT 0 +#define BONITO_SDCFG_ACOLBITS 0x0000000c +#define BONITO_SDCFG_ACOLBITS_SHIFT 2 +#define BONITO_SDCFG_ABANKBIT 0x00000010 +#define BONITO_SDCFG_ASIDES 0x00000020 +#define BONITO_SDCFG_AABSENT 0x00000040 +#define BONITO_SDCFG_AWIDTH64 0x00000080 + +#define BONITO_SDCFG_BROWBITS 0x00000300 +#define BONITO_SDCFG_BROWBITS_SHIFT 8 +#define BONITO_SDCFG_BCOLBITS 0x00000c00 +#define BONITO_SDCFG_BCOLBITS_SHIFT 10 +#define BONITO_SDCFG_BBANKBIT 0x00001000 +#define BONITO_SDCFG_BSIDES 0x00002000 +#define BONITO_SDCFG_BABSENT 0x00004000 +#define BONITO_SDCFG_BWIDTH64 0x00008000 + +#define BONITO_SDCFG_EXTRDDATA 0x00010000 +#define BONITO_SDCFG_EXTRASCAS 0x00020000 +#define BONITO_SDCFG_EXTPRECH 0x00040000 +#define BONITO_SDCFG_EXTRASWIDTH 0x00180000 +#define BONITO_SDCFG_EXTRASWIDTH_SHIFT 19 +/* Changed by RPF 11-9-00 */ +#define BONITO_SDCFG_DRAMMODESET 0x00200000 +/* --- */ +#define BONITO_SDCFG_DRAMEXTREGS 0x00400000 +#define BONITO_SDCFG_DRAMPARITY 0x00800000 +/* Added by RPF 11-9-00 */ +#define BONITO_SDCFG_DRAMBURSTLEN 0x03000000 +#define BONITO_SDCFG_DRAMBURSTLEN_SHIFT 24 +#define BONITO_SDCFG_DRAMMODESET_DONE 0x80000000 +/* --- */ + +/* PCI Cache - pciCacheCtrl */ + +#define BONITO_PCICACHECTRL_CACHECMD 0x00000007 +#define BONITO_PCICACHECTRL_CACHECMD_SHIFT 0 +#define BONITO_PCICACHECTRL_CACHECMDLINE 0x00000018 +#define BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT 3 +#define BONITO_PCICACHECTRL_CMDEXEC 0x00000020 + +#define BONITO_IODEVCFG_BUFFBIT_CS0 0x00000001 +#define BONITO_IODEVCFG_SPEEDBIT_CS0 0x00000002 +#define BONITO_IODEVCFG_MOREABITS_CS0 0x00000004 + +#define BONITO_IODEVCFG_BUFFBIT_CS1 0x00000008 +#define BONITO_IODEVCFG_SPEEDBIT_CS1 0x00000010 +#define BONITO_IODEVCFG_MOREABITS_CS1 0x00000020 + +#define BONITO_IODEVCFG_BUFFBIT_CS2 0x00000040 +#define BONITO_IODEVCFG_SPEEDBIT_CS2 0x00000080 +#define BONITO_IODEVCFG_MOREABITS_CS2 0x00000100 + +#define BONITO_IODEVCFG_BUFFBIT_CS3 0x00000200 +#define BONITO_IODEVCFG_SPEEDBIT_CS3 0x00000400 +#define BONITO_IODEVCFG_MOREABITS_CS3 0x00000800 + +#define BONITO_IODEVCFG_BUFFBIT_IDE 0x00001000 +#define BONITO_IODEVCFG_SPEEDBIT_IDE 0x00002000 +#define BONITO_IODEVCFG_WORDSWAPBIT_IDE 0x00004000 +#define BONITO_IODEVCFG_MODEBIT_IDE 0x00008000 +#define BONITO_IODEVCFG_DMAON_IDE 0x001f0000 +#define BONITO_IODEVCFG_DMAON_IDE_SHIFT 16 +#define BONITO_IODEVCFG_DMAOFF_IDE 0x01e00000 +#define BONITO_IODEVCFG_DMAOFF_IDE_SHIFT 21 +#define BONITO_IODEVCFG_EPROMSPLIT 0x02000000 +/* Added by RPF 11-9-00 */ +#define BONITO_IODEVCFG_CPUCLOCKPERIOD 0xfc000000 +#define BONITO_IODEVCFG_CPUCLOCKPERIOD_SHIFT 26 +/* --- */ + +/* gpio */ +#define BONITO_GPIO_GPIOW 0x000003ff +#define BONITO_GPIO_GPIOW_SHIFT 0 +#define BONITO_GPIO_GPIOR 0x01ff0000 +#define BONITO_GPIO_GPIOR_SHIFT 16 +#define BONITO_GPIO_GPINR 0xfe000000 +#define BONITO_GPIO_GPINR_SHIFT 25 +#define BONITO_GPIO_IOW(N) (1<<(BONITO_GPIO_GPIOW_SHIFT+(N))) +#define BONITO_GPIO_IOR(N) (1<<(BONITO_GPIO_GPIOR_SHIFT+(N))) +#define BONITO_GPIO_INR(N) (1<<(BONITO_GPIO_GPINR_SHIFT+(N))) + +/* ICU */ +#define BONITO_ICU_MBOXES 0x0000000f +#define BONITO_ICU_MBOXES_SHIFT 0 +#define BONITO_ICU_DMARDY 0x00000010 +#define BONITO_ICU_DMAEMPTY 0x00000020 +#define BONITO_ICU_COPYRDY 0x00000040 +#define BONITO_ICU_COPYEMPTY 0x00000080 +#define BONITO_ICU_COPYERR 0x00000100 +#define BONITO_ICU_PCIIRQ 0x00000200 +#define BONITO_ICU_MASTERERR 0x00000400 +#define BONITO_ICU_SYSTEMERR 0x00000800 +#define BONITO_ICU_DRAMPERR 0x00001000 +#define BONITO_ICU_RETRYERR 0x00002000 +#define BONITO_ICU_GPIOS 0x01ff0000 +#define BONITO_ICU_GPIOS_SHIFT 16 +#define BONITO_ICU_GPINS 0x7e000000 +#define BONITO_ICU_GPINS_SHIFT 25 +#define BONITO_ICU_MBOX(N) (1<<(BONITO_ICU_MBOXES_SHIFT+(N))) +#define BONITO_ICU_GPIO(N) (1<<(BONITO_ICU_GPIOS_SHIFT+(N))) +#define BONITO_ICU_GPIN(N) (1<<(BONITO_ICU_GPINS_SHIFT+(N))) + +/* pcimap */ + +#define BONITO_PCIMAP_PCIMAP_LO0 0x0000003f +#define BONITO_PCIMAP_PCIMAP_LO0_SHIFT 0 +#define BONITO_PCIMAP_PCIMAP_LO1 0x00000fc0 +#define BONITO_PCIMAP_PCIMAP_LO1_SHIFT 6 +#define BONITO_PCIMAP_PCIMAP_LO2 0x0003f000 +#define BONITO_PCIMAP_PCIMAP_LO2_SHIFT 12 +#define BONITO_PCIMAP_PCIMAP_2 0x00040000 +#define BONITO_PCIMAP_WIN(WIN,ADDR) ((((ADDR)>>26) & BONITO_PCIMAP_PCIMAP_LO0) << ((WIN)*6)) + +#define BONITO_PCIMAP_WINSIZE (1<<26) +#define BONITO_PCIMAP_WINOFFSET(ADDR) ((ADDR) & (BONITO_PCIMAP_WINSIZE - 1)) +#define BONITO_PCIMAP_WINBASE(ADDR) ((ADDR) << 26) + +/* pcimembaseCfg */ + +#define BONITO_PCIMEMBASECFG_MASK 0xf0000000 +#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK 0x0000001f +#define BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT 0 +#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS 0x000003e0 +#define BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT 5 +#define BONITO_PCIMEMBASECFG_MEMBASE0_CACHED 0x00000400 +#define BONITO_PCIMEMBASECFG_MEMBASE0_IO 0x00000800 + +#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK 0x0001f000 +#define BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT 12 +#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS 0x003e0000 +#define BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT 17 +#define BONITO_PCIMEMBASECFG_MEMBASE1_CACHED 0x00400000 +#define BONITO_PCIMEMBASECFG_MEMBASE1_IO 0x00800000 + +#define BONITO_PCIMEMBASECFG_ASHIFT 23 +#define BONITO_PCIMEMBASECFG_AMASK 0x007fffff +#define BONITO_PCIMEMBASECFGSIZE(WIN,SIZE) (((~((SIZE)-1))>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) +#define BONITO_PCIMEMBASECFGBASE(WIN,BASE) (((BASE)>>(BONITO_PCIMEMBASECFG_ASHIFT-BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) + +#define BONITO_PCIMEMBASECFG_SIZE(WIN,CFG) (((((~(CFG)) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK)) << (BONITO_PCIMEMBASECFG_ASHIFT - BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT)) | BONITO_PCIMEMBASECFG_AMASK) + + +#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) +#define BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) +#define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) + +#define BONITO_PCITOPHYS(WIN,ADDR,CFG) ( \ + (((ADDR) & (~(BONITO_PCIMEMBASECFG_MASK))) & (~(BONITO_PCIMEMBASECFG_ADDRMASK(WIN,CFG)))) | \ + (BONITO_PCIMEMBASECFG_ADDRTRANS(WIN,CFG)) \ + ) + +/* PCICmd */ + +#define BONITO_PCICMD_MEMEN 0x00000002 +#define BONITO_PCICMD_MSTREN 0x00000004 + + +#endif /* _ASM_MIPS_BOARDS_BONITO64_H */ diff -Nru a/include/asm-mips64/mips-boards/generic.h b/include/asm-mips64/mips-boards/generic.h --- a/include/asm-mips64/mips-boards/generic.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/mips-boards/generic.h Fri Jun 27 14:19:57 2003 @@ -25,14 +25,20 @@ #ifndef _MIPS_GENERIC_H #define _MIPS_GENERIC_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/byteorder.h> +#include <asm/mips-boards/bonito64.h> /* * Display register base. */ +#if defined(CONFIG_MIPS_SEAD) +#define ASCII_DISPLAY_POS_BASE (KSEG1ADDR(0x1f0005c0)) +#else #define ASCII_DISPLAY_WORD_BASE (KSEG1ADDR(0x1f000410)) #define ASCII_DISPLAY_POS_BASE (KSEG1ADDR(0x1f000418)) +#endif /* @@ -44,8 +50,28 @@ /* * Reset register. */ +#if defined(CONFIG_MIPS_SEAD) +#define SOFTRES_REG (KSEG1ADDR(0x1e800050)) +#define GORESET 0x4d +#else #define SOFTRES_REG (KSEG1ADDR(0x1f000500)) #define GORESET 0x42 +#endif + +/* + * Revision register. + */ +#define MIPS_REVISION_REG (KSEG1ADDR(0x1fc00010)) +#define MIPS_REVISION_CORID_QED_RM5261 0 +#define MIPS_REVISION_CORID_CORE_LV 1 +#define MIPS_REVISION_CORID_BONITO64 2 +#define MIPS_REVISION_CORID_CORE_20K 3 +#define MIPS_REVISION_CORID_CORE_FPGA 4 +#define MIPS_REVISION_CORID_CORE_MSC 5 + +#define MIPS_REVISION_CORID (((*(volatile u32 *)(MIPS_REVISION_REG)) >> 10) & 0x3f) + +extern unsigned int mips_revision_corid; /* @@ -66,5 +92,20 @@ *(volatile u32 *)(MIPS_GT_BASE+ofs) = data #define GT_PCI_READ(ofs, data) \ data = *(volatile u32 *)(MIPS_GT_BASE+ofs) + +/* + * Algorithmics Bonito64 system controller register base. + */ +static char * const _bonito = (char *)KSEG1ADDR(BONITO_REG_BASE); + +/* + * MIPS System controller PCI register base. + */ +#define MSC01_PCI_REG_BASE (KSEG1ADDR(0x1bd00000)) + +#define MSC_WRITE(reg, data) \ + *(volatile u32 *)(reg) = data +#define MSC_READ(reg, data) \ + data = *(volatile u32 *)(reg) #endif /* !(_MIPS_GENERIC_H) */ diff -Nru a/include/asm-mips64/mips-boards/gt64120.h b/include/asm-mips64/mips-boards/gt64120.h --- a/include/asm-mips64/mips-boards/gt64120.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/mips-boards/gt64120.h Fri Jun 27 14:19:55 2003 @@ -56,7 +56,7 @@ #define GT_PCI1M1LD_OFS 0x0b0 #define GT_PCI1M1HD_OFS 0x0b8 -#define GT_SCS0LD_OFS 0x400 +#define GT_SCS0LD_OFS 0x400 #define GT_SCS0HD_OFS 0x404 #define GT_SCS1LD_OFS 0x408 #define GT_SCS1HD_OFS 0x40c @@ -260,7 +260,7 @@ #define GT_PCI0_BARE_SWSCS32DIS_SHF 1 #define GT_PCI0_BARE_SWSCS32DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS32DIS_SHF) #define GT_PCI0_BARE_SWSCS32DIS_BIT GT_PCI0_BARE_SWSCS32DIS_MSK - + #define GT_PCI0_BARE_SWSCS10DIS_SHF 2 #define GT_PCI0_BARE_SWSCS10DIS_MSK (MSK(1) << GT_PCI0_BARE_SWSCS10DIS_SHF) #define GT_PCI0_BARE_SWSCS10DIS_BIT GT_PCI0_BARE_SWSCS10DIS_MSK diff -Nru a/include/asm-mips64/mips-boards/malta.h b/include/asm-mips64/mips-boards/malta.h --- a/include/asm-mips64/mips-boards/malta.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/mips-boards/malta.h Fri Jun 27 14:19:54 2003 @@ -28,12 +28,29 @@ #include <asm/addrspace.h> #include <asm/io.h> -/* - * Malta I/O ports base address. -*/ -#define MALTA_PORT_BASE (KSEG1ADDR(0x18000000)) +/* + * Malta I/O ports base address for the Galileo GT64120 and Algorithmics + * Bonito system controllers. + */ +#define MALTA_GT_PORT_BASE get_gt_port_base(GT_PCI0IOLD_OFS) +#define MALTA_BONITO_PORT_BASE (KSEG1ADDR(0x1fd00000)) +#define MALTA_MSC_PORT_BASE get_msc_port_base(MSC01_PCI_SC2PIOBASL) + +static inline unsigned long get_gt_port_base(unsigned long reg) +{ + unsigned long addr; + GT_READ(reg, addr); + return KSEG1ADDR((addr & 0xffff) << 21); +} + +static inline unsigned long get_msc_port_base(unsigned long reg) +{ + unsigned long addr; + MSC_READ(reg, addr); + return KSEG1ADDR(addr); +} -/* +/* * Malta RTC-device indirect register access. */ #define MALTA_RTC_ADR_REG 0x70 @@ -55,5 +72,7 @@ #define SMSC_CONFIG_ACTIVATE_ENABLE 1 #define SMSC_WRITE(x,a) outb(x,a) + +#define MALTA_JMPRS_REG (KSEG1ADDR(0x1f000210)) #endif /* !(_MIPS_MALTA_H) */ diff -Nru a/include/asm-mips64/mips-boards/msc01_pci.h b/include/asm-mips64/mips-boards/msc01_pci.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/mips-boards/msc01_pci.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,244 @@ +/* + * mcs01_pci.h + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * PCI Register definitions for the MIPS System Controller. + */ +#ifndef MSC01_PCI_H +#define MSC01_PCI_H + +/***************************************************************************** + * Register offset addresses + ****************************************************************************/ + +#define MSC01_PCI_ID_OFS 0x0000 +#define MSC01_PCI_SC2PMBASL_OFS 0x0208 +#define MSC01_PCI_SC2PMMSKL_OFS 0x0218 +#define MSC01_PCI_SC2PMMAPL_OFS 0x0228 +#define MSC01_PCI_SC2PIOBASL_OFS 0x0248 +#define MSC01_PCI_SC2PIOMSKL_OFS 0x0258 +#define MSC01_PCI_SC2PIOMAPL_OFS 0x0268 +#define MSC01_PCI_P2SCMSKL_OFS 0x0308 +#define MSC01_PCI_P2SCMAPL_OFS 0x0318 +#define MSC01_PCI_INTCFG_OFS 0x0600 +#define MSC01_PCI_INTSTAT_OFS 0x0608 +#define MSC01_PCI_CFGADDR_OFS 0x0610 +#define MSC01_PCI_CFGDATA_OFS 0x0618 +#define MSC01_PCI_IACK_OFS 0x0620 +#define MSC01_PCI_HEAD0_OFS 0x2000 /* DevID, VendorID */ +#define MSC01_PCI_HEAD1_OFS 0x2008 /* Status, Command */ +#define MSC01_PCI_HEAD2_OFS 0x2010 /* Class code, RevID */ +#define MSC01_PCI_HEAD3_OFS 0x2018 /* bist, header, latency */ +#define MSC01_PCI_HEAD4_OFS 0x2020 /* BAR 0 */ +#define MSC01_PCI_HEAD5_OFS 0x2028 /* BAR 1 */ +#define MSC01_PCI_HEAD6_OFS 0x2030 /* BAR 2 */ +#define MSC01_PCI_HEAD7_OFS 0x2038 /* BAR 3 */ +#define MSC01_PCI_HEAD8_OFS 0x2040 /* BAR 4 */ +#define MSC01_PCI_HEAD9_OFS 0x2048 /* BAR 5 */ +#define MSC01_PCI_HEAD10_OFS 0x2050 /* CardBus CIS Ptr */ +#define MSC01_PCI_HEAD11_OFS 0x2058 /* SubSystem ID, -VendorID */ +#define MSC01_PCI_HEAD12_OFS 0x2060 /* ROM BAR */ +#define MSC01_PCI_HEAD13_OFS 0x2068 /* Capabilities ptr */ +#define MSC01_PCI_HEAD14_OFS 0x2070 /* reserved */ +#define MSC01_PCI_HEAD15_OFS 0x2078 /* Maxl, ming, intpin, int */ +#define MSC01_PCI_BAR0_OFS 0x2220 +#define MSC01_PCI_CFG_OFS 0x2380 +#define MSC01_PCI_SWAP_OFS 0x2388 + + +/***************************************************************************** + * Register encodings + ****************************************************************************/ + +#define MSC01_PCI_ID_ID_SHF 16 +#define MSC01_PCI_ID_ID_MSK 0x00ff0000 +#define MSC01_PCI_ID_ID_HOSTBRIDGE 82 +#define MSC01_PCI_ID_MAR_SHF 8 +#define MSC01_PCI_ID_MAR_MSK 0x0000ff00 +#define MSC01_PCI_ID_MIR_SHF 0 +#define MSC01_PCI_ID_MIR_MSK 0x000000ff + +#define MSC01_PCI_SC2PMBASL_BAS_SHF 24 +#define MSC01_PCI_SC2PMBASL_BAS_MSK 0xff000000 + +#define MSC01_PCI_SC2PMMSKL_MSK_SHF 24 +#define MSC01_PCI_SC2PMMSKL_MSK_MSK 0xff000000 + +#define MSC01_PCI_SC2PMMAPL_MAP_SHF 24 +#define MSC01_PCI_SC2PMMAPL_MAP_MSK 0xff000000 + +#define MSC01_PCI_SC2PIOBASL_BAS_SHF 24 +#define MSC01_PCI_SC2PIOBASL_BAS_MSK 0xff000000 + +#define MSC01_PCI_SC2PIOMSKL_MSK_SHF 24 +#define MSC01_PCI_SC2PIOMSKL_MSK_MSK 0xff000000 + +#define MSC01_PCI_SC2PIOMAPL_MAP_SHF 24 +#define MSC01_PCI_SC2PIOMAPL_MAP_MSK 0xff000000 + +#define MSC01_PCI_P2SCMSKL_MSK_SHF 24 +#define MSC01_PCI_P2SCMSKL_MSK_MSK 0xff000000 + +#define MSC01_PCI_P2SCMAPL_MAP_SHF 24 +#define MSC01_PCI_P2SCMAPL_MAP_MSK 0xff000000 + +#define MSC01_PCI_INTCFG_RST_SHF 10 +#define MSC01_PCI_INTCFG_RST_MSK 0x00000400 +#define MSC01_PCI_INTCFG_RST_BIT 0x00000400 +#define MSC01_PCI_INTCFG_MWE_SHF 9 +#define MSC01_PCI_INTCFG_MWE_MSK 0x00000200 +#define MSC01_PCI_INTCFG_MWE_BIT 0x00000200 +#define MSC01_PCI_INTCFG_DTO_SHF 8 +#define MSC01_PCI_INTCFG_DTO_MSK 0x00000100 +#define MSC01_PCI_INTCFG_DTO_BIT 0x00000100 +#define MSC01_PCI_INTCFG_MA_SHF 7 +#define MSC01_PCI_INTCFG_MA_MSK 0x00000080 +#define MSC01_PCI_INTCFG_MA_BIT 0x00000080 +#define MSC01_PCI_INTCFG_TA_SHF 6 +#define MSC01_PCI_INTCFG_TA_MSK 0x00000040 +#define MSC01_PCI_INTCFG_TA_BIT 0x00000040 +#define MSC01_PCI_INTCFG_RTY_SHF 5 +#define MSC01_PCI_INTCFG_RTY_MSK 0x00000020 +#define MSC01_PCI_INTCFG_RTY_BIT 0x00000020 +#define MSC01_PCI_INTCFG_MWP_SHF 4 +#define MSC01_PCI_INTCFG_MWP_MSK 0x00000010 +#define MSC01_PCI_INTCFG_MWP_BIT 0x00000010 +#define MSC01_PCI_INTCFG_MRP_SHF 3 +#define MSC01_PCI_INTCFG_MRP_MSK 0x00000008 +#define MSC01_PCI_INTCFG_MRP_BIT 0x00000008 +#define MSC01_PCI_INTCFG_SWP_SHF 2 +#define MSC01_PCI_INTCFG_SWP_MSK 0x00000004 +#define MSC01_PCI_INTCFG_SWP_BIT 0x00000004 +#define MSC01_PCI_INTCFG_SRP_SHF 1 +#define MSC01_PCI_INTCFG_SRP_MSK 0x00000002 +#define MSC01_PCI_INTCFG_SRP_BIT 0x00000002 +#define MSC01_PCI_INTCFG_SE_SHF 0 +#define MSC01_PCI_INTCFG_SE_MSK 0x00000001 +#define MSC01_PCI_INTCFG_SE_BIT 0x00000001 + +#define MSC01_PCI_INTSTAT_RST_SHF 10 +#define MSC01_PCI_INTSTAT_RST_MSK 0x00000400 +#define MSC01_PCI_INTSTAT_RST_BIT 0x00000400 +#define MSC01_PCI_INTSTAT_MWE_SHF 9 +#define MSC01_PCI_INTSTAT_MWE_MSK 0x00000200 +#define MSC01_PCI_INTSTAT_MWE_BIT 0x00000200 +#define MSC01_PCI_INTSTAT_DTO_SHF 8 +#define MSC01_PCI_INTSTAT_DTO_MSK 0x00000100 +#define MSC01_PCI_INTSTAT_DTO_BIT 0x00000100 +#define MSC01_PCI_INTSTAT_MA_SHF 7 +#define MSC01_PCI_INTSTAT_MA_MSK 0x00000080 +#define MSC01_PCI_INTSTAT_MA_BIT 0x00000080 +#define MSC01_PCI_INTSTAT_TA_SHF 6 +#define MSC01_PCI_INTSTAT_TA_MSK 0x00000040 +#define MSC01_PCI_INTSTAT_TA_BIT 0x00000040 +#define MSC01_PCI_INTSTAT_RTY_SHF 5 +#define MSC01_PCI_INTSTAT_RTY_MSK 0x00000020 +#define MSC01_PCI_INTSTAT_RTY_BIT 0x00000020 +#define MSC01_PCI_INTSTAT_MWP_SHF 4 +#define MSC01_PCI_INTSTAT_MWP_MSK 0x00000010 +#define MSC01_PCI_INTSTAT_MWP_BIT 0x00000010 +#define MSC01_PCI_INTSTAT_MRP_SHF 3 +#define MSC01_PCI_INTSTAT_MRP_MSK 0x00000008 +#define MSC01_PCI_INTSTAT_MRP_BIT 0x00000008 +#define MSC01_PCI_INTSTAT_SWP_SHF 2 +#define MSC01_PCI_INTSTAT_SWP_MSK 0x00000004 +#define MSC01_PCI_INTSTAT_SWP_BIT 0x00000004 +#define MSC01_PCI_INTSTAT_SRP_SHF 1 +#define MSC01_PCI_INTSTAT_SRP_MSK 0x00000002 +#define MSC01_PCI_INTSTAT_SRP_BIT 0x00000002 +#define MSC01_PCI_INTSTAT_SE_SHF 0 +#define MSC01_PCI_INTSTAT_SE_MSK 0x00000001 +#define MSC01_PCI_INTSTAT_SE_BIT 0x00000001 + +#define MSC01_PCI_CFGADDR_BNUM_SHF 16 +#define MSC01_PCI_CFGADDR_BNUM_MSK 0x00ff0000 +#define MSC01_PCI_CFGADDR_DNUM_SHF 11 +#define MSC01_PCI_CFGADDR_DNUM_MSK 0x0000f800 +#define MSC01_PCI_CFGADDR_FNUM_SHF 8 +#define MSC01_PCI_CFGADDR_FNUM_MSK 0x00000700 +#define MSC01_PCI_CFGADDR_RNUM_SHF 2 +#define MSC01_PCI_CFGADDR_RNUM_MSK 0x000000fc + +#define MSC01_PCI_CFGDATA_DATA_SHF 0 +#define MSC01_PCI_CFGDATA_DATA_MSK 0xffffffff + +/* The defines below are ONLY valid for a MEM bar! */ +#define MSC01_PCI_BAR0_SIZE_SHF 4 +#define MSC01_PCI_BAR0_SIZE_MSK 0xfffffff0 +#define MSC01_PCI_BAR0_P_SHF 3 +#define MSC01_PCI_BAR0_P_MSK 0x00000008 +#define MSC01_PCI_BAR0_P_BIT MSC01_PCI_BAR0_P_MSK +#define MSC01_PCI_BAR0_D_SHF 1 +#define MSC01_PCI_BAR0_D_MSK 0x00000006 +#define MSC01_PCI_BAR0_T_SHF 0 +#define MSC01_PCI_BAR0_T_MSK 0x00000001 +#define MSC01_PCI_BAR0_T_BIT MSC01_PCI_BAR0_T_MSK + + +#define MSC01_PCI_CFG_RA_SHF 17 +#define MSC01_PCI_CFG_RA_MSK 0x00020000 +#define MSC01_PCI_CFG_RA_BIT MSC01_PCI_CFG_RA_MSK +#define MSC01_PCI_CFG_G_SHF 16 +#define MSC01_PCI_CFG_G_MSK 0x00010000 +#define MSC01_PCI_CFG_G_BIT MSC01_PCI_CFG_G_MSK +#define MSC01_PCI_CFG_EN_SHF 15 +#define MSC01_PCI_CFG_EN_MSK 0x00008000 +#define MSC01_PCI_CFG_EN_BIT MSC01_PCI_CFG_EN_MSK +#define MSC01_PCI_CFG_MAXRTRY_SHF 0 +#define MSC01_PCI_CFG_MAXRTRY_MSK 0x000000ff + +#define MSC01_PCI_SWAP_IO_SHF 18 +#define MSC01_PCI_SWAP_IO_MSK 0x000c0000 +#define MSC01_PCI_SWAP_MEM_SHF 16 +#define MSC01_PCI_SWAP_MEM_MSK 0x00030000 +#define MSC01_PCI_SWAP_BAR0_SHF 0 +#define MSC01_PCI_SWAP_BAR0_MSK 0x00000003 +#define MSC01_PCI_SWAP_NOSWAP 0 +#define MSC01_PCI_SWAP_BYTESWAP 1 + +/***************************************************************************** + * Registers absolute addresses + ****************************************************************************/ + +#define MSC01_PCI_ID (MSC01_PCI_REG_BASE + MSC01_PCI_ID_OFS) +#define MSC01_PCI_SC2PMBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMBASL_OFS) +#define MSC01_PCI_SC2PMMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMSKL_OFS) +#define MSC01_PCI_SC2PMMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PMMAPL_OFS) +#define MSC01_PCI_SC2PIOBASL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOBASL_OFS) +#define MSC01_PCI_SC2PIOMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMSKL_OFS) +#define MSC01_PCI_SC2PIOMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_SC2PIOMAPL_OFS) +#define MSC01_PCI_P2SCMSKL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMSKL_OFS) +#define MSC01_PCI_P2SCMAPL (MSC01_PCI_REG_BASE + MSC01_PCI_P2SCMAPL_OFS) +#define MSC01_PCI_INTCFG (MSC01_PCI_REG_BASE + MSC01_PCI_INTCFG_OFS) +#define MSC01_PCI_INTSTAT (MSC01_PCI_REG_BASE + MSC01_PCI_INTSTAT_OFS) +#define MSC01_PCI_CFGADDR (MSC01_PCI_REG_BASE + MSC01_PCI_CFGADDR_OFS) +#define MSC01_PCI_CFGDATA (MSC01_PCI_REG_BASE + MSC01_PCI_CFGDATA_OFS) +#define MSC01_PCI_IACK (MSC01_PCI_REG_BASE + MSC01_PCI_IACK_OFS) +#define MSC01_PCI_HEAD0 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD0_OFS) +#define MSC01_PCI_HEAD1 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD1_OFS) +#define MSC01_PCI_HEAD2 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD2_OFS) +#define MSC01_PCI_HEAD3 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD3_OFS) +#define MSC01_PCI_HEAD4 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD4_OFS) +#define MSC01_PCI_HEAD5 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD5_OFS) +#define MSC01_PCI_HEAD6 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD6_OFS) +#define MSC01_PCI_HEAD7 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD7_OFS) +#define MSC01_PCI_HEAD8 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD8_OFS) +#define MSC01_PCI_HEAD9 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD9_OFS) +#define MSC01_PCI_HEAD10 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD10_OFS) +#define MSC01_PCI_HEAD11 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD12 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD13 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD14 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_HEAD15 (MSC01_PCI_REG_BASE + MSC01_PCI_HEAD11_OFS) +#define MSC01_PCI_BAR0 (MSC01_PCI_REG_BASE + MSC01_PCI_BAR0_OFS) +#define MSC01_PCI_CFG (MSC01_PCI_REG_BASE + MSC01_PCI_CFG_OFS) +#define MSC01_PCI_SWAP (MSC01_PCI_REG_BASE + MSC01_PCI_SWAP_OFS) + +#endif +/***************************************************************************** + * End of msc01_pci.h + *****************************************************************************/ diff -Nru a/include/asm-mips64/mips-boards/sead.h b/include/asm-mips64/mips-boards/sead.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/mips-boards/sead.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,36 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Defines of the SEAD board specific address-MAP, registers, etc. + * + */ +#ifndef _MIPS_SEAD_H +#define _MIPS_SEAD_H + +#include <asm/addrspace.h> + +/* + * SEAD UART register base. + */ +#define SEAD_UART0_REGS_BASE (0x1f000800) +#define SEAD_BASE_BAUD ( 3686400 / 16 ) + +#endif /* !(_MIPS_SEAD_H) */ diff -Nru a/include/asm-mips64/mips-boards/seadint.h b/include/asm-mips64/mips-boards/seadint.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/mips-boards/seadint.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,35 @@ +/* + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. + * + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * ######################################################################## + * + * Defines for the SEAD interrupt controller. + * + */ +#ifndef _MIPS_SEADINT_H +#define _MIPS_SEADINT_H + +/* Number of IRQ supported */ +#define SEADINT_UART0 0 +#define SEADINT_UART1 1 +#define SEADINT_END 2 + +extern void seadint_init(void); + +#endif /* !(_MIPS_SEADINT_H) */ diff -Nru a/include/asm-mips64/mipsregs.h b/include/asm-mips64/mipsregs.h --- a/include/asm-mips64/mipsregs.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips64/mipsregs.h Fri Jun 27 14:20:00 2003 @@ -3,13 +3,17 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994, 1995, 1996, 1997, 1999 by Ralf Baechle + * Copyright (C) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle + * Copyright (C) 2000 Silicon Graphics, Inc. * Modified for further R[236]000 support by Paul M. Antoine, 1996. - * Copyright (C) 1999 Silicon Graphics, Inc. + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com + * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2003 Maciej W. Rozycki */ #ifndef _ASM_MIPSREGS_H #define _ASM_MIPSREGS_H +#include <linux/config.h> #include <linux/linkage.h> /* @@ -24,12 +28,22 @@ #endif /* + * Configure language + */ +#ifdef __ASSEMBLY__ +#define _ULCAST_ +#else +#define _ULCAST_ (unsigned long) +#endif + +/* * Coprocessor 0 register names */ #define CP0_INDEX $0 #define CP0_RANDOM $1 #define CP0_ENTRYLO0 $2 #define CP0_ENTRYLO1 $3 +#define CP0_CONF $3 #define CP0_CONTEXT $4 #define CP0_PAGEMASK $5 #define CP0_WIRED $6 @@ -49,12 +63,41 @@ #define CP0_XCONTEXT $20 #define CP0_FRAMEMASK $21 #define CP0_DIAGNOSTIC $22 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 #define CP0_PERFORMANCE $25 #define CP0_ECC $26 #define CP0_CACHEERR $27 #define CP0_TAGLO $28 #define CP0_TAGHI $29 #define CP0_ERROREPC $30 +#define CP0_DESAVE $31 + +/* + * R4640/R4650 cp0 register names. These registers are listed + * here only for completeness; without MMU these CPUs are not useable + * by Linux. A future ELKS port might take make Linux run on them + * though ... + */ +#define CP0_IBASE $0 +#define CP0_IBOUND $1 +#define CP0_DBASE $2 +#define CP0_DBOUND $3 +#define CP0_CALG $17 +#define CP0_IWATCH $18 +#define CP0_DWATCH $19 + +/* + * Coprocessor 0 Set 1 register names + */ +#define CP0_S1_DERRADDR0 $26 +#define CP0_S1_DERRADDR1 $27 +#define CP0_S1_INTCONTROL $20 + +/* + * TX39 Series + */ +#define CP0_TX39_CACHE $7 /* * Coprocessor 1 (FPU) register names @@ -63,106 +106,120 @@ #define CP1_STATUS $31 /* - * Values for PageMask register + * FPU Status Register Values */ -#define PM_4K 0x00000000 -#define PM_16K 0x00006000 -#define PM_64K 0x0001e000 -#define PM_256K 0x0007e000 -#define PM_1M 0x001fe000 -#define PM_4M 0x007fe000 -#define PM_16M 0x01ffe000 - /* - * Values used for computation of new tlb entries + * Status Register Values */ -#define PL_4K 12 -#define PL_16K 14 -#define PL_64K 16 -#define PL_256K 18 -#define PL_1M 20 -#define PL_4M 22 -#define PL_16M 24 + +#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */ +#define FPU_CSR_COND 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND0 0x00800000 /* $fcc0 */ +#define FPU_CSR_COND1 0x02000000 /* $fcc1 */ +#define FPU_CSR_COND2 0x04000000 /* $fcc2 */ +#define FPU_CSR_COND3 0x08000000 /* $fcc3 */ +#define FPU_CSR_COND4 0x10000000 /* $fcc4 */ +#define FPU_CSR_COND5 0x20000000 /* $fcc5 */ +#define FPU_CSR_COND6 0x40000000 /* $fcc6 */ +#define FPU_CSR_COND7 0x80000000 /* $fcc7 */ + +/* + * X the exception cause indicator + * E the exception enable + * S the sticky/flag bit +*/ +#define FPU_CSR_ALL_X 0x0003f000 +#define FPU_CSR_UNI_X 0x00020000 +#define FPU_CSR_INV_X 0x00010000 +#define FPU_CSR_DIV_X 0x00008000 +#define FPU_CSR_OVF_X 0x00004000 +#define FPU_CSR_UDF_X 0x00002000 +#define FPU_CSR_INE_X 0x00001000 + +#define FPU_CSR_ALL_E 0x00000f80 +#define FPU_CSR_INV_E 0x00000800 +#define FPU_CSR_DIV_E 0x00000400 +#define FPU_CSR_OVF_E 0x00000200 +#define FPU_CSR_UDF_E 0x00000100 +#define FPU_CSR_INE_E 0x00000080 + +#define FPU_CSR_ALL_S 0x0000007c +#define FPU_CSR_INV_S 0x00000040 +#define FPU_CSR_DIV_S 0x00000020 +#define FPU_CSR_OVF_S 0x00000010 +#define FPU_CSR_UDF_S 0x00000008 +#define FPU_CSR_INE_S 0x00000004 + +/* rounding mode */ +#define FPU_CSR_RN 0x0 /* nearest */ +#define FPU_CSR_RZ 0x1 /* towards zero */ +#define FPU_CSR_RU 0x2 /* towards +Infinity */ +#define FPU_CSR_RD 0x3 /* towards -Infinity */ + /* - * Macros to access the system control coprocessor + * Values for PageMask register */ -#define read_32bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - "mfc0\t%0,"STR(source) \ - : "=r" (__res)); \ - __res;}) +#ifdef CONFIG_CPU_VR41XX -#define read_64bit_cp0_register(source) \ -({ int __res; \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmfc0\t%0,"STR(source)"\n\t" \ - ".set\tmips0" \ - : "=r" (__res)); \ - __res;}) +/* Why doesn't stupidity hurt ... */ -#define write_32bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - "mtc0\t%0,"STR(register) \ - : : "r" (value)); +#define PM_1K 0x00000000 +#define PM_4K 0x00001800 +#define PM_16K 0x00007800 +#define PM_64K 0x0001f800 +#define PM_256K 0x0007f800 + +#else + +#define PM_4K 0x00000000 +#define PM_16K 0x00006000 +#define PM_64K 0x0001e000 +#define PM_256K 0x0007e000 +#define PM_1M 0x001fe000 +#define PM_4M 0x007fe000 +#define PM_16M 0x01ffe000 +#define PM_64M 0x07ffe000 +#define PM_256M 0x1fffe000 -#define write_64bit_cp0_register(register,value) \ - __asm__ __volatile__( \ - ".set\tmips3\n\t" \ - "dmtc0\t%0,"STR(register)"\n\t" \ - ".set\tmips0" \ - : : "r" (value)) +#endif + +/* + * Values used for computation of new tlb entries + */ +#define PL_4K 12 +#define PL_16K 14 +#define PL_64K 16 +#define PL_256K 18 +#define PL_1M 20 +#define PL_4M 22 +#define PL_16M 24 +#define PL_64M 26 +#define PL_256M 28 /* * R4x00 interrupt enable / cause bits */ -#define IE_SW0 (1<< 8) -#define IE_SW1 (1<< 9) -#define IE_IRQ0 (1<<10) -#define IE_IRQ1 (1<<11) -#define IE_IRQ2 (1<<12) -#define IE_IRQ3 (1<<13) -#define IE_IRQ4 (1<<14) -#define IE_IRQ5 (1<<15) +#define IE_SW0 (_ULCAST_(1) << 8) +#define IE_SW1 (_ULCAST_(1) << 9) +#define IE_IRQ0 (_ULCAST_(1) << 10) +#define IE_IRQ1 (_ULCAST_(1) << 11) +#define IE_IRQ2 (_ULCAST_(1) << 12) +#define IE_IRQ3 (_ULCAST_(1) << 13) +#define IE_IRQ4 (_ULCAST_(1) << 14) +#define IE_IRQ5 (_ULCAST_(1) << 15) /* * R4x00 interrupt cause bits */ -#define C_SW0 (1<< 8) -#define C_SW1 (1<< 9) -#define C_IRQ0 (1<<10) -#define C_IRQ1 (1<<11) -#define C_IRQ2 (1<<12) -#define C_IRQ3 (1<<13) -#define C_IRQ4 (1<<14) -#define C_IRQ5 (1<<15) - -#ifndef _LANGUAGE_ASSEMBLY -/* - * Manipulate the status register. - * Mostly used to access the interrupt bits. - */ -#define __BUILD_SET_CP0(name,register) \ -extern __inline__ unsigned int \ -set_cp0_##name(unsigned int change, unsigned int new) \ -{ \ - unsigned int res; \ - \ - res = read_32bit_cp0_register(register); \ - res &= ~change; \ - res |= (new & change); \ - write_32bit_cp0_register(register, res); \ - \ - return res; \ -} - -__BUILD_SET_CP0(status,CP0_STATUS) -__BUILD_SET_CP0(cause,CP0_CAUSE) -__BUILD_SET_CP0(config,CP0_CONFIG) - -#endif /* defined (_LANGUAGE_ASSEMBLY) */ +#define C_SW0 (_ULCAST_(1) << 8) +#define C_SW1 (_ULCAST_(1) << 9) +#define C_IRQ0 (_ULCAST_(1) << 10) +#define C_IRQ1 (_ULCAST_(1) << 11) +#define C_IRQ2 (_ULCAST_(1) << 12) +#define C_IRQ3 (_ULCAST_(1) << 13) +#define C_IRQ4 (_ULCAST_(1) << 14) +#define C_IRQ5 (_ULCAST_(1) << 15) /* * Bitfields in the R4xx0 cp0 status register @@ -181,25 +238,95 @@ #define ST0_CE 0x00020000 /* + * Bitfields in the R[23]000 cp0 status register. + */ +#define ST0_IEC 0x00000001 +#define ST0_KUC 0x00000002 +#define ST0_IEP 0x00000004 +#define ST0_KUP 0x00000008 +#define ST0_IEO 0x00000010 +#define ST0_KUO 0x00000020 +/* bits 6 & 7 are reserved on R[23]000 */ +#define ST0_ISC 0x00010000 +#define ST0_SWC 0x00020000 +#define ST0_CM 0x00080000 + +/* + * Bits specific to the R4640/R4650 + */ +#define ST0_UM (_ULCAST_(1) << 4) +#define ST0_IL (_ULCAST_(1) << 23) +#define ST0_DL (_ULCAST_(1) << 24) + +/* + * Bitfields in the TX39 family CP0 Configuration Register 3 + */ +#define TX39_CONF_ICS_SHIFT 19 +#define TX39_CONF_ICS_MASK 0x00380000 +#define TX39_CONF_ICS_1KB 0x00000000 +#define TX39_CONF_ICS_2KB 0x00080000 +#define TX39_CONF_ICS_4KB 0x00100000 +#define TX39_CONF_ICS_8KB 0x00180000 +#define TX39_CONF_ICS_16KB 0x00200000 + +#define TX39_CONF_DCS_SHIFT 16 +#define TX39_CONF_DCS_MASK 0x00070000 +#define TX39_CONF_DCS_1KB 0x00000000 +#define TX39_CONF_DCS_2KB 0x00010000 +#define TX39_CONF_DCS_4KB 0x00020000 +#define TX39_CONF_DCS_8KB 0x00030000 +#define TX39_CONF_DCS_16KB 0x00040000 + +#define TX39_CONF_CWFON 0x00004000 +#define TX39_CONF_WBON 0x00002000 +#define TX39_CONF_RF_SHIFT 10 +#define TX39_CONF_RF_MASK 0x00000c00 +#define TX39_CONF_DOZE 0x00000200 +#define TX39_CONF_HALT 0x00000100 +#define TX39_CONF_LOCK 0x00000080 +#define TX39_CONF_ICE 0x00000020 +#define TX39_CONF_DCE 0x00000010 +#define TX39_CONF_IRSIZE_SHIFT 2 +#define TX39_CONF_IRSIZE_MASK 0x0000000c +#define TX39_CONF_DRSIZE_SHIFT 0 +#define TX39_CONF_DRSIZE_MASK 0x00000003 + +/* * Status register bits available in all MIPS CPUs. */ #define ST0_IM 0x0000ff00 #define STATUSB_IP0 8 -#define STATUSF_IP0 (1 << 8) +#define STATUSF_IP0 (_ULCAST_(1) << 8) #define STATUSB_IP1 9 -#define STATUSF_IP1 (1 << 9) +#define STATUSF_IP1 (_ULCAST_(1) << 9) #define STATUSB_IP2 10 -#define STATUSF_IP2 (1 << 10) +#define STATUSF_IP2 (_ULCAST_(1) << 10) #define STATUSB_IP3 11 -#define STATUSF_IP3 (1 << 11) +#define STATUSF_IP3 (_ULCAST_(1) << 11) #define STATUSB_IP4 12 -#define STATUSF_IP4 (1 << 12) +#define STATUSF_IP4 (_ULCAST_(1) << 12) #define STATUSB_IP5 13 -#define STATUSF_IP5 (1 << 13) +#define STATUSF_IP5 (_ULCAST_(1) << 13) #define STATUSB_IP6 14 -#define STATUSF_IP6 (1 << 14) +#define STATUSF_IP6 (_ULCAST_(1) << 14) #define STATUSB_IP7 15 -#define STATUSF_IP7 (1 << 15) +#define STATUSF_IP7 (_ULCAST_(1) << 15) +#define STATUSB_IP8 0 +#define STATUSF_IP8 (_ULCAST_(1) << 0) +#define STATUSB_IP9 1 +#define STATUSF_IP9 (_ULCAST_(1) << 1) +#define STATUSB_IP10 2 +#define STATUSF_IP10 (_ULCAST_(1) << 2) +#define STATUSB_IP11 3 +#define STATUSF_IP11 (_ULCAST_(1) << 3) +#define STATUSB_IP12 4 +#define STATUSF_IP12 (_ULCAST_(1) << 4) +#define STATUSB_IP13 5 +#define STATUSF_IP13 (_ULCAST_(1) << 5) +#define STATUSB_IP14 6 +#define STATUSF_IP14 (_ULCAST_(1) << 6) +#define STATUSB_IP15 7 +#define STATUSF_IP15 (_ULCAST_(1) << 7) #define ST0_CH 0x00040000 #define ST0_SR 0x00100000 #define ST0_TS 0x00200000 @@ -219,35 +346,36 @@ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation. */ #define CAUSEB_EXCCODE 2 -#define CAUSEF_EXCCODE (31 << 2) +#define CAUSEF_EXCCODE (_ULCAST_(31) << 2) #define CAUSEB_IP 8 -#define CAUSEF_IP (255 << 8) +#define CAUSEF_IP (_ULCAST_(255) << 8) #define CAUSEB_IP0 8 -#define CAUSEF_IP0 (1 << 8) +#define CAUSEF_IP0 (_ULCAST_(1) << 8) #define CAUSEB_IP1 9 -#define CAUSEF_IP1 (1 << 9) +#define CAUSEF_IP1 (_ULCAST_(1) << 9) #define CAUSEB_IP2 10 -#define CAUSEF_IP2 (1 << 10) +#define CAUSEF_IP2 (_ULCAST_(1) << 10) #define CAUSEB_IP3 11 -#define CAUSEF_IP3 (1 << 11) +#define CAUSEF_IP3 (_ULCAST_(1) << 11) #define CAUSEB_IP4 12 -#define CAUSEF_IP4 (1 << 12) +#define CAUSEF_IP4 (_ULCAST_(1) << 12) #define CAUSEB_IP5 13 -#define CAUSEF_IP5 (1 << 13) +#define CAUSEF_IP5 (_ULCAST_(1) << 13) #define CAUSEB_IP6 14 -#define CAUSEF_IP6 (1 << 14) +#define CAUSEF_IP6 (_ULCAST_(1) << 14) #define CAUSEB_IP7 15 -#define CAUSEF_IP7 (1 << 15) +#define CAUSEF_IP7 (_ULCAST_(1) << 15) #define CAUSEB_IV 23 -#define CAUSEF_IV (1 << 23) +#define CAUSEF_IV (_ULCAST_(1) << 23) #define CAUSEB_CE 28 -#define CAUSEF_CE (3 << 28) +#define CAUSEF_CE (_ULCAST_(3) << 28) #define CAUSEB_BD 31 -#define CAUSEF_BD (1 << 31) +#define CAUSEF_BD (_ULCAST_(1) << 31) /* * Bits in the coprocessor 0 config register. */ +/* Generic bits. */ #define CONF_CM_CACHABLE_NO_WA 0 #define CONF_CM_CACHABLE_WA 1 #define CONF_CM_UNCACHED 2 @@ -257,15 +385,78 @@ #define CONF_CM_CACHABLE_CUW 6 #define CONF_CM_CACHABLE_ACCELERATED 7 #define CONF_CM_CMASK 7 -#define CONF_DB (1 << 4) -#define CONF_IB (1 << 5) -#define CONF_SC (1 << 17) +#define CONF_BE (_ULCAST_(1) << 15) + +/* Bits common to various processors. */ +#define CONF_CU (_ULCAST_(1) << 3) +#define CONF_DB (_ULCAST_(1) << 4) +#define CONF_IB (_ULCAST_(1) << 5) +#define CONF_DC (_ULCAST_(7) << 6) +#define CONF_IC (_ULCAST_(7) << 9) +#define CONF_EB (_ULCAST_(1) << 13) +#define CONF_EM (_ULCAST_(1) << 14) +#define CONF_SM (_ULCAST_(1) << 16) +#define CONF_SC (_ULCAST_(1) << 17) +#define CONF_EW (_ULCAST_(3) << 18) +#define CONF_EP (_ULCAST_(15)<< 24) +#define CONF_EC (_ULCAST_(7) << 28) +#define CONF_CM (_ULCAST_(1) << 31) + +/* Bits specific to the R4xx0. */ +#define R4K_CONF_SW (_ULCAST_(1) << 20) +#define R4K_CONF_SS (_ULCAST_(1) << 21) +#define R4K_CONF_SB (_ULCAST_(3) << 22) + +/* Bits specific to the R5000. */ +#define R5K_CONF_SE (_ULCAST_(1) << 12) +#define R5K_CONF_SS (_ULCAST_(3) << 20) + +/* Bits specific to the R10000. */ +#define R10K_CONF_DN (_ULCAST_(3) << 3) +#define R10K_CONF_CT (_ULCAST_(1) << 5) +#define R10K_CONF_PE (_ULCAST_(1) << 6) +#define R10K_CONF_PM (_ULCAST_(3) << 7) +#define R10K_CONF_EC (_ULCAST_(15)<< 9) +#define R10K_CONF_SB (_ULCAST_(1) << 13) +#define R10K_CONF_SK (_ULCAST_(1) << 14) +#define R10K_CONF_SS (_ULCAST_(7) << 16) +#define R10K_CONF_SC (_ULCAST_(7) << 19) +#define R10K_CONF_DC (_ULCAST_(7) << 26) +#define R10K_CONF_IC (_ULCAST_(7) << 29) + +/* Bits specific to the VR41xx. */ +#define VR41_CONF_CS (_ULCAST_(1) << 12) +#define VR41_CONF_M16 (_ULCAST_(1) << 20) +#define VR41_CONF_AD (_ULCAST_(1) << 23) + +/* Bits specific to the R30xx. */ +#define R30XX_CONF_FDM (_ULCAST_(1) << 19) +#define R30XX_CONF_REV (_ULCAST_(1) << 22) +#define R30XX_CONF_AC (_ULCAST_(1) << 23) +#define R30XX_CONF_RF (_ULCAST_(1) << 24) +#define R30XX_CONF_HALT (_ULCAST_(1) << 25) +#define R30XX_CONF_FPINT (_ULCAST_(7) << 26) +#define R30XX_CONF_DBR (_ULCAST_(1) << 29) +#define R30XX_CONF_SB (_ULCAST_(1) << 30) +#define R30XX_CONF_LOCK (_ULCAST_(1) << 31) + +/* Bits specific to the TX49. */ +#define TX49_CONF_DC (_ULCAST_(1) << 16) +#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */ +#define TX49_CONF_HALT (_ULCAST_(1) << 18) +#define TX49_CONF_CWFON (_ULCAST_(1) << 27) + +/* Bits specific to the MIPS32/64 PRA. */ +#define MIPS_CONF_MT (_ULCAST_(7) << 7) +#define MIPS_CONF_AR (_ULCAST_(7) << 10) +#define MIPS_CONF_AT (_ULCAST_(3) << 13) +#define MIPS_CONF_M (_ULCAST_(1) << 31) /* * R10000 performance counter definitions. * * FIXME: The R10000 performance counter opens a nice way to implement CPU - * time accounting with a precision of one cycle. I don't have + * time accounting with a precission of one cycle. I don't have * R10000 silicon but just a manual, so ... */ @@ -317,14 +508,394 @@ #define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */ #define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ + /* - * Functions to access the performance counter and control registers + * Functions to access the r10k performance counter and control registers */ -extern asmlinkage unsigned int read_perf_cntr(unsigned int counter); -extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val); -extern asmlinkage unsigned int read_perf_cntl(unsigned int counter); -extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val); -#endif +#define read_r10k_perf_cntr(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfpc\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntr(counter,val) \ + __asm__ __volatile__( \ + "mtpc\t%0, "STR(counter) \ + : : "r" (val)); + +#define read_r10k_perf_cntl(counter) \ +({ unsigned int __res; \ + __asm__ __volatile__( \ + "mfps\t%0, "STR(counter) \ + : "=r" (__res)); \ + __res;}) + +#define write_r10k_perf_cntl(counter,val) \ + __asm__ __volatile__( \ + "mtps\t%0, "STR(counter) \ + : : "r" (val)); + +/* + * Macros to access the system control coprocessor + */ + +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __read_64bit_c0_register(source, sel) \ +({ unsigned long __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmfc0\t%0, " #source "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __write_64bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips3\n\t" \ + "dmtc0\t%z0, " #register "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" (value)); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + ((sizeof(unsigned long) == 4) ? \ + __read_32bit_c0_register(reg, sel) : \ + __read_64bit_c0_register(reg, sel)) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + if (sizeof(unsigned long) == 4) \ + __write_32bit_c0_register(reg, sel, val); \ + else \ + __write_64bit_c0_register(reg, sel, val); \ +} while (0) + +/* + * These versions are only needed for systems with more than 38 bits of + * physical address space running the 32-bit kernel. That's none atm :-) + */ +#define __read_64bit_c0_split(source, sel) \ +({ \ + unsigned long long val; \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dmfc0\t%M0, " #source ", " #sel "\n\t" \ + "dsll\t%L0, %M0, 32\n\t" \ + "dsrl\t%M0, %M0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + ".set\tmips0" \ + : "=r" (val)); \ + local_irq_restore(flags); \ + \ + val; \ +}) + +#define __write_64bit_c0_split(source, sel, val) \ +do { \ + unsigned long flags; \ + \ + local_irq_save(flags); \ + if (sel == 0) \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips64\n\t" \ + "dsll\t%L0, %L0, 32\n\t" \ + "dsrl\t%L0, %L0, 32\n\t" \ + "dsll\t%M0, %M0, 32\n\t" \ + "or\t%L0, %L0, %M0\n\t" \ + "dmtc0\t%L0, " #source ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "r" (val)); \ + local_irq_restore(flags); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ +#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define read_c0_config3() __read_32bit_c0_register($16, 3) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) +#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val) + +/* + * The WatchLo register. There may be upto 8 of them. + */ +#define read_c0_watchlo0() __read_ulong_c0_register($18, 0) +#define read_c0_watchlo1() __read_ulong_c0_register($18, 1) +#define read_c0_watchlo2() __read_ulong_c0_register($18, 2) +#define read_c0_watchlo3() __read_ulong_c0_register($18, 3) +#define read_c0_watchlo4() __read_ulong_c0_register($18, 4) +#define read_c0_watchlo5() __read_ulong_c0_register($18, 5) +#define read_c0_watchlo6() __read_ulong_c0_register($18, 6) +#define read_c0_watchlo7() __read_ulong_c0_register($18, 7) +#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val) +#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val) +#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val) +#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val) +#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val) +#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val) +#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val) +#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val) + +/* + * The WatchHi register. There may be upto 8 of them. + */ +#define read_c0_watchhi0() __read_32bit_c0_register($19, 0) +#define read_c0_watchhi1() __read_32bit_c0_register($19, 1) +#define read_c0_watchhi2() __read_32bit_c0_register($19, 2) +#define read_c0_watchhi3() __read_32bit_c0_register($19, 3) +#define read_c0_watchhi4() __read_32bit_c0_register($19, 4) +#define read_c0_watchhi5() __read_32bit_c0_register($19, 5) +#define read_c0_watchhi6() __read_32bit_c0_register($19, 6) +#define read_c0_watchhi7() __read_32bit_c0_register($19, 7) + +#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val) +#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val) +#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val) +#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val) +#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val) +#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val) +#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val) +#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_register($20, 1) +#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +#define read_c0_debug() __read_32bit_c0_register($23, 0) +#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val) + +#define read_c0_depc() __read_ulong_c0_register($24, 0) +#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val) + +#define read_c0_ecc() __read_32bit_c0_register($26, 0) +#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val) + +#define read_c0_derraddr0() __read_ulong_c0_register($26, 1) +#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val) + +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_derraddr1() __read_ulong_c0_register($27, 1) +#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* + * Macros to access the floating point coprocessor control registers + */ +#define read_32bit_cp1_register(source) \ +({ int __res; \ + __asm__ __volatile__( \ + ".set\tpush\n\t" \ + ".set\treorder\n\t" \ + "cfc1\t%0,"STR(source)"\n\t" \ + ".set\tpop" \ + : "=r" (__res)); \ + __res;}) + +/* TLB operations. */ +static inline void tlb_probe(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbp\n\t" + ".set reorder"); +} + +static inline void tlb_read(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbr\n\t" + ".set reorder"); +} + +static inline void tlb_write_indexed(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwi\n\t" + ".set reorder"); +} + +static inline void tlb_write_random(void) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + "tlbwr\n\t" + ".set reorder"); +} + +/* + * Manipulate bits in a c0 register. + */ +#define __BUILD_SET_C0(name,register) \ +static inline unsigned int \ +set_c0_##name(unsigned int set) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res |= set; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +clear_c0_##name(unsigned int clear) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~clear; \ + write_c0_##name(res); \ + \ + return res; \ +} \ + \ +static inline unsigned int \ +change_c0_##name(unsigned int change, unsigned int new) \ +{ \ + unsigned int res; \ + \ + res = read_c0_##name(); \ + res &= ~change; \ + res |= (new & change); \ + write_c0_##name(res); \ + \ + return res; \ +} + +__BUILD_SET_C0(status,CP0_STATUS) +__BUILD_SET_C0(cause,CP0_CAUSE) +__BUILD_SET_C0(config,CP0_CONFIG) + +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_MIPSREGS_H */ diff -Nru a/include/asm-mips64/mman.h b/include/asm-mips64/mman.h --- a/include/asm-mips64/mman.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/mman.h Fri Jun 27 14:19:56 2003 @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1995, 1999 by Ralf Baechle + * Copyright (C) 1995, 1999, 2002 by Ralf Baechle */ #ifndef _ASM_MMAN_H #define _ASM_MMAN_H @@ -14,10 +14,12 @@ * without PROT_READ. The only guarantees are that no writing will be * allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */ -#define PROT_NONE 0x0 /* page can not be accessed */ -#define PROT_READ 0x1 /* page can be read */ -#define PROT_WRITE 0x2 /* page can be written */ -#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_NONE 0x00 /* page can not be accessed */ +#define PROT_READ 0x01 /* page can be read */ +#define PROT_WRITE 0x02 /* page can be written */ +#define PROT_EXEC 0x04 /* page can be executed */ +/* 0x08 reserved for PROT_EXEC_NOFLUSH */ +#define PROT_SEM 0x10 /* page may be used for atomic ops */ /* * Flags for mmap @@ -40,6 +42,8 @@ #define MAP_DENYWRITE 0x2000 /* ETXTBSY */ #define MAP_EXECUTABLE 0x4000 /* mark it as an executable */ #define MAP_LOCKED 0x8000 /* pages are locked */ +#define MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x20000 /* do not block on IO */ /* * Flags for msync diff -Nru a/include/asm-mips64/mmu.h b/include/asm-mips64/mmu.h --- a/include/asm-mips64/mmu.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/mmu.h Fri Jun 27 14:19:53 2003 @@ -1,7 +1,6 @@ -#ifndef __MMU_H -#define __MMU_H +#ifndef __ASM_MMU_H +#define __ASM_MMU_H -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; +typedef unsigned long mm_context_t[NR_CPUS]; -#endif +#endif /* __ASM_MMU_H */ diff -Nru a/include/asm-mips64/mmu_context.h b/include/asm-mips64/mmu_context.h --- a/include/asm-mips64/mmu_context.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/mmu_context.h Fri Jun 27 14:19:53 2003 @@ -12,14 +12,16 @@ #define _ASM_MMU_CONTEXT_H #include <linux/config.h> +#include <linux/errno.h> +#include <linux/sched.h> #include <linux/slab.h> -#include <asm/pgalloc.h> -#include <asm/processor.h> +#include <asm/cacheflush.h> +#include <asm/tlbflush.h> /* * For the fast tlb miss handlers, we currently keep a per cpu array * of pointers to the current pgd for each processor. Also, the proc. - * id is stuffed into the context register. This should be changed to + * id is stuffed into the context register. This should be changed to * use the processor id via current->processor, where current is stored * in watchhi/lo. The context register should be used to contiguously * map the page tables. @@ -27,20 +29,17 @@ #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ pgd_current[smp_processor_id()] = (unsigned long)(pgd) #define TLBMISS_HANDLER_SETUP() \ - set_context((unsigned long) smp_processor_id() << (23 + 3)); \ + write_c0_context(((long)(&pgd_current[smp_processor_id()])) << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) extern unsigned long pgd_current[]; -#ifndef CONFIG_SMP -#define CPU_CONTEXT(cpu, mm) (mm)->context -#else -#define CPU_CONTEXT(cpu, mm) (*((unsigned long *)((mm)->context) + cpu)) -#endif -#define ASID_CACHE(cpu) cpu_data[cpu].asid_cache - #define ASID_INC 0x1 #define ASID_MASK 0xff +#define cpu_context(cpu, mm) ((mm)->context[cpu]) +#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK) +#define asid_cache(cpu) (cpu_data[cpu].asid_cache) + static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } @@ -52,63 +51,67 @@ #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) -extern inline void -get_new_cpu_mmu_context(struct mm_struct *mm, unsigned long cpu) +static inline void +get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) { - unsigned long asid = ASID_CACHE(cpu); + unsigned long asid = asid_cache(cpu); if (! ((asid += ASID_INC) & ASID_MASK) ) { - _flush_tlb_all(); /* start new asid cycle */ - if (!asid) /* fix version if needed */ +#ifdef CONFIG_VTAG_ICACHE + flush_icache_all(); +#endif + local_flush_tlb_all(); /* start new asid cycle */ + if (!asid) /* fix version if needed */ asid = ASID_FIRST_VERSION; } - CPU_CONTEXT(cpu, mm) = ASID_CACHE(cpu) = asid; + cpu_context(cpu, mm) = asid_cache(cpu) = asid; } /* * Initialize the context related info for a new mm_struct * instance. */ -extern inline int +static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { -#ifndef CONFIG_SMP - mm->context = 0; -#else - mm->context = (unsigned long)kmalloc(smp_num_cpus * - sizeof(unsigned long), GFP_KERNEL); - /* - * Init the "context" values so that a tlbpid allocation - * happens on the first switch. - */ - if (mm->context == 0) - return -ENOMEM; - memset((void *)mm->context, 0, smp_num_cpus * sizeof(unsigned long)); -#endif + int i; + + for (i = 0; i < num_online_cpus(); i++) + cpu_context(i, mm) = 0; + return 0; } -extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, +static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu) { + unsigned long flags; + + local_irq_save(flags); + /* Check if our ASID is of an older version and thus invalid */ - if ((CPU_CONTEXT(cpu, next) ^ ASID_CACHE(cpu)) & ASID_VERSION_MASK) - get_new_cpu_mmu_context(next, cpu); + if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) + get_new_mmu_context(next, cpu); - set_entryhi(CPU_CONTEXT(cpu, next) & 0xff); + write_c0_entryhi(cpu_context(cpu, next)); TLBMISS_HANDLER_SETUP_PGD(next->pgd); + + /* + * Mark current->active_mm as not "active" anymore. + * We don't want to mislead possible IPI tlb flush routines. + */ + clear_bit(cpu, &prev->cpu_vm_mask); + set_bit(cpu, &next->cpu_vm_mask); + + local_irq_restore(flags); } /* * Destroy context related info for an mm_struct that is about * to be put to rest. */ -extern inline void destroy_context(struct mm_struct *mm) +static inline void destroy_context(struct mm_struct *mm) { -#ifdef CONFIG_SMP - if (mm->context) - kfree((void *)mm->context); -#endif } #define deactivate_mm(tsk,mm) do { } while (0) @@ -117,14 +120,47 @@ * After we have set current->mm to a new value, this activates * the context for the new mm so we see the new mappings. */ -extern inline void +static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { + unsigned long flags; + int cpu = smp_processor_id(); + + local_irq_save(flags); + /* Unconditionally get a new ASID. */ - get_new_cpu_mmu_context(next, smp_processor_id()); + get_new_mmu_context(next, cpu); - set_entryhi(CPU_CONTEXT(smp_processor_id(), next) & 0xff); + write_c0_entryhi(cpu_context(cpu, next)); TLBMISS_HANDLER_SETUP_PGD(next->pgd); + + /* mark mmu ownership change */ + clear_bit(cpu, &prev->cpu_vm_mask); + set_bit(cpu, &next->cpu_vm_mask); + + local_irq_restore(flags); +} + +/* + * If mm is currently active_mm, we can't really drop it. Instead, + * we will get a new one for it. + */ +static inline void +drop_mmu_context(struct mm_struct *mm, unsigned cpu) +{ + unsigned long flags; + + local_irq_save(flags); + + if (test_bit(cpu, &mm->cpu_vm_mask)) { + get_new_mmu_context(mm, cpu); + write_c0_entryhi(cpu_asid(cpu, mm)); + } else { + /* will get a new context next time */ + cpu_context(cpu, mm) = 0; + } + + local_irq_restore(flags); } #endif /* _ASM_MMU_CONTEXT_H */ diff -Nru a/include/asm-mips64/mmzone.h b/include/asm-mips64/mmzone.h --- a/include/asm-mips64/mmzone.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/mmzone.h Fri Jun 27 14:19:52 2003 @@ -79,8 +79,16 @@ -1) ? 0 : (test_bit(LOCAL_MAP_NR((addr)), \ NODE_DATA(KVADDR_TO_NID((unsigned long)addr))->valid_addr_bitmap))) -#define virt_to_page(kaddr) (mem_map + MIPS64_NR(kaddr)) -#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) +#define pfn_to_page(pfn) (mem_map + (pfn)) +#define page_to_pfn(page) \ + ((((page)-(page)->zone->zone_mem_map) + (page)->zone->zone_start_pfn) \ + << PAGE_SHIFT) +#define virt_to_page(kaddr) pfn_to_page(MIPS64_NR(kaddr)) + +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT)) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #endif /* CONFIG_DISCONTIGMEM */ diff -Nru a/include/asm-mips64/module.h b/include/asm-mips64/module.h --- a/include/asm-mips64/module.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips64/module.h Fri Jun 27 14:20:06 2003 @@ -1,67 +1,14 @@ -#ifndef _ASM_MIPS64_MODULE_H -#define _ASM_MIPS64_MODULE_H -/* - * This file contains the mips64 architecture specific module code. - */ +#ifndef _ASM_MODULE_H +#define _ASM_MODULE_H -#include <linux/module.h> -#include <asm/uaccess.h> - -#define module_map(x) vmalloc(x) -#define module_unmap(x) vfree(x) -#define module_arch_init(x) mips64_module_init(x) -#define arch_init_modules(x) mips64_init_modules(x) - -/* - * This must match in size and layout the data created by - * modutils/obj/obj-mips64.c - */ -struct archdata { +struct mod_arch_specific { + /* Data Bus Error exception tables */ const struct exception_table_entry *dbe_table_start; const struct exception_table_entry *dbe_table_end; }; -static inline int -mips64_module_init(struct module *mod) -{ - struct archdata *archdata; - - if (!mod_member_present(mod, archdata_end)) - return 0; - - archdata = (struct archdata *)(mod->archdata_start); - if (!mod_archdata_member_present(mod, struct archdata, dbe_table_end)) - return 0; - - if (archdata->dbe_table_start > archdata->dbe_table_end || - (archdata->dbe_table_start && - !((unsigned long)archdata->dbe_table_start >= - ((unsigned long)mod + mod->size_of_struct) && - ((unsigned long)archdata->dbe_table_end < - (unsigned long)mod + mod->size))) || - (((unsigned long)archdata->dbe_table_start - - (unsigned long)archdata->dbe_table_end) % - sizeof(struct exception_table_entry))) { - printk(KERN_ERR - "module_arch_init: archdata->dbe_table_* invalid.\n"); - return 1; - } - - return 0; -} - -static inline void -mips64_init_modules(struct module *mod) -{ - extern const struct exception_table_entry __start___dbe_table[]; - extern const struct exception_table_entry __stop___dbe_table[]; - static struct archdata archdata = { - dbe_table_start: __start___dbe_table, - dbe_table_end: __stop___dbe_table, - }; - - mod->archdata_start = (char *)&archdata; - mod->archdata_end = mod->archdata_start + sizeof(archdata); -} +#define Elf_Shdr Elf32_Shdr +#define Elf_Sym Elf32_Sym +#define Elf_Ehdr Elf32_Ehdr -#endif /* _ASM_MIPS64_MODULE_H */ +#endif /* _ASM_MODULE_H */ diff -Nru a/include/asm-mips64/msgbuf.h b/include/asm-mips64/msgbuf.h --- a/include/asm-mips64/msgbuf.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/msgbuf.h Fri Jun 27 14:19:57 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_MSGBUF_H #define _ASM_MSGBUF_H -/* +/* * The msqid64_ds structure for alpha architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. @@ -13,15 +13,18 @@ struct msqid64_ds { struct ipc64_perm msg_perm; __kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; __kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; __kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; unsigned long msg_cbytes; /* current number of bytes on queue */ unsigned long msg_qnum; /* number of messages in queue */ unsigned long msg_qbytes; /* max number of bytes on queue */ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ __kernel_pid_t msg_lrpid; /* last receive pid */ - unsigned long __unused1; - unsigned long __unused2; + unsigned long __unused4; + unsigned long __unused5; }; #endif /* _ASM_MSGBUF_H */ diff -Nru a/include/asm-mips64/mv64340.h b/include/asm-mips64/mv64340.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/mv64340.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,1037 @@ +/******************************************************************************* +* mv64340.h - MV-64340 Internal registers definition file. +* +* Copyright 2002 Momentum Computer, Inc. +* Copyright 2002 GALILEO TECHNOLOGY, LTD. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +*******************************************************************************/ + +#ifndef __MV64340_H__ +#define __MV64340_H__ + +#include <asm/mv64340_dep.h> + +/****************************************/ +/* Processor Address Space */ +/****************************************/ + +/* DDR SDRAM BAR and size registers */ + +#define MV64340_CS_0_BASE_ADDR 0x008 +#define MV64340_CS_0_SIZE 0x010 +#define MV64340_CS_1_BASE_ADDR 0x208 +#define MV64340_CS_1_SIZE 0x210 +#define MV64340_CS_2_BASE_ADDR 0x018 +#define MV64340_CS_2_SIZE 0x020 +#define MV64340_CS_3_BASE_ADDR 0x218 +#define MV64340_CS_3_SIZE 0x220 + +/* Devices BAR and size registers */ + +#define MV64340_DEV_CS0_BASE_ADDR 0x028 +#define MV64340_DEV_CS0_SIZE 0x030 +#define MV64340_DEV_CS1_BASE_ADDR 0x228 +#define MV64340_DEV_CS1_SIZE 0x230 +#define MV64340_DEV_CS2_BASE_ADDR 0x248 +#define MV64340_DEV_CS2_SIZE 0x250 +#define MV64340_DEV_CS3_BASE_ADDR 0x038 +#define MV64340_DEV_CS3_SIZE 0x040 +#define MV64340_BOOTCS_BASE_ADDR 0x238 +#define MV64340_BOOTCS_SIZE 0x240 + +/* PCI 0 BAR and size registers */ + +#define MV64340_PCI_0_IO_BASE_ADDR 0x048 +#define MV64340_PCI_0_IO_SIZE 0x050 +#define MV64340_PCI_0_MEMORY0_BASE_ADDR 0x058 +#define MV64340_PCI_0_MEMORY0_SIZE 0x060 +#define MV64340_PCI_0_MEMORY1_BASE_ADDR 0x080 +#define MV64340_PCI_0_MEMORY1_SIZE 0x088 +#define MV64340_PCI_0_MEMORY2_BASE_ADDR 0x258 +#define MV64340_PCI_0_MEMORY2_SIZE 0x260 +#define MV64340_PCI_0_MEMORY3_BASE_ADDR 0x280 +#define MV64340_PCI_0_MEMORY3_SIZE 0x288 + +/* PCI 1 BAR and size registers */ +#define MV64340_PCI_1_IO_BASE_ADDR 0x090 +#define MV64340_PCI_1_IO_SIZE 0x098 +#define MV64340_PCI_1_MEMORY0_BASE_ADDR 0x0a0 +#define MV64340_PCI_1_MEMORY0_SIZE 0x0a8 +#define MV64340_PCI_1_MEMORY1_BASE_ADDR 0x0b0 +#define MV64340_PCI_1_MEMORY1_SIZE 0x0b8 +#define MV64340_PCI_1_MEMORY2_BASE_ADDR 0x2a0 +#define MV64340_PCI_1_MEMORY2_SIZE 0x2a8 +#define MV64340_PCI_1_MEMORY3_BASE_ADDR 0x2b0 +#define MV64340_PCI_1_MEMORY3_SIZE 0x2b8 + +/* SRAM base address */ +#define MV64340_INTEGRATED_SRAM_BASE_ADDR 0x268 + +/* internal registers space base address */ +#define MV64340_INTERNAL_SPACE_BASE_ADDR 0x068 + +/* Enables the CS , DEV_CS , PCI 0 and PCI 1 + windows above */ +#define MV64340_BASE_ADDR_ENABLE 0x278 + +/****************************************/ +/* PCI remap registers */ +/****************************************/ + /* PCI 0 */ +#define MV64340_PCI_0_IO_ADDR_REMAP 0x0f0 +#define MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP 0x0f8 +#define MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP 0x320 +#define MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP 0x100 +#define MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP 0x328 +#define MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP 0x2f8 +#define MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP 0x330 +#define MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP 0x300 +#define MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP 0x338 + /* PCI 1 */ +#define MV64340_PCI_1_IO_ADDR_REMAP 0x108 +#define MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP 0x110 +#define MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP 0x340 +#define MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP 0x118 +#define MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP 0x348 +#define MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP 0x310 +#define MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP 0x350 +#define MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP 0x318 +#define MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP 0x358 + +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_CONTROL 0x3b0 +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_BASE 0x3b8 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_CONTROL 0x3c0 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_BASE 0x3c8 +#define MV64340_CPU_GE_HEADERS_RETARGET_CONTROL 0x3d0 +#define MV64340_CPU_GE_HEADERS_RETARGET_BASE 0x3d8 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_CONTROL 0x3e0 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_BASE 0x3e8 + +/****************************************/ +/* CPU Control Registers */ +/****************************************/ + +#define MV64340_CPU_CONFIG 0x000 +#define MV64340_CPU_MODE 0x120 +#define MV64340_CPU_MASTER_CONTROL 0x160 +#define MV64340_CPU_CROSS_BAR_CONTROL_LOW 0x150 +#define MV64340_CPU_CROSS_BAR_CONTROL_HIGH 0x158 +#define MV64340_CPU_CROSS_BAR_TIMEOUT 0x168 + +/****************************************/ +/* SMP RegisterS */ +/****************************************/ + +#define MV64340_SMP_WHO_AM_I 0x200 +#define MV64340_SMP_CPU0_DOORBELL 0x214 +#define MV64340_SMP_CPU0_DOORBELL_CLEAR 0x21C +#define MV64340_SMP_CPU1_DOORBELL 0x224 +#define MV64340_SMP_CPU1_DOORBELL_CLEAR 0x22C +#define MV64340_SMP_CPU0_DOORBELL_MASK 0x234 +#define MV64340_SMP_CPU1_DOORBELL_MASK 0x23C +#define MV64340_SMP_SEMAPHOR0 0x244 +#define MV64340_SMP_SEMAPHOR1 0x24c +#define MV64340_SMP_SEMAPHOR2 0x254 +#define MV64340_SMP_SEMAPHOR3 0x25c +#define MV64340_SMP_SEMAPHOR4 0x264 +#define MV64340_SMP_SEMAPHOR5 0x26c +#define MV64340_SMP_SEMAPHOR6 0x274 +#define MV64340_SMP_SEMAPHOR7 0x27c + +/****************************************/ +/* CPU Sync Barrier Register */ +/****************************************/ + +#define MV64340_CPU_0_SYNC_BARRIER_TRIGGER 0x0c0 +#define MV64340_CPU_0_SYNC_BARRIER_VIRTUAL 0x0c8 +#define MV64340_CPU_1_SYNC_BARRIER_TRIGGER 0x0d0 +#define MV64340_CPU_1_SYNC_BARRIER_VIRTUAL 0x0d8 + +/****************************************/ +/* CPU Access Protect */ +/****************************************/ + +#define MV64340_CPU_PROTECT_WINDOW_0_BASE_ADDR 0x180 +#define MV64340_CPU_PROTECT_WINDOW_0_SIZE 0x188 +#define MV64340_CPU_PROTECT_WINDOW_1_BASE_ADDR 0x190 +#define MV64340_CPU_PROTECT_WINDOW_1_SIZE 0x198 +#define MV64340_CPU_PROTECT_WINDOW_2_BASE_ADDR 0x1a0 +#define MV64340_CPU_PROTECT_WINDOW_2_SIZE 0x1a8 +#define MV64340_CPU_PROTECT_WINDOW_3_BASE_ADDR 0x1b0 +#define MV64340_CPU_PROTECT_WINDOW_3_SIZE 0x1b8 + + +/****************************************/ +/* CPU Error Report */ +/****************************************/ + +#define MV64340_CPU_ERROR_ADDR_LOW 0x070 +#define MV64340_CPU_ERROR_ADDR_HIGH 0x078 +#define MV64340_CPU_ERROR_DATA_LOW 0x128 +#define MV64340_CPU_ERROR_DATA_HIGH 0x130 +#define MV64340_CPU_ERROR_PARITY 0x138 +#define MV64340_CPU_ERROR_CAUSE 0x140 +#define MV64340_CPU_ERROR_MASK 0x148 + +/****************************************/ +/* CPU Interface Debug Registers */ +/****************************************/ + +#define MV64340_PUNIT_SLAVE_DEBUG_LOW 0x360 +#define MV64340_PUNIT_SLAVE_DEBUG_HIGH 0x368 +#define MV64340_PUNIT_MASTER_DEBUG_LOW 0x370 +#define MV64340_PUNIT_MASTER_DEBUG_HIGH 0x378 +#define MV64340_PUNIT_MMASK 0x3e4 + +/****************************************/ +/* Integrated SRAM Registers */ +/****************************************/ + +#define MV64340_SRAM_CONFIG 0x380 +#define MV64340_SRAM_TEST_MODE 0X3F4 +#define MV64340_SRAM_ERROR_CAUSE 0x388 +#define MV64340_SRAM_ERROR_ADDR 0x390 +#define MV64340_SRAM_ERROR_ADDR_HIGH 0X3F8 +#define MV64340_SRAM_ERROR_DATA_LOW 0x398 +#define MV64340_SRAM_ERROR_DATA_HIGH 0x3a0 +#define MV64340_SRAM_ERROR_DATA_PARITY 0x3a8 + +/****************************************/ +/* SDRAM Configuration */ +/****************************************/ + +#define MV64340_SDRAM_CONFIG 0x1400 +#define MV64340_D_UNIT_CONTROL_LOW 0x1404 +#define MV64340_D_UNIT_CONTROL_HIGH 0x1424 +#define MV64340_SDRAM_TIMING_CONTROL_LOW 0x1408 +#define MV64340_SDRAM_TIMING_CONTROL_HIGH 0x140c +#define MV64340_SDRAM_ADDR_CONTROL 0x1410 +#define MV64340_SDRAM_OPEN_PAGES_CONTROL 0x1414 +#define MV64340_SDRAM_OPERATION 0x1418 +#define MV64340_SDRAM_MODE 0x141c +#define MV64340_EXTENDED_DRAM_MODE 0x1420 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_LOW 0x1430 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_HIGH 0x1434 +#define MV64340_SDRAM_CROSS_BAR_TIMEOUT 0x1438 +#define MV64340_SDRAM_ADDR_CTRL_PADS_CALIBRATION 0x14c0 +#define MV64340_SDRAM_DATA_PADS_CALIBRATION 0x14c4 + +/****************************************/ +/* SDRAM Error Report */ +/****************************************/ + +#define MV64340_SDRAM_ERROR_DATA_LOW 0x1444 +#define MV64340_SDRAM_ERROR_DATA_HIGH 0x1440 +#define MV64340_SDRAM_ERROR_ADDR 0x1450 +#define MV64340_SDRAM_RECEIVED_ECC 0x1448 +#define MV64340_SDRAM_CALCULATED_ECC 0x144c +#define MV64340_SDRAM_ECC_CONTROL 0x1454 +#define MV64340_SDRAM_ECC_ERROR_COUNTER 0x1458 + +/******************************************/ +/* Controlled Delay Line (CDL) Registers */ +/******************************************/ + +#define MV64340_DFCDL_CONFIG0 0x1480 +#define MV64340_DFCDL_CONFIG1 0x1484 +#define MV64340_DLL_WRITE 0x1488 +#define MV64340_DLL_READ 0x148c +#define MV64340_SRAM_ADDR 0x1490 +#define MV64340_SRAM_DATA0 0x1494 +#define MV64340_SRAM_DATA1 0x1498 +#define MV64340_SRAM_DATA2 0x149c +#define MV64340_DFCL_PROBE 0x14a0 + +/******************************************/ +/* Debug Registers */ +/******************************************/ + +#define MV64340_DUNIT_DEBUG_LOW 0x1460 +#define MV64340_DUNIT_DEBUG_HIGH 0x1464 +#define MV64340_DUNIT_MMASK 0X1b40 + +/****************************************/ +/* Device Parameters */ +/****************************************/ + +#define MV64340_DEVICE_BANK0_PARAMETERS 0x45c +#define MV64340_DEVICE_BANK1_PARAMETERS 0x460 +#define MV64340_DEVICE_BANK2_PARAMETERS 0x464 +#define MV64340_DEVICE_BANK3_PARAMETERS 0x468 +#define MV64340_DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define MV64340_DEVICE_INTERFACE_CONTROL 0x4c0 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_TIMEOUT 0x4c4 + +/****************************************/ +/* Device interrupt registers */ +/****************************************/ + +#define MV64340_DEVICE_INTERRUPT_CAUSE 0x4d0 +#define MV64340_DEVICE_INTERRUPT_MASK 0x4d4 +#define MV64340_DEVICE_ERROR_ADDR 0x4d8 +#define MV64340_DEVICE_ERROR_DATA 0x4dc +#define MV64340_DEVICE_ERROR_PARITY 0x4e0 + +/****************************************/ +/* Device debug registers */ +/****************************************/ + +#define MV64340_DEVICE_DEBUG_LOW 0x4e4 +#define MV64340_DEVICE_DEBUG_HIGH 0x4e8 +#define MV64340_RUNIT_MMASK 0x4f0 + +/****************************************/ +/* PCI Slave Address Decoding registers */ +/****************************************/ + +#define MV64340_PCI_0_CS_0_BANK_SIZE 0xc08 +#define MV64340_PCI_1_CS_0_BANK_SIZE 0xc88 +#define MV64340_PCI_0_CS_1_BANK_SIZE 0xd08 +#define MV64340_PCI_1_CS_1_BANK_SIZE 0xd88 +#define MV64340_PCI_0_CS_2_BANK_SIZE 0xc0c +#define MV64340_PCI_1_CS_2_BANK_SIZE 0xc8c +#define MV64340_PCI_0_CS_3_BANK_SIZE 0xd0c +#define MV64340_PCI_1_CS_3_BANK_SIZE 0xd8c +#define MV64340_PCI_0_DEVCS_0_BANK_SIZE 0xc10 +#define MV64340_PCI_1_DEVCS_0_BANK_SIZE 0xc90 +#define MV64340_PCI_0_DEVCS_1_BANK_SIZE 0xd10 +#define MV64340_PCI_1_DEVCS_1_BANK_SIZE 0xd90 +#define MV64340_PCI_0_DEVCS_2_BANK_SIZE 0xd18 +#define MV64340_PCI_1_DEVCS_2_BANK_SIZE 0xd98 +#define MV64340_PCI_0_DEVCS_3_BANK_SIZE 0xc14 +#define MV64340_PCI_1_DEVCS_3_BANK_SIZE 0xc94 +#define MV64340_PCI_0_DEVCS_BOOT_BANK_SIZE 0xd14 +#define MV64340_PCI_1_DEVCS_BOOT_BANK_SIZE 0xd94 +#define MV64340_PCI_0_P2P_MEM0_BAR_SIZE 0xd1c +#define MV64340_PCI_1_P2P_MEM0_BAR_SIZE 0xd9c +#define MV64340_PCI_0_P2P_MEM1_BAR_SIZE 0xd20 +#define MV64340_PCI_1_P2P_MEM1_BAR_SIZE 0xda0 +#define MV64340_PCI_0_P2P_I_O_BAR_SIZE 0xd24 +#define MV64340_PCI_1_P2P_I_O_BAR_SIZE 0xda4 +#define MV64340_PCI_0_CPU_BAR_SIZE 0xd28 +#define MV64340_PCI_1_CPU_BAR_SIZE 0xda8 +#define MV64340_PCI_0_INTERNAL_SRAM_BAR_SIZE 0xe00 +#define MV64340_PCI_1_INTERNAL_SRAM_BAR_SIZE 0xe80 +#define MV64340_PCI_0_EXPANSION_ROM_BAR_SIZE 0xd2c +#define MV64340_PCI_1_EXPANSION_ROM_BAR_SIZE 0xd9c +#define MV64340_PCI_0_BASE_ADDR_REG_ENABLE 0xc3c +#define MV64340_PCI_1_BASE_ADDR_REG_ENABLE 0xcbc +#define MV64340_PCI_0_CS_0_BASE_ADDR_REMAP 0xc48 +#define MV64340_PCI_1_CS_0_BASE_ADDR_REMAP 0xcc8 +#define MV64340_PCI_0_CS_1_BASE_ADDR_REMAP 0xd48 +#define MV64340_PCI_1_CS_1_BASE_ADDR_REMAP 0xdc8 +#define MV64340_PCI_0_CS_2_BASE_ADDR_REMAP 0xc4c +#define MV64340_PCI_1_CS_2_BASE_ADDR_REMAP 0xccc +#define MV64340_PCI_0_CS_3_BASE_ADDR_REMAP 0xd4c +#define MV64340_PCI_1_CS_3_BASE_ADDR_REMAP 0xdcc +#define MV64340_PCI_0_CS_0_BASE_HIGH_ADDR_REMAP 0xF04 +#define MV64340_PCI_1_CS_0_BASE_HIGH_ADDR_REMAP 0xF84 +#define MV64340_PCI_0_CS_1_BASE_HIGH_ADDR_REMAP 0xF08 +#define MV64340_PCI_1_CS_1_BASE_HIGH_ADDR_REMAP 0xF88 +#define MV64340_PCI_0_CS_2_BASE_HIGH_ADDR_REMAP 0xF0C +#define MV64340_PCI_1_CS_2_BASE_HIGH_ADDR_REMAP 0xF8C +#define MV64340_PCI_0_CS_3_BASE_HIGH_ADDR_REMAP 0xF10 +#define MV64340_PCI_1_CS_3_BASE_HIGH_ADDR_REMAP 0xF90 +#define MV64340_PCI_0_DEVCS_0_BASE_ADDR_REMAP 0xc50 +#define MV64340_PCI_1_DEVCS_0_BASE_ADDR_REMAP 0xcd0 +#define MV64340_PCI_0_DEVCS_1_BASE_ADDR_REMAP 0xd50 +#define MV64340_PCI_1_DEVCS_1_BASE_ADDR_REMAP 0xdd0 +#define MV64340_PCI_0_DEVCS_2_BASE_ADDR_REMAP 0xd58 +#define MV64340_PCI_1_DEVCS_2_BASE_ADDR_REMAP 0xdd8 +#define MV64340_PCI_0_DEVCS_3_BASE_ADDR_REMAP 0xc54 +#define MV64340_PCI_1_DEVCS_3_BASE_ADDR_REMAP 0xcd4 +#define MV64340_PCI_0_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xd54 +#define MV64340_PCI_1_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xdd4 +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xd5c +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xddc +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xd60 +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xde0 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xd64 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xde4 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xd68 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xde8 +#define MV64340_PCI_0_P2P_I_O_BASE_ADDR_REMAP 0xd6c +#define MV64340_PCI_1_P2P_I_O_BASE_ADDR_REMAP 0xdec +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_LOW 0xd70 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_LOW 0xdf0 +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_HIGH 0xd74 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_HIGH 0xdf4 +#define MV64340_PCI_0_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf00 +#define MV64340_PCI_1_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf80 +#define MV64340_PCI_0_EXPANSION_ROM_BASE_ADDR_REMAP 0xf38 +#define MV64340_PCI_1_EXPANSION_ROM_BASE_ADDR_REMAP 0xfb8 +#define MV64340_PCI_0_ADDR_DECODE_CONTROL 0xd3c +#define MV64340_PCI_1_ADDR_DECODE_CONTROL 0xdbc +#define MV64340_PCI_0_HEADERS_RETARGET_CONTROL 0xF40 +#define MV64340_PCI_1_HEADERS_RETARGET_CONTROL 0xFc0 +#define MV64340_PCI_0_HEADERS_RETARGET_BASE 0xF44 +#define MV64340_PCI_1_HEADERS_RETARGET_BASE 0xFc4 +#define MV64340_PCI_0_HEADERS_RETARGET_HIGH 0xF48 +#define MV64340_PCI_1_HEADERS_RETARGET_HIGH 0xFc8 + +/***********************************/ +/* PCI Control Register Map */ +/***********************************/ + +#define MV64340_PCI_0_DLL_STATUS_AND_COMMAND 0x1d20 +#define MV64340_PCI_1_DLL_STATUS_AND_COMMAND 0x1da0 +#define MV64340_PCI_0_MPP_PADS_DRIVE_CONTROL 0x1d1C +#define MV64340_PCI_1_MPP_PADS_DRIVE_CONTROL 0x1d9C +#define MV64340_PCI_0_COMMAND 0xc00 +#define MV64340_PCI_1_COMMAND 0xc80 +#define MV64340_PCI_0_MODE 0xd00 +#define MV64340_PCI_1_MODE 0xd80 +#define MV64340_PCI_0_RETRY 0xc04 +#define MV64340_PCI_1_RETRY 0xc84 +#define MV64340_PCI_0_READ_BUFFER_DISCARD_TIMER 0xd04 +#define MV64340_PCI_1_READ_BUFFER_DISCARD_TIMER 0xd84 +#define MV64340_PCI_0_MSI_TRIGGER_TIMER 0xc38 +#define MV64340_PCI_1_MSI_TRIGGER_TIMER 0xcb8 +#define MV64340_PCI_0_ARBITER_CONTROL 0x1d00 +#define MV64340_PCI_1_ARBITER_CONTROL 0x1d80 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_LOW 0x1d08 +#define MV64340_PCI_1_CROSS_BAR_CONTROL_LOW 0x1d88 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_HIGH 0x1d0c +#define MV64340_PCI_1_CROSS_BAR_CONTROL_HIGH 0x1d8c +#define MV64340_PCI_0_CROSS_BAR_TIMEOUT 0x1d04 +#define MV64340_PCI_1_CROSS_BAR_TIMEOUT 0x1d84 +#define MV64340_PCI_0_SYNC_BARRIER_TRIGGER_REG 0x1D18 +#define MV64340_PCI_1_SYNC_BARRIER_TRIGGER_REG 0x1D98 +#define MV64340_PCI_0_SYNC_BARRIER_VIRTUAL_REG 0x1d10 +#define MV64340_PCI_1_SYNC_BARRIER_VIRTUAL_REG 0x1d90 +#define MV64340_PCI_0_P2P_CONFIG 0x1d14 +#define MV64340_PCI_1_P2P_CONFIG 0x1d94 + +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_0 0x1e08 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_LOW 0x1e10 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_1 0x1e18 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_LOW 0x1e20 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_2 0x1e28 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_LOW 0x1e30 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_3 0x1e38 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_LOW 0x1e40 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_4 0x1e48 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_LOW 0x1e50 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_5 0x1e58 + +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_0 0x1e88 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_LOW 0x1e90 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_1 0x1e98 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_LOW 0x1ea0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_2 0x1ea8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_LOW 0x1eb0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_3 0x1eb8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_LOW 0x1ec0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_4 0x1ec8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_LOW 0x1ed0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_5 0x1ed8 + +/****************************************/ +/* PCI Configuration Access Registers */ +/****************************************/ + +#define MV64340_PCI_0_CONFIG_ADDR 0xcf8 +#define MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG 0xcfc +#define MV64340_PCI_1_CONFIG_ADDR 0xc78 +#define MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG 0xc7c +#define MV64340_PCI_0_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xc34 +#define MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xcb4 + +/****************************************/ +/* PCI Error Report Registers */ +/****************************************/ + +#define MV64340_PCI_0_SERR_MASK 0xc28 +#define MV64340_PCI_1_SERR_MASK 0xca8 +#define MV64340_PCI_0_ERROR_ADDR_LOW 0x1d40 +#define MV64340_PCI_1_ERROR_ADDR_LOW 0x1dc0 +#define MV64340_PCI_0_ERROR_ADDR_HIGH 0x1d44 +#define MV64340_PCI_1_ERROR_ADDR_HIGH 0x1dc4 +#define MV64340_PCI_0_ERROR_ATTRIBUTE 0x1d48 +#define MV64340_PCI_1_ERROR_ATTRIBUTE 0x1dc8 +#define MV64340_PCI_0_ERROR_COMMAND 0x1d50 +#define MV64340_PCI_1_ERROR_COMMAND 0x1dd0 +#define MV64340_PCI_0_ERROR_CAUSE 0x1d58 +#define MV64340_PCI_1_ERROR_CAUSE 0x1dd8 +#define MV64340_PCI_0_ERROR_MASK 0x1d5c +#define MV64340_PCI_1_ERROR_MASK 0x1ddc + +/****************************************/ +/* PCI Debug Registers */ +/****************************************/ + +#define MV64340_PCI_0_MMASK 0X1D24 +#define MV64340_PCI_1_MMASK 0X1DA4 + +/*********************************************/ +/* PCI Configuration, Function 0, Registers */ +/*********************************************/ + +#define MV64340_PCI_DEVICE_AND_VENDOR_ID 0x000 +#define MV64340_PCI_STATUS_AND_COMMAND 0x004 +#define MV64340_PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define MV64340_PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C + +#define MV64340_PCI_SCS_0_BASE_ADDR_LOW 0x010 +#define MV64340_PCI_SCS_0_BASE_ADDR_HIGH 0x014 +#define MV64340_PCI_SCS_1_BASE_ADDR_LOW 0x018 +#define MV64340_PCI_SCS_1_BASE_ADDR_HIGH 0x01C +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_LOW 0x020 +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_HIGH 0x024 +#define MV64340_PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02c +#define MV64340_PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030 +#define MV64340_PCI_CAPABILTY_LIST_POINTER 0x034 +#define MV64340_PCI_INTERRUPT_PIN_AND_LINE 0x03C + /* capability list */ +#define MV64340_PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define MV64340_PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define MV64340_PCI_VPD_ADDR 0x048 +#define MV64340_PCI_VPD_DATA 0x04c +#define MV64340_PCI_MSI_MESSAGE_CONTROL 0x050 +#define MV64340_PCI_MSI_MESSAGE_ADDR 0x054 +#define MV64340_PCI_MSI_MESSAGE_UPPER_ADDR 0x058 +#define MV64340_PCI_MSI_MESSAGE_DATA 0x05c +#define MV64340_PCI_X_COMMAND 0x060 +#define MV64340_PCI_X_STATUS 0x064 +#define MV64340_PCI_COMPACT_PCI_HOT_SWAP 0x068 + +/***********************************************/ +/* PCI Configuration, Function 1, Registers */ +/***********************************************/ + +#define MV64340_PCI_SCS_2_BASE_ADDR_LOW 0x110 +#define MV64340_PCI_SCS_2_BASE_ADDR_HIGH 0x114 +#define MV64340_PCI_SCS_3_BASE_ADDR_LOW 0x118 +#define MV64340_PCI_SCS_3_BASE_ADDR_HIGH 0x11c +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_LOW 0x120 +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_HIGH 0x124 + +/***********************************************/ +/* PCI Configuration, Function 2, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_0_BASE_ADDR_LOW 0x210 +#define MV64340_PCI_DEVCS_0_BASE_ADDR_HIGH 0x214 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_LOW 0x218 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_HIGH 0x21c +#define MV64340_PCI_DEVCS_2_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_DEVCS_2_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 3, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_3_BASE_ADDR_LOW 0x310 +#define MV64340_PCI_DEVCS_3_BASE_ADDR_HIGH 0x314 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_LOW 0x318 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_HIGH 0x31c +#define MV64340_PCI_CPU_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_CPU_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 4, Registers */ +/***********************************************/ + +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_LOW 0x410 +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_HIGH 0x414 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_LOW 0x418 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_HIGH 0x41c +#define MV64340_PCI_P2P_I_O_BASE_ADDR 0x420 +#define MV64340_PCI_INTERNAL_REGS_I_O_MAPPED_BASE_ADDR 0x424 + +/****************************************/ +/* Messaging Unit Registers (I20) */ +/****************************************/ + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_0_SIDE 0x010 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_0_SIDE 0x014 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_0_SIDE 0x018 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_0_SIDE 0x01C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_0_SIDE 0x020 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x024 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x028 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_0_SIDE 0x02C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x030 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x034 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x040 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x044 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_0_SIDE 0x050 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_0_SIDE 0x054 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x060 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x064 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x068 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x06C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x070 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x074 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x0F8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x0FC + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_1_SIDE 0x090 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_1_SIDE 0x094 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_1_SIDE 0x098 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_1_SIDE 0x09C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_1_SIDE 0x0A0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0A4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0A8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_1_SIDE 0x0AC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0B0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0B4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C4 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_1_SIDE 0x0D0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_1_SIDE 0x0D4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0E0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0E4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x0E8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x0EC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0F0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0F4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x078 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x07C + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C10 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C14 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C18 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C1C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU0_SIDE 0x1C20 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C24 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C28 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU0_SIDE 0x1C2C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C30 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C34 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C40 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C44 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU0_SIDE 0x1C50 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU0_SIDE 0x1C54 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C60 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C64 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1C68 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1C6C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C70 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C74 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1CF8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1CFC +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C90 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C94 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C98 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C9C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU1_SIDE 0x1CA0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CA4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CA8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU1_SIDE 0x1CAC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CB0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CB4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC4 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU1_SIDE 0x1CD0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU1_SIDE 0x1CD4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CE0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CE4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1CE8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1CEC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CF0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CF4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1C78 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1C7C + +/****************************************/ +/* Ethernet Unit Registers */ +/****************************************/ + +#define MV64340_ETH_PHY_ADDR_REG 0x2000 +#define MV64340_ETH_SMI_REG 0x2004 +#define MV64340_ETH_UNIT_DEFAULT_ADDR_REG 0x2008 +#define MV64340_ETH_UNIT_DEFAULTID_REG 0x200c +#define MV64340_ETH_UNIT_INTERRUPT_CAUSE_REG 0x2080 +#define MV64340_ETH_UNIT_INTERRUPT_MASK_REG 0x2084 +#define MV64340_ETH_UNIT_INTERNAL_USE_REG 0x24fc +#define MV64340_ETH_UNIT_ERROR_ADDR_REG 0x2094 +#define MV64340_ETH_BAR_0 0x2200 +#define MV64340_ETH_BAR_1 0x2208 +#define MV64340_ETH_BAR_2 0x2210 +#define MV64340_ETH_BAR_3 0x2218 +#define MV64340_ETH_BAR_4 0x2220 +#define MV64340_ETH_BAR_5 0x2228 +#define MV64340_ETH_SIZE_REG_0 0x2204 +#define MV64340_ETH_SIZE_REG_1 0x220c +#define MV64340_ETH_SIZE_REG_2 0x2214 +#define MV64340_ETH_SIZE_REG_3 0x221c +#define MV64340_ETH_SIZE_REG_4 0x2224 +#define MV64340_ETH_SIZE_REG_5 0x222c +#define MV64340_ETH_HEADERS_RETARGET_BASE_REG 0x2230 +#define MV64340_ETH_HEADERS_RETARGET_CONTROL_REG 0x2234 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_0 0x2280 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_1 0x2284 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_2 0x2288 +#define MV64340_ETH_HIGH_ADDR_REMAP_REG_3 0x228c +#define MV64340_ETH_BASE_ADDR_ENABLE_REG 0x2290 +#define MV64340_ETH_ACCESS_PROTECTION_REG(port) (0x2294 + (port<<2)) +#define MV64340_ETH_MIB_COUNTERS_BASE(port) (0x3000 + (port<<7)) +#define MV64340_ETH_PORT_CONFIG_REG(port) (0x2400 + (port<<10)) +#define MV64340_ETH_PORT_CONFIG_EXTEND_REG(port) (0x2404 + (port<<10)) +#define MV64340_ETH_MII_SERIAL_PARAMETRS_REG(port) (0x2408 + (port<<10)) +#define MV64340_ETH_GMII_SERIAL_PARAMETRS_REG(port) (0x240c + (port<<10)) +#define MV64340_ETH_VLAN_ETHERTYPE_REG(port) (0x2410 + (port<<10)) +#define MV64340_ETH_MAC_ADDR_LOW(port) (0x2414 + (port<<10)) +#define MV64340_ETH_MAC_ADDR_HIGH(port) (0x2418 + (port<<10)) +#define MV64340_ETH_SDMA_CONFIG_REG(port) (0x241c + (port<<10)) +#define MV64340_ETH_DSCP_0(port) (0x2420 + (port<<10)) +#define MV64340_ETH_DSCP_1(port) (0x2424 + (port<<10)) +#define MV64340_ETH_DSCP_2(port) (0x2428 + (port<<10)) +#define MV64340_ETH_DSCP_3(port) (0x242c + (port<<10)) +#define MV64340_ETH_DSCP_4(port) (0x2430 + (port<<10)) +#define MV64340_ETH_DSCP_5(port) (0x2434 + (port<<10)) +#define MV64340_ETH_DSCP_6(port) (0x2438 + (port<<10)) +#define MV64340_ETH_PORT_SERIAL_CONTROL_REG(port) (0x243c + (port<<10)) +#define MV64340_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port) (0x2440 + (port<<10)) +#define MV64340_ETH_PORT_STATUS_REG(port) (0x2444 + (port<<10)) +#define MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port) (0x2448 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_FIXED_PRIORITY(port) (0x244c + (port<<10)) +#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port) (0x2450 + (port<<10)) +#define MV64340_ETH_MAXIMUM_TRANSMIT_UNIT(port) (0x2458 + (port<<10)) +#define MV64340_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port) (0x245c + (port<<10)) +#define MV64340_ETH_INTERRUPT_CAUSE_REG(port) (0x2460 + (port<<10)) +#define MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port) (0x2464 + (port<<10)) +#define MV64340_ETH_INTERRUPT_MASK_REG(port) (0x2468 + (port<<10)) +#define MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port) (0x246c + (port<<10)) +#define MV64340_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port) (0x2470 + (port<<10)) +#define MV64340_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port) (0x2474 + (port<<10)) +#define MV64340_ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (0x247c + (port<<10)) +#define MV64340_ETH_RX_DISCARDED_FRAMES_COUNTER(port) (0x2484 + (port<<10) +#define MV64340_ETH_PORT_DEBUG_0_REG(port) (0x248c + (port<<10)) +#define MV64340_ETH_PORT_DEBUG_1_REG(port) (0x2490 + (port<<10)) +#define MV64340_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port) (0x2494 + (port<<10)) +#define MV64340_ETH_INTERNAL_USE_REG(port) (0x24fc + (port<<10)) +#define MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port) (0x2680 + (port<<10)) +#define MV64340_ETH_CURRENT_SERVED_TX_DESC_PTR(port) (0x2684 + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port) (0x260c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port) (0x261c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port) (0x262c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port) (0x263c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port) (0x264c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port) (0x265c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port) (0x266c + (port<<10)) +#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port) (0x267c + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port) (0x26c0 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port) (0x26c4 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port) (0x26c8 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port) (0x26cc + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port) (0x26d0 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port) (0x26d4 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port) (0x26d8 + (port<<10)) +#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port) (0x26dc + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port) (0x2700 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port) (0x2710 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port) (0x2720 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port) (0x2730 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port) (0x2740 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port) (0x2750 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port) (0x2760 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port) (0x2770 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port) (0x2704 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port) (0x2714 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port) (0x2724 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port) (0x2734 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port) (0x2744 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port) (0x2754 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port) (0x2764 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port) (0x2774 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_0_ARBITER_CONFIG(port) (0x2708 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_1_ARBITER_CONFIG(port) (0x2718 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_2_ARBITER_CONFIG(port) (0x2728 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_3_ARBITER_CONFIG(port) (0x2738 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_4_ARBITER_CONFIG(port) (0x2748 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_5_ARBITER_CONFIG(port) (0x2758 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_6_ARBITER_CONFIG(port) (0x2768 + (port<<10)) +#define MV64340_ETH_TX_QUEUE_7_ARBITER_CONFIG(port) (0x2778 + (port<<10)) +#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port) (0x2780 + (port<<10)) +#define MV64340_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port) (0x3400 + (port<<10)) +#define MV64340_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port) (0x3500 + (port<<10)) +#define MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE(port) (0x3600 + (port<<10)) + +/*******************************************/ +/* CUNIT Registers */ +/*******************************************/ + + /* Address Decoding Register Map */ + +#define MV64340_CUNIT_BASE_ADDR_REG0 0xf200 +#define MV64340_CUNIT_BASE_ADDR_REG1 0xf208 +#define MV64340_CUNIT_BASE_ADDR_REG2 0xf210 +#define MV64340_CUNIT_BASE_ADDR_REG3 0xf218 +#define MV64340_CUNIT_SIZE0 0xf204 +#define MV64340_CUNIT_SIZE1 0xf20c +#define MV64340_CUNIT_SIZE2 0xf214 +#define MV64340_CUNIT_SIZE3 0xf21c +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG0 0xf240 +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG1 0xf244 +#define MV64340_CUNIT_BASE_ADDR_ENABLE_REG 0xf250 +#define MV64340_MPSC0_ACCESS_PROTECTION_REG 0xf254 +#define MV64340_MPSC1_ACCESS_PROTECTION_REG 0xf258 +#define MV64340_CUNIT_INTERNAL_SPACE_BASE_ADDR_REG 0xf25C + + /* Error Report Registers */ + +#define MV64340_CUNIT_INTERRUPT_CAUSE_REG 0xf310 +#define MV64340_CUNIT_INTERRUPT_MASK_REG 0xf314 +#define MV64340_CUNIT_ERROR_ADDR 0xf318 + + /* Cunit Control Registers */ + +#define MV64340_CUNIT_ARBITER_CONTROL_REG 0xf300 +#define MV64340_CUNIT_CONFIG_REG 0xb40c +#define MV64340_CUNIT_CRROSBAR_TIMEOUT_REG 0xf304 + + /* Cunit Debug Registers */ + +#define MV64340_CUNIT_DEBUG_LOW 0xf340 +#define MV64340_CUNIT_DEBUG_HIGH 0xf344 +#define MV64340_CUNIT_MMASK 0xf380 + + /* MPSCs Clocks Routing Registers */ + +#define MV64340_MPSC_ROUTING_REG 0xb400 +#define MV64340_MPSC_RX_CLOCK_ROUTING_REG 0xb404 +#define MV64340_MPSC_TX_CLOCK_ROUTING_REG 0xb408 + + /* MPSCs Interrupts Registers */ + +#define MV64340_MPSC_CAUSE_REG(port) (0xb804 + (port<<3)) +#define MV64340_MPSC_MASK_REG(port) (0xb884 + (port<<3)) + +#define MV64340_MPSC_MAIN_CONFIG_LOW(port) (0x8000 + (port<<12)) +#define MV64340_MPSC_MAIN_CONFIG_HIGH(port) (0x8004 + (port<<12)) +#define MV64340_MPSC_PROTOCOL_CONFIG(port) (0x8008 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG1(port) (0x800c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG2(port) (0x8010 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG3(port) (0x8014 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG4(port) (0x8018 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG5(port) (0x801c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG6(port) (0x8020 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG7(port) (0x8024 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG8(port) (0x8028 + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG9(port) (0x802c + (port<<12)) +#define MV64340_MPSC_CHANNEL_REG10(port) (0x8030 + (port<<12)) + + /* MPSC0 Registers */ + + +/***************************************/ +/* SDMA Registers */ +/***************************************/ + +#define MV64340_SDMA_CONFIG_REG(channel) (0x4000 + (channel<<13)) +#define MV64340_SDMA_COMMAND_REG(channel) (0x4008 + (channel<<13)) +#define MV64340_SDMA_CURRENT_RX_DESCRIPTOR_POINTER(channel) (0x4810 + (channel<<13)) +#define MV64340_SDMA_CURRENT_TX_DESCRIPTOR_POINTER(channel) (0x4c10 + (channel<<13)) +#define MV64340_SDMA_FIRST_TX_DESCRIPTOR_POINTER(channel) (0x4c14 + (channel<<13)) + +#define MV64340_SDMA_CAUSE_REG 0xb800 +#define MV64340_SDMA_MASK_REG 0xb880 + +/* BRG Interrupts */ + +#define MV64340_BRG_CONFIG_REG(brg) (0xb200 + (brg<<3)) +#define MV64340_BRG_BAUDE_TUNING_REG(brg) (0xb208 + (brg<<3)) +#define MV64340_BRG_CAUSE_REG 0xb834 +#define MV64340_BRG_MASK_REG 0xb8b4 + +/****************************************/ +/* DMA Channel Control */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_CONTROL 0x840 +#define MV64340_DMA_CHANNEL0_CONTROL_HIGH 0x880 +#define MV64340_DMA_CHANNEL1_CONTROL 0x844 +#define MV64340_DMA_CHANNEL1_CONTROL_HIGH 0x884 +#define MV64340_DMA_CHANNEL2_CONTROL 0x848 +#define MV64340_DMA_CHANNEL2_CONTROL_HIGH 0x888 +#define MV64340_DMA_CHANNEL3_CONTROL 0x84C +#define MV64340_DMA_CHANNEL3_CONTROL_HIGH 0x88C + + +/****************************************/ +/* IDMA Registers */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_BYTE_COUNT 0x800 +#define MV64340_DMA_CHANNEL1_BYTE_COUNT 0x804 +#define MV64340_DMA_CHANNEL2_BYTE_COUNT 0x808 +#define MV64340_DMA_CHANNEL3_BYTE_COUNT 0x80C +#define MV64340_DMA_CHANNEL0_SOURCE_ADDR 0x810 +#define MV64340_DMA_CHANNEL1_SOURCE_ADDR 0x814 +#define MV64340_DMA_CHANNEL2_SOURCE_ADDR 0x818 +#define MV64340_DMA_CHANNEL3_SOURCE_ADDR 0x81c +#define MV64340_DMA_CHANNEL0_DESTINATION_ADDR 0x820 +#define MV64340_DMA_CHANNEL1_DESTINATION_ADDR 0x824 +#define MV64340_DMA_CHANNEL2_DESTINATION_ADDR 0x828 +#define MV64340_DMA_CHANNEL3_DESTINATION_ADDR 0x82C +#define MV64340_DMA_CHANNEL0_NEXT_DESCRIPTOR_POINTER 0x830 +#define MV64340_DMA_CHANNEL1_NEXT_DESCRIPTOR_POINTER 0x834 +#define MV64340_DMA_CHANNEL2_NEXT_DESCRIPTOR_POINTER 0x838 +#define MV64340_DMA_CHANNEL3_NEXT_DESCRIPTOR_POINTER 0x83C +#define MV64340_DMA_CHANNEL0_CURRENT_DESCRIPTOR_POINTER 0x870 +#define MV64340_DMA_CHANNEL1_CURRENT_DESCRIPTOR_POINTER 0x874 +#define MV64340_DMA_CHANNEL2_CURRENT_DESCRIPTOR_POINTER 0x878 +#define MV64340_DMA_CHANNEL3_CURRENT_DESCRIPTOR_POINTER 0x87C + + /* IDMA Address Decoding Base Address Registers */ + +#define MV64340_DMA_BASE_ADDR_REG0 0xa00 +#define MV64340_DMA_BASE_ADDR_REG1 0xa08 +#define MV64340_DMA_BASE_ADDR_REG2 0xa10 +#define MV64340_DMA_BASE_ADDR_REG3 0xa18 +#define MV64340_DMA_BASE_ADDR_REG4 0xa20 +#define MV64340_DMA_BASE_ADDR_REG5 0xa28 +#define MV64340_DMA_BASE_ADDR_REG6 0xa30 +#define MV64340_DMA_BASE_ADDR_REG7 0xa38 + + /* IDMA Address Decoding Size Address Register */ + +#define MV64340_DMA_SIZE_REG0 0xa04 +#define MV64340_DMA_SIZE_REG1 0xa0c +#define MV64340_DMA_SIZE_REG2 0xa14 +#define MV64340_DMA_SIZE_REG3 0xa1c +#define MV64340_DMA_SIZE_REG4 0xa24 +#define MV64340_DMA_SIZE_REG5 0xa2c +#define MV64340_DMA_SIZE_REG6 0xa34 +#define MV64340_DMA_SIZE_REG7 0xa3C + + /* IDMA Address Decoding High Address Remap and Access + Protection Registers */ + +#define MV64340_DMA_HIGH_ADDR_REMAP_REG0 0xa60 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG1 0xa64 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG2 0xa68 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG3 0xa6C +#define MV64340_DMA_BASE_ADDR_ENABLE_REG 0xa80 +#define MV64340_DMA_CHANNEL0_ACCESS_PROTECTION_REG 0xa70 +#define MV64340_DMA_CHANNEL1_ACCESS_PROTECTION_REG 0xa74 +#define MV64340_DMA_CHANNEL2_ACCESS_PROTECTION_REG 0xa78 +#define MV64340_DMA_CHANNEL3_ACCESS_PROTECTION_REG 0xa7c +#define MV64340_DMA_ARBITER_CONTROL 0x860 +#define MV64340_DMA_CROSS_BAR_TIMEOUT 0x8d0 + + /* IDMA Headers Retarget Registers */ + +#define MV64340_DMA_HEADERS_RETARGET_CONTROL 0xa84 +#define MV64340_DMA_HEADERS_RETARGET_BASE 0xa88 + + /* IDMA Interrupt Register */ + +#define MV64340_DMA_INTERRUPT_CAUSE_REG 0x8c0 +#define MV64340_DMA_INTERRUPT_CAUSE_MASK 0x8c4 +#define MV64340_DMA_ERROR_ADDR 0x8c8 +#define MV64340_DMA_ERROR_SELECT 0x8cc + + /* IDMA Debug Register ( for internal use ) */ + +#define MV64340_DMA_DEBUG_LOW 0x8e0 +#define MV64340_DMA_DEBUG_HIGH 0x8e4 +#define MV64340_DMA_SPARE 0xA8C + +/****************************************/ +/* Timer_Counter */ +/****************************************/ + +#define MV64340_TIMER_COUNTER0 0x850 +#define MV64340_TIMER_COUNTER1 0x854 +#define MV64340_TIMER_COUNTER2 0x858 +#define MV64340_TIMER_COUNTER3 0x85C +#define MV64340_TIMER_COUNTER_0_3_CONTROL 0x864 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c + +/****************************************/ +/* Watchdog registers */ +/****************************************/ + +#define MV64340_WATCHDOG_CONFIG_REG 0xb410 +#define MV64340_WATCHDOG_VALUE_REG 0xb414 + +/****************************************/ +/* I2C Registers */ +/****************************************/ + +#define MV64340_I2C_SLAVE_ADDR 0xc000 +#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 +#define MV64340_I2C_DATA 0xc004 +#define MV64340_I2C_CONTROL 0xc008 +#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C +#define MV64340_I2C_SOFT_RESET 0xc01c + +/****************************************/ +/* GPP Interface Registers */ +/****************************************/ + +#define MV64340_GPP_IO_CONTROL 0xf100 +#define MV64340_GPP_LEVEL_CONTROL 0xf110 +#define MV64340_GPP_VALUE 0xf104 +#define MV64340_GPP_INTERRUPT_CAUSE 0xf108 +#define MV64340_GPP_INTERRUPT_MASK0 0xf10c +#define MV64340_GPP_INTERRUPT_MASK1 0xf114 +#define MV64340_GPP_VALUE_SET 0xf118 +#define MV64340_GPP_VALUE_CLEAR 0xf11c + +/****************************************/ +/* Interrupt Controller Registers */ +/****************************************/ + +/****************************************/ +/* Interrupts */ +/****************************************/ + +#define MV64340_MAIN_INTERRUPT_CAUSE_LOW 0x004 +#define MV64340_MAIN_INTERRUPT_CAUSE_HIGH 0x00c +#define MV64340_CPU_INTERRUPT0_MASK_LOW 0x014 +#define MV64340_CPU_INTERRUPT0_MASK_HIGH 0x01c +#define MV64340_CPU_INTERRUPT0_SELECT_CAUSE 0x024 +#define MV64340_CPU_INTERRUPT1_MASK_LOW 0x034 +#define MV64340_CPU_INTERRUPT1_MASK_HIGH 0x03c +#define MV64340_CPU_INTERRUPT1_SELECT_CAUSE 0x044 +#define MV64340_INTERRUPT0_MASK_0_LOW 0x054 +#define MV64340_INTERRUPT0_MASK_0_HIGH 0x05c +#define MV64340_INTERRUPT0_SELECT_CAUSE 0x064 +#define MV64340_INTERRUPT1_MASK_0_LOW 0x074 +#define MV64340_INTERRUPT1_MASK_0_HIGH 0x07c +#define MV64340_INTERRUPT1_SELECT_CAUSE 0x084 + +/****************************************/ +/* MPP Interface Registers */ +/****************************************/ + +#define MV64340_MPP_CONTROL0 0xf000 +#define MV64340_MPP_CONTROL1 0xf004 +#define MV64340_MPP_CONTROL2 0xf008 +#define MV64340_MPP_CONTROL3 0xf00c + +/****************************************/ +/* Serial Initialization registers */ +/****************************************/ + +#define MV64340_SERIAL_INIT_LAST_DATA 0xf324 +#define MV64340_SERIAL_INIT_CONTROL 0xf328 +#define MV64340_SERIAL_INIT_STATUS 0xf32c + +#endif diff -Nru a/include/asm-mips64/mv64340_dep.h b/include/asm-mips64/mv64340_dep.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/mv64340_dep.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,51 @@ +/* + * Copyright 2002 Momentum Computer Inc. + * Author: Matthew Dharm <mdharm@momenco.com> + * + * include/asm-mips/mv64340-dep.h + * Board-dependent definitions for MV-64340 chip. + * + * 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 __MV64340_DEP_H__ +#define __MV64340_DEP_H__ + +#include <asm/addrspace.h> /* for KSEG1ADDR() */ +#include <asm/byteorder.h> /* for cpu_to_le32() */ + +extern unsigned long mv64340_base; + +#define MV64340_BASE (mv64340_base) + +/* + * Because of an error/peculiarity in the Galileo chip, we need to swap the + * bytes when running bigendian. + */ + +#define MV_WRITE(ofs, data) \ + *(volatile u32 *)(MV64340_BASE+(ofs)) = cpu_to_le32(data) +#define MV_READ(ofs, data) \ + *(data) = le32_to_cpu(*(volatile u32 *)(MV64340_BASE+(ofs))) +#define MV_READ_DATA(ofs) \ + le32_to_cpu(*(volatile u32 *)(MV64340_BASE+(ofs))) + +#define MV_WRITE_16(ofs, data) \ + *(volatile u16 *)(MV64340_BASE+(ofs)) = cpu_to_le16(data) +#define MV_READ_16(ofs, data) \ + *(data) = le16_to_cpu(*(volatile u16 *)(MV64340_BASE+(ofs))) + +#define MV_WRITE_8(ofs, data) \ + *(volatile u8 *)(MV64340_BASE+(ofs)) = data +#define MV_READ_8(ofs, data) \ + *(data) = *(volatile u8 *)(MV64340_BASE+(ofs)) + +#define MV_SET_REG_BITS(ofs,bits) \ + (*((volatile u32 *)(MV64340_BASE+(ofs)))) |= ((u32)cpu_to_le32(bits)) +#define MV_RESET_REG_BITS(ofs,bits) \ + (*((volatile u32 *)(MV64340_BASE+(ofs)))) &= ~((u32)cpu_to_le32(bits)) + +#endif diff -Nru a/include/asm-mips64/paccess.h b/include/asm-mips64/paccess.h --- a/include/asm-mips64/paccess.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/paccess.h Fri Jun 27 14:20:05 2003 @@ -15,6 +15,9 @@ #include <linux/errno.h> +extern asmlinkage void handle_ibe(void); +extern asmlinkage void handle_dbe(void); + #define put_dbe(x,ptr) __put_dbe((x),(ptr),sizeof(*(ptr))) #define get_dbe(x,ptr) __get_dbe((x),(ptr),sizeof(*(ptr))) @@ -87,5 +90,10 @@ :"r" (__pu_val), "o" (__mp(__pu_addr)), "i" (-EFAULT)); }) extern void __put_dbe_unknown(void); + +extern asmlinkage void handle_ibe(void); +extern asmlinkage void handle_dbe(void); + +extern unsigned long search_dbe_table(unsigned long addr); #endif /* _ASM_PACCESS_H */ diff -Nru a/include/asm-mips64/page.h b/include/asm-mips64/page.h --- a/include/asm-mips64/page.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/page.h Fri Jun 27 14:19:52 2003 @@ -18,22 +18,43 @@ #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ extern void (*_clear_page)(void * page); extern void (*_copy_page)(void * to, void * from); -#define clear_page(page) _clear_page(page) -#define copy_page(to, from) _copy_page(to, from) +#define clear_page(page) _clear_page((void *)(page)) +#define copy_page(to, from) _copy_page((void *)(to), (void *)(from)) -#define clear_user_page(addr, vaddr, page) \ - do { clear_page(addr); \ - flush_dcache_page(page); \ - } while (0) -#define copy_user_page(to, from, vaddr, page) \ - do { copy_page(to, from); \ - flush_dcache_page(page); \ - } while (0) +extern unsigned long shm_align_mask; + +static inline unsigned long pages_do_alias(unsigned long addr1, + unsigned long addr2) +{ + return (addr1 ^ addr2) & shm_align_mask; +} + +struct page; + +static inline void clear_user_page(void *addr, unsigned long vaddr, + struct page *page) +{ + extern void (*flush_data_cache_page)(unsigned long addr); + + clear_page(addr); + if (pages_do_alias((unsigned long) addr, vaddr)) + flush_data_cache_page((unsigned long)addr); +} + +static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *to) +{ + extern void (*flush_data_cache_page)(unsigned long addr); + + copy_page(vto, vfrom); + if (pages_do_alias((unsigned long)vto, vaddr)) + flush_data_cache_page((unsigned long)vto); +} /* * These are used to make use of C type-checking.. @@ -48,37 +69,60 @@ #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) +#define ptep_buddy(x) ((pte_t *)((unsigned long)(x) ^ sizeof(pte_t))) + #define __pte(x) ((pte_t) { (x) } ) -#define __pme(x) ((pme_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -#endif /* _LANGUAGE_ASSEMBLY */ +/* Pure 2^n version of get_order */ +extern __inline__ int get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +#endif /* !__ASSEMBLY__ */ /* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) /* * This handles the memory map. - * We handle pages at KSEG0 for kernels with upto 512mb of memory, - * at XKPHYS for kernels with more than that. */ -#ifdef CONFIG_SGI_IP22 -#define PAGE_OFFSET 0xffffffff80000000UL -#endif -#ifdef CONFIG_SGI_IP27 +#ifdef CONFIG_NONCOHERENT_IO +#define PAGE_OFFSET 0x9800000000000000UL +#else #define PAGE_OFFSET 0xa800000000000000UL #endif -#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) -#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) +#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) +#define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) + +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) + #ifndef CONFIG_DISCONTIGMEM -#define virt_to_page(kaddr) (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) -#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) +#define pfn_to_page(pfn) (mem_map + (pfn)) +#define page_to_pfn(page) ((unsigned long)((page) - mem_map)) +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) + +#define pfn_valid(pfn) ((pfn) < max_mapnr) +#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) #endif #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE) +#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET) #endif /* defined (__KERNEL__) */ diff -Nru a/include/asm-mips64/param.h b/include/asm-mips64/param.h --- a/include/asm-mips64/param.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/param.h Fri Jun 27 14:19:55 2003 @@ -3,18 +3,32 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright 1994 - 2000 Ralf Baechle (ralf@gnu.org) + * Copyright 1994 - 2000, 2002 Ralf Baechle (ralf@gnu.org) * Copyright 2000 Silicon Graphics, Inc. */ #ifndef _ASM_PARAM_H #define _ASM_PARAM_H -#ifndef HZ -#define HZ 100 -# define HZ 100 #ifdef __KERNEL__ -# define hz_to_std(a) (a) + +#include <linux/config.h> + +#ifdef CONFIG_DECSTATION + /* + * log2(HZ), change this here if you want another HZ value. This is also + * used in dec_time_init. Minimum is 1, Maximum is 15. + */ +# define LOG_2_HZ 7 +# define HZ (1 << LOG_2_HZ) +#else +# define HZ 1000 /* Internal kernel timer frequency */ #endif +# define USER_HZ 100 /* .. some user interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#endif + +#ifndef HZ +#define HZ 100 #endif #define EXEC_PAGESIZE 4096 @@ -28,9 +42,5 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ - -#ifdef __KERNEL__ -# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ -#endif #endif /* _ASM_PARAM_H */ diff -Nru a/include/asm-mips64/pci/bridge.h b/include/asm-mips64/pci/bridge.h --- a/include/asm-mips64/pci/bridge.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/pci/bridge.h Fri Jun 27 14:19:54 2003 @@ -41,7 +41,7 @@ * Bridge address map */ -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +#ifndef __ASSEMBLY__ /* * All accesses to bridge hardware registers must be done @@ -283,7 +283,7 @@ } bridge_err_cmdword_t; #define berr_field berr_un.berr_st -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * The values of these macros can and should be crosschecked @@ -612,7 +612,7 @@ /* Bridge INT_DEV register bits definition */ #define BRIDGE_INT_DEV_SHFT(n) ((n)*3) #define BRIDGE_INT_DEV_MASK(n) (0x7 << BRIDGE_INT_DEV_SHFT(n)) -#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line)) +#define BRIDGE_INT_DEV_SET(_dev, _line) (_dev << BRIDGE_INT_DEV_SHFT(_line)) /* Bridge interrupt(x) register bits definition */ #define BRIDGE_INT_ADDR_HOST 0x0003FF00 @@ -793,7 +793,7 @@ #define PCI64_ATTR_RMF_MASK 0x00ff000000000000 #define PCI64_ATTR_RMF_SHFT 48 -#if LANGUAGE_C +#ifndef __ASSEMBLY__ /* Address translation entry for mapped pci32 accesses */ typedef union ate_u { u64 ent; @@ -809,7 +809,7 @@ u64 valid:1; } field; } ate_t; -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #define ATE_V 0x01 #define ATE_CO 0x02 diff -Nru a/include/asm-mips64/pci.h b/include/asm-mips64/pci.h --- a/include/asm-mips64/pci.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/pci.h Fri Jun 27 14:19:53 2003 @@ -7,6 +7,7 @@ #define _ASM_PCI_H #include <linux/config.h> +#include <linux/mm.h> #ifdef __KERNEL__ @@ -23,12 +24,12 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 -extern inline void pcibios_set_master(struct pci_dev *dev) +static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ } -extern inline void pcibios_penalize_isa_irq(int irq) +static inline void pcibios_penalize_isa_irq(int irq) { /* We don't do dynamic PCI IRQ allocation */ } @@ -38,16 +39,29 @@ * MIPS has everything mapped statically. */ -#include <linux/config.h> #include <linux/types.h> #include <linux/slab.h> #include <asm/scatterlist.h> #include <linux/string.h> #include <asm/io.h> +#if defined(CONFIG_DDB5074) || defined(CONFIG_DDB5476) +#undef PCIBIOS_MIN_IO +#undef PCIBIOS_MIN_MEM +#define PCIBIOS_MIN_IO 0x0100000 +#define PCIBIOS_MIN_MEM 0x1000000 +#endif + struct pci_dev; /* + * The PCI address space does equal the physical memory address space. The + * networking and block device layers use this boolean for bounce buffer + * decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (1) + +/* * Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices, * NULL for PCI-like buses (ISA, EISA). @@ -87,18 +101,12 @@ int nelems, int direction); /* pci_unmap_{single,page} is not a nop, thus... */ -#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ - dma_addr_t ADDR_NAME; -#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ - __u32 LEN_NAME; -#define pci_unmap_addr(PTR, ADDR_NAME) \ - ((PTR)->ADDR_NAME) -#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ - (((PTR)->ADDR_NAME) = (VAL)) -#define pci_unmap_len(PTR, LEN_NAME) \ - ((PTR)->LEN_NAME) -#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ - (((PTR)->LEN_NAME) = (VAL)) +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; +#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) #else /* CONFIG_MAPPED_PCI_IO */ @@ -112,13 +120,14 @@ static inline dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) { + unsigned long addr = (unsigned long) ptr; + if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)ptr, size); -#endif - return virt_to_bus(ptr); + dma_cache_wback_inv(addr, size); + + return bus_to_baddr(hwdev->bus, __pa(ptr)); } /* @@ -135,7 +144,12 @@ if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do */ + if (direction != PCI_DMA_TODEVICE) { + unsigned long addr; + + addr = baddr_to_bus(hwdev->bus, dma_addr) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); + } } /* pci_unmap_{page,single} is a nop so... */ @@ -147,6 +161,39 @@ #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) /* + * pci_{map,unmap}_single_page maps a kernel page to a dma_addr_t. identical + * to pci_map_single, but takes a struct page instead of a virtual address + */ +static inline dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page, + unsigned long offset, size_t size, + int direction) +{ + unsigned long addr; + + if (direction == PCI_DMA_NONE) + BUG(); + + addr = (unsigned long) page_address(page) + offset; + dma_cache_wback_inv(addr, size); + + return bus_to_baddr(hwdev->bus, page_to_phys(page) + offset); +} + +static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address, + size_t size, int direction) +{ + if (direction == PCI_DMA_NONE) + BUG(); + + if (direction != PCI_DMA_TODEVICE) { + unsigned long addr; + + addr = baddr_to_bus(hwdev->bus, dma_address) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); + } +} + +/* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list @@ -170,12 +217,14 @@ if (direction == PCI_DMA_NONE) BUG(); - /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nents; i++, sg++) { -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)sg->address, sg->length); -#endif - sg->address = (char *)(bus_to_baddr[hwdev->bus->number] | __pa(sg->address)); + unsigned long addr; + + addr = (unsigned long) page_address(sg->page); + if (addr) + dma_cache_wback_inv(addr + sg->offset, sg->length); + sg->dma_address = (dma_addr_t) bus_to_baddr(hwdev->bus, + page_to_phys(sg->page) + sg->offset); } return nents; @@ -189,10 +238,24 @@ static inline void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { + int i; + if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do */ + if (direction == PCI_DMA_TODEVICE) + return; + + for (i = 0; i < nents; i++, sg++) { + unsigned long addr; + + if (!sg->page) + BUG(); + + addr = (unsigned long) page_address(sg->page); + if (addr) + dma_cache_wback_inv(addr + sg->offset, sg->length); + } } /* @@ -209,11 +272,13 @@ dma_addr_t dma_handle, size_t size, int direction) { + unsigned long addr; + if (direction == PCI_DMA_NONE) BUG(); -#ifndef CONFIG_COHERENT_IO - dma_cache_wback_inv((unsigned long)__va(dma_handle - bus_to_baddr[hwdev->bus->number]), size); -#endif + + addr = baddr_to_bus(hwdev->bus, dma_handle) + PAGE_OFFSET; + dma_cache_wback_inv(addr, size); } /* @@ -227,21 +292,28 @@ struct scatterlist *sg, int nelems, int direction) { -#ifndef CONFIG_COHERENT_IO +#ifdef CONFIG_NONCOHERENT_IO int i; #endif if (direction == PCI_DMA_NONE) BUG(); - /* Make sure that gcc doesn't leave the empty loop body. */ -#ifndef CONFIG_COHERENT_IO + /* Make sure that gcc doesn't leave the empty loop body. */ +#ifdef CONFIG_NONCOHERENT_IO for (i = 0; i < nelems; i++, sg++) - dma_cache_wback_inv((unsigned long)sg->address, sg->length); + dma_cache_wback_inv((unsigned long)page_address(sg->page), + sg->length); #endif } #endif /* CONFIG_MAPPED_PCI_IO */ +/* + * Return whether the given PCI device DMA address mask can + * be supported properly. For example, if your device can + * only drive the low 24-bits during PCI bus mastering, then + * you would pass 0x00ffffff as the mask to this function. + */ static inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) { /* @@ -249,12 +321,51 @@ * so we can't guarantee allocations that must be * within a tighter range than GFP_DMA.. */ +#ifdef CONFIG_ISA if (mask < 0x00ffffff) return 0; +#endif return 1; } +/* This is always fine. */ +#define pci_dac_dma_supported(pci_dev, mask) (1) + +static inline dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, + struct page *page, unsigned long offset, int direction) +{ + dma64_addr_t addr = page_to_phys(page) + offset; + + return (dma64_addr_t) bus_to_baddr(pdev->bus, addr); +} + +static inline struct page *pci_dac_dma_to_page(struct pci_dev *pdev, + dma64_addr_t dma_addr) +{ + unsigned long poff = baddr_to_bus(pdev->bus, dma_addr) >> PAGE_SHIFT; + + return mem_map + poff; +} + +static inline unsigned long pci_dac_dma_to_offset(struct pci_dev *pdev, + dma64_addr_t dma_addr) +{ + return dma_addr & ~PAGE_MASK; +} + +static inline void pci_dac_dma_sync_single(struct pci_dev *pdev, + dma64_addr_t dma_addr, size_t len, int direction) +{ + unsigned long addr; + + if (direction == PCI_DMA_NONE) + BUG(); + + addr = baddr_to_bus(pdev->bus, dma_addr) + PAGE_OFFSET; + dma_cache_wback_inv(addr, len); +} + /* * These macros should be used after a pci_map_sg call has been done * to get bus addresses of each of the SG entries and their lengths. @@ -262,7 +373,7 @@ * returns, or alternatively stop on the first sg_dma_len(sg) which * is 0. */ -#define sg_dma_address(sg) ((unsigned long)((sg)->address)) +#define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) #endif /* __KERNEL__ */ diff -Nru a/include/asm-mips64/percpu.h b/include/asm-mips64/percpu.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/percpu.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +#ifndef __ASM_PERCPU_H +#define __ASM_PERCPU_H + +#include <asm-generic/percpu.h> + +#endif /* __ASM_PERCPU_H */ diff -Nru a/include/asm-mips64/pgalloc.h b/include/asm-mips64/pgalloc.h --- a/include/asm-mips64/pgalloc.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips64/pgalloc.h Fri Jun 27 14:20:00 2003 @@ -10,191 +10,100 @@ #define _ASM_PGALLOC_H #include <linux/config.h> +#include <linux/highmem.h> +#include <linux/mm.h> +#include <asm/page.h> -/* TLB flushing: - * - * - flush_tlb_all() flushes all processes TLB entries - * - flush_tlb_mm(mm) flushes the specified mm context TLB entries - * - flush_tlb_page(vma, vmaddr) flushes a single page - * - flush_tlb_range(vma, start, end) flushes a range of pages - * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables - */ -extern void (*_flush_tlb_all)(void); -extern void (*_flush_tlb_mm)(struct mm_struct *mm); -extern void (*_flush_tlb_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void (*_flush_tlb_page)(struct vm_area_struct *vma, unsigned long page); +#define check_pgt_cache() do { } while (0) -#ifndef CONFIG_SMP - -#define flush_tlb_all() _flush_tlb_all() -#define flush_tlb_mm(mm) _flush_tlb_mm(mm) -#define flush_tlb_range(vma,vmaddr,end) _flush_tlb_range(vma, vmaddr, end) -#define flush_tlb_page(vma,page) _flush_tlb_page(vma, page) - -#else /* CONFIG_SMP */ - -extern void flush_tlb_all(void); -extern void flush_tlb_mm(struct mm_struct *); -extern void flush_tlb_range(struct vm_area_struct *, unsigned long, unsigned long); -extern void flush_tlb_page(struct vm_area_struct *, unsigned long); - -#endif /* CONFIG_SMP */ - -extern inline void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, unsigned long end) +static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, + pte_t *pte) { - /* Nothing to do on MIPS. */ + set_pmd(pmd, __pmd(__pa(pte))); } +static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, + struct page *pte) +{ + set_pmd(pmd, __pmd((PAGE_OFFSET + page_to_pfn(pte)) << PAGE_SHIFT)); +} -/* - * Allocate and free page tables. - */ - -#define pgd_quicklist (current_cpu_data.pgd_quick) -#define pmd_quicklist (current_cpu_data.pmd_quick) -#define pte_quicklist (current_cpu_data.pte_quick) -#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) - -#define pmd_populate(mm, pmd, pte) pmd_set(pmd, pte) -#define pgd_populate(mm, pgd, pmd) pgd_set(pgd, pmd) - -extern pgd_t *get_pgd_slow(void); +#define pgd_populate(mm, pgd, pmd) set_pgd(pgd, __pgd(pmd)) -extern inline pgd_t *get_pgd_fast(void) +static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - unsigned long *ret; + pgd_t *ret, *init; - if((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - return (pgd_t *)ret; + ret = (pgd_t *) __get_free_pages(GFP_KERNEL, 1); + if (ret) { + init = pgd_offset(&init_mm, 0); + pgd_init((unsigned long)ret); + memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); } - ret = (unsigned long *) get_pgd_slow(); - return (pgd_t *)ret; + return ret; } -extern inline void free_pgd_fast(pgd_t *pgd) +static inline void pgd_free(pgd_t *pgd) { - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; + free_pages((unsigned long)pgd, PGD_ORDER); } -extern inline void free_pgd_slow(pgd_t *pgd) -{ - free_pages((unsigned long)pgd, 1); -} - -static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, + unsigned long address) { pte_t *pte; - pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); + pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, + PTE_ORDER); if (pte) clear_page(pte); + return pte; } -static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) +static inline struct page *pte_alloc_one(struct mm_struct *mm, + unsigned long address) { - unsigned long *ret; - - if ((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; -} - -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); + struct page *pte; -extern inline pte_t *get_pte_fast(void) -{ - unsigned long *ret; + pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER); + if (pte) + clear_highpage(pte); - if((ret = (unsigned long *)pte_quicklist) != NULL) { - pte_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pte_t *)ret; + return pte; } -extern inline void free_pte_fast(pte_t *pte) +static inline void pte_free_kernel(pte_t *pte) { - *(unsigned long *)pte = (unsigned long) pte_quicklist; - pte_quicklist = (unsigned long *) pte; - pgtable_cache_size++; + free_pages((unsigned long)pte, PTE_ORDER); } -extern inline void free_pte_slow(pte_t *pte) +static inline void pte_free(struct page *pte) { - free_pages((unsigned long)pte, 0); + __free_pages(pte, PTE_ORDER); } +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) +#define __pmd_free_tlb(tlb,x) do { } while (0) + static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { pmd_t *pmd; - pmd = (pmd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1); + pmd = (pmd_t *) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, PMD_ORDER); if (pmd) pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); return pmd; } -static inline pmd_t *pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address) -{ - unsigned long *ret; - - if ((ret = (unsigned long *)pmd_quicklist) != NULL) { - pmd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } - return (pmd_t *)ret; -} - -extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long address_preadjusted); - -extern inline pmd_t *get_pmd_fast(void) -{ - unsigned long *ret; - - if ((ret = (unsigned long *)pmd_quicklist) != NULL) { - pmd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - return (pmd_t *)ret; - } - - return (pmd_t *)ret; -} - -extern inline void free_pmd_fast(pmd_t *pmd) +static inline void pmd_free(pmd_t *pmd) { - *(unsigned long *)pmd = (unsigned long) pmd_quicklist; - pmd_quicklist = (unsigned long *) pmd; - pgtable_cache_size++; + free_pages((unsigned long)pmd, PMD_ORDER); } -extern inline void free_pmd_slow(pmd_t *pmd) -{ - free_pages((unsigned long)pmd, 1); -} - -#define pte_free(pte) free_pte_fast(pte) -#define pmd_free(pte) free_pmd_fast(pte) -#define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc(mm) get_pgd_fast() - -extern pte_t kptbl[(PAGE_SIZE<<KPTBL_PAGE_ORDER)/sizeof(pte_t)]; +extern pte_t kptbl[(PAGE_SIZE << PGD_ORDER)/sizeof(pte_t)]; extern pmd_t kpmdtbl[PTRS_PER_PMD]; - -extern int do_check_pgt_cache(int, int); #endif /* _ASM_PGALLOC_H */ diff -Nru a/include/asm-mips64/pgtable-bits.h b/include/asm-mips64/pgtable-bits.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/pgtable-bits.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,102 @@ +/* + * 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 - 2002 by Ralf Baechle + * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + * Copyright (C) 2002 Maciej W. Rozycki + */ +#ifndef _ASM_PGTABLE_BITS_H +#define _ASM_PGTABLE_BITS_H + +#include <linux/config.h> + +/* + * Note that we shift the lower 32bits of each EntryLo[01] entry + * 6 bits to the left. That way we can convert the PFN into the + * physical address by a single 'and' operation and gain 6 additional + * bits for storing information which isn't present in a normal + * MIPS page table. + * + * Similar to the Alpha port, we need to keep track of the ref + * and mod bits in software. We have a software "yeah you can read + * from this page" bit, and a hardware one which actually lets the + * process read from the page. On the same token we have a software + * writable bit and the real hardware one which actually lets the + * process write to the page, this keeps a mod bit via the hardware + * dirty bit. + * + * Certain revisions of the R4000 and R5000 have a bug where if a + * certain sequence occurs in the last 3 instructions of an executable + * page, and the following page is not mapped, the cpu can do + * unpredictable things. The code (when it is written) to deal with + * this problem will be in the update_mmu_cache() code for the r4k. + */ +#define _PAGE_PRESENT (1<<0) /* implemented in software */ +#define _PAGE_READ (1<<1) /* implemented in software */ +#define _PAGE_WRITE (1<<2) /* implemented in software */ +#define _PAGE_ACCESSED (1<<3) /* implemented in software */ +#define _PAGE_MODIFIED (1<<4) /* implemented in software */ +#define _PAGE_FILE (1<<4) /* set:pagecache unset:swap */ + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + +#define _PAGE_GLOBAL (1<<8) +#define _PAGE_VALID (1<<9) +#define _PAGE_SILENT_READ (1<<9) /* synonym */ +#define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<10) +#define _CACHE_UNCACHED (1<<11) +#define _CACHE_MASK (1<<11) +#define _CACHE_CACHABLE_NONCOHERENT 0 + +#else +#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ +#define _PAGE_GLOBAL (1<<6) +#define _PAGE_VALID (1<<7) +#define _PAGE_SILENT_READ (1<<7) /* synonym */ +#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ +#define _PAGE_SILENT_WRITE (1<<8) +#define _CACHE_MASK (7<<9) + +#if defined(CONFIG_CPU_SB1) + +/* No penalty for being coherent on the SB1, so just + use it for "noncoherent" spaces, too. Shouldn't hurt. */ + +#define _CACHE_UNCACHED (2<<9) +#define _CACHE_CACHABLE_COW (5<<9) +#define _CACHE_CACHABLE_NONCOHERENT (5<<9) +#define _CACHE_UNCACHED_ACCELERATED (7<<9) + +#else + +#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ +#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ +#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ +#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00MC only */ +#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00MC only */ +#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00MC only */ +#define _CACHE_UNCACHED_ACCELERATED (7<<9) /* R10000 only */ + +#endif +#endif + +#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) +#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) + +#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) + +#ifdef CONFIG_MIPS_UNCACHED +#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED +#elif defined(CONFIG_NONCOHERENT_IO) +#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT +#else +#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW +#endif + +#define CONF_CM_DEFAULT (PAGE_CACHABLE_DEFAULT >> 9) + +#endif /* _ASM_PGTABLE_BITS_H */ diff -Nru a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h --- a/include/asm-mips64/pgtable.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/pgtable.h Fri Jun 27 14:20:05 2003 @@ -9,82 +9,29 @@ #ifndef _ASM_PGTABLE_H #define _ASM_PGTABLE_H +#include <linux/config.h> #include <asm/addrspace.h> #include <asm/page.h> -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ #include <linux/linkage.h> -#include <linux/config.h> #include <linux/mmzone.h> #include <asm/cachectl.h> -/* Cache flushing: - * - * - flush_cache_all() flushes entire cache - * - flush_cache_mm(mm) flushes the specified mm context's cache lines - * - flush_cache_page(mm, vmaddr) flushes a single page - * - flush_cache_range(vma, start, end) flushes a range of pages - */ -extern void (*_flush_cache_mm)(struct mm_struct *mm); -extern void (*_flush_cache_range)(struct vm_area_struct *vma, unsigned long start, - unsigned long end); -extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page); -extern void (*_flush_page_to_ram)(struct page * page); - -#define flush_cache_all() do { } while(0) - -#ifndef CONFIG_CPU_R10000 -#define flush_cache_mm(mm) _flush_cache_mm(mm) -#define flush_cache_range(vma,start,end) _flush_cache_range(vma,start,end) -#define flush_cache_page(vma,page) _flush_cache_page(vma, page) -#define flush_dcache_page(page) _flush_page_to_ram(page) -#define flush_icache_range(start, end) _flush_cache_l1() -#define flush_icache_user_range(vma, page, addr, len) \ - flush_icache_page((vma), (page)) - -#define flush_icache_page(vma, page) \ -do { \ - unsigned long addr; \ - addr = (unsigned long) page_address(page); \ - _flush_cache_page(vma, addr); \ -} while (0) -#else /* !CONFIG_CPU_R10000 */ -/* - * Since the r10k handles VCEs in hardware, most of the flush cache - * routines are not needed. Only the icache on a processor is not - * coherent with the dcache of the _same_ processor, so we must flush - * the icache so that it does not contain stale contents of physical - * memory. No flushes are needed for dma coherency, since the o200s - * are io coherent. The only place where we might be overoptimizing - * out icache flushes are from mprotect (when PROT_EXEC is added). - */ -extern void andes_flush_icache_page(unsigned long); -#define flush_cache_mm(mm) do { } while(0) -#define flush_cache_range(vma,start,end) do { } while(0) -#define flush_cache_page(vma,page) do { } while(0) -#define flush_dcache_page(page) do { } while(0) -#define flush_icache_range(start, end) _flush_cache_l1() -#define flush_icache_user_range(vma, page, addr, len) \ - flush_icache_page((vma), (page)) -#define flush_icache_page(vma, page) \ -do { \ - if ((vma)->vm_flags & VM_EXEC) \ - andes_flush_icache_page(page_address(page)); \ -} while (0) -#endif /* !CONFIG_CPU_R10000 */ - -/* - * The foll cache flushing routines are MIPS specific. - * flush_cache_l2 is needed only during initialization. - */ -extern void (*_flush_cache_sigtramp)(unsigned long addr); -extern void (*_flush_cache_l2)(void); -extern void (*_flush_cache_l1)(void); - -#define flush_cache_sigtramp(addr) _flush_cache_sigtramp(addr) -#define flush_cache_l2() _flush_cache_l2() -#define flush_cache_l1() _flush_cache_l1() +/* + * This flag is used to indicate that the page pointed to by a pte + * is dirty and requires cleaning before returning it to the user. + */ +#define PG_dcache_dirty PG_arch_1 + +#define Page_dcache_dirty(page) \ + test_bit(PG_dcache_dirty, &(page)->flags) +#define SetPageDcacheDirty(page) \ + set_bit(PG_dcache_dirty, &(page)->flags) +#define ClearPageDcacheDirty(page) \ + clear_bit(PG_dcache_dirty, &(page)->flags) + /* * Each address space has 2 4K pages as its page directory, giving 1024 @@ -92,21 +39,21 @@ * pair of 4K pages, giving 1024 (== PTRS_PER_PMD) 8 byte pointers to * page tables. Each page table is a single 4K page, giving 512 (== * PTRS_PER_PTE) 8 byte ptes. Each pgde is initialized to point to - * invalid_pmd_table, each pmde is initialized to point to + * invalid_pmd_table, each pmde is initialized to point to * invalid_pte_table, each pte is initialized to 0. When memory is low, * and a pmd table or a page table allocation fails, empty_bad_pmd_table * and empty_bad_page_table is returned back to higher layer code, so - * that the failure is recognized later on. Linux does not seem to + * that the failure is recognized later on. Linux does not seem to * handle these failures very well though. The empty_bad_page_table has * invalid pte entries in it, to force page faults. - * Vmalloc handling: vmalloc uses swapper_pg_dir[0] (returned by - * pgd_offset_k), which is initalized to point to kpmdtbl. kpmdtbl is - * the only single page pmd in the system. kpmdtbl entries point into - * kptbl[] array. We reserve 1<<KPTBL_PAGE_ORDER pages to hold the + * Vmalloc handling: vmalloc uses swapper_pg_dir[0] (returned by + * pgd_offset_k), which is initalized to point to kpmdtbl. kpmdtbl is + * the only single page pmd in the system. kpmdtbl entries point into + * kptbl[] array. We reserve 1 << PGD_ORDER pages to hold the * vmalloc range translations, which the fault handler looks at. */ -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ /* PMD_SHIFT determines the size of the area a second-level page table can map */ #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3)) @@ -120,75 +67,24 @@ /* Entries per page directory level: we use two-level, so we don't really have any PMD directory physically. */ -#define PTRS_PER_PGD 1024 -#define PTRS_PER_PMD 1024 -#define PTRS_PER_PTE 512 -#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) +#define PTRS_PER_PGD 1024 +#define PTRS_PER_PMD 1024 +#define PTRS_PER_PTE 512 +#define PGD_ORDER 1 +#define PMD_ORDER 1 +#define PTE_ORDER 0 + +#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 -#define KPTBL_PAGE_ORDER 1 -#define VMALLOC_START XKSEG -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -#define VMALLOC_END \ - (VMALLOC_START + ((1 << KPTBL_PAGE_ORDER) * PTRS_PER_PTE * PAGE_SIZE)) - -/* Note that we shift the lower 32bits of each EntryLo[01] entry - * 6 bits to the left. That way we can convert the PFN into the - * physical address by a single 'and' operation and gain 6 additional - * bits for storing information which isn't present in a normal - * MIPS page table. - * - * Similar to the Alpha port, we need to keep track of the ref - * and mod bits in software. We have a software "yeah you can read - * from this page" bit, and a hardware one which actually lets the - * process read from the page. On the same token we have a software - * writable bit and the real hardware one which actually lets the - * process write to the page, this keeps a mod bit via the hardware - * dirty bit. - * - * Certain revisions of the R4000 and R5000 have a bug where if a - * certain sequence occurs in the last 3 instructions of an executable - * page, and the following page is not mapped, the cpu can do - * unpredictable things. The code (when it is written) to deal with - * this problem will be in the update_mmu_cache() code for the r4k. - */ -#define _PAGE_PRESENT (1<<0) /* implemented in software */ -#define _PAGE_READ (1<<1) /* implemented in software */ -#define _PAGE_WRITE (1<<2) /* implemented in software */ -#define _PAGE_ACCESSED (1<<3) /* implemented in software */ -#define _PAGE_MODIFIED (1<<4) /* implemented in software */ -#define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */ -#define _PAGE_GLOBAL (1<<6) -#define _PAGE_VALID (1<<7) -#define _PAGE_SILENT_READ (1<<7) /* synonym */ -#define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */ -#define _PAGE_SILENT_WRITE (1<<8) -#define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */ -#define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */ -#define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */ -#define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */ -#define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00 only */ -#define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */ -#define _CACHE_MASK (7<<9) - -#define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED) -#define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED) - -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK) - -#ifdef CONFIG_MIPS_UNCACHED -#define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED -#else /* ! UNCACHED */ -#ifdef CONFIG_SGI_IP22 -#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT -#else /* ! IP22 */ -#define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW -#endif /* IP22 */ -#endif /* UNCACHED */ +#define VMALLOC_START XKSEG +#define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END \ + (VMALLOC_START + ((1 << PGD_ORDER) * PTRS_PER_PTE * PAGE_SIZE)) + +#include <asm/pgtable-bits.h> -#define PAGE_NONE __pgprot(_PAGE_PRESENT | PAGE_CACHABLE_DEFAULT) +#define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ PAGE_CACHABLE_DEFAULT) #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ @@ -196,11 +92,11 @@ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \ PAGE_CACHABLE_DEFAULT) #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - PAGE_CACHABLE_DEFAULT) + _PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT) #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ - _CACHE_UNCACHED) -#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \ - _CACHE_UNCACHED) + PAGE_CACHABLE_DEFAULT) +#define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \ + __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED) /* * MIPS can't do page protection for execute, and considers that the same like @@ -225,7 +121,7 @@ #define __S110 PAGE_SHARED #define __S111 PAGE_SHARED -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ #define pte_ERROR(e) \ printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) @@ -235,7 +131,7 @@ printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) /* - * ZERO_PAGE is a global shared page that is always zero: used + * ZERO_PAGE is a global shared page that is always zero; used * for zero-mapped memory areas etc.. */ @@ -245,21 +141,6 @@ #define ZERO_PAGE(vaddr) \ (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask))) -/* number of bits that fit into a memory pointer */ -#define BITS_PER_PTR (8*sizeof(unsigned long)) - -/* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - -/* - * sizeof(void*) == (1 << SIZEOF_PTR_LOG2) - */ -#define SIZEOF_PTR_LOG2 3 - -/* to find an entry in a page-table */ -#define PAGE_PTR(address) \ -((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) - extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)]; extern pte_t empty_bad_page_table[PAGE_SIZE/sizeof(pte_t)]; extern pmd_t invalid_pmd_table[2*PAGE_SIZE/sizeof(pmd_t)]; @@ -269,32 +150,22 @@ * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -extern inline unsigned long pmd_page(pmd_t pmd) -{ - return pmd_val(pmd); -} +#define page_pte(page) page_pte_prot(page, __pgprot(0)) +#define pmd_phys(pmd) (pmd_val(pmd) - PAGE_OFFSET) +#define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) +#define pmd_page_kernel(pmd) pmd_val(pmd) -extern inline unsigned long pgd_page(pgd_t pgd) +static inline unsigned long pgd_page(pgd_t pgd) { return pgd_val(pgd); } -extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK); -} - -extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp) +static inline int pte_none(pte_t pte) { - pgd_val(*pgdp) = (((unsigned long) pmdp) & PAGE_MASK); + return !(pte_val(pte) & ~_PAGE_GLOBAL); } -extern inline int pte_none(pte_t pte) -{ - return !pte_val(pte); -} - -extern inline int pte_present(pte_t pte) +static inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } @@ -304,42 +175,56 @@ * within a page table are directly modified. Thus, the following * hook is made available. */ -extern inline void set_pte(pte_t *ptep, pte_t pteval) +static inline void set_pte(pte_t *ptep, pte_t pteval) { *ptep = pteval; +#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) + if (pte_val(pteval) & _PAGE_GLOBAL) { + pte_t *buddy = ptep_buddy(ptep); + /* + * Make sure the buddy is global too (if it's !none, + * it better already be global) + */ + if (pte_none(*buddy)) + pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; + } +#endif } -extern inline void pte_clear(pte_t *ptep) +static inline void pte_clear(pte_t *ptep) { - set_pte(ptep, __pte(0)); +#if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) + /* Preserve global status for the pair */ + if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL) + set_pte(ptep, __pte(_PAGE_GLOBAL)); + else +#endif + set_pte(ptep, __pte(0)); } /* * (pmds are folded into pgds so this doesn't get actually called, * but the define is needed for a generic inline function.) */ -#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) -#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) +#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0) +#define set_pgd(pgdptr, pgdval) do { *(pgdptr) = (pgdval); } while(0) /* * Empty pmd entries point to the invalid_pte_table. */ -extern inline int pmd_none(pmd_t pmd) +static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) == (unsigned long) invalid_pte_table; } -extern inline int pmd_bad(pmd_t pmd) -{ - return pmd_val(pmd) &~ PAGE_MASK; -} +#define pmd_bad(pmd) (pmd_val(pmd) &~ PAGE_MASK) -extern inline int pmd_present(pmd_t pmd) +static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) != (unsigned long) invalid_pte_table; } -extern inline void pmd_clear(pmd_t *pmdp) +static inline void pmd_clear(pmd_t *pmdp) { pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); } @@ -347,84 +232,99 @@ /* * Empty pgd entries point to the invalid_pmd_table. */ -extern inline int pgd_none(pgd_t pgd) +static inline int pgd_none(pgd_t pgd) { return pgd_val(pgd) == (unsigned long) invalid_pmd_table; } -extern inline int pgd_bad(pgd_t pgd) -{ - return pgd_val(pgd) &~ PAGE_MASK; -} +#define pgd_bad(pgd) (pgd_val(pgd) &~ PAGE_MASK) -extern inline int pgd_present(pgd_t pgd) +static inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) != (unsigned long) invalid_pmd_table; } -extern inline void pgd_clear(pgd_t *pgdp) +static inline void pgd_clear(pgd_t *pgdp) { pgd_val(*pgdp) = ((unsigned long) invalid_pmd_table); } -#ifndef CONFIG_DISCONTIGMEM -#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT))) -#else +#ifdef CONFIG_DISCONTIGMEM -#define pte_page(x) ( NODE_MEM_MAP(PHYSADDR_TO_NID(pte_val(x))) + - PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x))) ) +#define pte_page(x) (NODE_MEM_MAP(PHYSADDR_TO_NID(pte_val(x))) + \ + PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x)))) +#else +#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT))) +#define pte_pfn(x) ((unsigned long)((x).pte >> PAGE_SHIFT)) +#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) #endif +#define PTE_FILE_MAX_BITS 27 + +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + /* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. + * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset + * into this range: */ -extern inline int pte_read(pte_t pte) -{ - return pte_val(pte) & _PAGE_READ; -} -extern inline int pte_write(pte_t pte) -{ - return pte_val(pte) & _PAGE_WRITE; -} +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) -extern inline int pte_dirty(pte_t pte) -{ - return pte_val(pte) & _PAGE_MODIFIED; -} +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) -extern inline int pte_young(pte_t pte) -{ - return pte_val(pte) & _PAGE_ACCESSED; -} +#else + +/* + * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset + * into this range: + */ +#define pte_to_pgoff(_pte) \ + ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) + +#define pgoff_to_pte(off) \ + ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) -extern inline pte_t pte_wrprotect(pte_t pte) +#endif + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +static inline int pte_user(pte_t pte) { BUG(); return 0; } +static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; } + +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_rdprotect(pte_t pte) +static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ); return pte; } -extern inline pte_t pte_mkclean(pte_t pte) +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); return pte; } -extern inline pte_t pte_mkold(pte_t pte) +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; if (pte_val(pte) & _PAGE_MODIFIED) @@ -432,7 +332,7 @@ return pte; } -extern inline pte_t pte_mkread(pte_t pte) +static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_READ; if (pte_val(pte) & _PAGE_ACCESSED) @@ -440,7 +340,7 @@ return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_MODIFIED; if (pte_val(pte) & _PAGE_WRITE) @@ -448,7 +348,7 @@ return pte; } -extern inline pte_t pte_mkyoung(pte_t pte) +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; if (pte_val(pte) & _PAGE_READ) @@ -477,29 +377,9 @@ * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#ifndef CONFIG_DISCONTIGMEM -#define PAGE_TO_PA(page) ((page - mem_map) << PAGE_SHIFT) -#else -#define PAGE_TO_PA(page) \ - (( ((page)-(page)->zone->zone_mem_map) + \ - (page)->zone->zone_start_pfn) << PAGE_SHIFT) -#endif -#define mk_pte(page, pgprot) \ -({ \ - pte_t __pte; \ - \ - pte_val(__pte) = ((unsigned long)(PAGE_TO_PA(page))) | \ - pgprot_val(pgprot); \ - \ - __pte; \ -}) +#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) -extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) -{ - return __pte(physpage | pgprot_val(pgprot)); -} - -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); } @@ -509,27 +389,31 @@ /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, 0) -#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) +#define pgd_index(address) ((address) >> PGDIR_SHIFT) /* to find an entry in a page-table-directory */ -extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address) -{ - return mm->pgd + pgd_index(address); -} +#define pgd_offset(mm,addr) ((mm)->pgd + pgd_index(addr)) /* Find an entry in the second-level page table.. */ -extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +static inline pmd_t *pmd_offset(pgd_t * dir, unsigned long address) { return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD - 1)); } -/* Find an entry in the third-level page table.. */ -extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) (pmd_page(*dir)) + - ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} +/* Find an entry in the third-level page table.. */ +#define __pte_offset(address) \ + (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset(dir, address) \ + ((pte_t *) (pmd_page_kernel(*dir)) + __pte_offset(address)) +#define pte_offset_kernel(dir, address) \ + ((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address)) +#define pte_offset_map(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_offset_map_nested(dir, address) \ + ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) +#define pte_unmap(pte) ((void)(pte)) +#define pte_unmap_nested(pte) ((void)(pte)) /* * Initialize a new pgd / pmd table with invalid pointers. @@ -540,14 +424,23 @@ extern pgd_t swapper_pg_dir[1024]; extern void paging_init(void); -extern void (*update_mmu_cache)(struct vm_area_struct *vma, - unsigned long address, pte_t pte); +extern void __update_tlb(struct vm_area_struct *vma, unsigned long address, + pte_t pte); +extern void __update_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte); + +static inline void update_mmu_cache(struct vm_area_struct *vma, + unsigned long address, pte_t pte) +{ + __update_tlb(vma, address, pte); + __update_cache(vma, address, pte); +} /* * Non-present pages: high 24 bits are offset, next 8 bits type, * low 32 bits zero. */ -extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) +static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) { pte_t pte; pte_val(pte) = (type << 32) | (offset << 40); return pte; } #define __swp_type(x) (((x).val >> 32) & 0xff) @@ -560,261 +453,23 @@ #define kern_addr_valid(addr) (1) #endif -/* TLB operations. */ -extern inline void tlb_probe(void) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "tlbp\n\t" - ".set reorder"); -} - -extern inline void tlb_read(void) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "tlbr\n\t" - ".set reorder"); -} - -extern inline void tlb_write_indexed(void) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "tlbwi\n\t" - ".set reorder"); -} - -extern inline void tlb_write_random(void) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "tlbwr\n\t" - ".set reorder"); -} - -/* Dealing with various CP0 mmu/cache related registers. */ - -/* CP0_PAGEMASK register */ -extern inline unsigned long get_pagemask(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "mfc0 %0, $5\n\t" - ".set reorder" - : "=r" (val)); - return val; -} - -extern inline void set_pagemask(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "mtc0 %z0, $5\n\t" - ".set reorder" - : : "Jr" (val)); -} - -/* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */ -extern inline unsigned long get_entrylo0(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "dmfc0 %0, $2\n\t" - ".set reorder" - : "=r" (val)); - return val; -} - -extern inline void set_entrylo0(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "dmtc0 %z0, $2\n\t" - ".set reorder" - : : "Jr" (val)); -} - -extern inline unsigned long get_entrylo1(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "dmfc0 %0, $3\n\t" - ".set reorder" : "=r" (val)); - - return val; -} - -extern inline void set_entrylo1(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "dmtc0 %z0, $3\n\t" - ".set reorder" - : : "Jr" (val)); -} - -/* CP0_ENTRYHI register */ -extern inline unsigned long get_entryhi(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "dmfc0 %0, $10\n\t" - ".set reorder" - : "=r" (val)); - - return val; -} - -extern inline void set_entryhi(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "dmtc0 %z0, $10\n\t" - ".set reorder" - : : "Jr" (val)); -} - -/* CP0_INDEX register */ -extern inline unsigned int get_index(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "mfc0 %0, $0\n\t" - ".set reorder" - : "=r" (val)); - return val; -} - -extern inline void set_index(unsigned int val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "mtc0 %z0, $0\n\t" - ".set reorder\n\t" - : : "Jr" (val)); -} - -/* CP0_WIRED register */ -extern inline unsigned long get_wired(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "mfc0 %0, $6\n\t" - ".set reorder\n\t" - : "=r" (val)); - return val; -} - -extern inline void set_wired(unsigned long val) -{ - __asm__ __volatile__( - "\n\t.set noreorder\n\t" - "mtc0 %z0, $6\n\t" - ".set reorder" - : : "Jr" (val)); -} - -extern inline unsigned long get_info(void) -{ - unsigned long val; - - __asm__( - ".set push\n\t" - ".set reorder\n\t" - "mfc0 %0, $7\n\t" - ".set pop" - : "=r" (val)); - return val; -} - -/* CP0_TAGLO and CP0_TAGHI registers */ -extern inline unsigned long get_taglo(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "mfc0 %0, $28\n\t" - ".set reorder" - : "=r" (val)); - return val; -} - -extern inline void set_taglo(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "mtc0 %z0, $28\n\t" - ".set reorder" - : : "Jr" (val)); -} - -extern inline unsigned long get_taghi(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "mfc0 %0, $29\n\t" - ".set reorder" - : "=r" (val)); - return val; -} - -extern inline void set_taghi(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "mtc0 %z0, $29\n\t" - ".set reorder" - : : "Jr" (val)); -} - -/* CP0_CONTEXT register */ -extern inline unsigned long get_context(void) -{ - unsigned long val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "dmfc0 %0, $4\n\t" - ".set reorder" - : "=r" (val)); - - return val; -} - -extern inline void set_context(unsigned long val) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "dmtc0 %z0, $4\n\t" - ".set reorder" - : : "Jr" (val)); -} +/* + * No page table caches to initialise + */ +#define pgtable_cache_init() do { } while (0) #include <asm-generic/pgtable.h> typedef pte_t *pte_addr_t; -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ - /* - * No page table caches to initialise + * We provide our own get_unmapped area to cope with the virtual aliasing + * constraints placed on us by the cache architecture. */ -#define pgtable_cache_init() do { } while (0) +#define HAVE_ARCH_UNMAPPED_AREA + +#define io_remap_page_range remap_page_range + +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_PGTABLE_H */ diff -Nru a/include/asm-mips64/poll.h b/include/asm-mips64/poll.h --- a/include/asm-mips64/poll.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/poll.h Fri Jun 27 14:19:54 2003 @@ -1,12 +1,5 @@ -/* - * 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) 1998, 1999 Ralf Baechle (ralf@gnu.org) - */ -#ifndef _ASM_POLL_H -#define _ASM_POLL_H +#ifndef __ASM_POLL_H +#define __ASM_POLL_H #define POLLIN 0x0001 #define POLLPRI 0x0002 @@ -21,8 +14,9 @@ #define POLLWRNORM POLLOUT #define POLLWRBAND 0x0100 -/* XXX This one seems to be more-or-less nonstandard. */ +/* These seem to be more or less nonstandard ... */ #define POLLMSG 0x0400 +#define POLLREMOVE 0x1000 struct pollfd { int fd; @@ -30,4 +24,4 @@ short revents; }; -#endif /* _ASM_POLL_H */ +#endif /* __ASM_POLL_H */ diff -Nru a/include/asm-mips64/posix_types.h b/include/asm-mips64/posix_types.h --- a/include/asm-mips64/posix_types.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/posix_types.h Fri Jun 27 14:19:54 2003 @@ -16,7 +16,7 @@ */ typedef unsigned int __kernel_dev_t; -typedef unsigned int __kernel_ino_t; +typedef unsigned long __kernel_ino_t; typedef unsigned int __kernel_mode_t; typedef unsigned int __kernel_nlink_t; typedef long __kernel_off_t; @@ -26,10 +26,12 @@ typedef int __kernel_gid_t; typedef unsigned long __kernel_size_t; typedef long __kernel_ssize_t; -typedef long __kernel_ptrdiff_t; +typedef long __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; typedef long __kernel_daddr_t; typedef char * __kernel_caddr_t; @@ -86,7 +88,7 @@ #undef __FD_ISSET static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p) -{ +{ unsigned long __tmp = __fd / __NFDBITS; unsigned long __rem = __fd % __NFDBITS; return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0; diff -Nru a/include/asm-mips64/processor.h b/include/asm-mips64/processor.h --- a/include/asm-mips64/processor.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/processor.h Fri Jun 27 14:19:56 2003 @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1994 Waldorf GMBH - * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Ralf Baechle + * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle * Modified further for R[236]000 compatibility by Paul M. Antoine * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ @@ -15,55 +15,56 @@ /* * Return current * instruction pointer ("program counter"). - * - * Two implementations. The ``la'' version results in shorter code for - * the kernel which we assume to reside in the 32-bit compat address space. - * The ``jal'' version is for use by modules which live in outer space. - * This is just a single instruction unlike the long dla macro expansion. */ -#ifdef MODULE #define current_text_addr() \ ({ \ void *_a; \ \ - __asm__ ("jal\t1f, %0\n\t" \ - "1:" \ - : "=r" (_a)); \ + __asm__ ("bal\t1f\t\t\t# current_text_addr\n" \ + "1:\tmove\t%0, $31" \ + : "=r" (_a) \ + : \ + : "$31"); \ \ _a; \ }) -#else -#define current_text_addr() \ -({ \ - void *_a; \ - \ - __asm__ ("dla\t%0, 1f\n\t" \ - "1:" \ - : "=r" (_a)); \ - \ - _a; \ -}) -#endif -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ +#include <linux/cache.h> +#include <linux/threads.h> + #include <asm/cachectl.h> #include <asm/mipsregs.h> #include <asm/reg.h> #include <asm/system.h> -#if (defined(CONFIG_SGI_IP27)) +#if defined(CONFIG_SGI_IP27) #include <asm/sn/types.h> #include <asm/sn/intr_public.h> #endif +/* + * Descriptor for a cache + */ +struct cache_desc { + unsigned short linesz; + unsigned short ways; + unsigned int sets; + unsigned int waybit; /* Bits to select in a cache set */ + unsigned int flags; /* Flags describingcache properties */ +}; + +/* + * Flag definitions + */ +#define MIPS_CACHE_NOT_PRESENT 0x00000001 +#define MIPS_CACHE_VTAG 0x00000002 /* Virtually tagged cache */ +#define MIPS_CACHE_ALIASES 0x00000004 /* Cache could have aliases */ +#define MIPS_CACHE_IC_F_DC 0x00000008 /* Ic can refill from D-cache */ + struct cpuinfo_mips { - unsigned long udelay_val; - unsigned long *pgd_quick; - unsigned long *pmd_quick; - unsigned long *pte_quick; - unsigned long pgtable_cache_sz; - unsigned long last_asn; - unsigned long asid_cache; + unsigned long udelay_val; + unsigned long asid_cache; #if defined(CONFIG_SGI_IP27) cpuid_t p_cpuid; /* PROM assigned cpuid */ cnodeid_t p_nodeid; /* my node ID in compact-id-space */ @@ -71,69 +72,94 @@ unsigned char p_slice; /* Physical position on node board */ hub_intmasks_t p_intmasks; /* SN0 per-CPU interrupt masks */ #endif -} __attribute__((aligned(128))); +#if 0 + unsigned long loops_per_sec; + unsigned long ipi_count; + unsigned long irq_attempt[NR_IRQS]; + unsigned long smp_local_irq_count; + unsigned long prof_multiplier; + unsigned long prof_counter; +#endif + + /* + * Capability and feature descriptor structure for MIPS CPU + */ + unsigned long options; + unsigned int processor_id; + unsigned int fpu_id; + unsigned int cputype; + int isa_level; + int tlbsize; + struct cache_desc icache; /* Primary I-cache */ + struct cache_desc dcache; /* Primary D or combined I/D cache */ + struct cache_desc scache; /* Secondary cache */ + struct cache_desc tcache; /* Tertiary/split secondary cache */ +} __attribute__((aligned(SMP_CACHE_BYTES))); + +/* + * Assumption: Options of CPU 0 are a superset of all processors. + * This is true for all known MIPS systems. + */ +#define cpu_has_tlb (cpu_data[0].options & MIPS_CPU_TLB) +#define cpu_has_4kex (cpu_data[0].options & MIPS_CPU_4KEX) +#define cpu_has_4ktlb (cpu_data[0].options & MIPS_CPU_4KTLB) +#define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU) +#define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) +#define cpu_has_counter (cpu_data[0].options & MIPS_CPU_COUNTER) +#define cpu_has_watch (cpu_data[0].options & MIPS_CPU_WATCH) +#define cpu_has_mips16 (cpu_data[0].options & MIPS_CPU_MIPS16) +#define cpu_has_divec (cpu_data[0].options & MIPS_CPU_DIVEC) +#define cpu_has_vce (cpu_data[0].options & MIPS_CPU_VCE) +#define cpu_has_cache_cdex (cpu_data[0].options & MIPS_CPU_CACHE_CDEX) +#define cpu_has_mcheck (cpu_data[0].options & MIPS_CPU_MCHECK) +#define cpu_has_ejtag (cpu_data[0].options & MIPS_CPU_EJTAG) +#define cpu_has_nofpuex (cpu_data[0].options & MIPS_CPU_NOFPUEX) +#define cpu_has_llsc (cpu_data[0].options & MIPS_CPU_LLSC) +#define cpu_has_vtag_icache (cpu_data[0].icache.flags & MIPS_CACHE_VTAG) +#define cpu_has_dc_aliases (cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES) +#define cpu_has_ic_fills_f_dc (cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC) +#define cpu_has_64bits 1 +#define cpu_has_subset_pcaches (cpu_data[0].options & MIPS_CPU_SUBSET_CACHES) + +extern struct cpuinfo_mips cpu_data[]; +#define current_cpu_data cpu_data[smp_processor_id()] + +extern void cpu_probe(void); +extern void cpu_report(void); /* * System setup and hardware flags.. - * XXX: Should go into mips_cpuinfo. */ -extern char wait_available; /* only available on R4[26]00 */ -extern char cyclecounter_available; /* only available from R4000 upwards. */ -extern char dedicated_iv_available; /* some embedded MIPS like Nevada */ -extern char vce_available; /* Supports VCED / VCEI exceptions */ -extern char mips4_available; /* CPU has MIPS IV ISA or better */ +extern void (*cpu_wait)(void); extern unsigned int vced_count, vcei_count; -extern struct cpuinfo_mips cpu_data[]; - -#ifdef CONFIG_SMP -#define current_cpu_data cpu_data[smp_processor_id()] -#else -#define current_cpu_data cpu_data[0] -#endif /* * Bus types (default is ISA, but people can check others with these..) - * MCA_bus hardcoded to 0 for now. - * - * This needs to be extended since MIPS systems are being delivered with - * numerous different types of bus systems. */ +#ifdef CONFIG_EISA extern int EISA_bus; -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - -/* - * MIPS has no problems with write protection - */ -#define wp_works_ok 1 -#define wp_works_ok__is_a_macro /* for versions in ksyms.c */ - -/* Lazy FPU handling on uni-processor */ -extern struct task_struct *last_task_used_math; - -#ifndef CONFIG_SMP -#define IS_FPU_OWNER() (last_task_used_math == current) -#define CLEAR_FPU_OWNER() last_task_used_math = NULL; #else -#define IS_FPU_OWNER() (current->flags & PF_USEDFPU) -#define CLEAR_FPU_OWNER() current->flags &= ~PF_USEDFPU; +#define EISA_bus (0) #endif +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + /* * User space process size: 1TB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. TASK_SIZE * is limited to 1TB by the R4000 architecture; R10000 and better can * support 16TB. */ -#define TASK_SIZE32 0x80000000UL +#define TASK_SIZE32 0x7fff8000UL #define TASK_SIZE 0x10000000000UL /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE ((current->thread.mflags & MF_32BIT) ? \ - (TASK_SIZE32 / 3) : (TASK_SIZE / 3)) +#define TASK_UNMAPPED_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? \ + PAGE_ALIGN(TASK_SIZE32 / 3) : PAGE_ALIGN(TASK_SIZE / 3)) /* * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. @@ -148,12 +174,18 @@ }; /* - * FIXME: no fpu emulator yet (but who cares anyway?) + * It would be nice to add some more fields for emulator statistics, but there + * are a number of fixed offsets in offset.h and elsewhere that would have to + * be recalculated by hand. So the additional information will be private to + * the FPU emulator for now. See asm-mips/fpu_emulator.h. */ +typedef u64 fpureg_t; struct mips_fpu_soft_struct { - long dummy; + fpureg_t regs[NUM_FPU_REGS]; + unsigned int sr; }; + union mips_fpu_union { struct mips_fpu_hard_struct hard; struct mips_fpu_soft_struct soft; @@ -187,16 +219,21 @@ unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ unsigned long error_code; unsigned long trap_no; -#define MF_FIXADE 1 /* Fix address errors in software */ -#define MF_LOGADE 2 /* Log address errors to syslog */ -#define MF_32BIT 4 /* Process is in 32-bit compat mode */ +#define MF_FIXADE 1 /* Fix address errors in software */ +#define MF_LOGADE 2 /* Log address errors to syslog */ +#define MF_32BIT_REGS 4 /* also implies 16/32 fprs */ +#define MF_32BIT_ADDR 8 /* 32-bit address space (o32/n32) */ unsigned long mflags; - mm_segment_t current_ds; unsigned long irix_trampoline; /* Wheee... */ unsigned long irix_oldctx; }; -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR) +#define MF_O32 (MF_32BIT_REGS | MF_32BIT_ADDR) +#define MF_N32 MF_32BIT_ADDR +#define MF_N64 0 + +#endif /* !__ASSEMBLY__ */ #define INIT_THREAD { \ /* \ @@ -219,14 +256,14 @@ /* \ * For now the default is to fix address errors \ */ \ - MF_FIXADE, { 0 }, 0, 0 \ + MF_FIXADE, 0, 0 \ } #ifdef __KERNEL__ #define KERNEL_STACK_SIZE 0x4000 -#if !defined (_LANGUAGE_ASSEMBLY) +#ifndef __ASSEMBLY__ /* Free all resources held by a thread. */ #define release_thread(thread) do { } while(0) @@ -236,62 +273,27 @@ extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -/* - * Return saved PC of a blocked thread. - */ -extern inline unsigned long thread_saved_pc(struct thread_struct *t) -{ - extern void ret_from_sys_call(void); - - /* New born processes are a special case */ - if (t->reg31 == (unsigned long) ret_from_sys_call) - return t->reg31; - - return ((unsigned long*)t->reg29)[11]; -} +extern unsigned long thread_saved_pc(struct thread_struct *t); #define user_mode(regs) (((regs)->cp0_status & ST0_KSU) == KSU_USER) /* * Do necessary setup to start up a newly executed thread. */ -#define start_thread(regs, pc, sp) \ -do { \ - unsigned long __status; \ - \ - /* New thread loses kernel privileges. */ \ - __status = regs->cp0_status & ~(ST0_CU0|ST0_FR|ST0_KSU); \ - __status |= KSU_USER; \ - __status |= (current->thread.mflags & MF_32BIT) ? 0 : ST0_FR; \ - regs->cp0_status = __status; \ - regs->cp0_epc = pc; \ - regs->regs[29] = sp; \ - current->thread.current_ds = USER_DS; \ -} while(0) +extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); +struct task_struct; unsigned long get_wchan(struct task_struct *p); #define __PT_REG(reg) ((long)&((struct pt_regs *)0)->reg - sizeof(struct pt_regs)) -#define __KSTK_TOS(tsk) ((unsigned long)(tsk) + KERNEL_STACK_SIZE - 32) +#define __KSTK_TOS(tsk) ((unsigned long)(tsk->thread_info) + KERNEL_STACK_SIZE - 32) #define KSTK_EIP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_epc))) #define KSTK_ESP(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(regs[29]))) - -/* Allocation and freeing of basic task resources. */ -/* - * NOTE! The task struct and the stack go together - */ -#define THREAD_SIZE (2*PAGE_SIZE) -#define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL, 2)) -#define free_task_struct(p) free_pages((unsigned long)(p), 2) -#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - -#define init_task (init_task_union.task) -#define init_stack (init_task_union.stack) +#define KSTK_STATUS(tsk) (*(unsigned long *)(__KSTK_TOS(tsk) + __PT_REG(cp0_status))) #define cpu_relax() barrier() -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ /* diff -Nru a/include/asm-mips64/ptrace.h b/include/asm-mips64/ptrace.h --- a/include/asm-mips64/ptrace.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips64/ptrace.h Fri Jun 27 14:20:04 2003 @@ -9,8 +9,6 @@ #ifndef _ASM_PTRACE_H #define _ASM_PTRACE_H -#include <linux/types.h> - /* 0 - 31 are integer registers, 32 - 63 are fp registers. */ #define FPR_BASE 32 #define PC 64 @@ -21,7 +19,7 @@ #define FPC_CSR 69 #define FPC_EIR 70 -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ #define abi64_no_regargs \ unsigned long __dummy0, \ @@ -54,7 +52,7 @@ unsigned long cp0_cause; }; -#endif /* !(_LANGUAGE_ASSEMBLY__) */ +#endif /* !__ASSEMBLY__ */ /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ /* #define PTRACE_GETREGS 12 */ @@ -66,19 +64,20 @@ #define PTRACE_OLDSETOPTIONS 21 -#ifdef _LANGUAGE_ASSEMBLY +#define PTRACE_GET_THREAD_AREA 25 +#define PTRACE_SET_THREAD_AREA 26 + +#ifdef __ASSEMBLY__ #include <asm/offset.h> -#endif /* (_LANGUAGE_ASSEMBLY__) */ +#endif /* !__ASSEMBLY__ */ #ifdef __KERNEL__ -#ifndef _LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ #define instruction_pointer(regs) ((regs)->cp0_epc) -extern void (*_show_regs)(struct pt_regs *); -#define show_regs(regs) _show_regs(regs) - -#endif /* !(_LANGUAGE_ASSEMBLY__) */ +extern void show_regs(struct pt_regs *); +#endif /* !__ASSEMBLY__ */ #endif diff -Nru a/include/asm-mips64/r10kcache.h b/include/asm-mips64/r10kcache.h --- a/include/asm-mips64/r10kcache.h Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,414 +0,0 @@ -/* - * 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. - * - * Inline assembly cache operations. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - * - * FIXME: Handle split L2 caches. - */ -#ifndef _ASM_R10KCACHE_H -#define _ASM_R10KCACHE_H - -#include <asm/asm.h> -#include <asm/r10kcacheops.h> - -/* These are fixed for the current R10000. */ -#define icache_size 0x8000 -#define dcache_size 0x8000 -#define icache_way_size 0x4000 -#define dcache_way_size 0x4000 -#define ic_lsize 64 -#define dc_lsize 32 - -/* These are configuration dependent. */ -#define scache_size() ({ \ - unsigned long __res; \ - __res = (read_32bit_cp0_register(CP0_CONFIG) >> 16) & 3; \ - __res = 1 << (__res + 19); \ - __res; \ -}) - -#define sc_lsize() ({ \ - unsigned long __res; \ - __res = (read_32bit_cp0_register(CP0_CONFIG) >> 13) & 1; \ - __res = 1 << (__res + 6); \ - __res; \ -}) - -extern inline void flush_icache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Index_Invalidate_I)); -} - -extern inline void flush_dcache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Index_Writeback_Inv_D)); -} - -extern inline void flush_scache_line_indexed(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Index_Writeback_Inv_S)); -} - -extern inline void flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Invalidate_I)); -} - -extern inline void flush_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Writeback_Inv_D)); -} - -extern inline void invalidate_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Invalidate_D)); -} - -extern inline void invalidate_scache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Invalidate_S)); -} - -extern inline void flush_scache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Writeback_Inv_S)); -} - -/* - * The next two are for badland addresses like signal trampolines. - */ -extern inline void protected_flush_icache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "1:\tcache %1,(%0)\n" - "2:\t.set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - ".dword\t1b,2b\n\t" - ".previous" - : - : "r" (addr), "i" (Hit_Invalidate_I)); -} - -extern inline void protected_writeback_dcache_line(unsigned long addr) -{ - __asm__ __volatile__( - ".set noreorder\n\t" - "1:\tcache %1,(%0)\n" - "2:\t.set reorder\n\t" - ".section\t__ex_table,\"a\"\n\t" - ".dword\t1b,2b\n\t" - ".previous" - : - : "r" (addr), "i" (Hit_Writeback_Inv_D)); -} - -#define cache32_unroll16(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - cache %1, 0x000(%0); cache %1, 0x020(%0); \ - cache %1, 0x040(%0); cache %1, 0x060(%0); \ - cache %1, 0x080(%0); cache %1, 0x0a0(%0); \ - cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \ - cache %1, 0x100(%0); cache %1, 0x120(%0); \ - cache %1, 0x140(%0); cache %1, 0x160(%0); \ - cache %1, 0x180(%0); cache %1, 0x1a0(%0); \ - cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -#define cache32_unroll32(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - cache %1, 0x000(%0); cache %1, 0x020(%0); \ - cache %1, 0x040(%0); cache %1, 0x060(%0); \ - cache %1, 0x080(%0); cache %1, 0x0a0(%0); \ - cache %1, 0x0c0(%0); cache %1, 0x0e0(%0); \ - cache %1, 0x100(%0); cache %1, 0x120(%0); \ - cache %1, 0x140(%0); cache %1, 0x160(%0); \ - cache %1, 0x180(%0); cache %1, 0x1a0(%0); \ - cache %1, 0x1c0(%0); cache %1, 0x1e0(%0); \ - cache %1, 0x200(%0); cache %1, 0x220(%0); \ - cache %1, 0x240(%0); cache %1, 0x260(%0); \ - cache %1, 0x280(%0); cache %1, 0x2a0(%0); \ - cache %1, 0x2c0(%0); cache %1, 0x2e0(%0); \ - cache %1, 0x300(%0); cache %1, 0x320(%0); \ - cache %1, 0x340(%0); cache %1, 0x360(%0); \ - cache %1, 0x380(%0); cache %1, 0x3a0(%0); \ - cache %1, 0x3c0(%0); cache %1, 0x3e0(%0); \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -extern inline void blast_dcache32(void) -{ - unsigned long way0 = KSEG0; - unsigned long way1 = way0 ^ 1; - unsigned long end = (way0 + dcache_way_size); - - while (way0 < end) { - cache32_unroll16(way0, Index_Writeback_Inv_D); - cache32_unroll16(way1, Index_Writeback_Inv_D); - way0 += 0x200; - way1 += 0x200; - } -} - -extern inline void blast_dcache32_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while (start < end) { - cache32_unroll32(start, Hit_Writeback_Inv_D); - start += 0x400; - } -} - -extern inline void blast_dcache32_page_indexed(unsigned long page) -{ - unsigned long way0 = page; - unsigned long way1 = page ^ 1; - unsigned long end = page + PAGE_SIZE; - - while (way0 < end) { - cache32_unroll16(way0, Index_Writeback_Inv_D); - cache32_unroll16(way1, Index_Writeback_Inv_D); - way0 += 0x200; - way1 += 0x200; - } -} - -#define cache64_unroll16(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - cache %1, 0x000(%0); cache %1, 0x040(%0); \ - cache %1, 0x080(%0); cache %1, 0x0c0(%0); \ - cache %1, 0x100(%0); cache %1, 0x140(%0); \ - cache %1, 0x180(%0); cache %1, 0x1c0(%0); \ - cache %1, 0x200(%0); cache %1, 0x240(%0); \ - cache %1, 0x280(%0); cache %1, 0x2c0(%0); \ - cache %1, 0x300(%0); cache %1, 0x340(%0); \ - cache %1, 0x380(%0); cache %1, 0x3c0(%0); \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -#define cache64_unroll32(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - cache %1, 0x000(%0); cache %1, 0x040(%0); \ - cache %1, 0x080(%0); cache %1, 0x0c0(%0); \ - cache %1, 0x100(%0); cache %1, 0x140(%0); \ - cache %1, 0x180(%0); cache %1, 0x1c0(%0); \ - cache %1, 0x200(%0); cache %1, 0x240(%0); \ - cache %1, 0x280(%0); cache %1, 0x2c0(%0); \ - cache %1, 0x300(%0); cache %1, 0x340(%0); \ - cache %1, 0x380(%0); cache %1, 0x3c0(%0); \ - cache %1, 0x400(%0); cache %1, 0x440(%0); \ - cache %1, 0x480(%0); cache %1, 0x4c0(%0); \ - cache %1, 0x500(%0); cache %1, 0x540(%0); \ - cache %1, 0x580(%0); cache %1, 0x5c0(%0); \ - cache %1, 0x600(%0); cache %1, 0x640(%0); \ - cache %1, 0x680(%0); cache %1, 0x6c0(%0); \ - cache %1, 0x700(%0); cache %1, 0x740(%0); \ - cache %1, 0x780(%0); cache %1, 0x7c0(%0); \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -extern inline void blast_icache64(void) -{ - unsigned long way0 = KSEG0; - unsigned long way1 = way0 ^ 1; - unsigned long end = way0 + icache_way_size; - - while (way0 < end) { - cache64_unroll16(way0,Index_Invalidate_I); - cache64_unroll16(way1,Index_Invalidate_I); - way0 += 0x400; - way1 += 0x400; - } -} - -extern inline void blast_icache64_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while (start < end) { - cache64_unroll32(start,Hit_Invalidate_I); - start += 0x800; - } -} - -extern inline void blast_icache64_page_indexed(unsigned long page) -{ - unsigned long way0 = page; - unsigned long way1 = page ^ 1; - unsigned long end = page + PAGE_SIZE; - - while (way0 < end) { - cache64_unroll16(way0,Index_Invalidate_I); - cache64_unroll16(way1,Index_Invalidate_I); - way0 += 0x400; - way1 += 0x400; - } -} - -extern inline void blast_scache64(void) -{ - unsigned long way0 = KSEG0; - unsigned long way1 = way0 ^ 1; - unsigned long end = KSEG0 + scache_size(); - - while (way0 < end) { - cache64_unroll16(way0,Index_Writeback_Inv_S); - cache64_unroll16(way1,Index_Writeback_Inv_S); - way0 += 0x400; - way1 += 0x400; - } -} - -extern inline void blast_scache64_page(unsigned long page) -{ - unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while (start < end) { - cache64_unroll32(start,Hit_Writeback_Inv_S); - start += 0x800; - } -} - -extern inline void blast_scache64_page_indexed(unsigned long page) -{ - unsigned long way0 = page; - unsigned long way1 = page ^ 1; - unsigned long end = page + PAGE_SIZE; - - while (way0 < end) { - cache64_unroll16(way0,Index_Writeback_Inv_S); - cache64_unroll16(way1,Index_Writeback_Inv_S); - way0 += 0x400; - way1 += 0x400; - } -} - -#define cache128_unroll16(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - cache %1, 0x000(%0); cache %1, 0x080(%0); \ - cache %1, 0x100(%0); cache %1, 0x180(%0); \ - cache %1, 0x200(%0); cache %1, 0x280(%0); \ - cache %1, 0x300(%0); cache %1, 0x380(%0); \ - cache %1, 0x400(%0); cache %1, 0x480(%0); \ - cache %1, 0x500(%0); cache %1, 0x580(%0); \ - cache %1, 0x600(%0); cache %1, 0x680(%0); \ - cache %1, 0x700(%0); cache %1, 0x780(%0); \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -#define cache128_unroll32(base,op) \ - __asm__ __volatile__(" \ - .set noreorder; \ - cache %1, 0x000(%0); cache %1, 0x080(%0); \ - cache %1, 0x100(%0); cache %1, 0x180(%0); \ - cache %1, 0x200(%0); cache %1, 0x280(%0); \ - cache %1, 0x300(%0); cache %1, 0x380(%0); \ - cache %1, 0x400(%0); cache %1, 0x480(%0); \ - cache %1, 0x500(%0); cache %1, 0x580(%0); \ - cache %1, 0x600(%0); cache %1, 0x680(%0); \ - cache %1, 0x700(%0); cache %1, 0x780(%0); \ - cache %1, 0x800(%0); cache %1, 0x880(%0); \ - cache %1, 0x900(%0); cache %1, 0x980(%0); \ - cache %1, 0xa00(%0); cache %1, 0xa80(%0); \ - cache %1, 0xb00(%0); cache %1, 0xb80(%0); \ - cache %1, 0xc00(%0); cache %1, 0xc80(%0); \ - cache %1, 0xd00(%0); cache %1, 0xd80(%0); \ - cache %1, 0xe00(%0); cache %1, 0xe80(%0); \ - cache %1, 0xf00(%0); cache %1, 0xf80(%0); \ - .set reorder" \ - : \ - : "r" (base), \ - "i" (op)); - -extern inline void blast_scache128(void) -{ - unsigned long way0 = KSEG0; - unsigned long way1 = way0 ^ 1; - unsigned long end = way0 + scache_size(); - - while (way0 < end) { - cache128_unroll16(way0, Index_Writeback_Inv_S); - cache128_unroll16(way1, Index_Writeback_Inv_S); - way0 += 0x800; - way1 += 0x800; - } -} - -extern inline void blast_scache128_page(unsigned long page) -{ - cache128_unroll32(page, Hit_Writeback_Inv_S); -} - -extern inline void blast_scache128_page_indexed(unsigned long page) -{ - cache128_unroll32(page , Index_Writeback_Inv_S); - cache128_unroll32(page ^ 1, Index_Writeback_Inv_S); -} - -#endif /* _ASM_R10KCACHE_H */ diff -Nru a/include/asm-mips64/r10kcacheops.h b/include/asm-mips64/r10kcacheops.h --- a/include/asm-mips64/r10kcacheops.h Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,47 +0,0 @@ -/* - * 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. - * - * Cache operations for the cache instruction. - * - * (C) Copyright 1996, 1997, 1999 by Ralf Baechle - * (C) Copyright 1999 Silicon Graphics, Inc. - */ -#ifndef _ASM_R10KCACHEOPS_H -#define _ASM_R10KCACHEOPS_H - -/* - * Cache Operations - */ -#define Index_Invalidate_I 0x00 -#define Index_Writeback_Inv_D 0x01 - /* 0x02 is unused */ -#define Index_Writeback_Inv_S 0x03 -#define Index_Load_Tag_I 0x04 -#define Index_Load_Tag_D 0x05 - /* 0x06 is unused */ -#define Index_Load_Tag_S 0x07 -#define Index_Store_Tag_I 0x08 -#define Index_Store_Tag_D 0x09 - /* 0x0a is unused */ -#define Index_Store_Tag_S 0x0b - /* 0x0c - 0x0e are unused */ -#define Hit_Invalidate_I 0x10 -#define Hit_Invalidate_D 0x11 - /* 0x12 is unused */ -#define Hit_Invalidate_S 0x13 -#define Cache_Barrier 0x14 -#define Hit_Writeback_Inv_D 0x15 - /* 0x16 is unused */ -#define Hit_Writeback_Inv_S 0x17 -#define Index_Load_Data_I 0x18 -#define Index_Load_Data_D 0x19 - /* 0x1a is unused */ -#define Index_Load_Data_S 0x1b -#define Index_Store_Data_I 0x1c -#define Index_Store_Data_D 0x1d - /* 0x1e is unused */ -#define Index_Store_Data_S 0x1f - -#endif /* _ASM_R10KCACHEOPS_H */ diff -Nru a/include/asm-mips64/r4kcache.h b/include/asm-mips64/r4kcache.h --- a/include/asm-mips64/r4kcache.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/r4kcache.h Fri Jun 27 14:19:59 2003 @@ -6,127 +6,115 @@ * Inline assembly cache operations. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * FIXME: Handle split L2 caches. + * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org) */ -#ifndef _ASM_R4KCACHE_H -#define _ASM_R4KCACHE_H +#ifndef __ASM_R4KCACHE_H +#define __ASM_R4KCACHE_H #include <asm/asm.h> -#include <asm/r4kcacheops.h> +#include <asm/cacheops.h> -extern inline void flush_icache_line_indexed(unsigned long addr) +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set mips0 \n" \ + " .set reorder" \ + : \ + : "i" (op), "m" (*(unsigned char *)(addr))) + +static inline void flush_icache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Index_Invalidate_I)); + cache_op(Index_Invalidate_I, addr); } -extern inline void flush_dcache_line_indexed(unsigned long addr) +static inline void flush_dcache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Index_Writeback_Inv_D)); + cache_op(Index_Writeback_Inv_D, addr); } -extern inline void flush_scache_line_indexed(unsigned long addr) +static inline void flush_scache_line_indexed(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Index_Writeback_Inv_SD)); + cache_op(Index_Writeback_Inv_SD, addr); } -extern inline void flush_icache_line(unsigned long addr) +static inline void flush_icache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Invalidate_I)); + cache_op(Hit_Invalidate_I, addr); } -extern inline void flush_dcache_line(unsigned long addr) +static inline void flush_dcache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Writeback_Inv_D)); + cache_op(Hit_Writeback_Inv_D, addr); } -extern inline void invalidate_dcache_line(unsigned long addr) +static inline void invalidate_dcache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Invalidate_D)); + cache_op(Hit_Invalidate_D, addr); } -extern inline void invalidate_scache_line(unsigned long addr) +static inline void invalidate_scache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Invalidate_SD)); + cache_op(Hit_Invalidate_SD, addr); } -extern inline void flush_scache_line(unsigned long addr) +static inline void flush_scache_line(unsigned long addr) { - __asm__ __volatile__( - ".set noreorder\n\t" - "cache %1, (%0)\n\t" - ".set reorder" - : - : "r" (addr), "i" (Hit_Writeback_Inv_SD)); + cache_op(Hit_Writeback_Inv_SD, addr); } /* * The next two are for badland addresses like signal trampolines. */ -extern inline void protected_flush_icache_line(unsigned long addr) +static inline void protected_flush_icache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" - "1:\tcache %1,(%0)\n" - "2:\t.set reorder\n\t" + ".set mips3\n" + "1:\tcache %0,(%1)\n" + "2:\t.set mips0\n\t" + ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" - ".dword\t1b,2b\n\t" + STR(PTR)"\t1b,2b\n\t" ".previous" : - : "r" (addr), "i" (Hit_Invalidate_I)); + : "i" (Hit_Invalidate_I), "r" (addr)); } -extern inline void protected_writeback_dcache_line(unsigned long addr) +/* + * R10000 / R12000 hazard - these processors don't support the Hit_Writeback_D + * cacheop so we use Hit_Writeback_Inv_D which is supported by all R4000-style + * caches. We're talking about one cacheline unnecessarily getting invalidated + * here so the penaltiy isn't overly hard. + */ +static inline void protected_writeback_dcache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" - "1:\tcache %1,(%0)\n" - "2:\t.set reorder\n\t" + ".set mips3\n" + "1:\tcache %0,(%1)\n" + "2:\t.set mips0\n\t" + ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" - ".dword\t1b,2b\n\t" + STR(PTR)"\t1b,2b\n\t" ".previous" : - : "r" (addr), "i" (Hit_Writeback_D)); + : "i" (Hit_Writeback_Inv_D), "r" (addr)); +} + +/* + * This one is RM7000-specific + */ +static inline void invalidate_tcache_page(unsigned long addr) +{ + cache_op(Page_Invalidate_T, addr); } #define cache16_unroll32(base,op) \ __asm__ __volatile__(" \ .set noreorder; \ + .set mips3; \ cache %1, 0x000(%0); cache %1, 0x010(%0); \ cache %1, 0x020(%0); cache %1, 0x030(%0); \ cache %1, 0x040(%0); cache %1, 0x050(%0); \ @@ -143,113 +131,133 @@ cache %1, 0x1a0(%0); cache %1, 0x1b0(%0); \ cache %1, 0x1c0(%0); cache %1, 0x1d0(%0); \ cache %1, 0x1e0(%0); cache %1, 0x1f0(%0); \ + .set mips0; \ .set reorder" \ : \ : "r" (base), \ "i" (op)); -extern inline void blast_dcache16(void) +static inline void blast_dcache16(void) { unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); + unsigned long end = start + dcache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_D); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_dcache16_page(unsigned long page) +static inline void blast_dcache16_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Writeback_Inv_D); start += 0x200; } } -extern inline void blast_dcache16_page_indexed(unsigned long page) +static inline void blast_dcache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_D); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_icache16(void) +static inline void blast_icache16(void) { unsigned long start = KSEG0; - unsigned long end = (start + icache_size); + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_icache16_page(unsigned long page) +static inline void blast_icache16_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Invalidate_I); start += 0x200; } } -extern inline void blast_icache16_page_indexed(unsigned long page) +static inline void blast_icache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache16_unroll32(start,Index_Invalidate_I); - start += 0x200; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache16(void) +static inline void blast_scache16(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_SD); - start += 0x200; - } + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache16_page(unsigned long page) +static inline void blast_scache16_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache16_unroll32(start,Hit_Writeback_Inv_SD); start += 0x200; } } -extern inline void blast_scache16_page_indexed(unsigned long page) +static inline void blast_scache16_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache16_unroll32(start,Index_Writeback_Inv_SD); - start += 0x200; - } + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x200) + cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache32_unroll32(base,op) \ __asm__ __volatile__(" \ .set noreorder; \ + .set mips3; \ cache %1, 0x000(%0); cache %1, 0x020(%0); \ cache %1, 0x040(%0); cache %1, 0x060(%0); \ cache %1, 0x080(%0); cache %1, 0x0a0(%0); \ @@ -266,131 +274,133 @@ cache %1, 0x340(%0); cache %1, 0x360(%0); \ cache %1, 0x380(%0); cache %1, 0x3a0(%0); \ cache %1, 0x3c0(%0); cache %1, 0x3e0(%0); \ + .set mips0; \ .set reorder" \ : \ : "r" (base), \ "i" (op)); -extern inline void blast_dcache32(void) +static inline void blast_dcache32(void) { unsigned long start = KSEG0; - unsigned long end = (start + dcache_size); + unsigned long end = start + dcache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); } -/* - * Call this function only with interrupts disabled or R4600 V2.0 may blow - * up on you. - * - * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, - * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Excl_D will only - * operate correctly if the internal data cache refill buffer is empty. These - * CACHE instructions should be separated from any potential data cache miss - * by a load instruction to an uncached address to empty the response buffer." - * (Revision 2.0 device errata from IDT available on http://www.idt.com/ - * in .pdf format.) - */ -extern inline void blast_dcache32_page(unsigned long page) +static inline void blast_dcache32_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); - - /* - * Sigh ... workaround for R4600 v1.7 bug. Explanation see above. - */ - *(volatile unsigned long *)KSEG1; + unsigned long end = start + PAGE_SIZE; - __asm__ __volatile__("nop;nop;nop;nop"); - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Writeback_Inv_D); start += 0x400; } } -extern inline void blast_dcache32_page_indexed(unsigned long page) +static inline void blast_dcache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; + unsigned long ws_end = current_cpu_data.dcache.ways << + current_cpu_data.dcache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_D); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_D); } -extern inline void blast_icache32(void) +static inline void blast_icache32(void) { unsigned long start = KSEG0; - unsigned long end = (start + icache_size); + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_icache32_page(unsigned long page) +static inline void blast_icache32_page(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Invalidate_I); start += 0x400; } } -extern inline void blast_icache32_page_indexed(unsigned long page) +static inline void blast_icache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = (start + PAGE_SIZE); + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache32_unroll32(start,Index_Invalidate_I); - start += 0x400; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache32(void) +static inline void blast_scache32(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_SD); - start += 0x400; - } + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache32_page(unsigned long page) +static inline void blast_scache32_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { + while (start < end) { cache32_unroll32(start,Hit_Writeback_Inv_SD); start += 0x400; } } -extern inline void blast_scache32_page_indexed(unsigned long page) +static inline void blast_scache32_page_indexed(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; - - while(start < end) { - cache32_unroll32(start,Index_Writeback_Inv_SD); - start += 0x400; - } + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x400) + cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); } #define cache64_unroll32(base,op) \ __asm__ __volatile__(" \ .set noreorder; \ + .set mips3; \ cache %1, 0x000(%0); cache %1, 0x040(%0); \ cache %1, 0x080(%0); cache %1, 0x0c0(%0); \ cache %1, 0x100(%0); cache %1, 0x140(%0); \ @@ -407,47 +417,94 @@ cache %1, 0x680(%0); cache %1, 0x6c0(%0); \ cache %1, 0x700(%0); cache %1, 0x740(%0); \ cache %1, 0x780(%0); cache %1, 0x7c0(%0); \ + .set mips0; \ .set reorder" \ : \ : "r" (base), \ "i" (op)); -extern inline void blast_scache64(void) +static inline void blast_icache64(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; + unsigned long end = start + icache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; - while(start < end) { - cache64_unroll32(start,Index_Writeback_Inv_SD); - start += 0x800; - } + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Invalidate_I); } -extern inline void blast_scache64_page(unsigned long page) +static inline void blast_icache64_page(unsigned long page) { unsigned long start = page; - unsigned long end = page + PAGE_SIZE; + unsigned long end = start + PAGE_SIZE; - while(start < end) { - cache64_unroll32(start,Hit_Writeback_Inv_SD); + while (start < end) { + cache64_unroll32(start,Hit_Invalidate_I); start += 0x800; } } -extern inline void blast_scache64_page_indexed(unsigned long page) +static inline void blast_icache64_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; + unsigned long ws_end = current_cpu_data.icache.ways << + current_cpu_data.icache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Invalidate_I); +} + +static inline void blast_scache64(void) +{ + unsigned long start = KSEG0; + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); +} + +static inline void blast_scache64_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; - while(start < end) { - cache64_unroll32(start,Index_Writeback_Inv_SD); + while (start < end) { + cache64_unroll32(start,Hit_Writeback_Inv_SD); start += 0x800; } } +static inline void blast_scache64_page_indexed(unsigned long page) +{ + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x800) + cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); +} + #define cache128_unroll32(base,op) \ __asm__ __volatile__(" \ .set noreorder; \ + .set mips3; \ cache %1, 0x000(%0); cache %1, 0x080(%0); \ cache %1, 0x100(%0); cache %1, 0x180(%0); \ cache %1, 0x200(%0); cache %1, 0x280(%0); \ @@ -464,30 +521,49 @@ cache %1, 0xd00(%0); cache %1, 0xd80(%0); \ cache %1, 0xe00(%0); cache %1, 0xe80(%0); \ cache %1, 0xf00(%0); cache %1, 0xf80(%0); \ + .set mips0; \ .set reorder" \ : \ : "r" (base), \ "i" (op)); -extern inline void blast_scache128(void) +static inline void blast_scache128(void) { unsigned long start = KSEG0; - unsigned long end = KSEG0 + scache_size; - - while(start < end) { - cache128_unroll32(start,Index_Writeback_Inv_SD); - start += 0x1000; - } + unsigned long end = start + scache_way_size; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x1000) + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } -extern inline void blast_scache128_page(unsigned long page) +static inline void blast_scache128_page(unsigned long page) { - cache128_unroll32(page,Hit_Writeback_Inv_SD); + unsigned long start = page; + unsigned long end = page + PAGE_SIZE; + + while (start < end) { + cache128_unroll32(start,Hit_Writeback_Inv_SD); + start += 0x1000; + } } -extern inline void blast_scache128_page_indexed(unsigned long page) +static inline void blast_scache128_page_indexed(unsigned long page) { - cache128_unroll32(page,Index_Writeback_Inv_SD); + unsigned long start = page; + unsigned long end = start + PAGE_SIZE; + unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; + unsigned long ws_end = current_cpu_data.scache.ways << + current_cpu_data.scache.waybit; + unsigned long ws, addr; + + for (ws = 0; ws < ws_end; ws += ws_inc) + for (addr = start; addr < end; addr += 0x1000) + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } #endif /* __ASM_R4KCACHE_H */ diff -Nru a/include/asm-mips64/r4kcacheops.h b/include/asm-mips64/r4kcacheops.h --- a/include/asm-mips64/r4kcacheops.h Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,47 +0,0 @@ -/* - * 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. - * - * Cache operations for the cache instruction. - * - * (C) Copyright 1996, 1997, 1999 by Ralf Baechle - */ -#ifndef _ASM_R4kCACHEOPS_H -#define _ASM_R4kCACHEOPS_H - -/* - * Cache Operations - */ -#define Index_Invalidate_I 0x00 -#define Index_Writeback_Inv_D 0x01 -#define Index_Invalidate_SI 0x02 -#define Index_Writeback_Inv_SD 0x03 -#define Index_Load_Tag_I 0x04 -#define Index_Load_Tag_D 0x05 -#define Index_Load_Tag_SI 0x06 -#define Index_Load_Tag_SD 0x07 -#define Index_Store_Tag_I 0x08 -#define Index_Store_Tag_D 0x09 -#define Index_Store_Tag_SI 0x0A -#define Index_Store_Tag_SD 0x0B -#define Create_Dirty_Excl_D 0x0d -#define Create_Dirty_Excl_SD 0x0f -#define Hit_Invalidate_I 0x10 -#define Hit_Invalidate_D 0x11 -#define Hit_Invalidate_SI 0x12 -#define Hit_Invalidate_SD 0x13 -#define Fill 0x14 -#define Hit_Writeback_Inv_D 0x15 - /* 0x16 is unused */ -#define Hit_Writeback_Inv_SD 0x17 -#define Hit_Writeback_I 0x18 -#define Hit_Writeback_D 0x19 - /* 0x1a is unused */ -#define Hit_Writeback_SD 0x1b - /* 0x1c is unused */ - /* 0x1e is unused */ -#define Hit_Set_Virtual_SI 0x1e -#define Hit_Set_Virtual_SD 0x1f - -#endif /* _ASM_R4kCACHEOPS_H */ diff -Nru a/include/asm-mips64/reboot.h b/include/asm-mips64/reboot.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/reboot.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,16 @@ +/* + * 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) 1997, 1999, 2001 by Ralf Baechle + * Copyright (C) 2001 MIPS Technologies, Inc. + */ +#ifndef _ASM_REBOOT_H +#define _ASM_REBOOT_H + +extern void (*_machine_restart)(char *command); +extern void (*_machine_halt)(void); +extern void (*_machine_power_off)(void); + +#endif /* _ASM_REBOOT_H */ diff -Nru a/include/asm-mips64/reg.h b/include/asm-mips64/reg.h --- a/include/asm-mips64/reg.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/reg.h Fri Jun 27 14:19:55 2003 @@ -17,51 +17,51 @@ * if the order here is changed, it needs to be updated in * include/asm-mips/stackframe.h */ -#define EF_REG0 8 -#define EF_REG1 9 -#define EF_REG2 10 -#define EF_REG3 11 -#define EF_REG4 12 -#define EF_REG5 13 -#define EF_REG6 14 -#define EF_REG7 15 -#define EF_REG8 16 -#define EF_REG9 17 -#define EF_REG10 18 -#define EF_REG11 19 -#define EF_REG12 20 -#define EF_REG13 21 -#define EF_REG14 22 -#define EF_REG15 23 -#define EF_REG16 24 -#define EF_REG17 25 -#define EF_REG18 26 -#define EF_REG19 27 -#define EF_REG20 28 -#define EF_REG21 29 -#define EF_REG22 30 -#define EF_REG23 31 -#define EF_REG24 32 -#define EF_REG25 33 +#define EF_REG0 0 +#define EF_REG1 1 +#define EF_REG2 2 +#define EF_REG3 3 +#define EF_REG4 4 +#define EF_REG5 5 +#define EF_REG6 6 +#define EF_REG7 7 +#define EF_REG8 8 +#define EF_REG9 9 +#define EF_REG10 10 +#define EF_REG11 11 +#define EF_REG12 12 +#define EF_REG13 13 +#define EF_REG14 14 +#define EF_REG15 15 +#define EF_REG16 16 +#define EF_REG17 17 +#define EF_REG18 18 +#define EF_REG19 19 +#define EF_REG20 20 +#define EF_REG21 21 +#define EF_REG22 22 +#define EF_REG23 23 +#define EF_REG24 24 +#define EF_REG25 25 /* * k0/k1 unsaved */ -#define EF_REG28 36 -#define EF_REG29 37 -#define EF_REG30 38 -#define EF_REG31 39 +#define EF_REG28 28 +#define EF_REG29 29 +#define EF_REG30 30 +#define EF_REG31 31 /* * Saved special registers */ -#define EF_LO 40 -#define EF_HI 41 +#define EF_LO 32 +#define EF_HI 33 -#define EF_CP0_EPC 42 -#define EF_CP0_BADVADDR 43 -#define EF_CP0_STATUS 44 -#define EF_CP0_CAUSE 45 +#define EF_CP0_EPC 34 +#define EF_CP0_BADVADDR 35 +#define EF_CP0_STATUS 36 +#define EF_CP0_CAUSE 37 -#define EF_SIZE 368 /* size in bytes */ +#define EF_SIZE 304 /* size in bytes */ #endif /* _ASM_REG_H */ diff -Nru a/include/asm-mips64/riscos-syscall.h b/include/asm-mips64/riscos-syscall.h --- a/include/asm-mips64/riscos-syscall.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips64/riscos-syscall.h Fri Jun 27 14:20:04 2003 @@ -220,7 +220,7 @@ #define __NR_SVR4_reserved62 (__NR_SVR4 + 199) #define __NR_SVR4_reserved63 (__NR_SVR4 + 200) #define __NR_SVR4_aread (__NR_SVR4 + 201) -#define __NR_SVR4_awrite (__NR_SVR4 + 202) +#define __NR_SVR4_awrite (__NR_SVR4 + 202) #define __NR_SVR4_listio (__NR_SVR4 + 203) #define __NR_SVR4_mips_acancel (__NR_SVR4 + 204) #define __NR_SVR4_astatus (__NR_SVR4 + 205) diff -Nru a/include/asm-mips64/rmap.h b/include/asm-mips64/rmap.h --- a/include/asm-mips64/rmap.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips64/rmap.h Fri Jun 27 14:20:00 2003 @@ -1,7 +1,7 @@ -#ifndef _MIPS64_RMAP_H -#define _MIPS64_RMAP_H +#ifndef __ASM_RMAP_H +#define __ASM_RMAP_H /* nothing to see, move along */ #include <asm-generic/rmap.h> -#endif +#endif /* __ASM_RMAP_H */ diff -Nru a/include/asm-mips64/rrm.h b/include/asm-mips64/rrm.h --- a/include/asm-mips64/rrm.h Fri Jun 27 14:20:01 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,88 +0,0 @@ -/* - * SGI Rendering Resource Manager API (?). - * - * written by Miguel de Icaza (miguel@nuclecu.unam.mx) - * - * Ok, even if SGI choosed to do mmap trough ioctls, their - * kernel support for virtualizing the graphics card is nice. - * - * We should be able to make graphic applications on Linux - * fly. - * - * This header file should be included from GNU libc as well. - */ - - -/* Why like this you say? Well, gdb can print enums */ -#define RRM_BASE 1000 -#define RRM_CMD_LIMIT (RRM_BASE + 100) - -enum { - RRM_OPENRN = RRM_BASE, /* open rendering node */ - RRM_CLOSERN, - RRM_BINDPROCTORN, /* set current rendering region for node */ - RRM_BINDRNTOCLIP, - RRM_UNBINDRNFROMCLIP, - RRM_SWAPBUF, - RRM_SETSWAPINTERVAL, - RRM_WAITFORRETRACE, - RRM_SETDISPLAYMODE, - RRM_MESSAGE, - RRM_INVALIDATERN, - RRM_VALIDATECLIP, - RRM_VALIDATESWAPBUF, - RRM_SWAPGROUP, - RRM_SWAPUNGROUP, - RRM_VALIDATEMESSAGE, - RRM_GETDISPLAYMODES, - RRM_LOADDISPLAYMODE, - RRM_CUSHIONBUFFER, - RRM_SWAPREADY, - RRM_MGR_SWAPBUF, - RRM_SETVSYNC, - RRM_GETVSYNC, - RRM_WAITVSYNC, - RRM_BINDRNTOREADANDCLIP, - RRM_MAPCLIPTOSWPBUFID -}; - -/* Parameters for the above ioctls - * - * All of the ioctls take as their first argument the rendering node id. - * - */ - -/* - * RRM_OPENRN: - * - * This is called by the IRIX X server with: - * rnid = 0xffffffff rmask = 0 - * - * Returns a number like this: 0x10001. - * If you run the X server over and over, you get a value - * that is of the form (n * 0x10000) + 1. - * - * The return value seems to be the RNID. - */ -struct RRM_OpenRN { - int rnid; - unsigned int rmask; -}; - -struct RRM_CloseRN { - int rnid; -}; - -/* - * RRM_BINDPROCTORN: - * - * Return value when the X server calls it: 0 - */ -struct RRM_BindProcToRN { - int rnid; -}; - -#ifdef __KERNEL__ -int rrm_command (unsigned int cmd, void *arg); -int rrm_close (struct inode *inode, struct file *file); -#endif diff -Nru a/include/asm-mips64/rtc.h b/include/asm-mips64/rtc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/rtc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,10 @@ +#ifndef _I386_RTC_H +#define _I386_RTC_H + +/* + * x86 uses the default access methods for the RTC. + */ + +#include <asm-generic/rtc.h> + +#endif diff -Nru a/include/asm-mips64/scatterlist.h b/include/asm-mips64/scatterlist.h --- a/include/asm-mips64/scatterlist.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/scatterlist.h Fri Jun 27 14:19:54 2003 @@ -1,21 +1,13 @@ -#ifndef __ASM_MIPS64_SCATTERLIST_H -#define __ASM_MIPS64_SCATTERLIST_H +#ifndef __ASM_SCATTERLIST_H +#define __ASM_SCATTERLIST_H struct scatterlist { - struct page *page; - unsigned int offset; - unsigned int length; - - __u32 dvma_address; -}; - -struct mmu_sglist { - char *addr; - char *__dont_touch; - unsigned int len; - __u32 dvma_addr; + struct page * page; + unsigned int offset; + dma_addr_t dma_address; + unsigned int length; }; #define ISA_DMA_THRESHOLD (0x00ffffffUL) -#endif /* __ASM_MIPS64_SCATTERLIST_H */ +#endif /* __ASM_SCATTERLIST_H */ diff -Nru a/include/asm-mips64/sections.h b/include/asm-mips64/sections.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sections.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,9 @@ +#ifndef __ASM_SECTIONS_H +#define __ASM_SECTIONS_H + +#include <asm-generic/sections.h> + +extern char _stext, _etext; +extern char _end; + +#endif /* __ASM_SECTIONS_H */ diff -Nru a/include/asm-mips64/semaphore-helper.h b/include/asm-mips64/semaphore-helper.h --- a/include/asm-mips64/semaphore-helper.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/semaphore-helper.h Fri Jun 27 14:19:52 2003 @@ -1,14 +1,21 @@ /* * SMP- and interrupt-safe semaphores helper functions. * - * (C) Copyright 1996 Linus Torvalds - * (C) Copyright 1999 Andrea Arcangeli - * (C) Copyright 1999, 2001 Ralf Baechle - * (C) Copyright 1999, 2001 Silicon Graphics, Inc. + * Copyright (C) 1996 Linus Torvalds + * Copyright (C) 1999 Andrea Arcangeli + * Copyright (C) 1999, 2001, 2002 Ralf Baechle + * Copyright (C) 1999, 2001 Silicon Graphics, Inc. + * Copyright (C) 2000 MIPS Technologies, Inc. */ #ifndef _ASM_SEMAPHORE_HELPER_H #define _ASM_SEMAPHORE_HELPER_H +#include <linux/config.h> +#include <linux/errno.h> + +#define sem_read(a) ((a)->counter) +#define sem_inc(a) (((a)->counter)++) +#define sem_dec(a) (((a)->counter)--) /* * These two _must_ execute atomically wrt each other. */ @@ -17,25 +24,49 @@ atomic_inc(&sem->waking); } -static inline int -waking_non_zero(struct semaphore *sem) +#ifdef CONFIG_CPU_HAS_LLSC + +static inline int waking_non_zero(struct semaphore *sem) { int ret, tmp; __asm__ __volatile__( - "1:\tll\t%1, %2\n\t" + "1:\tll\t%1, %2\t\t\t# waking_non_zero\n\t" "blez\t%1, 2f\n\t" "subu\t%0, %1, 1\n\t" "sc\t%0, %2\n\t" - "beqz\t%0, 1b\n\t" + "beqz\t%0, 1b\n" "2:" - ".text" - : "=r" (ret), "=r" (tmp), "=m" (sem->waking) + : "=r" (ret), "=r" (tmp), "+m" (sem->waking) : "0" (0)); return ret; } +#else /* !CONFIG_CPU_HAS_LLSC */ + +/* + * It doesn't make sense, IMHO, to endlessly turn interrupts off and on again. + * Do it once and that's it. ll/sc *has* it's advantages. HK + */ + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int ret = 0; + + local_irq_save(flags); + if (sem_read(&sem->waking) > 0) { + sem_dec(&sem->waking); + ret = 1; + } + local_irq_restore(flags); + return ret; +} +#endif /* !CONFIG_CPU_HAS_LLSC */ + +#ifdef CONFIG_CPU_HAS_LLDSCD + /* * waking_non_zero_interruptible: * 1 got the lock @@ -43,17 +74,22 @@ * -EINTR interrupted * * We must undo the sem->count down_interruptible decrement - * simultaneously and atomicly with the sem->waking adjustment, + * simultaneously and atomically with the sem->waking adjustment, * otherwise we can race with wake_one_more. * - * This is accomplished by doing a 64-bit ll/sc on the 2 32-bit words. + * This is accomplished by doing a 64-bit lld/scd on the 2 32-bit words. + * + * This is crazy. Normally it's strictly forbidden to use 64-bit operations + * in the 32-bit MIPS kernel. In this case it's however ok because if an + * interrupt has destroyed the upper half of registers sc will fail. + * Note also that this will not work for MIPS32 CPUs! * * Pseudocode: * * If(sem->waking > 0) { * Decrement(sem->waking) * Return(SUCCESS) - * } else If(segnal_pending(tsk)) { + * } else If(signal_pending(tsk)) { * Increment(sem->count) * Return(-EINTR) * } else { @@ -66,70 +102,36 @@ { long ret, tmp; -#ifdef __MIPSEB__ - - __asm__ __volatile__( + __asm__ __volatile__( ".set\tpush\t\t\t# waking_non_zero_interruptible\n\t" - ".set\tnoat\n\t" + ".set\tmips3\n\t" + ".set\tnoat\n" "0:\tlld\t%1, %2\n\t" "li\t%0, 0\n\t" "sll\t$1, %1, 0\n\t" "blez\t$1, 1f\n\t" "daddiu\t%1, %1, -1\n\t" "li\t%0, 1\n\t" - "b\t2f\n\t" + "b\t2f\n" "1:\tbeqz\t%3, 2f\n\t" "li\t%0, %4\n\t" "dli\t$1, 0x0000000100000000\n\t" - "daddu\t%1, %1, $1\n\t" + "daddu\t%1, %1, $1\n" "2:\tscd\t%1, %2\n\t" "beqz\t%1, 0b\n\t" ".set\tpop" : "=&r" (ret), "=&r" (tmp), "=m" (*sem) : "r" (signal_pending(tsk)), "i" (-EINTR)); -#elif defined(__MIPSEL__) - - __asm__ __volatile__( - ".set\tpush\t\t\t# waking_non_zero_interruptible\n\t" - ".set\t noat\n" - "0:\tlld\t%1, %2\n\t" - "li\t%0, 0\n\t" - "blez\t%1, 1f\n\t" - "dli\t$1, 0x0000000100000000\n\t" - "dsubu\t%1, %1, $1\n\t" - "li\t%0, 1\n\t" - "b\t2f\n" - "1:\tbeqz\t%3, 2f\n\t" - "li\t%0, %4\n\t" - /* - * It would be nice to assume that sem->count - * is != -1, but we will guard against that case - */ - "daddiu\t$1, %1, 1\n\t" - "dsll32\t$1, $1, 0\n\t" - "dsrl32\t$1, $1, 0\n\t" - "dsrl32\t%1, %1, 0\n\t" - "dsll32\t%1, %1, 0\n\t" - "or\t%1, %1, $1\n" - "2:\tscd\t%1, %2\n\t" - "beqz\t %1, 0b\n\t" - ".set\tpop" - : "=&r" (ret), "=&r" (tmp), "=m" (*sem) - : "r" (signal_pending(tsk)), "i" (-EINTR)); - -#endif - return ret; } /* - * waking_non_zero_trylock is unused. we do everything in + * waking_non_zero_trylock is unused. we do everything in * down_trylock and let non-ll/sc hosts bounce around. */ -static inline int -waking_non_zero_trylock(struct semaphore *sem) +static inline int waking_non_zero_trylock(struct semaphore *sem) { #if WAITQUEUE_DEBUG CHECK_MAGIC(sem->__magic); @@ -137,5 +139,44 @@ return 0; } + +#else /* !CONFIG_CPU_HAS_LLDSCD */ + +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) +{ + int ret = 0; + unsigned long flags; + + local_irq_save(flags); + if (sem_read(&sem->waking) > 0) { + sem_dec(&sem->waking); + ret = 1; + } else if (signal_pending(tsk)) { + sem_inc(&sem->count); + ret = -EINTR; + } + local_irq_restore(flags); + return ret; +} + +static inline int waking_non_zero_trylock(struct semaphore *sem) +{ + int ret = 1; + unsigned long flags; + + local_irq_save(flags); + if (sem_read(&sem->waking) <= 0) + sem_inc(&sem->count); + else { + sem_dec(&sem->waking); + ret = 0; + } + local_irq_restore(flags); + + return ret; +} + +#endif /* !CONFIG_CPU_HAS_LLDSCD */ #endif /* _ASM_SEMAPHORE_HELPER_H */ diff -Nru a/include/asm-mips64/semaphore.h b/include/asm-mips64/semaphore.h --- a/include/asm-mips64/semaphore.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/semaphore.h Fri Jun 27 14:19:56 2003 @@ -1,14 +1,17 @@ /* + * 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) 1996 Linus Torvalds - * Copyright (C) 1998, 1999, 2000, 2001 Ralf Baechle - * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. + * Copyright (C) 1998, 99, 2000, 01 Ralf Baechle + * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc. + * Copyright (C) 2000, 01 MIPS Technologies, Inc. */ #ifndef _ASM_SEMAPHORE_H #define _ASM_SEMAPHORE_H +#include <linux/config.h> #include <asm/system.h> #include <asm/atomic.h> #include <linux/spinlock.h> @@ -27,7 +30,7 @@ #if WAITQUEUE_DEBUG long __magic; #endif -}; +} __attribute__((aligned(8))); #if WAITQUEUE_DEBUG # define __SEM_DEBUG_INIT(name) \ @@ -89,6 +92,10 @@ __down(sem); } +/* + * Interruptible try to acquire a semaphore. If we obtained + * it, return zero. If we were interrupted, returns -EINTR + */ static inline int down_interruptible(struct semaphore * sem) { int ret = 0; @@ -101,11 +108,27 @@ return ret; } +#ifndef CONFIG_CPU_HAS_LLDSCD + +/* + * Non-blockingly attempt to down() a semaphore. + * Returns zero if we acquired it + */ +static inline int down_trylock(struct semaphore * sem) +{ + int ret = 0; + if (atomic_dec_return(&sem->count) < 0) + ret = __down_trylock(sem); + return ret; +} + +#else + /* * down_trylock returns 0 on success, 1 if we failed to get the lock. * * We must manipulate count and waking simultaneously and atomically. - * Here, we this by using ll/sc on the pair of 32-bit words. + * Here, we do this by using lld/scd on the pair of 32-bit words. * * Pseudocode: * @@ -133,25 +156,27 @@ __asm__ __volatile__( ".set\tmips3\t\t\t# down_trylock\n" "0:\tlld\t%1, %4\n\t" - "\tdli\t%3, 0x0000000100000000\n\t" - "\tdsubu\t%1, %3\n\t" - "\tli\t%0, 0\n\t" - "\tbgez\t%1, 2f\n\t" - "\tsll\t%2, %1, 0\n\t" - "\tblez\t%2, 1f\n\t" - "\tdaddiu\t%1, %1, -1\n\t" - "\tb\t2f\n" + "dli\t%3, 0x0000000100000000\n\t" + "dsubu\t%1, %3\n\t" + "li\t%0, 0\n\t" + "bgez\t%1, 2f\n\t" + "sll\t%2, %1, 0\n\t" + "blez\t%2, 1f\n\t" + "daddiu\t%1, %1, -1\n\t" + "b\t2f\n" "1:\tdaddu\t%1, %1, %3\n\t" - "\tli\t%0, 1\n" + "li\t%0, 1\n" "2:\tscd\t%1, %4\n\t" - "\tbeqz\t%1, 0b\n\t" - "\t.set\tmips0" + "beqz\t%1, 0b\n\t" + ".set\tmips0" : "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub) : "m"(*sem) : "memory"); return ret; } + +#endif /* CONFIG_CPU_HAS_LLDSCD */ /* * Note! This is subtle. We jump to wake people up only if diff -Nru a/include/asm-mips64/sembuf.h b/include/asm-mips64/sembuf.h --- a/include/asm-mips64/sembuf.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips64/sembuf.h Fri Jun 27 14:20:00 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_SEMBUF_H #define _ASM_SEMBUF_H -/* +/* * The semid64_ds structure for the MIPS architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. diff -Nru a/include/asm-mips64/serial.h b/include/asm-mips64/serial.h --- a/include/asm-mips64/serial.h Fri Jun 27 14:20:03 2003 +++ b/include/asm-mips64/serial.h Fri Jun 27 14:20:03 2003 @@ -9,6 +9,8 @@ #ifndef _ASM_SERIAL_H #define _ASM_SERIAL_H +#include <linux/config.h> + /* * This assumes you have a 1.8432 MHz clock for your UART. * @@ -18,6 +20,65 @@ */ #define BASE_BAUD (1843200 / 16) +#ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ + { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ + { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ + { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ + +#else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ +#define STD_SERIAL_PORT_DEFNS +#endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ + +#ifdef CONFIG_MIPS_SEAD +#include <asm/mips-boards/sead.h> +#include <asm/mips-boards/seadint.h> +#define SEAD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ + { 0, SEAD_BASE_BAUD, SEAD_UART0_REGS_BASE, SEADINT_UART0, STD_COM_FLAGS }, /* ttyS0 */ +#else +#define SEAD_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_MOMENCO_OCELOT_C +/* Ordinary NS16552 duart with a 20MHz crystal. */ +#define OCELOT_C_BASE_BAUD ( 20000000 / 16 ) + +#define OCELOT_C_SERIAL1_IRQ 80 +#define OCELOT_C_SERIAL1_BASE 0xfd000020 + +#define OCELOT_C_SERIAL2_IRQ 81 +#define OCELOT_C_SERIAL2_BASE 0xfd000000 + +#define _OCELOT_C_SERIAL_INIT(int, base) \ + { .baud_base = OCELOT_C_BASE_BAUD, \ + .irq = (int), \ + .flags = STD_COM_FLAGS, \ + .iomem_base = (u8 *) base, \ + .iomem_reg_shift = 2, \ + .io_type = SERIAL_IO_MEM \ + } +#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ + _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL1_IRQ, OCELOT_C_SERIAL1_BASE), \ + _OCELOT_C_SERIAL_INIT(OCELOT_C_SERIAL2_IRQ, OCELOT_C_SERIAL2_BASE) +#else +#define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS +#endif + +#ifdef CONFIG_SGI_IP27 + /* * Note about serial ports and consoles: * For console output, everyone uses the IOC3 UARTA (offset 0x178) @@ -35,8 +96,8 @@ * * The first one to do a register_console becomes the preferred console * (if there is no kernel command line console= directive). /dev/console - * (ie 5, 1) is then "aliased" into the device number returned by the - * "device" routine referred to in this console structure + * (ie 5, 1) is then "aliased" into the device number returned by the + * "device" routine referred to in this console structure * (ip27prom_console_dev). * * Also look in ip27-pci.c:pci_fixuop_ioc3() for some comments on working @@ -44,10 +105,57 @@ * * The IOC3 serials use a 22MHz clock rate with an additional divider by 3. * (IOC3_BAUD = (22000000 / (3*16))) + * + * At the moment this is only a skeleton definition as we register all serials + * at runtime. */ -#define RS_TABLE_SIZE 64 +#define IP27_SERIAL_PORT_DEFNS +#else +#define IP27_SERIAL_PORT_DEFNS +#endif /* CONFIG_SGI_IP27 */ + +#ifdef CONFIG_SGI_IP32 -#define SERIAL_PORT_DFNS +#include <asm/ip32/ip32_ints.h> + +/* + * The IP32 (SGI O2) has standard serial ports (UART 16550A) mapped in memory + */ + +/* Standard COM flags (except for COM4, because of the 8514 problem) */ +#ifdef CONFIG_SERIAL_DETECT_IRQ +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ) +#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ) +#else +#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF/* | ASYNC_SKIP_TEST*/) +#define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF +#endif + +#define IP32_SERIAL_PORT_DEFNS \ + { .baud_base = BASE_BAUD, \ + .irq = MACEISA_SERIAL1_IRQ, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = (u8*)MACE_BASE+MACEISA_SER1_BASE, \ + .iomem_reg_shift = 8, \ + .io_type = SERIAL_IO_MEM}, \ + { .baud_base = BASE_BAUD, \ + .irq = MACEISA_SERIAL2_IRQ, \ + .flags = STD_COM_FLAGS, \ + .iomem_base = (u8*)MACE_BASE+MACEISA_SER2_BASE, \ + .iomem_reg_shift = 8, \ + .io_type = SERIAL_IO_MEM}, +#else +#define IP32_SERIAL_PORT_DEFNS +#endif /* CONFIG_SGI_IP31 */ + +#define SERIAL_PORT_DFNS \ + IP27_SERIAL_PORT_DEFNS \ + IP32_SERIAL_PORT_DEFNS \ + MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS \ + SEAD_SERIAL_PORT_DEFNS \ + STD_SERIAL_PORT_DEFNS + +#define RS_TABLE_SIZE 64 #endif /* _ASM_SERIAL_H */ diff -Nru a/include/asm-mips64/sgi/gio.h b/include/asm-mips64/sgi/gio.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sgi/gio.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,86 @@ +/* + * 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. + * + * gio.h: Definitions for SGI GIO bus + * + * Copyright (C) 2002 Ladislav Michl + */ + +#ifndef _SGI_GIO_H +#define _SGI_GIO_H + +/* + * GIO bus addresses + * + * The Indigo and Indy have two GIO bus connectors. Indigo2 (all models) have + * three physical connectors, but only two slots, GFX and EXP0. + * + * There is 10MB of GIO address space for GIO64 slot devices + * slot# slot type address range size + * ----- --------- ----------------------- ----- + * 0 GFX 0x1f000000 - 0x1f3fffff 4MB + * 1 EXP0 0x1f400000 - 0x1f5fffff 2MB + * 2 EXP1 0x1f600000 - 0x1f9fffff 4MB + * + * There are un-slotted devices, HPC, I/O and misc devices, which are grouped + * into the HPC address space. + * - MISC 0x1fb00000 - 0x1fbfffff 1MB + * + * Following space is reserved and unused + * - RESERVED 0x18000000 - 0x1effffff 112MB + * + * GIO bus IDs + * + * Each GIO bus device identifies itself to the system by answering a + * read with an "ID" value. IDs are either 8 or 32 bits long. IDs less + * than 128 are 8 bits long, with the most significant 24 bits read from + * the slot undefined. + * + * 32-bit IDs are divided into + * bits 0:6 the product ID; ranges from 0x00 to 0x7F. + * bit 7 0=GIO Product ID is 8 bits wide + * 1=GIO Product ID is 32 bits wide. + * bits 8:15 manufacturer version for the product. + * bit 16 0=GIO32 and GIO32-bis, 1=GIO64. + * bit 17 0=no ROM present + * 1=ROM present on this board AND next three words + * space define the ROM. + * bits 18:31 up to manufacturer. + * + * IDs above 0x50/0xd0 are of 3rd party boards. + * + * 8-bit IDs + * 0x01 XPI low cost FDDI + * 0x02 GTR TokenRing + * 0x04 Synchronous ISDN + * 0x05 ATM board [*] + * 0x06 Canon Interface + * 0x07 16 bit SCSI Card [*] + * 0x08 JPEG (Double Wide) + * 0x09 JPEG (Single Wide) + * 0x0a XPI mez. FDDI device 0 + * 0x0b XPI mez. FDDI device 1 + * 0x0c SMPTE 259M Video [*] + * 0x0d Babblefish Compression [*] + * 0x0e E-Plex 8-port Ethernet + * 0x30 Lyon Lamb IVAS + * 0xb8 GIO 100BaseTX Fast Ethernet (gfe) + * + * [*] Device provide 32-bit ID. + * + */ + +#define GIO_ID(x) (x & 0x7f) +#define GIO_32BIT_ID 0x80 +#define GIO_REV(x) ((x >> 8) & 0xff) +#define GIO_64BIT_IFACE 0x10000 +#define GIO_ROM_PRESENT 0x20000 +#define GIO_VENDOR_CODE(x) ((x >> 18) & 0x3fff) + +#define GIO_SLOT_GFX_BASE 0x1f000000 +#define GIO_SLOT_EXP0_BASE 0x1f400000 +#define GIO_SLOT_EXP1_BASE 0x1f600000 + +#endif /* _SGI_GIO_H */ diff -Nru a/include/asm-mips64/sgi/hpc3.h b/include/asm-mips64/sgi/hpc3.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sgi/hpc3.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,316 @@ +/* + * 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. + * + * hpc3.h: Definitions for SGI HPC3 controller + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1998 Ralf Baechle + */ + +#ifndef _SGI_HPC3_H +#define _SGI_HPC3_H + +#include <linux/types.h> +#include <asm/page.h> + +/* An HPC DMA descriptor. */ +struct hpc_dma_desc { + u32 pbuf; /* physical address of data buffer */ + u32 cntinfo; /* counter and info bits */ +#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */ +#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */ +#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */ +#define HPCDMA_EORP 0x40000000 /* end of packet for rx */ +#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */ +#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */ +#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */ +#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */ +#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */ +#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */ + + u32 pnext; /* paddr of next hpc_dma_desc if any */ +}; + +/* The set of regs for each HPC3 PBUS DMA channel. */ +struct hpc3_pbus_dmacregs { + volatile u32 pbdma_bptr; /* pbus dma channel buffer ptr */ + volatile u32 pbdma_dptr; /* pbus dma channel desc ptr */ + u32 _unused0[0x1000/4 - 2]; /* padding */ + volatile u32 pbdma_ctrl; /* pbus dma channel control register has + * copletely different meaning for read + * compared with write */ + /* read */ +#define HPC3_PDMACTRL_INT 0x00000001 /* interrupt (cleared after read) */ +#define HPC3_PDMACTRL_ISACT 0x00000002 /* channel active */ + /* write */ +#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */ +#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */ +#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */ +#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */ +#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */ +#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */ +#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */ +#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */ +#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */ + + u32 _unused1[0x1000/4 - 1]; /* padding */ +}; + +/* The HPC3 SCSI registers, this does not include external ones. */ +struct hpc3_scsiregs { + volatile u32 cbptr; /* current dma buffer ptr, diagnostic use only */ + volatile u32 ndptr; /* next dma descriptor ptr */ + u32 _unused0[0x1000/4 - 2]; /* padding */ + volatile u32 bcd; /* byte count info */ +#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */ +#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */ +#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */ + + volatile u32 ctrl; /* control register */ +#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */ +#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */ +#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */ +#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */ +#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */ +#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */ +#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */ +#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */ + + volatile u32 gfptr; /* current GIO fifo ptr */ + volatile u32 dfptr; /* current device fifo ptr */ + volatile u32 dconfig; /* DMA configuration register */ +#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */ +#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */ +#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */ +#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */ +#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */ +#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */ +#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */ +#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */ +#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */ +#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */ + + volatile u32 pconfig; /* PIO configuration register */ +#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */ +#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */ +#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */ +#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */ +#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */ +#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */ +#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */ +#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */ + + u32 _unused1[0x1000/4 - 6]; /* padding */ +}; + +/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */ +struct hpc3_ethregs { + /* Receiver registers. */ + volatile u32 rx_cbptr; /* current dma buffer ptr, diagnostic use only */ + volatile u32 rx_ndptr; /* next dma descriptor ptr */ + u32 _unused0[0x1000/4 - 2]; /* padding */ + volatile u32 rx_bcd; /* byte count info */ +#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */ +#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */ +#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */ + + volatile u32 rx_ctrl; /* control register */ +#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */ +#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */ +#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */ +#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */ +#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */ +#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */ +#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */ + + volatile u32 rx_gfptr; /* current GIO fifo ptr */ + volatile u32 rx_dfptr; /* current device fifo ptr */ + u32 _unused1; /* padding */ + volatile u32 rx_reset; /* reset register */ +#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */ +#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */ +#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */ + + volatile u32 rx_dconfig; /* DMA configuration register */ +#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */ +#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */ +#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */ +#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */ +#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */ +#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */ +#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */ +#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */ + + volatile u32 rx_pconfig; /* PIO configuration register */ +#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ +#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ +#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ +#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ + + u32 _unused2[0x1000/4 - 8]; /* padding */ + + /* Transmitter registers. */ + volatile u32 tx_cbptr; /* current dma buffer ptr, diagnostic use only */ + volatile u32 tx_ndptr; /* next dma descriptor ptr */ + u32 _unused3[0x1000/4 - 2]; /* padding */ + volatile u32 tx_bcd; /* byte count info */ +#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */ +#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */ +#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */ +#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */ +#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */ + + volatile u32 tx_ctrl; /* control register */ +#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */ +#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */ +#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */ +#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* DMA channel endian mode, 1=little 0=big */ +#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */ +#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */ + + volatile u32 tx_gfptr; /* current GIO fifo ptr */ + volatile u32 tx_dfptr; /* current device fifo ptr */ + u32 _unused4[0x1000/4 - 4]; /* padding */ +}; + +struct hpc3_regs { + /* First regs for the PBUS 8 dma channels. */ + struct hpc3_pbus_dmacregs pbdma[8]; + + /* Now the HPC scsi registers, we get two scsi reg sets. */ + struct hpc3_scsiregs scsi_chan0, scsi_chan1; + + /* The SEEQ hpc3 ethernet dma/control registers. */ + struct hpc3_ethregs ethregs; + + /* Here are where the hpc3 fifo's can be directly accessed + * via PIO accesses. Under normal operation we never stick + * our grubby paws in here so it's just padding. */ + u32 _unused0[0x18000/4]; + + /* HPC3 irq status regs. Due to a peculiar bug you need to + * look at two different register addresses to get at all of + * the status bits. The first reg can only reliably report + * bits 4:0 of the status, and the second reg can only + * reliably report bits 9:5 of the hpc3 irq status. I told + * you it was a peculiar bug. ;-) + */ + volatile u32 istat0; /* Irq status, only bits <4:0> reliable. */ +#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */ +#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */ +#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */ + + volatile u32 gio_misc; /* GIO misc control bits. */ +#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */ +#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */ + + volatile u32 eeprom; /* EEPROM data reg. */ +#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */ +#define HPC3_EEPROM_CSEL 0x02 /* Chip select */ +#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */ +#define HPC3_EEPROM_DATO 0x08 /* Data out */ +#define HPC3_EEPROM_DATI 0x10 /* Data in */ + + volatile u32 istat1; /* Irq status, only bits <9:5> reliable. */ + volatile u32 gio_estat; /* GIO error interrupt status reg. */ +#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */ +#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */ +#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */ + + u32 _unused1[0x14000/4 - 5]; /* padding */ + + /* Now direct PIO per-HPC3 peripheral access to external regs. */ + volatile u32 scsi0_ext[256]; /* SCSI channel 0 external regs */ + u32 _unused2[0x7c00/4]; + volatile u32 scsi1_ext[256]; /* SCSI channel 1 external regs */ + u32 _unused3[0x7c00/4]; + volatile u32 eth_ext[320]; /* Ethernet external registers */ + u32 _unused4[0x3b00/4]; + + /* Per-peripheral device external registers and DMA/PIO control. */ + volatile u32 pbus_extregs[16][256]; + volatile u32 pbus_dmacfg[8][128]; + /* Cycles to spend in D3 for reads */ +#define HPC3_DMACFG_D3R_MASK 0x00000001 +#define HPC3_DMACFG_D3R_SHIFT 0 + /* Cycles to spend in D4 for reads */ +#define HPC3_DMACFG_D4R_MASK 0x0000001e +#define HPC3_DMACFG_D4R_SHIFT 1 + /* Cycles to spend in D5 for reads */ +#define HPC3_DMACFG_D5R_MASK 0x000001e0 +#define HPC3_DMACFG_D5R_SHIFT 5 + /* Cycles to spend in D3 for writes */ +#define HPC3_DMACFG_D3W_MASK 0x00000200 +#define HPC3_DMACFG_D3W_SHIFT 9 + /* Cycles to spend in D4 for writes */ +#define HPC3_DMACFG_D4W_MASK 0x00003c00 +#define HPC3_DMACFG_D4W_SHIFT 10 + /* Cycles to spend in D5 for writes */ +#define HPC3_DMACFG_D5W_MASK 0x0003c000 +#define HPC3_DMACFG_D5W_SHIFT 14 + /* Enable 16-bit DMA access mode */ +#define HPC3_DMACFG_DS16 0x00040000 + /* Places halfwords on high 16 bits of bus */ +#define HPC3_DMACFG_EVENHI 0x00080000 + /* Make this device real time */ +#define HPC3_DMACFG_RTIME 0x00200000 + /* 5 bit burst count for DMA device */ +#define HPC3_DMACFG_BURST_MASK 0x07c00000 +#define HPC3_DMACFG_BURST_SHIFT 22 + /* Use live pbus_dreq unsynchronized signal */ +#define HPC3_DMACFG_DRQLIVE 0x08000000 + volatile u32 pbus_piocfg[16][64]; + /* Cycles to spend in P2 state for reads */ +#define HPC3_PIOCFG_P2R_MASK 0x00001 +#define HPC3_PIOCFG_P2R_SHIFT 0 + /* Cycles to spend in P3 state for reads */ +#define HPC3_PIOCFG_P3R_MASK 0x0001e +#define HPC3_PIOCFG_P3R_SHIFT 1 + /* Cycles to spend in P4 state for reads */ +#define HPC3_PIOCFG_P4R_MASK 0x001e0 +#define HPC3_PIOCFG_P4R_SHIFT 5 + /* Cycles to spend in P2 state for writes */ +#define HPC3_PIOCFG_P2W_MASK 0x00200 +#define HPC3_PIOCFG_P2W_SHIFT 9 + /* Cycles to spend in P3 state for writes */ +#define HPC3_PIOCFG_P3W_MASK 0x03c00 +#define HPC3_PIOCFG_P3W_SHIFT 10 + /* Cycles to spend in P4 state for writes */ +#define HPC3_PIOCFG_P4W_MASK 0x3c000 +#define HPC3_PIOCFG_P4W_SHIFT 14 + /* Enable 16-bit PIO accesses */ +#define HPC3_PIOCFG_DS16 0x40000 + /* Place even address bits in bits <15:8> */ +#define HPC3_PIOCFG_EVENHI 0x80000 + + /* PBUS PROM control regs. */ + volatile u32 pbus_promwe; /* PROM write enable register */ +#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */ + + u32 _unused5[0x0800/4 - 1]; + volatile u32 pbus_promswap; /* Chip select swap reg */ +#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */ + + u32 _unused6[0x0800/4 - 1]; + volatile u32 pbus_gout; /* PROM general purpose output reg */ +#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */ + + u32 _unused7[0x1000/4 - 1]; + volatile u32 rtcregs[14]; /* Dallas clock registers */ + u32 _unused8[50]; + volatile u32 bbram[8192-50-14]; /* Battery backed ram */ +}; + +/* + * It is possible to have two HPC3's within the address space on + * one machine, though only having one is more likely on an Indy. + */ +extern struct hpc3_regs *hpc3c0, *hpc3c1; +#define HPC3_CHIP0_BASE 0x1fb80000 /* physical */ +#define HPC3_CHIP1_BASE 0x1fb00000 /* physical */ + +extern void sgihpc_init(void); + +#endif /* _SGI_HPC3_H */ diff -Nru a/include/asm-mips64/sgi/ioc.h b/include/asm-mips64/sgi/ioc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sgi/ioc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,209 @@ +/* + * 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. + * + * ioc.h: Definitions for SGI I/O Controller + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle + * Copyright (C) 2001, 2003 Ladislav Michl + */ + +#ifndef _SGI_IOC_H +#define _SGI_IOC_H + +#include <linux/types.h> + +/* + * All registers are 8-bit wide alligned on 32-bit boundary. Bad things + * happen if you try word access them. You have been warned. + */ + +struct sgioc_pport_regs { + u8 _data[3]; + volatile u8 data; + u8 _ctrl[3]; + volatile u8 ctrl; +#define SGIOC_PCTRL_STROBE 0x01 +#define SGIOC_PCTRL_AFD 0x02 +#define SGIOC_PCTRL_INIT 0x04 +#define SGIOC_PCTRL_SLIN 0x08 +#define SGIOC_PCTRL_DIRECTION 0x20 +#define SGIOC_PCTRL_SEL 0x40 + u8 _status[3]; + volatile u8 status; +#define SGIOC_PSTAT_DEVID 0x03 +#define SGIOC_PSTAT_NOINK 0x04 +#define SGIOC_PSTAT_ERROR 0x08 +#define SGIOC_PSTAT_ONLINE 0x10 +#define SGIOC_PSTAT_PE 0x20 +#define SGIOC_PSTAT_ACK 0x40 +#define SGIOC_PSTAT_BUSY 0x80 + u8 _dmactrl[3]; + volatile u8 dmactrl; + u8 _intrstat[3]; + volatile u8 intrstat; + u8 _intrmask[3]; + volatile u8 intrmask; + u8 _timer1[3]; + volatile u8 timer1; + u8 _timer2[3]; + volatile u8 timer2; + u8 _timer3[3]; + volatile u8 timer3; + u8 _timer4[3]; + volatile u8 timer4; +}; + +struct sgioc_uart_regs { + u8 _ctrl1[3]; + volatile u8 ctrl1; + u8 _data1[3]; + volatile u8 data1; + u8 _ctrl2[3]; + volatile u8 ctrl2; + u8 _data2[3]; + volatile u8 data2; +}; + +struct sgioc_keyb_regs { + u8 _data[3]; + volatile u8 data; + u8 _command[3]; + volatile u8 command; +}; + +struct sgint_regs { + u8 _istat0[3]; + volatile u8 istat0; /* Interrupt status zero */ +#define SGINT_ISTAT0_FFULL 0x01 +#define SGINT_ISTAT0_SCSI0 0x02 +#define SGINT_ISTAT0_SCSI1 0x04 +#define SGINT_ISTAT0_ENET 0x08 +#define SGINT_ISTAT0_GFXDMA 0x10 +#define SGINT_ISTAT0_PPORT 0x20 +#define SGINT_ISTAT0_HPC2 0x40 +#define SGINT_ISTAT0_LIO2 0x80 + u8 _imask0[3]; + volatile u8 imask0; /* Interrupt mask zero */ + u8 _istat1[3]; + volatile u8 istat1; /* Interrupt status one */ +#define SGINT_ISTAT1_ISDNI 0x01 +#define SGINT_ISTAT1_PWR 0x02 +#define SGINT_ISTAT1_ISDNH 0x04 +#define SGINT_ISTAT1_LIO3 0x08 +#define SGINT_ISTAT1_HPC3 0x10 +#define SGINT_ISTAT1_AFAIL 0x20 +#define SGINT_ISTAT1_VIDEO 0x40 +#define SGINT_ISTAT1_GIO2 0x80 + u8 _imask1[3]; + volatile u8 imask1; /* Interrupt mask one */ + u8 _vmeistat[3]; + volatile u8 vmeistat; /* VME interrupt status */ + u8 _cmeimask0[3]; + volatile u8 cmeimask0; /* VME interrupt mask zero */ + u8 _cmeimask1[3]; + volatile u8 cmeimask1; /* VME interrupt mask one */ + u8 _cmepol[3]; + volatile u8 cmepol; /* VME polarity */ + u8 _tclear[3]; + volatile u8 tclear; + u8 _errstat[3]; + volatile u8 errstat; /* Error status reg, reserved on INT2 */ + u32 _unused0[2]; + u8 _tcnt0[3]; + volatile u8 tcnt0; /* counter 0 */ + u8 _tcnt1[3]; + volatile u8 tcnt1; /* counter 1 */ + u8 _tcnt2[3]; + volatile u8 tcnt2; /* counter 2 */ + u8 _tcword[3]; + volatile u8 tcword; /* control word */ +#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */ +#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */ +#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */ +#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */ +#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */ +#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */ +#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */ +#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */ +#define SGINT_TCWORD_CMASK 0x30 /* Command mask */ +#define SGINT_TCWORD_CLAT 0x00 /* Latch command */ +#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */ +#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */ +#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */ +#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */ +#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */ +#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */ +#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */ +}; + +#define SGINT_TCSAMP_COUNTER 10255 + +/* We need software copies of these because they are write only. */ +extern u8 sgi_ioc_reset, sgi_ioc_write; + +struct sgioc_regs { + struct sgioc_pport_regs pport; + u32 _unused0[2]; + struct sgioc_uart_regs serport; + struct sgioc_keyb_regs kbdmouse; + u8 _gcsel[3]; + volatile u8 gcsel; + u8 _genctrl[3]; + volatile u8 genctrl; + u8 _panel[3]; + volatile u8 panel; +#define SGIOC_PANEL_POWERON 0x01 +#define SGIOC_PANEL_POWERINTR 0x02 +#define SGIOC_PANEL_VOLDNINTR 0x10 +#define SGIOC_PANEL_VOLDNHOLD 0x20 +#define SGIOC_PANEL_VOLUPINTR 0x40 +#define SGIOC_PANEL_VOLUPHOLD 0x80 + u32 _unused1; + u8 _sysid[3]; + volatile u8 sysid; +#define SGIOC_SYSID_FULLHOUSE 0x01 +#define SGIOC_SYSID_BOARDREV(x) ((x & 0xe0) > 5) +#define SGIOC_SYSID_CHIPREV(x) ((x & 0x1e) > 1) + u32 _unused2; + u8 _read[3]; + volatile u8 read; + u32 _unused3; + u8 _dmasel[3]; + volatile u8 dmasel; +#define SGIOC_DMASEL_SCLK10MHZ 0x00 /* use 10MHZ serial clock */ +#define SGIOC_DMASEL_ISDNB 0x01 /* enable isdn B */ +#define SGIOC_DMASEL_ISDNA 0x02 /* enable isdn A */ +#define SGIOC_DMASEL_PPORT 0x04 /* use parallel DMA */ +#define SGIOC_DMASEL_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */ +#define SGIOC_DMASEL_SCLKEXT 0x20 /* use external serial clock */ + u32 _unused4; + u8 _reset[3]; + volatile u8 reset; +#define SGIOC_RESET_PPORT 0x01 /* 0=parport reset, 1=nornal */ +#define SGIOC_RESET_KBDMOUSE 0x02 /* 0=kbdmouse reset, 1=normal */ +#define SGIOC_RESET_EISA 0x04 /* 0=eisa reset, 1=normal */ +#define SGIOC_RESET_ISDN 0x08 /* 0=isdn reset, 1=normal */ +#define SGIOC_RESET_LC0OFF 0x10 /* guiness: turn led off (red, else green) */ +#define SGIOC_RESET_LC1OFF 0x20 /* guiness: turn led off (green, else amber) */ + u32 _unused5; + u8 _write[3]; + volatile u8 write; +#define SGIOC_WRITE_NTHRESH 0x01 /* use 4.5db threshhold */ +#define SGIOC_WRITE_TPSPEED 0x02 /* use 100ohm TP speed */ +#define SGIOC_WRITE_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ +#define SGIOC_WRITE_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ +#define SGIOC_WRITE_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */ +#define SGIOC_WRITE_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */ +#define SGIOC_WRITE_MLO 0x40 /* 1=4.75V 0=+5V */ +#define SGIOC_WRITE_MHI 0x80 /* 1=5.25V 0=+5V */ + u32 _unused6; + struct sgint_regs int3; +}; + +extern struct sgioc_regs *sgioc; +extern struct sgint_regs *sgint; + +#endif diff -Nru a/include/asm-mips64/sgi/ip22.h b/include/asm-mips64/sgi/ip22.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sgi/ip22.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,77 @@ +/* + * 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. + * + * ip22.h: Definitions for SGI IP22 machines + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle + */ + +#ifndef _SGI_IP22_H +#define _SGI_IP22_H + +/* + * These are the virtual IRQ numbers, we divide all IRQ's into + * 'spaces', the 'space' determines where and how to enable/disable + * that particular IRQ on an SGI machine. HPC DMA and MC DMA interrups + * are not supported this way. Driver is supposed to allocate HPC/MC + * interrupt as shareable and then look to proper status bit (see + * HAL2 driver). This will prevent many complications, trust me ;-) + */ + +#include <asm/sgi/ioc.h> + +#define SGINT_EISA 0 /* INDIGO 2 has 16 EISA irq levels */ +#define SGINT_CPU 16 /* MIPS CPU define 8 interrupt sources */ +#define SGINT_LOCAL0 24 /* INDY has 8 local0 irq levels */ +#define SGINT_LOCAL1 32 /* INDY has 8 local1 irq levels */ +#define SGINT_LOCAL2 40 /* INDY has 8 local2 vectored irq levels */ +#define SGINT_LOCAL3 48 /* INDY has 8 local3 vectored irq levels */ +#define SGINT_END 56 /* End of 'spaces' */ + +/* + * Individual interrupt definitions for the Indy and Indigo2 + */ + +#define SGI_SOFT_0_IRQ SGINT_CPU + 0 +#define SGI_SOFT_1_IRQ SGINT_CPU + 1 +#define SGI_LOCAL_0_IRQ SGINT_CPU + 2 +#define SGI_LOCAL_1_IRQ SGINT_CPU + 3 +#define SGI_8254_0_IRQ SGINT_CPU + 4 +#define SGI_8254_1_IRQ SGINT_CPU + 5 +#define SGI_BUSERR_IRQ SGINT_CPU + 6 +#define SGI_TIMER_IRQ SGINT_CPU + 7 + +#define SGI_FIFO_IRQ SGINT_LOCAL0 + 0 /* FIFO full */ +#define SGI_GIO_0_IRQ SGI_FIFO_IRQ /* GIO-0 */ +#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */ +#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */ +#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */ +#define SGI_MCDMA_IRQ SGINT_LOCAL0 + 4 /* MC DMA done */ +#define SGI_PARPORT_IRQ SGINT_LOCAL0 + 5 /* Parallel port */ +#define SGI_GIO_1_IRQ SGINT_LOCAL0 + 6 /* GE / GIO-1 / 2nd-HPC */ +#define SGI_MAP_0_IRQ SGINT_LOCAL0 + 7 /* Mappable interrupt 0 */ + +#define SGI_GPL0_IRQ SGINT_LOCAL1 + 0 /* General Purpose LOCAL1_N<0> */ +#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */ +#define SGI_GPL2_IRQ SGINT_LOCAL1 + 2 /* General Purpose LOCAL1_N<2> */ +#define SGI_MAP_1_IRQ SGINT_LOCAL1 + 3 /* Mappable interrupt 1 */ +#define SGI_HPCDMA_IRQ SGINT_LOCAL1 + 4 /* HPC DMA done */ +#define SGI_ACFAIL_IRQ SGINT_LOCAL1 + 5 /* AC fail */ +#define SGI_VINO_IRQ SGINT_LOCAL1 + 6 /* Indy VINO */ +#define SGI_GIO_2_IRQ SGINT_LOCAL1 + 7 /* Vert retrace / GIO-2 */ + +/* Mapped interrupts. These interrupts may be mapped to either 0, or 1 */ +#define SGI_VERT_IRQ SGINT_LOCAL2 + 0 /* INT3: newport vertical status */ +#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */ +#define SGI_KEYBD_IRQ SGINT_LOCAL2 + 4 /* keyboard */ +#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */ + +#define ip22_is_fullhouse() (sgioc->sysid & SGIOC_SYSID_FULLHOUSE) + +extern unsigned short ip22_eeprom_read(volatile unsigned int *ctrl, int reg); +extern unsigned short ip22_nvram_read(int reg); + +#endif diff -Nru a/include/asm-mips64/sgi/mc.h b/include/asm-mips64/sgi/mc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sgi/mc.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,231 @@ +/* + * 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. + * + * mc.h: Definitions for SGI Memory Controller + * + * Copyright (C) 1996 David S. Miller + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ + +#ifndef _SGI_MC_H +#define _SGI_MC_H + +struct sgimc_regs { + u32 _unused0; + volatile u32 cpuctrl0; /* CPU control register 0, readwrite */ +#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */ +#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */ +#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */ +#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */ +#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */ +#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */ +#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */ +#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */ +#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */ +#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */ +#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */ +#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */ +#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */ +#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */ +#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */ +#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */ +#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */ +#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */ +#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */ + u32 _unused1; + volatile u32 cpuctrl1; /* CPU control register 1, readwrite */ +#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */ +#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */ +#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */ +#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */ +#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */ +#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */ + + u32 _unused2; + volatile u32 watchdogt; /* Watchdog reg rdonly, write clears */ + + u32 _unused3; + volatile u32 systemid; /* MC system ID register, readonly */ +#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */ +#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */ + + u32 _unused4[3]; + volatile u32 divider; /* Divider reg for RPSS */ + + u32 _unused5; + volatile u32 eeprom; /* EEPROM byte reg for r4k */ +#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */ +#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */ +#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */ +#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */ +#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */ + + u32 _unused6[3]; + volatile u32 rcntpre; /* Preload refresh counter */ + + u32 _unused7; + volatile u32 rcounter; /* Readonly refresh counter */ + + u32 _unused8[13]; + volatile u32 giopar; /* Parameter word for GIO64 */ +#define SGIMC_GIOPAR_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */ +#define SGIMC_GIOPAR_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */ +#define SGIMC_GIOPAR_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */ +#define SGIMC_GIOPAR_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */ +#define SGIMC_GIOPAR_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */ +#define SGIMC_GIOPAR_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */ +#define SGIMC_GIOPAR_RTIMEGFX 0x00000040 /* GFX device has realtime attr */ +#define SGIMC_GIOPAR_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */ +#define SGIMC_GIOPAR_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */ +#define SGIMC_GIOPAR_MASTEREISA 0x00000200 /* EISA bus can act as bus master */ +#define SGIMC_GIOPAR_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */ +#define SGIMC_GIOPAR_MASTERGFX 0x00000800 /* GFX can act as a bus master */ +#define SGIMC_GIOPAR_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */ +#define SGIMC_GIOPAR_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */ +#define SGIMC_GIOPAR_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */ +#define SGIMC_GIOPAR_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */ + + u32 _unused9; + volatile u32 cputp; /* CPU bus arb time period */ + + u32 _unused10[3]; + volatile u32 lbursttp; /* Time period for long bursts */ + + /* MC chip can drive up to 4 bank 4 SIMMs each. All SIMMs in bank must + * be the same size. The size encoding for supported SIMMs is bellow */ + u32 _unused11[9]; + volatile u32 mconfig0; /* Memory config register zero */ + u32 _unused12; + volatile u32 mconfig1; /* Memory config register one */ +#define SGIMC_MCONFIG_BASEADDR 0x000000ff /* Base address of bank*/ +#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */ +#define SGIMC_MCONFIG_BVALID 0x00002000 /* Bank is valid */ +#define SGIMC_MCONFIG_SBANKS 0x00004000 /* Number of subbanks */ + + u32 _unused13; + volatile u32 cmacc; /* Mem access config for CPU */ + u32 _unused14; + volatile u32 gmacc; /* Mem access config for GIO */ + + /* This define applies to both cmacc and gmacc registers above. */ +#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */ + + /* Error address/status regs from GIO and CPU perspectives. */ + u32 _unused15; + volatile u32 cerr; /* Error address reg for CPU */ + u32 _unused16; + volatile u32 cstat; /* Status reg for CPU */ +#define SGIMC_CSTAT_RD 0x00000100 /* read parity error */ +#define SGIMC_CSTAT_PAR 0x00000200 /* CPU parity error */ +#define SGIMC_CSTAT_ADDR 0x00000400 /* memory bus error bad addr */ +#define SGIMC_CSTAT_SYSAD_PAR 0x00000800 /* sysad parity error */ +#define SGIMC_CSTAT_SYSCMD_PAR 0x00001000 /* syscmd parity error */ +#define SGIMC_CSTAT_BAD_DATA 0x00002000 /* bad data identifier */ +#define SGIMC_CSTAT_PAR_MASK 0x00001f00 /* parity error mask */ +#define SGIMC_CSTAT_RD_PAR (SGIMC_CSTAT_RD | SGIMC_CSTAT_PAR) + + u32 _unused17; + volatile u32 gerr; /* Error address reg for GIO */ + u32 _unused18; + volatile u32 gstat; /* Status reg for GIO */ +#define SGIMC_GSTAT_RD 0x00000100 /* read parity error */ +#define SGIMC_GSTAT_WR 0x00000200 /* write parity error */ +#define SGIMC_GSTAT_TIME 0x00000400 /* GIO bus timed out */ +#define SGIMC_GSTAT_PROM 0x00000800 /* write to PROM when PROM_EN not set */ +#define SGIMC_GSTAT_ADDR 0x00001000 /* parity error on addr cycle */ +#define SGIMC_GSTAT_BC 0x00002000 /* parity error on byte count cycle */ +#define SGIMC_GSTAT_PIO_RD 0x00004000 /* read data parity on pio */ +#define SGIMC_GSTAT_PIO_WR 0x00008000 /* write data parity on pio */ + + /* Special hard bus locking registers. */ + u32 _unused19; + volatile u32 syssembit; /* Uni-bit system semaphore */ + u32 _unused20; + volatile u32 mlock; /* Global GIO memory access lock */ + u32 _unused21; + volatile u32 elock; /* Locks EISA from GIO accesses */ + + /* GIO dma control registers. */ + u32 _unused22[15]; + volatile u32 gio_dma_trans; /* DMA mask to translation GIO addrs */ + u32 _unused23; + volatile u32 gio_dma_sbits; /* DMA GIO addr substitution bits */ + u32 _unused24; + volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */ + u32 _unused25; + volatile u32 dma_ctrl; /* Main DMA control reg */ + + /* DMA TLB entry 0 */ + u32 _unused26[5]; + volatile u32 dtlb_hi0; + u32 _unused27; + volatile u32 dtlb_lo0; + + /* DMA TLB entry 1 */ + u32 _unused28; + volatile u32 dtlb_hi1; + u32 _unused29; + volatile u32 dtlb_lo1; + + /* DMA TLB entry 2 */ + u32 _unused30; + volatile u32 dtlb_hi2; + u32 _unused31; + volatile u32 dtlb_lo2; + + /* DMA TLB entry 3 */ + u32 _unused32; + volatile u32 dtlb_hi3; + u32 _unused33; + volatile u32 dtlb_lo3; + + u32 _unused34[0x0392]; + + u32 _unused35; + volatile u32 rpsscounter; /* Chirps at 100ns */ + + u32 _unused36[0x1000/4-2*4]; + + u32 _unused37; + volatile u32 maddronly; /* Address DMA goes at */ + u32 _unused38; + volatile u32 maddrpdeflts; /* Same as above, plus set defaults */ + u32 _unused39; + volatile u32 dmasz; /* DMA count */ + u32 _unused40; + volatile u32 ssize; /* DMA stride size */ + u32 _unused41; + volatile u32 gmaddronly; /* Set GIO DMA but don't start trans */ + u32 _unused42; + volatile u32 dmaddnpgo; /* Set GIO DMA addr + start transfer */ + u32 _unused43; + volatile u32 dmamode; /* DMA mode config bit settings */ + u32 _unused44; + volatile u32 dmaccount; /* Zoom and byte count for DMA */ + u32 _unused45; + volatile u32 dmastart; /* Pedal to the metal. */ + u32 _unused46; + volatile u32 dmarunning; /* DMA op is in progress */ + u32 _unused47; + volatile u32 maddrdefstart; /* Set dma addr, defaults, and kick it */ +}; + +extern struct sgimc_regs *sgimc; +#define SGIMC_BASE 0x1fa00000 /* physical */ + +/* Base location of the two ram banks found in IP2[0268] machines. */ +#define SGIMC_SEG0_BADDR 0x08000000 +#define SGIMC_SEG1_BADDR 0x20000000 + +/* Maximum size of the above banks are per machine. */ +#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */ +#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */ +#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ + +extern void sgimc_init(void); + +#endif /* _SGI_MC_H */ diff -Nru a/include/asm-mips64/sgi/sgihpc.h b/include/asm-mips64/sgi/sgihpc.h --- a/include/asm-mips64/sgi/sgihpc.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,375 +0,0 @@ -/* - * 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. - * - * sgihpc.h: Various HPC I/O controller defines. The HPC is basically - * the approximate functional equivalent of the Sun SYSIO - * on SGI INDY machines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1998 Ralf Baechle (ralf@gnu.org) - */ -#ifndef _ASM_SGI_SGIHPC_H -#define _ASM_SGI_SGIHPC_H - -#include <asm/page.h> - -extern int sgi_has_ioc2; /* to know if we have older ioc1 or ioc2. */ -extern int sgi_guiness; /* GUINESS or FULLHOUSE machine. */ -extern int sgi_boardid; /* Board revision. */ - -/* An HPC dma descriptor. */ -struct hpc_dma_desc { - int pbuf; /* physical address of data buffer */ - int cntinfo; /* counter and info bits */ -#define HPCDMA_EOX 0x80000000 /* last desc in chain for tx */ -#define HPCDMA_EOR 0x80000000 /* last desc in chain for rx */ -#define HPCDMA_EOXP 0x40000000 /* end of packet for tx */ -#define HPCDMA_EORP 0x40000000 /* end of packet for rx */ -#define HPCDMA_XIE 0x20000000 /* irq generated when at end of this desc */ -#define HPCDMA_XIU 0x01000000 /* Tx buffer in use by CPU. */ -#define HPCDMA_EIPC 0x00ff0000 /* SEEQ ethernet special xternal bytecount */ -#define HPCDMA_ETXD 0x00008000 /* set to one by HPC when packet tx'd */ -#define HPCDMA_OWN 0x00004000 /* Denotes ring buffer ownership on rx */ -#define HPCDMA_BCNT 0x00003fff /* size in bytes of this dma buffer */ - - int pnext; /* paddr of next hpc_dma_desc if any */ -}; - -typedef volatile unsigned int hpcreg; - -/* HPC1 stuff. */ - -/* HPC3 stuff. */ - -/* The set of regs for each HPC3 pbus dma channel. */ -struct hpc3_pbus_dmacregs { - hpcreg pbdma_bptr; /* pbus dma channel buffer ptr */ - hpcreg pbdma_dptr; /* pbus dma channel desc ptr */ - char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg pbdma_ctrl; /* pbus dma channel control reg */ -#define HPC3_PDMACTRL_SEL 0x00000002 /* little endian transfer */ -#define HPC3_PDMACTRL_RCV 0x00000004 /* direction is receive */ -#define HPC3_PDMACTRL_FLSH 0x00000008 /* enable flush for receive DMA */ -#define HPC3_PDMACTRL_ACT 0x00000010 /* start dma transfer */ -#define HPC3_PDMACTRL_LD 0x00000020 /* load enable for ACT */ -#define HPC3_PDMACTRL_RT 0x00000040 /* Use realtime GIO bus servicing */ -#define HPC3_PDMACTRL_HW 0x0000ff00 /* DMA High-water mark */ -#define HPC3_PDMACTRL_FB 0x003f0000 /* Ptr to beginning of fifo */ -#define HPC3_PDMACTRL_FE 0x3f000000 /* Ptr to end of fifo */ - - char _unused2[PAGE_SIZE - (sizeof(hpcreg))]; /* padding */ -}; - -/* The HPC3 scsi registers, this does not include external ones. */ -struct hpc3_scsiregs { - hpcreg cbptr; /* current dma buffer ptr, diagnostic use only */ - hpcreg ndptr; /* next dma descriptor ptr */ - char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg bcd; /* byte count info */ -#define HPC3_SBCD_BCNTMSK 0x00003fff /* bytes to transfer from/to memory */ -#define HPC3_SBCD_XIE 0x00004000 /* Send IRQ when done with cur buf */ -#define HPC3_SBCD_EOX 0x00008000 /* Indicates this is last buf in chain */ - - hpcreg ctrl; /* control register */ -#define HPC3_SCTRL_IRQ 0x01 /* IRQ asserted, either dma done or parity */ -#define HPC3_SCTRL_ENDIAN 0x02 /* DMA endian mode, 0=big 1=little */ -#define HPC3_SCTRL_DIR 0x04 /* DMA direction, 1=dev2mem 0=mem2dev */ -#define HPC3_SCTRL_FLUSH 0x08 /* Tells HPC3 to flush scsi fifos */ -#define HPC3_SCTRL_ACTIVE 0x10 /* SCSI DMA channel is active */ -#define HPC3_SCTRL_AMASK 0x20 /* DMA active inhibits PIO */ -#define HPC3_SCTRL_CRESET 0x40 /* Resets dma channel and external controller */ -#define HPC3_SCTRL_PERR 0x80 /* Bad parity on HPC3 iface to scsi controller */ - - hpcreg gfptr; /* current GIO fifo ptr */ - hpcreg dfptr; /* current device fifo ptr */ - hpcreg dconfig; /* DMA configuration register */ -#define HPC3_SDCFG_HCLK 0x00001 /* Enable DMA half clock mode */ -#define HPC3_SDCFG_D1 0x00006 /* Cycles to spend in D1 state */ -#define HPC3_SDCFG_D2 0x00038 /* Cycles to spend in D2 state */ -#define HPC3_SDCFG_D3 0x001c0 /* Cycles to spend in D3 state */ -#define HPC3_SDCFG_HWAT 0x00e00 /* DMA high water mark */ -#define HPC3_SDCFG_HW 0x01000 /* Enable 16-bit halfword DMA accesses to scsi */ -#define HPC3_SDCFG_SWAP 0x02000 /* Byte swap all DMA accesses */ -#define HPC3_SDCFG_EPAR 0x04000 /* Enable parity checking for DMA */ -#define HPC3_SDCFG_POLL 0x08000 /* hd_dreq polarity control */ -#define HPC3_SDCFG_ERLY 0x30000 /* hd_dreq behavior control bits */ - - hpcreg pconfig; /* PIO configuration register */ -#define HPC3_SPCFG_P3 0x0003 /* Cycles to spend in P3 state */ -#define HPC3_SPCFG_P2W 0x001c /* Cycles to spend in P2 state for writes */ -#define HPC3_SPCFG_P2R 0x01e0 /* Cycles to spend in P2 state for reads */ -#define HPC3_SPCFG_P1 0x0e00 /* Cycles to spend in P1 state */ -#define HPC3_SPCFG_HW 0x1000 /* Enable 16-bit halfword PIO accesses to scsi */ -#define HPC3_SPCFG_SWAP 0x2000 /* Byte swap all PIO accesses */ -#define HPC3_SPCFG_EPAR 0x4000 /* Enable parity checking for PIO */ -#define HPC3_SPCFG_FUJI 0x8000 /* Fujitsu scsi controller mode for faster dma/pio */ - - char _unused2[PAGE_SIZE - (6 * sizeof(hpcreg))]; /* padding */ -}; - -/* SEEQ ethernet HPC3 registers, only one seeq per HPC3. */ -struct hpc3_ethregs { - /* Receiver registers. */ - hpcreg rx_cbptr; /* current dma buffer ptr, diagnostic use only */ - hpcreg rx_ndptr; /* next dma descriptor ptr */ - char _unused1[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg rx_bcd; /* byte count info */ -#define HPC3_ERXBCD_BCNTMSK 0x00003fff /* bytes to be sent to memory */ -#define HPC3_ERXBCD_XIE 0x20000000 /* HPC3 interrupts cpu at end of this buf */ -#define HPC3_ERXBCD_EOX 0x80000000 /* flags this as end of descriptor chain */ - - hpcreg rx_ctrl; /* control register */ -#define HPC3_ERXCTRL_STAT50 0x0000003f /* Receive status reg bits of Seeq8003 */ -#define HPC3_ERXCTRL_STAT6 0x00000040 /* Rdonly irq status */ -#define HPC3_ERXCTRL_STAT7 0x00000080 /* Rdonlt old/new status bit from Seeq */ -#define HPC3_ERXCTRL_ENDIAN 0x00000100 /* Endian for dma channel, little=1 big=0 */ -#define HPC3_ERXCTRL_ACTIVE 0x00000200 /* Tells if DMA transfer is in progress */ -#define HPC3_ERXCTRL_AMASK 0x00000400 /* Tells if ACTIVE inhibits PIO's to hpc3 */ -#define HPC3_ERXCTRL_RBO 0x00000800 /* Receive buffer overflow if set to 1 */ - - hpcreg rx_gfptr; /* current GIO fifo ptr */ - hpcreg rx_dfptr; /* current device fifo ptr */ - hpcreg _unused2; /* padding */ - hpcreg rx_reset; /* reset register */ -#define HPC3_ERXRST_CRESET 0x1 /* Reset dma channel and external controller */ -#define HPC3_ERXRST_CLRIRQ 0x2 /* Clear channel interrupt */ -#define HPC3_ERXRST_LBACK 0x4 /* Enable diagnostic loopback mode of Seeq8003 */ - - hpcreg rx_dconfig; /* DMA configuration register */ -#define HPC3_ERXDCFG_D1 0x0000f /* Cycles to spend in D1 state for PIO */ -#define HPC3_ERXDCFG_D2 0x000f0 /* Cycles to spend in D2 state for PIO */ -#define HPC3_ERXDCFG_D3 0x00f00 /* Cycles to spend in D3 state for PIO */ -#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */ -#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */ -#define HPC3_ERXDCFG_FEOP 0x04000 /* Bad packet marker timeout enable */ -#define HPC3_ERXDCFG_FIRQ 0x08000 /* Another bad packet timeout enable */ -#define HPC3_ERXDCFG_PTO 0x30000 /* Programmed timeout value for above two */ - - hpcreg rx_pconfig; /* PIO configuration register */ -#define HPC3_ERXPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ -#define HPC3_ERXPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ -#define HPC3_ERXPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ -#define HPC3_ERXPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ - - char _unused3[PAGE_SIZE - (8 * sizeof(hpcreg))]; /* padding */ - - /* Transmitter registers. */ - hpcreg tx_cbptr; /* current dma buffer ptr, diagnostic use only */ - hpcreg tx_ndptr; /* next dma descriptor ptr */ - char _unused4[PAGE_SIZE - (2 * sizeof(hpcreg))]; /* padding */ - hpcreg tx_bcd; /* byte count info */ -#define HPC3_ETXBCD_BCNTMSK 0x00003fff /* bytes to be read from memory */ -#define HPC3_ETXBCD_ESAMP 0x10000000 /* if set, too late to add descriptor */ -#define HPC3_ETXBCD_XIE 0x20000000 /* Interrupt cpu at end of cur desc */ -#define HPC3_ETXBCD_EOP 0x40000000 /* Last byte of cur buf is end of packet */ -#define HPC3_ETXBCD_EOX 0x80000000 /* This buf is the end of desc chain */ - - hpcreg tx_ctrl; /* control register */ -#define HPC3_ETXCTRL_STAT30 0x0000000f /* Rdonly copy of seeq tx stat reg */ -#define HPC3_ETXCTRL_STAT4 0x00000010 /* Indicate late collision occurred */ -#define HPC3_ETXCTRL_STAT75 0x000000e0 /* Rdonly irq status from seeq */ -#define HPC3_ETXCTRL_ENDIAN 0x00000100 /* Dma channel endian mode, 1=little 0=big */ -#define HPC3_ETXCTRL_ACTIVE 0x00000200 /* DMA tx channel is active */ -#define HPC3_ETXCTRL_AMASK 0x00000400 /* Indicates ACTIVE inhibits PIO's */ - - hpcreg tx_gfptr; /* current GIO fifo ptr */ - hpcreg tx_dfptr; /* current device fifo ptr */ - char _unused5[PAGE_SIZE - (4 * sizeof(hpcreg))]; /* padding */ -}; - -struct hpc3_regs { - /* First regs for the PBUS 8 dma channels. */ - struct hpc3_pbus_dmacregs pbdma[8]; - - /* Now the HPC scsi registers, we get two scsi reg sets. */ - struct hpc3_scsiregs scsi_chan0, scsi_chan1; - - /* The SEEQ hpc3 ethernet dma/control registers. */ - struct hpc3_ethregs ethregs; - - /* Here are where the hpc3 fifo's can be directly accessed - * via PIO accesses. Under normal operation we never stick - * our grubby paws in here so it's just padding. - */ - char _unused1[PAGE_SIZE * 24]; - - /* HPC3 irq status regs. Due to a peculiar bug you need to - * look at two different register addresses to get at all of - * the status bits. The first reg can only reliably report - * bits 4:0 of the status, and the second reg can only - * reliably report bits 9:5 of the hpc3 irq status. I told - * you it was a peculiar bug. ;-) - */ - hpcreg istat0; /* Irq status, only bits <4:0> reliable. */ -#define HPC3_ISTAT_PBIMASK 0x0ff /* irq bits for pbus devs 0 --> 7 */ -#define HPC3_ISTAT_SC0MASK 0x100 /* irq bit for scsi channel 0 */ -#define HPC3_ISTAT_SC1MASK 0x200 /* irq bit for scsi channel 1 */ - - hpcreg gio64_misc; /* GIO64 misc control bits. */ -#define HPC3_GIOMISC_ERTIME 0x1 /* Enable external timer real time. */ -#define HPC3_GIOMISC_DENDIAN 0x2 /* dma descriptor endian, 1=lit 0=big */ - - hpcreg eeprom_data; /* EEPROM data reg. */ -#define HPC3_EEPROM_EPROT 0x01 /* Protect register enable */ -#define HPC3_EEPROM_CSEL 0x02 /* Chip select */ -#define HPC3_EEPROM_ECLK 0x04 /* EEPROM clock */ -#define HPC3_EEPROM_DATO 0x08 /* Data out */ -#define HPC3_EEPROM_DATI 0x10 /* Data in */ - - hpcreg istat1; /* Irq status, only bits <9:5> reliable. */ - hpcreg gio64_estat; /* GIO64 error interrupt status reg. */ -#define HPC3_GIOESTAT_BLMASK 0x000ff /* Bus lane where bad parity occurred */ -#define HPC3_GIOESTAT_CTYPE 0x00100 /* Bus cycle type, 0=PIO 1=DMA */ -#define HPC3_GIOESTAT_PIDMSK 0x3f700 /* DMA channel parity identifier */ - - /* Now direct PIO per-HPC3 peripheral access to external regs. */ - char _unused2[0x13fec]; /* Trust me... */ - hpcreg scsi0_ext[256]; /* SCSI channel 0 external regs */ - char _unused3[0x07c00]; /* Trust me... */ - hpcreg scsi1_ext[256]; /* SCSI channel 1 external regs */ - char _unused4[0x07c00]; /* It'll only hurt a little... */ - - /* Did DaveM forget the ethernet external regs? - * Anyhow, they're not here and we need some padding instead. - */ - char _unused5[0x04000]; /* It'll hurt a lot if you leave this out */ - - /* Per-peripheral device external registers and dma/pio control. */ - hpcreg pbus_extregs[16][256]; /* 2nd indice indexes controller */ - hpcreg pbus_dmacfgs[8][128]; /* 2nd indice indexes controller */ -#define HPC3_PIODCFG_D3R 0x00000001 /* Cycles to spend in D3 for reads */ -#define HPC3_PIODCFG_D4R 0x0000001e /* Cycles to spend in D4 for reads */ -#define HPC3_PIODCFG_D5R 0x000001e0 /* Cycles to spend in D5 for reads */ -#define HPC3_PIODCFG_D3W 0x00000200 /* Cycles to spend in D3 for writes */ -#define HPC3_PIODCFG_D4W 0x00003c00 /* Cycles to spend in D4 for writes */ -#define HPC3_PIODCFG_D5W 0x0003c000 /* Cycles to spend in D5 for writes */ -#define HPC3_PIODCFG_HWORD 0x00040000 /* Enable 16-bit dma access mode */ -#define HPC3_PIODCFG_EHI 0x00080000 /* Places halfwords on high 16 bits of bus */ -#define HPC3_PIODCFG_RTIME 0x00200000 /* Make this device real time on GIO bus */ -#define HPC3_PIODCFG_BURST 0x07c00000 /* 5 bit burst count for DMA device */ -#define HPC3_PIODCFG_DRQLV 0x08000000 /* Use live pbus_dreq unsynchronized signal */ - - hpcreg pbus_piocfgs[64][10]; /* 2nd indice indexes controller */ -#define HPC3_PIOPCFG_RP2 0x00001 /* Cycles to spend in P2 state for reads */ -#define HPC3_PIOPCFG_RP3 0x0001e /* Cycles to spend in P3 state for reads */ -#define HPC3_PIOPCFG_RP4 0x001e0 /* Cycles to spend in P4 state for reads */ -#define HPC3_PIOPCFG_WP2 0x00200 /* Cycles to spend in P2 state for writes */ -#define HPC3_PIOPCFG_WP3 0x03c00 /* Cycles to spend in P3 state for writes */ -#define HPC3_PIOPCFG_WP4 0x3c000 /* Cycles to spend in P4 state for writes */ -#define HPC3_PIOPCFG_HW 0x40000 /* Enable 16-bit PIO accesses */ -#define HPC3_PIOPCFG_EHI 0x80000 /* Place even address bits in bits <15:8> */ - - /* PBUS PROM control regs. */ - hpcreg pbus_promwe; /* PROM write enable register */ -#define HPC3_PROM_WENAB 0x1 /* Enable writes to the PROM */ - - char _unused6[0x800 - sizeof(hpcreg)]; - hpcreg pbus_promswap; /* Chip select swap reg */ -#define HPC3_PROM_SWAP 0x1 /* invert GIO addr bit to select prom0 or prom1 */ - - char _unused7[0x800 - sizeof(hpcreg)]; - hpcreg pbus_gout; /* PROM general purpose output reg */ -#define HPC3_PROM_STAT 0x1 /* General purpose status bit in gout */ - - char _unused8[0x1000 - sizeof(hpcreg)]; - hpcreg pbus_promram[16384]; /* 64k of PROM battery backed ram */ -}; - -/* It is possible to have two HPC3's within the address space on - * one machine, though only having one is more likely on an INDY. - * Controller 0 lives at physical address 0x1fb80000 and the controller - * 1 if present lives at address 0x1fb00000. - */ -extern struct hpc3_regs *hpc3c0, *hpc3c1; -#define HPC3_CHIP0_PBASE 0x1fb80000 /* physical */ -#define HPC3_CHIP1_PBASE 0x1fb00000 /* physical */ - -/* Control and misc status information, these live in pbus channel 6. */ -struct hpc3_miscregs { - hpcreg pdata, pctrl, pstat, pdmactrl, pistat, pimask; - hpcreg ptimer1, ptimer2, ptimer3, ptimer4; - hpcreg _unused1[2]; - hpcreg ser1cmd, ser1data; - hpcreg ser0cmd, ser0data; - hpcreg kbdmouse0, kbdmouse1; - hpcreg gcsel, genctrl, panel; - hpcreg _unused2; - hpcreg sysid; - hpcreg _unused3; - hpcreg read, _unused4; - hpcreg dselect; -#define HPC3_DSELECT_SCLK10MHZ 0x00 /* use 10MHZ serial clock */ -#define HPC3_DSELECT_ISDNB 0x01 /* enable isdn B */ -#define HPC3_DSELECT_ISDNA 0x02 /* enable isdn A */ -#define HPC3_DSELECT_LPR 0x04 /* use parallel DMA */ -#define HPC3_DSELECT_SCLK667MHZ 0x10 /* use 6.67MHZ serial clock */ -#define HPC3_DSELECT_SCLKEXT 0x20 /* use external serial clock */ - - hpcreg _unused5; - hpcreg write1; -#define HPC3_WRITE1_PRESET 0x01 /* 0=LPR_RESET, 1=NORMAL */ -#define HPC3_WRITE1_KMRESET 0x02 /* 0=KBDMOUSE_RESET, 1=NORMAL */ -#define HPC3_WRITE1_ERESET 0x04 /* 0=EISA_RESET, 1=NORMAL */ -#define HPC3_WRITE1_GRESET 0x08 /* 0=MAGIC_GIO_RESET, 1=NORMAL */ -#define HPC3_WRITE1_LC0OFF 0x10 /* turn led off (guiness=red, else green) */ -#define HPC3_WRITE1_LC1OFF 0x20 /* turn led off (guiness=green, else amber) */ - - hpcreg _unused6; - hpcreg write2; -#define HPC3_WRITE2_NTHRESH 0x01 /* use 4.5db threshhold */ -#define HPC3_WRITE2_TPSPEED 0x02 /* use 100ohm TP speed */ -#define HPC3_WRITE2_EPSEL 0x04 /* force cable mode: 1=AUI 0=TP */ -#define HPC3_WRITE2_EASEL 0x08 /* 1=autoselect 0=manual cable selection */ -#define HPC3_WRITE2_U1AMODE 0x10 /* 1=PC 0=MAC UART mode */ -#define HPC3_WRITE2_U0AMODE 0x20 /* 1=PC 0=MAC UART mode */ -#define HPC3_WRITE2_MLO 0x40 /* 1=4.75V 0=+5V */ -#define HPC3_WRITE2_MHI 0x80 /* 1=5.25V 0=+5V */ -}; -extern struct hpc3_miscregs *hpc3mregs; -#define HPC3_MREGS_PBASE 0x1fbd9800 /* physical */ - -/* We need software copies of these because they are write only. */ -extern unsigned int sgi_hpc_write1, sgi_hpc_write2; - -struct hpc_keyb { -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char data; - unsigned char _unused1[3]; - volatile unsigned char command; -#else - volatile unsigned char data; - unsigned char _unused0[3]; - volatile unsigned char command; - unsigned char _unused1[3]; -#endif -}; - -/* Indy RTC */ - -/* The layout of registers for the INDY Dallas 1286 clock chipset. */ -struct indy_clock { - volatile unsigned int hsec; - volatile unsigned int sec; - volatile unsigned int min; - volatile unsigned int malarm; - volatile unsigned int hr; - volatile unsigned int halarm; - volatile unsigned int day; - volatile unsigned int dalarm; - volatile unsigned int date; - volatile unsigned int month; - volatile unsigned int year; - volatile unsigned int cmd; - volatile unsigned int whsec; - volatile unsigned int wsec; - volatile unsigned int _unused0[50]; -}; - -#define INDY_CLOCK_REGS (KSEG1ADDR(0x1fbe0000)) - -extern void sgihpc_init(void); - -#endif /* _ASM_SGI_SGIHPC_H */ diff -Nru a/include/asm-mips64/sgi/sgimc.h b/include/asm-mips64/sgi/sgimc.h --- a/include/asm-mips64/sgi/sgimc.h Fri Jun 27 14:19:54 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,228 +0,0 @@ -/* - * 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. - * - * sgimc.h: Definitions for memory controller hardware found on - * SGI IP20, IP22, IP26, and IP28 machines. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#ifndef _ASM_SGI_SGIMC_H -#define _ASM_SGI_SGIMC_H - -struct sgimc_misc_ctrl { - u32 _unused1; - volatile u32 cpuctrl0; /* CPU control register 0, readwrite */ -#define SGIMC_CCTRL0_REFS 0x0000000f /* REFS mask */ -#define SGIMC_CCTRL0_EREFRESH 0x00000010 /* Memory refresh enable */ -#define SGIMC_CCTRL0_EPERRGIO 0x00000020 /* GIO parity error enable */ -#define SGIMC_CCTRL0_EPERRMEM 0x00000040 /* Main mem parity error enable */ -#define SGIMC_CCTRL0_EPERRCPU 0x00000080 /* CPU bus parity error enable */ -#define SGIMC_CCTRL0_WDOG 0x00000100 /* Watchdog timer enable */ -#define SGIMC_CCTRL0_SYSINIT 0x00000200 /* System init bit */ -#define SGIMC_CCTRL0_GFXRESET 0x00000400 /* Graphics interface reset */ -#define SGIMC_CCTRL0_EISALOCK 0x00000800 /* Lock CPU from memory for EISA */ -#define SGIMC_CCTRL0_EPERRSCMD 0x00001000 /* SysCMD bus parity error enable */ -#define SGIMC_CCTRL0_IENAB 0x00002000 /* Allow interrupts from MC */ -#define SGIMC_CCTRL0_ESNOOP 0x00004000 /* Snooping I/O enable */ -#define SGIMC_CCTRL0_EPROMWR 0x00008000 /* Prom writes from cpu enable */ -#define SGIMC_CCTRL0_WRESETPMEM 0x00010000 /* Perform warm reset, preserves mem */ -#define SGIMC_CCTRL0_LENDIAN 0x00020000 /* Put MC in little-endian mode */ -#define SGIMC_CCTRL0_WRESETDMEM 0x00040000 /* Warm reset, destroys mem contents */ -#define SGIMC_CCTRL0_CMEMBADPAR 0x02000000 /* Generate bad perr from cpu to mem */ -#define SGIMC_CCTRL0_R4KNOCHKPARR 0x04000000 /* Don't chk parity on mem data reads */ -#define SGIMC_CCTRL0_GIOBTOB 0x08000000 /* Allow GIO back to back writes */ - - u32 _unused2; - volatile u32 cpuctrl1; /* CPU control register 1, readwrite */ -#define SGIMC_CCTRL1_EGIOTIMEO 0x00000010 /* GIO bus timeout enable */ -#define SGIMC_CCTRL1_FIXEDEHPC 0x00001000 /* Fixed HPC endianness */ -#define SGIMC_CCTRL1_LITTLEHPC 0x00002000 /* Little endian HPC */ -#define SGIMC_CCTRL1_FIXEDEEXP0 0x00004000 /* Fixed EXP0 endianness */ -#define SGIMC_CCTRL1_LITTLEEXP0 0x00008000 /* Little endian EXP0 */ -#define SGIMC_CCTRL1_FIXEDEEXP1 0x00010000 /* Fixed EXP1 endianness */ -#define SGIMC_CCTRL1_LITTLEEXP1 0x00020000 /* Little endian EXP1 */ - - u32 _unused3; - volatile u32 watchdogt; /* Watchdog reg rdonly, write clears */ - - u32 _unused4; - volatile u32 systemid; /* MC system ID register, readonly */ -#define SGIMC_SYSID_MASKREV 0x0000000f /* Revision of MC controller */ -#define SGIMC_SYSID_EPRESENT 0x00000010 /* Indicates presence of EISA bus */ - - u32 _unused5[3]; - volatile u32 divider; /* Divider reg for RPSS */ - - u32 _unused6; - volatile unsigned char eeprom; /* EEPROM byte reg for r4k */ -#define SGIMC_EEPROM_PRE 0x00000001 /* eeprom chip PRE pin assertion */ -#define SGIMC_EEPROM_CSEL 0x00000002 /* Active high, eeprom chip select */ -#define SGIMC_EEPROM_SECLOCK 0x00000004 /* EEPROM serial clock */ -#define SGIMC_EEPROM_SDATAO 0x00000008 /* Serial EEPROM data-out */ -#define SGIMC_EEPROM_SDATAI 0x00000010 /* Serial EEPROM data-in */ - - unsigned char _unused7[3]; - u32 _unused8[3]; - volatile unsigned short rcntpre; /* Preload refresh counter */ - - unsigned short _unused9; - u32 _unused9a; - volatile unsigned short rcounter; /* Readonly refresh counter */ - - unsigned short _unused10; - u32 _unused11[13]; - volatile u32 gioparm; /* Parameter word for GIO64 */ -#define SGIMC_GIOPARM_HPC64 0x00000001 /* HPC talks to GIO using 64-bits */ -#define SGIMC_GIOPARM_GFX64 0x00000002 /* GFX talks to GIO using 64-bits */ -#define SGIMC_GIOPARM_EXP064 0x00000004 /* EXP(slot0) talks using 64-bits */ -#define SGIMC_GIOPARM_EXP164 0x00000008 /* EXP(slot1) talks using 64-bits */ -#define SGIMC_GIOPARM_EISA64 0x00000010 /* EISA bus talks 64-bits to GIO */ -#define SGIMC_GIOPARM_HPC264 0x00000020 /* 2nd HPX talks 64-bits to GIO */ -#define SGIMC_GIOPARM_RTIMEGFX 0x00000040 /* GFX device has realtime attr */ -#define SGIMC_GIOPARM_RTIMEEXP0 0x00000080 /* EXP(slot0) has realtime attr */ -#define SGIMC_GIOPARM_RTIMEEXP1 0x00000100 /* EXP(slot1) has realtime attr */ -#define SGIMC_GIOPARM_MASTEREISA 0x00000200 /* EISA bus can act as bus master */ -#define SGIMC_GIOPARM_ONEBUS 0x00000400 /* Exists one GIO64 pipelined bus */ -#define SGIMC_GIOPARM_MASTERGFX 0x00000800 /* GFX can act as a bus master */ -#define SGIMC_GIOPARM_MASTEREXP0 0x00001000 /* EXP(slot0) can bus master */ -#define SGIMC_GIOPARM_MASTEREXP1 0x00002000 /* EXP(slot1) can bus master */ -#define SGIMC_GIOPARM_PLINEEXP0 0x00004000 /* EXP(slot0) has pipeline attr */ -#define SGIMC_GIOPARM_PLINEEXP1 0x00008000 /* EXP(slot1) has pipeline attr */ - - u32 _unused13; - volatile unsigned short cputp; /* CPU bus arb time period */ - - unsigned short _unused14; - u32 _unused15[3]; - volatile unsigned short lbursttp; /* Time period for long bursts */ - - unsigned short _unused16; - u32 _unused17[9]; - volatile u32 mconfig0; /* Memory config register zero */ - u32 _unused18; - volatile u32 mconfig1; /* Memory config register one */ - - /* These defines apply to both mconfig registers above. */ -#define SGIMC_MCONFIG_FOURMB 0x00000000 /* Physical ram = 4megs */ -#define SGIMC_MCONFIG_EIGHTMB 0x00000100 /* Physical ram = 8megs */ -#define SGIMC_MCONFIG_SXTEENMB 0x00000300 /* Physical ram = 16megs */ -#define SGIMC_MCONFIG_TTWOMB 0x00000700 /* Physical ram = 32megs */ -#define SGIMC_MCONFIG_SFOURMB 0x00000f00 /* Physical ram = 64megs */ -#define SGIMC_MCONFIG_OTEIGHTMB 0x00001f00 /* Physical ram = 128megs */ -#define SGIMC_MCONFIG_RMASK 0x00001f00 /* Ram config bitmask */ - - u32 _unused19; - volatile u32 cmacc; /* Mem access config for CPU */ - u32 _unused20; - volatile u32 gmacc; /* Mem access config for GIO */ - - /* This define applies to both cmacc and gmacc registers above. */ -#define SGIMC_MACC_ALIASBIG 0x20000000 /* 512MB home for alias */ - - /* Error address/status regs from GIO and CPU perspectives. */ - u32 _unused21; - volatile u32 cerr; /* Error address reg for CPU */ - u32 _unused22; - volatile u32 cstat; /* Status reg for CPU */ - u32 _unused23; - volatile u32 gerr; /* Error address reg for GIO */ - u32 _unused24; - volatile u32 gstat; /* Status reg for GIO */ - - /* Special hard bus locking registers. */ - u32 _unused25; - volatile unsigned char syssembit; /* Uni-bit system semaphore */ - unsigned char _unused26[3]; - u32 _unused27; - volatile unsigned char mlock; /* Global GIO memory access lock */ - unsigned char _unused28[3]; - u32 _unused29; - volatile unsigned char elock; /* Locks EISA from GIO accesses */ - - /* GIO dma control registers. */ - unsigned char _unused30[3]; - u32 _unused31[14]; - volatile u32 gio_dma_trans;/* DMA mask to translation GIO addrs */ - u32 _unused32; - volatile u32 gio_dma_sbits;/* DMA GIO addr substitution bits */ - u32 _unused33; - volatile u32 dma_intr_cause; /* DMA IRQ cause indicator bits */ - u32 _unused34; - volatile u32 dma_ctrl; /* Main DMA control reg */ - - /* DMA TLB entry 0 */ - u32 _unused35; - volatile u32 dtlb_hi0; - u32 _unused36; - volatile u32 dtlb_lo0; - - /* DMA TLB entry 1 */ - u32 _unused37; - volatile u32 dtlb_hi1; - u32 _unused38; - volatile u32 dtlb_lo1; - - /* DMA TLB entry 2 */ - u32 _unused39; - volatile u32 dtlb_hi2; - u32 _unused40; - volatile u32 dtlb_lo2; - - /* DMA TLB entry 3 */ - u32 _unused41; - volatile u32 dtlb_hi3; - u32 _unused42; - volatile u32 dtlb_lo3; -}; - -/* MC misc control registers live at physical 0x1fa00000. */ -extern struct sgimc_misc_ctrl *mcmisc_regs; -extern u32 *rpsscounter; /* Chirps at 100ns */ - -struct sgimc_dma_ctrl { - u32 _unused1; - volatile u32 maddronly; /* Address DMA goes at */ - u32 _unused2; - volatile u32 maddrpdeflts; /* Same as above, plus set defaults */ - u32 _unused3; - volatile u32 dmasz; /* DMA count */ - u32 _unused4; - volatile u32 ssize; /* DMA stride size */ - u32 _unused5; - volatile u32 gmaddronly; /* Set GIO DMA but do not start trans */ - u32 _unused6; - volatile u32 dmaddnpgo; /* Set GIO DMA addr + start transfer */ - u32 _unused7; - volatile u32 dmamode; /* DMA mode config bit settings */ - u32 _unused8; - volatile u32 dmacount; /* Zoom and byte count for DMA */ - u32 _unused9; - volatile u32 dmastart; /* Pedal to the metal. */ - u32 _unused10; - volatile u32 dmarunning; /* DMA op is in progress */ - u32 _unused11; - - /* Set dma addr, defaults, and kick it */ - volatile u32 maddr_defl_go; /* go go go! -lm */ -}; - -/* MC controller dma regs live at physical 0x1fa02000. */ -extern struct sgimc_dma_ctrl *dmactrlregs; - -/* Base location of the two ram banks found in IP2[0268] machines. */ -#define SGIMC_SEG0_BADDR 0x08000000 -#define SGIMC_SEG1_BADDR 0x20000000 - -/* Maximum size of the above banks are per machine. */ -extern u32 sgimc_seg0_size, sgimc_seg1_size; -#define SGIMC_SEG0_SIZE_ALL 0x10000000 /* 256MB */ -#define SGIMC_SEG1_SIZE_IP20_IP22 0x08000000 /* 128MB */ -#define SGIMC_SEG1_SIZE_IP26_IP28 0x20000000 /* 512MB */ - -extern void sgimc_init(void); - -#endif /* _ASM_SGI_SGIMC_H */ diff -Nru a/include/asm-mips64/sgi/sgint23.h b/include/asm-mips64/sgi/sgint23.h --- a/include/asm-mips64/sgi/sgint23.h Fri Jun 27 14:20:04 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,204 +0,0 @@ -/* - * 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. - * - * sgint23.h: Defines for the SGI INT2 and INT3 chipsets. - * - * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1997, 98, 1999, 2000 Ralf Baechle - * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections - */ -#ifndef _ASM_SGI_SGINT23_H -#define _ASM_SGI_SGINT23_H - -/* These are the virtual IRQ numbers, we divide all IRQ's into - * 'spaces', the 'space' determines where and how to enable/disable - * that particular IRQ on an SGI machine. Add new 'spaces' as new - * IRQ hardware is supported. - */ -#define SGINT_LOCAL0 0 /* INDY has 8 local0 irq levels */ -#define SGINT_LOCAL1 8 /* INDY has 8 local1 irq levels */ -#define SGINT_LOCAL2 16 /* INDY has 8 local2 vectored irq levels */ -#define SGINT_LOCAL3 24 /* INDY has 8 local3 vectored irq levels */ -#define SGINT_GIO 32 /* INDY has 9 GIO irq levels */ -#define SGINT_HPCDMA 41 /* INDY has 11 HPCDMA irq _sources_ */ -#define SGINT_END 52 /* End of 'spaces' */ - -/* - * Individual interrupt definitions for the INDY and Indigo2 - */ -#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */ -#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */ -#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */ - -#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */ - -#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */ -#define SGI_KEYBOARD_IRQ SGINT_LOCAL2 + 4 /* keyboard */ -#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */ - -/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */ -#define SGI_INT2_BASE 0x1fbd9000 /* physical */ -#define SGI_INT3_BASE 0x1fbd9880 /* physical */ - -struct sgi_ioc_ints { -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char istat0; /* Interrupt status zero */ -#else - volatile unsigned char istat0; /* Interrupt status zero */ - unsigned char _unused0[3]; -#endif -#define ISTAT0_FFULL 0x01 -#define ISTAT0_SCSI0 0x02 -#define ISTAT0_SCSI1 0x04 -#define ISTAT0_ENET 0x08 -#define ISTAT0_GFXDMA 0x10 -#define ISTAT0_LPR 0x20 -#define ISTAT0_HPC2 0x40 -#define ISTAT0_LIO2 0x80 - -#ifdef __MIPSEB__ - unsigned char _unused1[3]; - volatile unsigned char imask0; /* Interrupt mask zero */ - unsigned char _unused2[3]; - volatile unsigned char istat1; /* Interrupt status one */ -#else - volatile unsigned char imask0; /* Interrupt mask zero */ - unsigned char _unused1[3]; - volatile unsigned char istat1; /* Interrupt status one */ - unsigned char _unused2[3]; -#endif -#define ISTAT1_ISDNI 0x01 -#define ISTAT1_PWR 0x02 -#define ISTAT1_ISDNH 0x04 -#define ISTAT1_LIO3 0x08 -#define ISTAT1_HPC3 0x10 -#define ISTAT1_AFAIL 0x20 -#define ISTAT1_VIDEO 0x40 -#define ISTAT1_GIO2 0x80 - -#ifdef __MIPSEB__ - unsigned char _unused3[3]; - volatile unsigned char imask1; /* Interrupt mask one */ - unsigned char _unused4[3]; - volatile unsigned char vmeistat; /* VME interrupt status */ - unsigned char _unused5[3]; - volatile unsigned char cmeimask0; /* VME interrupt mask zero */ - unsigned char _unused6[3]; - volatile unsigned char cmeimask1; /* VME interrupt mask one */ - unsigned char _unused7[3]; - volatile unsigned char cmepol; /* VME polarity */ -#else - volatile unsigned char imask1; /* Interrupt mask one */ - unsigned char _unused3[3]; - volatile unsigned char vmeistat; /* VME interrupt status */ - unsigned char _unused4[3]; - volatile unsigned char cmeimask0; /* VME interrupt mask zero */ - unsigned char _unused5[3]; - volatile unsigned char cmeimask1; /* VME interrupt mask one */ - unsigned char _unused6[3]; - volatile unsigned char cmepol; /* VME polarity */ - unsigned char _unused7[3]; -#endif -}; - -struct sgi_ioc_timers { -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char tcnt0; /* counter 0 */ - unsigned char _unused1[3]; - volatile unsigned char tcnt1; /* counter 1 */ - unsigned char _unused2[3]; - volatile unsigned char tcnt2; /* counter 2 */ - unsigned char _unused3[3]; - volatile unsigned char tcword; /* control word */ -#else - volatile unsigned char tcnt0; /* counter 0 */ - unsigned char _unused0[3]; - volatile unsigned char tcnt1; /* counter 1 */ - unsigned char _unused1[3]; - volatile unsigned char tcnt2; /* counter 2 */ - unsigned char _unused2[3]; - volatile unsigned char tcword; /* control word */ - unsigned char _unused3[3]; -#endif -}; - -/* Timer control word bits. */ -#define SGINT_TCWORD_BCD 0x01 /* Use BCD mode for counters */ -#define SGINT_TCWORD_MMASK 0x0e /* Mode bitmask. */ -#define SGINT_TCWORD_MITC 0x00 /* IRQ on terminal count (doesn't work) */ -#define SGINT_TCWORD_MOS 0x02 /* One-shot IRQ mode. */ -#define SGINT_TCWORD_MRGEN 0x04 /* Normal rate generation */ -#define SGINT_TCWORD_MSWGEN 0x06 /* Square wave generator mode */ -#define SGINT_TCWORD_MSWST 0x08 /* Software strobe */ -#define SGINT_TCWORD_MHWST 0x0a /* Hardware strobe */ -#define SGINT_TCWORD_CMASK 0x30 /* Command mask */ -#define SGINT_TCWORD_CLAT 0x00 /* Latch command */ -#define SGINT_TCWORD_CLSB 0x10 /* LSB read/write */ -#define SGINT_TCWORD_CMSB 0x20 /* MSB read/write */ -#define SGINT_TCWORD_CALL 0x30 /* Full counter read/write */ -#define SGINT_TCWORD_CNT0 0x00 /* Select counter zero */ -#define SGINT_TCWORD_CNT1 0x40 /* Select counter one */ -#define SGINT_TCWORD_CNT2 0x80 /* Select counter two */ -#define SGINT_TCWORD_CRBCK 0xc0 /* Readback command */ - -#define SGINT_TCSAMP_COUNTER 10255 - -/* FIXME: What does this really look like? It was written to have - * 17 registers, but there are only 16 in my Indigo2. - * I guessed at which one to remove... - andrewb - */ -struct sgi_int2_regs { - struct sgi_ioc_ints ints; - - volatile u32 ledbits; /* LED control bits */ -#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */ -#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */ -#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */ -#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */ -#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */ - -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char tclear; /* Timer clear strobe address */ -#else - volatile unsigned char tclear; /* Timer clear strobe address */ - unsigned char _unused0[3]; -#endif -#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */ -#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */ -/* I am guessing there are only two unused registers here - * but I could be wrong... - andrewb - */ -/* u32 _unused[3]; */ - u32 _unused[2]; - struct sgi_ioc_timers timers; -}; - -struct sgi_int3_regs { - struct sgi_ioc_ints ints; - -#ifdef __MIPSEB__ - unsigned char _unused0[3]; - volatile unsigned char tclear; /* Timer clear strobe address */ -#else - volatile unsigned char tclear; /* Timer clear strobe address */ - unsigned char _unused0[3]; -#endif - volatile u32 estatus; /* Error status reg */ - u32 _unused1[2]; - struct sgi_ioc_timers timers; -}; - -extern struct sgi_int2_regs *sgi_i2regs; -extern struct sgi_int3_regs *sgi_i3regs; -extern struct sgi_ioc_ints *ioc_icontrol; -extern struct sgi_ioc_timers *ioc_timers; -extern volatile unsigned char *ioc_tclear; - -extern void indy_timer_init(void); - -#endif /* _ASM_SGI_SGINT23_H */ diff -Nru a/include/asm-mips64/sgialib.h b/include/asm-mips64/sgialib.h --- a/include/asm-mips64/sgialib.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/sgialib.h Fri Jun 27 14:19:54 2003 @@ -6,7 +6,7 @@ * SGI ARCS firmware interface library for the Linux kernel. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org) */ #ifndef _ASM_SGIALIB_H #define _ASM_SGIALIB_H @@ -24,12 +24,11 @@ #define prom_argc(index) ((char *) (long) _prom_argc[(index)]) extern int prom_flags; -#define PROM_FLAG_ARCS 1 +#define PROM_FLAG_ARCS 1 +#define PROM_FLAG_USE_AS_CONSOLE 2 -/* Init the PROM library and it's internal data structures. Called - * at boot time from head.S before start_kernel is invoked. - */ -extern int prom_init(int argc, char **argv, char **envp); +/* Init the PROM library and it's internal data structures. */ +extern void prom_init(int argc, char **argv, char **envp, int *prom_vec); /* Simple char-by-char console I/O. */ extern void prom_putchar(char c); @@ -41,9 +40,9 @@ /* Memory descriptor management. */ #define PROM_MAX_PMEMBLOCKS 32 struct prom_pmemblock { - LONG base; /* Within KSEG0 or XKPHYS. */ + LONG base; /* Within KSEG0 or XKPHYS. */ ULONG size; /* In bytes. */ - ULONG type; /* free or prom memory */ + ULONG type; /* free or prom memory */ }; /* Get next memory descriptor after CURR, returns first descriptor @@ -57,9 +56,6 @@ */ extern void prom_meminit(void); extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); - -/* Returns pointer to PROM physical memory block array. */ -extern struct prom_pmemblock *prom_getpblock_array(void); /* PROM device tree library routines. */ #define PROM_NULL_COMPONENT ((pcomponent *) 0) diff -Nru a/include/asm-mips64/sgiarcs.h b/include/asm-mips64/sgiarcs.h --- a/include/asm-mips64/sgiarcs.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/sgiarcs.h Fri Jun 27 14:19:55 2003 @@ -6,13 +6,14 @@ * ARC firmware interface defines. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org) * Copyright (C) 1999 Silicon Graphics, Inc. */ #ifndef _ASM_SGIARCS_H #define _ASM_SGIARCS_H #include <linux/config.h> +#include <asm/types.h> #include <asm/arc/types.h> /* Various ARCS error codes. */ @@ -115,7 +116,7 @@ arc_prog, /* A loaded program resides here */ arc_atmp, /* temporary storage area */ arc_aperm, /* permanent storage */ - arc_fcontig, /* Contiguous and free */ + arc_fcontig, /* Contiguous and free */ }; union linux_memtypes { @@ -164,11 +165,11 @@ /* This prom has a bolixed design. */ struct linux_bigint { #ifdef __MIPSEL__ - unsigned long lo; - long hi; + u32 lo; + s32 hi; #else /* !(__MIPSEL__) */ - long hi; - unsigned long lo; + s32 hi; + u32 lo; #endif }; @@ -364,9 +365,10 @@ * Macros for calling a 32-bit ARC implementation from 64-bit code */ -#ifdef CONFIG_ARC32 +#if defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) + #define __arc_clobbers \ - "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ + "$2","$3" /* ... */, "$8","$9","$10","$11", \ "$12","$13","$14","$15","$16","$24","25","$31" #define ARC_CALL0(dest) \ @@ -379,7 +381,7 @@ "move\t%0, $2" \ : "=r" (__res), "=r" (__vec) \ : "1" (__vec) \ - : __arc_clobbers); \ + : __arc_clobbers, "$4","$5","$6","$7"); \ (unsigned long) __res; \ }) @@ -394,7 +396,7 @@ "move\t%0, $2" \ : "=r" (__res), "=r" (__vec) \ : "1" (__vec), "r" (__a1) \ - : __arc_clobbers); \ + : __arc_clobbers, "$5","$6","$7"); \ (unsigned long) __res; \ }) @@ -410,7 +412,7 @@ "move\t%0, $2" \ : "=r" (__res), "=r" (__vec) \ : "1" (__vec), "r" (__a1), "r" (__a2) \ - : __arc_clobbers); \ + : __arc_clobbers, "$6","$7"); \ __res; \ }) @@ -427,7 +429,7 @@ "move\t%0, $2" \ : "=r" (__res), "=r" (__vec) \ : "1" (__vec), "r" (__a1), "r" (__a2), "r" (__a3) \ - : __arc_clobbers); \ + : __arc_clobbers, "$7"); \ __res; \ }) @@ -471,9 +473,11 @@ : __arc_clobbers); \ __res; \ }) -#endif /* CONFIG_ARC32 */ -#ifdef CONFIG_ARC64 +#endif /* defined(CONFIG_MIPS64) && defined(CONFIG_ARC32) */ + +#if (defined(CONFIG_MIPS32) && defined(CONFIG_ARC32)) || \ + (defined(CONFIG_MIPS64) && defined(CONFIG_ARC64)) #define ARC_CALL0(dest) \ ({ long __res; \ @@ -538,6 +542,6 @@ __res = __vec(__a1, __a2, __a3, __a4, __a5); \ __res; \ }) -#endif /* CONFIG_ARC64 */ +#endif /* both kernel and ARC either 32-bit or 64-bit */ #endif /* _ASM_SGIARCS_H */ diff -Nru a/include/asm-mips64/shmbuf.h b/include/asm-mips64/shmbuf.h --- a/include/asm-mips64/shmbuf.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/shmbuf.h Fri Jun 27 14:19:52 2003 @@ -1,7 +1,7 @@ #ifndef _ASM_SHMBUF_H #define _ASM_SHMBUF_H -/* +/* * The shmid64_ds structure for the MIPS architecture. * Note extra padding because this structure is passed back and forth * between kernel and user space. diff -Nru a/include/asm-mips64/shmiq.h b/include/asm-mips64/shmiq.h --- a/include/asm-mips64/shmiq.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/shmiq.h Fri Jun 27 14:19:57 2003 @@ -9,7 +9,7 @@ * * This also contains some streams and idev bits. * - * They may contain errors, please, refer to the source code of the Linux + * They may contain errors, please, refer to the source code of the Linux * kernel for a definitive answer on what we have implemented * * Miguel. @@ -97,7 +97,7 @@ * head is the user index into the events, user can modify this one. * tail is managed by the kernel. * flags is one of SHMIQ_OVERFLOW or SHMIQ_CORRUPTED - * if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called + * if OVERFLOW is set it seems ioctl QUIOCSERVICED should be called * to notify the kernel. * events where the kernel sticks the events. */ @@ -192,14 +192,14 @@ unsigned hwMaxRes; int hwMinVal; int hwMaxVal; - + unsigned char possibleModes; #define IDEV_ABSOLUTE 0x0 #define IDEV_RELATIVE 0x1 #define IDEV_EITHER 0x2 - + unsigned char mode; /* One of: IDEV_ABSOLUTE, IDEV_RELATIVE */ - + unsigned short resolution; int minVal; int maxVal; diff -Nru a/include/asm-mips64/sibyte/64bit.h b/include/asm-mips64/sibyte/64bit.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/64bit.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2002 Ralf Baechle + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ASM_SIBYTE_64BIT_H +#define __ASM_SIBYTE_64BIT_H + +#include <linux/config.h> +#include <linux/types.h> + +#ifdef CONFIG_MIPS32 + +#include <asm/system.h> + +/* + * This is annoying...we can't actually write the 64-bit IO register properly + * without having access to 64-bit registers... which doesn't work by default + * in o32 format...grrr... + */ +static inline void __out64(u64 val, unsigned long addr) +{ + u64 tmp; + + __asm__ __volatile__ ( + " .set mips3 \n" + " dsll32 %L0, %L0, 0 # __out64 \n" + " dsrl32 %L0, %L0, 0 \n" + " dsll32 %M0, %M0, 0 \n" + " or %L0, %L0, %M0 \n" + " sd %L0, (%2) \n" + " .set mips0 \n" + : "=r" (tmp) + : "0" (val), "r" (addr)); +} + +static inline void out64(u64 val, unsigned long addr) +{ + unsigned long flags; + + local_irq_save(flags); + __out64(val, addr); + local_irq_restore(flags); +} + +static inline u64 __in64(unsigned long addr) +{ + u64 res; + + __asm__ __volatile__ ( + " .set mips3 # __in64 \n" + " ld %L0, (%1) \n" + " dsra32 %M0, %L0, 0 \n" + " sll %L0, %L0, 0 \n" + " .set mips0 \n" + : "=r" (res) + : "r" (addr)); + + return res; +} + +static inline u64 in64(unsigned long addr) +{ + unsigned long flags; + u64 res; + + local_irq_save(flags); + res = __in64(addr); + local_irq_restore(flags); + + return res; +} + +#endif /* CONFIG_MIPS32 */ + +#ifdef CONFIG_MIPS64 + +/* + * These are provided so as to be able to use common + * driver code for the 32-bit and 64-bit trees + */ +extern inline void out64(u64 val, unsigned long addr) +{ + *(volatile unsigned long *)addr = val; +} + +extern inline u64 in64(unsigned long addr) +{ + return *(volatile unsigned long *)addr; +} + +#define __in64(a) in64(a) +#define __out64(v,a) out64(v,a) + +#endif /* CONFIG_MIPS64 */ + +/* + * Avoid interrupt mucking, just adjust the address for 4-byte access. + * Assume the addresses are 8-byte aligned. + */ + +#ifdef __MIPSEB__ +#define __CSR_32_ADJUST 4 +#else +#define __CSR_32_ADJUST 0 +#endif + +#define csr_out32(v,a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST) = (v)) +#define csr_in32(a) (*(volatile u32 *)((unsigned long)(a) + __CSR_32_ADJUST)) + +#endif /* __ASM_SIBYTE_64BIT_H */ diff -Nru a/include/asm-mips64/sibyte/board.h b/include/asm-mips64/sibyte/board.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/board.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _SIBYTE_BOARD_H +#define _SIBYTE_BOARD_H + +#ifdef CONFIG_SIBYTE_BOARD + +#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) || \ + defined(CONFIG_SIBYTE_CRHONE) || defined(CONFIG_SIBYTE_CRHINE) +#include <asm/sibyte/swarm.h> +#endif + +#if defined(CONFIG_SIBYTE_SENTOSA) || defined(CONFIG_SIBYTE_RHONE) +#include <asm/sibyte/sentosa.h> +#endif + +#ifdef CONFIG_SIBYTE_CARMEL +#include <asm/sibyte/carmel.h> +#endif + +#ifdef __ASSEMBLY__ + +#ifdef LEDS_PHYS +#define setleds(t0,t1,c0,c1,c2,c3) \ + li t0, (LEDS_PHYS|0xa0000000); \ + li t1, c0; \ + sb t1, 0x18(t0); \ + li t1, c1; \ + sb t1, 0x10(t0); \ + li t1, c2; \ + sb t1, 0x08(t0); \ + li t1, c3; \ + sb t1, 0x00(t0) +#else +#define setleds(t0,t1,c0,c1,c2,c3) +#endif /* LEDS_PHYS */ + +#else + +void swarm_setup(void); + +#ifdef LEDS_PHYS +extern void setleds(char *str); +#else +#define setleds(s) do { } while (0) +#endif /* LEDS_PHYS */ + +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_SIBYTE_BOARD */ + +#endif /* _SIBYTE_BOARD_H */ diff -Nru a/include/asm-mips64/sibyte/carmel.h b/include/asm-mips64/sibyte/carmel.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/carmel.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2002 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __ASM_SIBYTE_CARMEL_H +#define __ASM_SIBYTE_CARMEL_H + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_int.h> + +#define SIBYTE_BOARD_NAME "Carmel" + +#define GPIO_PHY_INTERRUPT 2 +#define GPIO_NONMASKABLE_INT 3 +#define GPIO_CF_INSERTED 6 +#define GPIO_MONTEREY_RESET 7 +#define GPIO_QUADUART_INT 8 +#define GPIO_CF_INT 9 +#define GPIO_FPGA_CCLK 10 +#define GPIO_FPGA_DOUT 11 +#define GPIO_FPGA_DIN 12 +#define GPIO_FPGA_PGM 13 +#define GPIO_FPGA_DONE 14 +#define GPIO_FPGA_INIT 15 + +#define LEDS_CS 2 +#define LEDS_PHYS 0x100C0000 +#define MLEDS_CS 3 +#define MLEDS_PHYS 0x100A0000 +#define UART_CS 4 +#define UART_PHYS 0x100D0000 +#define ARAVALI_CS 5 +#define ARAVALI_PHYS 0x11000000 +#define IDE_CS 6 +#define IDE_PHYS 0x100B0000 +#define ARAVALI2_CS 7 +#define ARAVALI2_PHYS 0x100E0000 + +#if defined(CONFIG_SIBYTE_CARMEL) +#define K_GPIO_GB_IDE 9 +#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE) +#endif + + +#endif /* __ASM_SIBYTE_CARMEL_H */ diff -Nru a/include/asm-mips64/sibyte/io.h b/include/asm-mips64/sibyte/io.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/io.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,21 @@ +/* + * 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) 2000 Ralf Baechle + * Copyright (C) 2000 Silicon Graphics, Inc. + */ +#ifndef _ASM_SIBYTE_IO_H +#define _ASM_SIBYTE_IO_H + +#include <asm/addrspace.h> + +#define IO_SPACE_BASE K1BASE + +/* For Indigo2. */ +#define IO_SPACE_LIMIT 0xffff + +/* XXX ISA specific functions go here here. */ + +#endif /* _ASM_SIBYTE_IO_H */ diff -Nru a/include/asm-mips64/sibyte/sb1250.h b/include/asm-mips64/sibyte/sb1250.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ASM_SIBYTE_SB1250_H +#define _ASM_SIBYTE_SB1250_H + +#define SB1250_NR_IRQS 64 + +#ifndef __ASSEMBLY__ + +#include <asm/addrspace.h> + +/* For revision/pass information */ +#include <asm/sibyte/sb1250_scd.h> +extern unsigned int sb1_pass; +extern unsigned int soc_pass; +extern unsigned int soc_type; +extern unsigned int periph_rev; + +extern void sb1250_time_init(void); +extern unsigned long sb1250_gettimeoffset(void); +extern void sb1250_mask_irq(int cpu, int irq); +extern void sb1250_unmask_irq(int cpu, int irq); +extern void sb1250_smp_finish(void); +extern void prom_printf(char *fmt, ...); + +#define AT_spin \ + __asm__ __volatile__ ( \ + ".set noat\n" \ + "li $at, 0\n" \ + "1: beqz $at, 1b\n" \ + ".set at\n" \ + ) + +#endif + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_defs.h b/include/asm-mips64/sibyte/sb1250_defs.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_defs.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,242 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Global constants and macros File: sb1250_defs.h + * + * This file contains macros and definitions used by the other + * include files. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + +#ifndef _SB1250_DEFS_H +#define _SB1250_DEFS_H + +/* + * These headers require ANSI C89 string concatenation, and GCC or other + * 'long long' (64-bit integer) support. + */ +#if !defined(__STDC__) && !defined(_MSC_VER) +#error SiByte headers require ANSI C89 support +#endif + + +/* ********************************************************************* + * Macros for feature tests, used to enable include file features + * for chip features only present in certain chip revisions. + * + * SIBYTE_HDR_FEATURES may be defined to be the mask value chip/revision + * which is to be exposed by the headers. If undefined, it defaults to + * "all features." + * + * Use like: + * + * #define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_112x_PASS1 + * + * Generate defines only for that revision of chip. + * + * #if SIBYTE_HDR_FEATURE(chip,pass) + * + * True if header features for that revision or later of + * that particular chip type are enabled in SIBYTE_HDR_FEATURES. + * (Use this to bracket #defines for features present in a given + * revision and later.) + * + * Note that there is no implied ordering between chip types. + * + * Note also that 'chip' and 'pass' must textually exactly + * match the defines below. So, for example, + * SIBYTE_HDR_FEATURE(112x, PASS1) is OK, but + * SIBYTE_HDR_FEATURE(1120, pass1) is not (for two reasons). + * + * #if SIBYTE_HDR_FEATURE_UP_TO(chip,pass) + * + * Same as SIBYTE_HDR_FEATURE, but true for the named revision + * and earlier revisions of the named chip type. + * + * #if SIBYTE_HDR_FEATURE_EXACT(chip,pass) + * + * Same as SIBYTE_HDR_FEATURE, but only true for the named + * revision of the named chip type. (Note that this CANNOT + * be used to verify that you're compiling only for that + * particular chip/revision. It will be true any time this + * chip/revision is included in SIBYTE_HDR_FEATURES.) + * + * #if SIBYTE_HDR_FEATURE_CHIP(chip) + * + * True if header features for (any revision of) that chip type + * are enabled in SIBYTE_HDR_FEATURES. (Use this to bracket + * #defines for features specific to a given chip type.) + * + * Mask values currently include room for additional revisions of each + * chip type, but can be renumbered at will. Note that they MUST fit + * into 31 bits and may not include C type constructs, for safe use in + * CPP conditionals. Bit positions within chip types DO indicate + * ordering, so be careful when adding support for new minor revs. + ********************************************************************* */ + +#define SIBYTE_HDR_FMASK_1250_ALL 0x00000ff +#define SIBYTE_HDR_FMASK_1250_PASS1 0x0000001 +#define SIBYTE_HDR_FMASK_1250_PASS2 0x0000002 + +#define SIBYTE_HDR_FMASK_112x_ALL 0x0000f00 +#define SIBYTE_HDR_FMASK_112x_PASS1 0x0000100 +#define SIBYTE_HDR_FMASK_112x_PASS3 0x0000200 + +/* Bit mask for chip/revision. (use _ALL for all revisions of a chip). */ +#define SIBYTE_HDR_FMASK(chip, pass) \ + (SIBYTE_HDR_FMASK_ ## chip ## _ ## pass) +#define SIBYTE_HDR_FMASK_ALLREVS(chip) \ + (SIBYTE_HDR_FMASK_ ## chip ## _ALL) + +#define SIBYTE_HDR_FMASK_ALL \ + (SIBYTE_HDR_FMASK_1250_ALL | SIBYTE_HDR_FMASK_112x_ALL) + +#ifndef SIBYTE_HDR_FEATURES +#define SIBYTE_HDR_FEATURES SIBYTE_HDR_FMASK_ALL +#endif + + +/* Bit mask for revisions of chip exclusively before the named revision. */ +#define SIBYTE_HDR_FMASK_BEFORE(chip, pass) \ + ((SIBYTE_HDR_FMASK(chip, pass) - 1) & SIBYTE_HDR_FMASK_ALLREVS(chip)) + +/* Bit mask for revisions of chip exclusively after the named revision. */ +#define SIBYTE_HDR_FMASK_AFTER(chip, pass) \ + (~(SIBYTE_HDR_FMASK(chip, pass) \ + | (SIBYTE_HDR_FMASK(chip, pass) - 1)) & SIBYTE_HDR_FMASK_ALLREVS(chip)) + + +/* True if header features enabled for (any revision of) that chip type. */ +#define SIBYTE_HDR_FEATURE_CHIP(chip) \ + (!! (SIBYTE_HDR_FMASK_ALLREVS(chip) & SIBYTE_HDR_FEATURES)) + +/* True if header features enabled for that rev or later, inclusive. */ +#define SIBYTE_HDR_FEATURE(chip, pass) \ + (!! ((SIBYTE_HDR_FMASK(chip, pass) \ + | SIBYTE_HDR_FMASK_AFTER(chip, pass)) & SIBYTE_HDR_FEATURES)) + +/* True if header features enabled for exactly that rev. */ +#define SIBYTE_HDR_FEATURE_EXACT(chip, pass) \ + (!! (SIBYTE_HDR_FMASK(chip, pass) & SIBYTE_HDR_FEATURES)) + +/* True if header features enabled for that rev or before, inclusive. */ +#define SIBYTE_HDR_FEATURE_UP_TO(chip, pass) \ + (!! ((SIBYTE_HDR_FMASK(chip, pass) \ + | SIBYTE_HDR_FMASK_BEFORE(chip, pass)) & SIBYTE_HDR_FEATURES)) + + +/* ********************************************************************* + * Naming schemes for constants in these files: + * + * M_xxx MASK constant (identifies bits in a register). + * For multi-bit fields, all bits in the field will + * be set. + * + * K_xxx "Code" constant (value for data in a multi-bit + * field). The value is right justified. + * + * V_xxx "Value" constant. This is the same as the + * corresponding "K_xxx" constant, except it is + * shifted to the correct position in the register. + * + * S_xxx SHIFT constant. This is the number of bits that + * a field value (code) needs to be shifted + * (towards the left) to put the value in the right + * position for the register. + * + * A_xxx ADDRESS constant. This will be a physical + * address. Use the PHYS_TO_K1 macro to generate + * a K1SEG address. + * + * R_xxx RELATIVE offset constant. This is an offset from + * an A_xxx constant (usually the first register in + * a group). + * + * G_xxx(X) GET value. This macro obtains a multi-bit field + * from a register, masks it, and shifts it to + * the bottom of the register (retrieving a K_xxx + * value, for example). + * + * V_xxx(X) VALUE. This macro computes the value of a + * K_xxx constant shifted to the correct position + * in the register. + ********************************************************************* */ + + + + +/* + * Cast to 64-bit number. Presumably the syntax is different in + * assembly language. + * + * Note: you'll need to define uint32_t and uint64_t in your headers. + */ + +#if !defined(__ASSEMBLER__) +#define _SB_MAKE64(x) ((uint64_t)(x)) +#define _SB_MAKE32(x) ((uint32_t)(x)) +#else +#define _SB_MAKE64(x) (x) +#define _SB_MAKE32(x) (x) +#endif + + +/* + * Make a mask for 1 bit at position 'n' + */ + +#define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n)) +#define _SB_MAKEMASK1_32(n) (_SB_MAKE32(1) << _SB_MAKE32(n)) + +/* + * Make a mask for 'v' bits at position 'n' + */ + +#define _SB_MAKEMASK(v,n) (_SB_MAKE64((_SB_MAKE64(1)<<(v))-1) << _SB_MAKE64(n)) +#define _SB_MAKEMASK_32(v,n) (_SB_MAKE32((_SB_MAKE32(1)<<(v))-1) << _SB_MAKE32(n)) + +/* + * Make a value at 'v' at bit position 'n' + */ + +#define _SB_MAKEVALUE(v,n) (_SB_MAKE64(v) << _SB_MAKE64(n)) +#define _SB_MAKEVALUE_32(v,n) (_SB_MAKE32(v) << _SB_MAKE32(n)) + +#define _SB_GETVALUE(v,n,m) ((_SB_MAKE64(v) & _SB_MAKE64(m)) >> _SB_MAKE64(n)) +#define _SB_GETVALUE_32(v,n,m) ((_SB_MAKE32(v) & _SB_MAKE32(m)) >> _SB_MAKE32(n)) + +/* + * Macros to read/write on-chip registers + * XXX should we do the PHYS_TO_K1 here? + */ + + +#if !defined(__ASSEMBLER__) +#define SBWRITECSR(csr,val) *((volatile uint64_t *) PHYS_TO_K1(csr)) = (val) +#define SBREADCSR(csr) (*((volatile uint64_t *) PHYS_TO_K1(csr))) +#endif /* __ASSEMBLER__ */ + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_dma.h b/include/asm-mips64/sibyte/sb1250_dma.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_dma.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,594 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * DMA definitions File: sb1250_dma.h + * + * This module contains constants and macros useful for + * programming the SB1250's DMA controllers, both the data mover + * and the Ethernet DMA. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_DMA_H +#define _SB1250_DMA_H + + +#include "sb1250_defs.h" + +/* ********************************************************************* + * DMA Registers + ********************************************************************* */ + +/* + * Ethernet and Serial DMA Configuration Register 0 (Table 7-4) + * Registers: DMA_CONFIG0_MAC_x_RX_CH_0 + * Registers: DMA_CONFIG0_MAC_x_TX_CH_0 + * Registers: DMA_CONFIG0_SER_x_RX + * Registers: DMA_CONFIG0_SER_x_TX + */ + + +#define M_DMA_DROP _SB_MAKEMASK1(0) + +#define M_DMA_CHAIN_SEL _SB_MAKEMASK1(1) +#define M_DMA_RESERVED1 _SB_MAKEMASK1(2) + +#define S_DMA_DESC_TYPE _SB_MAKE64(1) +#define M_DMA_DESC_TYPE _SB_MAKE64(2,S_DMA_DESC_TYPE) +#define V_DMA_DESC_TYPE(x) _SB_MAKEVALUE(x,S_DMA_DESC_TYPE) +#define G_DMA_DESC_TYPE(x) _SB_GETVALUE(x,S_DMA_DESC_TYPE,M_DMA_DESC_TYPE) + +#define K_DMA_DESC_TYPE_RING_AL 0 +#define K_DMA_DESC_TYPE_CHAIN_AL 1 + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define K_DMA_DESC_TYPE_RING_UAL_WI 2 +#define K_DMA_DESC_TYPE_RING_UAL_RMW 3 +#endif + +#define M_DMA_EOP_INT_EN _SB_MAKEMASK1(3) +#define M_DMA_HWM_INT_EN _SB_MAKEMASK1(4) +#define M_DMA_LWM_INT_EN _SB_MAKEMASK1(5) +#define M_DMA_TBX_EN _SB_MAKEMASK1(6) +#define M_DMA_TDX_EN _SB_MAKEMASK1(7) + +#define S_DMA_INT_PKTCNT _SB_MAKE64(8) +#define M_DMA_INT_PKTCNT _SB_MAKEMASK(8,S_DMA_INT_PKTCNT) +#define V_DMA_INT_PKTCNT(x) _SB_MAKEVALUE(x,S_DMA_INT_PKTCNT) +#define G_DMA_INT_PKTCNT(x) _SB_GETVALUE(x,S_DMA_INT_PKTCNT,M_DMA_INT_PKTCNT) + +#define S_DMA_RINGSZ _SB_MAKE64(16) +#define M_DMA_RINGSZ _SB_MAKEMASK(16,S_DMA_RINGSZ) +#define V_DMA_RINGSZ(x) _SB_MAKEVALUE(x,S_DMA_RINGSZ) +#define G_DMA_RINGSZ(x) _SB_GETVALUE(x,S_DMA_RINGSZ,M_DMA_RINGSZ) + +#define S_DMA_HIGH_WATERMARK _SB_MAKE64(32) +#define M_DMA_HIGH_WATERMARK _SB_MAKEMASK(16,S_DMA_HIGH_WATERMARK) +#define V_DMA_HIGH_WATERMARK(x) _SB_MAKEVALUE(x,S_DMA_HIGH_WATERMARK) +#define G_DMA_HIGH_WATERMARK(x) _SB_GETVALUE(x,S_DMA_HIGH_WATERMARK,M_DMA_HIGH_WATERMARK) + +#define S_DMA_LOW_WATERMARK _SB_MAKE64(48) +#define M_DMA_LOW_WATERMARK _SB_MAKEMASK(16,S_DMA_LOW_WATERMARK) +#define V_DMA_LOW_WATERMARK(x) _SB_MAKEVALUE(x,S_DMA_LOW_WATERMARK) +#define G_DMA_LOW_WATERMARK(x) _SB_GETVALUE(x,S_DMA_LOW_WATERMARK,M_DMA_LOW_WATERMARK) + +/* + * Ethernet and Serial DMA Configuration Register 1 (Table 7-5) + * Registers: DMA_CONFIG1_MAC_x_RX_CH_0 + * Registers: DMA_CONFIG1_DMA_x_TX_CH_0 + * Registers: DMA_CONFIG1_SER_x_RX + * Registers: DMA_CONFIG1_SER_x_TX + */ + +#define M_DMA_HDR_CF_EN _SB_MAKEMASK1(0) +#define M_DMA_ASIC_XFR_EN _SB_MAKEMASK1(1) +#define M_DMA_PRE_ADDR_EN _SB_MAKEMASK1(2) +#define M_DMA_FLOW_CTL_EN _SB_MAKEMASK1(3) +#define M_DMA_NO_DSCR_UPDT _SB_MAKEMASK1(4) +#define M_DMA_L2CA _SB_MAKEMASK1(5) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define M_DMA_RX_XTRA_STATUS _SB_MAKEMASK1(6) +#define M_DMA_TX_CPU_PAUSE _SB_MAKEMASK1(6) +#define M_DMA_TX_FC_PAUSE_EN _SB_MAKEMASK1(7) +#endif + +#define M_DMA_MBZ1 _SB_MAKEMASK(6,15) + +#define S_DMA_HDR_SIZE _SB_MAKE64(21) +#define M_DMA_HDR_SIZE _SB_MAKEMASK(9,S_DMA_HDR_SIZE) +#define V_DMA_HDR_SIZE(x) _SB_MAKEVALUE(x,S_DMA_HDR_SIZE) +#define G_DMA_HDR_SIZE(x) _SB_GETVALUE(x,S_DMA_HDR_SIZE,M_DMA_HDR_SIZE) + +#define M_DMA_MBZ2 _SB_MAKEMASK(5,32) + +#define S_DMA_ASICXFR_SIZE _SB_MAKE64(37) +#define M_DMA_ASICXFR_SIZE _SB_MAKEMASK(9,S_DMA_ASICXFR_SIZE) +#define V_DMA_ASICXFR_SIZE(x) _SB_MAKEVALUE(x,S_DMA_ASICXFR_SIZE) +#define G_DMA_ASICXFR_SIZE(x) _SB_GETVALUE(x,S_DMA_ASICXFR_SIZE,M_DMA_ASICXFR_SIZE) + +#define S_DMA_INT_TIMEOUT _SB_MAKE64(48) +#define M_DMA_INT_TIMEOUT _SB_MAKEMASK(16,S_DMA_INT_TIMEOUT) +#define V_DMA_INT_TIMEOUT(x) _SB_MAKEVALUE(x,S_DMA_INT_TIMEOUT) +#define G_DMA_INT_TIMEOUT(x) _SB_GETVALUE(x,S_DMA_INT_TIMEOUT,M_DMA_INT_TIMEOUT) + +/* + * Ethernet and Serial DMA Descriptor base address (Table 7-6) + */ + +#define M_DMA_DSCRBASE_MBZ _SB_MAKEMASK(4,0) + + +/* + * ASIC Mode Base Address (Table 7-7) + */ + +#define M_DMA_ASIC_BASE_MBZ _SB_MAKEMASK(20,0) + +/* + * DMA Descriptor Count Registers (Table 7-8) + */ + +/* No bitfields */ + + +/* + * Current Descriptor Address Register (Table 7-11) + */ + +#define S_DMA_CURDSCR_ADDR _SB_MAKE64(0) +#define M_DMA_CURDSCR_ADDR _SB_MAKEMASK(40,S_DMA_CURDSCR_ADDR) +#define S_DMA_CURDSCR_COUNT _SB_MAKE64(40) +#define M_DMA_CURDSCR_COUNT _SB_MAKEMASK(16,S_DMA_CURDSCR_COUNT) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define M_DMA_TX_CH_PAUSE_ON _SB_MAKEMASK1(56) +#endif + +/* + * Receive Packet Drop Registers + */ +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_OODLOST_RX _SB_MAKE64(0) +#define M_DMA_OODLOST_RX _SB_MAKEMASK(16,S_DMA_OODLOST_RX) +#define G_DMA_OODLOST_RX(x) _SB_GETVALUE(x,S_DMA_OODLOST_RX,M_DMA_OODLOST_RX) + +#define S_DMA_EOP_COUNT_RX _SB_MAKE64(16) +#define M_DMA_EOP_COUNT_RX _SB_MAKEMASK(8,S_DMA_EOP_COUNT_RX) +#define G_DMA_EOP_COUNT_RX(x) _SB_GETVALUE(x,S_DMA_EOP_COUNT_RX,M_DMA_EOP_COUNT_RX) +#endif + +/* ********************************************************************* + * DMA Descriptors + ********************************************************************* */ + +/* + * Descriptor doubleword "A" (Table 7-12) + */ + +#define S_DMA_DSCRA_OFFSET _SB_MAKE64(0) +#define M_DMA_DSCRA_OFFSET _SB_MAKEMASK(5,S_DMA_DSCRA_OFFSET) +#define V_DMA_DSCRA_OFFSET(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_OFFSET) +#define G_DMA_DSCRA_OFFSET(x) _SB_GETVALUE(x,S_DMA_DSCRA_OFFSET,M_DMA_DSCRA_OFFSET) + +/* Note: Don't shift the address over, just mask it with the mask below */ +#define S_DMA_DSCRA_A_ADDR _SB_MAKE64(5) +#define M_DMA_DSCRA_A_ADDR _SB_MAKEMASK(35,S_DMA_DSCRA_A_ADDR) + +#define M_DMA_DSCRA_A_ADDR_OFFSET (M_DMA_DSCRA_OFFSET | M_DMA_DSCRA_A_ADDR) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRA_A_ADDR_UA _SB_MAKE64(0) +#define M_DMA_DSCRA_A_ADDR_UA _SB_MAKEMASK(40,S_DMA_DSCRA_A_ADDR_UA) +#endif + +#define S_DMA_DSCRA_A_SIZE _SB_MAKE64(40) +#define M_DMA_DSCRA_A_SIZE _SB_MAKEMASK(9,S_DMA_DSCRA_A_SIZE) +#define V_DMA_DSCRA_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_A_SIZE) +#define G_DMA_DSCRA_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRA_A_SIZE,M_DMA_DSCRA_A_SIZE) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRA_DSCR_CNT _SB_MAKE64(40) +#define M_DMA_DSCRA_DSCR_CNT _SB_MAKEMASK(8,S_DMA_DSCRA_DSCR_CNT) +#define G_DMA_DSCRA_DSCR_CNT(x) _SB_GETVALUE(x,S_DMA_DSCRA_DSCR_CNT,M_DMA_DSCRA_DSCR_CNT) +#endif + +#define M_DMA_DSCRA_INTERRUPT _SB_MAKEMASK1(49) +#define M_DMA_DSCRA_OFFSETB _SB_MAKEMASK1(50) + +#define S_DMA_DSCRA_STATUS _SB_MAKE64(51) +#define M_DMA_DSCRA_STATUS _SB_MAKEMASK(13,S_DMA_DSCRA_STATUS) +#define V_DMA_DSCRA_STATUS(x) _SB_MAKEVALUE(x,S_DMA_DSCRA_STATUS) +#define G_DMA_DSCRA_STATUS(x) _SB_GETVALUE(x,S_DMA_DSCRA_STATUS,M_DMA_DSCRA_STATUS) + +/* + * Descriptor doubleword "B" (Table 7-13) + */ + + +#define S_DMA_DSCRB_OPTIONS _SB_MAKE64(0) +#define M_DMA_DSCRB_OPTIONS _SB_MAKEMASK(4,S_DMA_DSCRB_OPTIONS) +#define V_DMA_DSCRB_OPTIONS(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_OPTIONS) +#define G_DMA_DSCRB_OPTIONS(x) _SB_GETVALUE(x,S_DMA_DSCRB_OPTIONS,M_DMA_DSCRB_OPTIONS) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRB_A_SIZE _SB_MAKE64(8) +#define M_DMA_DSCRB_A_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_A_SIZE) +#define V_DMA_DSCRB_A_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_A_SIZE) +#define G_DMA_DSCRB_A_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_A_SIZE,M_DMA_DSCRB_A_SIZE) +#endif + +#define R_DMA_DSCRB_ADDR _SB_MAKE64(0x10) + +/* Note: Don't shift the address over, just mask it with the mask below */ +#define S_DMA_DSCRB_B_ADDR _SB_MAKE64(5) +#define M_DMA_DSCRB_B_ADDR _SB_MAKEMASK(35,S_DMA_DSCRB_B_ADDR) + +#define S_DMA_DSCRB_B_SIZE _SB_MAKE64(40) +#define M_DMA_DSCRB_B_SIZE _SB_MAKEMASK(9,S_DMA_DSCRB_B_SIZE) +#define V_DMA_DSCRB_B_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_B_SIZE) +#define G_DMA_DSCRB_B_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_B_SIZE,M_DMA_DSCRB_B_SIZE) + +#define M_DMA_DSCRB_B_VALID _SB_MAKEMASK1(49) + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define S_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKE64(48) +#define M_DMA_DSCRB_PKT_SIZE_MSB _SB_MAKEMASK(2,S_DMA_DSCRB_PKT_SIZE_MSB) +#define V_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB) +#define G_DMA_DSCRB_PKT_SIZE_MSB(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE_MSB,M_DMA_DSCRB_PKT_SIZE_MSB) +#endif + +#define S_DMA_DSCRB_PKT_SIZE _SB_MAKE64(50) +#define M_DMA_DSCRB_PKT_SIZE _SB_MAKEMASK(14,S_DMA_DSCRB_PKT_SIZE) +#define V_DMA_DSCRB_PKT_SIZE(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_PKT_SIZE) +#define G_DMA_DSCRB_PKT_SIZE(x) _SB_GETVALUE(x,S_DMA_DSCRB_PKT_SIZE,M_DMA_DSCRB_PKT_SIZE) + +/* + * from pass2 some bits in dscr_b are also used for rx status + */ +#define S_DMA_DSCRB_STATUS _SB_MAKE64(0) +#define M_DMA_DSCRB_STATUS _SB_MAKEMASK(1,S_DMA_DSCRB_STATUS) +#define V_DMA_DSCRB_STATUS(x) _SB_MAKEVALUE(x,S_DMA_DSCRB_STATUS) +#define G_DMA_DSCRB_STATUS(x) _SB_GETVALUE(x,S_DMA_DSCRB_STATUS,M_DMA_DSCRB_STATUS) + +/* + * Ethernet Descriptor Status Bits (Table 7-15) + */ + +#define M_DMA_ETHRX_BADIP4CS _SB_MAKEMASK1(51) +#define M_DMA_ETHRX_DSCRERR _SB_MAKEMASK1(52) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +/* Note: BADTCPCS is actually in DSCR_B options field */ +#define M_DMA_ETHRX_BADTCPCS _SB_MAKEMASK1(0) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS3) +#define M_DMA_ETH_VLAN_FLAG _SB_MAKEMASK1(1) +#define M_DMA_ETH_CRC_FLAG _SB_MAKEMASK1(2) +#endif + +#define S_DMA_ETHRX_RXCH 53 +#define M_DMA_ETHRX_RXCH _SB_MAKEMASK(2,S_DMA_ETHRX_RXCH) +#define V_DMA_ETHRX_RXCH(x) _SB_MAKEVALUE(x,S_DMA_ETHRX_RXCH) +#define G_DMA_ETHRX_RXCH(x) _SB_GETVALUE(x,S_DMA_ETHRX_RXCH,M_DMA_ETHRX_RXCH) + +#define S_DMA_ETHRX_PKTTYPE 55 +#define M_DMA_ETHRX_PKTTYPE _SB_MAKEMASK(3,S_DMA_ETHRX_PKTTYPE) +#define V_DMA_ETHRX_PKTTYPE(x) _SB_MAKEVALUE(x,S_DMA_ETHRX_PKTTYPE) +#define G_DMA_ETHRX_PKTTYPE(x) _SB_GETVALUE(x,S_DMA_ETHRX_PKTTYPE,M_DMA_ETHRX_PKTTYPE) + +#define K_DMA_ETHRX_PKTTYPE_IPV4 0 +#define K_DMA_ETHRX_PKTTYPE_ARPV4 1 +#define K_DMA_ETHRX_PKTTYPE_802 2 +#define K_DMA_ETHRX_PKTTYPE_OTHER 3 +#define K_DMA_ETHRX_PKTTYPE_USER0 4 +#define K_DMA_ETHRX_PKTTYPE_USER1 5 +#define K_DMA_ETHRX_PKTTYPE_USER2 6 +#define K_DMA_ETHRX_PKTTYPE_USER3 7 + +#define M_DMA_ETHRX_MATCH_HASH _SB_MAKEMASK1(58) +#define M_DMA_ETHRX_MATCH_EXACT _SB_MAKEMASK1(59) +#define M_DMA_ETHRX_BCAST _SB_MAKEMASK1(60) +#define M_DMA_ETHRX_MCAST _SB_MAKEMASK1(61) +#define M_DMA_ETHRX_BAD _SB_MAKEMASK1(62) +#define M_DMA_ETHRX_SOP _SB_MAKEMASK1(63) + +/* + * Ethernet Transmit Status Bits (Table 7-16) + */ + +#define M_DMA_ETHTX_SOP _SB_MAKEMASK1(63) + +/* + * Ethernet Transmit Options (Table 7-17) + */ + +#define K_DMA_ETHTX_NOTSOP _SB_MAKE64(0x00) +#define K_DMA_ETHTX_APPENDCRC _SB_MAKE64(0x01) +#define K_DMA_ETHTX_REPLACECRC _SB_MAKE64(0x02) +#define K_DMA_ETHTX_APPENDCRC_APPENDPAD _SB_MAKE64(0x03) +#define K_DMA_ETHTX_APPENDVLAN_REPLACECRC _SB_MAKE64(0x04) +#define K_DMA_ETHTX_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x05) +#define K_DMA_ETHTX_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x6) +#define K_DMA_ETHTX_NOMODS _SB_MAKE64(0x07) +#define K_DMA_ETHTX_RESERVED1 _SB_MAKE64(0x08) +#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC _SB_MAKE64(0x09) +#define K_DMA_ETHTX_REPLACESADDR_REPLACECRC _SB_MAKE64(0x0A) +#define K_DMA_ETHTX_REPLACESADDR_APPENDCRC_APPENDPAD _SB_MAKE64(0x0B) +#define K_DMA_ETHTX_REPLACESADDR_APPENDVLAN_REPLACECRC _SB_MAKE64(0x0C) +#define K_DMA_ETHTX_REPLACESADDR_REMOVEVLAN_REPLACECRC _SB_MAKE64(0x0D) +#define K_DMA_ETHTX_REPLACESADDR_REPLACEVLAN_REPLACECRC _SB_MAKE64(0x0E) +#define K_DMA_ETHTX_RESERVED2 _SB_MAKE64(0x0F) + +/* + * Serial Receive Options (Table 7-18) + */ +#define M_DMA_SERRX_CRC_ERROR _SB_MAKEMASK1(56) +#define M_DMA_SERRX_ABORT _SB_MAKEMASK1(57) +#define M_DMA_SERRX_OCTET_ERROR _SB_MAKEMASK1(58) +#define M_DMA_SERRX_LONGFRAME_ERROR _SB_MAKEMASK1(59) +#define M_DMA_SERRX_SHORTFRAME_ERROR _SB_MAKEMASK1(60) +#define M_DMA_SERRX_OVERRUN_ERROR _SB_MAKEMASK1(61) +#define M_DMA_SERRX_GOOD _SB_MAKEMASK1(62) +#define M_DMA_SERRX_SOP _SB_MAKEMASK1(63) + +/* + * Serial Transmit Status Bits (Table 7-20) + */ + +#define M_DMA_SERTX_FLAG _SB_MAKEMASK1(63) + +/* + * Serial Transmit Options (Table 7-21) + */ + +#define K_DMA_SERTX_RESERVED _SB_MAKEMASK1(0) +#define K_DMA_SERTX_APPENDCRC _SB_MAKEMASK1(1) +#define K_DMA_SERTX_APPENDPAD _SB_MAKEMASK1(2) +#define K_DMA_SERTX_ABORT _SB_MAKEMASK1(3) + + +/* ********************************************************************* + * Data Mover Registers + ********************************************************************* */ + +/* + * Data Mover Descriptor Base Address Register (Table 7-22) + * Register: DM_DSCR_BASE_0 + * Register: DM_DSCR_BASE_1 + * Register: DM_DSCR_BASE_2 + * Register: DM_DSCR_BASE_3 + */ + +#define M_DM_DSCR_BASE_MBZ _SB_MAKEMASK(4,0) + +/* Note: Just mask the base address and then OR it in. */ +#define S_DM_DSCR_BASE_ADDR _SB_MAKE64(4) +#define M_DM_DSCR_BASE_ADDR _SB_MAKEMASK(36,S_DM_DSCR_BASE_ADDR) + +#define S_DM_DSCR_BASE_RINGSZ _SB_MAKE64(40) +#define M_DM_DSCR_BASE_RINGSZ _SB_MAKEMASK(16,S_DM_DSCR_BASE_RINGSZ) +#define V_DM_DSCR_BASE_RINGSZ(x) _SB_MAKEVALUE(x,S_DM_DSCR_BASE_RINGSZ) +#define G_DM_DSCR_BASE_RINGSZ(x) _SB_GETVALUE(x,S_DM_DSCR_BASE_RINGSZ,M_DM_DSCR_BASE_RINGSZ) + +#define S_DM_DSCR_BASE_PRIORITY _SB_MAKE64(56) +#define M_DM_DSCR_BASE_PRIORITY _SB_MAKEMASK(3,S_DM_DSCR_BASE_PRIORITY) +#define V_DM_DSCR_BASE_PRIORITY(x) _SB_MAKEVALUE(x,S_DM_DSCR_BASE_PRIORITY) +#define G_DM_DSCR_BASE_PRIORITY(x) _SB_GETVALUE(x,S_DM_DSCR_BASE_PRIORITY,M_DM_DSCR_BASE_PRIORITY) + +#define K_DM_DSCR_BASE_PRIORITY_1 0 +#define K_DM_DSCR_BASE_PRIORITY_2 1 +#define K_DM_DSCR_BASE_PRIORITY_4 2 +#define K_DM_DSCR_BASE_PRIORITY_8 3 +#define K_DM_DSCR_BASE_PRIORITY_16 4 + +#define M_DM_DSCR_BASE_ACTIVE _SB_MAKEMASK1(59) +#define M_DM_DSCR_BASE_INTERRUPT _SB_MAKEMASK1(60) +#define M_DM_DSCR_BASE_RESET _SB_MAKEMASK1(61) /* write register */ +#define M_DM_DSCR_BASE_ERROR _SB_MAKEMASK1(61) /* read register */ +#define M_DM_DSCR_BASE_ABORT _SB_MAKEMASK1(62) +#define M_DM_DSCR_BASE_ENABL _SB_MAKEMASK1(63) + +/* + * Data Mover Descriptor Count Register (Table 7-25) + */ + +/* no bitfields */ + +/* + * Data Mover Current Descriptor Address (Table 7-24) + * Register: DM_CUR_DSCR_ADDR_0 + * Register: DM_CUR_DSCR_ADDR_1 + * Register: DM_CUR_DSCR_ADDR_2 + * Register: DM_CUR_DSCR_ADDR_3 + */ + +#define S_DM_CUR_DSCR_DSCR_ADDR _SB_MAKE64(0) +#define M_DM_CUR_DSCR_DSCR_ADDR _SB_MAKEMASK(40,S_DM_CUR_DSCR_DSCR_ADDR) + +#define S_DM_CUR_DSCR_DSCR_COUNT _SB_MAKE64(48) +#define M_DM_CUR_DSCR_DSCR_COUNT _SB_MAKEMASK(16,S_DM_CUR_DSCR_DSCR_COUNT) +#define V_DM_CUR_DSCR_DSCR_COUNT(r) _SB_MAKEVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT) +#define G_DM_CUR_DSCR_DSCR_COUNT(r) _SB_GETVALUE(r,S_DM_CUR_DSCR_DSCR_COUNT,\ + M_DM_CUR_DSCR_DSCR_COUNT) + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Data Mover Channel Partial Result Registers + * Register: DM_PARTIAL_0 + * Register: DM_PARTIAL_1 + * Register: DM_PARTIAL_2 + * Register: DM_PARTIAL_3 + */ +#define S_DM_PARTIAL_CRC_PARTIAL _SB_MAKE64(0) +#define M_DM_PARTIAL_CRC_PARTIAL _SB_MAKEMASK(32,S_DM_PARTIAL_CRC_PARTIAL) +#define V_DM_PARTIAL_CRC_PARTIAL(r) _SB_MAKEVALUE(r,S_DM_PARTIAL_CRC_PARTIAL) +#define G_DM_PARTIAL_CRC_PARTIAL(r) _SB_GETVALUE(r,S_DM_PARTIAL_CRC_PARTIAL,\ + M_DM_PARTIAL_CRC_PARTIAL) + +#define S_DM_PARTIAL_TCPCS_PARTIAL _SB_MAKE64(32) +#define M_DM_PARTIAL_TCPCS_PARTIAL _SB_MAKEMASK(16,S_DM_PARTIAL_TCPCS_PARTIAL) +#define V_DM_PARTIAL_TCPCS_PARTIAL(r) _SB_MAKEVALUE(r,S_DM_PARTIAL_TCPCS_PARTIAL) +#define G_DM_PARTIAL_TCPCS_PARTIAL(r) _SB_GETVALUE(r,S_DM_PARTIAL_TCPCS_PARTIAL,\ + M_DM_PARTIAL_TCPCS_PARTIAL) + +#define M_DM_PARTIAL_ODD_BYTE _SB_MAKEMASK1(48) +#endif /* 112x PASS1 */ + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Data Mover CRC Definition Registers + * Register: CRC_DEF_0 + * Register: CRC_DEF_1 + */ +#define S_CRC_DEF_CRC_INIT _SB_MAKE64(0) +#define M_CRC_DEF_CRC_INIT _SB_MAKEMASK(32,S_CRC_DEF_CRC_INIT) +#define V_CRC_DEF_CRC_INIT(r) _SB_MAKEVALUE(r,S_CRC_DEF_CRC_INIT) +#define G_CRC_DEF_CRC_INIT(r) _SB_GETVALUE(r,S_CRC_DEF_CRC_INIT,\ + M_CRC_DEF_CRC_INIT) + +#define S_CRC_DEF_CRC_POLY _SB_MAKE64(32) +#define M_CRC_DEF_CRC_POLY _SB_MAKEMASK(32,S_CRC_DEF_CRC_POLY) +#define V_CRC_DEF_CRC_POLY(r) _SB_MAKEVALUE(r,S_CRC_DEF_CRC_POLY) +#define G_CRC_DEF_CRC_POLY(r) _SB_GETVALUE(r,S_CRC_DEF_CRC_POLY,\ + M_CRC_DEF_CRC_POLY) +#endif /* 112x PASS1 */ + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Data Mover CRC/Checksum Definition Registers + * Register: CTCP_DEF_0 + * Register: CTCP_DEF_1 + */ +#define S_CTCP_DEF_CRC_TXOR _SB_MAKE64(0) +#define M_CTCP_DEF_CRC_TXOR _SB_MAKEMASK(32,S_CTCP_DEF_CRC_TXOR) +#define V_CTCP_DEF_CRC_TXOR(r) _SB_MAKEVALUE(r,S_CTCP_DEF_CRC_TXOR) +#define G_CTCP_DEF_CRC_TXOR(r) _SB_GETVALUE(r,S_CTCP_DEF_CRC_TXOR,\ + M_CTCP_DEF_CRC_TXOR) + +#define S_CTCP_DEF_TCPCS_INIT _SB_MAKE64(32) +#define M_CTCP_DEF_TCPCS_INIT _SB_MAKEMASK(16,S_CTCP_DEF_TCPCS_INIT) +#define V_CTCP_DEF_TCPCS_INIT(r) _SB_MAKEVALUE(r,S_CTCP_DEF_TCPCS_INIT) +#define G_CTCP_DEF_TCPCS_INIT(r) _SB_GETVALUE(r,S_CTCP_DEF_TCPCS_INIT,\ + M_CTCP_DEF_TCPCS_INIT) + +#define S_CTCP_DEF_CRC_WIDTH _SB_MAKE64(48) +#define M_CTCP_DEF_CRC_WIDTH _SB_MAKEMASK(2,S_CTCP_DEF_CRC_WIDTH) +#define V_CTCP_DEF_CRC_WIDTH(r) _SB_MAKEVALUE(r,S_CTCP_DEF_CRC_WIDTH) +#define G_CTCP_DEF_CRC_WIDTH(r) _SB_GETVALUE(r,S_CTCP_DEF_CRC_WIDTH,\ + M_CTCP_DEF_CRC_WIDTH) + +#define K_CTCP_DEF_CRC_WIDTH_4 0 +#define K_CTCP_DEF_CRC_WIDTH_2 1 +#define K_CTCP_DEF_CRC_WIDTH_1 2 + +#define M_CTCP_DEF_CRC_BIT_ORDER _SB_MAKEMASK1(50) +#endif /* 112x PASS1 */ + + +/* + * Data Mover Descriptor Doubleword "A" (Table 7-26) + */ + +#define S_DM_DSCRA_DST_ADDR _SB_MAKE64(0) +#define M_DM_DSCRA_DST_ADDR _SB_MAKEMASK(40,S_DM_DSCRA_DST_ADDR) + +#define M_DM_DSCRA_UN_DEST _SB_MAKEMASK1(40) +#define M_DM_DSCRA_UN_SRC _SB_MAKEMASK1(41) +#define M_DM_DSCRA_INTERRUPT _SB_MAKEMASK1(42) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +#define M_DM_DSCRA_THROTTLE _SB_MAKEMASK1(43) +#endif /* up to 1250 PASS1 */ + +#define S_DM_DSCRA_DIR_DEST _SB_MAKE64(44) +#define M_DM_DSCRA_DIR_DEST _SB_MAKEMASK(2,S_DM_DSCRA_DIR_DEST) +#define V_DM_DSCRA_DIR_DEST(x) _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_DEST) +#define G_DM_DSCRA_DIR_DEST(x) _SB_GETVALUE(x,S_DM_DSCRA_DIR_DEST,M_DM_DSCRA_DIR_DEST) + +#define K_DM_DSCRA_DIR_DEST_INCR 0 +#define K_DM_DSCRA_DIR_DEST_DECR 1 +#define K_DM_DSCRA_DIR_DEST_CONST 2 + +#define V_DM_DSCRA_DIR_DEST_INCR _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_INCR,S_DM_DSCRA_DIR_DEST) +#define V_DM_DSCRA_DIR_DEST_DECR _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_DECR,S_DM_DSCRA_DIR_DEST) +#define V_DM_DSCRA_DIR_DEST_CONST _SB_MAKEVALUE(K_DM_DSCRA_DIR_DEST_CONST,S_DM_DSCRA_DIR_DEST) + +#define S_DM_DSCRA_DIR_SRC _SB_MAKE64(46) +#define M_DM_DSCRA_DIR_SRC _SB_MAKEMASK(2,S_DM_DSCRA_DIR_SRC) +#define V_DM_DSCRA_DIR_SRC(x) _SB_MAKEVALUE(x,S_DM_DSCRA_DIR_SRC) +#define G_DM_DSCRA_DIR_SRC(x) _SB_GETVALUE(x,S_DM_DSCRA_DIR_SRC,M_DM_DSCRA_DIR_SRC) + +#define K_DM_DSCRA_DIR_SRC_INCR 0 +#define K_DM_DSCRA_DIR_SRC_DECR 1 +#define K_DM_DSCRA_DIR_SRC_CONST 2 + +#define V_DM_DSCRA_DIR_SRC_INCR _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_INCR,S_DM_DSCRA_DIR_SRC) +#define V_DM_DSCRA_DIR_SRC_DECR _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_DECR,S_DM_DSCRA_DIR_SRC) +#define V_DM_DSCRA_DIR_SRC_CONST _SB_MAKEVALUE(K_DM_DSCRA_DIR_SRC_CONST,S_DM_DSCRA_DIR_SRC) + + +#define M_DM_DSCRA_ZERO_MEM _SB_MAKEMASK1(48) +#define M_DM_DSCRA_PREFETCH _SB_MAKEMASK1(49) +#define M_DM_DSCRA_L2C_DEST _SB_MAKEMASK1(50) +#define M_DM_DSCRA_L2C_SRC _SB_MAKEMASK1(51) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_DM_DSCRA_RD_BKOFF _SB_MAKEMASK1(52) +#define M_DM_DSCRA_WR_BKOFF _SB_MAKEMASK1(53) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_DM_DSCRA_TCPCS_EN _SB_MAKEMASK1(54) +#define M_DM_DSCRA_TCPCS_RES _SB_MAKEMASK1(55) +#define M_DM_DSCRA_TCPCS_AP _SB_MAKEMASK1(56) +#define M_DM_DSCRA_CRC_EN _SB_MAKEMASK1(57) +#define M_DM_DSCRA_CRC_RES _SB_MAKEMASK1(58) +#define M_DM_DSCRA_CRC_AP _SB_MAKEMASK1(59) +#define M_DM_DSCRA_CRC_DFN _SB_MAKEMASK1(60) +#define M_DM_DSCRA_CRC_XBIT _SB_MAKEMASK1(61) +#endif /* 112x PASS1 */ + +#define M_DM_DSCRA_RESERVED2 _SB_MAKEMASK(3,61) + +/* + * Data Mover Descriptor Doubleword "B" (Table 7-25) + */ + +#define S_DM_DSCRB_SRC_ADDR _SB_MAKE64(0) +#define M_DM_DSCRB_SRC_ADDR _SB_MAKEMASK(40,S_DM_DSCRB_SRC_ADDR) + +#define S_DM_DSCRB_SRC_LENGTH _SB_MAKE64(40) +#define M_DM_DSCRB_SRC_LENGTH _SB_MAKEMASK(20,S_DM_DSCRB_SRC_LENGTH) +#define V_DM_DSCRB_SRC_LENGTH(x) _SB_MAKEVALUE(x,S_DM_DSCRB_SRC_LENGTH) +#define G_DM_DSCRB_SRC_LENGTH(x) _SB_GETVALUE(x,S_DM_DSCRB_SRC_LENGTH,M_DM_DSCRB_SRC_LENGTH) + + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_genbus.h b/include/asm-mips64/sibyte/sb1250_genbus.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_genbus.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,276 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Generic Bus Constants File: sb1250_genbus.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's Generic Bus interface + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_GENBUS_H +#define _SB1250_GENBUS_H + +#include "sb1250_defs.h" + +/* + * Generic Bus Region Configuration Registers (Table 11-4) + */ + +#define S_IO_RDY_ACTIVE 0 +#define M_IO_RDY_ACTIVE _SB_MAKEMASK1(S_IO_RDY_ACTIVE) + +#define S_IO_ENA_RDY 1 +#define M_IO_ENA_RDY _SB_MAKEMASK1(S_IO_ENA_RDY) + +#define S_IO_WIDTH_SEL 2 +#define M_IO_WIDTH_SEL _SB_MAKEMASK(2,S_IO_WIDTH_SEL) +#define K_IO_WIDTH_SEL_1 0 +#define K_IO_WIDTH_SEL_2 1 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define K_IO_WIDTH_SEL_1L 2 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define K_IO_WIDTH_SEL_4 3 +#define V_IO_WIDTH_SEL(x) _SB_MAKEVALUE(x,S_IO_WIDTH_SEL) +#define G_IO_WIDTH_SEL(x) _SB_GETVALUE(x,S_IO_WIDTH_SEL,M_IO_WIDTH_SEL) + +#define S_IO_PARITY_ENA 4 +#define M_IO_PARITY_ENA _SB_MAKEMASK1(S_IO_PARITY_ENA) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_IO_BURST_EN 5 +#define M_IO_BURST_EN _SB_MAKEMASK1(S_IO_BURST_EN) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define S_IO_PARITY_ODD 6 +#define M_IO_PARITY_ODD _SB_MAKEMASK1(S_IO_PARITY_ODD) +#define S_IO_NONMUX 7 +#define M_IO_NONMUX _SB_MAKEMASK1(S_IO_NONMUX) + +#define S_IO_TIMEOUT 8 +#define M_IO_TIMEOUT _SB_MAKEMASK(8,S_IO_TIMEOUT) +#define V_IO_TIMEOUT(x) _SB_MAKEVALUE(x,S_IO_TIMEOUT) +#define G_IO_TIMEOUT(x) _SB_GETVALUE(x,S_IO_TIMEOUT,M_IO_TIMEOUT) + +/* + * Generic Bus Region Size register (Table 11-5) + */ + +#define S_IO_MULT_SIZE 0 +#define M_IO_MULT_SIZE _SB_MAKEMASK(12,S_IO_MULT_SIZE) +#define V_IO_MULT_SIZE(x) _SB_MAKEVALUE(x,S_IO_MULT_SIZE) +#define G_IO_MULT_SIZE(x) _SB_GETVALUE(x,S_IO_MULT_SIZE,M_IO_MULT_SIZE) + +#define S_IO_REGSIZE 16 /* # bits to shift size for this reg */ + +/* + * Generic Bus Region Address (Table 11-6) + */ + +#define S_IO_START_ADDR 0 +#define M_IO_START_ADDR _SB_MAKEMASK(14,S_IO_START_ADDR) +#define V_IO_START_ADDR(x) _SB_MAKEVALUE(x,S_IO_START_ADDR) +#define G_IO_START_ADDR(x) _SB_GETVALUE(x,S_IO_START_ADDR,M_IO_START_ADDR) + +#define S_IO_ADDRBASE 16 /* # bits to shift addr for this reg */ + +/* + * Generic Bus Region 0 Timing Registers (Table 11-7) + */ + +#define S_IO_ALE_WIDTH 0 +#define M_IO_ALE_WIDTH _SB_MAKEMASK(3,S_IO_ALE_WIDTH) +#define V_IO_ALE_WIDTH(x) _SB_MAKEVALUE(x,S_IO_ALE_WIDTH) +#define G_IO_ALE_WIDTH(x) _SB_GETVALUE(x,S_IO_ALE_WIDTH,M_IO_ALE_WIDTH) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_IO_EARLY_CS _SB_MAKEMASK1(3) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_IO_ALE_TO_CS 4 +#define M_IO_ALE_TO_CS _SB_MAKEMASK(2,S_IO_ALE_TO_CS) +#define V_IO_ALE_TO_CS(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_CS) +#define G_IO_ALE_TO_CS(x) _SB_GETVALUE(x,S_IO_ALE_TO_CS,M_IO_ALE_TO_CS) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_IO_BURST_WIDTH _SB_MAKE64(6) +#define M_IO_BURST_WIDTH _SB_MAKEMASK(2,S_IO_BURST_WIDTH) +#define V_IO_BURST_WIDTH(x) _SB_MAKEVALUE(x,S_IO_BURST_WIDTH) +#define G_IO_BURST_WIDTH(x) _SB_GETVALUE(x,S_IO_BURST_WIDTH,M_IO_BURST_WIDTH) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_IO_CS_WIDTH 8 +#define M_IO_CS_WIDTH _SB_MAKEMASK(5,S_IO_CS_WIDTH) +#define V_IO_CS_WIDTH(x) _SB_MAKEVALUE(x,S_IO_CS_WIDTH) +#define G_IO_CS_WIDTH(x) _SB_GETVALUE(x,S_IO_CS_WIDTH,M_IO_CS_WIDTH) + +#define S_IO_RDY_SMPLE 13 +#define M_IO_RDY_SMPLE _SB_MAKEMASK(3,S_IO_RDY_SMPLE) +#define V_IO_RDY_SMPLE(x) _SB_MAKEVALUE(x,S_IO_RDY_SMPLE) +#define G_IO_RDY_SMPLE(x) _SB_GETVALUE(x,S_IO_RDY_SMPLE,M_IO_RDY_SMPLE) + + +/* + * Generic Bus Timing 1 Registers (Table 11-8) + */ + +#define S_IO_ALE_TO_WRITE 0 +#define M_IO_ALE_TO_WRITE _SB_MAKEMASK(3,S_IO_ALE_TO_WRITE) +#define V_IO_ALE_TO_WRITE(x) _SB_MAKEVALUE(x,S_IO_ALE_TO_WRITE) +#define G_IO_ALE_TO_WRITE(x) _SB_GETVALUE(x,S_IO_ALE_TO_WRITE,M_IO_ALE_TO_WRITE) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_IO_RDY_SYNC _SB_MAKEMASK1(3) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_IO_WRITE_WIDTH 4 +#define M_IO_WRITE_WIDTH _SB_MAKEMASK(4,S_IO_WRITE_WIDTH) +#define V_IO_WRITE_WIDTH(x) _SB_MAKEVALUE(x,S_IO_WRITE_WIDTH) +#define G_IO_WRITE_WIDTH(x) _SB_GETVALUE(x,S_IO_WRITE_WIDTH,M_IO_WRITE_WIDTH) + +#define S_IO_IDLE_CYCLE 8 +#define M_IO_IDLE_CYCLE _SB_MAKEMASK(4,S_IO_IDLE_CYCLE) +#define V_IO_IDLE_CYCLE(x) _SB_MAKEVALUE(x,S_IO_IDLE_CYCLE) +#define G_IO_IDLE_CYCLE(x) _SB_GETVALUE(x,S_IO_IDLE_CYCLE,M_IO_IDLE_CYCLE) + +#define S_IO_OE_TO_CS 12 +#define M_IO_OE_TO_CS _SB_MAKEMASK(2,S_IO_OE_TO_CS) +#define V_IO_OE_TO_CS(x) _SB_MAKEVALUE(x,S_IO_OE_TO_CS) +#define G_IO_OE_TO_CS(x) _SB_GETVALUE(x,S_IO_OE_TO_CS,M_IO_OE_TO_CS) + +#define S_IO_CS_TO_OE 14 +#define M_IO_CS_TO_OE _SB_MAKEMASK(2,S_IO_CS_TO_OE) +#define V_IO_CS_TO_OE(x) _SB_MAKEVALUE(x,S_IO_CS_TO_OE) +#define G_IO_CS_TO_OE(x) _SB_GETVALUE(x,S_IO_CS_TO_OE,M_IO_CS_TO_OE) + +/* + * Generic Bus Interrupt Status Register (Table 11-9) + */ + +#define M_IO_CS_ERR_INT _SB_MAKEMASK(0,8) +#define M_IO_CS0_ERR_INT _SB_MAKEMASK1(0) +#define M_IO_CS1_ERR_INT _SB_MAKEMASK1(1) +#define M_IO_CS2_ERR_INT _SB_MAKEMASK1(2) +#define M_IO_CS3_ERR_INT _SB_MAKEMASK1(3) +#define M_IO_CS4_ERR_INT _SB_MAKEMASK1(4) +#define M_IO_CS5_ERR_INT _SB_MAKEMASK1(5) +#define M_IO_CS6_ERR_INT _SB_MAKEMASK1(6) +#define M_IO_CS7_ERR_INT _SB_MAKEMASK1(7) + +#define M_IO_RD_PAR_INT _SB_MAKEMASK1(9) +#define M_IO_TIMEOUT_INT _SB_MAKEMASK1(10) +#define M_IO_ILL_ADDR_INT _SB_MAKEMASK1(11) +#define M_IO_MULT_CS_INT _SB_MAKEMASK1(12) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_IO_COH_ERR _SB_MAKEMASK1(14) +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * PCMCIA configuration register (Table 12-6) + */ + +#define M_PCMCIA_CFG_ATTRMEM _SB_MAKEMASK1(0) +#define M_PCMCIA_CFG_3VEN _SB_MAKEMASK1(1) +#define M_PCMCIA_CFG_5VEN _SB_MAKEMASK1(2) +#define M_PCMCIA_CFG_VPPEN _SB_MAKEMASK1(3) +#define M_PCMCIA_CFG_RESET _SB_MAKEMASK1(4) +#define M_PCMCIA_CFG_APWRONEN _SB_MAKEMASK1(5) +#define M_PCMCIA_CFG_CDMASK _SB_MAKEMASK1(6) +#define M_PCMCIA_CFG_WPMASK _SB_MAKEMASK1(7) +#define M_PCMCIA_CFG_RDYMASK _SB_MAKEMASK1(8) +#define M_PCMCIA_CFG_PWRCTL _SB_MAKEMASK1(9) + +/* + * PCMCIA status register (Table 12-7) + */ + +#define M_PCMCIA_STATUS_CD1 _SB_MAKEMASK1(0) +#define M_PCMCIA_STATUS_CD2 _SB_MAKEMASK1(1) +#define M_PCMCIA_STATUS_VS1 _SB_MAKEMASK1(2) +#define M_PCMCIA_STATUS_VS2 _SB_MAKEMASK1(3) +#define M_PCMCIA_STATUS_WP _SB_MAKEMASK1(4) +#define M_PCMCIA_STATUS_RDY _SB_MAKEMASK1(5) +#define M_PCMCIA_STATUS_3VEN _SB_MAKEMASK1(6) +#define M_PCMCIA_STATUS_5VEN _SB_MAKEMASK1(7) +#define M_PCMCIA_STATUS_CDCHG _SB_MAKEMASK1(8) +#define M_PCMCIA_STATUS_WPCHG _SB_MAKEMASK1(9) +#define M_PCMCIA_STATUS_RDYCHG _SB_MAKEMASK1(10) + +/* + * GPIO Interrupt Type Register (table 13-3) + */ + +#define K_GPIO_INTR_DISABLE 0 +#define K_GPIO_INTR_EDGE 1 +#define K_GPIO_INTR_LEVEL 2 +#define K_GPIO_INTR_SPLIT 3 + +#define S_GPIO_INTR_TYPEX(n) (((n)/2)*2) +#define M_GPIO_INTR_TYPEX(n) _SB_MAKEMASK(2,S_GPIO_INTR_TYPEX(n)) +#define V_GPIO_INTR_TYPEX(n,x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPEX(n)) +#define G_GPIO_INTR_TYPEX(n,x) _SB_GETVALUE(x,S_GPIO_INTR_TYPEX(n),M_GPIO_INTR_TYPEX(n)) + +#define S_GPIO_INTR_TYPE0 0 +#define M_GPIO_INTR_TYPE0 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE0) +#define V_GPIO_INTR_TYPE0(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE0) +#define G_GPIO_INTR_TYPE0(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE0,M_GPIO_INTR_TYPE0) + +#define S_GPIO_INTR_TYPE2 2 +#define M_GPIO_INTR_TYPE2 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE2) +#define V_GPIO_INTR_TYPE2(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE2) +#define G_GPIO_INTR_TYPE2(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE2,M_GPIO_INTR_TYPE2) + +#define S_GPIO_INTR_TYPE4 4 +#define M_GPIO_INTR_TYPE4 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE4) +#define V_GPIO_INTR_TYPE4(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE4) +#define G_GPIO_INTR_TYPE4(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE4,M_GPIO_INTR_TYPE4) + +#define S_GPIO_INTR_TYPE6 6 +#define M_GPIO_INTR_TYPE6 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE6) +#define V_GPIO_INTR_TYPE6(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE6) +#define G_GPIO_INTR_TYPE6(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE6,M_GPIO_INTR_TYPE6) + +#define S_GPIO_INTR_TYPE8 8 +#define M_GPIO_INTR_TYPE8 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE8) +#define V_GPIO_INTR_TYPE8(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE8) +#define G_GPIO_INTR_TYPE8(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE8,M_GPIO_INTR_TYPE8) + +#define S_GPIO_INTR_TYPE10 10 +#define M_GPIO_INTR_TYPE10 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE10) +#define V_GPIO_INTR_TYPE10(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE10) +#define G_GPIO_INTR_TYPE10(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE10,M_GPIO_INTR_TYPE10) + +#define S_GPIO_INTR_TYPE12 12 +#define M_GPIO_INTR_TYPE12 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE12) +#define V_GPIO_INTR_TYPE12(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE12) +#define G_GPIO_INTR_TYPE12(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE12,M_GPIO_INTR_TYPE12) + +#define S_GPIO_INTR_TYPE14 14 +#define M_GPIO_INTR_TYPE14 _SB_MAKEMASK(2,S_GPIO_INTR_TYPE14) +#define V_GPIO_INTR_TYPE14(x) _SB_MAKEVALUE(x,S_GPIO_INTR_TYPE14) +#define G_GPIO_INTR_TYPE14(x) _SB_GETVALUE(x,S_GPIO_INTR_TYPE14,M_GPIO_INTR_TYPE14) + + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_int.h b/include/asm-mips64/sibyte/sb1250_int.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_int.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,247 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Interrupt Mapper definitions File: sb1250_int.h + * + * This module contains constants for manipulating the SB1250's + * interrupt mapper and definitions for the interrupt sources. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_INT_H +#define _SB1250_INT_H + +#include "sb1250_defs.h" + +/* ********************************************************************* + * Interrupt Mapper Constants + ********************************************************************* */ + +/* + * Interrupt sources (Table 4-8, UM 0.2) + * + * First, the interrupt numbers. + */ + +#define K_INT_WATCHDOG_TIMER_0 0 +#define K_INT_WATCHDOG_TIMER_1 1 +#define K_INT_TIMER_0 2 +#define K_INT_TIMER_1 3 +#define K_INT_TIMER_2 4 +#define K_INT_TIMER_3 5 +#define K_INT_SMB_0 6 +#define K_INT_SMB_1 7 +#define K_INT_UART_0 8 +#define K_INT_UART_1 9 +#define K_INT_SER_0 10 +#define K_INT_SER_1 11 +#define K_INT_PCMCIA 12 +#define K_INT_ADDR_TRAP 13 +#define K_INT_PERF_CNT 14 +#define K_INT_TRACE_FREEZE 15 +#define K_INT_BAD_ECC 16 +#define K_INT_COR_ECC 17 +#define K_INT_IO_BUS 18 +#define K_INT_MAC_0 19 +#define K_INT_MAC_1 20 +#define K_INT_MAC_2 21 +#define K_INT_DM_CH_0 22 +#define K_INT_DM_CH_1 23 +#define K_INT_DM_CH_2 24 +#define K_INT_DM_CH_3 25 +#define K_INT_MBOX_0 26 +#define K_INT_MBOX_1 27 +#define K_INT_MBOX_2 28 +#define K_INT_MBOX_3 29 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define K_INT_CYCLE_CP0_INT 30 +#define K_INT_CYCLE_CP1_INT 31 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define K_INT_GPIO_0 32 +#define K_INT_GPIO_1 33 +#define K_INT_GPIO_2 34 +#define K_INT_GPIO_3 35 +#define K_INT_GPIO_4 36 +#define K_INT_GPIO_5 37 +#define K_INT_GPIO_6 38 +#define K_INT_GPIO_7 39 +#define K_INT_GPIO_8 40 +#define K_INT_GPIO_9 41 +#define K_INT_GPIO_10 42 +#define K_INT_GPIO_11 43 +#define K_INT_GPIO_12 44 +#define K_INT_GPIO_13 45 +#define K_INT_GPIO_14 46 +#define K_INT_GPIO_15 47 +#define K_INT_LDT_FATAL 48 +#define K_INT_LDT_NONFATAL 49 +#define K_INT_LDT_SMI 50 +#define K_INT_LDT_NMI 51 +#define K_INT_LDT_INIT 52 +#define K_INT_LDT_STARTUP 53 +#define K_INT_LDT_EXT 54 +#define K_INT_PCI_ERROR 55 +#define K_INT_PCI_INTA 56 +#define K_INT_PCI_INTB 57 +#define K_INT_PCI_INTC 58 +#define K_INT_PCI_INTD 59 +#define K_INT_SPARE_2 60 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define K_INT_MAC_0_CH1 61 +#define K_INT_MAC_1_CH1 62 +#define K_INT_MAC_2_CH1 63 +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * Mask values for each interrupt + */ + +#define M_INT_WATCHDOG_TIMER_0 _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_0) +#define M_INT_WATCHDOG_TIMER_1 _SB_MAKEMASK1(K_INT_WATCHDOG_TIMER_1) +#define M_INT_TIMER_0 _SB_MAKEMASK1(K_INT_TIMER_0) +#define M_INT_TIMER_1 _SB_MAKEMASK1(K_INT_TIMER_1) +#define M_INT_TIMER_2 _SB_MAKEMASK1(K_INT_TIMER_2) +#define M_INT_TIMER_3 _SB_MAKEMASK1(K_INT_TIMER_3) +#define M_INT_SMB_0 _SB_MAKEMASK1(K_INT_SMB_0) +#define M_INT_SMB_1 _SB_MAKEMASK1(K_INT_SMB_1) +#define M_INT_UART_0 _SB_MAKEMASK1(K_INT_UART_0) +#define M_INT_UART_1 _SB_MAKEMASK1(K_INT_UART_1) +#define M_INT_SER_0 _SB_MAKEMASK1(K_INT_SER_0) +#define M_INT_SER_1 _SB_MAKEMASK1(K_INT_SER_1) +#define M_INT_PCMCIA _SB_MAKEMASK1(K_INT_PCMCIA) +#define M_INT_ADDR_TRAP _SB_MAKEMASK1(K_INT_ADDR_TRAP) +#define M_INT_PERF_CNT _SB_MAKEMASK1(K_INT_PERF_CNT) +#define M_INT_TRACE_FREEZE _SB_MAKEMASK1(K_INT_TRACE_FREEZE) +#define M_INT_BAD_ECC _SB_MAKEMASK1(K_INT_BAD_ECC) +#define M_INT_COR_ECC _SB_MAKEMASK1(K_INT_COR_ECC) +#define M_INT_IO_BUS _SB_MAKEMASK1(K_INT_IO_BUS) +#define M_INT_MAC_0 _SB_MAKEMASK1(K_INT_MAC_0) +#define M_INT_MAC_1 _SB_MAKEMASK1(K_INT_MAC_1) +#define M_INT_MAC_2 _SB_MAKEMASK1(K_INT_MAC_2) +#define M_INT_DM_CH_0 _SB_MAKEMASK1(K_INT_DM_CH_0) +#define M_INT_DM_CH_1 _SB_MAKEMASK1(K_INT_DM_CH_1) +#define M_INT_DM_CH_2 _SB_MAKEMASK1(K_INT_DM_CH_2) +#define M_INT_DM_CH_3 _SB_MAKEMASK1(K_INT_DM_CH_3) +#define M_INT_MBOX_0 _SB_MAKEMASK1(K_INT_MBOX_0) +#define M_INT_MBOX_1 _SB_MAKEMASK1(K_INT_MBOX_1) +#define M_INT_MBOX_2 _SB_MAKEMASK1(K_INT_MBOX_2) +#define M_INT_MBOX_3 _SB_MAKEMASK1(K_INT_MBOX_3) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_INT_CYCLE_CP0_INT _SB_MAKEMASK1(K_INT_CYCLE_CP0_INT) +#define M_INT_CYCLE_CP1_INT _SB_MAKEMASK1(K_INT_CYCLE_CP1_INT) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define M_INT_GPIO_0 _SB_MAKEMASK1(K_INT_GPIO_0) +#define M_INT_GPIO_1 _SB_MAKEMASK1(K_INT_GPIO_1) +#define M_INT_GPIO_2 _SB_MAKEMASK1(K_INT_GPIO_2) +#define M_INT_GPIO_3 _SB_MAKEMASK1(K_INT_GPIO_3) +#define M_INT_GPIO_4 _SB_MAKEMASK1(K_INT_GPIO_4) +#define M_INT_GPIO_5 _SB_MAKEMASK1(K_INT_GPIO_5) +#define M_INT_GPIO_6 _SB_MAKEMASK1(K_INT_GPIO_6) +#define M_INT_GPIO_7 _SB_MAKEMASK1(K_INT_GPIO_7) +#define M_INT_GPIO_8 _SB_MAKEMASK1(K_INT_GPIO_8) +#define M_INT_GPIO_9 _SB_MAKEMASK1(K_INT_GPIO_9) +#define M_INT_GPIO_10 _SB_MAKEMASK1(K_INT_GPIO_10) +#define M_INT_GPIO_11 _SB_MAKEMASK1(K_INT_GPIO_11) +#define M_INT_GPIO_12 _SB_MAKEMASK1(K_INT_GPIO_12) +#define M_INT_GPIO_13 _SB_MAKEMASK1(K_INT_GPIO_13) +#define M_INT_GPIO_14 _SB_MAKEMASK1(K_INT_GPIO_14) +#define M_INT_GPIO_15 _SB_MAKEMASK1(K_INT_GPIO_15) +#define M_INT_LDT_FATAL _SB_MAKEMASK1(K_INT_LDT_FATAL) +#define M_INT_LDT_NONFATAL _SB_MAKEMASK1(K_INT_LDT_NONFATAL) +#define M_INT_LDT_SMI _SB_MAKEMASK1(K_INT_LDT_SMI) +#define M_INT_LDT_NMI _SB_MAKEMASK1(K_INT_LDT_NMI) +#define M_INT_LDT_INIT _SB_MAKEMASK1(K_INT_LDT_INIT) +#define M_INT_LDT_STARTUP _SB_MAKEMASK1(K_INT_LDT_STARTUP) +#define M_INT_LDT_EXT _SB_MAKEMASK1(K_INT_LDT_EXT) +#define M_INT_PCI_ERROR _SB_MAKEMASK1(K_INT_PCI_ERROR) +#define M_INT_PCI_INTA _SB_MAKEMASK1(K_INT_PCI_INTA) +#define M_INT_PCI_INTB _SB_MAKEMASK1(K_INT_PCI_INTB) +#define M_INT_PCI_INTC _SB_MAKEMASK1(K_INT_PCI_INTC) +#define M_INT_PCI_INTD _SB_MAKEMASK1(K_INT_PCI_INTD) +#define M_INT_SPARE_2 _SB_MAKEMASK1(K_INT_SPARE_2) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_INT_MAC_0_CH1 _SB_MAKEMASK1(K_INT_MAC_0_CH1) +#define M_INT_MAC_1_CH1 _SB_MAKEMASK1(K_INT_MAC_1_CH1) +#define M_INT_MAC_2_CH1 _SB_MAKEMASK1(K_INT_MAC_2_CH1) +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * Interrupt mappings + */ + +#define K_INT_MAP_I0 0 /* interrupt pins on processor */ +#define K_INT_MAP_I1 1 +#define K_INT_MAP_I2 2 +#define K_INT_MAP_I3 3 +#define K_INT_MAP_I4 4 +#define K_INT_MAP_I5 5 +#define K_INT_MAP_NMI 6 /* nonmaskable */ +#define K_INT_MAP_DINT 7 /* debug interrupt */ + +/* + * LDT Interrupt Set Register (table 4-5) + */ + +#define S_INT_LDT_INTMSG 0 +#define M_INT_LDT_INTMSG _SB_MAKEMASK(3,S_INT_LDT_INTMSG) +#define V_INT_LDT_INTMSG(x) _SB_MAKEVALUE(x,S_INT_LDT_INTMSG) +#define G_INT_LDT_INTMSG(x) _SB_GETVALUE(x,S_INT_LDT_INTMSG,M_INT_LDT_INTMSG) + +#define K_INT_LDT_INTMSG_FIXED 0 +#define K_INT_LDT_INTMSG_ARBITRATED 1 +#define K_INT_LDT_INTMSG_SMI 2 +#define K_INT_LDT_INTMSG_NMI 3 +#define K_INT_LDT_INTMSG_INIT 4 +#define K_INT_LDT_INTMSG_STARTUP 5 +#define K_INT_LDT_INTMSG_EXTINT 6 +#define K_INT_LDT_INTMSG_RESERVED 7 + +#define M_INT_LDT_EDGETRIGGER 0 +#define M_INT_LDT_LEVELTRIGGER _SB_MAKEMASK1(3) + +#define M_INT_LDT_PHYSICALDEST 0 +#define M_INT_LDT_LOGICALDEST _SB_MAKEMASK1(4) + +#define S_INT_LDT_INTDEST 5 +#define M_INT_LDT_INTDEST _SB_MAKEMASK(10,S_INT_LDT_INTDEST) +#define V_INT_LDT_INTDEST(x) _SB_MAKEVALUE(x,S_INT_LDT_INTDEST) +#define G_INT_LDT_INTDEST(x) _SB_GETVALUE(x,S_INT_LDT_INTDEST,M_INT_LDT_INTDEST) + +#define S_INT_LDT_VECTOR 13 +#define M_INT_LDT_VECTOR _SB_MAKEMASK(8,S_INT_LDT_VECTOR) +#define V_INT_LDT_VECTOR(x) _SB_MAKEVALUE(x,S_INT_LDT_VECTOR) +#define G_INT_LDT_VECTOR(x) _SB_GETVALUE(x,S_INT_LDT_VECTOR,M_INT_LDT_VECTOR) + +/* + * Vector format (Table 4-6) + */ + +#define M_LDTVECT_RAISEINT 0x00 +#define M_LDTVECT_RAISEMBOX 0x40 + + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_l2c.h b/include/asm-mips64/sibyte/sb1250_l2c.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_l2c.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,128 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * L2 Cache constants and macros File: sb1250_l2c.h + * + * This module contains constants useful for manipulating the + * level 2 cache. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_L2C_H +#define _SB1250_L2C_H + +#include "sb1250_defs.h" + +/* + * Level 2 Cache Tag register (Table 5-3) + */ + +#define S_L2C_TAG_MBZ 0 +#define M_L2C_TAG_MBZ _SB_MAKEMASK(5,S_L2C_TAG_MBZ) + +#define S_L2C_TAG_INDEX 5 +#define M_L2C_TAG_INDEX _SB_MAKEMASK(12,S_L2C_TAG_INDEX) +#define V_L2C_TAG_INDEX(x) _SB_MAKEVALUE(x,S_L2C_TAG_INDEX) +#define G_L2C_TAG_INDEX(x) _SB_GETVALUE(x,S_L2C_TAG_INDEX,M_L2C_TAG_INDEX) + +#define S_L2C_TAG_TAG 17 +#define M_L2C_TAG_TAG _SB_MAKEMASK(23,S_L2C_TAG_TAG) +#define V_L2C_TAG_TAG(x) _SB_MAKEVALUE(x,S_L2C_TAG_TAG) +#define G_L2C_TAG_TAG(x) _SB_GETVALUE(x,S_L2C_TAG_TAG,M_L2C_TAG_TAG) + +#define S_L2C_TAG_ECC 40 +#define M_L2C_TAG_ECC _SB_MAKEMASK(6,S_L2C_TAG_ECC) +#define V_L2C_TAG_ECC(x) _SB_MAKEVALUE(x,S_L2C_TAG_ECC) +#define G_L2C_TAG_ECC(x) _SB_GETVALUE(x,S_L2C_TAG_ECC,M_L2C_TAG_ECC) + +#define S_L2C_TAG_WAY 46 +#define M_L2C_TAG_WAY _SB_MAKEMASK(2,S_L2C_TAG_WAY) +#define V_L2C_TAG_WAY(x) _SB_MAKEVALUE(x,S_L2C_TAG_WAY) +#define G_L2C_TAG_WAY(x) _SB_GETVALUE(x,S_L2C_TAG_WAY,M_L2C_TAG_WAY) + +#define M_L2C_TAG_DIRTY _SB_MAKEMASK1(48) +#define M_L2C_TAG_VALID _SB_MAKEMASK1(49) + +/* + * Format of level 2 cache management address (table 5-2) + */ + +#define S_L2C_MGMT_INDEX 5 +#define M_L2C_MGMT_INDEX _SB_MAKEMASK(12,S_L2C_MGMT_INDEX) +#define V_L2C_MGMT_INDEX(x) _SB_MAKEVALUE(x,S_L2C_MGMT_INDEX) +#define G_L2C_MGMT_INDEX(x) _SB_GETVALUE(x,S_L2C_MGMT_INDEX,M_L2C_MGMT_INDEX) + +#define S_L2C_MGMT_QUADRANT 15 +#define M_L2C_MGMT_QUADRANT _SB_MAKEMASK(2,S_L2C_MGMT_QUADRANT) +#define V_L2C_MGMT_QUADRANT(x) _SB_MAKEVALUE(x,S_L2C_MGMT_QUADRANT) +#define G_L2C_MGMT_QUADRANT(x) _SB_GETVALUE(x,S_L2C_MGMT_QUADRANT,M_L2C_MGMT_QUADRANT) + +#define S_L2C_MGMT_HALF 16 +#define M_L2C_MGMT_HALF _SB_MAKEMASK(1,S_L2C_MGMT_HALF) + +#define S_L2C_MGMT_WAY 17 +#define M_L2C_MGMT_WAY _SB_MAKEMASK(2,S_L2C_MGMT_WAY) +#define V_L2C_MGMT_WAY(x) _SB_MAKEVALUE(x,S_L2C_MGMT_WAY) +#define G_L2C_MGMT_WAY(x) _SB_GETVALUE(x,S_L2C_MGMT_WAY,M_L2C_MGMT_WAY) + +#define S_L2C_MGMT_TAG 21 +#define M_L2C_MGMT_TAG _SB_MAKEMASK(6,S_L2C_MGMT_TAG) +#define V_L2C_MGMT_TAG(x) _SB_MAKEVALUE(x,S_L2C_MGMT_TAG) +#define G_L2C_MGMT_TAG(x) _SB_GETVALUE(x,S_L2C_MGMT_TAG,M_L2C_MGMT_TAG) + +#define M_L2C_MGMT_DIRTY _SB_MAKEMASK1(19) +#define M_L2C_MGMT_VALID _SB_MAKEMASK1(20) + +#define A_L2C_MGMT_TAG_BASE 0x00D0000000 + +#define L2C_ENTRIES_PER_WAY 4096 +#define L2C_NUM_WAYS 4 + + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * L2 Read Misc. register (A_L2_READ_MISC) + */ +#define S_L2C_MISC_NO_WAY 10 +#define M_L2C_MISC_NO_WAY _SB_MAKEMASK(4,S_L2C_MISC_NO_WAY) +#define V_L2C_MISC_NO_WAY(x) _SB_MAKEVALUE(x,S_L2C_MISC_NO_WAY) +#define G_L2C_MISC_NO_WAY(x) _SB_GETVALUE(x,S_L2C_MISC_NO_WAY,M_L2C_MISC_NO_WAY) + +#define M_L2C_MISC_ECC_CLEANUP_DIS _SB_MAKEMASK1(9) +#define M_L2C_MISC_MC_PRIO_LOW _SB_MAKEMASK1(8) +#define M_L2C_MISC_SOFT_DISABLE_T _SB_MAKEMASK1(7) +#define M_L2C_MISC_SOFT_DISABLE_B _SB_MAKEMASK1(6) +#define M_L2C_MISC_SOFT_DISABLE_R _SB_MAKEMASK1(5) +#define M_L2C_MISC_SOFT_DISABLE_L _SB_MAKEMASK1(4) +#define M_L2C_MISC_SCACHE_DISABLE_T _SB_MAKEMASK1(3) +#define M_L2C_MISC_SCACHE_DISABLE_B _SB_MAKEMASK1(2) +#define M_L2C_MISC_SCACHE_DISABLE_R _SB_MAKEMASK1(1) +#define M_L2C_MISC_SCACHE_DISABLE_L _SB_MAKEMASK1(0) +#endif /* 112x PASS1 */ + + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_ldt.h b/include/asm-mips64/sibyte/sb1250_ldt.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_ldt.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,425 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * LDT constants File: sb1250_ldt.h + * + * This module contains constants and macros to describe + * the LDT interface on the SB1250. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_LDT_H +#define _SB1250_LDT_H + +#include "sb1250_defs.h" + +#define K_LDT_VENDOR_SIBYTE 0x166D +#define K_LDT_DEVICE_SB1250 0x0002 + +/* + * LDT Interface Type 1 (bridge) configuration header + */ + +#define R_LDT_TYPE1_DEVICEID 0x0000 +#define R_LDT_TYPE1_CMDSTATUS 0x0004 +#define R_LDT_TYPE1_CLASSREV 0x0008 +#define R_LDT_TYPE1_DEVHDR 0x000C +#define R_LDT_TYPE1_BAR0 0x0010 /* not used */ +#define R_LDT_TYPE1_BAR1 0x0014 /* not used */ + +#define R_LDT_TYPE1_BUSID 0x0018 /* bus ID register */ +#define R_LDT_TYPE1_SECSTATUS 0x001C /* secondary status / I/O base/limit */ +#define R_LDT_TYPE1_MEMLIMIT 0x0020 +#define R_LDT_TYPE1_PREFETCH 0x0024 +#define R_LDT_TYPE1_PREF_BASE 0x0028 +#define R_LDT_TYPE1_PREF_LIMIT 0x002C +#define R_LDT_TYPE1_IOLIMIT 0x0030 +#define R_LDT_TYPE1_CAPPTR 0x0034 +#define R_LDT_TYPE1_ROMADDR 0x0038 +#define R_LDT_TYPE1_BRCTL 0x003C +#define R_LDT_TYPE1_CMD 0x0040 +#define R_LDT_TYPE1_LINKCTRL 0x0044 +#define R_LDT_TYPE1_LINKFREQ 0x0048 +#define R_LDT_TYPE1_RESERVED1 0x004C +#define R_LDT_TYPE1_SRICMD 0x0050 +#define R_LDT_TYPE1_SRITXNUM 0x0054 +#define R_LDT_TYPE1_SRIRXNUM 0x0058 +#define R_LDT_TYPE1_ERRSTATUS 0x0068 +#define R_LDT_TYPE1_SRICTRL 0x006C +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_LDT_TYPE1_ADDSTATUS 0x0070 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define R_LDT_TYPE1_TXBUFCNT 0x00C8 +#define R_LDT_TYPE1_EXPCRC 0x00DC +#define R_LDT_TYPE1_RXCRC 0x00F0 + + +/* + * LDT Device ID register + */ + +#define S_LDT_DEVICEID_VENDOR 0 +#define M_LDT_DEVICEID_VENDOR _SB_MAKEMASK_32(16,S_LDT_DEVICEID_VENDOR) +#define V_LDT_DEVICEID_VENDOR(x) _SB_MAKEVALUE_32(x,S_LDT_DEVICEID_VENDOR) +#define G_LDT_DEVICEID_VENDOR(x) _SB_GETVALUE_32(x,S_LDT_DEVICEID_VENDOR,M_LDT_DEVICEID_VENDOR) + +#define S_LDT_DEVICEID_DEVICEID 16 +#define M_LDT_DEVICEID_DEVICEID _SB_MAKEMASK_32(16,S_LDT_DEVICEID_DEVICEID) +#define V_LDT_DEVICEID_DEVICEID(x) _SB_MAKEVALUE_32(x,S_LDT_DEVICEID_DEVICEID) +#define G_LDT_DEVICEID_DEVICEID(x) _SB_GETVALUE_32(x,S_LDT_DEVICEID_DEVICEID,M_LDT_DEVICEID_DEVICEID) + + +/* + * LDT Command Register (Table 8-13) + */ + +#define M_LDT_CMD_IOSPACE_EN _SB_MAKEMASK1_32(0) +#define M_LDT_CMD_MEMSPACE_EN _SB_MAKEMASK1_32(1) +#define M_LDT_CMD_MASTER_EN _SB_MAKEMASK1_32(2) +#define M_LDT_CMD_SPECCYC_EN _SB_MAKEMASK1_32(3) +#define M_LDT_CMD_MEMWRINV_EN _SB_MAKEMASK1_32(4) +#define M_LDT_CMD_VGAPALSNP_EN _SB_MAKEMASK1_32(5) +#define M_LDT_CMD_PARERRRESP _SB_MAKEMASK1_32(6) +#define M_LDT_CMD_WAITCYCCTRL _SB_MAKEMASK1_32(7) +#define M_LDT_CMD_SERR_EN _SB_MAKEMASK1_32(8) +#define M_LDT_CMD_FASTB2B_EN _SB_MAKEMASK1_32(9) + +/* + * LDT class and revision registers + */ + +#define S_LDT_CLASSREV_REV 0 +#define M_LDT_CLASSREV_REV _SB_MAKEMASK_32(8,S_LDT_CLASSREV_REV) +#define V_LDT_CLASSREV_REV(x) _SB_MAKEVALUE_32(x,S_LDT_CLASSREV_REV) +#define G_LDT_CLASSREV_REV(x) _SB_GETVALUE_32(x,S_LDT_CLASSREV_REV,M_LDT_CLASSREV_REV) + +#define S_LDT_CLASSREV_CLASS 8 +#define M_LDT_CLASSREV_CLASS _SB_MAKEMASK_32(24,S_LDT_CLASSREV_CLASS) +#define V_LDT_CLASSREV_CLASS(x) _SB_MAKEVALUE_32(x,S_LDT_CLASSREV_CLASS) +#define G_LDT_CLASSREV_CLASS(x) _SB_GETVALUE_32(x,S_LDT_CLASSREV_CLASS,M_LDT_CLASSREV_CLASS) + +#define K_LDT_REV 0x01 +#define K_LDT_CLASS 0x060000 + +/* + * Device Header (offset 0x0C) + */ + +#define S_LDT_DEVHDR_CLINESZ 0 +#define M_LDT_DEVHDR_CLINESZ _SB_MAKEMASK_32(8,S_LDT_DEVHDR_CLINESZ) +#define V_LDT_DEVHDR_CLINESZ(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_CLINESZ) +#define G_LDT_DEVHDR_CLINESZ(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_CLINESZ,M_LDT_DEVHDR_CLINESZ) + +#define S_LDT_DEVHDR_LATTMR 8 +#define M_LDT_DEVHDR_LATTMR _SB_MAKEMASK_32(8,S_LDT_DEVHDR_LATTMR) +#define V_LDT_DEVHDR_LATTMR(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_LATTMR) +#define G_LDT_DEVHDR_LATTMR(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_LATTMR,M_LDT_DEVHDR_LATTMR) + +#define S_LDT_DEVHDR_HDRTYPE 16 +#define M_LDT_DEVHDR_HDRTYPE _SB_MAKEMASK_32(8,S_LDT_DEVHDR_HDRTYPE) +#define V_LDT_DEVHDR_HDRTYPE(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_HDRTYPE) +#define G_LDT_DEVHDR_HDRTYPE(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_HDRTYPE,M_LDT_DEVHDR_HDRTYPE) + +#define K_LDT_DEVHDR_HDRTYPE_TYPE1 1 + +#define S_LDT_DEVHDR_BIST 24 +#define M_LDT_DEVHDR_BIST _SB_MAKEMASK_32(8,S_LDT_DEVHDR_BIST) +#define V_LDT_DEVHDR_BIST(x) _SB_MAKEVALUE_32(x,S_LDT_DEVHDR_BIST) +#define G_LDT_DEVHDR_BIST(x) _SB_GETVALUE_32(x,S_LDT_DEVHDR_BIST,M_LDT_DEVHDR_BIST) + + + +/* + * LDT Status Register (Table 8-14). Note that these constants + * assume you've read the command and status register + * together (32-bit read at offset 0x04) + * + * These bits also apply to the secondary status + * register (Table 8-15), offset 0x1C + */ + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_LDT_STATUS_VGAEN _SB_MAKEMASK1_32(3) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define M_LDT_STATUS_CAPLIST _SB_MAKEMASK1_32(20) +#define M_LDT_STATUS_66MHZCAP _SB_MAKEMASK1_32(21) +#define M_LDT_STATUS_RESERVED2 _SB_MAKEMASK1_32(22) +#define M_LDT_STATUS_FASTB2BCAP _SB_MAKEMASK1_32(23) +#define M_LDT_STATUS_MSTRDPARERR _SB_MAKEMASK1_32(24) + +#define S_LDT_STATUS_DEVSELTIMING 25 +#define M_LDT_STATUS_DEVSELTIMING _SB_MAKEMASK_32(2,S_LDT_STATUS_DEVSELTIMING) +#define V_LDT_STATUS_DEVSELTIMING(x) _SB_MAKEVALUE_32(x,S_LDT_STATUS_DEVSELTIMING) +#define G_LDT_STATUS_DEVSELTIMING(x) _SB_GETVALUE_32(x,S_LDT_STATUS_DEVSELTIMING,M_LDT_STATUS_DEVSELTIMING) + +#define M_LDT_STATUS_SIGDTGTABORT _SB_MAKEMASK1_32(27) +#define M_LDT_STATUS_RCVDTGTABORT _SB_MAKEMASK1_32(28) +#define M_LDT_STATUS_RCVDMSTRABORT _SB_MAKEMASK1_32(29) +#define M_LDT_STATUS_SIGDSERR _SB_MAKEMASK1_32(30) +#define M_LDT_STATUS_DETPARERR _SB_MAKEMASK1_32(31) + +/* + * Bridge Control Register (Table 8-16). Note that these + * constants assume you've read the register as a 32-bit + * read (offset 0x3C) + */ + +#define M_LDT_BRCTL_PARERRRESP_EN _SB_MAKEMASK1_32(16) +#define M_LDT_BRCTL_SERR_EN _SB_MAKEMASK1_32(17) +#define M_LDT_BRCTL_ISA_EN _SB_MAKEMASK1_32(18) +#define M_LDT_BRCTL_VGA_EN _SB_MAKEMASK1_32(19) +#define M_LDT_BRCTL_MSTRABORTMODE _SB_MAKEMASK1_32(21) +#define M_LDT_BRCTL_SECBUSRESET _SB_MAKEMASK1_32(22) +#define M_LDT_BRCTL_FASTB2B_EN _SB_MAKEMASK1_32(23) +#define M_LDT_BRCTL_PRIDISCARD _SB_MAKEMASK1_32(24) +#define M_LDT_BRCTL_SECDISCARD _SB_MAKEMASK1_32(25) +#define M_LDT_BRCTL_DISCARDSTAT _SB_MAKEMASK1_32(26) +#define M_LDT_BRCTL_DISCARDSERR_EN _SB_MAKEMASK1_32(27) + +/* + * LDT Command Register (Table 8-17). Note that these constants + * assume you've read the command and status register together + * 32-bit read at offset 0x40 + */ + +#define M_LDT_CMD_WARMRESET _SB_MAKEMASK1_32(16) +#define M_LDT_CMD_DOUBLEENDED _SB_MAKEMASK1_32(17) + +#define S_LDT_CMD_CAPTYPE 29 +#define M_LDT_CMD_CAPTYPE _SB_MAKEMASK_32(3,S_LDT_CMD_CAPTYPE) +#define V_LDT_CMD_CAPTYPE(x) _SB_MAKEVALUE_32(x,S_LDT_CMD_CAPTYPE) +#define G_LDT_CMD_CAPTYPE(x) _SB_GETVALUE_32(x,S_LDT_CMD_CAPTYPE,M_LDT_CMD_CAPTYPE) + +/* + * LDT link control register (Table 8-18), and (Table 8-19) + */ + +#define M_LDT_LINKCTRL_CAPSYNCFLOOD_EN _SB_MAKEMASK1_32(1) +#define M_LDT_LINKCTRL_CRCSTARTTEST _SB_MAKEMASK1_32(2) +#define M_LDT_LINKCTRL_CRCFORCEERR _SB_MAKEMASK1_32(3) +#define M_LDT_LINKCTRL_LINKFAIL _SB_MAKEMASK1_32(4) +#define M_LDT_LINKCTRL_INITDONE _SB_MAKEMASK1_32(5) +#define M_LDT_LINKCTRL_EOC _SB_MAKEMASK1_32(6) +#define M_LDT_LINKCTRL_XMITOFF _SB_MAKEMASK1_32(7) + +#define S_LDT_LINKCTRL_CRCERR 8 +#define M_LDT_LINKCTRL_CRCERR _SB_MAKEMASK_32(4,S_LDT_LINKCTRL_CRCERR) +#define V_LDT_LINKCTRL_CRCERR(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_CRCERR) +#define G_LDT_LINKCTRL_CRCERR(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_CRCERR,M_LDT_LINKCTRL_CRCERR) + +#define S_LDT_LINKCTRL_MAXIN 16 +#define M_LDT_LINKCTRL_MAXIN _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXIN) +#define V_LDT_LINKCTRL_MAXIN(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXIN) +#define G_LDT_LINKCTRL_MAXIN(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXIN,M_LDT_LINKCTRL_MAXIN) + +#define M_LDT_LINKCTRL_DWFCLN _SB_MAKEMASK1_32(19) + +#define S_LDT_LINKCTRL_MAXOUT 20 +#define M_LDT_LINKCTRL_MAXOUT _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_MAXOUT) +#define V_LDT_LINKCTRL_MAXOUT(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_MAXOUT) +#define G_LDT_LINKCTRL_MAXOUT(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_MAXOUT,M_LDT_LINKCTRL_MAXOUT) + +#define M_LDT_LINKCTRL_DWFCOUT _SB_MAKEMASK1_32(23) + +#define S_LDT_LINKCTRL_WIDTHIN 24 +#define M_LDT_LINKCTRL_WIDTHIN _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHIN) +#define V_LDT_LINKCTRL_WIDTHIN(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN) +#define G_LDT_LINKCTRL_WIDTHIN(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHIN,M_LDT_LINKCTRL_WIDTHIN) + +#define M_LDT_LINKCTRL_DWFCLIN_EN _SB_MAKEMASK1_32(27) + +#define S_LDT_LINKCTRL_WIDTHOUT 28 +#define M_LDT_LINKCTRL_WIDTHOUT _SB_MAKEMASK_32(3,S_LDT_LINKCTRL_WIDTHOUT) +#define V_LDT_LINKCTRL_WIDTHOUT(x) _SB_MAKEVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT) +#define G_LDT_LINKCTRL_WIDTHOUT(x) _SB_GETVALUE_32(x,S_LDT_LINKCTRL_WIDTHOUT,M_LDT_LINKCTRL_WIDTHOUT) + +#define M_LDT_LINKCTRL_DWFCOUT_EN _SB_MAKEMASK1_32(31) + +/* + * LDT Link frequency register (Table 8-20) offset 0x48 + */ + +#define S_LDT_LINKFREQ_FREQ 8 +#define M_LDT_LINKFREQ_FREQ _SB_MAKEMASK_32(4,S_LDT_LINKFREQ_FREQ) +#define V_LDT_LINKFREQ_FREQ(x) _SB_MAKEVALUE_32(x,S_LDT_LINKFREQ_FREQ) +#define G_LDT_LINKFREQ_FREQ(x) _SB_GETVALUE_32(x,S_LDT_LINKFREQ_FREQ,M_LDT_LINKFREQ_FREQ) + +#define K_LDT_LINKFREQ_200MHZ 0 +#define K_LDT_LINKFREQ_300MHZ 1 +#define K_LDT_LINKFREQ_400MHZ 2 +#define K_LDT_LINKFREQ_500MHZ 3 +#define K_LDT_LINKFREQ_600MHZ 4 +#define K_LDT_LINKFREQ_800MHZ 5 +#define K_LDT_LINKFREQ_1000MHZ 6 + +/* + * LDT SRI Command Register (Table 8-21). Note that these constants + * assume you've read the command and status register together + * 32-bit read at offset 0x50 + */ + +#define M_LDT_SRICMD_SIPREADY _SB_MAKEMASK1_32(16) +#define M_LDT_SRICMD_SYNCPTRCTL _SB_MAKEMASK1_32(17) +#define M_LDT_SRICMD_REDUCESYNCZERO _SB_MAKEMASK1_32(18) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +#define M_LDT_SRICMD_DISSTARVATIONCNT _SB_MAKEMASK1_32(19) /* PASS1 */ +#endif /* up to 1250 PASS1 */ +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_LDT_SRICMD_DISMULTTXVLD _SB_MAKEMASK1_32(19) +#define M_LDT_SRICMD_EXPENDIAN _SB_MAKEMASK1_32(26) +#endif /* 1250 PASS2 || 112x PASS1 */ + + +#define S_LDT_SRICMD_RXMARGIN 20 +#define M_LDT_SRICMD_RXMARGIN _SB_MAKEMASK_32(5,S_LDT_SRICMD_RXMARGIN) +#define V_LDT_SRICMD_RXMARGIN(x) _SB_MAKEVALUE_32(x,S_LDT_SRICMD_RXMARGIN) +#define G_LDT_SRICMD_RXMARGIN(x) _SB_GETVALUE_32(x,S_LDT_SRICMD_RXMARGIN,M_LDT_SRICMD_RXMARGIN) + +#define M_LDT_SRICMD_LDTPLLCOMPAT _SB_MAKEMASK1_32(25) + +#define S_LDT_SRICMD_TXINITIALOFFSET 28 +#define M_LDT_SRICMD_TXINITIALOFFSET _SB_MAKEMASK_32(3,S_LDT_SRICMD_TXINITIALOFFSET) +#define V_LDT_SRICMD_TXINITIALOFFSET(x) _SB_MAKEVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET) +#define G_LDT_SRICMD_TXINITIALOFFSET(x) _SB_GETVALUE_32(x,S_LDT_SRICMD_TXINITIALOFFSET,M_LDT_SRICMD_TXINITIALOFFSET) + +#define M_LDT_SRICMD_LINKFREQDIRECT _SB_MAKEMASK1_32(31) + +/* + * LDT Error control and status register (Table 8-22) (Table 8-23) + */ + +#define M_LDT_ERRCTL_PROTFATAL_EN _SB_MAKEMASK1_32(0) +#define M_LDT_ERRCTL_PROTNONFATAL_EN _SB_MAKEMASK1_32(1) +#define M_LDT_ERRCTL_PROTSYNCFLOOD_EN _SB_MAKEMASK1_32(2) +#define M_LDT_ERRCTL_OVFFATAL_EN _SB_MAKEMASK1_32(3) +#define M_LDT_ERRCTL_OVFNONFATAL_EN _SB_MAKEMASK1_32(4) +#define M_LDT_ERRCTL_OVFSYNCFLOOD_EN _SB_MAKEMASK1_32(5) +#define M_LDT_ERRCTL_EOCNXAFATAL_EN _SB_MAKEMASK1_32(6) +#define M_LDT_ERRCTL_EOCNXANONFATAL_EN _SB_MAKEMASK1_32(7) +#define M_LDT_ERRCTL_EOCNXASYNCFLOOD_EN _SB_MAKEMASK1_32(8) +#define M_LDT_ERRCTL_CRCFATAL_EN _SB_MAKEMASK1_32(9) +#define M_LDT_ERRCTL_CRCNONFATAL_EN _SB_MAKEMASK1_32(10) +#define M_LDT_ERRCTL_SERRFATAL_EN _SB_MAKEMASK1_32(11) +#define M_LDT_ERRCTL_SRCTAGFATAL_EN _SB_MAKEMASK1_32(12) +#define M_LDT_ERRCTL_SRCTAGNONFATAL_EN _SB_MAKEMASK1_32(13) +#define M_LDT_ERRCTL_SRCTAGSYNCFLOOD_EN _SB_MAKEMASK1_32(14) +#define M_LDT_ERRCTL_MAPNXAFATAL_EN _SB_MAKEMASK1_32(15) +#define M_LDT_ERRCTL_MAPNXANONFATAL_EN _SB_MAKEMASK1_32(16) +#define M_LDT_ERRCTL_MAPNXASYNCFLOOD_EN _SB_MAKEMASK1_32(17) + +#define M_LDT_ERRCTL_PROTOERR _SB_MAKEMASK1_32(24) +#define M_LDT_ERRCTL_OVFERR _SB_MAKEMASK1_32(25) +#define M_LDT_ERRCTL_EOCNXAERR _SB_MAKEMASK1_32(26) +#define M_LDT_ERRCTL_SRCTAGERR _SB_MAKEMASK1_32(27) +#define M_LDT_ERRCTL_MAPNXAERR _SB_MAKEMASK1_32(28) + +/* + * SRI Control register (Table 8-24, 8-25) Offset 0x6C + */ + +#define S_LDT_SRICTRL_NEEDRESP 0 +#define M_LDT_SRICTRL_NEEDRESP _SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDRESP) +#define V_LDT_SRICTRL_NEEDRESP(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDRESP) +#define G_LDT_SRICTRL_NEEDRESP(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDRESP,M_LDT_SRICTRL_NEEDRESP) + +#define S_LDT_SRICTRL_NEEDNPREQ 2 +#define M_LDT_SRICTRL_NEEDNPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDNPREQ) +#define V_LDT_SRICTRL_NEEDNPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ) +#define G_LDT_SRICTRL_NEEDNPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDNPREQ,M_LDT_SRICTRL_NEEDNPREQ) + +#define S_LDT_SRICTRL_NEEDPREQ 4 +#define M_LDT_SRICTRL_NEEDPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_NEEDPREQ) +#define V_LDT_SRICTRL_NEEDPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ) +#define G_LDT_SRICTRL_NEEDPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_NEEDPREQ,M_LDT_SRICTRL_NEEDPREQ) + +#define S_LDT_SRICTRL_WANTRESP 8 +#define M_LDT_SRICTRL_WANTRESP _SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTRESP) +#define V_LDT_SRICTRL_WANTRESP(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTRESP) +#define G_LDT_SRICTRL_WANTRESP(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTRESP,M_LDT_SRICTRL_WANTRESP) + +#define S_LDT_SRICTRL_WANTNPREQ 10 +#define M_LDT_SRICTRL_WANTNPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTNPREQ) +#define V_LDT_SRICTRL_WANTNPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ) +#define G_LDT_SRICTRL_WANTNPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTNPREQ,M_LDT_SRICTRL_WANTNPREQ) + +#define S_LDT_SRICTRL_WANTPREQ 12 +#define M_LDT_SRICTRL_WANTPREQ _SB_MAKEMASK_32(2,S_LDT_SRICTRL_WANTPREQ) +#define V_LDT_SRICTRL_WANTPREQ(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_WANTPREQ) +#define G_LDT_SRICTRL_WANTPREQ(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_WANTPREQ,M_LDT_SRICTRL_WANTPREQ) + +#define S_LDT_SRICTRL_BUFRELSPACE 16 +#define M_LDT_SRICTRL_BUFRELSPACE _SB_MAKEMASK_32(4,S_LDT_SRICTRL_BUFRELSPACE) +#define V_LDT_SRICTRL_BUFRELSPACE(x) _SB_MAKEVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE) +#define G_LDT_SRICTRL_BUFRELSPACE(x) _SB_GETVALUE_32(x,S_LDT_SRICTRL_BUFRELSPACE,M_LDT_SRICTRL_BUFRELSPACE) + +/* + * LDT SRI Transmit Buffer Count register (Table 8-26) + */ + +#define S_LDT_TXBUFCNT_PCMD 0 +#define M_LDT_TXBUFCNT_PCMD _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PCMD) +#define V_LDT_TXBUFCNT_PCMD(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PCMD) +#define G_LDT_TXBUFCNT_PCMD(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PCMD,M_LDT_TXBUFCNT_PCMD) + +#define S_LDT_TXBUFCNT_PDATA 4 +#define M_LDT_TXBUFCNT_PDATA _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_PDATA) +#define V_LDT_TXBUFCNT_PDATA(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_PDATA) +#define G_LDT_TXBUFCNT_PDATA(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_PDATA,M_LDT_TXBUFCNT_PDATA) + +#define S_LDT_TXBUFCNT_NPCMD 8 +#define M_LDT_TXBUFCNT_NPCMD _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPCMD) +#define V_LDT_TXBUFCNT_NPCMD(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPCMD) +#define G_LDT_TXBUFCNT_NPCMD(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPCMD,M_LDT_TXBUFCNT_NPCMD) + +#define S_LDT_TXBUFCNT_NPDATA 12 +#define M_LDT_TXBUFCNT_NPDATA _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_NPDATA) +#define V_LDT_TXBUFCNT_NPDATA(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_NPDATA) +#define G_LDT_TXBUFCNT_NPDATA(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_NPDATA,M_LDT_TXBUFCNT_NPDATA) + +#define S_LDT_TXBUFCNT_RCMD 16 +#define M_LDT_TXBUFCNT_RCMD _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RCMD) +#define V_LDT_TXBUFCNT_RCMD(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RCMD) +#define G_LDT_TXBUFCNT_RCMD(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RCMD,M_LDT_TXBUFCNT_RCMD) + +#define S_LDT_TXBUFCNT_RDATA 20 +#define M_LDT_TXBUFCNT_RDATA _SB_MAKEMASK_32(4,S_LDT_TXBUFCNT_RDATA) +#define V_LDT_TXBUFCNT_RDATA(x) _SB_MAKEVALUE_32(x,S_LDT_TXBUFCNT_RDATA) +#define G_LDT_TXBUFCNT_RDATA(x) _SB_GETVALUE_32(x,S_LDT_TXBUFCNT_RDATA,M_LDT_TXBUFCNT_RDATA) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Additional Status Register + */ + +#define S_LDT_ADDSTATUS_TGTDONE 0 +#define M_LDT_ADDSTATUS_TGTDONE _SB_MAKEMASK_32(8,S_LDT_ADDSTATUS_TGTDONE) +#define V_LDT_ADDSTATUS_TGTDONE(x) _SB_MAKEVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE) +#define G_LDT_ADDSTATUS_TGTDONE(x) _SB_GETVALUE_32(x,S_LDT_ADDSTATUS_TGTDONE,M_LDT_ADDSTATUS_TGTDONE) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#endif + diff -Nru a/include/asm-mips64/sibyte/sb1250_mac.h b/include/asm-mips64/sibyte/sb1250_mac.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_mac.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,643 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * MAC constants and macros File: sb1250_mac.h + * + * This module contains constants and macros for the SB1250's + * ethernet controllers. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_MAC_H +#define _SB1250_MAC_H + +#include "sb1250_defs.h" + +/* ********************************************************************* + * Ethernet MAC Registers + ********************************************************************* */ + +/* + * MAC Configuration Register (Table 9-13) + * Register: MAC_CFG_0 + * Register: MAC_CFG_1 + * Register: MAC_CFG_2 + */ + + +#define M_MAC_RESERVED0 _SB_MAKEMASK1(0) +#define M_MAC_TX_HOLD_SOP_EN _SB_MAKEMASK1(1) +#define M_MAC_RETRY_EN _SB_MAKEMASK1(2) +#define M_MAC_RET_DRPREQ_EN _SB_MAKEMASK1(3) +#define M_MAC_RET_UFL_EN _SB_MAKEMASK1(4) +#define M_MAC_BURST_EN _SB_MAKEMASK1(5) + +#define S_MAC_TX_PAUSE _SB_MAKE64(6) +#define M_MAC_TX_PAUSE_CNT _SB_MAKEMASK(3,S_MAC_TX_PAUSE) +#define V_MAC_TX_PAUSE_CNT(x) _SB_MAKEVALUE(x,S_MAC_TX_PAUSE) + +#define K_MAC_TX_PAUSE_CNT_512 0 +#define K_MAC_TX_PAUSE_CNT_1K 1 +#define K_MAC_TX_PAUSE_CNT_2K 2 +#define K_MAC_TX_PAUSE_CNT_4K 3 +#define K_MAC_TX_PAUSE_CNT_8K 4 +#define K_MAC_TX_PAUSE_CNT_16K 5 +#define K_MAC_TX_PAUSE_CNT_32K 6 +#define K_MAC_TX_PAUSE_CNT_64K 7 + +#define V_MAC_TX_PAUSE_CNT_512 V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_512) +#define V_MAC_TX_PAUSE_CNT_1K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_1K) +#define V_MAC_TX_PAUSE_CNT_2K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_2K) +#define V_MAC_TX_PAUSE_CNT_4K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_4K) +#define V_MAC_TX_PAUSE_CNT_8K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_8K) +#define V_MAC_TX_PAUSE_CNT_16K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_16K) +#define V_MAC_TX_PAUSE_CNT_32K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_32K) +#define V_MAC_TX_PAUSE_CNT_64K V_MAC_TX_PAUSE_CNT(K_MAC_TX_PAUSE_CNT_64K) + +#define M_MAC_RESERVED1 _SB_MAKEMASK(8,9) + +#define M_MAC_AP_STAT_EN _SB_MAKEMASK1(17) +#define M_MAC_RESERVED2 _SB_MAKEMASK1(18) +#define M_MAC_DRP_ERRPKT_EN _SB_MAKEMASK1(19) +#define M_MAC_DRP_FCSERRPKT_EN _SB_MAKEMASK1(20) +#define M_MAC_DRP_CODEERRPKT_EN _SB_MAKEMASK1(21) +#define M_MAC_DRP_DRBLERRPKT_EN _SB_MAKEMASK1(22) +#define M_MAC_DRP_RNTPKT_EN _SB_MAKEMASK1(23) +#define M_MAC_DRP_OSZPKT_EN _SB_MAKEMASK1(24) +#define M_MAC_DRP_LENERRPKT_EN _SB_MAKEMASK1(25) + +#define M_MAC_RESERVED3 _SB_MAKEMASK(6,26) + +#define M_MAC_BYPASS_SEL _SB_MAKEMASK1(32) +#define M_MAC_HDX_EN _SB_MAKEMASK1(33) + +#define S_MAC_SPEED_SEL _SB_MAKE64(34) +#define M_MAC_SPEED_SEL _SB_MAKEMASK(2,S_MAC_SPEED_SEL) +#define V_MAC_SPEED_SEL(x) _SB_MAKEVALUE(x,S_MAC_SPEED_SEL) +#define G_MAC_SPEED_SEL(x) _SB_GETVALUE(x,S_MAC_SPEED_SEL,M_MAC_SPEED_SEL) + +#define K_MAC_SPEED_SEL_10MBPS 0 +#define K_MAC_SPEED_SEL_100MBPS 1 +#define K_MAC_SPEED_SEL_1000MBPS 2 +#define K_MAC_SPEED_SEL_RESERVED 3 + +#define V_MAC_SPEED_SEL_10MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_10MBPS) +#define V_MAC_SPEED_SEL_100MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_100MBPS) +#define V_MAC_SPEED_SEL_1000MBPS V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_1000MBPS) +#define V_MAC_SPEED_SEL_RESERVED V_MAC_SPEED_SEL(K_MAC_SPEED_SEL_RESERVED) + +#define M_MAC_TX_CLK_EDGE_SEL _SB_MAKEMASK1(36) +#define M_MAC_LOOPBACK_SEL _SB_MAKEMASK1(37) +#define M_MAC_FAST_SYNC _SB_MAKEMASK1(38) +#define M_MAC_SS_EN _SB_MAKEMASK1(39) + +#define S_MAC_BYPASS_CFG _SB_MAKE64(40) +#define M_MAC_BYPASS_CFG _SB_MAKEMASK(2,S_MAC_BYPASS_CFG) +#define V_MAC_BYPASS_CFG(x) _SB_MAKEVALUE(x,S_MAC_BYPASS_CFG) +#define G_MAC_BYPASS_CFG(x) _SB_GETVALUE(x,S_MAC_BYPASS_CFG,M_MAC_BYPASS_CFG) + +#define K_MAC_BYPASS_GMII 0 +#define K_MAC_BYPASS_ENCODED 1 +#define K_MAC_BYPASS_SOP 2 +#define K_MAC_BYPASS_EOP 3 + +#define M_MAC_BYPASS_16 _SB_MAKEMASK1(42) +#define M_MAC_BYPASS_FCS_CHK _SB_MAKEMASK1(43) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_RX_CH_SEL_MSB _SB_MAKEMASK1(44) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_SPLIT_CH_SEL _SB_MAKEMASK1(45) +#endif /* 112x PASS1 */ + +#define S_MAC_BYPASS_IFG _SB_MAKE64(46) +#define M_MAC_BYPASS_IFG _SB_MAKEMASK(8,S_MAC_BYPASS_IFG) +#define V_MAC_BYPASS_IFG(x) _SB_MAKEVALUE(x,S_MAC_BYPASS_IFG) +#define G_MAC_BYPASS_IFG(x) _SB_GETVALUE(x,S_MAC_BYPASS_IFG,M_MAC_BYPASS_IFG) + +#define K_MAC_FC_CMD_DISABLED 0 +#define K_MAC_FC_CMD_ENABLED 1 +#define K_MAC_FC_CMD_ENAB_FALSECARR 2 + +#define V_MAC_FC_CMD_DISABLED V_MAC_FC_CMD(K_MAC_FC_CMD_DISABLED) +#define V_MAC_FC_CMD_ENABLED V_MAC_FC_CMD(K_MAC_FC_CMD_ENABLED) +#define V_MAC_FC_CMD_ENAB_FALSECARR V_MAC_FC_CMD(K_MAC_FC_CMD_ENAB_FALSECARR) + +#define M_MAC_FC_SEL _SB_MAKEMASK1(54) + +#define S_MAC_FC_CMD _SB_MAKE64(55) +#define M_MAC_FC_CMD _SB_MAKEMASK(2,S_MAC_FC_CMD) +#define V_MAC_FC_CMD(x) _SB_MAKEVALUE(x,S_MAC_FC_CMD) +#define G_MAC_FC_CMD(x) _SB_GETVALUE(x,S_MAC_FC_CMD,M_MAC_FC_CMD) + +#define S_MAC_RX_CH_SEL _SB_MAKE64(57) +#define M_MAC_RX_CH_SEL _SB_MAKEMASK(7,S_MAC_RX_CH_SEL) +#define V_MAC_RX_CH_SEL(x) _SB_MAKEVALUE(x,S_MAC_RX_CH_SEL) +#define G_MAC_RX_CH_SEL(x) _SB_GETVALUE(x,S_MAC_RX_CH_SEL,M_MAC_RX_CH_SEL) + + +/* + * MAC Enable Registers + * Register: MAC_ENABLE_0 + * Register: MAC_ENABLE_1 + * Register: MAC_ENABLE_2 + */ + +#define M_MAC_RXDMA_EN0 _SB_MAKEMASK1(0) +#define M_MAC_RXDMA_EN1 _SB_MAKEMASK1(1) +#define M_MAC_TXDMA_EN0 _SB_MAKEMASK1(4) +#define M_MAC_TXDMA_EN1 _SB_MAKEMASK1(5) + +#define M_MAC_PORT_RESET _SB_MAKEMASK1(8) + +#define M_MAC_RX_ENABLE _SB_MAKEMASK1(10) +#define M_MAC_TX_ENABLE _SB_MAKEMASK1(11) +#define M_MAC_BYP_RX_ENABLE _SB_MAKEMASK1(12) +#define M_MAC_BYP_TX_ENABLE _SB_MAKEMASK1(13) + +/* + * MAC DMA Control Register + * Register: MAC_TXD_CTL_0 + * Register: MAC_TXD_CTL_1 + * Register: MAC_TXD_CTL_2 + */ + +#define S_MAC_TXD_WEIGHT0 _SB_MAKE64(0) +#define M_MAC_TXD_WEIGHT0 _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT0) +#define V_MAC_TXD_WEIGHT0(x) _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT0) +#define G_MAC_TXD_WEIGHT0(x) _SB_GETVALUE(x,S_MAC_TXD_WEIGHT0,M_MAC_TXD_WEIGHT0) + +#define S_MAC_TXD_WEIGHT1 _SB_MAKE64(4) +#define M_MAC_TXD_WEIGHT1 _SB_MAKEMASK(4,S_MAC_TXD_WEIGHT1) +#define V_MAC_TXD_WEIGHT1(x) _SB_MAKEVALUE(x,S_MAC_TXD_WEIGHT1) +#define G_MAC_TXD_WEIGHT1(x) _SB_GETVALUE(x,S_MAC_TXD_WEIGHT1,M_MAC_TXD_WEIGHT1) + +/* + * MAC Fifo Threshhold registers (Table 9-14) + * Register: MAC_THRSH_CFG_0 + * Register: MAC_THRSH_CFG_1 + * Register: MAC_THRSH_CFG_2 + */ + +#define S_MAC_TX_WR_THRSH _SB_MAKE64(0) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +/* XXX: Can't enable, as it has the same name as a pass2+ define below. */ +/* #define M_MAC_TX_WR_THRSH _SB_MAKEMASK(6,S_MAC_TX_WR_THRSH) */ +#endif /* up to 1250 PASS1 */ +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_TX_WR_THRSH _SB_MAKEMASK(7,S_MAC_TX_WR_THRSH) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define V_MAC_TX_WR_THRSH(x) _SB_MAKEVALUE(x,S_MAC_TX_WR_THRSH) +#define G_MAC_TX_WR_THRSH(x) _SB_GETVALUE(x,S_MAC_TX_WR_THRSH,M_MAC_TX_WR_THRSH) + +#define S_MAC_TX_RD_THRSH _SB_MAKE64(8) +#if SIBYTE_HDR_FEATURE_UP_TO(1250, PASS1) +/* XXX: Can't enable, as it has the same name as a pass2+ define below. */ +/* #define M_MAC_TX_RD_THRSH _SB_MAKEMASK(6,S_MAC_TX_RD_THRSH) */ +#endif /* up to 1250 PASS1 */ +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_TX_RD_THRSH _SB_MAKEMASK(7,S_MAC_TX_RD_THRSH) +#endif /* 1250 PASS2 || 112x PASS1 */ +#define V_MAC_TX_RD_THRSH(x) _SB_MAKEVALUE(x,S_MAC_TX_RD_THRSH) +#define G_MAC_TX_RD_THRSH(x) _SB_GETVALUE(x,S_MAC_TX_RD_THRSH,M_MAC_TX_RD_THRSH) + +#define S_MAC_TX_RL_THRSH _SB_MAKE64(16) +#define M_MAC_TX_RL_THRSH _SB_MAKEMASK(4,S_MAC_TX_RL_THRSH) +#define V_MAC_TX_RL_THRSH(x) _SB_MAKEVALUE(x,S_MAC_TX_RL_THRSH) +#define G_MAC_TX_RL_THRSH(x) _SB_GETVALUE(x,S_MAC_TX_RL_THRSH,M_MAC_TX_RL_THRSH) + +#define S_MAC_RX_PL_THRSH _SB_MAKE64(24) +#define M_MAC_RX_PL_THRSH _SB_MAKEMASK(6,S_MAC_RX_PL_THRSH) +#define V_MAC_RX_PL_THRSH(x) _SB_MAKEVALUE(x,S_MAC_RX_PL_THRSH) +#define G_MAC_RX_PL_THRSH(x) _SB_GETVALUE(x,S_MAC_RX_PL_THRSH,M_MAC_RX_PL_THRSH) + +#define S_MAC_RX_RD_THRSH _SB_MAKE64(32) +#define M_MAC_RX_RD_THRSH _SB_MAKEMASK(6,S_MAC_RX_RD_THRSH) +#define V_MAC_RX_RD_THRSH(x) _SB_MAKEVALUE(x,S_MAC_RX_RD_THRSH) +#define G_MAC_RX_RD_THRSH(x) _SB_GETVALUE(x,S_MAC_RX_RD_THRSH,M_MAC_RX_RD_THRSH) + +#define S_MAC_RX_RL_THRSH _SB_MAKE64(40) +#define M_MAC_RX_RL_THRSH _SB_MAKEMASK(6,S_MAC_RX_RL_THRSH) +#define V_MAC_RX_RL_THRSH(x) _SB_MAKEVALUE(x,S_MAC_RX_RL_THRSH) +#define G_MAC_RX_RL_THRSH(x) _SB_GETVALUE(x,S_MAC_RX_RL_THRSH,M_MAC_RX_RL_THRSH) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_ENC_FC_THRSH _SB_MAKE64(56) +#define M_MAC_ENC_FC_THRSH _SB_MAKEMASK(6,S_MAC_ENC_FC_THRSH) +#define V_MAC_ENC_FC_THRSH(x) _SB_MAKEVALUE(x,S_MAC_ENC_FC_THRSH) +#define G_MAC_ENC_FC_THRSH(x) _SB_GETVALUE(x,S_MAC_ENC_FC_THRSH,M_MAC_ENC_FC_THRSH) +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* + * MAC Frame Configuration Registers (Table 9-15) + * Register: MAC_FRAME_CFG_0 + * Register: MAC_FRAME_CFG_1 + * Register: MAC_FRAME_CFG_2 + */ + +/* XXXCGD: ??? Unused in pass2? */ +#define S_MAC_IFG_RX _SB_MAKE64(0) +#define M_MAC_IFG_RX _SB_MAKEMASK(6,S_MAC_IFG_RX) +#define V_MAC_IFG_RX(x) _SB_MAKEVALUE(x,S_MAC_IFG_RX) +#define G_MAC_IFG_RX(x) _SB_GETVALUE(x,S_MAC_IFG_RX,M_MAC_IFG_RX) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_PRE_LEN _SB_MAKE64(0) +#define M_MAC_PRE_LEN _SB_MAKEMASK(6,S_MAC_PRE_LEN) +#define V_MAC_PRE_LEN(x) _SB_MAKEVALUE(x,S_MAC_PRE_LEN) +#define G_MAC_PRE_LEN(x) _SB_GETVALUE(x,S_MAC_PRE_LEN,M_MAC_PRE_LEN) +#endif /* 112x PASS1 */ + +#define S_MAC_IFG_TX _SB_MAKE64(6) +#define M_MAC_IFG_TX _SB_MAKEMASK(6,S_MAC_IFG_TX) +#define V_MAC_IFG_TX(x) _SB_MAKEVALUE(x,S_MAC_IFG_TX) +#define G_MAC_IFG_TX(x) _SB_GETVALUE(x,S_MAC_IFG_TX,M_MAC_IFG_TX) + +#define S_MAC_IFG_THRSH _SB_MAKE64(12) +#define M_MAC_IFG_THRSH _SB_MAKEMASK(6,S_MAC_IFG_THRSH) +#define V_MAC_IFG_THRSH(x) _SB_MAKEVALUE(x,S_MAC_IFG_THRSH) +#define G_MAC_IFG_THRSH(x) _SB_GETVALUE(x,S_MAC_IFG_THRSH,M_MAC_IFG_THRSH) + +#define S_MAC_BACKOFF_SEL _SB_MAKE64(18) +#define M_MAC_BACKOFF_SEL _SB_MAKEMASK(4,S_MAC_BACKOFF_SEL) +#define V_MAC_BACKOFF_SEL(x) _SB_MAKEVALUE(x,S_MAC_BACKOFF_SEL) +#define G_MAC_BACKOFF_SEL(x) _SB_GETVALUE(x,S_MAC_BACKOFF_SEL,M_MAC_BACKOFF_SEL) + +#define S_MAC_LFSR_SEED _SB_MAKE64(22) +#define M_MAC_LFSR_SEED _SB_MAKEMASK(8,S_MAC_LFSR_SEED) +#define V_MAC_LFSR_SEED(x) _SB_MAKEVALUE(x,S_MAC_LFSR_SEED) +#define G_MAC_LFSR_SEED(x) _SB_GETVALUE(x,S_MAC_LFSR_SEED,M_MAC_LFSR_SEED) + +#define S_MAC_SLOT_SIZE _SB_MAKE64(30) +#define M_MAC_SLOT_SIZE _SB_MAKEMASK(10,S_MAC_SLOT_SIZE) +#define V_MAC_SLOT_SIZE(x) _SB_MAKEVALUE(x,S_MAC_SLOT_SIZE) +#define G_MAC_SLOT_SIZE(x) _SB_GETVALUE(x,S_MAC_SLOT_SIZE,M_MAC_SLOT_SIZE) + +#define S_MAC_MIN_FRAMESZ _SB_MAKE64(40) +#define M_MAC_MIN_FRAMESZ _SB_MAKEMASK(8,S_MAC_MIN_FRAMESZ) +#define V_MAC_MIN_FRAMESZ(x) _SB_MAKEVALUE(x,S_MAC_MIN_FRAMESZ) +#define G_MAC_MIN_FRAMESZ(x) _SB_GETVALUE(x,S_MAC_MIN_FRAMESZ,M_MAC_MIN_FRAMESZ) + +#define S_MAC_MAX_FRAMESZ _SB_MAKE64(48) +#define M_MAC_MAX_FRAMESZ _SB_MAKEMASK(16,S_MAC_MAX_FRAMESZ) +#define V_MAC_MAX_FRAMESZ(x) _SB_MAKEVALUE(x,S_MAC_MAX_FRAMESZ) +#define G_MAC_MAX_FRAMESZ(x) _SB_GETVALUE(x,S_MAC_MAX_FRAMESZ,M_MAC_MAX_FRAMESZ) + +/* + * These constants are used to configure the fields within the Frame + * Configuration Register. + */ + +#define K_MAC_IFG_RX_10 _SB_MAKE64(0) /* See table 176, not used */ +#define K_MAC_IFG_RX_100 _SB_MAKE64(0) +#define K_MAC_IFG_RX_1000 _SB_MAKE64(0) + +#define K_MAC_IFG_TX_10 _SB_MAKE64(20) +#define K_MAC_IFG_TX_100 _SB_MAKE64(20) +#define K_MAC_IFG_TX_1000 _SB_MAKE64(8) + +#define K_MAC_IFG_THRSH_10 _SB_MAKE64(4) +#define K_MAC_IFG_THRSH_100 _SB_MAKE64(4) +#define K_MAC_IFG_THRSH_1000 _SB_MAKE64(0) + +#define K_MAC_SLOT_SIZE_10 _SB_MAKE64(0) +#define K_MAC_SLOT_SIZE_100 _SB_MAKE64(0) +#define K_MAC_SLOT_SIZE_1000 _SB_MAKE64(0) + +#define V_MAC_IFG_RX_10 V_MAC_IFG_RX(K_MAC_IFG_RX_10) +#define V_MAC_IFG_RX_100 V_MAC_IFG_RX(K_MAC_IFG_RX_100) +#define V_MAC_IFG_RX_1000 V_MAC_IFG_RX(K_MAC_IFG_RX_1000) + +#define V_MAC_IFG_TX_10 V_MAC_IFG_TX(K_MAC_IFG_TX_10) +#define V_MAC_IFG_TX_100 V_MAC_IFG_TX(K_MAC_IFG_TX_100) +#define V_MAC_IFG_TX_1000 V_MAC_IFG_TX(K_MAC_IFG_TX_1000) + +#define V_MAC_IFG_THRSH_10 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_10) +#define V_MAC_IFG_THRSH_100 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_100) +#define V_MAC_IFG_THRSH_1000 V_MAC_IFG_THRSH(K_MAC_IFG_THRSH_1000) + +#define V_MAC_SLOT_SIZE_10 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_10) +#define V_MAC_SLOT_SIZE_100 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_100) +#define V_MAC_SLOT_SIZE_1000 V_MAC_SLOT_SIZE(K_MAC_SLOT_SIZE_1000) + +#define K_MAC_MIN_FRAMESZ_FIFO _SB_MAKE64(9) +#define K_MAC_MIN_FRAMESZ_DEFAULT _SB_MAKE64(64) +#define K_MAC_MAX_FRAMESZ_DEFAULT _SB_MAKE64(1518) +#define K_MAC_MAX_FRAMESZ_JUMBO _SB_MAKE64(9216) + +#define V_MAC_MIN_FRAMESZ_FIFO V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_FIFO) +#define V_MAC_MIN_FRAMESZ_DEFAULT V_MAC_MIN_FRAMESZ(K_MAC_MIN_FRAMESZ_DEFAULT) +#define V_MAC_MAX_FRAMESZ_DEFAULT V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_DEFAULT) +#define V_MAC_MAX_FRAMESZ_JUMBO V_MAC_MAX_FRAMESZ(K_MAC_MAX_FRAMESZ_JUMBO) + +/* + * MAC VLAN Tag Registers (Table 9-16) + * Register: MAC_VLANTAG_0 + * Register: MAC_VLANTAG_1 + * Register: MAC_VLANTAG_2 + */ + +#define S_MAC_VLAN_TAG _SB_MAKE64(0) +#define M_MAC_VLAN_TAG _SB_MAKEMASK(32,S_MAC_VLAN_TAG) +#define V_MAC_VLAN_TAG(x) _SB_MAKEVALUE(x,S_MAC_VLAN_TAG) +#define G_MAC_VLAN_TAG(x) _SB_GETVALUE(x,S_MAC_VLAN_TAG,M_MAC_VLAN_TAG) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_TX_PKT_OFFSET _SB_MAKE64(32) +#define M_MAC_TX_PKT_OFFSET _SB_MAKEMASK(8,S_MAC_TX_PKT_OFFSET) +#define V_MAC_TX_PKT_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_TX_PKT_OFFSET) +#define G_MAC_TX_PKT_OFFSET(x) _SB_GETVALUE(x,S_MAC_TX_PKT_OFFSET,M_MAC_TX_PKT_OFFSET) + +#define S_MAC_TX_CRC_OFFSET _SB_MAKE64(40) +#define M_MAC_TX_CRC_OFFSET _SB_MAKEMASK(8,S_MAC_TX_CRC_OFFSET) +#define V_MAC_TX_CRC_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_TX_CRC_OFFSET) +#define G_MAC_TX_CRC_OFFSET(x) _SB_GETVALUE(x,S_MAC_TX_CRC_OFFSET,M_MAC_TX_CRC_OFFSET) + +#define M_MAC_CH_BASE_FC_EN _SB_MAKEMASK1(48) +#endif /* 112x PASS1 */ + +/* + * MAC Status Registers (Table 9-17) + * Also used for the MAC Interrupt Mask Register (Table 9-18) + * Register: MAC_STATUS_0 + * Register: MAC_STATUS_1 + * Register: MAC_STATUS_2 + * Register: MAC_INT_MASK_0 + * Register: MAC_INT_MASK_1 + * Register: MAC_INT_MASK_2 + */ + +/* + * Use these constants to shift the appropriate channel + * into the CH0 position so the same tests can be used + * on each channel. + */ + +#define S_MAC_RX_CH0 _SB_MAKE64(0) +#define S_MAC_RX_CH1 _SB_MAKE64(8) +#define S_MAC_TX_CH0 _SB_MAKE64(16) +#define S_MAC_TX_CH1 _SB_MAKE64(24) + +#define S_MAC_TXCHANNELS _SB_MAKE64(16) /* this is 1st TX chan */ +#define S_MAC_CHANWIDTH _SB_MAKE64(8) /* bits between channels */ + +/* + * These are the same as RX channel 0. The idea here + * is that you'll use one of the "S_" things above + * and pass just the six bits to a DMA-channel-specific ISR + */ +#define M_MAC_INT_CHANNEL _SB_MAKEMASK(8,0) +#define M_MAC_INT_EOP_COUNT _SB_MAKEMASK1(0) +#define M_MAC_INT_EOP_TIMER _SB_MAKEMASK1(1) +#define M_MAC_INT_EOP_SEEN _SB_MAKEMASK1(2) +#define M_MAC_INT_HWM _SB_MAKEMASK1(3) +#define M_MAC_INT_LWM _SB_MAKEMASK1(4) +#define M_MAC_INT_DSCR _SB_MAKEMASK1(5) +#define M_MAC_INT_ERR _SB_MAKEMASK1(6) +#define M_MAC_INT_DZERO _SB_MAKEMASK1(7) /* only for TX channels */ +#define M_MAC_INT_DROP _SB_MAKEMASK1(7) /* only for RX channels */ + +/* + * In the following definitions we use ch (0/1) and txrx (TX=1, RX=0, see + * also DMA_TX/DMA_RX in sb_regs.h). + */ +#define S_MAC_STATUS_CH_OFFSET(ch,txrx) _SB_MAKE64(((ch) + 2 * (txrx)) * S_MAC_CHANWIDTH) + +#define M_MAC_STATUS_CHANNEL(ch,txrx) _SB_MAKEVALUE(_SB_MAKEMASK(8,0),S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_EOP_COUNT(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_COUNT,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_EOP_TIMER(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_TIMER,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_EOP_SEEN(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_EOP_SEEN,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_HWM(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_HWM,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_LWM(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_LWM,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_DSCR(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_DSCR,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_ERR(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_ERR,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_DZERO(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_DZERO,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_DROP(ch,txrx) _SB_MAKEVALUE(M_MAC_INT_DROP,S_MAC_STATUS_CH_OFFSET(ch,txrx)) +#define M_MAC_STATUS_OTHER_ERR _SB_MAKEVALUE(_SB_MAKEMASK(7,0),40) + + +#define M_MAC_RX_UNDRFL _SB_MAKEMASK1(40) +#define M_MAC_RX_OVRFL _SB_MAKEMASK1(41) +#define M_MAC_TX_UNDRFL _SB_MAKEMASK1(42) +#define M_MAC_TX_OVRFL _SB_MAKEMASK1(43) +#define M_MAC_LTCOL_ERR _SB_MAKEMASK1(44) +#define M_MAC_EXCOL_ERR _SB_MAKEMASK1(45) +#define M_MAC_CNTR_OVRFL_ERR _SB_MAKEMASK1(46) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_SPLIT_EN _SB_MAKEMASK1(47) /* interrupt mask only */ +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_MAC_COUNTER_ADDR _SB_MAKE64(47) +#define M_MAC_COUNTER_ADDR _SB_MAKEMASK(5,S_MAC_COUNTER_ADDR) +#define V_MAC_COUNTER_ADDR(x) _SB_MAKEVALUE(x,S_MAC_COUNTER_ADDR) +#define G_MAC_COUNTER_ADDR(x) _SB_GETVALUE(x,S_MAC_COUNTER_ADDR,M_MAC_COUNTER_ADDR) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_TX_PAUSE_ON _SB_MAKEMASK1(52) +#endif /* 112x PASS1 */ + +/* + * MAC Fifo Pointer Registers (Table 9-19) [Debug register] + * Register: MAC_FIFO_PTRS_0 + * Register: MAC_FIFO_PTRS_1 + * Register: MAC_FIFO_PTRS_2 + */ + +#define S_MAC_TX_WRPTR _SB_MAKE64(0) +#define M_MAC_TX_WRPTR _SB_MAKEMASK(6,S_MAC_TX_WRPTR) +#define V_MAC_TX_WRPTR(x) _SB_MAKEVALUE(x,S_MAC_TX_WRPTR) +#define G_MAC_TX_WRPTR(x) _SB_GETVALUE(x,S_MAC_TX_WRPTR,M_MAC_TX_WRPTR) + +#define S_MAC_TX_RDPTR _SB_MAKE64(8) +#define M_MAC_TX_RDPTR _SB_MAKEMASK(6,S_MAC_TX_RDPTR) +#define V_MAC_TX_RDPTR(x) _SB_MAKEVALUE(x,S_MAC_TX_RDPTR) +#define G_MAC_TX_RDPTR(x) _SB_GETVALUE(x,S_MAC_TX_RDPTR,M_MAC_TX_RDPTR) + +#define S_MAC_RX_WRPTR _SB_MAKE64(16) +#define M_MAC_RX_WRPTR _SB_MAKEMASK(6,S_MAC_RX_WRPTR) +#define V_MAC_RX_WRPTR(x) _SB_MAKEVALUE(x,S_MAC_RX_WRPTR) +#define G_MAC_RX_WRPTR(x) _SB_GETVALUE(x,S_MAC_RX_WRPTR,M_MAC_TX_WRPTR) + +#define S_MAC_RX_RDPTR _SB_MAKE64(24) +#define M_MAC_RX_RDPTR _SB_MAKEMASK(6,S_MAC_RX_RDPTR) +#define V_MAC_RX_RDPTR(x) _SB_MAKEVALUE(x,S_MAC_RX_RDPTR) +#define G_MAC_RX_RDPTR(x) _SB_GETVALUE(x,S_MAC_RX_RDPTR,M_MAC_TX_RDPTR) + +/* + * MAC Fifo End Of Packet Count Registers (Table 9-20) [Debug register] + * Register: MAC_EOPCNT_0 + * Register: MAC_EOPCNT_1 + * Register: MAC_EOPCNT_2 + */ + +#define S_MAC_TX_EOP_COUNTER _SB_MAKE64(0) +#define M_MAC_TX_EOP_COUNTER _SB_MAKEMASK(6,S_MAC_TX_EOP_COUNTER) +#define V_MAC_TX_EOP_COUNTER(x) _SB_MAKEVALUE(x,S_MAC_TX_EOP_COUNTER) +#define G_MAC_TX_EOP_COUNTER(x) _SB_GETVALUE(x,S_MAC_TX_EOP_COUNTER,M_MAC_TX_EOP_COUNTER) + +#define S_MAC_RX_EOP_COUNTER _SB_MAKE64(8) +#define M_MAC_RX_EOP_COUNTER _SB_MAKEMASK(6,S_MAC_RX_EOP_COUNTER) +#define V_MAC_RX_EOP_COUNTER(x) _SB_MAKEVALUE(x,S_MAC_RX_EOP_COUNTER) +#define G_MAC_RX_EOP_COUNTER(x) _SB_GETVALUE(x,S_MAC_RX_EOP_COUNTER,M_MAC_RX_EOP_COUNTER) + +/* + * MAC Recieve Address Filter Exact Match Registers (Table 9-21) + * Registers: MAC_ADDR0_0 through MAC_ADDR7_0 + * Registers: MAC_ADDR0_1 through MAC_ADDR7_1 + * Registers: MAC_ADDR0_2 through MAC_ADDR7_2 + */ + +/* No bitfields */ + +/* + * MAC Receive Address Filter Mask Registers + * Registers: MAC_ADDRMASK0_0 and MAC_ADDRMASK0_1 + * Registers: MAC_ADDRMASK1_0 and MAC_ADDRMASK1_1 + * Registers: MAC_ADDRMASK2_0 and MAC_ADDRMASK2_1 + */ + +/* No bitfields */ + +/* + * MAC Recieve Address Filter Hash Match Registers (Table 9-22) + * Registers: MAC_HASH0_0 through MAC_HASH7_0 + * Registers: MAC_HASH0_1 through MAC_HASH7_1 + * Registers: MAC_HASH0_2 through MAC_HASH7_2 + */ + +/* No bitfields */ + +/* + * MAC Transmit Source Address Registers (Table 9-23) + * Register: MAC_ETHERNET_ADDR_0 + * Register: MAC_ETHERNET_ADDR_1 + * Register: MAC_ETHERNET_ADDR_2 + */ + +/* No bitfields */ + +/* + * MAC Packet Type Configuration Register + * Register: MAC_TYPE_CFG_0 + * Register: MAC_TYPE_CFG_1 + * Register: MAC_TYPE_CFG_2 + */ + +#define S_TYPECFG_TYPESIZE _SB_MAKE64(16) + +#define S_TYPECFG_TYPE0 _SB_MAKE64(0) +#define M_TYPECFG_TYPE0 _SB_MAKEMASK(16,S_TYPECFG_TYPE0) +#define V_TYPECFG_TYPE0(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE0) +#define G_TYPECFG_TYPE0(x) _SB_GETVALUE(x,S_TYPECFG_TYPE0,M_TYPECFG_TYPE0) + +#define S_TYPECFG_TYPE1 _SB_MAKE64(0) +#define M_TYPECFG_TYPE1 _SB_MAKEMASK(16,S_TYPECFG_TYPE1) +#define V_TYPECFG_TYPE1(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE1) +#define G_TYPECFG_TYPE1(x) _SB_GETVALUE(x,S_TYPECFG_TYPE1,M_TYPECFG_TYPE1) + +#define S_TYPECFG_TYPE2 _SB_MAKE64(0) +#define M_TYPECFG_TYPE2 _SB_MAKEMASK(16,S_TYPECFG_TYPE2) +#define V_TYPECFG_TYPE2(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE2) +#define G_TYPECFG_TYPE2(x) _SB_GETVALUE(x,S_TYPECFG_TYPE2,M_TYPECFG_TYPE2) + +#define S_TYPECFG_TYPE3 _SB_MAKE64(0) +#define M_TYPECFG_TYPE3 _SB_MAKEMASK(16,S_TYPECFG_TYPE3) +#define V_TYPECFG_TYPE3(x) _SB_MAKEVALUE(x,S_TYPECFG_TYPE3) +#define G_TYPECFG_TYPE3(x) _SB_GETVALUE(x,S_TYPECFG_TYPE3,M_TYPECFG_TYPE3) + +/* + * MAC Receive Address Filter Control Registers (Table 9-24) + * Register: MAC_ADFILTER_CFG_0 + * Register: MAC_ADFILTER_CFG_1 + * Register: MAC_ADFILTER_CFG_2 + */ + +#define M_MAC_ALLPKT_EN _SB_MAKEMASK1(0) +#define M_MAC_UCAST_EN _SB_MAKEMASK1(1) +#define M_MAC_UCAST_INV _SB_MAKEMASK1(2) +#define M_MAC_MCAST_EN _SB_MAKEMASK1(3) +#define M_MAC_MCAST_INV _SB_MAKEMASK1(4) +#define M_MAC_BCAST_EN _SB_MAKEMASK1(5) +#define M_MAC_DIRECT_INV _SB_MAKEMASK1(6) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MAC_ALLMCAST_EN _SB_MAKEMASK1(7) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_MAC_IPHDR_OFFSET _SB_MAKE64(8) +#define M_MAC_IPHDR_OFFSET _SB_MAKEMASK(8,S_MAC_IPHDR_OFFSET) +#define V_MAC_IPHDR_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_IPHDR_OFFSET) +#define G_MAC_IPHDR_OFFSET(x) _SB_GETVALUE(x,S_MAC_IPHDR_OFFSET,M_MAC_IPHDR_OFFSET) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define S_MAC_RX_CRC_OFFSET _SB_MAKE64(16) +#define M_MAC_RX_CRC_OFFSET _SB_MAKEMASK(8,S_MAC_RX_CRC_OFFSET) +#define V_MAC_RX_CRC_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_RX_CRC_OFFSET) +#define G_MAC_RX_CRC_OFFSET(x) _SB_GETVALUE(x,S_MAC_RX_CRC_OFFSET,M_MAC_RX_CRC_OFFSET) + +#define S_MAC_RX_PKT_OFFSET _SB_MAKE64(24) +#define M_MAC_RX_PKT_OFFSET _SB_MAKEMASK(8,S_MAC_RX_PKT_OFFSET) +#define V_MAC_RX_PKT_OFFSET(x) _SB_MAKEVALUE(x,S_MAC_RX_PKT_OFFSET) +#define G_MAC_RX_PKT_OFFSET(x) _SB_GETVALUE(x,S_MAC_RX_PKT_OFFSET,M_MAC_RX_PKT_OFFSET) + +#define M_MAC_FWDPAUSE_EN _SB_MAKEMASK1(32) +#define M_MAC_VLAN_DET_EN _SB_MAKEMASK1(33) + +#define S_MAC_RX_CH_MSN_SEL _SB_MAKE64(34) +#define M_MAC_RX_CH_MSN_SEL _SB_MAKEMASK(8,S_MAC_RX_CH_MSN_SEL) +#define V_MAC_RX_CH_MSN_SEL(x) _SB_MAKEVALUE(x,S_MAC_RX_CH_MSN_SEL) +#define G_MAC_RX_CH_MSN_SEL(x) _SB_GETVALUE(x,S_MAC_RX_CH_MSN_SEL,M_MAC_RX_CH_MSN_SEL) +#endif /* 112x PASS1 */ + +/* + * MAC Receive Channel Select Registers (Table 9-25) + */ + +/* no bitfields */ + +/* + * MAC MII Management Interface Registers (Table 9-26) + * Register: MAC_MDIO_0 + * Register: MAC_MDIO_1 + * Register: MAC_MDIO_2 + */ + +#define S_MAC_MDC 0 +#define S_MAC_MDIO_DIR 1 +#define S_MAC_MDIO_OUT 2 +#define S_MAC_GENC 3 +#define S_MAC_MDIO_IN 4 + +#define M_MAC_MDC _SB_MAKEMASK1(S_MAC_MDC) +#define M_MAC_MDIO_DIR _SB_MAKEMASK1(S_MAC_MDIO_DIR) +#define M_MAC_MDIO_DIR_INPUT _SB_MAKEMASK1(S_MAC_MDIO_DIR) +#define M_MAC_MDIO_OUT _SB_MAKEMASK1(S_MAC_MDIO_OUT) +#define M_MAC_GENC _SB_MAKEMASK1(S_MAC_GENC) +#define M_MAC_MDIO_IN _SB_MAKEMASK1(S_MAC_MDIO_IN) + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_mc.h b/include/asm-mips64/sibyte/sb1250_mc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_mc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,548 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Memory Controller constants File: sb1250_mc.h + * + * This module contains constants and macros useful for + * programming the memory controller. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_MC_H +#define _SB1250_MC_H + +#include "sb1250_defs.h" + +/* + * Memory Channel Config Register (table 6-14) + */ + +#define S_MC_RESERVED0 0 +#define M_MC_RESERVED0 _SB_MAKEMASK(8,S_MC_RESERVED0) + +#define S_MC_CHANNEL_SEL 8 +#define M_MC_CHANNEL_SEL _SB_MAKEMASK(8,S_MC_CHANNEL_SEL) +#define V_MC_CHANNEL_SEL(x) _SB_MAKEVALUE(x,S_MC_CHANNEL_SEL) +#define G_MC_CHANNEL_SEL(x) _SB_GETVALUE(x,S_MC_CHANNEL_SEL,M_MC_CHANNEL_SEL) + +#define S_MC_BANK0_MAP 16 +#define M_MC_BANK0_MAP _SB_MAKEMASK(4,S_MC_BANK0_MAP) +#define V_MC_BANK0_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK0_MAP) +#define G_MC_BANK0_MAP(x) _SB_GETVALUE(x,S_MC_BANK0_MAP,M_MC_BANK0_MAP) + +#define K_MC_BANK0_MAP_DEFAULT 0x00 +#define V_MC_BANK0_MAP_DEFAULT V_MC_BANK0_MAP(K_MC_BANK0_MAP_DEFAULT) + +#define S_MC_BANK1_MAP 20 +#define M_MC_BANK1_MAP _SB_MAKEMASK(4,S_MC_BANK1_MAP) +#define V_MC_BANK1_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK1_MAP) +#define G_MC_BANK1_MAP(x) _SB_GETVALUE(x,S_MC_BANK1_MAP,M_MC_BANK1_MAP) + +#define K_MC_BANK1_MAP_DEFAULT 0x08 +#define V_MC_BANK1_MAP_DEFAULT V_MC_BANK1_MAP(K_MC_BANK1_MAP_DEFAULT) + +#define S_MC_BANK2_MAP 24 +#define M_MC_BANK2_MAP _SB_MAKEMASK(4,S_MC_BANK2_MAP) +#define V_MC_BANK2_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK2_MAP) +#define G_MC_BANK2_MAP(x) _SB_GETVALUE(x,S_MC_BANK2_MAP,M_MC_BANK2_MAP) + +#define K_MC_BANK2_MAP_DEFAULT 0x09 +#define V_MC_BANK2_MAP_DEFAULT V_MC_BANK2_MAP(K_MC_BANK2_MAP_DEFAULT) + +#define S_MC_BANK3_MAP 28 +#define M_MC_BANK3_MAP _SB_MAKEMASK(4,S_MC_BANK3_MAP) +#define V_MC_BANK3_MAP(x) _SB_MAKEVALUE(x,S_MC_BANK3_MAP) +#define G_MC_BANK3_MAP(x) _SB_GETVALUE(x,S_MC_BANK3_MAP,M_MC_BANK3_MAP) + +#define K_MC_BANK3_MAP_DEFAULT 0x0C +#define V_MC_BANK3_MAP_DEFAULT V_MC_BANK3_MAP(K_MC_BANK3_MAP_DEFAULT) + +#define M_MC_RESERVED1 _SB_MAKEMASK(8,32) + +#define S_MC_QUEUE_SIZE 40 +#define M_MC_QUEUE_SIZE _SB_MAKEMASK(4,S_MC_QUEUE_SIZE) +#define V_MC_QUEUE_SIZE(x) _SB_MAKEVALUE(x,S_MC_QUEUE_SIZE) +#define G_MC_QUEUE_SIZE(x) _SB_GETVALUE(x,S_MC_QUEUE_SIZE,M_MC_QUEUE_SIZE) +#define V_MC_QUEUE_SIZE_DEFAULT V_MC_QUEUE_SIZE(0x0A) + +#define S_MC_AGE_LIMIT 44 +#define M_MC_AGE_LIMIT _SB_MAKEMASK(4,S_MC_AGE_LIMIT) +#define V_MC_AGE_LIMIT(x) _SB_MAKEVALUE(x,S_MC_AGE_LIMIT) +#define G_MC_AGE_LIMIT(x) _SB_GETVALUE(x,S_MC_AGE_LIMIT,M_MC_AGE_LIMIT) +#define V_MC_AGE_LIMIT_DEFAULT V_MC_AGE_LIMIT(8) + +#define S_MC_WR_LIMIT 48 +#define M_MC_WR_LIMIT _SB_MAKEMASK(4,S_MC_WR_LIMIT) +#define V_MC_WR_LIMIT(x) _SB_MAKEVALUE(x,S_MC_WR_LIMIT) +#define G_MC_WR_LIMIT(x) _SB_GETVALUE(x,S_MC_WR_LIMIT,M_MC_WR_LIMIT) +#define V_MC_WR_LIMIT_DEFAULT V_MC_WR_LIMIT(5) + +#define M_MC_IOB1HIGHPRIORITY _SB_MAKEMASK1(52) + +#define M_MC_RESERVED2 _SB_MAKEMASK(3,53) + +#define S_MC_CS_MODE 56 +#define M_MC_CS_MODE _SB_MAKEMASK(4,S_MC_CS_MODE) +#define V_MC_CS_MODE(x) _SB_MAKEVALUE(x,S_MC_CS_MODE) +#define G_MC_CS_MODE(x) _SB_GETVALUE(x,S_MC_CS_MODE,M_MC_CS_MODE) + +#define K_MC_CS_MODE_MSB_CS 0 +#define K_MC_CS_MODE_INTLV_CS 15 +#define K_MC_CS_MODE_MIXED_CS_10 12 +#define K_MC_CS_MODE_MIXED_CS_30 6 +#define K_MC_CS_MODE_MIXED_CS_32 3 + +#define V_MC_CS_MODE_MSB_CS V_MC_CS_MODE(K_MC_CS_MODE_MSB_CS) +#define V_MC_CS_MODE_INTLV_CS V_MC_CS_MODE(K_MC_CS_MODE_INTLV_CS) +#define V_MC_CS_MODE_MIXED_CS_10 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_10) +#define V_MC_CS_MODE_MIXED_CS_30 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_30) +#define V_MC_CS_MODE_MIXED_CS_32 V_MC_CS_MODE(K_MC_CS_MODE_MIXED_CS_32) + +#define M_MC_ECC_DISABLE _SB_MAKEMASK1(60) +#define M_MC_BERR_DISABLE _SB_MAKEMASK1(61) +#define M_MC_FORCE_SEQ _SB_MAKEMASK1(62) +#define M_MC_DEBUG _SB_MAKEMASK1(63) + +#define V_MC_CONFIG_DEFAULT V_MC_WR_LIMIT_DEFAULT | V_MC_AGE_LIMIT_DEFAULT | \ + V_MC_BANK0_MAP_DEFAULT | V_MC_BANK1_MAP_DEFAULT | \ + V_MC_BANK2_MAP_DEFAULT | V_MC_BANK3_MAP_DEFAULT | V_MC_CHANNEL_SEL(0) | \ + M_MC_IOB1HIGHPRIORITY | V_MC_QUEUE_SIZE_DEFAULT + + +/* + * Memory clock config register (Table 6-15) + * + * Note: this field has been updated to be consistent with the errata to 0.2 + */ + +#define S_MC_CLK_RATIO 0 +#define M_MC_CLK_RATIO _SB_MAKEMASK(4,S_MC_CLK_RATIO) +#define V_MC_CLK_RATIO(x) _SB_MAKEVALUE(x,S_MC_CLK_RATIO) +#define G_MC_CLK_RATIO(x) _SB_GETVALUE(x,S_MC_CLK_RATIO,M_MC_CLK_RATIO) + +#define K_MC_CLK_RATIO_2X 4 +#define K_MC_CLK_RATIO_25X 5 +#define K_MC_CLK_RATIO_3X 6 +#define K_MC_CLK_RATIO_35X 7 +#define K_MC_CLK_RATIO_4X 8 +#define K_MC_CLK_RATIO_45X 9 + +#define V_MC_CLK_RATIO_2X V_MC_CLK_RATIO(K_MC_CLK_RATIO_2X) +#define V_MC_CLK_RATIO_25X V_MC_CLK_RATIO(K_MC_CLK_RATIO_25X) +#define V_MC_CLK_RATIO_3X V_MC_CLK_RATIO(K_MC_CLK_RATIO_3X) +#define V_MC_CLK_RATIO_35X V_MC_CLK_RATIO(K_MC_CLK_RATIO_35X) +#define V_MC_CLK_RATIO_4X V_MC_CLK_RATIO(K_MC_CLK_RATIO_4X) +#define V_MC_CLK_RATIO_45X V_MC_CLK_RATIO(K_MC_CLK_RATIO_45X) +#define V_MC_CLK_RATIO_DEFAULT V_MC_CLK_RATIO_25X + +#define S_MC_REF_RATE 8 +#define M_MC_REF_RATE _SB_MAKEMASK(8,S_MC_REF_RATE) +#define V_MC_REF_RATE(x) _SB_MAKEVALUE(x,S_MC_REF_RATE) +#define G_MC_REF_RATE(x) _SB_GETVALUE(x,S_MC_REF_RATE,M_MC_REF_RATE) + +#define K_MC_REF_RATE_100MHz 0x62 +#define K_MC_REF_RATE_133MHz 0x81 +#define K_MC_REF_RATE_200MHz 0xC4 + +#define V_MC_REF_RATE_100MHz V_MC_REF_RATE(K_MC_REF_RATE_100MHz) +#define V_MC_REF_RATE_133MHz V_MC_REF_RATE(K_MC_REF_RATE_133MHz) +#define V_MC_REF_RATE_200MHz V_MC_REF_RATE(K_MC_REF_RATE_200MHz) +#define V_MC_REF_RATE_DEFAULT V_MC_REF_RATE_100MHz + +#define S_MC_CLOCK_DRIVE 16 +#define M_MC_CLOCK_DRIVE _SB_MAKEMASK(4,S_MC_CLOCK_DRIVE) +#define V_MC_CLOCK_DRIVE(x) _SB_MAKEVALUE(x,S_MC_CLOCK_DRIVE) +#define G_MC_CLOCK_DRIVE(x) _SB_GETVALUE(x,S_MC_CLOCK_DRIVE,M_MC_CLOCK_DRIVE) +#define V_MC_CLOCK_DRIVE_DEFAULT V_MC_CLOCK_DRIVE(0xF) + +#define S_MC_DATA_DRIVE 20 +#define M_MC_DATA_DRIVE _SB_MAKEMASK(4,S_MC_DATA_DRIVE) +#define V_MC_DATA_DRIVE(x) _SB_MAKEVALUE(x,S_MC_DATA_DRIVE) +#define G_MC_DATA_DRIVE(x) _SB_GETVALUE(x,S_MC_DATA_DRIVE,M_MC_DATA_DRIVE) +#define V_MC_DATA_DRIVE_DEFAULT V_MC_DATA_DRIVE(0x0) + +#define S_MC_ADDR_DRIVE 24 +#define M_MC_ADDR_DRIVE _SB_MAKEMASK(4,S_MC_ADDR_DRIVE) +#define V_MC_ADDR_DRIVE(x) _SB_MAKEVALUE(x,S_MC_ADDR_DRIVE) +#define G_MC_ADDR_DRIVE(x) _SB_GETVALUE(x,S_MC_ADDR_DRIVE,M_MC_ADDR_DRIVE) +#define V_MC_ADDR_DRIVE_DEFAULT V_MC_ADDR_DRIVE(0x0) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MC_REF_DISABLE _SB_MAKEMASK1(30) +#endif /* 112x PASS1 */ + +#define M_MC_DLL_BYPASS _SB_MAKEMASK1(31) + +#define S_MC_DQI_SKEW 32 +#define M_MC_DQI_SKEW _SB_MAKEMASK(8,S_MC_DQI_SKEW) +#define V_MC_DQI_SKEW(x) _SB_MAKEVALUE(x,S_MC_DQI_SKEW) +#define G_MC_DQI_SKEW(x) _SB_GETVALUE(x,S_MC_DQI_SKEW,M_MC_DQI_SKEW) +#define V_MC_DQI_SKEW_DEFAULT V_MC_DQI_SKEW(0) + +#define S_MC_DQO_SKEW 40 +#define M_MC_DQO_SKEW _SB_MAKEMASK(8,S_MC_DQO_SKEW) +#define V_MC_DQO_SKEW(x) _SB_MAKEVALUE(x,S_MC_DQO_SKEW) +#define G_MC_DQO_SKEW(x) _SB_GETVALUE(x,S_MC_DQO_SKEW,M_MC_DQO_SKEW) +#define V_MC_DQO_SKEW_DEFAULT V_MC_DQO_SKEW(0) + +#define S_MC_ADDR_SKEW 48 +#define M_MC_ADDR_SKEW _SB_MAKEMASK(8,S_MC_ADDR_SKEW) +#define V_MC_ADDR_SKEW(x) _SB_MAKEVALUE(x,S_MC_ADDR_SKEW) +#define G_MC_ADDR_SKEW(x) _SB_GETVALUE(x,S_MC_ADDR_SKEW,M_MC_ADDR_SKEW) +#define V_MC_ADDR_SKEW_DEFAULT V_MC_ADDR_SKEW(0x0F) + +#define S_MC_DLL_DEFAULT 56 +#define M_MC_DLL_DEFAULT _SB_MAKEMASK(8,S_MC_DLL_DEFAULT) +#define V_MC_DLL_DEFAULT(x) _SB_MAKEVALUE(x,S_MC_DLL_DEFAULT) +#define G_MC_DLL_DEFAULT(x) _SB_GETVALUE(x,S_MC_DLL_DEFAULT,M_MC_DLL_DEFAULT) +#define V_MC_DLL_DEFAULT_DEFAULT V_MC_DLL_DEFAULT(0x10) + +#define V_MC_CLKCONFIG_DEFAULT V_MC_DLL_DEFAULT_DEFAULT | \ + V_MC_ADDR_SKEW_DEFAULT | \ + V_MC_DQO_SKEW_DEFAULT | \ + V_MC_DQI_SKEW_DEFAULT | \ + V_MC_ADDR_DRIVE_DEFAULT | \ + V_MC_DATA_DRIVE_DEFAULT | \ + V_MC_CLOCK_DRIVE_DEFAULT | \ + V_MC_REF_RATE_DEFAULT + + + +/* + * DRAM Command Register (Table 6-13) + */ + +#define S_MC_COMMAND 0 +#define M_MC_COMMAND _SB_MAKEMASK(4,S_MC_COMMAND) +#define V_MC_COMMAND(x) _SB_MAKEVALUE(x,S_MC_COMMAND) +#define G_MC_COMMAND(x) _SB_GETVALUE(x,S_MC_COMMAND,M_MC_COMMAND) + +#define K_MC_COMMAND_EMRS 0 +#define K_MC_COMMAND_MRS 1 +#define K_MC_COMMAND_PRE 2 +#define K_MC_COMMAND_AR 3 +#define K_MC_COMMAND_SETRFSH 4 +#define K_MC_COMMAND_CLRRFSH 5 +#define K_MC_COMMAND_SETPWRDN 6 +#define K_MC_COMMAND_CLRPWRDN 7 + +#define V_MC_COMMAND_EMRS V_MC_COMMAND(K_MC_COMMAND_EMRS) +#define V_MC_COMMAND_MRS V_MC_COMMAND(K_MC_COMMAND_MRS) +#define V_MC_COMMAND_PRE V_MC_COMMAND(K_MC_COMMAND_PRE) +#define V_MC_COMMAND_AR V_MC_COMMAND(K_MC_COMMAND_AR) +#define V_MC_COMMAND_SETRFSH V_MC_COMMAND(K_MC_COMMAND_SETRFSH) +#define V_MC_COMMAND_CLRRFSH V_MC_COMMAND(K_MC_COMMAND_CLRRFSH) +#define V_MC_COMMAND_SETPWRDN V_MC_COMMAND(K_MC_COMMAND_SETPWRDN) +#define V_MC_COMMAND_CLRPWRDN V_MC_COMMAND(K_MC_COMMAND_CLRPWRDN) + +#define M_MC_CS0 _SB_MAKEMASK1(4) +#define M_MC_CS1 _SB_MAKEMASK1(5) +#define M_MC_CS2 _SB_MAKEMASK1(6) +#define M_MC_CS3 _SB_MAKEMASK1(7) + +/* + * DRAM Mode Register (Table 6-14) + */ + +#define S_MC_EMODE 0 +#define M_MC_EMODE _SB_MAKEMASK(15,S_MC_EMODE) +#define V_MC_EMODE(x) _SB_MAKEVALUE(x,S_MC_EMODE) +#define G_MC_EMODE(x) _SB_GETVALUE(x,S_MC_EMODE,M_MC_EMODE) +#define V_MC_EMODE_DEFAULT V_MC_EMODE(0) + +#define S_MC_MODE 16 +#define M_MC_MODE _SB_MAKEMASK(15,S_MC_MODE) +#define V_MC_MODE(x) _SB_MAKEVALUE(x,S_MC_MODE) +#define G_MC_MODE(x) _SB_GETVALUE(x,S_MC_MODE,M_MC_MODE) +#define V_MC_MODE_DEFAULT V_MC_MODE(0x22) + +#define S_MC_DRAM_TYPE 32 +#define M_MC_DRAM_TYPE _SB_MAKEMASK(3,S_MC_DRAM_TYPE) +#define V_MC_DRAM_TYPE(x) _SB_MAKEVALUE(x,S_MC_DRAM_TYPE) +#define G_MC_DRAM_TYPE(x) _SB_GETVALUE(x,S_MC_DRAM_TYPE,M_MC_DRAM_TYPE) + +#define K_MC_DRAM_TYPE_JEDEC 0 +#define K_MC_DRAM_TYPE_FCRAM 1 +#define K_MC_DRAM_TYPE_SGRAM 2 + +#define V_MC_DRAM_TYPE_JEDEC V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_JEDEC) +#define V_MC_DRAM_TYPE_FCRAM V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_FCRAM) +#define V_MC_DRAM_TYPE_SGRAM V_MC_DRAM_TYPE(K_MC_DRAM_TYPE_SGRAM) + +#define M_MC_EXTERNALDECODE _SB_MAKEMASK1(35) + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_MC_PRE_ON_A8 _SB_MAKEMASK1(36) +#define M_MC_RAM_WITH_A13 _SB_MAKEMASK1(38) +#endif /* 112x PASS1 */ + + + +/* + * SDRAM Timing Register (Table 6-15) + */ + +#define M_MC_w2rIDLE_TWOCYCLES _SB_MAKEMASK1(60) +#define M_MC_r2wIDLE_TWOCYCLES _SB_MAKEMASK1(61) +#define M_MC_r2rIDLE_TWOCYCLES _SB_MAKEMASK1(62) + +#define S_MC_tFIFO 56 +#define M_MC_tFIFO _SB_MAKEMASK(4,S_MC_tFIFO) +#define V_MC_tFIFO(x) _SB_MAKEVALUE(x,S_MC_tFIFO) +#define G_MC_tFIFO(x) _SB_GETVALUE(x,S_MC_tFIFO,M_MC_tFIFO) +#define K_MC_tFIFO_DEFAULT 1 +#define V_MC_tFIFO_DEFAULT V_MC_tFIFO(K_MC_tFIFO_DEFAULT) + +#define S_MC_tRFC 52 +#define M_MC_tRFC _SB_MAKEMASK(4,S_MC_tRFC) +#define V_MC_tRFC(x) _SB_MAKEVALUE(x,S_MC_tRFC) +#define G_MC_tRFC(x) _SB_GETVALUE(x,S_MC_tRFC,M_MC_tRFC) +#define K_MC_tRFC_DEFAULT 12 +#define V_MC_tRFC_DEFAULT V_MC_tRFC(K_MC_tRFC_DEFAULT) + +#define S_MC_tCwCr 40 +#define M_MC_tCwCr _SB_MAKEMASK(4,S_MC_tCwCr) +#define V_MC_tCwCr(x) _SB_MAKEVALUE(x,S_MC_tCwCr) +#define G_MC_tCwCr(x) _SB_GETVALUE(x,S_MC_tCwCr,M_MC_tCwCr) +#define K_MC_tCwCr_DEFAULT 4 +#define V_MC_tCwCr_DEFAULT V_MC_tCwCr(K_MC_tCwCr_DEFAULT) + +#define S_MC_tRCr 28 +#define M_MC_tRCr _SB_MAKEMASK(4,S_MC_tRCr) +#define V_MC_tRCr(x) _SB_MAKEVALUE(x,S_MC_tRCr) +#define G_MC_tRCr(x) _SB_GETVALUE(x,S_MC_tRCr,M_MC_tRCr) +#define K_MC_tRCr_DEFAULT 9 +#define V_MC_tRCr_DEFAULT V_MC_tRCr(K_MC_tRCr_DEFAULT) + +#define S_MC_tRCw 24 +#define M_MC_tRCw _SB_MAKEMASK(4,S_MC_tRCw) +#define V_MC_tRCw(x) _SB_MAKEVALUE(x,S_MC_tRCw) +#define G_MC_tRCw(x) _SB_GETVALUE(x,S_MC_tRCw,M_MC_tRCw) +#define K_MC_tRCw_DEFAULT 10 +#define V_MC_tRCw_DEFAULT V_MC_tRCw(K_MC_tRCw_DEFAULT) + +#define S_MC_tRRD 20 +#define M_MC_tRRD _SB_MAKEMASK(4,S_MC_tRRD) +#define V_MC_tRRD(x) _SB_MAKEVALUE(x,S_MC_tRRD) +#define G_MC_tRRD(x) _SB_GETVALUE(x,S_MC_tRRD,M_MC_tRRD) +#define K_MC_tRRD_DEFAULT 2 +#define V_MC_tRRD_DEFAULT V_MC_tRRD(K_MC_tRRD_DEFAULT) + +#define S_MC_tRP 16 +#define M_MC_tRP _SB_MAKEMASK(4,S_MC_tRP) +#define V_MC_tRP(x) _SB_MAKEVALUE(x,S_MC_tRP) +#define G_MC_tRP(x) _SB_GETVALUE(x,S_MC_tRP,M_MC_tRP) +#define K_MC_tRP_DEFAULT 4 +#define V_MC_tRP_DEFAULT V_MC_tRP(K_MC_tRP_DEFAULT) + +#define S_MC_tCwD 8 +#define M_MC_tCwD _SB_MAKEMASK(4,S_MC_tCwD) +#define V_MC_tCwD(x) _SB_MAKEVALUE(x,S_MC_tCwD) +#define G_MC_tCwD(x) _SB_GETVALUE(x,S_MC_tCwD,M_MC_tCwD) +#define K_MC_tCwD_DEFAULT 1 +#define V_MC_tCwD_DEFAULT V_MC_tCwD(K_MC_tCwD_DEFAULT) + +#define M_tCrDh _SB_MAKEMASK1(7) +#define M_MC_tCrDh M_tCrDh + +#define S_MC_tCrD 4 +#define M_MC_tCrD _SB_MAKEMASK(3,S_MC_tCrD) +#define V_MC_tCrD(x) _SB_MAKEVALUE(x,S_MC_tCrD) +#define G_MC_tCrD(x) _SB_GETVALUE(x,S_MC_tCrD,M_MC_tCrD) +#define K_MC_tCrD_DEFAULT 2 +#define V_MC_tCrD_DEFAULT V_MC_tCrD(K_MC_tCrD_DEFAULT) + +#define S_MC_tRCD 0 +#define M_MC_tRCD _SB_MAKEMASK(4,S_MC_tRCD) +#define V_MC_tRCD(x) _SB_MAKEVALUE(x,S_MC_tRCD) +#define G_MC_tRCD(x) _SB_GETVALUE(x,S_MC_tRCD,M_MC_tRCD) +#define K_MC_tRCD_DEFAULT 3 +#define V_MC_tRCD_DEFAULT V_MC_tRCD(K_MC_tRCD_DEFAULT) + +#define V_MC_TIMING_DEFAULT V_MC_tFIFO(K_MC_tFIFO_DEFAULT) | \ + V_MC_tRFC(K_MC_tRFC_DEFAULT) | \ + V_MC_tCwCr(K_MC_tCwCr_DEFAULT) | \ + V_MC_tRCr(K_MC_tRCr_DEFAULT) | \ + V_MC_tRCw(K_MC_tRCw_DEFAULT) | \ + V_MC_tRRD(K_MC_tRRD_DEFAULT) | \ + V_MC_tRP(K_MC_tRP_DEFAULT) | \ + V_MC_tCwD(K_MC_tCwD_DEFAULT) | \ + V_MC_tCrD(K_MC_tCrD_DEFAULT) | \ + V_MC_tRCD(K_MC_tRCD_DEFAULT) | \ + M_MC_r2rIDLE_TWOCYCLES + +/* + * Errata says these are not the default + * M_MC_w2rIDLE_TWOCYCLES | \ + * M_MC_r2wIDLE_TWOCYCLES | \ + */ + + +/* + * Chip Select Start Address Register (Table 6-17) + */ + +#define S_MC_CS0_START 0 +#define M_MC_CS0_START _SB_MAKEMASK(16,S_MC_CS0_START) +#define V_MC_CS0_START(x) _SB_MAKEVALUE(x,S_MC_CS0_START) +#define G_MC_CS0_START(x) _SB_GETVALUE(x,S_MC_CS0_START,M_MC_CS0_START) + +#define S_MC_CS1_START 16 +#define M_MC_CS1_START _SB_MAKEMASK(16,S_MC_CS1_START) +#define V_MC_CS1_START(x) _SB_MAKEVALUE(x,S_MC_CS1_START) +#define G_MC_CS1_START(x) _SB_GETVALUE(x,S_MC_CS1_START,M_MC_CS1_START) + +#define S_MC_CS2_START 32 +#define M_MC_CS2_START _SB_MAKEMASK(16,S_MC_CS2_START) +#define V_MC_CS2_START(x) _SB_MAKEVALUE(x,S_MC_CS2_START) +#define G_MC_CS2_START(x) _SB_GETVALUE(x,S_MC_CS2_START,M_MC_CS2_START) + +#define S_MC_CS3_START 48 +#define M_MC_CS3_START _SB_MAKEMASK(16,S_MC_CS3_START) +#define V_MC_CS3_START(x) _SB_MAKEVALUE(x,S_MC_CS3_START) +#define G_MC_CS3_START(x) _SB_GETVALUE(x,S_MC_CS3_START,M_MC_CS3_START) + +/* + * Chip Select End Address Register (Table 6-18) + */ + +#define S_MC_CS0_END 0 +#define M_MC_CS0_END _SB_MAKEMASK(16,S_MC_CS0_END) +#define V_MC_CS0_END(x) _SB_MAKEVALUE(x,S_MC_CS0_END) +#define G_MC_CS0_END(x) _SB_GETVALUE(x,S_MC_CS0_END,M_MC_CS0_END) + +#define S_MC_CS1_END 16 +#define M_MC_CS1_END _SB_MAKEMASK(16,S_MC_CS1_END) +#define V_MC_CS1_END(x) _SB_MAKEVALUE(x,S_MC_CS1_END) +#define G_MC_CS1_END(x) _SB_GETVALUE(x,S_MC_CS1_END,M_MC_CS1_END) + +#define S_MC_CS2_END 32 +#define M_MC_CS2_END _SB_MAKEMASK(16,S_MC_CS2_END) +#define V_MC_CS2_END(x) _SB_MAKEVALUE(x,S_MC_CS2_END) +#define G_MC_CS2_END(x) _SB_GETVALUE(x,S_MC_CS2_END,M_MC_CS2_END) + +#define S_MC_CS3_END 48 +#define M_MC_CS3_END _SB_MAKEMASK(16,S_MC_CS3_END) +#define V_MC_CS3_END(x) _SB_MAKEVALUE(x,S_MC_CS3_END) +#define G_MC_CS3_END(x) _SB_GETVALUE(x,S_MC_CS3_END,M_MC_CS3_END) + +/* + * Chip Select Interleave Register (Table 6-19) + */ + +#define S_MC_INTLV_RESERVED 0 +#define M_MC_INTLV_RESERVED _SB_MAKEMASK(5,S_MC_INTLV_RESERVED) + +#define S_MC_INTERLEAVE 7 +#define M_MC_INTERLEAVE _SB_MAKEMASK(18,S_MC_INTERLEAVE) +#define V_MC_INTERLEAVE(x) _SB_MAKEVALUE(x,S_MC_INTERLEAVE) + +#define S_MC_INTLV_MBZ 25 +#define M_MC_INTLV_MBZ _SB_MAKEMASK(39,S_MC_INTLV_MBZ) + +/* + * Row Address Bits Register (Table 6-20) + */ + +#define S_MC_RAS_RESERVED 0 +#define M_MC_RAS_RESERVED _SB_MAKEMASK(5,S_MC_RAS_RESERVED) + +#define S_MC_RAS_SELECT 12 +#define M_MC_RAS_SELECT _SB_MAKEMASK(25,S_MC_RAS_SELECT) +#define V_MC_RAS_SELECT(x) _SB_MAKEVALUE(x,S_MC_RAS_SELECT) + +#define S_MC_RAS_MBZ 37 +#define M_MC_RAS_MBZ _SB_MAKEMASK(27,S_MC_RAS_MBZ) + + +/* + * Column Address Bits Register (Table 6-21) + */ + +#define S_MC_CAS_RESERVED 0 +#define M_MC_CAS_RESERVED _SB_MAKEMASK(5,S_MC_CAS_RESERVED) + +#define S_MC_CAS_SELECT 5 +#define M_MC_CAS_SELECT _SB_MAKEMASK(18,S_MC_CAS_SELECT) +#define V_MC_CAS_SELECT(x) _SB_MAKEVALUE(x,S_MC_CAS_SELECT) + +#define S_MC_CAS_MBZ 23 +#define M_MC_CAS_MBZ _SB_MAKEMASK(41,S_MC_CAS_MBZ) + + +/* + * Bank Address Address Bits Register (Table 6-22) + */ + +#define S_MC_BA_RESERVED 0 +#define M_MC_BA_RESERVED _SB_MAKEMASK(5,S_MC_BA_RESERVED) + +#define S_MC_BA_SELECT 5 +#define M_MC_BA_SELECT _SB_MAKEMASK(20,S_MC_BA_SELECT) +#define V_MC_BA_SELECT(x) _SB_MAKEVALUE(x,S_MC_BA_SELECT) + +#define S_MC_BA_MBZ 25 +#define M_MC_BA_MBZ _SB_MAKEMASK(39,S_MC_BA_MBZ) + +/* + * Chip Select Attribute Register (Table 6-23) + */ + +#define K_MC_CS_ATTR_CLOSED 0 +#define K_MC_CS_ATTR_CASCHECK 1 +#define K_MC_CS_ATTR_HINT 2 +#define K_MC_CS_ATTR_OPEN 3 + +#define S_MC_CS0_PAGE 0 +#define M_MC_CS0_PAGE _SB_MAKEMASK(2,S_MC_CS0_PAGE) +#define V_MC_CS0_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS0_PAGE) +#define G_MC_CS0_PAGE(x) _SB_GETVALUE(x,S_MC_CS0_PAGE,M_MC_CS0_PAGE) + +#define S_MC_CS1_PAGE 16 +#define M_MC_CS1_PAGE _SB_MAKEMASK(2,S_MC_CS1_PAGE) +#define V_MC_CS1_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS1_PAGE) +#define G_MC_CS1_PAGE(x) _SB_GETVALUE(x,S_MC_CS1_PAGE,M_MC_CS1_PAGE) + +#define S_MC_CS2_PAGE 32 +#define M_MC_CS2_PAGE _SB_MAKEMASK(2,S_MC_CS2_PAGE) +#define V_MC_CS2_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS2_PAGE) +#define G_MC_CS2_PAGE(x) _SB_GETVALUE(x,S_MC_CS2_PAGE,M_MC_CS2_PAGE) + +#define S_MC_CS3_PAGE 48 +#define M_MC_CS3_PAGE _SB_MAKEMASK(2,S_MC_CS3_PAGE) +#define V_MC_CS3_PAGE(x) _SB_MAKEVALUE(x,S_MC_CS3_PAGE) +#define G_MC_CS3_PAGE(x) _SB_GETVALUE(x,S_MC_CS3_PAGE,M_MC_CS3_PAGE) + +/* + * ECC Test ECC Register (Table 6-25) + */ + +#define S_MC_ECC_INVERT 0 +#define M_MC_ECC_INVERT _SB_MAKEMASK(8,S_MC_ECC_INVERT) + + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_regs.h b/include/asm-mips64/sibyte/sb1250_regs.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_regs.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,835 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Register Definitions File: sb1250_regs.h + * + * This module contains the addresses of the on-chip peripherals + * on the SB1250. + * + * SB1250 specification level: 01/02/2002 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_REGS_H +#define _SB1250_REGS_H + +#include "sb1250_defs.h" + + +/* ********************************************************************* + * Some general notes: + * + * For the most part, when there is more than one peripheral + * of the same type on the SOC, the constants below will be + * offsets from the base of each peripheral. For example, + * the MAC registers are described as offsets from the first + * MAC register, and there will be a MAC_REGISTER() macro + * to calculate the base address of a given MAC. + * + * The information in this file is based on the SB1250 SOC + * manual version 0.2, July 2000. + ********************************************************************* */ + + +/* ********************************************************************* + * Memory Controller Registers + ********************************************************************* */ + +/* + * XXX: can't remove MC base 0 if 112x, since it's used by other macros, + * since there is one reg there (but it could get its addr/offset constant). + */ +#define A_MC_BASE_0 0x0010051000 +#define A_MC_BASE_1 0x0010052000 +#define MC_REGISTER_SPACING 0x1000 + +#define A_MC_BASE(ctlid) ((ctlid)*MC_REGISTER_SPACING+A_MC_BASE_0) +#define A_MC_REGISTER(ctlid,reg) (A_MC_BASE(ctlid)+(reg)) + +#define R_MC_CONFIG 0x0000000100 +#define R_MC_DRAMCMD 0x0000000120 +#define R_MC_DRAMMODE 0x0000000140 +#define R_MC_TIMING1 0x0000000160 +#define R_MC_TIMING2 0x0000000180 +#define R_MC_CS_START 0x00000001A0 +#define R_MC_CS_END 0x00000001C0 +#define R_MC_CS_INTERLEAVE 0x00000001E0 +#define S_MC_CS_STARTEND 16 + +#define R_MC_CSX_BASE 0x0000000200 +#define R_MC_CSX_ROW 0x0000000000 /* relative to CSX_BASE, above */ +#define R_MC_CSX_COL 0x0000000020 /* relative to CSX_BASE, above */ +#define R_MC_CSX_BA 0x0000000040 /* relative to CSX_BASE, above */ +#define MC_CSX_SPACING 0x0000000060 /* relative to CSX_BASE, above */ + +#define R_MC_CS0_ROW 0x0000000200 +#define R_MC_CS0_COL 0x0000000220 +#define R_MC_CS0_BA 0x0000000240 +#define R_MC_CS1_ROW 0x0000000260 +#define R_MC_CS1_COL 0x0000000280 +#define R_MC_CS1_BA 0x00000002A0 +#define R_MC_CS2_ROW 0x00000002C0 +#define R_MC_CS2_COL 0x00000002E0 +#define R_MC_CS2_BA 0x0000000300 +#define R_MC_CS3_ROW 0x0000000320 +#define R_MC_CS3_COL 0x0000000340 +#define R_MC_CS3_BA 0x0000000360 +#define R_MC_CS_ATTR 0x0000000380 +#define R_MC_TEST_DATA 0x0000000400 +#define R_MC_TEST_ECC 0x0000000420 +#define R_MC_MCLK_CFG 0x0000000500 + +/* ********************************************************************* + * L2 Cache Control Registers + ********************************************************************* */ + +#define A_L2_READ_TAG 0x0010040018 +#define A_L2_ECC_TAG 0x0010040038 +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_L2_READ_MISC 0x0010040058 +#endif /* 112x PASS1 */ +#define A_L2_WAY_DISABLE 0x0010041000 +#define A_L2_MAKEDISABLE(x) (A_L2_WAY_DISABLE | (((~(x))&0x0F) << 8)) +#define A_L2_MGMT_TAG_BASE 0x00D0000000 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_L2_CACHE_DISABLE 0x0010042000 +#define A_L2_MAKECACHEDISABLE(x) (A_L2_CACHE_DISABLE | (((x)&0x0F) << 8)) +#define A_L2_MISC_CONFIG 0x0010043000 +#endif /* 1250 PASS2 || 112x PASS1 */ + +/* Backward-compatibility definitions. */ +/* XXX: discourage people from using these constants. */ +#define A_L2_READ_ADDRESS A_L2_READ_TAG +#define A_L2_EEC_ADDRESS A_L2_ECC_TAG + + +/* ********************************************************************* + * PCI Interface Registers + ********************************************************************* */ + +#define A_PCI_TYPE00_HEADER 0x00DE000000 +#define A_PCI_TYPE01_HEADER 0x00DE000800 + + +/* ********************************************************************* + * Ethernet DMA and MACs + ********************************************************************* */ + +#define A_MAC_BASE_0 0x0010064000 +#define A_MAC_BASE_1 0x0010065000 +#if SIBYTE_HDR_FEATURE_CHIP(1250) +#define A_MAC_BASE_2 0x0010066000 +#endif /* 1250 */ + +#define MAC_SPACING 0x1000 +#define MAC_DMA_TXRX_SPACING 0x0400 +#define MAC_DMA_CHANNEL_SPACING 0x0100 +#define DMA_RX 0 +#define DMA_TX 1 +#define MAC_NUM_DMACHAN 2 /* channels per direction */ + +/* XXX: not correct; depends on SOC type. */ +#define MAC_NUM_PORTS 3 + +#define A_MAC_CHANNEL_BASE(macnum) \ + (A_MAC_BASE_0 + \ + MAC_SPACING*(macnum)) + +#define A_MAC_REGISTER(macnum,reg) \ + (A_MAC_BASE_0 + \ + MAC_SPACING*(macnum) + (reg)) + + +#define R_MAC_DMA_CHANNELS 0x800 /* Relative to A_MAC_CHANNEL_BASE */ + +#define A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan) \ + ((A_MAC_CHANNEL_BASE(macnum)) + \ + R_MAC_DMA_CHANNELS + \ + (MAC_DMA_TXRX_SPACING*(txrx)) + \ + (MAC_DMA_CHANNEL_SPACING*(chan))) + +#define R_MAC_DMA_CHANNEL_BASE(txrx,chan) \ + (R_MAC_DMA_CHANNELS + \ + (MAC_DMA_TXRX_SPACING*(txrx)) + \ + (MAC_DMA_CHANNEL_SPACING*(chan))) + +#define A_MAC_DMA_REGISTER(macnum,txrx,chan,reg) \ + (A_MAC_DMA_CHANNEL_BASE(macnum,txrx,chan) + \ + (reg)) + +#define R_MAC_DMA_REGISTER(txrx,chan,reg) \ + (R_MAC_DMA_CHANNEL_BASE(txrx,chan) + \ + (reg)) + +/* + * DMA channel registers, relative to A_MAC_DMA_CHANNEL_BASE + */ + +#define R_MAC_DMA_CONFIG0 0x00000000 +#define R_MAC_DMA_CONFIG1 0x00000008 +#define R_MAC_DMA_DSCR_BASE 0x00000010 +#define R_MAC_DMA_DSCR_CNT 0x00000018 +#define R_MAC_DMA_CUR_DSCRA 0x00000020 +#define R_MAC_DMA_CUR_DSCRB 0x00000028 +#define R_MAC_DMA_CUR_DSCRADDR 0x00000030 +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_MAC_DMA_OODPKTLOST_RX 0x00000038 /* rx only */ +#endif /* 112x PASS1 */ + +/* + * RMON Counters + */ + +#define R_MAC_RMON_TX_BYTES 0x00000000 +#define R_MAC_RMON_COLLISIONS 0x00000008 +#define R_MAC_RMON_LATE_COL 0x00000010 +#define R_MAC_RMON_EX_COL 0x00000018 +#define R_MAC_RMON_FCS_ERROR 0x00000020 +#define R_MAC_RMON_TX_ABORT 0x00000028 +/* Counter #6 (0x30) now reserved */ +#define R_MAC_RMON_TX_BAD 0x00000038 +#define R_MAC_RMON_TX_GOOD 0x00000040 +#define R_MAC_RMON_TX_RUNT 0x00000048 +#define R_MAC_RMON_TX_OVERSIZE 0x00000050 +#define R_MAC_RMON_RX_BYTES 0x00000080 +#define R_MAC_RMON_RX_MCAST 0x00000088 +#define R_MAC_RMON_RX_BCAST 0x00000090 +#define R_MAC_RMON_RX_BAD 0x00000098 +#define R_MAC_RMON_RX_GOOD 0x000000A0 +#define R_MAC_RMON_RX_RUNT 0x000000A8 +#define R_MAC_RMON_RX_OVERSIZE 0x000000B0 +#define R_MAC_RMON_RX_FCS_ERROR 0x000000B8 +#define R_MAC_RMON_RX_LENGTH_ERROR 0x000000C0 +#define R_MAC_RMON_RX_CODE_ERROR 0x000000C8 +#define R_MAC_RMON_RX_ALIGN_ERROR 0x000000D0 + +/* Updated to spec 0.2 */ +#define R_MAC_CFG 0x00000100 +#define R_MAC_THRSH_CFG 0x00000108 +#define R_MAC_VLANTAG 0x00000110 +#define R_MAC_FRAMECFG 0x00000118 +#define R_MAC_EOPCNT 0x00000120 +#define R_MAC_FIFO_PTRS 0x00000130 +#define R_MAC_ADFILTER_CFG 0x00000200 +#define R_MAC_ETHERNET_ADDR 0x00000208 +#define R_MAC_PKT_TYPE 0x00000210 +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_MAC_ADMASK0 0x00000218 +#define R_MAC_ADMASK1 0x00000220 +#endif /* 112x PASS1 */ +#define R_MAC_HASH_BASE 0x00000240 +#define R_MAC_ADDR_BASE 0x00000280 +#define R_MAC_CHLO0_BASE 0x00000300 +#define R_MAC_CHUP0_BASE 0x00000320 +#define R_MAC_ENABLE 0x00000400 +#define R_MAC_STATUS 0x00000408 +#define R_MAC_INT_MASK 0x00000410 +#define R_MAC_TXD_CTL 0x00000420 +#define R_MAC_MDIO 0x00000428 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_MAC_STATUS1 0x00000430 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define R_MAC_DEBUG_STATUS 0x00000448 + +#define MAC_HASH_COUNT 8 +#define MAC_ADDR_COUNT 8 +#define MAC_CHMAP_COUNT 4 + + +/* ********************************************************************* + * DUART Registers + ********************************************************************* */ + + +#define R_DUART_NUM_PORTS 2 + +#define A_DUART 0x0010060000 + +#define A_DUART_REG(r) + +#define DUART_CHANREG_SPACING 0x100 +#define A_DUART_CHANREG(chan,reg) (A_DUART + DUART_CHANREG_SPACING*(chan) + (reg)) +#define R_DUART_CHANREG(chan,reg) (DUART_CHANREG_SPACING*(chan) + (reg)) + +#define R_DUART_MODE_REG_1 0x100 +#define R_DUART_MODE_REG_2 0x110 +#define R_DUART_STATUS 0x120 +#define R_DUART_CLK_SEL 0x130 +#define R_DUART_CMD 0x150 +#define R_DUART_RX_HOLD 0x160 +#define R_DUART_TX_HOLD 0x170 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define R_DUART_FULL_CTL 0x140 +#define R_DUART_OPCR_X 0x180 +#define R_DUART_AUXCTL_X 0x190 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* + * The IMR and ISR can't be addressed with A_DUART_CHANREG, + * so use this macro instead. + */ + +#define R_DUART_AUX_CTRL 0x310 +#define R_DUART_ISR_A 0x320 +#define R_DUART_IMR_A 0x330 +#define R_DUART_ISR_B 0x340 +#define R_DUART_IMR_B 0x350 +#define R_DUART_OUT_PORT 0x360 +#define R_DUART_OPCR 0x370 + +#define R_DUART_SET_OPR 0x3B0 +#define R_DUART_CLEAR_OPR 0x3C0 + +#define DUART_IMRISR_SPACING 0x20 + +#define R_DUART_IMRREG(chan) (R_DUART_IMR_A + (chan)*DUART_IMRISR_SPACING) +#define R_DUART_ISRREG(chan) (R_DUART_ISR_A + (chan)*DUART_IMRISR_SPACING) + +#define A_DUART_IMRREG(chan) (A_DUART + R_DUART_IMRREG(chan)) +#define A_DUART_ISRREG(chan) (A_DUART + R_DUART_ISRREG(chan)) + + + + +/* + * These constants are the absolute addresses. + */ + +#define A_DUART_MODE_REG_1_A 0x0010060100 +#define A_DUART_MODE_REG_2_A 0x0010060110 +#define A_DUART_STATUS_A 0x0010060120 +#define A_DUART_CLK_SEL_A 0x0010060130 +#define A_DUART_CMD_A 0x0010060150 +#define A_DUART_RX_HOLD_A 0x0010060160 +#define A_DUART_TX_HOLD_A 0x0010060170 + +#define A_DUART_MODE_REG_1_B 0x0010060200 +#define A_DUART_MODE_REG_2_B 0x0010060210 +#define A_DUART_STATUS_B 0x0010060220 +#define A_DUART_CLK_SEL_B 0x0010060230 +#define A_DUART_CMD_B 0x0010060250 +#define A_DUART_RX_HOLD_B 0x0010060260 +#define A_DUART_TX_HOLD_B 0x0010060270 + +#define A_DUART_INPORT_CHNG 0x0010060300 +#define A_DUART_AUX_CTRL 0x0010060310 +#define A_DUART_ISR_A 0x0010060320 +#define A_DUART_IMR_A 0x0010060330 +#define A_DUART_ISR_B 0x0010060340 +#define A_DUART_IMR_B 0x0010060350 +#define A_DUART_OUT_PORT 0x0010060360 +#define A_DUART_OPCR 0x0010060370 +#define A_DUART_IN_PORT 0x0010060380 +#define A_DUART_ISR 0x0010060390 +#define A_DUART_IMR 0x00100603A0 +#define A_DUART_SET_OPR 0x00100603B0 +#define A_DUART_CLEAR_OPR 0x00100603C0 +#define A_DUART_INPORT_CHNG_A 0x00100603D0 +#define A_DUART_INPORT_CHNG_B 0x00100603E0 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_DUART_FULL_CTL_A 0x0010060140 +#define A_DUART_FULL_CTL_B 0x0010060240 + +#define A_DUART_OPCR_A 0x0010060180 +#define A_DUART_OPCR_B 0x0010060280 + +#define A_DUART_INPORT_CHNG_DEBUG 0x00100603F0 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************* + * Synchronous Serial Registers + ********************************************************************* */ + + +#define A_SER_BASE_0 0x0010060400 +#define A_SER_BASE_1 0x0010060800 +#define SER_SPACING 0x400 + +#define SER_DMA_TXRX_SPACING 0x80 + +#define SER_NUM_PORTS 2 + +#define A_SER_CHANNEL_BASE(sernum) \ + (A_SER_BASE_0 + \ + SER_SPACING*(sernum)) + +#define A_SER_REGISTER(sernum,reg) \ + (A_SER_BASE_0 + \ + SER_SPACING*(sernum) + (reg)) + + +#define R_SER_DMA_CHANNELS 0 /* Relative to A_SER_BASE_x */ + +#define A_SER_DMA_CHANNEL_BASE(sernum,txrx) \ + ((A_SER_CHANNEL_BASE(sernum)) + \ + R_SER_DMA_CHANNELS + \ + (SER_DMA_TXRX_SPACING*(txrx))) + +#define A_SER_DMA_REGISTER(sernum,txrx,reg) \ + (A_SER_DMA_CHANNEL_BASE(sernum,txrx) + \ + (reg)) + + +/* + * DMA channel registers, relative to A_SER_DMA_CHANNEL_BASE + */ + +#define R_SER_DMA_CONFIG0 0x00000000 +#define R_SER_DMA_CONFIG1 0x00000008 +#define R_SER_DMA_DSCR_BASE 0x00000010 +#define R_SER_DMA_DSCR_CNT 0x00000018 +#define R_SER_DMA_CUR_DSCRA 0x00000020 +#define R_SER_DMA_CUR_DSCRB 0x00000028 +#define R_SER_DMA_CUR_DSCRADDR 0x00000030 + +#define R_SER_DMA_CONFIG0_RX 0x00000000 +#define R_SER_DMA_CONFIG1_RX 0x00000008 +#define R_SER_DMA_DSCR_BASE_RX 0x00000010 +#define R_SER_DMA_DSCR_COUNT_RX 0x00000018 +#define R_SER_DMA_CUR_DSCR_A_RX 0x00000020 +#define R_SER_DMA_CUR_DSCR_B_RX 0x00000028 +#define R_SER_DMA_CUR_DSCR_ADDR_RX 0x00000030 + +#define R_SER_DMA_CONFIG0_TX 0x00000080 +#define R_SER_DMA_CONFIG1_TX 0x00000088 +#define R_SER_DMA_DSCR_BASE_TX 0x00000090 +#define R_SER_DMA_DSCR_COUNT_TX 0x00000098 +#define R_SER_DMA_CUR_DSCR_A_TX 0x000000A0 +#define R_SER_DMA_CUR_DSCR_B_TX 0x000000A8 +#define R_SER_DMA_CUR_DSCR_ADDR_TX 0x000000B0 + +#define R_SER_MODE 0x00000100 +#define R_SER_MINFRM_SZ 0x00000108 +#define R_SER_MAXFRM_SZ 0x00000110 +#define R_SER_ADDR 0x00000118 +#define R_SER_USR0_ADDR 0x00000120 +#define R_SER_USR1_ADDR 0x00000128 +#define R_SER_USR2_ADDR 0x00000130 +#define R_SER_USR3_ADDR 0x00000138 +#define R_SER_CMD 0x00000140 +#define R_SER_TX_RD_THRSH 0x00000160 +#define R_SER_TX_WR_THRSH 0x00000168 +#define R_SER_RX_RD_THRSH 0x00000170 +#define R_SER_LINE_MODE 0x00000178 +#define R_SER_DMA_ENABLE 0x00000180 +#define R_SER_INT_MASK 0x00000190 +#define R_SER_STATUS 0x00000188 +#define R_SER_STATUS_DEBUG 0x000001A8 +#define R_SER_RX_TABLE_BASE 0x00000200 +#define SER_RX_TABLE_COUNT 16 +#define R_SER_TX_TABLE_BASE 0x00000300 +#define SER_TX_TABLE_COUNT 16 + +/* RMON Counters */ +#define R_SER_RMON_TX_BYTE_LO 0x000001C0 +#define R_SER_RMON_TX_BYTE_HI 0x000001C8 +#define R_SER_RMON_RX_BYTE_LO 0x000001D0 +#define R_SER_RMON_RX_BYTE_HI 0x000001D8 +#define R_SER_RMON_TX_UNDERRUN 0x000001E0 +#define R_SER_RMON_RX_OVERFLOW 0x000001E8 +#define R_SER_RMON_RX_ERRORS 0x000001F0 +#define R_SER_RMON_RX_BADADDR 0x000001F8 + +/* ********************************************************************* + * Generic Bus Registers + ********************************************************************* */ + +#define IO_EXT_CFG_COUNT 8 + +#define A_IO_EXT_BASE 0x0010061000 +#define A_IO_EXT_REG(r) (A_IO_EXT_BASE + (r)) + +#define A_IO_EXT_CFG_BASE 0x0010061000 +#define A_IO_EXT_MULT_SIZE_BASE 0x0010061100 +#define A_IO_EXT_START_ADDR_BASE 0x0010061200 +#define A_IO_EXT_TIME_CFG0_BASE 0x0010061600 +#define A_IO_EXT_TIME_CFG1_BASE 0x0010061700 + +#define IO_EXT_REGISTER_SPACING 8 +#define A_IO_EXT_CS_BASE(cs) (A_IO_EXT_CFG_BASE+IO_EXT_REGISTER_SPACING*(cs)) +#define R_IO_EXT_REG(reg,cs) ((cs)*IO_EXT_REGISTER_SPACING + (reg)) + +#define R_IO_EXT_CFG 0x0000 +#define R_IO_EXT_MULT_SIZE 0x0100 +#define R_IO_EXT_START_ADDR 0x0200 +#define R_IO_EXT_TIME_CFG0 0x0600 +#define R_IO_EXT_TIME_CFG1 0x0700 + + +#define A_IO_INTERRUPT_STATUS 0x0010061A00 +#define A_IO_INTERRUPT_DATA0 0x0010061A10 +#define A_IO_INTERRUPT_DATA1 0x0010061A18 +#define A_IO_INTERRUPT_DATA2 0x0010061A20 +#define A_IO_INTERRUPT_DATA3 0x0010061A28 +#define A_IO_INTERRUPT_ADDR0 0x0010061A30 +#define A_IO_INTERRUPT_ADDR1 0x0010061A40 +#define A_IO_INTERRUPT_PARITY 0x0010061A50 +#define A_IO_PCMCIA_CFG 0x0010061A60 +#define A_IO_PCMCIA_STATUS 0x0010061A70 +#define A_IO_DRIVE_0 0x0010061300 +#define A_IO_DRIVE_1 0x0010061308 +#define A_IO_DRIVE_2 0x0010061310 +#define A_IO_DRIVE_3 0x0010061318 +#define A_IO_DRIVE_BASE A_IO_DRIVE_0 +#define IO_DRIVE_REGISTER_SPACING 8 +#define R_IO_DRIVE(x) ((x)*IO_DRIVE_REGISTER_SPACING) +#define A_IO_DRIVE(x) (A_IO_DRIVE_BASE + R_IO_DRIVE(x)) + +#define R_IO_INTERRUPT_STATUS 0x0A00 +#define R_IO_INTERRUPT_DATA0 0x0A10 +#define R_IO_INTERRUPT_DATA1 0x0A18 +#define R_IO_INTERRUPT_DATA2 0x0A20 +#define R_IO_INTERRUPT_DATA3 0x0A28 +#define R_IO_INTERRUPT_ADDR0 0x0A30 +#define R_IO_INTERRUPT_ADDR1 0x0A40 +#define R_IO_INTERRUPT_PARITY 0x0A50 +#define R_IO_PCMCIA_CFG 0x0A60 +#define R_IO_PCMCIA_STATUS 0x0A70 + +/* ********************************************************************* + * GPIO Registers + ********************************************************************* */ + +#define A_GPIO_CLR_EDGE 0x0010061A80 +#define A_GPIO_INT_TYPE 0x0010061A88 +#define A_GPIO_INPUT_INVERT 0x0010061A90 +#define A_GPIO_GLITCH 0x0010061A98 +#define A_GPIO_READ 0x0010061AA0 +#define A_GPIO_DIRECTION 0x0010061AA8 +#define A_GPIO_PIN_CLR 0x0010061AB0 +#define A_GPIO_PIN_SET 0x0010061AB8 + +#define A_GPIO_BASE 0x0010061A80 + +#define R_GPIO_CLR_EDGE 0x00 +#define R_GPIO_INT_TYPE 0x08 +#define R_GPIO_INPUT_INVERT 0x10 +#define R_GPIO_GLITCH 0x18 +#define R_GPIO_READ 0x20 +#define R_GPIO_DIRECTION 0x28 +#define R_GPIO_PIN_CLR 0x30 +#define R_GPIO_PIN_SET 0x38 + +/* ********************************************************************* + * SMBus Registers + ********************************************************************* */ + +#define A_SMB_XTRA_0 0x0010060000 +#define A_SMB_XTRA_1 0x0010060008 +#define A_SMB_FREQ_0 0x0010060010 +#define A_SMB_FREQ_1 0x0010060018 +#define A_SMB_STATUS_0 0x0010060020 +#define A_SMB_STATUS_1 0x0010060028 +#define A_SMB_CMD_0 0x0010060030 +#define A_SMB_CMD_1 0x0010060038 +#define A_SMB_START_0 0x0010060040 +#define A_SMB_START_1 0x0010060048 +#define A_SMB_DATA_0 0x0010060050 +#define A_SMB_DATA_1 0x0010060058 +#define A_SMB_CONTROL_0 0x0010060060 +#define A_SMB_CONTROL_1 0x0010060068 +#define A_SMB_PEC_0 0x0010060070 +#define A_SMB_PEC_1 0x0010060078 + +#define A_SMB_0 0x0010060000 +#define A_SMB_1 0x0010060008 +#define SMB_REGISTER_SPACING 0x8 +#define A_SMB_BASE(idx) (A_SMB_0+(idx)*SMB_REGISTER_SPACING) +#define A_SMB_REGISTER(idx,reg) (A_SMB_BASE(idx)+(reg)) + +#define R_SMB_XTRA 0x0000000000 +#define R_SMB_FREQ 0x0000000010 +#define R_SMB_STATUS 0x0000000020 +#define R_SMB_CMD 0x0000000030 +#define R_SMB_START 0x0000000040 +#define R_SMB_DATA 0x0000000050 +#define R_SMB_CONTROL 0x0000000060 +#define R_SMB_PEC 0x0000000070 + +/* ********************************************************************* + * Timer Registers + ********************************************************************* */ + +/* + * Watchdog timers + */ + +#define A_SCD_WDOG_0 0x0010020050 +#define A_SCD_WDOG_1 0x0010020150 +#define SCD_WDOG_SPACING 0x100 +#define SCD_NUM_WDOGS 2 +#define A_SCD_WDOG_BASE(w) (A_SCD_WDOG_0+SCD_WDOG_SPACING*(w)) +#define A_SCD_WDOG_REGISTER(w,r) (A_SCD_WDOG_BASE(w) + (r)) + +#define R_SCD_WDOG_INIT 0x0000000000 +#define R_SCD_WDOG_CNT 0x0000000008 +#define R_SCD_WDOG_CFG 0x0000000010 + +#define A_SCD_WDOG_INIT_0 0x0010020050 +#define A_SCD_WDOG_CNT_0 0x0010020058 +#define A_SCD_WDOG_CFG_0 0x0010020060 + +#define A_SCD_WDOG_INIT_1 0x0010020150 +#define A_SCD_WDOG_CNT_1 0x0010020158 +#define A_SCD_WDOG_CFG_1 0x0010020160 + +/* + * Generic timers + */ + +#define A_SCD_TIMER_0 0x0010020070 +#define A_SCD_TIMER_1 0x0010020078 +#define A_SCD_TIMER_2 0x0010020170 +#define A_SCD_TIMER_3 0x0010020178 +#define SCD_NUM_TIMERS 4 +#define A_SCD_TIMER_BASE(w) (A_SCD_TIMER_0+0x08*((w)&1)+0x100*(((w)&2)>>1)) +#define A_SCD_TIMER_REGISTER(w,r) (A_SCD_TIMER_BASE(w) + (r)) + +#define R_SCD_TIMER_INIT 0x0000000000 +#define R_SCD_TIMER_CNT 0x0000000010 +#define R_SCD_TIMER_CFG 0x0000000020 + +#define A_SCD_TIMER_INIT_0 0x0010020070 +#define A_SCD_TIMER_CNT_0 0x0010020080 +#define A_SCD_TIMER_CFG_0 0x0010020090 + +#define A_SCD_TIMER_INIT_1 0x0010020078 +#define A_SCD_TIMER_CNT_1 0x0010020088 +#define A_SCD_TIMER_CFG_1 0x0010020098 + +#define A_SCD_TIMER_INIT_2 0x0010020170 +#define A_SCD_TIMER_CNT_2 0x0010020180 +#define A_SCD_TIMER_CFG_2 0x0010020190 + +#define A_SCD_TIMER_INIT_3 0x0010020178 +#define A_SCD_TIMER_CNT_3 0x0010020188 +#define A_SCD_TIMER_CFG_3 0x0010020198 + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_SCD_SCRATCH 0x0010020C10 + +#define A_SCD_ZBBUS_CYCLE_COUNT 0x0010030000 +#define A_SCD_ZBBUS_CYCLE_CP0 0x0010020C00 +#define A_SCD_ZBBUS_CYCLE_CP1 0x0010020C08 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************* + * System Control Registers + ********************************************************************* */ + +#define A_SCD_SYSTEM_REVISION 0x0010020000 +#define A_SCD_SYSTEM_CFG 0x0010020008 + +/* ********************************************************************* + * System Address Trap Registers + ********************************************************************* */ + +#define A_ADDR_TRAP_INDEX 0x00100200B0 +#define A_ADDR_TRAP_REG 0x00100200B8 +#define A_ADDR_TRAP_UP_0 0x0010020400 +#define A_ADDR_TRAP_UP_1 0x0010020408 +#define A_ADDR_TRAP_UP_2 0x0010020410 +#define A_ADDR_TRAP_UP_3 0x0010020418 +#define A_ADDR_TRAP_DOWN_0 0x0010020420 +#define A_ADDR_TRAP_DOWN_1 0x0010020428 +#define A_ADDR_TRAP_DOWN_2 0x0010020430 +#define A_ADDR_TRAP_DOWN_3 0x0010020438 +#define A_ADDR_TRAP_CFG_0 0x0010020440 +#define A_ADDR_TRAP_CFG_1 0x0010020448 +#define A_ADDR_TRAP_CFG_2 0x0010020450 +#define A_ADDR_TRAP_CFG_3 0x0010020458 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_ADDR_TRAP_REG_DEBUG 0x0010020460 +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************* + * System Interrupt Mapper Registers + ********************************************************************* */ + +#define A_IMR_CPU0_BASE 0x0010020000 +#define A_IMR_CPU1_BASE 0x0010022000 +#define IMR_REGISTER_SPACING 0x2000 +#define IMR_REGISTER_SPACING_SHIFT 13 + +#define A_IMR_MAPPER(cpu) (A_IMR_CPU0_BASE+(cpu)*IMR_REGISTER_SPACING) +#define A_IMR_REGISTER(cpu,reg) (A_IMR_MAPPER(cpu)+(reg)) + +#define R_IMR_INTERRUPT_DIAG 0x0010 +#define R_IMR_INTERRUPT_MASK 0x0028 +#define R_IMR_INTERRUPT_TRACE 0x0038 +#define R_IMR_INTERRUPT_SOURCE_STATUS 0x0040 +#define R_IMR_LDT_INTERRUPT_SET 0x0048 +#define R_IMR_LDT_INTERRUPT 0x0018 +#define R_IMR_LDT_INTERRUPT_CLR 0x0020 +#define R_IMR_MAILBOX_CPU 0x00c0 +#define R_IMR_ALIAS_MAILBOX_CPU 0x1000 +#define R_IMR_MAILBOX_SET_CPU 0x00C8 +#define R_IMR_ALIAS_MAILBOX_SET_CPU 0x1008 +#define R_IMR_MAILBOX_CLR_CPU 0x00D0 +#define R_IMR_INTERRUPT_STATUS_BASE 0x0100 +#define R_IMR_INTERRUPT_STATUS_COUNT 7 +#define R_IMR_INTERRUPT_MAP_BASE 0x0200 +#define R_IMR_INTERRUPT_MAP_COUNT 64 + +/* ********************************************************************* + * System Performance Counter Registers + ********************************************************************* */ + +#define A_SCD_PERF_CNT_CFG 0x00100204C0 +#define A_SCD_PERF_CNT_0 0x00100204D0 +#define A_SCD_PERF_CNT_1 0x00100204D8 +#define A_SCD_PERF_CNT_2 0x00100204E0 +#define A_SCD_PERF_CNT_3 0x00100204E8 + +/* ********************************************************************* + * System Bus Watcher Registers + ********************************************************************* */ + +#define A_SCD_BUS_ERR_STATUS 0x0010020880 +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_SCD_BUS_ERR_STATUS_DEBUG 0x00100208D0 +#endif /* 1250 PASS2 || 112x PASS1 */ +#define A_BUS_ERR_DATA_0 0x00100208A0 +#define A_BUS_ERR_DATA_1 0x00100208A8 +#define A_BUS_ERR_DATA_2 0x00100208B0 +#define A_BUS_ERR_DATA_3 0x00100208B8 +#define A_BUS_L2_ERRORS 0x00100208C0 +#define A_BUS_MEM_IO_ERRORS 0x00100208C8 + +/* ********************************************************************* + * System Debug Controller Registers + ********************************************************************* */ + +#define A_SCD_JTAG_BASE 0x0010000000 + +/* ********************************************************************* + * System Trace Buffer Registers + ********************************************************************* */ + +#define A_SCD_TRACE_CFG 0x0010020A00 +#define A_SCD_TRACE_READ 0x0010020A08 +#define A_SCD_TRACE_EVENT_0 0x0010020A20 +#define A_SCD_TRACE_EVENT_1 0x0010020A28 +#define A_SCD_TRACE_EVENT_2 0x0010020A30 +#define A_SCD_TRACE_EVENT_3 0x0010020A38 +#define A_SCD_TRACE_SEQUENCE_0 0x0010020A40 +#define A_SCD_TRACE_SEQUENCE_1 0x0010020A48 +#define A_SCD_TRACE_SEQUENCE_2 0x0010020A50 +#define A_SCD_TRACE_SEQUENCE_3 0x0010020A58 +#define A_SCD_TRACE_EVENT_4 0x0010020A60 +#define A_SCD_TRACE_EVENT_5 0x0010020A68 +#define A_SCD_TRACE_EVENT_6 0x0010020A70 +#define A_SCD_TRACE_EVENT_7 0x0010020A78 +#define A_SCD_TRACE_SEQUENCE_4 0x0010020A80 +#define A_SCD_TRACE_SEQUENCE_5 0x0010020A88 +#define A_SCD_TRACE_SEQUENCE_6 0x0010020A90 +#define A_SCD_TRACE_SEQUENCE_7 0x0010020A98 + +/* ********************************************************************* + * System Generic DMA Registers + ********************************************************************* */ + +#define A_DM_0 0x0010020B00 +#define A_DM_1 0x0010020B20 +#define A_DM_2 0x0010020B40 +#define A_DM_3 0x0010020B60 +#define DM_REGISTER_SPACING 0x20 +#define DM_NUM_CHANNELS 4 +#define A_DM_BASE(idx) (A_DM_0 + ((idx) * DM_REGISTER_SPACING)) +#define A_DM_REGISTER(idx,reg) (A_DM_BASE(idx) + (reg)) + +#define R_DM_DSCR_BASE 0x0000000000 +#define R_DM_DSCR_COUNT 0x0000000008 +#define R_DM_CUR_DSCR_ADDR 0x0000000010 +#define R_DM_DSCR_BASE_DEBUG 0x0000000018 + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_DM_PARTIAL_0 0x0010020ba0 +#define A_DM_PARTIAL_1 0x0010020ba8 +#define A_DM_PARTIAL_2 0x0010020bb0 +#define A_DM_PARTIAL_3 0x0010020bb8 +#define DM_PARTIAL_REGISTER_SPACING 0x8 +#define A_DM_PARTIAL(idx) (A_DM_PARTIAL_0 + ((idx) * DM_PARTIAL_REGISTER_SPACING)) +#endif /* 112x PASS1 */ + +#if SIBYTE_HDR_FEATURE(112x, PASS1) +#define A_DM_CRC_0 0x0010020b80 +#define A_DM_CRC_1 0x0010020b90 +#define DM_CRC_REGISTER_SPACING 0x10 +#define DM_CRC_NUM_CHANNELS 2 +#define A_DM_CRC_BASE(idx) (A_DM_CRC_0 + ((idx) * DM_CRC_REGISTER_SPACING)) +#define A_DM_CRC_REGISTER(idx,reg) (A_DM_CRC_BASE(idx) + (reg)) + +#define R_CRC_DEF_0 0x00 +#define R_CTCP_DEF_0 0x08 +#endif /* 112x PASS1 */ + +/* ********************************************************************* + * Physical Address Map + ********************************************************************* */ + +#define A_PHYS_MEMORY_0 _SB_MAKE64(0x0000000000) +#define A_PHYS_MEMORY_SIZE _SB_MAKE64((256*1024*1024)) +#define A_PHYS_SYSTEM_CTL _SB_MAKE64(0x0010000000) +#define A_PHYS_IO_SYSTEM _SB_MAKE64(0x0010060000) +#define A_PHYS_GENBUS _SB_MAKE64(0x0010090000) +#define A_PHYS_GENBUS_END _SB_MAKE64(0x0040000000) +#define A_PHYS_LDTPCI_IO_MATCH_BYTES_32 _SB_MAKE64(0x0040000000) +#define A_PHYS_LDTPCI_IO_MATCH_BITS_32 _SB_MAKE64(0x0060000000) +#define A_PHYS_MEMORY_1 _SB_MAKE64(0x0080000000) +#define A_PHYS_MEMORY_2 _SB_MAKE64(0x0090000000) +#define A_PHYS_MEMORY_3 _SB_MAKE64(0x00C0000000) +#define A_PHYS_L2_CACHE_TEST _SB_MAKE64(0x00D0000000) +#define A_PHYS_LDT_SPECIAL_MATCH_BYTES _SB_MAKE64(0x00D8000000) +#define A_PHYS_LDTPCI_IO_MATCH_BYTES _SB_MAKE64(0x00DC000000) +#define A_PHYS_LDTPCI_CFG_MATCH_BYTES _SB_MAKE64(0x00DE000000) +#define A_PHYS_LDT_SPECIAL_MATCH_BITS _SB_MAKE64(0x00F8000000) +#define A_PHYS_LDTPCI_IO_MATCH_BITS _SB_MAKE64(0x00FC000000) +#define A_PHYS_LDTPCI_CFG_MATCH_BITS _SB_MAKE64(0x00FE000000) +#define A_PHYS_MEMORY_EXP _SB_MAKE64(0x0100000000) +#define A_PHYS_MEMORY_EXP_SIZE _SB_MAKE64((508*1024*1024*1024)) +#define A_PHYS_LDT_EXP _SB_MAKE64(0x8000000000) +#define A_PHYS_PCI_FULLACCESS_BYTES _SB_MAKE64(0xF000000000) +#define A_PHYS_PCI_FULLACCESS_BITS _SB_MAKE64(0xF100000000) +#define A_PHYS_RESERVED _SB_MAKE64(0xF200000000) +#define A_PHYS_RESERVED_SPECIAL_LDT _SB_MAKE64(0xFD00000000) + +#define A_PHYS_L2CACHE_WAY_SIZE _SB_MAKE64(0x0000020000) +#define PHYS_L2CACHE_NUM_WAYS 4 +#define A_PHYS_L2CACHE_TOTAL_SIZE _SB_MAKE64(0x0000080000) +#define A_PHYS_L2CACHE_WAY0 _SB_MAKE64(0x00D0180000) +#define A_PHYS_L2CACHE_WAY1 _SB_MAKE64(0x00D01A0000) +#define A_PHYS_L2CACHE_WAY2 _SB_MAKE64(0x00D01C0000) +#define A_PHYS_L2CACHE_WAY3 _SB_MAKE64(0x00D01E0000) + + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_scd.h b/include/asm-mips64/sibyte/sb1250_scd.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_scd.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,525 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * SCD Constants and Macros File: sb1250_scd.h + * + * This module contains constants and macros useful for + * manipulating the System Control and Debug module on the 1250. + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + +#ifndef _SB1250_SCD_H +#define _SB1250_SCD_H + +#include "sb1250_defs.h" + +/* ********************************************************************* + * System control/debug registers + ********************************************************************* */ + +/* + * System Revision Register (Table 4-1) + */ + +#define M_SYS_RESERVED _SB_MAKEMASK(8,0) + +#define S_SYS_REVISION _SB_MAKE64(8) +#define M_SYS_REVISION _SB_MAKEMASK(8,S_SYS_REVISION) +#define V_SYS_REVISION(x) _SB_MAKEVALUE(x,S_SYS_REVISION) +#define G_SYS_REVISION(x) _SB_GETVALUE(x,S_SYS_REVISION,M_SYS_REVISION) + +#if SIBYTE_HDR_FEATURE_CHIP(1250) +#define K_SYS_REVISION_BCM1250_PASS1 1 +#define K_SYS_REVISION_BCM1250_PASS2 3 +#define K_SYS_REVISION_BCM1250_A10 11 +#define K_SYS_REVISION_BCM1250_PASS2_2 16 +#define K_SYS_REVISION_BCM1250_B2 17 +#define K_SYS_REVISION_BCM1250_PASS3 32 + +/* XXX: discourage people from using these constants. */ +#define K_SYS_REVISION_PASS1 K_SYS_REVISION_BCM1250_PASS1 +#define K_SYS_REVISION_PASS2 K_SYS_REVISION_BCM1250_PASS2 +#define K_SYS_REVISION_PASS2_2 K_SYS_REVISION_BCM1250_PASS2_2 +#define K_SYS_REVISION_PASS3 K_SYS_REVISION_BCM1250_PASS3 +#endif /* 1250 */ + +#if SIBYTE_HDR_FEATURE_CHIP(112x) +#define K_SYS_REVISION_BCM112x_A1 32 +#define K_SYS_REVISION_BCM112x_A2 33 +#endif /* 112x */ + +/* XXX: discourage people from using these constants. */ +#define S_SYS_PART _SB_MAKE64(16) +#define M_SYS_PART _SB_MAKEMASK(16,S_SYS_PART) +#define V_SYS_PART(x) _SB_MAKEVALUE(x,S_SYS_PART) +#define G_SYS_PART(x) _SB_GETVALUE(x,S_SYS_PART,M_SYS_PART) + +/* XXX: discourage people from using these constants. */ +#define K_SYS_PART_SB1250 0x1250 +#define K_SYS_PART_BCM1120 0x1121 +#define K_SYS_PART_BCM1125 0x1123 +#define K_SYS_PART_BCM1125H 0x1124 + +/* The "peripheral set" (SOC type) is the low 4 bits of the "part" field. */ +#define S_SYS_SOC_TYPE _SB_MAKE64(16) +#define M_SYS_SOC_TYPE _SB_MAKEMASK(4,S_SYS_SOC_TYPE) +#define V_SYS_SOC_TYPE(x) _SB_MAKEVALUE(x,S_SYS_SOC_TYPE) +#define G_SYS_SOC_TYPE(x) _SB_GETVALUE(x,S_SYS_SOC_TYPE,M_SYS_SOC_TYPE) + +#define K_SYS_SOC_TYPE_BCM1250 0x0 +#define K_SYS_SOC_TYPE_BCM1120 0x1 +#define K_SYS_SOC_TYPE_BCM1250_ALT 0x2 /* 1250pass2 w/ 1/4 L2. */ +#define K_SYS_SOC_TYPE_BCM1125 0x3 +#define K_SYS_SOC_TYPE_BCM1125H 0x4 +#define K_SYS_SOC_TYPE_BCM1250_ALT2 0x5 /* 1250pass2 w/ 1/2 L2. */ + +/* + * Calculate correct SOC type given a copy of system revision register. + * + * (For the assembler version, sysrev and dest may be the same register. + * Also, it clobbers AT.) + */ +#ifdef __ASSEMBLER__ +#define SYS_SOC_TYPE(dest, sysrev) \ + .set push ; \ + .set reorder ; \ + dsrl dest, sysrev, S_SYS_SOC_TYPE ; \ + andi dest, dest, (M_SYS_SOC_TYPE >> S_SYS_SOC_TYPE); \ + beq dest, K_SYS_SOC_TYPE_BCM1250_ALT, 991f ; \ + beq dest, K_SYS_SOC_TYPE_BCM1250_ALT2, 991f ; \ + b 992f ; \ +991: li dest, K_SYS_SOC_TYPE_BCM1250 ; \ +992: \ + .set pop +#else +#define SYS_SOC_TYPE(sysrev) \ + ((G_SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250_ALT \ + || G_SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250_ALT2) \ + ? K_SYS_SOC_TYPE_BCM1250 : G_SYS_SOC_TYPE(sysrev)) +#endif + +#define S_SYS_WID _SB_MAKE64(32) +#define M_SYS_WID _SB_MAKEMASK(32,S_SYS_WID) +#define V_SYS_WID(x) _SB_MAKEVALUE(x,S_SYS_WID) +#define G_SYS_WID(x) _SB_GETVALUE(x,S_SYS_WID,M_SYS_WID) + +/* + * System Config Register (Table 4-2) + * Register: SCD_SYSTEM_CFG + */ + +#define M_SYS_LDT_PLL_BYP _SB_MAKEMASK1(3) +#define M_SYS_PCI_SYNC_TEST_MODE _SB_MAKEMASK1(4) +#define M_SYS_IOB0_DIV _SB_MAKEMASK1(5) +#define M_SYS_IOB1_DIV _SB_MAKEMASK1(6) + +#define S_SYS_PLL_DIV _SB_MAKE64(7) +#define M_SYS_PLL_DIV _SB_MAKEMASK(5,S_SYS_PLL_DIV) +#define V_SYS_PLL_DIV(x) _SB_MAKEVALUE(x,S_SYS_PLL_DIV) +#define G_SYS_PLL_DIV(x) _SB_GETVALUE(x,S_SYS_PLL_DIV,M_SYS_PLL_DIV) + +#define M_SYS_SER0_ENABLE _SB_MAKEMASK1(12) +#define M_SYS_SER0_RSTB_EN _SB_MAKEMASK1(13) +#define M_SYS_SER1_ENABLE _SB_MAKEMASK1(14) +#define M_SYS_SER1_RSTB_EN _SB_MAKEMASK1(15) +#define M_SYS_PCMCIA_ENABLE _SB_MAKEMASK1(16) + +#define S_SYS_BOOT_MODE _SB_MAKE64(17) +#define M_SYS_BOOT_MODE _SB_MAKEMASK(2,S_SYS_BOOT_MODE) +#define V_SYS_BOOT_MODE(x) _SB_MAKEVALUE(x,S_SYS_BOOT_MODE) +#define G_SYS_BOOT_MODE(x) _SB_GETVALUE(x,S_SYS_BOOT_MODE,M_SYS_BOOT_MODE) +#define K_SYS_BOOT_MODE_ROM32 0 +#define K_SYS_BOOT_MODE_ROM8 1 +#define K_SYS_BOOT_MODE_SMBUS_SMALL 2 +#define K_SYS_BOOT_MODE_SMBUS_BIG 3 + +#define M_SYS_PCI_HOST _SB_MAKEMASK1(19) +#define M_SYS_PCI_ARBITER _SB_MAKEMASK1(20) +#define M_SYS_SOUTH_ON_LDT _SB_MAKEMASK1(21) +#define M_SYS_BIG_ENDIAN _SB_MAKEMASK1(22) +#define M_SYS_GENCLK_EN _SB_MAKEMASK1(23) +#define M_SYS_LDT_TEST_EN _SB_MAKEMASK1(24) +#define M_SYS_GEN_PARITY_EN _SB_MAKEMASK1(25) + +#define S_SYS_CONFIG 26 +#define M_SYS_CONFIG _SB_MAKEMASK(6,S_SYS_CONFIG) +#define V_SYS_CONFIG(x) _SB_MAKEVALUE(x,S_SYS_CONFIG) +#define G_SYS_CONFIG(x) _SB_GETVALUE(x,S_SYS_CONFIG,M_SYS_CONFIG) + +/* The following bits are writeable by JTAG only. */ + +#define M_SYS_CLKSTOP _SB_MAKEMASK1(32) +#define M_SYS_CLKSTEP _SB_MAKEMASK1(33) + +#define S_SYS_CLKCOUNT 34 +#define M_SYS_CLKCOUNT _SB_MAKEMASK(8,S_SYS_CLKCOUNT) +#define V_SYS_CLKCOUNT(x) _SB_MAKEVALUE(x,S_SYS_CLKCOUNT) +#define G_SYS_CLKCOUNT(x) _SB_GETVALUE(x,S_SYS_CLKCOUNT,M_SYS_CLKCOUNT) + +#define M_SYS_PLL_BYPASS _SB_MAKEMASK1(42) + +#define S_SYS_PLL_IREF 43 +#define M_SYS_PLL_IREF _SB_MAKEMASK(2,S_SYS_PLL_IREF) + +#define S_SYS_PLL_VCO 45 +#define M_SYS_PLL_VCO _SB_MAKEMASK(2,S_SYS_PLL_VCO) + +#define S_SYS_PLL_VREG 47 +#define M_SYS_PLL_VREG _SB_MAKEMASK(2,S_SYS_PLL_VREG) + +#define M_SYS_MEM_RESET _SB_MAKEMASK1(49) +#define M_SYS_L2C_RESET _SB_MAKEMASK1(50) +#define M_SYS_IO_RESET_0 _SB_MAKEMASK1(51) +#define M_SYS_IO_RESET_1 _SB_MAKEMASK1(52) +#define M_SYS_SCD_RESET _SB_MAKEMASK1(53) + +/* End of bits writable by JTAG only. */ + +#define M_SYS_CPU_RESET_0 _SB_MAKEMASK1(54) +#define M_SYS_CPU_RESET_1 _SB_MAKEMASK1(55) + +#define M_SYS_UNICPU0 _SB_MAKEMASK1(56) +#define M_SYS_UNICPU1 _SB_MAKEMASK1(57) + +#define M_SYS_SB_SOFTRES _SB_MAKEMASK1(58) +#define M_SYS_EXT_RESET _SB_MAKEMASK1(59) +#define M_SYS_SYSTEM_RESET _SB_MAKEMASK1(60) + +#define M_SYS_MISR_MODE _SB_MAKEMASK1(61) +#define M_SYS_MISR_RESET _SB_MAKEMASK1(62) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_SYS_SW_FLAG _SB_MAKEMASK1(63) +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* + * Mailbox Registers (Table 4-3) + * Registers: SCD_MBOX_CPU_x + */ + +#define S_MBOX_INT_3 0 +#define M_MBOX_INT_3 _SB_MAKEMASK(16,S_MBOX_INT_3) +#define S_MBOX_INT_2 16 +#define M_MBOX_INT_2 _SB_MAKEMASK(16,S_MBOX_INT_2) +#define S_MBOX_INT_1 32 +#define M_MBOX_INT_1 _SB_MAKEMASK(16,S_MBOX_INT_1) +#define S_MBOX_INT_0 48 +#define M_MBOX_INT_0 _SB_MAKEMASK(16,S_MBOX_INT_0) + +/* + * Watchdog Registers (Table 4-8) (Table 4-9) (Table 4-10) + * Registers: SCD_WDOG_INIT_CNT_x + */ + +#define V_SCD_WDOG_FREQ 1000000 + +#define S_SCD_WDOG_INIT 0 +#define M_SCD_WDOG_INIT _SB_MAKEMASK(23,S_SCD_WDOG_INIT) + +#define S_SCD_WDOG_CNT 0 +#define M_SCD_WDOG_CNT _SB_MAKEMASK(23,S_SCD_WDOG_CNT) + +#define M_SCD_WDOG_ENABLE _SB_MAKEMASK1(0) + +/* + * Timer Registers (Table 4-11) (Table 4-12) (Table 4-13) + */ + +#define V_SCD_TIMER_FREQ 1000000 + +#define S_SCD_TIMER_INIT 0 +#define M_SCD_TIMER_INIT _SB_MAKEMASK(20,S_SCD_TIMER_INIT) +#define V_SCD_TIMER_INIT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_INIT) +#define G_SCD_TIMER_INIT(x) _SB_GETVALUE(x,S_SCD_TIMER_INIT,M_SCD_TIMER_INIT) + +#define S_SCD_TIMER_CNT 0 +#define M_SCD_TIMER_CNT _SB_MAKEMASK(20,S_SCD_TIMER_CNT) +#define V_SCD_TIMER_CNT(x) _SB_MAKEVALUE(x,S_SCD_TIMER_CNT) +#define G_SCD_TIMER_CNT(x) _SB_GETVALUE(x,S_SCD_TIMER_CNT,M_SCD_TIMER_CNT) + +#define M_SCD_TIMER_ENABLE _SB_MAKEMASK1(0) +#define M_SCD_TIMER_MODE _SB_MAKEMASK1(1) +#define M_SCD_TIMER_MODE_CONTINUOUS M_SCD_TIMER_MODE + +/* + * System Performance Counters + */ + +#define S_SPC_CFG_SRC0 0 +#define M_SPC_CFG_SRC0 _SB_MAKEMASK(8,S_SPC_CFG_SRC0) +#define V_SPC_CFG_SRC0(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC0) +#define G_SPC_CFG_SRC0(x) _SB_GETVALUE(x,S_SPC_CFG_SRC0,M_SPC_CFG_SRC0) + +#define S_SPC_CFG_SRC1 8 +#define M_SPC_CFG_SRC1 _SB_MAKEMASK(8,S_SPC_CFG_SRC1) +#define V_SPC_CFG_SRC1(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC1) +#define G_SPC_CFG_SRC1(x) _SB_GETVALUE(x,S_SPC_CFG_SRC1,M_SPC_CFG_SRC1) + +#define S_SPC_CFG_SRC2 16 +#define M_SPC_CFG_SRC2 _SB_MAKEMASK(8,S_SPC_CFG_SRC2) +#define V_SPC_CFG_SRC2(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC2) +#define G_SPC_CFG_SRC2(x) _SB_GETVALUE(x,S_SPC_CFG_SRC2,M_SPC_CFG_SRC2) + +#define S_SPC_CFG_SRC3 24 +#define M_SPC_CFG_SRC3 _SB_MAKEMASK(8,S_SPC_CFG_SRC3) +#define V_SPC_CFG_SRC3(x) _SB_MAKEVALUE(x,S_SPC_CFG_SRC3) +#define G_SPC_CFG_SRC3(x) _SB_GETVALUE(x,S_SPC_CFG_SRC3,M_SPC_CFG_SRC3) + +#define M_SPC_CFG_CLEAR _SB_MAKEMASK1(32) +#define M_SPC_CFG_ENABLE _SB_MAKEMASK1(33) + + +/* + * Bus Watcher + */ + +#define S_SCD_BERR_TID 8 +#define M_SCD_BERR_TID _SB_MAKEMASK(10,S_SCD_BERR_TID) +#define V_SCD_BERR_TID(x) _SB_MAKEVALUE(x,S_SCD_BERR_TID) +#define G_SCD_BERR_TID(x) _SB_GETVALUE(x,S_SCD_BERR_TID,M_SCD_BERR_TID) + +#define S_SCD_BERR_RID 18 +#define M_SCD_BERR_RID _SB_MAKEMASK(4,S_SCD_BERR_RID) +#define V_SCD_BERR_RID(x) _SB_MAKEVALUE(x,S_SCD_BERR_RID) +#define G_SCD_BERR_RID(x) _SB_GETVALUE(x,S_SCD_BERR_RID,M_SCD_BERR_RID) + +#define S_SCD_BERR_DCODE 22 +#define M_SCD_BERR_DCODE _SB_MAKEMASK(3,S_SCD_BERR_DCODE) +#define V_SCD_BERR_DCODE(x) _SB_MAKEVALUE(x,S_SCD_BERR_DCODE) +#define G_SCD_BERR_DCODE(x) _SB_GETVALUE(x,S_SCD_BERR_DCODE,M_SCD_BERR_DCODE) + +#define M_SCD_BERR_MULTERRS _SB_MAKEMASK1(30) + + +#define S_SCD_L2ECC_CORR_D 0 +#define M_SCD_L2ECC_CORR_D _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_D) +#define V_SCD_L2ECC_CORR_D(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_D) +#define G_SCD_L2ECC_CORR_D(x) _SB_GETVALUE(x,S_SCD_L2ECC_CORR_D,M_SCD_L2ECC_CORR_D) + +#define S_SCD_L2ECC_BAD_D 8 +#define M_SCD_L2ECC_BAD_D _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_D) +#define V_SCD_L2ECC_BAD_D(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_D) +#define G_SCD_L2ECC_BAD_D(x) _SB_GETVALUE(x,S_SCD_L2ECC_BAD_D,M_SCD_L2ECC_BAD_D) + +#define S_SCD_L2ECC_CORR_T 16 +#define M_SCD_L2ECC_CORR_T _SB_MAKEMASK(8,S_SCD_L2ECC_CORR_T) +#define V_SCD_L2ECC_CORR_T(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_CORR_T) +#define G_SCD_L2ECC_CORR_T(x) _SB_GETVALUE(x,S_SCD_L2ECC_CORR_T,M_SCD_L2ECC_CORR_T) + +#define S_SCD_L2ECC_BAD_T 24 +#define M_SCD_L2ECC_BAD_T _SB_MAKEMASK(8,S_SCD_L2ECC_BAD_T) +#define V_SCD_L2ECC_BAD_T(x) _SB_MAKEVALUE(x,S_SCD_L2ECC_BAD_T) +#define G_SCD_L2ECC_BAD_T(x) _SB_GETVALUE(x,S_SCD_L2ECC_BAD_T,M_SCD_L2ECC_BAD_T) + +#define S_SCD_MEM_ECC_CORR 0 +#define M_SCD_MEM_ECC_CORR _SB_MAKEMASK(8,S_SCD_MEM_ECC_CORR) +#define V_SCD_MEM_ECC_CORR(x) _SB_MAKEVALUE(x,S_SCD_MEM_ECC_CORR) +#define G_SCD_MEM_ECC_CORR(x) _SB_GETVALUE(x,S_SCD_MEM_ECC_CORR,M_SCD_MEM_ECC_CORR) + +#define S_SCD_MEM_ECC_BAD 8 +#define M_SCD_MEM_ECC_BAD _SB_MAKEMASK(8,S_SCD_MEM_ECC_BAD) +#define V_SCD_MEM_ECC_BAD(x) _SB_MAKEVALUE(x,S_SCD_MEM_ECC_BAD) +#define G_SCD_MEM_ECC_BAD(x) _SB_GETVALUE(x,S_SCD_MEM_ECC_BAD,M_SCD_MEM_ECC_BAD) + +#define S_SCD_MEM_BUSERR 16 +#define M_SCD_MEM_BUSERR _SB_MAKEMASK(8,S_SCD_MEM_BUSERR) +#define V_SCD_MEM_BUSERR(x) _SB_MAKEVALUE(x,S_SCD_MEM_BUSERR) +#define G_SCD_MEM_BUSERR(x) _SB_GETVALUE(x,S_SCD_MEM_BUSERR,M_SCD_MEM_BUSERR) + + +/* + * Address Trap Registers + */ + +#define M_ATRAP_INDEX _SB_MAKEMASK(4,0) +#define M_ATRAP_ADDRESS _SB_MAKEMASK(40,0) + +#define S_ATRAP_CFG_CNT 0 +#define M_ATRAP_CFG_CNT _SB_MAKEMASK(3,S_ATRAP_CFG_CNT) +#define V_ATRAP_CFG_CNT(x) _SB_MAKEVALUE(x,S_ATRAP_CFG_CNT) +#define G_ATRAP_CFG_CNT(x) _SB_GETVALUE(x,S_ATRAP_CFG_CNT,M_ATRAP_CFG_CNT) + +#define M_ATRAP_CFG_WRITE _SB_MAKEMASK1(3) +#define M_ATRAP_CFG_ALL _SB_MAKEMASK1(4) +#define M_ATRAP_CFG_INV _SB_MAKEMASK1(5) +#define M_ATRAP_CFG_USESRC _SB_MAKEMASK1(6) +#define M_ATRAP_CFG_SRCINV _SB_MAKEMASK1(7) + +#define S_ATRAP_CFG_AGENTID 8 +#define M_ATRAP_CFG_AGENTID _SB_MAKEMASK(4,S_ATRAP_CFG_AGENTID) +#define V_ATRAP_CFG_AGENTID(x) _SB_MAKEVALUE(x,S_ATRAP_CFG_AGENTID) +#define G_ATRAP_CFG_AGENTID(x) _SB_GETVALUE(x,S_ATRAP_CFG_AGENTID,M_ATRAP_CFG_AGENTID) + +#define K_BUS_AGENT_CPU0 0 +#define K_BUS_AGENT_CPU1 1 +#define K_BUS_AGENT_IOB0 2 +#define K_BUS_AGENT_IOB1 3 +#define K_BUS_AGENT_SCD 4 +#define K_BUS_AGENT_RESERVED 5 +#define K_BUS_AGENT_L2C 6 +#define K_BUS_AGENT_MC 7 + +#define S_ATRAP_CFG_CATTR 12 +#define M_ATRAP_CFG_CATTR _SB_MAKEMASK(3,S_ATRAP_CFG_CATTR) +#define V_ATRAP_CFG_CATTR(x) _SB_MAKEVALUE(x,S_ATRAP_CFG_CATTR) +#define G_ATRAP_CFG_CATTR(x) _SB_GETVALUE(x,S_ATRAP_CFG_CATTR,M_ATRAP_CFG_CATTR) + +#define K_ATRAP_CFG_CATTR_IGNORE 0 +#define K_ATRAP_CFG_CATTR_UNC 1 +#define K_ATRAP_CFG_CATTR_CACHEABLE 2 +#define K_ATRAP_CFG_CATTR_NONCOH 3 +#define K_ATRAP_CFG_CATTR_COHERENT 4 +#define K_ATRAP_CFG_CATTR_NOTUNC 5 +#define K_ATRAP_CFG_CATTR_NOTNONCOH 6 +#define K_ATRAP_CFG_CATTR_NOTCOHERENT 7 + +/* + * Trace Buffer Config register + */ + +#define M_SCD_TRACE_CFG_RESET _SB_MAKEMASK1(0) +#define M_SCD_TRACE_CFG_START_READ _SB_MAKEMASK1(1) +#define M_SCD_TRACE_CFG_START _SB_MAKEMASK1(2) +#define M_SCD_TRACE_CFG_STOP _SB_MAKEMASK1(3) +#define M_SCD_TRACE_CFG_FREEZE _SB_MAKEMASK1(4) +#define M_SCD_TRACE_CFG_FREEZE_FULL _SB_MAKEMASK1(5) +#define M_SCD_TRACE_CFG_DEBUG_FULL _SB_MAKEMASK1(6) +#define M_SCD_TRACE_CFG_FULL _SB_MAKEMASK1(7) +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +#define M_SCD_TRACE_CFG_FORCECNT _SB_MAKEMASK1(8) +#endif /* 1250 PASS2 || 112x PASS1 */ + +#define S_SCD_TRACE_CFG_CUR_ADDR 10 +#define M_SCD_TRACE_CFG_CUR_ADDR _SB_MAKEMASK(8,S_SCD_TRACE_CFG_CUR_ADDR) +#define V_SCD_TRACE_CFG_CUR_ADDR(x) _SB_MAKEVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR) +#define G_SCD_TRACE_CFG_CUR_ADDR(x) _SB_GETVALUE(x,S_SCD_TRACE_CFG_CUR_ADDR,M_SCD_TRACE_CFG_CUR_ADDR) + +/* + * Trace Event registers + */ + +#define S_SCD_TREVT_ADDR_MATCH 0 +#define M_SCD_TREVT_ADDR_MATCH _SB_MAKEMASK(4,S_SCD_TREVT_ADDR_MATCH) +#define V_SCD_TREVT_ADDR_MATCH(x) _SB_MAKEVALUE(x,S_SCD_TREVT_ADDR_MATCH) +#define G_SCD_TREVT_ADDR_MATCH(x) _SB_GETVALUE(x,S_SCD_TREVT_ADDR_MATCH,M_SCD_TREVT_ADDR_MATCH) + +#define M_SCD_TREVT_REQID_MATCH _SB_MAKEMASK1(4) +#define M_SCD_TREVT_DATAID_MATCH _SB_MAKEMASK1(5) +#define M_SCD_TREVT_RESPID_MATCH _SB_MAKEMASK1(6) +#define M_SCD_TREVT_INTERRUPT _SB_MAKEMASK1(7) +#define M_SCD_TREVT_DEBUG_PIN _SB_MAKEMASK1(9) +#define M_SCD_TREVT_WRITE _SB_MAKEMASK1(10) +#define M_SCD_TREVT_READ _SB_MAKEMASK1(11) + +#define S_SCD_TREVT_REQID 12 +#define M_SCD_TREVT_REQID _SB_MAKEMASK(4,S_SCD_TREVT_REQID) +#define V_SCD_TREVT_REQID(x) _SB_MAKEVALUE(x,S_SCD_TREVT_REQID) +#define G_SCD_TREVT_REQID(x) _SB_GETVALUE(x,S_SCD_TREVT_REQID,M_SCD_TREVT_REQID) + +#define S_SCD_TREVT_RESPID 16 +#define M_SCD_TREVT_RESPID _SB_MAKEMASK(4,S_SCD_TREVT_RESPID) +#define V_SCD_TREVT_RESPID(x) _SB_MAKEVALUE(x,S_SCD_TREVT_RESPID) +#define G_SCD_TREVT_RESPID(x) _SB_GETVALUE(x,S_SCD_TREVT_RESPID,M_SCD_TREVT_RESPID) + +#define S_SCD_TREVT_DATAID 20 +#define M_SCD_TREVT_DATAID _SB_MAKEMASK(4,S_SCD_TREVT_DATAID) +#define V_SCD_TREVT_DATAID(x) _SB_MAKEVALUE(x,S_SCD_TREVT_DATAID) +#define G_SCD_TREVT_DATAID(x) _SB_GETVALUE(x,S_SCD_TREVT_DATAID,M_SCD_TREVT_DATID) + +#define S_SCD_TREVT_COUNT 24 +#define M_SCD_TREVT_COUNT _SB_MAKEMASK(8,S_SCD_TREVT_COUNT) +#define V_SCD_TREVT_COUNT(x) _SB_MAKEVALUE(x,S_SCD_TREVT_COUNT) +#define G_SCD_TREVT_COUNT(x) _SB_GETVALUE(x,S_SCD_TREVT_COUNT,M_SCD_TREVT_COUNT) + +/* + * Trace Sequence registers + */ + +#define S_SCD_TRSEQ_EVENT4 0 +#define M_SCD_TRSEQ_EVENT4 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT4) +#define V_SCD_TRSEQ_EVENT4(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT4) +#define G_SCD_TRSEQ_EVENT4(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT4,M_SCD_TRSEQ_EVENT4) + +#define S_SCD_TRSEQ_EVENT3 4 +#define M_SCD_TRSEQ_EVENT3 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT3) +#define V_SCD_TRSEQ_EVENT3(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT3) +#define G_SCD_TRSEQ_EVENT3(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT3,M_SCD_TRSEQ_EVENT3) + +#define S_SCD_TRSEQ_EVENT2 8 +#define M_SCD_TRSEQ_EVENT2 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT2) +#define V_SCD_TRSEQ_EVENT2(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT2) +#define G_SCD_TRSEQ_EVENT2(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT2,M_SCD_TRSEQ_EVENT2) + +#define S_SCD_TRSEQ_EVENT1 12 +#define M_SCD_TRSEQ_EVENT1 _SB_MAKEMASK(4,S_SCD_TRSEQ_EVENT1) +#define V_SCD_TRSEQ_EVENT1(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_EVENT1) +#define G_SCD_TRSEQ_EVENT1(x) _SB_GETVALUE(x,S_SCD_TRSEQ_EVENT1,M_SCD_TRSEQ_EVENT1) + +#define K_SCD_TRSEQ_E0 0 +#define K_SCD_TRSEQ_E1 1 +#define K_SCD_TRSEQ_E2 2 +#define K_SCD_TRSEQ_E3 3 +#define K_SCD_TRSEQ_E0_E1 4 +#define K_SCD_TRSEQ_E1_E2 5 +#define K_SCD_TRSEQ_E2_E3 6 +#define K_SCD_TRSEQ_E0_E1_E2 7 +#define K_SCD_TRSEQ_E0_E1_E2_E3 8 +#define K_SCD_TRSEQ_E0E1 9 +#define K_SCD_TRSEQ_E0E1E2 10 +#define K_SCD_TRSEQ_E0E1E2E3 11 +#define K_SCD_TRSEQ_E0E1_E2 12 +#define K_SCD_TRSEQ_E0E1_E2E3 13 +#define K_SCD_TRSEQ_E0E1_E2_E3 14 +#define K_SCD_TRSEQ_IGNORED 15 + +#define K_SCD_TRSEQ_TRIGGER_ALL (V_SCD_TRSEQ_EVENT1(K_SCD_TRSEQ_IGNORED) | \ + V_SCD_TRSEQ_EVENT2(K_SCD_TRSEQ_IGNORED) | \ + V_SCD_TRSEQ_EVENT3(K_SCD_TRSEQ_IGNORED) | \ + V_SCD_TRSEQ_EVENT4(K_SCD_TRSEQ_IGNORED)) + +#define S_SCD_TRSEQ_FUNCTION 16 +#define M_SCD_TRSEQ_FUNCTION _SB_MAKEMASK(4,S_SCD_TRSEQ_FUNCTION) +#define V_SCD_TRSEQ_FUNCTION(x) _SB_MAKEVALUE(x,S_SCD_TRSEQ_FUNCTION) +#define G_SCD_TRSEQ_FUNCTION(x) _SB_GETVALUE(x,S_SCD_TRSEQ_FUNCTION,M_SCD_TRSEQ_FUNCTION) + +#define K_SCD_TRSEQ_FUNC_NOP 0 +#define K_SCD_TRSEQ_FUNC_START 1 +#define K_SCD_TRSEQ_FUNC_STOP 2 +#define K_SCD_TRSEQ_FUNC_FREEZE 3 + +#define V_SCD_TRSEQ_FUNC_NOP V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_NOP) +#define V_SCD_TRSEQ_FUNC_START V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_START) +#define V_SCD_TRSEQ_FUNC_STOP V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_STOP) +#define V_SCD_TRSEQ_FUNC_FREEZE V_SCD_TRSEQ_FUNCTION(K_SCD_TRSEQ_FUNC_FREEZE) + +#define M_SCD_TRSEQ_ASAMPLE _SB_MAKEMASK1(18) +#define M_SCD_TRSEQ_DSAMPLE _SB_MAKEMASK1(19) +#define M_SCD_TRSEQ_DEBUGPIN _SB_MAKEMASK1(20) +#define M_SCD_TRSEQ_DEBUGCPU _SB_MAKEMASK1(21) +#define M_SCD_TRSEQ_CLEARUSE _SB_MAKEMASK1(22) + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_smbus.h b/include/asm-mips64/sibyte/sb1250_smbus.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_smbus.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,170 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * SMBUS Constants File: sb1250_smbus.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's SMbus devices. + * + * SB1250 specification level: 01/02/2002 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_SMBUS_H +#define _SB1250_SMBUS_H + +#include "sb1250_defs.h" + +/* + * SMBus Clock Frequency Register (Table 14-2) + */ + +#define S_SMB_FREQ_DIV 0 +#define M_SMB_FREQ_DIV _SB_MAKEMASK(13,S_SMB_FREQ_DIV) +#define V_SMB_FREQ_DIV(x) _SB_MAKEVALUE(x,S_SMB_FREQ_DIV) + +#define K_SMB_FREQ_400KHZ 0x1F +#define K_SMB_FREQ_100KHZ 0x7D + +#define S_SMB_CMD 0 +#define M_SMB_CMD _SB_MAKEMASK(8,S_SMB_CMD) +#define V_SMB_CMD(x) _SB_MAKEVALUE(x,S_SMB_CMD) + +/* + * SMBus control register (Table 14-4) + */ + +#define M_SMB_ERR_INTR _SB_MAKEMASK1(0) +#define M_SMB_FINISH_INTR _SB_MAKEMASK1(1) +#define M_SMB_DATA_OUT _SB_MAKEMASK1(4) +#define M_SMB_DATA_DIR _SB_MAKEMASK1(5) +#define M_SMB_DATA_DIR_OUTPUT M_SMB_DATA_DIR +#define M_SMB_CLK_OUT _SB_MAKEMASK1(6) +#define M_SMB_DIRECT_ENABLE _SB_MAKEMASK1(7) + +/* + * SMBus status registers (Table 14-5) + */ + +#define M_SMB_BUSY _SB_MAKEMASK1(0) +#define M_SMB_ERROR _SB_MAKEMASK1(1) +#define M_SMB_ERROR_TYPE _SB_MAKEMASK1(2) +#define M_SMB_REF _SB_MAKEMASK1(6) +#define M_SMB_DATA_IN _SB_MAKEMASK1(7) + +/* + * SMBus Start/Command registers (Table 14-9) + */ + +#define S_SMB_ADDR 0 +#define M_SMB_ADDR _SB_MAKEMASK(7,S_SMB_ADDR) +#define V_SMB_ADDR(x) _SB_MAKEVALUE(x,S_SMB_ADDR) +#define G_SMB_ADDR(x) _SB_GETVALUE(x,S_SMB_ADDR,M_SMB_ADDR) + +#define M_SMB_QDATA _SB_MAKEMASK1(7) + +#define S_SMB_TT 8 +#define M_SMB_TT _SB_MAKEMASK(3,S_SMB_TT) +#define V_SMB_TT(x) _SB_MAKEVALUE(x,S_SMB_TT) +#define G_SMB_TT(x) _SB_GETVALUE(x,S_SMB_TT,M_SMB_TT) + +#define K_SMB_TT_WR1BYTE 0 +#define K_SMB_TT_WR2BYTE 1 +#define K_SMB_TT_WR3BYTE 2 +#define K_SMB_TT_CMD_RD1BYTE 3 +#define K_SMB_TT_CMD_RD2BYTE 4 +#define K_SMB_TT_RD1BYTE 5 +#define K_SMB_TT_QUICKCMD 6 +#define K_SMB_TT_EEPROMREAD 7 + +#define V_SMB_TT_WR1BYTE V_SMB_TT(K_SMB_TT_WR1BYTE) +#define V_SMB_TT_WR2BYTE V_SMB_TT(K_SMB_TT_WR2BYTE) +#define V_SMB_TT_WR3BYTE V_SMB_TT(K_SMB_TT_WR3BYTE) +#define V_SMB_TT_CMD_RD1BYTE V_SMB_TT(K_SMB_TT_CMD_RD1BYTE) +#define V_SMB_TT_CMD_RD2BYTE V_SMB_TT(K_SMB_TT_CMD_RD2BYTE) +#define V_SMB_TT_RD1BYTE V_SMB_TT(K_SMB_TT_RD1BYTE) +#define V_SMB_TT_QUICKCMD V_SMB_TT(K_SMB_TT_QUICKCMD) +#define V_SMB_TT_EEPROMREAD V_SMB_TT(K_SMB_TT_EEPROMREAD) + +#define M_SMB_PEC _SB_MAKEMASK1(15) + +/* + * SMBus Data Register (Table 14-6) and SMBus Extra Register (Table 14-7) + */ + +#define S_SMB_LB 0 +#define M_SMB_LB _SB_MAKEMASK(8,S_SMB_LB) +#define V_SMB_LB(x) _SB_MAKEVALUE(x,S_SMB_LB) + +#define S_SMB_MB 8 +#define M_SMB_MB _SB_MAKEMASK(8,S_SMB_MB) +#define V_SMB_MB(x) _SB_MAKEVALUE(x,S_SMB_MB) + + +/* + * SMBus Packet Error Check register (Table 14-8) + */ + +#define S_SPEC_PEC 0 +#define M_SPEC_PEC _SB_MAKEMASK(8,S_SPEC_PEC) +#define V_SPEC_MB(x) _SB_MAKEVALUE(x,S_SPEC_PEC) + + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) + +#define S_SMB_CMDH 8 +#define M_SMB_CMDH _SB_MAKEMASK(8,S_SMBH_CMD) +#define V_SMB_CMDH(x) _SB_MAKEVALUE(x,S_SMBH_CMD) + +#define M_SMB_EXTEND _SB_MAKEMASK1(14) + +#define M_SMB_DIR _SB_MAKEMASK1(13) + +#define S_SMB_DFMT 8 +#define M_SMB_DFMT _SB_MAKEMASK(3,S_SMB_DFMT) +#define V_SMB_DFMT(x) _SB_MAKEVALUE(x,S_SMB_DFMT) +#define G_SMB_DFMT(x) _SB_GETVALUE(x,S_SMB_DFMT,M_SMB_DFMT) + +#define K_SMB_DFMT_1BYTE 0 +#define K_SMB_DFMT_2BYTE 1 +#define K_SMB_DFMT_3BYTE 2 +#define K_SMB_DFMT_4BYTE 3 +#define K_SMB_DFMT_NODATA 4 +#define K_SMB_DFMT_CMD4BYTE 5 +#define K_SMB_DFMT_CMD5BYTE 6 +#define K_SMB_DFMT_RESERVED 7 + +#define V_SMB_DFMT_1BYTE V_SMB_DFMT(K_SMB_DFMT_1BYTE) +#define V_SMB_DFMT_2BYTE V_SMB_DFMT(K_SMB_DFMT_2BYTE) +#define V_SMB_DFMT_3BYTE V_SMB_DFMT(K_SMB_DFMT_3BYTE) +#define V_SMB_DFMT_4BYTE V_SMB_DFMT(K_SMB_DFMT_4BYTE) +#define V_SMB_DFMT_NODATA V_SMB_DFMT(K_SMB_DFMT_NODATA) +#define V_SMB_DFMT_CMD4BYTE V_SMB_DFMT(K_SMB_DFMT_CMD4BYTE) +#define V_SMB_DFMT_CMD5BYTE V_SMB_DFMT(K_SMB_DFMT_CMD5BYTE) +#define V_SMB_DFMT_RESERVED V_SMB_DFMT(K_SMB_DFMT_RESERVED) + +#endif /* 1250 PASS2 || 112x PASS1 */ + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_syncser.h b/include/asm-mips64/sibyte/sb1250_syncser.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_syncser.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,148 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * Synchronous Serial Constants File: sb1250_syncser.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's Synchronous Serial + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_SYNCSER_H +#define _SB1250_SYNCSER_H + +#include "sb1250_defs.h" + +/* + * Serial Mode Configuration Register + */ + +#define M_SYNCSER_CRC_MODE _SB_MAKEMASK1(0) +#define M_SYNCSER_MSB_FIRST _SB_MAKEMASK1(1) + +#define S_SYNCSER_FLAG_NUM 2 +#define M_SYNCSER_FLAG_NUM _SB_MAKEMASK(4,S_SYNCSER_FLAG_NUM) +#define V_SYNCSER_FLAG_NUM _SB_MAKEVALUE(x,S_SYNCSER_FLAG_NUM) + +#define M_SYNCSER_FLAG_EN _SB_MAKEMASK1(6) +#define M_SYNCSER_HDLC_EN _SB_MAKEMASK1(7) +#define M_SYNCSER_LOOP_MODE _SB_MAKEMASK1(8) +#define M_SYNCSER_LOOPBACK _SB_MAKEMASK1(9) + +/* + * Serial Clock Source and Line Interface Mode Register + */ + +#define M_SYNCSER_RXCLK_INV _SB_MAKEMASK1(0) +#define M_SYNCSER_RXCLK_EXT _SB_MAKEMASK1(1) + +#define S_SYNCSER_RXSYNC_DLY 2 +#define M_SYNCSER_RXSYNC_DLY _SB_MAKEMASK(2,S_SYNCSER_RXSYNC_DLY) +#define V_SYNCSER_RXSYNC_DLY(x) _SB_MAKEVALUE(x,S_SYNCSER_RXSYNC_DLY) + +#define M_SYNCSER_RXSYNC_LOW _SB_MAKEMASK1(4) +#define M_SYNCSER_RXSTRB_LOW _SB_MAKEMASK1(5) + +#define M_SYNCSER_RXSYNC_EDGE _SB_MAKEMASK1(6) +#define M_SYNCSER_RXSYNC_INT _SB_MAKEMASK1(7) + +#define M_SYNCSER_TXCLK_INV _SB_MAKEMASK1(8) +#define M_SYNCSER_TXCLK_EXT _SB_MAKEMASK1(9) + +#define S_SYNCSER_TXSYNC_DLY 10 +#define M_SYNCSER_TXSYNC_DLY _SB_MAKEMASK(2,S_SYNCSER_TXSYNC_DLY) +#define V_SYNCSER_TXSYNC_DLY(x) _SB_MAKEVALUE(x,S_SYNCSER_TXSYNC_DLY) + +#define M_SYNCSER_TXSYNC_LOW _SB_MAKEMASK1(12) +#define M_SYNCSER_TXSTRB_LOW _SB_MAKEMASK1(13) + +#define M_SYNCSER_TXSYNC_EDGE _SB_MAKEMASK1(14) +#define M_SYNCSER_TXSYNC_INT _SB_MAKEMASK1(15) + +/* + * Serial Command Register + */ + +#define M_SYNCSER_CMD_RX_EN _SB_MAKEMASK1(0) +#define M_SYNCSER_CMD_TX_EN _SB_MAKEMASK1(1) +#define M_SYNCSER_CMD_RX_RESET _SB_MAKEMASK1(2) +#define M_SYNCSER_CMD_TX_RESET _SB_MAKEMASK1(3) +#define M_SYNCSER_CMD_TX_PAUSE _SB_MAKEMASK1(5) + +/* + * Serial DMA Enable Register + */ + +#define M_SYNCSER_DMA_RX_EN _SB_MAKEMASK1(0) +#define M_SYNCSER_DMA_TX_EN _SB_MAKEMASK1(4) + +/* + * Serial Status Register + */ + +#define M_SYNCSER_RX_CRCERR _SB_MAKEMASK1(0) +#define M_SYNCSER_RX_ABORT _SB_MAKEMASK1(1) +#define M_SYNCSER_RX_OCTET _SB_MAKEMASK1(2) +#define M_SYNCSER_RX_LONGFRM _SB_MAKEMASK1(3) +#define M_SYNCSER_RX_SHORTFRM _SB_MAKEMASK1(4) +#define M_SYNCSER_RX_OVERRUN _SB_MAKEMASK1(5) +#define M_SYNCSER_RX_SYNC_ERR _SB_MAKEMASK1(6) +#define M_SYNCSER_TX_CRCERR _SB_MAKEMASK1(8) +#define M_SYNCSER_TX_UNDERRUN _SB_MAKEMASK1(9) +#define M_SYNCSER_TX_SYNC_ERR _SB_MAKEMASK1(10) +#define M_SYNCSER_TX_PAUSE_COMPLETE _SB_MAKEMASK1(11) +#define M_SYNCSER_RX_EOP_COUNT _SB_MAKEMASK1(16) +#define M_SYNCSER_RX_EOP_TIMER _SB_MAKEMASK1(17) +#define M_SYNCSER_RX_EOP_SEEN _SB_MAKEMASK1(18) +#define M_SYNCSER_RX_HWM _SB_MAKEMASK1(19) +#define M_SYNCSER_RX_LWM _SB_MAKEMASK1(20) +#define M_SYNCSER_RX_DSCR _SB_MAKEMASK1(21) +#define M_SYNCSER_RX_DERR _SB_MAKEMASK1(22) +#define M_SYNCSER_TX_EOP_COUNT _SB_MAKEMASK1(24) +#define M_SYNCSER_TX_EOP_TIMER _SB_MAKEMASK1(25) +#define M_SYNCSER_TX_EOP_SEEN _SB_MAKEMASK1(26) +#define M_SYNCSER_TX_HWM _SB_MAKEMASK1(27) +#define M_SYNCSER_TX_LWM _SB_MAKEMASK1(28) +#define M_SYNCSER_TX_DSCR _SB_MAKEMASK1(29) +#define M_SYNCSER_TX_DERR _SB_MAKEMASK1(30) +#define M_SYNCSER_TX_DZERO _SB_MAKEMASK1(31) + +/* + * Sequencer Table Entry format + */ + +#define M_SYNCSER_SEQ_LAST _SB_MAKEMASK1(0) +#define M_SYNCSER_SEQ_BYTE _SB_MAKEMASK1(1) + +#define S_SYNCSER_SEQ_COUNT 2 +#define M_SYNCSER_SEQ_COUNT _SB_MAKEMASK(4,S_SYNCSER_SEQ_COUNT) +#define V_SYNCSER_SEQ_COUNT(x) _SB_MAKEVALUE(x,S_SYNCSER_SEQ_COUNT) + +#define M_SYNCSER_SEQ_ENABLE _SB_MAKEMASK1(6) +#define M_SYNCSER_SEQ_STROBE _SB_MAKEMASK1(7) + +#endif diff -Nru a/include/asm-mips64/sibyte/sb1250_uart.h b/include/asm-mips64/sibyte/sb1250_uart.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sb1250_uart.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,354 @@ +/* ********************************************************************* + * SB1250 Board Support Package + * + * UART Constants File: sb1250_uart.h + * + * This module contains constants and macros useful for + * manipulating the SB1250's UARTs + * + * SB1250 specification level: User's manual 1/02/02 + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + ********************************************************************* */ + + +#ifndef _SB1250_UART_H +#define _SB1250_UART_H + +#include "sb1250_defs.h" + +/* ********************************************************************** + * DUART Registers + ********************************************************************** */ + +/* + * DUART Mode Register #1 (Table 10-3) + * Register: DUART_MODE_REG_1_A + * Register: DUART_MODE_REG_1_B + */ + +#define S_DUART_BITS_PER_CHAR 0 +#define M_DUART_BITS_PER_CHAR _SB_MAKEMASK(2,S_DUART_BITS_PER_CHAR) +#define V_DUART_BITS_PER_CHAR(x) _SB_MAKEVALUE(x,S_DUART_BITS_PER_CHAR) + +#define K_DUART_BITS_PER_CHAR_RSV0 0 +#define K_DUART_BITS_PER_CHAR_RSV1 1 +#define K_DUART_BITS_PER_CHAR_7 2 +#define K_DUART_BITS_PER_CHAR_8 3 + +#define V_DUART_BITS_PER_CHAR_RSV0 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV0) +#define V_DUART_BITS_PER_CHAR_RSV1 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_RSV1) +#define V_DUART_BITS_PER_CHAR_7 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_7) +#define V_DUART_BITS_PER_CHAR_8 V_DUART_BITS_PER_CHAR(K_DUART_BITS_PER_CHAR_8) + + +#define M_DUART_PARITY_TYPE_EVEN 0x00 +#define M_DUART_PARITY_TYPE_ODD _SB_MAKEMASK1(2) + +#define S_DUART_PARITY_MODE 3 +#define M_DUART_PARITY_MODE _SB_MAKEMASK(2,S_DUART_PARITY_MODE) +#define V_DUART_PARITY_MODE(x) _SB_MAKEVALUE(x,S_DUART_PARITY_MODE) + +#define K_DUART_PARITY_MODE_ADD 0 +#define K_DUART_PARITY_MODE_ADD_FIXED 1 +#define K_DUART_PARITY_MODE_NONE 2 + +#define V_DUART_PARITY_MODE_ADD V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD) +#define V_DUART_PARITY_MODE_ADD_FIXED V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_ADD_FIXED) +#define V_DUART_PARITY_MODE_NONE V_DUART_PARITY_MODE(K_DUART_PARITY_MODE_NONE) + +#define M_DUART_ERR_MODE _SB_MAKEMASK1(5) /* must be zero */ + +#define M_DUART_RX_IRQ_SEL_RXRDY 0 +#define M_DUART_RX_IRQ_SEL_RXFULL _SB_MAKEMASK1(6) + +#define M_DUART_RX_RTS_ENA _SB_MAKEMASK1(7) + +/* + * DUART Mode Register #2 (Table 10-4) + * Register: DUART_MODE_REG_2_A + * Register: DUART_MODE_REG_2_B + */ + +#define M_DUART_MODE_RESERVED1 _SB_MAKEMASK(3,0) /* ignored */ + +#define M_DUART_STOP_BIT_LEN_2 _SB_MAKEMASK1(3) +#define M_DUART_STOP_BIT_LEN_1 0 + +#define M_DUART_TX_CTS_ENA _SB_MAKEMASK1(4) + + +#define M_DUART_MODE_RESERVED2 _SB_MAKEMASK1(5) /* must be zero */ + +#define S_DUART_CHAN_MODE 6 +#define M_DUART_CHAN_MODE _SB_MAKEMASK(2,S_DUART_CHAN_MODE) +#define V_DUART_CHAN_MODE(x) _SB_MAKEVALUE(x,S_DUART_CHAN_MODE) + +#define K_DUART_CHAN_MODE_NORMAL 0 +#define K_DUART_CHAN_MODE_LCL_LOOP 2 +#define K_DUART_CHAN_MODE_REM_LOOP 3 + +#define V_DUART_CHAN_MODE_NORMAL V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_NORMAL) +#define V_DUART_CHAN_MODE_LCL_LOOP V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_LCL_LOOP) +#define V_DUART_CHAN_MODE_REM_LOOP V_DUART_CHAN_MODE(K_DUART_CHAN_MODE_REM_LOOP) + +/* + * DUART Command Register (Table 10-5) + * Register: DUART_CMD_A + * Register: DUART_CMD_B + */ + +#define M_DUART_RX_EN _SB_MAKEMASK1(0) +#define M_DUART_RX_DIS _SB_MAKEMASK1(1) +#define M_DUART_TX_EN _SB_MAKEMASK1(2) +#define M_DUART_TX_DIS _SB_MAKEMASK1(3) + +#define S_DUART_MISC_CMD 4 +#define M_DUART_MISC_CMD _SB_MAKEMASK(3,S_DUART_MISC_CMD) +#define V_DUART_MISC_CMD(x) _SB_MAKEVALUE(x,S_DUART_MISC_CMD) + +#define K_DUART_MISC_CMD_NOACTION0 0 +#define K_DUART_MISC_CMD_NOACTION1 1 +#define K_DUART_MISC_CMD_RESET_RX 2 +#define K_DUART_MISC_CMD_RESET_TX 3 +#define K_DUART_MISC_CMD_NOACTION4 4 +#define K_DUART_MISC_CMD_RESET_BREAK_INT 5 +#define K_DUART_MISC_CMD_START_BREAK 6 +#define K_DUART_MISC_CMD_STOP_BREAK 7 + +#define V_DUART_MISC_CMD_NOACTION0 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION0) +#define V_DUART_MISC_CMD_NOACTION1 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION1) +#define V_DUART_MISC_CMD_RESET_RX V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_RX) +#define V_DUART_MISC_CMD_RESET_TX V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_TX) +#define V_DUART_MISC_CMD_NOACTION4 V_DUART_MISC_CMD(K_DUART_MISC_CMD_NOACTION4) +#define V_DUART_MISC_CMD_RESET_BREAK_INT V_DUART_MISC_CMD(K_DUART_MISC_CMD_RESET_BREAK_INT) +#define V_DUART_MISC_CMD_START_BREAK V_DUART_MISC_CMD(K_DUART_MISC_CMD_START_BREAK) +#define V_DUART_MISC_CMD_STOP_BREAK V_DUART_MISC_CMD(K_DUART_MISC_CMD_STOP_BREAK) + +#define M_DUART_CMD_RESERVED _SB_MAKEMASK1(7) + +/* + * DUART Status Register (Table 10-6) + * Register: DUART_STATUS_A + * Register: DUART_STATUS_B + * READ-ONLY + */ + +#define M_DUART_RX_RDY _SB_MAKEMASK1(0) +#define M_DUART_RX_FFUL _SB_MAKEMASK1(1) +#define M_DUART_TX_RDY _SB_MAKEMASK1(2) +#define M_DUART_TX_EMT _SB_MAKEMASK1(3) +#define M_DUART_OVRUN_ERR _SB_MAKEMASK1(4) +#define M_DUART_PARITY_ERR _SB_MAKEMASK1(5) +#define M_DUART_FRM_ERR _SB_MAKEMASK1(6) +#define M_DUART_RCVD_BRK _SB_MAKEMASK1(7) + +/* + * DUART Baud Rate Register (Table 10-7) + * Register: DUART_CLK_SEL_A + * Register: DUART_CLK_SEL_B + */ + +#define M_DUART_CLK_COUNTER _SB_MAKEMASK(12,0) +#define V_DUART_BAUD_RATE(x) (100000000/((x)*20)-1) + +/* + * DUART Data Registers (Table 10-8 and 10-9) + * Register: DUART_RX_HOLD_A + * Register: DUART_RX_HOLD_B + * Register: DUART_TX_HOLD_A + * Register: DUART_TX_HOLD_B + */ + +#define M_DUART_RX_DATA _SB_MAKEMASK(8,0) +#define M_DUART_TX_DATA _SB_MAKEMASK(8,0) + +/* + * DUART Input Port Register (Table 10-10) + * Register: DUART_IN_PORT + */ + +#define M_DUART_IN_PIN0_VAL _SB_MAKEMASK1(0) +#define M_DUART_IN_PIN1_VAL _SB_MAKEMASK1(1) +#define M_DUART_IN_PIN2_VAL _SB_MAKEMASK1(2) +#define M_DUART_IN_PIN3_VAL _SB_MAKEMASK1(3) +#define M_DUART_IN_PIN4_VAL _SB_MAKEMASK1(4) +#define M_DUART_IN_PIN5_VAL _SB_MAKEMASK1(5) +#define M_DUART_RIN0_PIN _SB_MAKEMASK1(6) +#define M_DUART_RIN1_PIN _SB_MAKEMASK1(7) + +/* + * DUART Input Port Change Status Register (Tables 10-11, 10-12, and 10-13) + * Register: DUART_INPORT_CHNG + */ + +#define S_DUART_IN_PIN_VAL 0 +#define M_DUART_IN_PIN_VAL _SB_MAKEMASK(4,S_DUART_IN_PIN_VAL) + +#define S_DUART_IN_PIN_CHNG 4 +#define M_DUART_IN_PIN_CHNG _SB_MAKEMASK(4,S_DUART_IN_PIN_CHNG) + + +/* + * DUART Output port control register (Table 10-14) + * Register: DUART_OPCR + */ + +#define M_DUART_OPCR_RESERVED0 _SB_MAKEMASK1(0) /* must be zero */ +#define M_DUART_OPC2_SEL _SB_MAKEMASK1(1) +#define M_DUART_OPCR_RESERVED1 _SB_MAKEMASK1(2) /* must be zero */ +#define M_DUART_OPC3_SEL _SB_MAKEMASK1(3) +#define M_DUART_OPCR_RESERVED2 _SB_MAKEMASK(4,4) /* must be zero */ + +/* + * DUART Aux Control Register (Table 10-15) + * Register: DUART_AUX_CTRL + */ + +#define M_DUART_IP0_CHNG_ENA _SB_MAKEMASK1(0) +#define M_DUART_IP1_CHNG_ENA _SB_MAKEMASK1(1) +#define M_DUART_IP2_CHNG_ENA _SB_MAKEMASK1(2) +#define M_DUART_IP3_CHNG_ENA _SB_MAKEMASK1(3) +#define M_DUART_ACR_RESERVED _SB_MAKEMASK(4,4) + +#define M_DUART_CTS_CHNG_ENA _SB_MAKEMASK1(0) +#define M_DUART_CIN_CHNG_ENA _SB_MAKEMASK1(2) + +/* + * DUART Interrupt Status Register (Table 10-16) + * Register: DUART_ISR + */ + +#define M_DUART_ISR_TX_A _SB_MAKEMASK1(0) +#define M_DUART_ISR_RX_A _SB_MAKEMASK1(1) +#define M_DUART_ISR_BRK_A _SB_MAKEMASK1(2) +#define M_DUART_ISR_IN_A _SB_MAKEMASK1(3) +#define M_DUART_ISR_TX_B _SB_MAKEMASK1(4) +#define M_DUART_ISR_RX_B _SB_MAKEMASK1(5) +#define M_DUART_ISR_BRK_B _SB_MAKEMASK1(6) +#define M_DUART_ISR_IN_B _SB_MAKEMASK1(7) + +/* + * DUART Channel A Interrupt Status Register (Table 10-17) + * DUART Channel B Interrupt Status Register (Table 10-18) + * Register: DUART_ISR_A + * Register: DUART_ISR_B + */ + +#define M_DUART_ISR_TX _SB_MAKEMASK1(0) +#define M_DUART_ISR_RX _SB_MAKEMASK1(1) +#define M_DUART_ISR_BRK _SB_MAKEMASK1(2) +#define M_DUART_ISR_IN _SB_MAKEMASK1(3) +#define M_DUART_ISR_RESERVED _SB_MAKEMASK(4,4) + +/* + * DUART Interrupt Mask Register (Table 10-19) + * Register: DUART_IMR + */ + +#define M_DUART_IMR_TX_A _SB_MAKEMASK1(0) +#define M_DUART_IMR_RX_A _SB_MAKEMASK1(1) +#define M_DUART_IMR_BRK_A _SB_MAKEMASK1(2) +#define M_DUART_IMR_IN_A _SB_MAKEMASK1(3) +#define M_DUART_IMR_ALL_A _SB_MAKEMASK(4,0) + +#define M_DUART_IMR_TX_B _SB_MAKEMASK1(4) +#define M_DUART_IMR_RX_B _SB_MAKEMASK1(5) +#define M_DUART_IMR_BRK_B _SB_MAKEMASK1(6) +#define M_DUART_IMR_IN_B _SB_MAKEMASK1(7) +#define M_DUART_IMR_ALL_B _SB_MAKEMASK(4,4) + +/* + * DUART Channel A Interrupt Mask Register (Table 10-20) + * DUART Channel B Interrupt Mask Register (Table 10-21) + * Register: DUART_IMR_A + * Register: DUART_IMR_B + */ + +#define M_DUART_IMR_TX _SB_MAKEMASK1(0) +#define M_DUART_IMR_RX _SB_MAKEMASK1(1) +#define M_DUART_IMR_BRK _SB_MAKEMASK1(2) +#define M_DUART_IMR_IN _SB_MAKEMASK1(3) +#define M_DUART_IMR_ALL _SB_MAKEMASK(4,0) +#define M_DUART_IMR_RESERVED _SB_MAKEMASK(4,4) + + +/* + * DUART Output Port Set Register (Table 10-22) + * Register: DUART_SET_OPR + */ + +#define M_DUART_SET_OPR0 _SB_MAKEMASK1(0) +#define M_DUART_SET_OPR1 _SB_MAKEMASK1(1) +#define M_DUART_SET_OPR2 _SB_MAKEMASK1(2) +#define M_DUART_SET_OPR3 _SB_MAKEMASK1(3) +#define M_DUART_OPSR_RESERVED _SB_MAKEMASK(4,4) + +/* + * DUART Output Port Clear Register (Table 10-23) + * Register: DUART_CLEAR_OPR + */ + +#define M_DUART_CLR_OPR0 _SB_MAKEMASK1(0) +#define M_DUART_CLR_OPR1 _SB_MAKEMASK1(1) +#define M_DUART_CLR_OPR2 _SB_MAKEMASK1(2) +#define M_DUART_CLR_OPR3 _SB_MAKEMASK1(3) +#define M_DUART_OPCR_RESERVED _SB_MAKEMASK(4,4) + +/* + * DUART Output Port RTS Register (Table 10-24) + * Register: DUART_OUT_PORT + */ + +#define M_DUART_OUT_PIN_SET0 _SB_MAKEMASK1(0) +#define M_DUART_OUT_PIN_SET1 _SB_MAKEMASK1(1) +#define M_DUART_OUT_PIN_CLR0 _SB_MAKEMASK1(2) +#define M_DUART_OUT_PIN_CLR1 _SB_MAKEMASK1(3) +#define M_DUART_OPRR_RESERVED _SB_MAKEMASK(4,4) + +#define M_DUART_OUT_PIN_SET(chan) \ + (chan == 0 ? M_DUART_OUT_PIN_SET0 : M_DUART_OUT_PIN_SET1) +#define M_DUART_OUT_PIN_CLR(chan) \ + (chan == 0 ? M_DUART_OUT_PIN_CLR0 : M_DUART_OUT_PIN_CLR1) + +#if SIBYTE_HDR_FEATURE(1250, PASS2) || SIBYTE_HDR_FEATURE(112x, PASS1) +/* + * Full Interrupt Control Register + */ + +#define S_DUART_SIG_FULL _SB_MAKE64(0) +#define M_DUART_SIG_FULL _SB_MAKEMASK(4,S_DUART_SIG_FULL) +#define V_DUART_SIG_FULL(x) _SB_MAKEVALUE(x,S_DUART_SIG_FULL) +#define G_DUART_SIG_FULL(x) _SB_GETVALUE(x,S_DUART_SIG_FULL,M_DUART_SIG_FULL) + +#define S_DUART_INT_TIME _SB_MAKE64(4) +#define M_DUART_INT_TIME _SB_MAKEMASK(4,S_DUART_INT_TIME) +#define V_DUART_INT_TIME(x) _SB_MAKEVALUE(x,S_DUART_INT_TIME) +#define G_DUART_INT_TIME(x) _SB_GETVALUE(x,S_DUART_INT_TIME,M_DUART_INT_TIME) +#endif /* 1250 PASS2 || 112x PASS1 */ + + +/* ********************************************************************** */ + + +#endif diff -Nru a/include/asm-mips64/sibyte/sentosa.h b/include/asm-mips64/sibyte/sentosa.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/sentosa.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __ASM_SIBYTE_SENTOSA_H +#define __ASM_SIBYTE_SENTOSA_H + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_int.h> + +#ifdef CONFIG_SIBYTE_SENTOSA +#define SIBYTE_BOARD_NAME "BCM91250E (Sentosa)" +#endif +#ifdef CONFIG_SIBYTE_RHONE +#define SIBYTE_BOARD_NAME "BCM91125E (Rhone)" +#endif + +/* Generic bus chip selects */ +#ifdef CONFIG_SIBYTE_RHONE +#define LEDS_CS 6 +#define LEDS_PHYS 0x1d0a0000 +#endif + +/* GPIOs */ +#define K_GPIO_DBG_LED 0 + +#endif /* __ASM_SIBYTE_SENTOSA_H */ diff -Nru a/include/asm-mips64/sibyte/swarm.h b/include/asm-mips64/sibyte/swarm.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/swarm.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2000, 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __ASM_SIBYTE_SWARM_H +#define __ASM_SIBYTE_SWARM_H + +#include <asm/sibyte/sb1250.h> +#include <asm/sibyte/sb1250_int.h> + +#ifdef CONFIG_SIBYTE_SWARM +#define SIBYTE_BOARD_NAME "BCM91250A (SWARM)" +#endif +#ifdef CONFIG_SIBYTE_PTSWARM +#define SIBYTE_BOARD_NAME "PTSWARM" +#endif +#ifdef CONFIG_SIBYTE_CRHONE +#define SIBYTE_BOARD_NAME "BCM91125C (CRhone)" +#endif +#ifdef CONFIG_SIBYTE_CRHINE +#define SIBYTE_BOARD_NAME "BCM91120C (CRhine)" +#endif + +/* Generic bus chip selects */ +#define LEDS_CS 3 +#define LEDS_PHYS 0x100a0000 +#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) +#define IDE_CS 4 +#define IDE_PHYS 0x100b0000 +#define PCMCIA_CS 6 +#define PCMCIA_PHYS 0x11000000 +#endif + +/* GPIOs */ +#if defined(CONFIG_SIBYTE_SWARM) || defined(CONFIG_SIBYTE_PTSWARM) +#define K_GPIO_GB_IDE 4 +#define K_INT_GB_IDE (K_INT_GPIO_0 + K_GPIO_GB_IDE) +#define K_GPIO_PC_READY 9 +#define K_INT_PC_READY (K_INT_GPIO_0 + K_GPIO_PC_READY) +#endif + +#endif /* __ASM_SIBYTE_SWARM_H */ diff -Nru a/include/asm-mips64/sibyte/trace_prof.h b/include/asm-mips64/sibyte/trace_prof.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/sibyte/trace_prof.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2001 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ASM_SIBYTE_TRACE_PROF_H +#define __ASM_SIBYTE_TRACE_PROF_H + +#if SBPROF_TB_DEBUG +#define DBG(a) a +#else +#define DBG(a) +#endif + +#define SBPROF_TB_MAJOR 240 +#define DEVNAME "bcm1250_tbprof" + +typedef u_int64_t tb_sample_t[6*256]; + +struct sbprof_tb { + int open; + tb_sample_t *sbprof_tbbuf; + int next_tb_sample; + + volatile int tb_enable; + volatile int tb_armed; + + wait_queue_head_t tb_sync; + wait_queue_head_t tb_read; +}; + +#define MAX_SAMPLE_BYTES (24*1024*1024) +#define MAX_TBSAMPLE_BYTES (12*1024*1024) + +#define MAX_SAMPLES (MAX_SAMPLE_BYTES/sizeof(u_int32_t)) +#define TB_SAMPLE_SIZE (sizeof(tb_sample_t)) +#define MAX_TB_SAMPLES (MAX_TBSAMPLE_BYTES/TB_SAMPLE_SIZE) + +/* IOCTLs */ +#define SBPROF_ZBSTART _IOW('s', 0, int) +#define SBPROF_ZBSTOP _IOW('s', 1, int) +#define SBPROF_ZBWAITFULL _IOW('s', 2, int) + +/*************************************************************************** + * Routines for gathering ZBbus profiles using trace buffer + ***************************************************************************/ + +/* Requires: Already called zclk_timer_init with a value that won't + saturate 40 bits. No subsequent use of SCD performance counters + or trace buffer. + Effect: Starts gathering random ZBbus profiles using trace buffer. */ +static int sbprof_zbprof_start(struct file *filp); + +/* Effect: Stops collection of ZBbus profiles */ +static int sbprof_zbprof_stop(void); + + +/*************************************************************************** + * Routines for using 40-bit SCD cycle counter + * + * Client responsible for either handling interrupts or making sure + * the cycles counter never saturates, e.g., by doing + * zclk_timer_init(0) at least every 2^40 - 1 ZCLKs. + ***************************************************************************/ + +/* Configures SCD counter 0 to count ZCLKs starting from val; + Configures SCD counters1,2,3 to count nothing. + Must not be called while gathering ZBbus profiles. + +unsigned long long val; */ +#define zclk_timer_init(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "sd %0, 0x10($8);" /* write val to counter0 */ \ + "sd %1, 0($8);" /* config counter0 for zclks*/ \ + ".set pop" \ + : /* no outputs */ \ + /* enable, counter0 */ \ + : /* inputs */ "r"(val), "r" ((1ULL << 33) | 1ULL) \ + : /* modifies */ "$8" ) + + +/* Reads SCD counter 0 and puts result in value + unsigned long long val; */ +#define zclk_get(val) \ + __asm__ __volatile__ (".set push;" \ + ".set mips64;" \ + "la $8, 0xb00204c0;" /* SCD perf_cnt_cfg */ \ + "ld %0, 0x10($8);" /* write val to counter0 */ \ + ".set pop" \ + : /* outputs */ "=r"(val) \ + : /* inputs */ \ + : /* modifies */ "$8" ) + +#endif /* __ASM_SIBYTE_TRACE_PROF_H */ diff -Nru a/include/asm-mips64/sigcontext.h b/include/asm-mips64/sigcontext.h --- a/include/asm-mips64/sigcontext.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/sigcontext.h Fri Jun 27 14:19:57 2003 @@ -20,10 +20,9 @@ unsigned long long sc_mdlo; unsigned long long sc_pc; unsigned int sc_status; - unsigned int sc_ownedfp; unsigned int sc_fpc_csr; unsigned int sc_fpc_eir; - + unsigned int sc_used_math; unsigned int sc_cause; unsigned int sc_badvaddr; }; diff -Nru a/include/asm-mips64/siginfo.h b/include/asm-mips64/siginfo.h --- a/include/asm-mips64/siginfo.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-mips64/siginfo.h Fri Jun 27 14:20:01 2003 @@ -9,20 +9,25 @@ #ifndef _ASM_SIGINFO_H #define _ASM_SIGINFO_H +/* This structure matches IRIX 32/n32 ABIs for binary compatibility but + has Linux extensions. */ + #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) +#define SI_PAD_SIZE ((SI_MAX_SIZE/sizeof(int)) - 4) +#define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3) #define HAVE_ARCH_SIGINFO_T #define HAVE_ARCH_SIGEVENT_T + +/* + * We duplicate the generic versions - <asm-generic/siginfo.h> is just borked + * by design ... + */ #define HAVE_ARCH_COPY_SIGINFO -#define HAVE_ARCH_COPY_SIGINFO_TO_USER +struct siginfo; #include <asm-generic/siginfo.h> -/* The sigval union matches IRIX 32/n32 ABIs for binary compatibility. */ - -/* This structure matches IRIX 32/n32 ABIs for binary compatibility but - has Linux extensions. */ - typedef struct siginfo { int si_signo; int si_code; @@ -67,8 +72,11 @@ /* POSIX.1b timers */ struct { - unsigned int _timer1; - unsigned int _timer2; + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ } _timer; /* POSIX.1b signals */ @@ -81,6 +89,73 @@ } _sifields; } siginfo_t; +#ifdef __KERNEL__ + +typedef union sigval32 { + int sival_int; + s32 sival_ptr; +} sigval_t32; + +typedef struct siginfo32 { + int si_signo; + int si_code; + int si_errno; + + union { + int _pad[SI_PAD_SIZE32]; + + /* kill() */ + struct { + __kernel_pid_t32 _pid; /* sender's pid */ + __kernel_uid_t32 _uid; /* sender's uid */ + } _kill; + + /* SIGCHLD */ + struct { + __kernel_pid_t32 _pid; /* which child */ + __kernel_uid_t32 _uid; /* sender's uid */ + __kernel_clock_t32 _utime; + int _status; /* exit code */ + __kernel_clock_t32 _stime; + } _sigchld; + + /* IRIX SIGCHLD */ + struct { + __kernel_pid_t32 _pid; /* which child */ + __kernel_clock_t32 _utime; + int _status; /* exit code */ + __kernel_clock_t32 _stime; + } _irix_sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + s32 _addr; /* faulting insn/memory ref. */ + } _sigfault; + + /* SIGPOLL, SIGXFSZ (To do ...) */ + struct { + int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + + /* POSIX.1b timers */ + struct { + unsigned int _timer1; + unsigned int _timer2; + } _timer; + + /* POSIX.1b signals */ + struct { + __kernel_pid_t32 _pid; /* sender's pid */ + __kernel_uid_t32 _uid; /* sender's uid */ + sigval_t32 _sigval; + } _rt; + + } _sifields; +} siginfo_t32; + +#endif /* __KERNEL__ */ + /* * si_code values * Again these have been choosen to be IRIX compatible. @@ -94,8 +169,8 @@ /* * sigevent definitions - * - * It seems likely that SIGEV_THREAD will have to be handled from + * + * It seems likely that SIGEV_THREAD will have to be handled from * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the * thread manager then catches and does the appropriate nonsense. * However, everything is written out here so as to not get lost. @@ -110,21 +185,25 @@ /* XXX This one isn't yet IRIX / ABI compatible. */ typedef struct sigevent { - int sigev_notify; - sigval_t sigev_value; - int sigev_signo; + int sigev_notify; + sigval_t sigev_value; + int sigev_signo; union { - int _pad[SIGEV_PAD_SIZE]; + int _pad[SIGEV_PAD_SIZE]; + int _tid; struct { - void (*_function)(sigval_t); - void *_attribute; /* really pthread_attr_t */ + void (*_function)(sigval_t); + void *_attribute; /* really pthread_attr_t */ } _sigev_thread; } _sigev_un; } sigevent_t; #ifdef __KERNEL__ +/* + * Duplicated here because of <asm-generic/siginfo.h> braindamage ... + */ #include <linux/string.h> static inline void copy_siginfo(struct siginfo *to, struct siginfo *from) diff -Nru a/include/asm-mips64/signal.h b/include/asm-mips64/signal.h --- a/include/asm-mips64/signal.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/signal.h Fri Jun 27 14:19:59 2003 @@ -16,11 +16,10 @@ #define _NSIG_WORDS (_NSIG / _NSIG_BPW) typedef struct { - long sig[_NSIG_WORDS]; + unsigned long sig[_NSIG_WORDS]; } sigset_t; typedef unsigned long old_sigset_t; /* at least 32 bits */ -typedef unsigned int old_sigset_t32; #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ @@ -87,9 +86,9 @@ #define SA_ONESHOT SA_RESETHAND #define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ -#define SA_RESTORER 0x04000000 +#define SA_RESTORER 0x04000000 /* Only for o32 compat code */ -/* +/* * sigaltstack controls */ #define SS_ONSTACK 1 @@ -131,8 +130,6 @@ unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; - void (*sa_restorer)(void); - int sa_resv[1]; /* reserved */ }; struct k_sigaction { @@ -149,28 +146,8 @@ #ifdef __KERNEL__ #include <asm/sigcontext.h> -/* - * The following break codes are or were in use for specific purposes in - * other MIPS operating systems. Linux/MIPS doesn't use all of them. The - * unused ones are here as placeholders; we might encounter them in - * non-Linux/MIPS object files or make use of them in the future. - */ -#define BRK_USERBP 0 /* User bp (used by debuggers) */ -#define BRK_KERNELBP 1 /* Break in the kernel */ -#define BRK_ABORT 2 /* Sometimes used by abort(3) to SIGIOT */ -#define BRK_BD_TAKEN 3 /* For bd slot emulation - not implemented */ -#define BRK_BD_NOTTAKEN 4 /* For bd slot emulation - not implemented */ -#define BRK_SSTEPBP 5 /* User bp (used by debuggers) */ -#define BRK_OVERFLOW 6 /* Overflow check */ -#define BRK_DIVZERO 7 /* Divide by zero check */ -#define BRK_RANGE 8 /* Range error check */ -#define BRK_STACKOVERFLOW 9 /* For Ada stackchecking */ -#define BRK_NORLD 10 /* No rld found - not used by Linux/MIPS */ -#define _BRK_THREADBP 11 /* For threads, user bp (used by debuggers) */ -#define BRK_MULOVF 1023 /* Multiply overflow */ - #define ptrace_signal_deliver(regs, cookie) do { } while (0) -#endif /* defined (__KERNEL__) || defined (__USE_MISC) */ +#endif /* __KERNEL__ */ #endif /* !defined (_ASM_SIGNAL_H) */ diff -Nru a/include/asm-mips64/smp.h b/include/asm-mips64/smp.h --- a/include/asm-mips64/smp.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/smp.h Fri Jun 27 14:19:54 2003 @@ -5,8 +5,9 @@ * * Copyright (C) 2000 - 2001 by Kanoj Sarcar (kanoj@sgi.com) * Copyright (C) 2000 - 2001 by Silicon Graphics, Inc. + * Copyright (C) 2000, 2001, 2002 Ralf Baechle + * Copyright (C) 2000, 2001 Broadcom Corporation */ - #ifndef __ASM_SMP_H #define __ASM_SMP_H @@ -14,29 +15,11 @@ #ifdef CONFIG_SMP +#include <linux/bitops.h> #include <linux/threads.h> -#include <linux/irq.h> - -#if 0 -struct cpuinfo_mips { /* XXX */ - unsigned long loops_per_sec; - unsigned long last_asn; - unsigned long *pgd_cache; - unsigned long *pte_cache; - unsigned long pgtable_cache_sz; - unsigned long ipi_count; - unsigned long irq_attempt[NR_IRQS]; - unsigned long smp_local_irq_count; - unsigned long prof_multiplier; - unsigned long prof_counter; -} __attribute__((aligned(64))); - -extern struct cpuinfo_mips cpu_data[NR_CPUS]; -#endif +#include <asm/atomic.h> -#define smp_processor_id() (current->processor) - -#define PROC_CHANGE_PENALTY 20 +#define smp_processor_id() (current_thread_info()->cpu) /* Map from cpu id to sequential logical cpu number. This will only not be idempotent when cpus failed to come on-line. */ @@ -47,18 +30,29 @@ extern int __cpu_logical_map[NR_CPUS]; #define cpu_logical_map(cpu) __cpu_logical_map[cpu] -#endif - #define NO_PROC_ID (-1) +struct call_data_struct { + void (*func)(void *); + void *info; + atomic_t started; + atomic_t finished; + int wait; +}; + +extern struct call_data_struct *call_data; + +#define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ +#define SMP_CALL_FUNCTION 0x2 + #if (NR_CPUS <= _MIPS_SZLONG) typedef unsigned long cpumask_t; #define CPUMASK_CLRALL(p) (p) = 0 -#define CPUMASK_SETB(p, bit) (p) |= 1 << (bit) -#define CPUMASK_CLRB(p, bit) (p) &= ~(1ULL << (bit)) -#define CPUMASK_TSTB(p, bit) ((p) & (1ULL << (bit))) +#define CPUMASK_SETB(p, bit) (p) |= 1UL << (bit) +#define CPUMASK_CLRB(p, bit) (p) &= ~(1UL << (bit)) +#define CPUMASK_TSTB(p, bit) ((p) & (1UL << (bit))) #elif (NR_CPUS <= 128) @@ -75,14 +69,34 @@ #define CPUMASK_CLRALL(p) (p)._bits[0] = 0, (p)._bits[1] = 0 #define CPUMASK_SETB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] |= \ - (1ULL << CPUMASK_SHFT(bit)) + (1UL << CPUMASK_SHFT(bit)) #define CPUMASK_CLRB(p, bit) (p)._bits[CPUMASK_INDEX(bit)] &= \ - ~(1ULL << CPUMASK_SHFT(bit)) + ~(1UL << CPUMASK_SHFT(bit)) #define CPUMASK_TSTB(p, bit) ((p)._bits[CPUMASK_INDEX(bit)] & \ - (1ULL << CPUMASK_SHFT(bit))) + (1UL << CPUMASK_SHFT(bit))) #else #error cpumask macros only defined for 128p kernels #endif + +extern cpumask_t phys_cpu_present_map; +extern cpumask_t cpu_online_map; + +#define cpu_possible(cpu) (phys_cpu_present_map & (1<<(cpu))) +#define cpu_online(cpu) (cpu_online_map & (1<<(cpu))) + +extern inline unsigned int num_online_cpus(void) +{ + return hweight32(cpu_online_map); +} + +extern volatile unsigned long cpu_callout_map; +/* We don't mark CPUs online until __cpu_up(), so we need another measure */ +static inline int num_booting_cpus(void) +{ + return hweight32(cpu_callout_map); +} + +#endif /* CONFIG_SMP */ #endif /* __ASM_SMP_H */ diff -Nru a/include/asm-mips64/smplock.h b/include/asm-mips64/smplock.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/smplock.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,67 @@ +/* + * 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. + * + * Default SMP lock implementation + */ +#include <linux/config.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> + +extern spinlock_t kernel_flag; + +#ifdef CONFIG_SMP +#define kernel_locked() spin_is_locked(&kernel_flag) +#else +#ifdef CONFIG_PREEMPT +#define kernel_locked() preempt_count() +#else +#define kernel_locked() 1 +#endif +#endif + +/* + * Release global kernel lock and global interrupt lock + */ +#define release_kernel_lock(task) \ +do { \ + if (unlikely(task->lock_depth >= 0)) \ + spin_unlock(&kernel_flag); \ +} while (0) + +/* + * Re-acquire the kernel lock + */ +#define reacquire_kernel_lock(task) \ +do { \ + if (unlikely(task->lock_depth >= 0)) \ + spin_lock(&kernel_flag); \ +} while (0) + + +/* + * Getting the big kernel lock. + * + * This cannot happen asynchronously, + * so we only need to worry about other + * CPU's. + */ +static __inline__ void lock_kernel(void) +{ +#ifdef CONFIG_PREEMPT + if (current->lock_depth == -1) + spin_lock(&kernel_flag); + ++current->lock_depth; +#else + + if (!++current->lock_depth) + spin_lock(&kernel_flag); +#endif +} + +static __inline__ void unlock_kernel(void) +{ + if (--current->lock_depth < 0) + spin_unlock(&kernel_flag); +} diff -Nru a/include/asm-mips64/sn/addrs.h b/include/asm-mips64/sn/addrs.h --- a/include/asm-mips64/sn/addrs.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/sn/addrs.h Fri Jun 27 14:19:57 2003 @@ -11,9 +11,9 @@ #include <linux/config.h> -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #include <linux/types.h> -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #include <asm/addrspace.h> #include <asm/reg.h> @@ -26,7 +26,7 @@ #endif -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #if defined(CONFIG_SGI_IO) /* FIXME */ #define PS_UINT_CAST (__psunsigned_t) @@ -38,13 +38,13 @@ #define HUBREG_CAST (volatile hubreg_t *) -#elif _LANGUAGE_ASSEMBLY +#else /* __ASSEMBLY__ */ #define PS_UINT_CAST #define UINT64_CAST #define HUBREG_CAST -#endif +#endif /* __ASSEMBLY__ */ #define NASID_GET_META(_n) ((_n) >> NASID_LOCAL_BITS) @@ -278,7 +278,7 @@ 0x800000 + (_x))) #endif /* CONFIG_SGI_IP27 */ -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #define HUB_L(_a) *(_a) #define HUB_S(_a, _d) *(_a) = (_d) @@ -290,7 +290,7 @@ #define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r))) #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d)) -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * The following macros are used to get to a hub/bridge register, given @@ -367,7 +367,7 @@ #define KLI_KERN_XP 8 #define KLI_KERN_PARTID 9 -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #define KLD_BASE(nasid) ((kldir_ent_t *) KLDIR_ADDR(nasid)) #define KLD_LAUNCH(nasid) (KLD_BASE(nasid) + KLI_LAUNCH) @@ -453,7 +453,7 @@ #define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET) -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_SN_ADDRS_H */ diff -Nru a/include/asm-mips64/sn/arch.h b/include/asm-mips64/sn/arch.h --- a/include/asm-mips64/sn/arch.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/sn/arch.h Fri Jun 27 14:19:54 2003 @@ -20,7 +20,7 @@ #endif -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +#ifndef __ASSEMBLY__ #if !defined(CONFIG_SGI_IO) typedef u64 hubreg_t; typedef u64 nic_t; @@ -44,7 +44,7 @@ #define makespnum(_nasid, _slice) \ (((_nasid) << CPUS_PER_NODE_SHFT) | (_slice)) -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +#ifndef __ASSEMBLY__ #define INVALID_NASID (nasid_t)-1 #define INVALID_CNODEID (cnodeid_t)-1 @@ -102,7 +102,7 @@ extern int node_getlastslot(cnodeid_t); -#endif /* _LANGUAGE_C || _LANGUAGE_C_PLUS_PLUS */ +#endif /* !__ASSEMBLY__ */ #define SLOT_BITMASK (MAX_MEM_SLOTS - 1) #define SLOT_SIZE (1LL<<SLOT_SHIFT) diff -Nru a/include/asm-mips64/sn/gda.h b/include/asm-mips64/sn/gda.h --- a/include/asm-mips64/sn/gda.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/sn/gda.h Fri Jun 27 14:19:55 2003 @@ -9,7 +9,7 @@ * * gda.h -- Contains the data structure for the global data area, * The GDA contains information communicated between the - * PROM, SYMMON, and the kernel. + * PROM, SYMMON, and the kernel. */ #ifndef _ASM_SN_GDA_H #define _ASM_SN_GDA_H @@ -23,9 +23,9 @@ * * Version # | Change * -------------+------------------------------------------------------- - * 1 | Initial SN0 version + * 1 | Initial SN0 version * 2 | Prom sets g_partid field to the partition number. 0 IS - * | a valid partition #. + * | a valid partition #. */ #define GDA_VERSION 2 /* Current GDA version # */ @@ -41,7 +41,7 @@ #define G_PARTIDOFF 40 #define G_TABLEOFF 128 -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef struct gda { u32 g_magic; /* GDA magic number */ @@ -67,10 +67,10 @@ #define GDA ((gda_t*) GDA_ADDR(get_nasid())) -#endif /* __LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * Define: PART_GDA_VERSION - * Purpose: Define the minimum version of the GDA required, lower + * Purpose: Define the minimum version of the GDA required, lower * revisions assume GDA is NOT set up, and read partition * information from the board info. */ diff -Nru a/include/asm-mips64/sn/intr.h b/include/asm-mips64/sn/intr.h --- a/include/asm-mips64/sn/intr.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips64/sn/intr.h Fri Jun 27 14:19:30 2003 @@ -19,7 +19,7 @@ #include <asm/sn/intr_public.h> -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ /* * Macros to manipulate the interrupt register on the calling hub chip. @@ -31,7 +31,7 @@ REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (0x100|(_level))) /* - * When clearing the interrupt, make sure this clear does make it + * When clearing the interrupt, make sure this clear does make it * to the hub. Otherwise we could end up losing interrupts. * We do an uncached load of the int_pend0 register to ensure this. */ @@ -43,9 +43,9 @@ REMOTE_HUB_S((_hub), PI_INT_PEND_MOD, (_level)), \ REMOTE_HUB_L((_hub), PI_INT_PEND0) -#else /* LANGUAGE_ASSEMBLY */ +#else /* __ASSEMBLY__ */ -#endif /* LANGUAGE_C */ +#endif /* __ASSEMBLY__ */ /* * Hard-coded interrupt levels: diff -Nru a/include/asm-mips64/sn/intr_public.h b/include/asm-mips64/sn/intr_public.h --- a/include/asm-mips64/sn/intr_public.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/sn/intr_public.h Fri Jun 27 14:19:55 2003 @@ -1,4 +1,4 @@ -/* +/* * 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. @@ -20,7 +20,7 @@ #define INTPEND0_MAXMASK (N_INTPEND0_MASKS - 1) #define INTPEND1_MAXMASK (N_INTPEND1_MASKS - 1) -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #include <asm/sn/arch.h> struct intr_vecblk_s; /* defined in asm/sn/intr.h */ @@ -40,14 +40,14 @@ * in the lowest-numbered masks (i.e., 0, 1, 2...). */ /* INT_PEND0: */ - hubreg_t intpend0_masks[N_INTPEND0_MASKS]; + hubreg_t intpend0_masks[N_INTPEND0_MASKS]; /* INT_PEND1: */ hubreg_t intpend1_masks[N_INTPEND1_MASKS]; /* INT_PEND0: */ - struct intr_vecblk_s *dispatch0; + struct intr_vecblk_s *dispatch0; /* INT_PEND1: */ struct intr_vecblk_s *dispatch1; } hub_intmasks_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_SN_INTR_PUBLIC_H */ diff -Nru a/include/asm-mips64/sn/io.h b/include/asm-mips64/sn/io.h --- a/include/asm-mips64/sn/io.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/sn/io.h Fri Jun 27 14:19:55 2003 @@ -11,19 +11,9 @@ #include <linux/config.h> -#if !defined(CONFIG_SGI_IO) -#include <asm/sn/sn0/addrs.h> - -#define IO_SPACE_BASE IO_BASE - -/* Because we only have PCI I/O ports. */ -#define IO_SPACE_LIMIT 0xffffffff - -/* No isa_* versions, the Origin doesn't have ISA / EISA bridges. */ +#ifdef CONFIG_SGI_IO -#else /* CONFIG_SGI_IO */ - -#define IIO_ITTE_BASE 0x400160 /* base of translation table entries */ +#define IIO_ITTE_BASE 0x400160 /* base of translation table entries */ #define IIO_ITTE(bigwin) (IIO_ITTE_BASE + 8*(bigwin)) #define IIO_ITTE_OFFSET_BITS 5 /* size of offset field */ @@ -56,9 +46,9 @@ #define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin)) /* - * Macro which takes the widget number, and returns the + * Macro which takes the widget number, and returns the * IO PRB address of that widget. - * value _x is expected to be a widget number in the range + * value _x is expected to be a widget number in the range * 0, 8 - 0xF */ #define IIO_IOPRB(_x) (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \ @@ -68,6 +58,17 @@ #if defined (CONFIG_SGI_IP27) #include <asm/sn/sn0/hubio.h> #endif + +#else /* CONFIG_SGI_IO */ + +#include <asm/sn/sn0/addrs.h> + +#define IO_SPACE_BASE IO_BASE + +/* Because we only have PCI I/O ports. */ +#define IO_SPACE_LIMIT 0xffffffff + +/* No isa_* versions, the Origin doesn't have ISA / EISA bridges. */ #endif /* CONFIG_SGI_IO */ diff -Nru a/include/asm-mips64/sn/klconfig.h b/include/asm-mips64/sn/klconfig.h --- a/include/asm-mips64/sn/klconfig.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/sn/klconfig.h Fri Jun 27 14:19:57 2003 @@ -19,9 +19,9 @@ /* * WARNING: - * Certain assembly language routines (notably xxxxx.s) in the IP27PROM - * will depend on the format of the data structures in this file. In - * most cases, rearranging the fields can seriously break things. + * Certain assembly language routines (notably xxxxx.s) in the IP27PROM + * will depend on the format of the data structures in this file. In + * most cases, rearranging the fields can seriously break things. * Adding fields in the beginning or middle can also break things. * Add fields if necessary, to the end of a struct in such a way * that offsets of existing fields do not change. @@ -76,11 +76,11 @@ #define MAX_MODULE_ID 255 #define SIZE_PAD 4096 /* 4k padding for structures */ -/* - * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, - * 2 Midplanes assuming no pci card cages +/* + * 1 NODE brd, 2 Router brd (1 8p, 1 meta), 6 Widgets, + * 2 Midplanes assuming no pci card cages */ -#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2) +#define MAX_SLOTS_PER_NODE (1 + 2 + 6 + 2) /* XXX if each node is guranteed to have some memory */ @@ -117,7 +117,7 @@ /* Structures to manage various data storage areas */ /* The numbers must be contiguous since the array index i - is used in the code to allocate various areas. + is used in the code to allocate various areas. */ #define BOARD_STRUCT 0 @@ -240,7 +240,7 @@ /* * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD - * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to + * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to * the LOCAL/current NODE. REMOTE means it is attached to a different * node.(TBD - Need a way to treat ROUTER boards.) * @@ -250,20 +250,20 @@ * Figure below). The first byte of the rboard or lboard structure * is used to find out its type - no unions are used. * If it is a lboard, then the config info of this board will be found - * on the local node. (LOCAL NODE BASE + offset value gives pointer to + * on the local node. (LOCAL NODE BASE + offset value gives pointer to * the structure. * If it is a rboard, the local structure contains the node number * and the offset of the beginning of the LINKED LIST on the remote node. * The details of the hardware on a remote node can be built locally, - * if required, by reading the LINKED LIST on the remote node and + * if required, by reading the LINKED LIST on the remote node and * ignoring all the rboards on that node. * - * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the - * First board info on the remote node. The remote node list is + * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the + * First board info on the remote node. The remote node list is * traversed as the local list, using the REMOTE BASE ADDRESS and not * the local base address and ignoring all rboard values. * - * + * KLCONFIG +------------+ +------------+ +------------+ +------------+ @@ -290,7 +290,7 @@ +--------------------------------+ * - * Each BOARD consists of COMPONENTs and the BOARD structure has + * Each BOARD consists of COMPONENTs and the BOARD structure has * pointers (offsets) to its COMPONENT structure. * The COMPONENT structure has version info, size and speed info, revision, * error info and the NIC info. This structure can accommodate any @@ -298,19 +298,19 @@ * * The ERRORINFO part of each BOARD has error information * that describes errors about the BOARD itself. It also has flags to - * indicate the COMPONENT(s) on the board that have errors. The error - * information specific to the COMPONENT is present in the respective + * indicate the COMPONENT(s) on the board that have errors. The error + * information specific to the COMPONENT is present in the respective * COMPONENT structure. * - * The ERRORINFO structure is also treated like a COMPONENT, ie. the + * The ERRORINFO structure is also treated like a COMPONENT, ie. the * BOARD has pointers(offset) to the ERRORINFO structure. The rboard - * structure also has a pointer to the ERRORINFO structure. This is + * structure also has a pointer to the ERRORINFO structure. This is * the place to store ERRORINFO about a REMOTE NODE, if the HUB on - * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where + * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can - * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info + * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info * which is present on the REMOTE NODE.(TBD) - * REMOTE ERRINFO can be stored on any of the nearest nodes + * REMOTE ERRINFO can be stored on any of the nearest nodes * or on all the nearest nodes.(TBD) * Like BOARD structures, REMOTE ERRINFO structures can be built locally * using the rboard errinfo pointer. @@ -319,9 +319,9 @@ * interface routines are provided (TBD). The important thing to remember while * manipulating the structures, is that, the NODE number information should * be used. If the NODE is non-zero (remote) then each offset should - * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. + * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. * This includes offsets for BOARDS, COMPONENTS and ERRORINFO. - * + * * Note that these structures do not provide much info about connectivity. * That info will be part of HWGRAPH, which is an extension of the cfg_t * data structure. (ref IP27prom/cfg.h) It has to be extended to include @@ -342,11 +342,11 @@ * IP27 BOARD classes */ -#define KLCLASS_MASK 0xf0 +#define KLCLASS_MASK 0xf0 #define KLCLASS_NONE 0x00 #define KLCLASS_NODE 0x10 /* CPU, Memory and HUB board */ -#define KLCLASS_CPU KLCLASS_NODE -#define KLCLASS_IO 0x20 /* BaseIO, 4 ch SCSI, ethernet, FDDI +#define KLCLASS_CPU KLCLASS_NODE +#define KLCLASS_IO 0x20 /* BaseIO, 4 ch SCSI, ethernet, FDDI and the non-graphics widget boards */ #define KLCLASS_ROUTER 0x30 /* Router board */ #define KLCLASS_MIDPLANE 0x40 /* We need to treat this as a board @@ -420,7 +420,7 @@ * out the board name from the NIC string. For values less than * 8 the name of the board needs to be hard coded in a few places. * When bringup started nic names had not standardized and so we - * had to hard code. (For people interested in history.) + * had to hard code. (For people interested in history.) */ #define KLTYPE_XTHD (KLCLASS_PSEUDO_GFX | 0x9) @@ -431,7 +431,7 @@ (l->brd_flags & SECOND_NIC_PRESENT)) #define IS_MIO_IOC3(l,n) (IS_MIO_PRESENT(l) && (n > 2)) -/* +/* * board structures */ @@ -511,10 +511,10 @@ /* - * Generic info structure. This stores common info about a + * Generic info structure. This stores common info about a * component. */ - + typedef struct klinfo_s { /* Generic info */ unsigned char struct_type; /* type of this structure */ unsigned char struct_version; /* version of this structure */ @@ -540,9 +540,9 @@ /* * Component structures. * Following are the currently identified components: - * CPU, HUB, MEM_BANK, + * CPU, HUB, MEM_BANK, * XBOW(consists of 16 WIDGETs, each of which can be HUB or GRAPHICS or BRIDGE) - * BRIDGE, IOC3, SuperIO, SCSI, FDDI + * BRIDGE, IOC3, SuperIO, SCSI, FDDI * ROUTER * GRAPHICS */ @@ -614,9 +614,9 @@ typedef u64 *router_t; /* - * The port info in ip27_cfg area translates to a lboart_t in the + * The port info in ip27_cfg area translates to a lboart_t in the * KLCONFIG area. But since KLCONFIG does not use pointers, lboart_t - * is stored in terms of a nasid and a offset from start of KLCONFIG + * is stored in terms of a nasid and a offset from start of KLCONFIG * area on that nasid. */ typedef struct klport_s { @@ -692,7 +692,7 @@ } klmod_serial_num_t; /* Macros needed to access serial number structure in lboard_t. - Hard coded values are necessary since we cannot treat + Hard coded values are necessary since we cannot treat serial number struct as a component without losing compatibility between prom versions. */ @@ -789,7 +789,7 @@ klconf_off_t gfx_mfg_nic; } klgfx_t; -typedef struct klxthd_s { +typedef struct klxthd_s { klinfo_t xthd_info ; klconf_off_t xthd_mfg_nic ; /* MFG NIC string */ } klxthd_t ; @@ -815,9 +815,9 @@ typedef struct klscsi_s { /* SCSI Controller */ klinfo_t scsi_info ; - scsi_t scsi_specific ; + scsi_t scsi_specific ; unsigned char scsi_numdevs ; - klconf_off_t scsi_devinfo[MAX_SCSI_DEVS] ; + klconf_off_t scsi_devinfo[MAX_SCSI_DEVS] ; } klscsi_t ; typedef struct klscdev_s { /* SCSI device */ @@ -842,20 +842,20 @@ typedef struct klmsdev_s { /* mouse device */ klinfo_t msdev_info ; - void *msdev_cfg ; + void *msdev_cfg ; } klmsdev_t ; #define MAX_FDDI_DEVS 10 /* XXX Is this true */ typedef struct klfddi_s { /* FDDI */ klinfo_t fddi_info ; - fddi_t fddi_specific ; + fddi_t fddi_specific ; klconf_off_t fddi_devinfo[MAX_FDDI_DEVS] ; } klfddi_t ; typedef struct klmio_s { /* MIO */ klinfo_t mio_info ; - mio_t mio_specific ; + mio_t mio_specific ; } klmio_t ; @@ -890,17 +890,17 @@ /* * TBD - Can the ARCS and device driver related info also be included in the - * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t + * KLCONFIG area. On the IO4PROM, prom device driver info is part of cfgnode_t * structure, viz private to the IO4prom. */ -/* - * TBD - Allocation issues. +/* + * TBD - Allocation issues. * - * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component, - * errinfo and allocate from them, or have a single heap and allocate all + * Do we need to Mark off sepatate heaps for lboard_t, rboard_t, component, + * errinfo and allocate from them, or have a single heap and allocate all * structures from it. Debug is easier in the former method since we can - * dump all similar structs in one command, but there will be lots of holes, + * dump all similar structs in one command, but there will be lots of holes, * in memory and max limits are needed for number of structures. * Another way to make it organized, is to have a union of all components * and allocate a aligned chunk of memory greater than the biggest diff -Nru a/include/asm-mips64/sn/kldir.h b/include/asm-mips64/sn/kldir.h --- a/include/asm-mips64/sn/kldir.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/sn/kldir.h Fri Jun 27 14:19:55 2003 @@ -127,14 +127,14 @@ * 0x0 (0K) +-----------------------------------------+ */ -#ifdef LANGUAGE_ASSEMBLY +#ifdef __ASSEMBLY__ #define KLDIR_OFF_MAGIC 0x00 #define KLDIR_OFF_OFFSET 0x08 #define KLDIR_OFF_POINTER 0x10 #define KLDIR_OFF_SIZE 0x18 #define KLDIR_OFF_COUNT 0x20 #define KLDIR_OFF_STRIDE 0x28 -#endif /* LANGUAGE_ASSEMBLY */ +#endif /* __ASSEMBLY__ */ #if !defined(CONFIG_SGI_IO) @@ -199,7 +199,7 @@ #define IP27_NMI_KREGS_OFFSET 0x11400 #define IP27_NMI_KREGS_CPU_SIZE 0x200 /* - * save area of kernel nmi regs in eframe format + * save area of kernel nmi regs in eframe format */ #define IP27_NMI_EFRAME_OFFSET 0x11800 #define IP27_NMI_EFRAME_SIZE 0x200 @@ -209,7 +209,7 @@ #endif /* !CONFIG_SGI_IO */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef struct kldir_ent_s { u64 magic; /* Indicates validity of entry */ off_t offset; /* Offset from start of node space */ @@ -225,7 +225,7 @@ /* NOTE: These 16 bytes are used in the Partition KLDIR entry to store partition info. Refer to klpart.h for this. */ } kldir_ent_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #if defined(CONFIG_SGI_IO) diff -Nru a/include/asm-mips64/sn/klkernvars.h b/include/asm-mips64/sn/klkernvars.h --- a/include/asm-mips64/sn/klkernvars.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/sn/klkernvars.h Fri Jun 27 14:19:56 2003 @@ -11,7 +11,7 @@ #define KV_MAGIC 0x5f4b565f -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #include <asm/sn/types.h> @@ -23,7 +23,7 @@ unsigned long kv_rw_baseaddr; } kern_vars_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* __ASM_SN_KLKERNVARS_H */ diff -Nru a/include/asm-mips64/sn/launch.h b/include/asm-mips64/sn/launch.h --- a/include/asm-mips64/sn/launch.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips64/sn/launch.h Fri Jun 27 14:20:04 2003 @@ -60,7 +60,7 @@ * clears the BUSY flag after control is returned to it. */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef int launch_state_t; typedef void (*launch_proc_t)(u64 call_parm); @@ -102,21 +102,6 @@ #define LAUNCH_FLASH (*(void (*)(void)) \ IP27PROM_FLASHLEDS) -#ifdef _STANDALONE - -launch_t *launch_get(int nasid, int cpu); -launch_t *launch_get_current(void); -void launch_loop(void); -void launch_slave(int nasid, int cpu, - launch_proc_t call_addr, - __int64_t call_parm, - void *stack_addr, - void *gp_addr); -int launch_wait(int nasid, int cpu, int timeout_msec); -launch_state_t launch_poll(int nasid, int cpu); - -#endif /* _STANDALONE */ - -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_SN_LAUNCH_H */ diff -Nru a/include/asm-mips64/sn/mapped_kernel.h b/include/asm-mips64/sn/mapped_kernel.h --- a/include/asm-mips64/sn/mapped_kernel.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/sn/mapped_kernel.h Fri Jun 27 14:19:56 2003 @@ -6,18 +6,18 @@ #define __ASM_SN_MAPPED_KERNEL_H /* - * Note on how mapped kernels work: the text and data section is - * compiled at cksseg segment (LOADADDR = 0xc001c000), and the - * init/setup/data section gets a 16M virtual address bump in the - * ld.script file (so that tlblo0 and tlblo1 maps the sections). - * The vmlinux.64 section addresses are put in the xkseg range - * using the change-addresses makefile option. Use elfdump -of - * on IRIX to see where the sections go. The Origin loader loads - * the two sections contiguously in physical memory. The loader - * sets the entry point into kernel_entry using a xkphys address, - * but instead of using 0xa800000001160000, it uses the address - * 0xa800000000160000, which is where it physically loaded that - * code. So no jumps can be done before we have switched to using + * Note on how mapped kernels work: the text and data section is + * compiled at cksseg segment (LOADADDR = 0xc001c000), and the + * init/setup/data section gets a 16M virtual address bump in the + * ld.script file (so that tlblo0 and tlblo1 maps the sections). + * The vmlinux.64 section addresses are put in the xkseg range + * using the change-addresses makefile option. Use elfdump -of + * on IRIX to see where the sections go. The Origin loader loads + * the two sections contiguously in physical memory. The loader + * sets the entry point into kernel_entry using a xkphys address, + * but instead of using 0xa800000001160000, it uses the address + * 0xa800000000160000, which is where it physically loaded that + * code. So no jumps can be done before we have switched to using * cksseg addresses. */ #include <linux/config.h> diff -Nru a/include/asm-mips64/sn/nmi.h b/include/asm-mips64/sn/nmi.h --- a/include/asm-mips64/sn/nmi.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-mips64/sn/nmi.h Fri Jun 27 14:19:57 2003 @@ -1,4 +1,4 @@ -/* +/* * 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. @@ -8,7 +8,7 @@ #ifndef __ASM_SN_NMI_H #define __ASM_SN_NMI_H -#ident "$Revision: 1.2 $" +#ident "$Revision: 1.5 $" #include <asm/sn/addrs.h> @@ -48,7 +48,7 @@ * */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef struct nmi_s { volatile unsigned long magic; /* Magic number */ @@ -59,13 +59,13 @@ volatile unsigned long gmaster; /* Flag true only on global master*/ } nmi_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* Following definitions are needed both in the prom & the kernel * to identify the format of the nmi cpu register save area in the * low memory on each node. */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ struct reg_struct { unsigned long gpr[32]; @@ -78,7 +78,7 @@ unsigned long nmi_sr; }; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* These are the assembly language offsets into the reg_struct structure */ diff -Nru a/include/asm-mips64/sn/sn0/addrs.h b/include/asm-mips64/sn/sn0/addrs.h --- a/include/asm-mips64/sn/sn0/addrs.h Fri Jun 27 14:19:52 2003 +++ b/include/asm-mips64/sn/sn0/addrs.h Fri Jun 27 14:19:52 2003 @@ -99,14 +99,15 @@ #define NASID_GET(_pa) (int) ((UINT64_CAST (_pa) >> \ NASID_SHFT) & NASID_BITMASK) -#if _LANGUAGE_C && !defined(_STANDALONE) +#if !defined(__ASSEMBLY__) && !defined(_STANDALONE) + #define NODE_SWIN_BASE(nasid, widget) \ ((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN) \ : RAW_NODE_SWIN_BASE(nasid, widget)) -#else +#else /* __ASSEMBLY__ || _STANDALONE */ #define NODE_SWIN_BASE(nasid, widget) \ (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS)) -#endif /* _LANGUAGE_C */ +#endif /* __ASSEMBLY__ || _STANDALONE */ /* * The following definitions pertain to the IO special address @@ -163,11 +164,11 @@ #define SABLE_LOG_TRIGGER(_map) #endif /* SABLE */ -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #define KERN_NMI_ADDR(nasid, slice) \ TO_NODE_UNCAC((nasid), IP27_NMI_KREGS_OFFSET + \ (IP27_NMI_KREGS_CPU_SIZE * (slice))) -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #ifdef PROM @@ -272,7 +273,8 @@ #define KL_UART_DATA LOCAL_HUB_ADDR(MD_UREG0_1) /* UART data reg */ #define KL_I2C_REG MD_UREG0_0 /* I2C reg */ -#if !_LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ + /* Address 0x400 to 0x1000 ualias points to cache error eframe + misc * CACHE_ERR_SP_PTR could either contain an address to the stack, or * the stack could start at CACHE_ERR_SP_PTR @@ -289,7 +291,7 @@ #define CACHE_ERR_SP (CACHE_ERR_SP_PTR - 16) #define CACHE_ERR_AREA_SIZE (ARCS_SPB_OFFSET - CACHE_ERR_EFRAME) -#endif /* !_LANGUAGE_ASSEMBLY */ +#endif /* !__ASSEMBLY__ */ #define _ARCSPROM @@ -314,7 +316,7 @@ * is in place. */ -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ #define uchar unsigned char @@ -359,7 +361,7 @@ #define PUT_INSTALL_STATUS(c,s) c->Revision = s #define GET_INSTALL_STATUS(c) c->Revision -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* _STANDALONE */ diff -Nru a/include/asm-mips64/sn/sn0/arch.h b/include/asm-mips64/sn/sn0/arch.h --- a/include/asm-mips64/sn/sn0/arch.h Fri Jun 27 14:19:56 2003 +++ b/include/asm-mips64/sn/sn0/arch.h Fri Jun 27 14:19:56 2003 @@ -49,7 +49,7 @@ #define MAX_PREMIUM_REGIONS MAX_REGIONS /* - * MAX_PARITIONS refers to the maximum number of logically defined + * MAX_PARITIONS refers to the maximum number of logically defined * partitions the system can support. */ #define MAX_PARTITIONS MAX_REGIONS diff -Nru a/include/asm-mips64/sn/sn0/hubio.h b/include/asm-mips64/sn/sn0/hubio.h --- a/include/asm-mips64/sn/sn0/hubio.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/sn/sn0/hubio.h Fri Jun 27 14:19:53 2003 @@ -18,7 +18,7 @@ * In general, the longer software name should be used when available. */ -/* +/* * Slightly friendlier names for some common registers. * The hardware definitions follow. */ @@ -26,7 +26,7 @@ #define IIO_WIDGET_STAT IIO_WSTAT /* Widget status register */ #define IIO_WIDGET_CTRL IIO_WCR /* Widget control register */ #define IIO_WIDGET_TOUT IIO_WRTO /* Widget request timeout */ -#define IIO_WIDGET_FLUSH IIO_WTFR /* Widget target flush */ +#define IIO_WIDGET_FLUSH IIO_WTFR /* Widget target flush */ #define IIO_PROTECT IIO_ILAPR /* IO interface protection */ #define IIO_PROTECT_OVRRD IIO_ILAPO /* IO protect override */ #define IIO_OUTWIDGET_ACCESS IIO_IOWA /* Outbound widget access */ @@ -67,7 +67,7 @@ /* * The following definitions use the names defined in the IO interface - * document for ease of reference. When possible, software should + * document for ease of reference. When possible, software should * generally use the longer but clearer names defined above. */ @@ -169,7 +169,7 @@ /* * The IO LLP control status register and widget control register */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union hubii_wid_u { u64 wid_reg_value; @@ -198,7 +198,7 @@ } hubii_wcr_t; #define iwcr_dir_con wcr_fields_s.wcr_dir_con - + typedef union hubii_wstat_u { u64 reg_value; struct { @@ -215,13 +215,13 @@ } wstat_fields_s; } hubii_wstat_t; - + typedef union hubii_ilcsr_u { u64 icsr_reg_value; struct { u64 icsr_rsvd: 22, /* unused */ icsr_max_burst: 10, /* max burst */ - icsr_rsvd4: 6, /* reserved */ + icsr_rsvd4: 6, /* reserved */ icsr_max_retry: 10, /* max retry */ icsr_rsvd3: 2, /* reserved */ icsr_lnk_stat: 2, /* link status */ @@ -285,23 +285,23 @@ typedef union io_perf_cnt { u64 perf_cnt; - struct { + struct { u64 perf_rsvd1 : 32, perf_rsvd2 : 12, perf_cnt : 20; } perf_cnt_bits; } io_perf_cnt_t; -#endif +#endif /* !__ASSEMBLY__ */ #define LNK_STAT_WORKING 0x2 #define IIO_LLP_CB_MAX 0xffff #define IIO_LLP_SN_MAX 0xffff - + /* IO PRB Entries */ -#define IIO_NUM_IPRBS (9) +#define IIO_NUM_IPRBS (9) #define IIO_IOPRB_0 0x400198 /* PRB entry 0 */ #define IIO_IOPRB_8 0x4001a0 /* PRB entry 8 */ #define IIO_IOPRB_9 0x4001a8 /* PRB entry 9 */ @@ -320,7 +320,7 @@ #define IIO_IECLR 0x4001f8 /* IO error clear */ #define IIO_IBCN 0x400200 /* IO BTE CRB count */ -/* +/* * IIO_IMEM Register fields. */ #define IIO_IMEM_W0ESD 0x1 /* Widget 0 shut down due to error */ @@ -366,7 +366,7 @@ #define IIO_ICMR_CLR_RPPD (1UL << 13) #define IIO_ICMR_CLR_RQPD (1UL << 12) -/* +/* * IIO PIO Deallocation register field masks : (IIO_IPDR) */ #define IIO_IPDR_PND (1 << 4) @@ -377,7 +377,7 @@ #define IIO_ICDR_PND (1 << 4) /* - * IIO CRB control register Fields: IIO_ICCR + * IIO CRB control register Fields: IIO_ICCR */ #define IIO_ICCR_PENDING (0x10000) #define IIO_ICCR_CMD_MASK (0xFF) @@ -385,7 +385,7 @@ #define IIO_ICCR_CMD_NOP (0x0) /* No Op */ #define IIO_ICCR_CMD_WAKE (0x100) /* Reactivate CRB entry and process */ #define IIO_ICCR_CMD_TIMEOUT (0x200) /* Make CRB timeout & mark invalid */ -#define IIO_ICCR_CMD_EJECT (0x400) /* Contents of entry written to memory +#define IIO_ICCR_CMD_EJECT (0x400) /* Contents of entry written to memory * via a WB */ #define IIO_ICCR_CMD_FLUSH (0x800) @@ -423,15 +423,15 @@ * * Many of the fields in CRB are status bits used by hardware * for implementation of the protocol. It's very dangerous to - * mess around with the CRB registers. - * + * mess around with the CRB registers. + * * It's OK to read the CRB registers and try to make sense out of the - * fields in CRB. + * fields in CRB. * - * Updating CRB requires all activities in Hub IIO to be quiesced. + * Updating CRB requires all activities in Hub IIO to be quiesced. * otherwise, a write to CRB could corrupt other CRB entries. * CRBs are here only as a back door peek to hub IIO's status. - * Quiescing implies no dmas no PIOs + * Quiescing implies no dmas no PIOs * either directly from the cpu or from sn0net. * this is not something that can be done easily. So, AVOID updating * CRBs. @@ -440,7 +440,7 @@ /* * Fields in CRB Register A */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union icrba_u { u64 reg_value; struct { @@ -465,7 +465,7 @@ NI_STATUS_REV_ID register. */ typedef union h1_icrba_u { u64 reg_value; - + struct { u64 resvd: 6, unused: 1, /* Unused but RW!! */ @@ -500,16 +500,16 @@ #define a_valid icrba_fields_s.valid #define a_iow icrba_fields_s.iow -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #define IIO_ICRB_ADDR_SHFT 2 /* Shift to get proper address */ /* - * values for "ecode" field + * values for "ecode" field */ #define IIO_ICRB_ECODE_DERR 0 /* Directory error due to IIO access */ #define IIO_ICRB_ECODE_PERR 1 /* Poison error on IO access */ -#define IIO_ICRB_ECODE_WERR 2 /* Write error by IIO access +#define IIO_ICRB_ECODE_WERR 2 /* Write error by IIO access * e.g. WINV to a Read only line. */ #define IIO_ICRB_ECODE_AERR 3 /* Access error caused by IIO access */ @@ -523,7 +523,7 @@ /* * Fields in CRB Register B */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union icrbb_u { u64 reg_value; struct { @@ -537,15 +537,15 @@ * 3: Reserved. */ srcnode: 9, /* Source Node ID */ - srcinit: 2, /* Source Initiator: + srcinit: 2, /* Source Initiator: * See below for field values. */ useold: 1, /* Use OLD command for processing */ imsgtype: 2, /* Incoming message type - * see below for field values + * see below for field values */ imsg: 8, /* Incoming message */ - initator: 3, /* Initiator of original request + initator: 3, /* Initiator of original request * See below for field values. */ reqtype: 5, /* Identifies type of request @@ -579,18 +579,18 @@ * 3: Reserved. */ srcnode: 9, /* Source Node ID */ - srcinit: 2, /* Source Initiator: + srcinit: 2, /* Source Initiator: * See below for field values. */ useold: 1, /* Use OLD command for processing */ imsgtype: 2, /* Incoming message type - * see below for field values + * see below for field values */ imsg: 8, /* Incoming message */ - initator: 3, /* Initiator of original request + initator: 3, /* Initiator of original request * See below for field values. */ - rsvd2: 1, + rsvd2: 1, pcache: 1, /* entry belongs to partial cache */ reqtype: 5, /* Identifies type of request * See below for field values. @@ -622,7 +622,7 @@ #define b_imsg icrbb_field_s.imsg #define b_initiator icrbb_field_s.initiator -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * values for field xtsize @@ -676,11 +676,11 @@ #define IIO_ICRB_REQ_WB 16 /* Request is Write back */ #define IIO_ICRB_REQ_DEX 17 /* Retained DEX Cache line */ -/* - * Fields in CRB Register C +/* + * Fields in CRB Register C */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union icrbc_s { u64 reg_value; @@ -690,7 +690,7 @@ pricnt: 4, /* Priority count sent with Read req */ pripsc: 4, /* Priority Pre scalar */ bteop: 1, /* BTE Operation */ - push_be: 34, /* Push address Byte enable + push_be: 34, /* Push address Byte enable * Holds push addr, if CRB is for BTE * If CRB belongs to Partial cache, * this contains byte enables bits @@ -712,20 +712,20 @@ #define c_barrop icrbc_field_s.barrop #define c_doresp icrbc_field_s.doresp #define c_gbr icrbc_field_s.gbr -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * Fields in CRB Register D */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union icrbd_s { u64 reg_value; struct { u64 rsvd: 38, toutvld: 1, /* Timeout in progress for this CRB */ ctxtvld: 1, /* Context field below is valid */ - rsvd2: 1, + rsvd2: 1, context: 15, /* Bit vector: * Has a bit set for each CRB entry * which needs to be deallocated @@ -751,7 +751,7 @@ } hi_ifdr_fields; } hubii_ifdr_t; -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * Hardware designed names for the BTE control registers. @@ -762,7 +762,7 @@ #define IIO_IBCT_0 0x410018 /* BTE control/terminate 0 */ #define IIO_IBNA_0 0x410020 /* BTE notification address 0 */ #define IIO_IBNR_0 IIO_IBNA_0 -#define IIO_IBIA_0 0x410028 /* BTE interrupt address 0 */ +#define IIO_IBIA_0 0x410028 /* BTE interrupt address 0 */ #define IIO_IBLS_1 0x420000 /* BTE length/status 1 */ #define IIO_IBSA_1 0x420008 /* BTE source address 1 */ @@ -770,7 +770,7 @@ #define IIO_IBCT_1 0x420018 /* BTE control/terminate 1 */ #define IIO_IBNA_1 0x420020 /* BTE notification address 1 */ #define IIO_IBNR_1 IIO_IBNA_1 -#define IIO_IBIA_1 0x420028 /* BTE interrupt address 1 */ +#define IIO_IBIA_1 0x420028 /* BTE interrupt address 1 */ /* * More miscellaneous registers @@ -795,10 +795,10 @@ #define IECLR_PRB_0 (1 << 0) /* clear err bit in PRB_0 reg */ /* - * IO PIO Read Table Entry format + * IO PIO Read Table Entry format */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union iprte_a { u64 entry; @@ -820,7 +820,7 @@ #define iprte_init iprte_fields.initiator #define iprte_addr iprte_fields.addr -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #define IPRTE_ADDRSHFT 3 @@ -828,9 +828,9 @@ * Hub IIO PRB Register format. */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ /* - * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are + * Note: Fields bnakctr, anakctr, xtalkctrmode, ovflow fields are * "Status" fields, and should only be used in case of clean up after errors. */ @@ -860,7 +860,7 @@ #define iprb_anakctr iprb_fields_s.anakctr #define iprb_xtalkctr iprb_fields_s.xtalkctr -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * values for mode field in iprb_t. @@ -875,7 +875,7 @@ /* * IO CRB entry C_A to E_A : Partial (cache) CRBS */ -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union icrbp_a { u64 ip_reg; /* the entire register value */ struct { @@ -909,7 +909,7 @@ } ip_fmt; } icrbp_a_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* * A couple of defines to go with the above structure. @@ -917,7 +917,7 @@ #define ICRBP_A_CERR_SHFT 54 #define ICRBP_A_ERR_MASK 0x3ff -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union hubii_idsr { u64 iin_reg; struct { @@ -931,9 +931,9 @@ level : 7; } iin_fmt; } hubii_idsr_t; -#endif /* LANGUAGE_C */ - -/* +#endif /* !__ASSEMBLY__ */ + +/* * IO BTE Length/Status (IIO_IBLS) register bit field definitions */ #define IBLS_BUSY (0x1 << 20) @@ -965,18 +965,18 @@ #define HUB_WIDGET_ID_MIN 0x8 #define HUB_WIDGET_ID_MAX 0xf -#define HUB_WIDGET_PART_NUM 0xc101 +#define HUB_WIDGET_PART_NUM 0xc101 #define MAX_HUBS_PER_XBOW 2 -/* - * Get a hub's widget id from widget control register +/* + * Get a hub's widget id from widget control register */ -#define IIO_WCR_WID_GET(nasid) (REMOTE_HUB_L(nasid, III_WCR) & 0xf) +#define IIO_WCR_WID_GET(nasid) (REMOTE_HUB_L(nasid, III_WCR) & 0xf) #define IIO_WST_ERROR_MASK (UINT64_CAST 1 << 32) /* Widget status error */ /* * Number of credits Hub widget has while sending req/response to - * xbow. + * xbow. * Value of 3 is required by Xbow 1.1 * We may be able to increase this to 4 with Xbow 1.2. */ diff -Nru a/include/asm-mips64/sn/sn0/hubmd.h b/include/asm-mips64/sn/sn0/hubmd.h --- a/include/asm-mips64/sn/sn0/hubmd.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips64/sn/sn0/hubmd.h Fri Jun 27 14:20:04 2003 @@ -228,7 +228,7 @@ #define MSU_SN0_SLOTID_MASK (UINT64_CAST 7) #define MSU_SN00_SLOTID_SHFT 7 #define MSU_SN00_SLOTID_MASK (UINT64_CAST 0x80) - + #define MSU_PIMM_PSC_SHFT 4 #define MSU_PIMM_PSC_MASK (0xf << MSU_PIMM_PSC_SHFT) @@ -424,8 +424,7 @@ * Operations on page migration threshold register */ -#if _LANGUAGE_C -#ifndef _STANDALONE +#ifndef __ASSEMBLY__ /* * LED register macros @@ -538,8 +537,6 @@ #define MD_SPROT_MIGMD_GET(value) ( \ ((value) & MD_SPROT_MIGMD_MASK) >> MD_SPROT_MIGMD_SHFT) -#endif /* _STANDALONE */ - /* * Format of dir_error, mem_error, protocol_error and misc_error registers */ @@ -739,7 +736,7 @@ } md_perf_cnt_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #define DIR_ERROR_VALID_MASK 0xe000000000000000 diff -Nru a/include/asm-mips64/sn/sn0/hubni.h b/include/asm-mips64/sn/sn0/hubni.h --- a/include/asm-mips64/sn/sn0/hubni.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/sn/sn0/hubni.h Fri Jun 27 14:19:53 2003 @@ -11,7 +11,7 @@ #ifndef _ASM_SGI_SN0_HUBNI_H #define _ASM_SGI_SN0_HUBNI_H -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ #include <linux/types.h> #endif @@ -226,7 +226,7 @@ #define NLT_EXIT_PORT_MASK (UINT64_CAST 0xf) -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef union hubni_port_error_u { u64 nipe_reg_value; @@ -250,6 +250,6 @@ #define NI_LLP_CB_MAX 0xff #define NI_LLP_SN_MAX 0xff -#endif /* LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_SGI_SN0_HUBNI_H */ diff -Nru a/include/asm-mips64/sn/sn0/hubpi.h b/include/asm-mips64/sn/sn0/hubpi.h --- a/include/asm-mips64/sn/sn0/hubpi.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/sn/sn0/hubpi.h Fri Jun 27 14:19:53 2003 @@ -136,8 +136,8 @@ #define PI_ERR_INT_PEND 0x000400 /* Error Interrupt Pending */ #define PI_ERR_INT_MASK_A 0x000408 /* Error Interrupt mask for CPU A */ #define PI_ERR_INT_MASK_B 0x000410 /* Error Interrupt mask for CPU B */ -#define PI_ERR_STACK_ADDR_A 0x000418 /* Error stack address for CPU A */ -#define PI_ERR_STACK_ADDR_B 0x000420 /* Error stack address for CPU B */ +#define PI_ERR_STACK_ADDR_A 0x000418 /* Error stack address for CPU A */ +#define PI_ERR_STACK_ADDR_B 0x000420 /* Error stack address for CPU B */ #define PI_ERR_STACK_SIZE 0x000428 /* Error Stack Size */ #define PI_ERR_STATUS0_A 0x000430 /* Error Status 0A */ #define PI_ERR_STATUS0_A_RCLR 0x000438 /* Error Status 0A clear on read */ @@ -193,7 +193,7 @@ /* - * The following three macros define all possible error int pends. + * The following three macros define all possible error int pends. */ #define PI_FATAL_ERR_CPU_A (PI_ERR_SYSSTATE_TAG_A | \ @@ -306,7 +306,7 @@ #define ERR_STACK_SIZE_BYTES(_sz) \ ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0) -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ /* * format of error stack and error status registers. */ @@ -359,7 +359,7 @@ typedef u64 rtc_time_t; -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ /* Bits in PI_SYSAD_ERRCHK_EN */ diff -Nru a/include/asm-mips64/sn/sn0/ip27.h b/include/asm-mips64/sn/sn0/ip27.h --- a/include/asm-mips64/sn/sn0/ip27.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/sn/sn0/ip27.h Fri Jun 27 14:19:53 2003 @@ -19,7 +19,7 @@ #define TLBLO_HWBITSHIFT 0 /* Shift value, for masking */ -#if !_LANGUAGE_ASSEMBLY +#ifndef __ASSEMBLY__ #define CAUSE_BERRINTR IE_IRQ5 @@ -30,9 +30,9 @@ #define ECCF_PADDR 4 #define ECCF_SIZE (5 * sizeof(long)) -#endif /* !_LANGUAGE_ASSEMBLY */ +#endif /* !__ASSEMBLY__ */ -#if _LANGUAGE_ASSEMBLY +#ifdef __ASSEMBLY__ /* * KL_GET_CPUNUM (similar to EV_GET_SPNUM for EVEREST platform) reads @@ -43,7 +43,7 @@ dli proc, LOCAL_HUB(0); \ ld proc, PI_CPU_NUM(proc) -#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* __ASSEMBLY__ */ /* * R10000 status register interrupt bit mask usage for IP27. diff -Nru a/include/asm-mips64/sn/sn0/sn0_fru.h b/include/asm-mips64/sn/sn0/sn0_fru.h --- a/include/asm-mips64/sn/sn0/sn0_fru.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/sn/sn0/sn0_fru.h Fri Jun 27 14:19:53 2003 @@ -17,11 +17,11 @@ typedef unsigned char confidence_t; typedef struct kf_mem_s { - confidence_t km_confidence; /* confidence level that the memory is bad - * is this necessary ? + confidence_t km_confidence; /* confidence level that the memory is bad + * is this necessary ? */ - confidence_t km_dimm[MAX_DIMMS]; - /* confidence level that dimm[i] is bad + confidence_t km_dimm[MAX_DIMMS]; + /* confidence level that dimm[i] is bad *I think this is the right number */ diff -Nru a/include/asm-mips64/softirq.h b/include/asm-mips64/softirq.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/softirq.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,20 @@ +#ifndef __ASM_SOFTIRQ_H +#define __ASM_SOFTIRQ_H + +#include <linux/preempt.h> +#include <asm/hardirq.h> + +#define local_bh_disable() \ + do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0) +#define __local_bh_enable() \ + do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0) + +#define local_bh_enable() \ +do { \ + __local_bh_enable(); \ + if (unlikely(!in_interrupt() && softirq_pending(smp_processor_id()))) \ + do_softirq(); \ + preempt_check_resched(); \ +} while (0) + +#endif /* __ASM_SOFTIRQ_H */ diff -Nru a/include/asm-mips64/spinlock.h b/include/asm-mips64/spinlock.h --- a/include/asm-mips64/spinlock.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/spinlock.h Fri Jun 27 14:20:05 2003 @@ -31,7 +31,7 @@ * We make no fairness assumptions. They have a cost. */ -static inline void spin_lock(spinlock_t *lock) +static inline void _raw_spin_lock(spinlock_t *lock) { unsigned int tmp; @@ -44,37 +44,37 @@ "beqz\t%1, 1b\n\t" " sync\n\t" ".set\treorder" - : "=o" (lock->lock), "=&r" (tmp) - : "o" (lock->lock) + : "=m" (lock->lock), "=&r" (tmp) + : "m" (lock->lock) : "memory"); } -static inline void spin_unlock(spinlock_t *lock) +static inline void _raw_spin_unlock(spinlock_t *lock) { __asm__ __volatile__( ".set\tnoreorder\t\t\t# spin_unlock\n\t" "sync\n\t" "sw\t$0, %0\n\t" - ".set\treorder" - : "=o" (lock->lock) - : "o" (lock->lock) + ".set\treorder" + : "=m" (lock->lock) + : "m" (lock->lock) : "memory"); } -static inline unsigned int spin_trylock(spinlock_t *lock) +static inline unsigned int _raw_spin_trylock(spinlock_t *lock) { unsigned int temp, res; __asm__ __volatile__( ".set\tnoreorder\t\t\t# spin_trylock\n\t" - "1:\tll\t%0, %1\n\t" - "or\t%2, %0, %3\n\t" + "1:\tll\t%0, %3\n\t" + "ori\t%2, %0, 1\n\t" "sc\t%2, %1\n\t" "beqz\t%2, 1b\n\t" - " and\t%2, %0, %3\n\t" + " andi\t%2, %0, 1\n\t" ".set\treorder" : "=&r" (temp), "=m" (lock->lock), "=&r" (res) - : "r" (1), "m" (lock->lock) + : "m" (lock->lock) : "memory"); return res == 0; @@ -95,7 +95,11 @@ #define RW_LOCK_UNLOCKED (rwlock_t) { 0 } -static inline void read_lock(rwlock_t *rw) +#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) + +#define rwlock_is_locked(x) ((x)->lock) + +static inline void _raw_read_lock(rwlock_t *rw) { unsigned int tmp; @@ -107,16 +111,16 @@ "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" " sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } /* Note the use of sub, not subu which will make the kernel die with an overflow exception if we ever try to unlock an rwlock that is already unlocked or is being held by a writer. */ -static inline void read_unlock(rwlock_t *rw) +static inline void _raw_read_unlock(rwlock_t *rw) { unsigned int tmp; @@ -126,14 +130,14 @@ "sub\t%1, 1\n\t" "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" - "sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + " sync\n\t" + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } -static inline void write_lock(rwlock_t *rw) +static inline void _raw_write_lock(rwlock_t *rw) { unsigned int tmp; @@ -145,21 +149,21 @@ "sc\t%1, %0\n\t" "beqz\t%1, 1b\n\t" " sync\n\t" - ".set\treorder" - : "=o" (rw->lock), "=&r" (tmp) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock), "=&r" (tmp) + : "m" (rw->lock) : "memory"); } -static inline void write_unlock(rwlock_t *rw) +static inline void _raw_write_unlock(rwlock_t *rw) { __asm__ __volatile__( ".set\tnoreorder\t\t\t# write_unlock\n\t" "sync\n\t" "sw\t$0, %0\n\t" - ".set\treorder" - : "=o" (rw->lock) - : "o" (rw->lock) + ".set\treorder" + : "=m" (rw->lock) + : "m" (rw->lock) : "memory"); } diff -Nru a/include/asm-mips64/stackframe.h b/include/asm-mips64/stackframe.h --- a/include/asm-mips64/stackframe.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-mips64/stackframe.h Fri Jun 27 14:19:54 2003 @@ -1,5 +1,4 @@ -/* $Id: stackframe.h,v 1.3 1999/12/04 03:59:12 ralf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -8,17 +7,18 @@ * Copyright (C) 1994, 1995, 1996 Paul M. Antoine. * Copyright (C) 1999 Silicon Graphics, Inc. */ -#ifndef _ASM_STACKFRAME_H -#define _ASM_STACKFRAME_H +#ifndef __ASM_STACKFRAME_H +#define __ASM_STACKFRAME_H #include <linux/config.h> +#include <linux/threads.h> #include <asm/asm.h> #include <asm/offset.h> #include <asm/processor.h> #include <asm/addrspace.h> -#ifdef _LANGUAGE_C +#ifndef __ASSEMBLY__ #define __str2(x) #x #define __str(x) __str2(x) @@ -37,9 +37,9 @@ : /* No outputs */ \ : "r" (frame)) -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ -#ifdef _LANGUAGE_ASSEMBLY +#ifdef __ASSEMBLY__ .macro SAVE_AT .set push @@ -76,6 +76,39 @@ sd $30, PT_R30(sp) .endm +#ifdef CONFIG_SMP + .macro get_saved_sp /* SMP variation */ + dmfc0 k1, CP0_CONTEXT + dsra k1, 23 + lui k0, %hi(pgd_current) + daddiu k0, %lo(pgd_current) + dsubu k1, k0 + lui k0, %hi(kernelsp) + daddu k1, k0 + ld k1, %lo(kernelsp)(k1) + .endm + + .macro set_saved_sp stackp temp temp2 + lw \temp, TI_CPU(gp) + dsll \temp, 3 + lui \temp2, %hi(kernelsp) + daddu \temp, \temp2 + sd \stackp, %lo(kernelsp)(\temp) + .endm +#else + .macro get_saved_sp /* Uniprocessor variation */ + lui k1, %hi(kernelsp) + ld k1, %lo(kernelsp)(k1) + .endm + + .macro set_saved_sp stackp temp temp2 + sd \stackp, kernelsp + .endm +#endif + .macro declare_saved_sp + .comm kernelsp, NR_CPUS * 8, 8 + .endm + .macro SAVE_SOME .set push .set reorder @@ -86,30 +119,17 @@ move k1, sp .set reorder /* Called from user mode, new stack. */ -#ifndef CONFIG_SMP - lui k1, %hi(kernelsp) - ld k1, %lo(kernelsp)(k1) -#else - mfc0 k0, CP0_WATCHLO - mfc0 k1, CP0_WATCHHI - dsll32 k0, k0, 0 /* Get rid of sign extension */ - dsrl32 k0, k0, 0 /* Get rid of sign extension */ - dsll32 k1, k1, 0 - or k1, k1, k0 - li k0, K0BASE - or k1, k1, k0 - daddiu k1, k1, KERNEL_STACK_SIZE-32 -#endif + get_saved_sp 8: move k0, sp dsubu sp, k1, PT_SIZE sd k0, PT_R29(sp) sd $3, PT_R3(sp) sd $0, PT_R0(sp) - dmfc0 v1, CP0_STATUS + mfc0 v1, CP0_STATUS sd $2, PT_R2(sp) sd v1, PT_STATUS(sp) sd $4, PT_R4(sp) - dmfc0 v1, CP0_CAUSE + mfc0 v1, CP0_CAUSE sd $5, PT_R5(sp) sd v1, PT_CAUSE(sp) sd $6, PT_R6(sp) @@ -184,7 +204,7 @@ nor v1, $0, v1 and v0, v1 or v0, t0 - dmtc0 v0, CP0_STATUS + mtc0 v0, CP0_STATUS ld v1, PT_EPC(sp) dmtc0 v1, CP0_EPC ld $31, PT_R31(sp) @@ -242,6 +262,6 @@ mtc0 t0, CP0_STATUS .endm -#endif /* _LANGUAGE_ASSEMBLY */ +#endif /* __ASSEMBLY__ */ -#endif /* _ASM_STACKFRAME_H */ +#endif /* __ASM_STACKFRAME_H */ diff -Nru a/include/asm-mips64/stat.h b/include/asm-mips64/stat.h --- a/include/asm-mips64/stat.h Fri Jun 27 14:20:04 2003 +++ b/include/asm-mips64/stat.h Fri Jun 27 14:20:04 2003 @@ -10,83 +10,42 @@ #define _ASM_STAT_H #include <linux/types.h> -#include <linux/compat.h> - -struct __old_kernel_stat { - unsigned int st_dev; - unsigned int st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned int st_uid; - unsigned int st_gid; - unsigned int st_rdev; - long st_size; - unsigned int st_atime, st_res1; - unsigned int st_mtime, st_res2; - unsigned int st_ctime, st_res3; - unsigned int st_blksize; - int st_blocks; - unsigned int st_unused[2]; -}; - -struct stat32 { - __kernel_dev_t32 st_dev; - int st_pad1[3]; - __kernel_ino_t32 st_ino; - __kernel_mode_t32 st_mode; - __kernel_nlink_t32 st_nlink; - __kernel_uid_t32 st_uid; - __kernel_gid_t32 st_gid; - __kernel_dev_t32 st_rdev; - int st_pad2[2]; - __kernel_off_t32 st_size; - int st_pad3; - compat_time_t st_atime; - int reserved0; - compat_time_t st_mtime; - int reserved1; - compat_time_t st_ctime; - int reserved2; - int st_blksize; - int st_blocks; - int st_pad4[14]; -}; /* The memory layout is the same as of struct stat64 of the 32-bit kernel. */ struct stat { - dev_t st_dev; - unsigned int st_pad0[3]; /* Reserved for st_dev expansion */ + dev_t st_dev; + unsigned int st_pad0[3]; /* Reserved for st_dev expansion */ - unsigned long st_ino; + unsigned long st_ino; - mode_t st_mode; - nlink_t st_nlink; + mode_t st_mode; + nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; + uid_t st_uid; + gid_t st_gid; - dev_t st_rdev; - unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */ + dev_t st_rdev; + unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */ - off_t st_size; + off_t st_size; /* * Actually this should be timestruc_t st_atime, st_mtime and st_ctime * but we don't have it under Linux. */ - unsigned int st_atime; - unsigned int st_atime_nsec; + unsigned int st_atime; + unsigned int st_atime_nsec; - unsigned int st_mtime; - unsigned int st_mtime_nsec; + unsigned int st_mtime; + unsigned int st_mtime_nsec; - unsigned int st_ctime; - unsigned int st_ctime_nsec; + unsigned int st_ctime; + unsigned int st_ctime_nsec; - unsigned int st_blksize; - unsigned int st_pad2; + unsigned int st_blksize; + unsigned int st_pad2; - unsigned long st_blocks; + unsigned long st_blocks; }; #define STAT_HAVE_NSEC 1 diff -Nru a/include/asm-mips64/statfs.h b/include/asm-mips64/statfs.h --- a/include/asm-mips64/statfs.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/statfs.h Fri Jun 27 14:19:59 2003 @@ -35,4 +35,20 @@ long f_spare[6]; }; +struct statfs64 { /* Same as struct statfs */ + long f_type; + long f_bsize; + long f_frsize; /* Fragment size - unsupported */ + long f_blocks; + long f_bfree; + long f_files; + long f_ffree; + + /* Linux specials */ + long f_bavail; + __kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + #endif /* _ASM_STATFS_H */ diff -Nru a/include/asm-mips64/suspend.h b/include/asm-mips64/suspend.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/suspend.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,6 @@ +#ifndef __ASM_SUSPEND_H +#define __ASM_SUSPEND_H + +/* Somewhen... Maybe :-) */ + +#endif /* __ASM_SUSPEND_H */ diff -Nru a/include/asm-mips64/system.h b/include/asm-mips64/system.h --- a/include/asm-mips64/system.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/system.h Fri Jun 27 14:19:55 2003 @@ -11,25 +11,32 @@ #define _ASM_SYSTEM_H #include <linux/config.h> - #include <asm/sgidefs.h> + #include <linux/kernel.h> -extern __inline__ void -local_irq_enable(void) +#include <asm/addrspace.h> +#include <asm/ptrace.h> + +__asm__ ( + ".macro\tlocal_irq_enable\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,0x1f\n\t" + "xori\t$1,0x1e\n\t" + "mtc0\t$1,$12\n\t" + ".set\tpop\n\t" + ".endm"); + +extern inline void local_irq_enable(void) { __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" - "ori\t$1,0x1f\n\t" - "xori\t$1,0x1e\n\t" - "mtc0\t$1,$12\n\t" - ".set\tat\n\t" - ".set\treorder" + "local_irq_enable" : /* no outputs */ : /* no inputs */ - : "$1", "memory"); + : "memory"); } /* @@ -39,111 +46,201 @@ * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs * no nops at all. */ -extern __inline__ void -local_irq_disable(void) +__asm__ ( + ".macro\tlocal_irq_disable\n\t" + ".set\tpush\n\t" + ".set\tnoat\n\t" + "mfc0\t$1,$12\n\t" + "ori\t$1,1\n\t" + "xori\t$1,1\n\t" + ".set\tnoreorder\n\t" + "mtc0\t$1,$12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tpop\n\t" + ".endm"); + +extern inline void local_irq_disable(void) { __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "mfc0\t$1,$12\n\t" - "ori\t$1,1\n\t" - "xori\t$1,1\n\t" - "mtc0\t$1,$12\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - ".set\tat\n\t" - ".set\treorder" + "local_irq_disable" : /* no outputs */ : /* no inputs */ - : "$1", "memory"); + : "memory"); } +__asm__ ( + ".macro\tlocal_save_flags flags\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + "mfc0\t\\flags, $12\n\t" + ".set\tpop\n\t" + ".endm"); + #define local_save_flags(x) \ __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - "mfc0\t%0,$12\n\t" \ - ".set\treorder" \ + "local_save_flags %0" \ : "=r" (x)) +__asm__ ( + ".macro\tlocal_irq_save result\n\t" + ".set\tpush\n\t" + ".set\treorder\n\t" + ".set\tnoat\n\t" + "mfc0\t\\result, $12\n\t" + "ori\t$1, \\result, 1\n\t" + "xori\t$1, 1\n\t" + ".set\tnoreorder\n\t" + "mtc0\t$1, $12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tpop\n\t" + ".endm"); + #define local_irq_save(x) \ __asm__ __volatile__( \ - ".set\tnoreorder\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t%0,$12\n\t" \ - "ori\t$1,%0,1\n\t" \ - "xori\t$1,1\n\t" \ - "mtc0\t$1,$12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ + "local_irq_save\t%0" \ : "=r" (x) \ : /* no inputs */ \ - : "$1", "memory") + : "memory") + +__asm__(".macro\tlocal_irq_restore flags\n\t" + ".set\tnoreorder\n\t" + ".set\tnoat\n\t" + "mfc0\t$1, $12\n\t" + "andi\t\\flags, 1\n\t" + "ori\t$1, 1\n\t" + "xori\t$1, 1\n\t" + "or\t\\flags, $1\n\t" + "mtc0\t\\flags, $12\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + "sll\t$0, $0, 1\t\t\t# nop\n\t" + ".set\tat\n\t" + ".set\treorder\n\t" + ".endm"); #define local_irq_restore(flags) \ do { \ unsigned long __tmp1; \ \ __asm__ __volatile__( \ - ".set\tnoreorder\t\t\t# local_irq_restore\n\t" \ - ".set\tnoat\n\t" \ - "mfc0\t$1, $12\n\t" \ - "andi\t%0, 1\n\t" \ - "ori\t$1, 1\n\t" \ - "xori\t$1, 1\n\t" \ - "or\t%0, $1\n\t" \ - "mtc0\t%0, $12\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - "nop\n\t" \ - ".set\tat\n\t" \ - ".set\treorder" \ + "local_irq_restore\t%0" \ : "=r" (__tmp1) \ : "0" (flags) \ - : "$1", "memory"); \ + : "memory"); \ } while(0) -#ifdef CONFIG_SMP - -extern void __global_cli(void); -extern void __global_sti(void); -extern unsigned long __global_save_flags(void); -extern void __global_restore_flags(unsigned long); -#define cli() __global_cli() -#define sti() __global_sti() -#define save_flags(x) ((x)=__global_save_flags()) -#define restore_flags(x) __global_restore_flags(x) -#define save_and_cli(x) do { save_flags(x); cli(); } while(0) - -#else - -#define cli() local_irq_disable() -#define sti() local_irq_enable() -#define save_flags(x) local_save_flags(x) -#define restore_flags(x) local_irq_restore(x) -#define save_and_cli(x) local_irq_save(x) - -#endif /* CONFIG_SMP */ +#define irqs_disabled() \ +({ \ + unsigned long flags; \ + local_save_flags(flags); \ + !(flags & 1); \ +}) /* - * These are probably defined overly paranoid ... + * read_barrier_depends - Flush all pending reads that subsequents reads + * depend on. + * + * No data-dependent reads from memory-like regions are ever reordered + * over this barrier. All reads preceding this primitive are guaranteed + * to access memory (but not necessarily other CPUs' caches) before any + * reads following this primitive that depend on the data return by + * any of the preceding reads. This primitive is much lighter weight than + * rmb() on most CPUs, and is never heavier weight than is + * rmb(). + * + * These ordering constraints are respected by both the local CPU + * and the compiler. + * + * Ordering is not guaranteed by anything other than these primitives, + * not even by data dependencies. See the documentation for + * memory_barrier() for examples and URLs to more information. + * + * For example, the following code would force ordering (the initial + * value of "a" is zero, "b" is one, and "p" is "&a"): + * + * <programlisting> + * CPU 0 CPU 1 + * + * b = 2; + * memory_barrier(); + * p = &b; q = p; + * read_barrier_depends(); + * d = *q; + * </programlisting> + * + * because the read of "*q" depends on the read of "p" and these + * two reads are separated by a read_barrier_depends(). However, + * the following code, with the same initial values for "a" and "b": + * + * <programlisting> + * CPU 0 CPU 1 + * + * a = 2; + * memory_barrier(); + * b = 3; y = b; + * read_barrier_depends(); + * x = a; + * </programlisting> + * + * does not enforce ordering, since there is no data dependency between + * the read of "a" and the read of "b". Therefore, on some CPUs, such + * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() + * in cases like thiswhere there are no data dependencies. */ -#define mb() \ -__asm__ __volatile__( \ - "# prevent instructions being moved around\n\t" \ - ".set\tnoreorder\n\t" \ - "sync\n\t" \ - ".set\treorder" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -#define rmb() mb() -#define wmb() mb() + #define read_barrier_depends() do { } while(0) +#ifdef CONFIG_CPU_HAS_SYNC +#define __sync() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "sync\n\t" \ + ".set pop" \ + : /* no output */ \ + : /* no input */ \ + : "memory") +#else +#define __sync() do { } while(0) +#endif + +#define __fast_iob() \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "lw $0,%0\n\t" \ + "nop\n\t" \ + ".set pop" \ + : /* no output */ \ + : "m" (*(int *)KSEG1) \ + : "memory") + +#define fast_wmb() __sync() +#define fast_rmb() __sync() +#define fast_mb() __sync() +#define fast_iob() \ + do { \ + __sync(); \ + __asm__ __volatile__( \ + ".set push\n\t" \ + ".set noreorder\n\t" \ + "lw $0,%0\n\t" \ + "nop\n\t" \ + ".set pop" \ + : /* no output */ \ + : "m" (*(int *)KSEG1) \ + : "memory"); \ + } while (0) + +#define wmb() fast_wmb() +#define rmb() fast_rmb() +#define mb() fast_mb() +#define iob() fast_iob() + #ifdef CONFIG_SMP #define smp_mb() mb() #define smp_rmb() rmb() @@ -162,35 +259,17 @@ #define set_wmb(var, value) \ do { var = value; wmb(); } while (0) -#if !defined (_LANGUAGE_ASSEMBLY) /* * switch_to(n) should switch tasks to task nr n, first * checking that n isn't the current task, in which case it does nothing. */ -extern asmlinkage void *resume(void *last, void *next); -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ - -#define prepare_to_switch() do { } while(0) - -extern asmlinkage void lazy_fpu_switch(void *, void *); -extern asmlinkage void init_fpu(void); -extern asmlinkage void save_fp(void *); +extern asmlinkage void *resume(void *last, void *next, void *next_ti); -#ifdef CONFIG_SMP -#define SWITCH_DO_LAZY_FPU \ - if (prev->flags & PF_USEDFPU) { \ - lazy_fpu_switch(prev, 0); \ - set_cp0_status(ST0_CU1, ~ST0_CU1); \ - prev->flags &= ~PF_USEDFPU; \ - } -#else /* CONFIG_SMP */ -#define SWITCH_DO_LAZY_FPU do { } while(0) -#endif /* CONFIG_SMP */ +struct task_struct; #define switch_to(prev,next,last) \ do { \ - SWITCH_DO_LAZY_FPU; \ - (last) = resume(prev, next); \ + (last) = resume(prev, next, next->thread_info); \ } while(0) extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) @@ -198,38 +277,40 @@ unsigned long dummy; __asm__ __volatile__( - ".set\tnoreorder\t\t\t# xchg_u32\n\t" - ".set\tnoat\n\t" + ".set\tpush\t\t\t\t# xchg_u32\n\t" + ".set\tnoreorder\n\t" + ".set\tnomacro\n\t" "ll\t%0, %3\n" - "1:\tmove\t$1, %2\n\t" - "sc\t$1, %1\n\t" - "beqzl\t$1, 1b\n\t" + "1:\tmove\t%2, %z4\n\t" + "sc\t%2, %1\n\t" + "beqzl\t%2, 1b\n\t" " ll\t%0, %3\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (val), "=o" (*m), "=r" (dummy) - : "o" (*m), "2" (val) + "sync\n\t" + ".set\tpop" + : "=&r" (val), "=m" (*m), "=&r" (dummy) + : "R" (*m), "Jr" (val) : "memory"); return val; } -extern __inline__ unsigned long xchg_u64(volatile long * m, unsigned long val) +extern __inline__ unsigned long xchg_u64(volatile int * m, unsigned long val) { unsigned long dummy; __asm__ __volatile__( - ".set\tnoreorder\t\t\t# xchg_u64\n\t" - ".set\tnoat\n\t" + ".set\tpush\t\t\t\t# xchg_u64\n\t" + ".set\tnoreorder\n\t" + ".set\tnomacro\n\t" "lld\t%0, %3\n" - "1:\tmove\t$1, %2\n\t" - "scd\t$1, %1\n\t" - "beqzl\t$1, 1b\n\t" + "1:\tmove\t%2, %z4\n\t" + "scd\t%2, %1\n\t" + "beqzl\t%2, 1b\n\t" " lld\t%0, %3\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (val), "=o" (*m), "=r" (dummy) - : "o" (*m), "2" (val) + "sync\n\t" + ".set\tpop" + : "=&r" (val), "=m" (*m), "=&r" (dummy) + : "R" (*m), "Jr" (val) : "memory"); return val; @@ -239,8 +320,8 @@ #define tas(ptr) (xchg((ptr),1)) -static __inline__ unsigned long -__xchg(unsigned long x, volatile void * ptr, int size) +static inline unsigned long __xchg(unsigned long x, volatile void * ptr, + int size) { switch (size) { case 4: @@ -251,6 +332,25 @@ return x; } -extern void set_except_vector(int n, void *addr); +extern void *set_except_vector(int n, void *addr); +extern void per_cpu_trap_init(void); + +extern void __die(const char *, struct pt_regs *, const char *file, + const char *func, unsigned long line) __attribute__((noreturn)); +extern void __die_if_kernel(const char *, struct pt_regs *, const char *file, + const char *func, unsigned long line); + +#define die(msg, regs) \ + __die(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) +#define die_if_kernel(msg, regs) \ + __die_if_kernel(msg, regs, __FILE__ ":", __FUNCTION__, __LINE__) + +extern int serial_console; +extern int stop_a_enabled; + +static __inline__ int con_is_present(void) +{ + return serial_console ? 0 : 1; +} #endif /* _ASM_SYSTEM_H */ diff -Nru a/include/asm-mips64/thread_info.h b/include/asm-mips64/thread_info.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/thread_info.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,103 @@ +/* thread_info.h: i386 low-level thread information + * + * Copyright (C) 2002 David Howells (dhowells@redhat.com) + * - Incorporating suggestions made by Linus Torvalds and Dave Miller + */ + +#ifndef _ASM_THREAD_INFO_H +#define _ASM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#ifndef __ASSEMBLY__ + +#include <asm/processor.h> + +/* + * low level task data that entry.S needs immediate access to + * - this struct should fit entirely inside of one cache line + * - this struct shares the supervisor stack pages + * - if the contents of this structure are changed, the assembly constants + * must also be changed + */ +struct thread_info { + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + unsigned long flags; /* low level flags */ + __u32 cpu; /* current CPU */ + __s32 preempt_count; /* 0 => preemptable, <0 => BUG */ + + mm_segment_t addr_limit; /* thread address space: + 0-0xBFFFFFFF for user-thead + 0-0xFFFFFFFF for kernel-thread + */ + struct restart_block restart_block; +}; + +#define PREEMPT_ACTIVE 0x4000000 + +/* + * macros/functions for gaining access to the thread information structure + * + * preempt_count needs to be 1 initially, until the scheduler is functional. + */ +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .cpu = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* How to get the thread information struct from C. */ +register struct thread_info *__current_thread_info __asm__("$28"); +#define current_thread_info() __current_thread_info + +/* thread information allocation */ +#define THREAD_SIZE_ORDER (2) +#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define alloc_thread_info(tsk) ((struct thread_info *) \ + __get_free_pages(GFP_KERNEL,THREAD_SIZE_ORDER)) +#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_SIZE_ORDER) +#define get_thread_info(ti) get_task_struct((ti)->task) +#define put_thread_info(ti) put_task_struct((ti)->task) + +#endif /* !__ASSEMBLY__ */ + +/* + * thread information flags + * - these are process state flags that various assembly files may need to + * access + * - pending work-to-be-done flags are in LSW + * - other flags in MSW + */ +#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ +#define TIF_SIGPENDING 2 /* signal pending */ +#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ +#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_SYSCALL_TRACE 31 /* syscall trace active */ + +#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) +#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) +#define _TIF_SIGPENDING (1<<TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_USEDFPU (1<<TIF_USEDFPU) +#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) + +#define _TIF_WORK_MASK 0x0000fffe /* work to do on + interrupt/exception return */ +#define _TIF_ALLWORK_MASK 0x8000fffe /* work to do on any return to + u-space */ + +#endif /* __KERNEL__ */ + +#endif /* _ASM_THREAD_INFO_H */ diff -Nru a/include/asm-mips64/time.h b/include/asm-mips64/time.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/time.h Fri Jun 27 14:20:07 2003 @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2001, 2002, MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * include/asm-mips/time.h + * header file for the new style time.c file and time services. + * + * 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. + * + * Please refer to Documentation/mips/time.README. + */ +#ifndef _ASM_TIME_H +#define _ASM_TIME_H + +#include <linux/interrupt.h> +#include <linux/linkage.h> +#include <linux/ptrace.h> +#include <linux/rtc.h> + +/* + * RTC ops. By default, they point a no-RTC functions. + * rtc_get_time - mktime(year, mon, day, hour, min, sec) in seconds. + * rtc_set_time - reverse the above translation and set time to RTC. + */ +extern unsigned long (*rtc_get_time)(void); +extern int (*rtc_set_time)(unsigned long); + +/* + * to_tm() converts system time back to (year, mon, day, hour, min, sec). + * It is intended to help implement rtc_set_time() functions. + * Copied from PPC implementation. + */ +extern void to_tm(unsigned long tim, struct rtc_time * tm); + +/* + * do_gettimeoffset(). By default, this func pointer points to + * do_null_gettimeoffset(), which leads to the same resolution as HZ. + * Higher resolution versions are vailable, which gives ~1us resolution. + */ +extern unsigned long (*do_gettimeoffset)(void); + +extern unsigned long null_gettimeoffset(void); +extern unsigned long fixed_rate_gettimeoffset(void); +extern unsigned long calibrate_div32_gettimeoffset(void); +extern unsigned long calibrate_div64_gettimeoffset(void); + +/* + * high-level timer interrupt routines. + */ +extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); + +/* + * the corresponding low-level timer interrupt routine. + */ +asmlinkage void ll_timer_interrupt(int irq, struct pt_regs *regs); + +/* + * profiling and process accouting is done separately in local_timer_interrupt + */ +void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); +asmlinkage void ll_local_timer_interrupt(int irq, struct pt_regs *regs); + +/* + * board specific routines required by time_init(). + * board_time_init is defaulted to NULL and can remains so. + * board_timer_setup must be setup properly in machine setup routine. + */ +struct irqaction; +extern void (*board_time_init)(void); +extern void (*board_timer_setup)(struct irqaction *irq); + +/* + * mips_counter_frequency - must be set if you intend to use + * counter as timer interrupt source or use fixed_rate_gettimeoffset. + */ +extern unsigned int mips_counter_frequency; + +#endif /* _ASM_TIME_H */ diff -Nru a/include/asm-mips64/timex.h b/include/asm-mips64/timex.h --- a/include/asm-mips64/timex.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-mips64/timex.h Fri Jun 27 14:20:01 2003 @@ -10,7 +10,9 @@ #ifndef _ASM_TIMEX_H #define _ASM_TIMEX_H -#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +#include <asm/mipsregs.h> + +#define CLOCK_TICK_RATE 1193182 /* Underlying HZ */ #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \ (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \ @@ -20,7 +22,7 @@ * Standard way to access the cycle counter. * Currently only used on SMP for scheduling. * - * Only the low 32 bits are available as a continuously counting entity. + * Only the low 32 bits are available as a continuously counting entity. * But this only means we'll force a reschedule every 8 seconds or so, * which isn't an evil thing. * @@ -32,15 +34,7 @@ static inline cycles_t get_cycles (void) { - cycles_t val; - - __asm__ __volatile__( - ".set noreorder\n\t" - "mfc0 %0, $9\n\t" - ".set reorder" - : "=r" (val)); - - return val; + return read_c0_count(); } #endif /* _ASM_TIMEX_H */ diff -Nru a/include/asm-mips64/tlb.h b/include/asm-mips64/tlb.h --- a/include/asm-mips64/tlb.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips64/tlb.h Fri Jun 27 14:20:00 2003 @@ -1 +1,18 @@ +#ifndef __ASM_TLB_H +#define __ASM_TLB_H + +/* + * MIPS doesn't need any special per-pte or per-vma handling.. + */ +#define tlb_start_vma(tlb, vma) do { } while (0) +#define tlb_end_vma(tlb, vma) do { } while (0) +#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) + +/* + * .. because we flush the whole mm when it fills up. + */ +#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) + #include <asm-generic/tlb.h> + +#endif /* __ASM_TLB_H */ diff -Nru a/include/asm-mips64/tlbdebug.h b/include/asm-mips64/tlbdebug.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/tlbdebug.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,20 @@ +/* + * 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) 2002 by Ralf Baechle + */ +#ifndef __ASM_TLBDEBUG_H +#define __ASM_TLBDEBUG_H + +/* + * TLB debugging functions: + */ +extern void dump_tlb(int first, int last); +extern void dump_tlb_all(void); +extern void dump_tlb_wired(void); +extern void dump_tlb_addr(unsigned long addr); +extern void dump_tlb_nonwired(void); + +#endif /* __ASM_TLBDEBUG_H */ diff -Nru a/include/asm-mips64/tlbflush.h b/include/asm-mips64/tlbflush.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/tlbflush.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,52 @@ +#ifndef __ASM_TLBFLUSH_H +#define __ASM_TLBFLUSH_H + +#include <linux/config.h> +#include <linux/mm.h> + +/* + * TLB flushing: + * + * - flush_tlb_all() flushes all processes TLB entries + * - flush_tlb_mm(mm) flushes the specified mm context TLB entries + * - flush_tlb_page(vma, vmaddr) flushes a single page + * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables + */ +extern void local_flush_tlb_all(void); +extern void local_flush_tlb_mm(struct mm_struct *mm); +extern void local_flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void local_flush_tlb_kernel_range(unsigned long start, + unsigned long end); +extern void local_flush_tlb_page(struct vm_area_struct *vma, + unsigned long page); + +#ifdef CONFIG_SMP + +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end); +extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long); + +#else /* CONFIG_SMP */ + +#define flush_tlb_all() local_flush_tlb_all() +#define flush_tlb_mm(mm) local_flush_tlb_mm(mm) +#define flush_tlb_range(vma,vmaddr,end) local_flush_tlb_range(vma, vmaddr, end) +#define flush_tlb_kernel_range(vmaddr,end) \ + local_flush_tlb_kernel_range(vmaddr, end) +#define flush_tlb_page(vma,page) local_flush_tlb_page(vma, page) + +#endif /* CONFIG_SMP */ + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Nothing to do on MIPS. */ +} + +#endif /* __ASM_TLBFLUSH_H */ diff -Nru a/include/asm-mips64/topology.h b/include/asm-mips64/topology.h --- a/include/asm-mips64/topology.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips64/topology.h Fri Jun 27 14:19:30 2003 @@ -1,8 +1,13 @@ -#ifndef _ASM_MIPS64_TOPOLOGY_H -#define _ASM_MIPS64_TOPOLOGY_H +#ifndef __ASM_TOPOLOGY_H +#define __ASM_TOPOLOGY_H + +#if CONFIG_SGI_IP27 #include <asm/mmzone.h> #define cpu_to_node(cpu) (cputocnode(cpu)) +#endif + +#include <asm-generic/topology.h> -#endif /* _ASM_MIPS64_TOPOLOGY_H */ +#endif /* __ASM_TOPOLOGY_H */ diff -Nru a/include/asm-mips64/traps.h b/include/asm-mips64/traps.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/traps.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,26 @@ +/* + * include/asm-mips64/traps.h + * + * Trap handling definitions. + * + * Copyright (C) 2002, 2003 Maciej W. Rozycki + * + * 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 __ASM_MIPS64_TRAPS_H +#define __ASM_MIPS64_TRAPS_H + +/* + * Possible status responses for a board_be_handler backend. + */ +#define MIPS_BE_DISCARD 0 /* return with no action */ +#define MIPS_BE_FIXUP 1 /* return to the fixup code */ +#define MIPS_BE_FATAL 2 /* treat as an unrecoverable error */ + +extern void (*board_be_init)(void); +extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup); + +#endif /* __ASM_MIPS64_TRAPS_H */ diff -Nru a/include/asm-mips64/types.h b/include/asm-mips64/types.h --- a/include/asm-mips64/types.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-mips64/types.h Fri Jun 27 14:20:05 2003 @@ -33,12 +33,12 @@ typedef unsigned long __u64; #else - + #if defined(__GNUC__) && !defined(__STRICT_ANSI__) typedef __signed__ long long __s64; typedef unsigned long long __u64; #endif - + #endif #endif /* __ASSEMBLY__ */ @@ -75,7 +75,10 @@ #endif -typedef unsigned long dma_addr_t; +typedef u64 dma_addr_t; +typedef u64 dma64_addr_t; + +typedef unsigned long phys_t; #endif /* __ASSEMBLY__ */ diff -Nru a/include/asm-mips64/uaccess.h b/include/asm-mips64/uaccess.h --- a/include/asm-mips64/uaccess.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/uaccess.h Fri Jun 27 14:19:55 2003 @@ -10,7 +10,7 @@ #define _ASM_UACCESS_H #include <linux/errno.h> -#include <linux/sched.h> +#include <linux/thread_info.h> #define STR(x) __STR(x) #define __STR(x) #x @@ -22,15 +22,15 @@ * * For historical reasons, these macros are grossly misnamed. */ -#define KERNEL_DS ((mm_segment_t) { (unsigned long) 0L }) -#define USER_DS ((mm_segment_t) { (unsigned long) -1L }) +#define KERNEL_DS ((mm_segment_t) { 0UL }) +#define USER_DS ((mm_segment_t) { -TASK_SIZE }) #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define get_fs() (current->thread.current_ds) #define get_ds() (KERNEL_DS) -#define set_fs(x) (current->thread.current_ds=(x)) +#define get_fs() (current_thread_info()->addr_limit) +#define set_fs(x) (current_thread_info()->addr_limit = (x)) #define segment_eq(a,b) ((a).seg == (b).seg) @@ -46,19 +46,19 @@ * - OR we are in kernel mode. */ #define __ua_size(size) \ - (__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 : (size)) + ((__builtin_constant_p(size) && (size)) > 0 ? 0 : (size)) -#define __access_ok(addr,size,mask) \ - (((signed long)((mask)&(addr | (addr + size) | __ua_size(size)))) >= 0) +#define __access_ok(addr, size, mask) \ + (((mask) & ((addr) | ((addr) + (size)) | __ua_size(size))) == 0) -#define __access_mask ((long)(get_fs().seg)) +#define __access_mask get_fs().seg -#define access_ok(type,addr,size) \ - __access_ok(((unsigned long)(addr)),(size),__access_mask) +#define access_ok(type, addr, size) \ + __access_ok((unsigned long)(addr), (size), __access_mask) -extern inline int verify_area(int type, const void * addr, unsigned long size) +static inline int verify_area(int type, const void * addr, unsigned long size) { - return access_ok(type,addr,size) ? 0 : -EFAULT; + return access_ok(type, addr, size) ? 0 : -EFAULT; } /* @@ -219,107 +219,106 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); -#define __copy_to_user(to,from,n) \ -({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - __MODULE_JAL(__copy_user) \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \ - "$15", "$24", "$31","memory"); \ - __cu_len; \ -}) - -#define __copy_from_user(to,from,n) \ -({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ - ".set\tnoat\n\t" \ - "daddu\t$1, %2, %3\n\t" \ - ".set\tat\n\t" \ - ".set\treorder\n\t" \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", "$12", \ - "$15", "$24", "$31","memory"); \ - __cu_len; \ -}) - -#define copy_to_user(to,from,n) \ -({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - __MODULE_JAL(__copy_user) \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", \ - "$12", "$15", "$24", "$31","memory"); \ - __cu_len; \ +#define __invoke_copy_to_user(to,from,n) \ +({ \ + register void *__cu_to_r __asm__ ("$4"); \ + register const void *__cu_from_r __asm__ ("$5"); \ + register long __cu_len_r __asm__ ("$6"); \ + \ + __cu_to_r = (to); \ + __cu_from_r = (from); \ + __cu_len_r = (n); \ + __asm__ __volatile__( \ + __MODULE_JAL(__copy_user) \ + : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ + : \ + : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ + "memory"); \ + __cu_len_r; \ +}) + +#define __copy_to_user(to,from,n) \ +({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, __cu_len); \ + __cu_len; \ +}) + +#define copy_to_user(to,from,n) \ +({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (access_ok(VERIFY_WRITE, __cu_to, __cu_len)) \ + __cu_len = __invoke_copy_to_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ +}) + +#define __invoke_copy_from_user(to,from,n) \ +({ \ + register void *__cu_to_r __asm__ ("$4"); \ + register const void *__cu_from_r __asm__ ("$5"); \ + register long __cu_len_r __asm__ ("$6"); \ + \ + __cu_to_r = (to); \ + __cu_from_r = (from); \ + __cu_len_r = (n); \ + __asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + __MODULE_JAL(__copy_user) \ + ".set\tnoat\n\t" \ + "daddu\t$1, %1, %2\n\t" \ + ".set\tat\n\t" \ + ".set\treorder\n\t" \ + "move\t%0, $6" \ + : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \ + : \ + : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \ + "memory"); \ + __cu_len_r; \ +}) + +#define __copy_from_user(to,from,n) \ +({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ +}) + +#define copy_from_user(to,from,n) \ +({ \ + void *__cu_to; \ + const void *__cu_from; \ + long __cu_len; \ + \ + __cu_to = (to); \ + __cu_from = (from); \ + __cu_len = (n); \ + if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \ + __cu_len = __invoke_copy_from_user(__cu_to, __cu_from, \ + __cu_len); \ + __cu_len; \ }) -#define copy_from_user(to,from,n) \ -({ \ - void *__cu_to; \ - const void *__cu_from; \ - long __cu_len; \ - \ - __cu_to = (to); \ - __cu_from = (from); \ - __cu_len = (n); \ - if (access_ok(VERIFY_READ, __cu_from, __cu_len)) \ - __asm__ __volatile__( \ - "move\t$4, %1\n\t" \ - "move\t$5, %2\n\t" \ - "move\t$6, %3\n\t" \ - ".set\tnoreorder\n\t" \ - __MODULE_JAL(__copy_user) \ - ".set\tnoat\n\t" \ - "daddu\t$1, %2, %3\n\t" \ - ".set\tat\n\t" \ - ".set\treorder\n\t" \ - "move\t%0, $6" \ - : "=r" (__cu_len) \ - : "r" (__cu_to), "r" (__cu_from), "r" (__cu_len) \ - : "$4", "$5", "$6", "$8", "$9", "$10", "$11", \ - "$12", "$15", "$24", "$31","memory"); \ - __cu_len; \ -}) - -extern inline __kernel_size_t +static inline __kernel_size_t __clear_user(void *addr, __kernel_size_t size) { __kernel_size_t res; @@ -341,8 +340,8 @@ ({ \ void * __cl_addr = (addr); \ unsigned long __cl_size = (n); \ - if (__cl_size && __access_ok(VERIFY_WRITE, \ - ((unsigned long)(__cl_addr)), __cl_size)) \ + if (__cl_size && access_ok(VERIFY_WRITE, \ + ((unsigned long)(__cl_addr)), __cl_size)) \ __cl_size = __clear_user(__cl_addr, __cl_size); \ __cl_size; \ }) @@ -351,7 +350,7 @@ * Returns: -EFAULT if exception before terminator, N if the entire * buffer filled, else strlen. */ -extern inline long +static inline long __strncpy_from_user(char *__to, const char *__from, long __len) { long res; @@ -369,7 +368,7 @@ return res; } -extern inline long +static inline long strncpy_from_user(char *__to, const char *__from, long __len) { long res; @@ -388,7 +387,7 @@ } /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -extern inline long __strlen_user(const char *s) +static inline long __strlen_user(const char *s) { long res; @@ -403,7 +402,7 @@ return res; } -extern inline long strlen_user(const char *s) +static inline long strlen_user(const char *s) { long res; @@ -419,14 +418,14 @@ } /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ -extern inline long __strnlen_user(const char *s, long n) +static inline long __strnlen_user(const char *s, long n) { long res; __asm__ __volatile__( "move\t$4, %1\n\t" "move\t$5, %2\n\t" - __MODULE_JAL(__strlen_user_nocheck_asm) + __MODULE_JAL(__strnlen_user_nocheck_asm) "move\t%0, $2" : "=r" (res) : "r" (s), "r" (n) @@ -435,14 +434,14 @@ return res; } -extern inline long strnlen_user(const char *s, long n) +static inline long strnlen_user(const char *s, long n) { long res; __asm__ __volatile__( "move\t$4, %1\n\t" "move\t$5, %2\n\t" - __MODULE_JAL(__strlen_user_asm) + __MODULE_JAL(__strnlen_user_asm) "move\t%0, $2" : "=r" (res) : "r" (s), "r" (n) diff -Nru a/include/asm-mips64/unaligned.h b/include/asm-mips64/unaligned.h --- a/include/asm-mips64/unaligned.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-mips64/unaligned.h Fri Jun 27 14:19:59 2003 @@ -15,7 +15,7 @@ /* * Load quad unaligned. */ -extern inline unsigned long __ldq_u(const unsigned long * __addr) +static inline unsigned long __ldq_u(const unsigned long * __addr) { unsigned long __res; @@ -29,7 +29,7 @@ /* * Load long unaligned. */ -extern inline unsigned long __ldl_u(const unsigned int * __addr) +static inline unsigned long __ldl_u(const unsigned int * __addr) { unsigned long __res; @@ -43,7 +43,7 @@ /* * Load word unaligned. */ -extern inline unsigned long __ldw_u(const unsigned short * __addr) +static inline unsigned long __ldw_u(const unsigned short * __addr) { unsigned long __res; @@ -55,9 +55,9 @@ } /* - * Store quad ununaligned. + * Store quad unaligned. */ -extern inline void __stq_u(unsigned long __val, unsigned long * __addr) +static inline void __stq_u(unsigned long __val, unsigned long * __addr) { __asm__("usd\t%1, %0" : "=m" (*__addr) @@ -65,9 +65,9 @@ } /* - * Store long ununaligned. + * Store long unaligned. */ -extern inline void __stl_u(unsigned long __val, unsigned int * __addr) +static inline void __stl_u(unsigned long __val, unsigned int * __addr) { __asm__("usw\t%1, %0" : "=m" (*__addr) @@ -75,9 +75,9 @@ } /* - * Store word ununaligned. + * Store word unaligned. */ -extern inline void __stw_u(unsigned long __val, unsigned short * __addr) +static inline void __stw_u(unsigned long __val, unsigned short * __addr) { __asm__("ush\t%1, %0" : "=m" (*__addr) @@ -88,8 +88,8 @@ * get_unaligned - get value from possibly mis-aligned location * @ptr: pointer to value * - * This macro should be used for accessing values larger in size than - * single bytes at locations that are expected to be improperly aligned, + * This macro should be used for accessing values larger in size than + * single bytes at locations that are expected to be improperly aligned, * e.g. retrieving a u16 value from a location not u16-aligned. * * Note that unaligned accesses can be very expensive on some architectures. @@ -124,8 +124,8 @@ * @val: value to place * @ptr: pointer to location * - * This macro should be used for placing values larger in size than - * single bytes at locations that are expected to be improperly aligned, + * This macro should be used for placing values larger in size than + * single bytes at locations that are expected to be improperly aligned, * e.g. writing a u16 value to a location not u16-aligned. * * Note that unaligned accesses can be very expensive on some architectures. diff -Nru a/include/asm-mips64/unistd.h b/include/asm-mips64/unistd.h --- a/include/asm-mips64/unistd.h Fri Jun 27 14:20:00 2003 +++ b/include/asm-mips64/unistd.h Fri Jun 27 14:20:00 2003 @@ -15,479 +15,748 @@ /* * Linux o32 style syscalls are in the range from 4000 to 4999. */ -#define __NR_Linux32 4000 -#define __NR_Linux32_syscall (__NR_Linux32 + 0) -#define __NR_Linux32_exit (__NR_Linux32 + 1) -#define __NR_Linux32_fork (__NR_Linux32 + 2) -#define __NR_Linux32_read (__NR_Linux32 + 3) -#define __NR_Linux32_write (__NR_Linux32 + 4) -#define __NR_Linux32_open (__NR_Linux32 + 5) -#define __NR_Linux32_close (__NR_Linux32 + 6) -#define __NR_Linux32_waitpid (__NR_Linux32 + 7) -#define __NR_Linux32_creat (__NR_Linux32 + 8) -#define __NR_Linux32_link (__NR_Linux32 + 9) -#define __NR_Linux32_unlink (__NR_Linux32 + 10) -#define __NR_Linux32_execve (__NR_Linux32 + 11) -#define __NR_Linux32_chdir (__NR_Linux32 + 12) -#define __NR_Linux32_time (__NR_Linux32 + 13) -#define __NR_Linux32_mknod (__NR_Linux32 + 14) -#define __NR_Linux32_chmod (__NR_Linux32 + 15) -#define __NR_Linux32_lchown (__NR_Linux32 + 16) -#define __NR_Linux32_break (__NR_Linux32 + 17) -#define __NR_Linux32_oldstat (__NR_Linux32 + 18) -#define __NR_Linux32_lseek (__NR_Linux32 + 19) -#define __NR_Linux32_getpid (__NR_Linux32 + 20) -#define __NR_Linux32_mount (__NR_Linux32 + 21) -#define __NR_Linux32_umount (__NR_Linux32 + 22) -#define __NR_Linux32_setuid (__NR_Linux32 + 23) -#define __NR_Linux32_getuid (__NR_Linux32 + 24) -#define __NR_Linux32_stime (__NR_Linux32 + 25) -#define __NR_Linux32_ptrace (__NR_Linux32 + 26) -#define __NR_Linux32_alarm (__NR_Linux32 + 27) -#define __NR_Linux32_oldfstat (__NR_Linux32 + 28) -#define __NR_Linux32_pause (__NR_Linux32 + 29) -#define __NR_Linux32_utime (__NR_Linux32 + 30) -#define __NR_Linux32_stty (__NR_Linux32 + 31) -#define __NR_Linux32_gtty (__NR_Linux32 + 32) -#define __NR_Linux32_access (__NR_Linux32 + 33) -#define __NR_Linux32_nice (__NR_Linux32 + 34) -#define __NR_Linux32_ftime (__NR_Linux32 + 35) -#define __NR_Linux32_sync (__NR_Linux32 + 36) -#define __NR_Linux32_kill (__NR_Linux32 + 37) -#define __NR_Linux32_rename (__NR_Linux32 + 38) -#define __NR_Linux32_mkdir (__NR_Linux32 + 39) -#define __NR_Linux32_rmdir (__NR_Linux32 + 40) -#define __NR_Linux32_dup (__NR_Linux32 + 41) -#define __NR_Linux32_pipe (__NR_Linux32 + 42) -#define __NR_Linux32_times (__NR_Linux32 + 43) -#define __NR_Linux32_prof (__NR_Linux32 + 44) -#define __NR_Linux32_brk (__NR_Linux32 + 45) -#define __NR_Linux32_setgid (__NR_Linux32 + 46) -#define __NR_Linux32_getgid (__NR_Linux32 + 47) -#define __NR_Linux32_signal (__NR_Linux32 + 48) -#define __NR_Linux32_geteuid (__NR_Linux32 + 49) -#define __NR_Linux32_getegid (__NR_Linux32 + 50) -#define __NR_Linux32_acct (__NR_Linux32 + 51) -#define __NR_Linux32_umount2 (__NR_Linux32 + 52) -#define __NR_Linux32_lock (__NR_Linux32 + 53) -#define __NR_Linux32_ioctl (__NR_Linux32 + 54) -#define __NR_Linux32_fcntl (__NR_Linux32 + 55) -#define __NR_Linux32_mpx (__NR_Linux32 + 56) -#define __NR_Linux32_setpgid (__NR_Linux32 + 57) -#define __NR_Linux32_ulimit (__NR_Linux32 + 58) -#define __NR_Linux32_unused59 (__NR_Linux32 + 59) -#define __NR_Linux32_umask (__NR_Linux32 + 60) -#define __NR_Linux32_chroot (__NR_Linux32 + 61) -#define __NR_Linux32_ustat (__NR_Linux32 + 62) -#define __NR_Linux32_dup2 (__NR_Linux32 + 63) -#define __NR_Linux32_getppid (__NR_Linux32 + 64) -#define __NR_Linux32_getpgrp (__NR_Linux32 + 65) -#define __NR_Linux32_setsid (__NR_Linux32 + 66) -#define __NR_Linux32_sigaction (__NR_Linux32 + 67) -#define __NR_Linux32_sgetmask (__NR_Linux32 + 68) -#define __NR_Linux32_ssetmask (__NR_Linux32 + 69) -#define __NR_Linux32_setreuid (__NR_Linux32 + 70) -#define __NR_Linux32_setregid (__NR_Linux32 + 71) -#define __NR_Linux32_sigsuspend (__NR_Linux32 + 72) -#define __NR_Linux32_sigpending (__NR_Linux32 + 73) -#define __NR_Linux32_sethostname (__NR_Linux32 + 74) -#define __NR_Linux32_setrlimit (__NR_Linux32 + 75) -#define __NR_Linux32_getrlimit (__NR_Linux32 + 76) -#define __NR_Linux32_getrusage (__NR_Linux32 + 77) -#define __NR_Linux32_gettimeofday (__NR_Linux32 + 78) -#define __NR_Linux32_settimeofday (__NR_Linux32 + 79) -#define __NR_Linux32_getgroups (__NR_Linux32 + 80) -#define __NR_Linux32_setgroups (__NR_Linux32 + 81) -#define __NR_Linux32_reserved82 (__NR_Linux32 + 82) -#define __NR_Linux32_symlink (__NR_Linux32 + 83) -#define __NR_Linux32_oldlstat (__NR_Linux32 + 84) -#define __NR_Linux32_readlink (__NR_Linux32 + 85) -#define __NR_Linux32_uselib (__NR_Linux32 + 86) -#define __NR_Linux32_swapon (__NR_Linux32 + 87) -#define __NR_Linux32_reboot (__NR_Linux32 + 88) -#define __NR_Linux32_readdir (__NR_Linux32 + 89) -#define __NR_Linux32_mmap (__NR_Linux32 + 90) -#define __NR_Linux32_munmap (__NR_Linux32 + 91) -#define __NR_Linux32_truncate (__NR_Linux32 + 92) -#define __NR_Linux32_ftruncate (__NR_Linux32 + 93) -#define __NR_Linux32_fchmod (__NR_Linux32 + 94) -#define __NR_Linux32_fchown (__NR_Linux32 + 95) -#define __NR_Linux32_getpriority (__NR_Linux32 + 96) -#define __NR_Linux32_setpriority (__NR_Linux32 + 97) -#define __NR_Linux32_profil (__NR_Linux32 + 98) -#define __NR_Linux32_statfs (__NR_Linux32 + 99) -#define __NR_Linux32_fstatfs (__NR_Linux32 + 100) -#define __NR_Linux32_ioperm (__NR_Linux32 + 101) -#define __NR_Linux32_socketcall (__NR_Linux32 + 102) -#define __NR_Linux32_syslog (__NR_Linux32 + 103) -#define __NR_Linux32_setitimer (__NR_Linux32 + 104) -#define __NR_Linux32_getitimer (__NR_Linux32 + 105) -#define __NR_Linux32_stat (__NR_Linux32 + 106) -#define __NR_Linux32_lstat (__NR_Linux32 + 107) -#define __NR_Linux32_fstat (__NR_Linux32 + 108) -#define __NR_Linux32_unused109 (__NR_Linux32 + 109) -#define __NR_Linux32_iopl (__NR_Linux32 + 110) -#define __NR_Linux32_vhangup (__NR_Linux32 + 111) -#define __NR_Linux32_idle (__NR_Linux32 + 112) -#define __NR_Linux32_vm86 (__NR_Linux32 + 113) -#define __NR_Linux32_wait4 (__NR_Linux32 + 114) -#define __NR_Linux32_swapoff (__NR_Linux32 + 115) -#define __NR_Linux32_sysinfo (__NR_Linux32 + 116) -#define __NR_Linux32_ipc (__NR_Linux32 + 117) -#define __NR_Linux32_fsync (__NR_Linux32 + 118) -#define __NR_Linux32_sigreturn (__NR_Linux32 + 119) -#define __NR_Linux32_clone (__NR_Linux32 + 120) -#define __NR_Linux32_setdomainname (__NR_Linux32 + 121) -#define __NR_Linux32_uname (__NR_Linux32 + 122) -#define __NR_Linux32_modify_ldt (__NR_Linux32 + 123) -#define __NR_Linux32_adjtimex (__NR_Linux32 + 124) -#define __NR_Linux32_mprotect (__NR_Linux32 + 125) -#define __NR_Linux32_sigprocmask (__NR_Linux32 + 126) -#define __NR_Linux32_create_module (__NR_Linux32 + 127) -#define __NR_Linux32_init_module (__NR_Linux32 + 128) -#define __NR_Linux32_delete_module (__NR_Linux32 + 129) -#define __NR_Linux32_get_kernel_syms (__NR_Linux32 + 130) -#define __NR_Linux32_quotactl (__NR_Linux32 + 131) -#define __NR_Linux32_getpgid (__NR_Linux32 + 132) -#define __NR_Linux32_fchdir (__NR_Linux32 + 133) -#define __NR_Linux32_bdflush (__NR_Linux32 + 134) -#define __NR_Linux32_sysfs (__NR_Linux32 + 135) -#define __NR_Linux32_personality (__NR_Linux32 + 136) -#define __NR_Linux32_afs_syscall (__NR_Linux32 + 137) /* Syscall for Andrew File System */ -#define __NR_Linux32_setfsuid (__NR_Linux32 + 138) -#define __NR_Linux32_setfsgid (__NR_Linux32 + 139) -#define __NR_Linux32__llseek (__NR_Linux32 + 140) -#define __NR_Linux32_getdents (__NR_Linux32 + 141) -#define __NR_Linux32__newselect (__NR_Linux32 + 142) -#define __NR_Linux32_flock (__NR_Linux32 + 143) -#define __NR_Linux32_msync (__NR_Linux32 + 144) -#define __NR_Linux32_readv (__NR_Linux32 + 145) -#define __NR_Linux32_writev (__NR_Linux32 + 146) -#define __NR_Linux32_cacheflush (__NR_Linux32 + 147) -#define __NR_Linux32_cachectl (__NR_Linux32 + 148) -#define __NR_Linux32_sysmips (__NR_Linux32 + 149) -#define __NR_Linux32_unused150 (__NR_Linux32 + 150) -#define __NR_Linux32_getsid (__NR_Linux32 + 151) -#define __NR_Linux32_fdatasync (__NR_Linux32 + 152) -#define __NR_Linux32__sysctl (__NR_Linux32 + 153) -#define __NR_Linux32_mlock (__NR_Linux32 + 154) -#define __NR_Linux32_munlock (__NR_Linux32 + 155) -#define __NR_Linux32_mlockall (__NR_Linux32 + 156) -#define __NR_Linux32_munlockall (__NR_Linux32 + 157) -#define __NR_Linux32_sched_setparam (__NR_Linux32 + 158) -#define __NR_Linux32_sched_getparam (__NR_Linux32 + 159) -#define __NR_Linux32_sched_setscheduler (__NR_Linux32 + 160) -#define __NR_Linux32_sched_getscheduler (__NR_Linux32 + 161) -#define __NR_Linux32_sched_yield (__NR_Linux32 + 162) -#define __NR_Linux32_sched_get_priority_max (__NR_Linux32 + 163) -#define __NR_Linux32_sched_get_priority_min (__NR_Linux32 + 164) -#define __NR_Linux32_sched_rr_get_interval (__NR_Linux32 + 165) -#define __NR_Linux32_nanosleep (__NR_Linux32 + 166) -#define __NR_Linux32_mremap (__NR_Linux32 + 167) -#define __NR_Linux32_accept (__NR_Linux32 + 168) -#define __NR_Linux32_bind (__NR_Linux32 + 169) -#define __NR_Linux32_connect (__NR_Linux32 + 170) -#define __NR_Linux32_getpeername (__NR_Linux32 + 171) -#define __NR_Linux32_getsockname (__NR_Linux32 + 172) -#define __NR_Linux32_getsockopt (__NR_Linux32 + 173) -#define __NR_Linux32_listen (__NR_Linux32 + 174) -#define __NR_Linux32_recv (__NR_Linux32 + 175) -#define __NR_Linux32_recvfrom (__NR_Linux32 + 176) -#define __NR_Linux32_recvmsg (__NR_Linux32 + 177) -#define __NR_Linux32_send (__NR_Linux32 + 178) -#define __NR_Linux32_sendmsg (__NR_Linux32 + 179) -#define __NR_Linux32_sendto (__NR_Linux32 + 180) -#define __NR_Linux32_setsockopt (__NR_Linux32 + 181) -#define __NR_Linux32_shutdown (__NR_Linux32 + 182) -#define __NR_Linux32_socket (__NR_Linux32 + 183) -#define __NR_Linux32_socketpair (__NR_Linux32 + 184) -#define __NR_Linux32_setresuid (__NR_Linux32 + 185) -#define __NR_Linux32_getresuid (__NR_Linux32 + 186) -#define __NR_Linux32_query_module (__NR_Linux32 + 187) -#define __NR_Linux32_poll (__NR_Linux32 + 188) -#define __NR_Linux32_nfsservctl (__NR_Linux32 + 189) -#define __NR_Linux32_setresgid (__NR_Linux32 + 190) -#define __NR_Linux32_getresgid (__NR_Linux32 + 191) -#define __NR_Linux32_prctl (__NR_Linux32 + 192) -#define __NR_Linux32_rt_sigreturn (__NR_Linux32 + 193) -#define __NR_Linux32_rt_sigaction (__NR_Linux32 + 194) -#define __NR_Linux32_rt_sigprocmask (__NR_Linux32 + 195) -#define __NR_Linux32_rt_sigpending (__NR_Linux32 + 196) -#define __NR_Linux32_rt_sigtimedwait (__NR_Linux32 + 197) -#define __NR_Linux32_rt_sigqueueinfo (__NR_Linux32 + 198) -#define __NR_Linux32_rt_sigsuspend (__NR_Linux32 + 199) -#define __NR_Linux32_pread (__NR_Linux32 + 200) -#define __NR_Linux32_pwrite (__NR_Linux32 + 201) -#define __NR_Linux32_chown (__NR_Linux32 + 202) -#define __NR_Linux32_getcwd (__NR_Linux32 + 203) -#define __NR_Linux32_capget (__NR_Linux32 + 204) -#define __NR_Linux32_capset (__NR_Linux32 + 205) -#define __NR_Linux32_sigaltstack (__NR_Linux32 + 206) -#define __NR_Linux32_sendfile (__NR_Linux32 + 207) -#define __NR_Linux32_getpmsg (__NR_Linux32 + 208) -#define __NR_Linux32_putpmsg (__NR_Linux32 + 209) -#define __NR_Linux32_mmap2 (__NR_Linux32 + 210) -#define __NR_Linux32_truncate64 (__NR_Linux32 + 211) -#define __NR_Linux32_ftruncate64 (__NR_Linux32 + 212) -#define __NR_Linux32_stat64 (__NR_Linux32 + 213) -#define __NR_Linux32_lstat64 (__NR_Linux32 + 214) -#define __NR_Linux32_fstat64 (__NR_Linux32 + 215) -#define __NR_Linux32_root_pivot (__NR_Linux32 + 216) -#define __NR_Linux32_mincore (__NR_Linux32 + 217) -#define __NR_Linux32_madvise (__NR_Linux32 + 218) -#define __NR_Linux32_getdents64 (__NR_Linux32 + 219) -#define __NR_Linux32_fcntl64 (__NR_Linux32 + 220) +#define __NR_O32_Linux 4000 +#define __NR_O32_syscall (__NR_O32_Linux + 0) +#define __NR_O32_exit (__NR_O32_Linux + 1) +#define __NR_O32_fork (__NR_O32_Linux + 2) +#define __NR_O32_read (__NR_O32_Linux + 3) +#define __NR_O32_write (__NR_O32_Linux + 4) +#define __NR_O32_open (__NR_O32_Linux + 5) +#define __NR_O32_close (__NR_O32_Linux + 6) +#define __NR_O32_waitpid (__NR_O32_Linux + 7) +#define __NR_O32_creat (__NR_O32_Linux + 8) +#define __NR_O32_link (__NR_O32_Linux + 9) +#define __NR_O32_unlink (__NR_O32_Linux + 10) +#define __NR_O32_execve (__NR_O32_Linux + 11) +#define __NR_O32_chdir (__NR_O32_Linux + 12) +#define __NR_O32_time (__NR_O32_Linux + 13) +#define __NR_O32_mknod (__NR_O32_Linux + 14) +#define __NR_O32_chmod (__NR_O32_Linux + 15) +#define __NR_O32_lchown (__NR_O32_Linux + 16) +#define __NR_O32_break (__NR_O32_Linux + 17) +#define __NR_O32_unused18 (__NR_O32_Linux + 18) +#define __NR_O32_lseek (__NR_O32_Linux + 19) +#define __NR_O32_getpid (__NR_O32_Linux + 20) +#define __NR_O32_mount (__NR_O32_Linux + 21) +#define __NR_O32_umount (__NR_O32_Linux + 22) +#define __NR_O32_setuid (__NR_O32_Linux + 23) +#define __NR_O32_getuid (__NR_O32_Linux + 24) +#define __NR_O32_stime (__NR_O32_Linux + 25) +#define __NR_O32_ptrace (__NR_O32_Linux + 26) +#define __NR_O32_alarm (__NR_O32_Linux + 27) +#define __NR_O32_unused28 (__NR_O32_Linux + 28) +#define __NR_O32_pause (__NR_O32_Linux + 29) +#define __NR_O32_utime (__NR_O32_Linux + 30) +#define __NR_O32_stty (__NR_O32_Linux + 31) +#define __NR_O32_gtty (__NR_O32_Linux + 32) +#define __NR_O32_access (__NR_O32_Linux + 33) +#define __NR_O32_nice (__NR_O32_Linux + 34) +#define __NR_O32_ftime (__NR_O32_Linux + 35) +#define __NR_O32_sync (__NR_O32_Linux + 36) +#define __NR_O32_kill (__NR_O32_Linux + 37) +#define __NR_O32_rename (__NR_O32_Linux + 38) +#define __NR_O32_mkdir (__NR_O32_Linux + 39) +#define __NR_O32_rmdir (__NR_O32_Linux + 40) +#define __NR_O32_dup (__NR_O32_Linux + 41) +#define __NR_O32_pipe (__NR_O32_Linux + 42) +#define __NR_O32_times (__NR_O32_Linux + 43) +#define __NR_O32_prof (__NR_O32_Linux + 44) +#define __NR_O32_brk (__NR_O32_Linux + 45) +#define __NR_O32_setgid (__NR_O32_Linux + 46) +#define __NR_O32_getgid (__NR_O32_Linux + 47) +#define __NR_O32_signal (__NR_O32_Linux + 48) +#define __NR_O32_geteuid (__NR_O32_Linux + 49) +#define __NR_O32_getegid (__NR_O32_Linux + 50) +#define __NR_O32_acct (__NR_O32_Linux + 51) +#define __NR_O32_umount2 (__NR_O32_Linux + 52) +#define __NR_O32_lock (__NR_O32_Linux + 53) +#define __NR_O32_ioctl (__NR_O32_Linux + 54) +#define __NR_O32_fcntl (__NR_O32_Linux + 55) +#define __NR_O32_mpx (__NR_O32_Linux + 56) +#define __NR_O32_setpgid (__NR_O32_Linux + 57) +#define __NR_O32_ulimit (__NR_O32_Linux + 58) +#define __NR_O32_unused59 (__NR_O32_Linux + 59) +#define __NR_O32_umask (__NR_O32_Linux + 60) +#define __NR_O32_chroot (__NR_O32_Linux + 61) +#define __NR_O32_ustat (__NR_O32_Linux + 62) +#define __NR_O32_dup2 (__NR_O32_Linux + 63) +#define __NR_O32_getppid (__NR_O32_Linux + 64) +#define __NR_O32_getpgrp (__NR_O32_Linux + 65) +#define __NR_O32_setsid (__NR_O32_Linux + 66) +#define __NR_O32_sigaction (__NR_O32_Linux + 67) +#define __NR_O32_sgetmask (__NR_O32_Linux + 68) +#define __NR_O32_ssetmask (__NR_O32_Linux + 69) +#define __NR_O32_setreuid (__NR_O32_Linux + 70) +#define __NR_O32_setregid (__NR_O32_Linux + 71) +#define __NR_O32_sigsuspend (__NR_O32_Linux + 72) +#define __NR_O32_sigpending (__NR_O32_Linux + 73) +#define __NR_O32_sethostname (__NR_O32_Linux + 74) +#define __NR_O32_setrlimit (__NR_O32_Linux + 75) +#define __NR_O32_getrlimit (__NR_O32_Linux + 76) +#define __NR_O32_getrusage (__NR_O32_Linux + 77) +#define __NR_O32_gettimeofday (__NR_O32_Linux + 78) +#define __NR_O32_settimeofday (__NR_O32_Linux + 79) +#define __NR_O32_getgroups (__NR_O32_Linux + 80) +#define __NR_O32_setgroups (__NR_O32_Linux + 81) +#define __NR_O32_reserved82 (__NR_O32_Linux + 82) +#define __NR_O32_symlink (__NR_O32_Linux + 83) +#define __NR_O32_unused84 (__NR_O32_Linux + 84) +#define __NR_O32_readlink (__NR_O32_Linux + 85) +#define __NR_O32_uselib (__NR_O32_Linux + 86) +#define __NR_O32_swapon (__NR_O32_Linux + 87) +#define __NR_O32_reboot (__NR_O32_Linux + 88) +#define __NR_O32_readdir (__NR_O32_Linux + 89) +#define __NR_O32_mmap (__NR_O32_Linux + 90) +#define __NR_O32_munmap (__NR_O32_Linux + 91) +#define __NR_O32_truncate (__NR_O32_Linux + 92) +#define __NR_O32_ftruncate (__NR_O32_Linux + 93) +#define __NR_O32_fchmod (__NR_O32_Linux + 94) +#define __NR_O32_fchown (__NR_O32_Linux + 95) +#define __NR_O32_getpriority (__NR_O32_Linux + 96) +#define __NR_O32_setpriority (__NR_O32_Linux + 97) +#define __NR_O32_profil (__NR_O32_Linux + 98) +#define __NR_O32_statfs (__NR_O32_Linux + 99) +#define __NR_O32_fstatfs (__NR_O32_Linux + 100) +#define __NR_O32_ioperm (__NR_O32_Linux + 101) +#define __NR_O32_socketcall (__NR_O32_Linux + 102) +#define __NR_O32_syslog (__NR_O32_Linux + 103) +#define __NR_O32_setitimer (__NR_O32_Linux + 104) +#define __NR_O32_getitimer (__NR_O32_Linux + 105) +#define __NR_O32_stat (__NR_O32_Linux + 106) +#define __NR_O32_lstat (__NR_O32_Linux + 107) +#define __NR_O32_fstat (__NR_O32_Linux + 108) +#define __NR_O32_unused109 (__NR_O32_Linux + 109) +#define __NR_O32_iopl (__NR_O32_Linux + 110) +#define __NR_O32_vhangup (__NR_O32_Linux + 111) +#define __NR_O32_idle (__NR_O32_Linux + 112) +#define __NR_O32_vm86 (__NR_O32_Linux + 113) +#define __NR_O32_wait4 (__NR_O32_Linux + 114) +#define __NR_O32_swapoff (__NR_O32_Linux + 115) +#define __NR_O32_sysinfo (__NR_O32_Linux + 116) +#define __NR_O32_ipc (__NR_O32_Linux + 117) +#define __NR_O32_fsync (__NR_O32_Linux + 118) +#define __NR_O32_sigreturn (__NR_O32_Linux + 119) +#define __NR_O32_clone (__NR_O32_Linux + 120) +#define __NR_O32_setdomainname (__NR_O32_Linux + 121) +#define __NR_O32_uname (__NR_O32_Linux + 122) +#define __NR_O32_modify_ldt (__NR_O32_Linux + 123) +#define __NR_O32_adjtimex (__NR_O32_Linux + 124) +#define __NR_O32_mprotect (__NR_O32_Linux + 125) +#define __NR_O32_sigprocmask (__NR_O32_Linux + 126) +#define __NR_O32_create_module (__NR_O32_Linux + 127) +#define __NR_O32_init_module (__NR_O32_Linux + 128) +#define __NR_O32_delete_module (__NR_O32_Linux + 129) +#define __NR_O32_get_kernel_syms (__NR_O32_Linux + 130) +#define __NR_O32_quotactl (__NR_O32_Linux + 131) +#define __NR_O32_getpgid (__NR_O32_Linux + 132) +#define __NR_O32_fchdir (__NR_O32_Linux + 133) +#define __NR_O32_bdflush (__NR_O32_Linux + 134) +#define __NR_O32_sysfs (__NR_O32_Linux + 135) +#define __NR_O32_personality (__NR_O32_Linux + 136) +#define __NR_O32_afs_syscall (__NR_O32_Linux + 137) /* Syscall for Andrew File System */ +#define __NR_O32_setfsuid (__NR_O32_Linux + 138) +#define __NR_O32_setfsgid (__NR_O32_Linux + 139) +#define __NR_O32__llseek (__NR_O32_Linux + 140) +#define __NR_O32_getdents (__NR_O32_Linux + 141) +#define __NR_O32__newselect (__NR_O32_Linux + 142) +#define __NR_O32_flock (__NR_O32_Linux + 143) +#define __NR_O32_msync (__NR_O32_Linux + 144) +#define __NR_O32_readv (__NR_O32_Linux + 145) +#define __NR_O32_writev (__NR_O32_Linux + 146) +#define __NR_O32_cacheflush (__NR_O32_Linux + 147) +#define __NR_O32_cachectl (__NR_O32_Linux + 148) +#define __NR_O32_sysmips (__NR_O32_Linux + 149) +#define __NR_O32_unused150 (__NR_O32_Linux + 150) +#define __NR_O32_getsid (__NR_O32_Linux + 151) +#define __NR_O32_fdatasync (__NR_O32_Linux + 152) +#define __NR_O32__sysctl (__NR_O32_Linux + 153) +#define __NR_O32_mlock (__NR_O32_Linux + 154) +#define __NR_O32_munlock (__NR_O32_Linux + 155) +#define __NR_O32_mlockall (__NR_O32_Linux + 156) +#define __NR_O32_munlockall (__NR_O32_Linux + 157) +#define __NR_O32_sched_setparam (__NR_O32_Linux + 158) +#define __NR_O32_sched_getparam (__NR_O32_Linux + 159) +#define __NR_O32_sched_setscheduler (__NR_O32_Linux + 160) +#define __NR_O32_sched_getscheduler (__NR_O32_Linux + 161) +#define __NR_O32_sched_yield (__NR_O32_Linux + 162) +#define __NR_O32_sched_get_priority_max (__NR_O32_Linux + 163) +#define __NR_O32_sched_get_priority_min (__NR_O32_Linux + 164) +#define __NR_O32_sched_rr_get_interval (__NR_O32_Linux + 165) +#define __NR_O32_nanosleep (__NR_O32_Linux + 166) +#define __NR_O32_mremap (__NR_O32_Linux + 167) +#define __NR_O32_accept (__NR_O32_Linux + 168) +#define __NR_O32_bind (__NR_O32_Linux + 169) +#define __NR_O32_connect (__NR_O32_Linux + 170) +#define __NR_O32_getpeername (__NR_O32_Linux + 171) +#define __NR_O32_getsockname (__NR_O32_Linux + 172) +#define __NR_O32_getsockopt (__NR_O32_Linux + 173) +#define __NR_O32_listen (__NR_O32_Linux + 174) +#define __NR_O32_recv (__NR_O32_Linux + 175) +#define __NR_O32_recvfrom (__NR_O32_Linux + 176) +#define __NR_O32_recvmsg (__NR_O32_Linux + 177) +#define __NR_O32_send (__NR_O32_Linux + 178) +#define __NR_O32_sendmsg (__NR_O32_Linux + 179) +#define __NR_O32_sendto (__NR_O32_Linux + 180) +#define __NR_O32_setsockopt (__NR_O32_Linux + 181) +#define __NR_O32_shutdown (__NR_O32_Linux + 182) +#define __NR_O32_socket (__NR_O32_Linux + 183) +#define __NR_O32_socketpair (__NR_O32_Linux + 184) +#define __NR_O32_setresuid (__NR_O32_Linux + 185) +#define __NR_O32_getresuid (__NR_O32_Linux + 186) +#define __NR_O32_query_module (__NR_O32_Linux + 187) +#define __NR_O32_poll (__NR_O32_Linux + 188) +#define __NR_O32_nfsservctl (__NR_O32_Linux + 189) +#define __NR_O32_setresgid (__NR_O32_Linux + 190) +#define __NR_O32_getresgid (__NR_O32_Linux + 191) +#define __NR_O32_prctl (__NR_O32_Linux + 192) +#define __NR_O32_rt_sigreturn (__NR_O32_Linux + 193) +#define __NR_O32_rt_sigaction (__NR_O32_Linux + 194) +#define __NR_O32_rt_sigprocmask (__NR_O32_Linux + 195) +#define __NR_O32_rt_sigpending (__NR_O32_Linux + 196) +#define __NR_O32_rt_sigtimedwait (__NR_O32_Linux + 197) +#define __NR_O32_rt_sigqueueinfo (__NR_O32_Linux + 198) +#define __NR_O32_rt_sigsuspend (__NR_O32_Linux + 199) +#define __NR_O32_pread64 (__NR_O32_Linux + 200) +#define __NR_O32_pwrite64 (__NR_O32_Linux + 201) +#define __NR_O32_chown (__NR_O32_Linux + 202) +#define __NR_O32_getcwd (__NR_O32_Linux + 203) +#define __NR_O32_capget (__NR_O32_Linux + 204) +#define __NR_O32_capset (__NR_O32_Linux + 205) +#define __NR_O32_sigaltstack (__NR_O32_Linux + 206) +#define __NR_O32_sendfile (__NR_O32_Linux + 207) +#define __NR_O32_getpmsg (__NR_O32_Linux + 208) +#define __NR_O32_putpmsg (__NR_O32_Linux + 209) +#define __NR_O32_mmap2 (__NR_O32_Linux + 210) +#define __NR_O32_truncate64 (__NR_O32_Linux + 211) +#define __NR_O32_ftruncate64 (__NR_O32_Linux + 212) +#define __NR_O32_stat64 (__NR_O32_Linux + 213) +#define __NR_O32_lstat64 (__NR_O32_Linux + 214) +#define __NR_O32_fstat64 (__NR_O32_Linux + 215) +#define __NR_O32_root_pivot (__NR_O32_Linux + 216) +#define __NR_O32_mincore (__NR_O32_Linux + 217) +#define __NR_O32_madvise (__NR_O32_Linux + 218) +#define __NR_O32_getdents64 (__NR_O32_Linux + 219) +#define __NR_O32_fcntl64 (__NR_O32_Linux + 220) +#define __NR_O32_reserved221 (__NR_O32_Linux + 221) +#define __NR_O32_gettid (__NR_O32_Linux + 222) +#define __NR_O32_readahead (__NR_O32_Linux + 223) +#define __NR_O32_setxattr (__NR_O32_Linux + 224) +#define __NR_O32_lsetxattr (__NR_O32_Linux + 225) +#define __NR_O32_fsetxattr (__NR_O32_Linux + 226) +#define __NR_O32_getxattr (__NR_O32_Linux + 227) +#define __NR_O32_lgetxattr (__NR_O32_Linux + 228) +#define __NR_O32_fgetxattr (__NR_O32_Linux + 229) +#define __NR_O32_listxattr (__NR_O32_Linux + 230) +#define __NR_O32_llistxattr (__NR_O32_Linux + 231) +#define __NR_O32_flistxattr (__NR_O32_Linux + 232) +#define __NR_O32_removexattr (__NR_O32_Linux + 233) +#define __NR_O32_lremovexattr (__NR_O32_Linux + 234) +#define __NR_O32_fremovexattr (__NR_O32_Linux + 235) +#define __NR_O32_tkill (__NR_O32_Linux + 236) +#define __NR_O32_sendfile64 (__NR_O32_Linux + 237) +#define __NR_O32_futex (__NR_O32_Linux + 238) +#define __NR_O32_sched_setaffinity (__NR_O32_Linux + 239) +#define __NR_O32_sched_getaffinity (__NR_O32_Linux + 240) +#define __NR_O32_io_setup (__NR_O32_Linux + 241) +#define __NR_O32_io_destroy (__NR_O32_Linux + 242) +#define __NR_O32_io_getevents (__NR_O32_Linux + 243) +#define __NR_O32_io_submit (__NR_O32_Linux + 244) +#define __NR_O32_io_cancel (__NR_O32_Linux + 245) +#define __NR_O32_exit_group (__NR_O32_Linux + 246) +#define __NR_O32_lookup_dcookie (__NR_O32_Linux + 247) +#define __NR_O32_epoll_create (__NR_O32_Linux + 248) +#define __NR_O32_epoll_ctl (__NR_O32_Linux + 249) +#define __NR_O32_epoll_wait (__NR_O32_Linux + 250) +#define __NR_O32_remap_file_page (__NR_O32_Linux + 251) +#define __NR_O32_set_tid_address (__NR_O32_Linux + 252) +#define __NR_O32_restart_syscall (__NR_O32_Linux + 253) +#define __NR_O32_fadvise64 (__NR_O32_Linux + 254) +#define __NR_O32_statfs64 (__NR_O32_Linux + 255) +#define __NR_O32_fstatfs64 (__NR_O32_Linux + 256) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux32_syscalls 220 +#define __NR_O32_Linux_syscalls 256 + /* * Linux 64-bit syscalls are in the range from 5000 to 5999. */ #define __NR_Linux 5000 -#define __NR_syscall (__NR_Linux + 0) -#define __NR_exit (__NR_Linux + 1) -#define __NR_fork (__NR_Linux + 2) -#define __NR_read (__NR_Linux + 3) -#define __NR_write (__NR_Linux + 4) -#define __NR_open (__NR_Linux + 5) -#define __NR_close (__NR_Linux + 6) -#define __NR_waitpid (__NR_Linux + 7) -#define __NR_creat (__NR_Linux + 8) -#define __NR_link (__NR_Linux + 9) -#define __NR_unlink (__NR_Linux + 10) -#define __NR_execve (__NR_Linux + 11) -#define __NR_chdir (__NR_Linux + 12) -#define __NR_time (__NR_Linux + 13) -#define __NR_mknod (__NR_Linux + 14) -#define __NR_chmod (__NR_Linux + 15) -#define __NR_lchown (__NR_Linux + 16) -#define __NR_break (__NR_Linux + 17) -#define __NR_oldstat (__NR_Linux + 18) -#define __NR_lseek (__NR_Linux + 19) -#define __NR_getpid (__NR_Linux + 20) -#define __NR_mount (__NR_Linux + 21) -#define __NR_umount (__NR_Linux + 22) -#define __NR_setuid (__NR_Linux + 23) -#define __NR_getuid (__NR_Linux + 24) -#define __NR_stime (__NR_Linux + 25) -#define __NR_ptrace (__NR_Linux + 26) -#define __NR_alarm (__NR_Linux + 27) -#define __NR_oldfstat (__NR_Linux + 28) -#define __NR_pause (__NR_Linux + 29) -#define __NR_utime (__NR_Linux + 30) -#define __NR_stty (__NR_Linux + 31) -#define __NR_gtty (__NR_Linux + 32) -#define __NR_access (__NR_Linux + 33) -#define __NR_nice (__NR_Linux + 34) -#define __NR_ftime (__NR_Linux + 35) -#define __NR_sync (__NR_Linux + 36) -#define __NR_kill (__NR_Linux + 37) -#define __NR_rename (__NR_Linux + 38) -#define __NR_mkdir (__NR_Linux + 39) -#define __NR_rmdir (__NR_Linux + 40) -#define __NR_dup (__NR_Linux + 41) -#define __NR_pipe (__NR_Linux + 42) -#define __NR_times (__NR_Linux + 43) -#define __NR_prof (__NR_Linux + 44) -#define __NR_brk (__NR_Linux + 45) -#define __NR_setgid (__NR_Linux + 46) -#define __NR_getgid (__NR_Linux + 47) -#define __NR_signal (__NR_Linux + 48) -#define __NR_geteuid (__NR_Linux + 49) -#define __NR_getegid (__NR_Linux + 50) -#define __NR_acct (__NR_Linux + 51) -#define __NR_umount2 (__NR_Linux + 52) -#define __NR_lock (__NR_Linux + 53) -#define __NR_ioctl (__NR_Linux + 54) -#define __NR_fcntl (__NR_Linux + 55) -#define __NR_mpx (__NR_Linux + 56) -#define __NR_setpgid (__NR_Linux + 57) -#define __NR_ulimit (__NR_Linux + 58) -#define __NR_unused59 (__NR_Linux + 59) -#define __NR_umask (__NR_Linux + 60) -#define __NR_chroot (__NR_Linux + 61) -#define __NR_ustat (__NR_Linux + 62) -#define __NR_dup2 (__NR_Linux + 63) -#define __NR_getppid (__NR_Linux + 64) -#define __NR_getpgrp (__NR_Linux + 65) -#define __NR_setsid (__NR_Linux + 66) -#define __NR_sigaction (__NR_Linux + 67) -#define __NR_sgetmask (__NR_Linux + 68) -#define __NR_ssetmask (__NR_Linux + 69) -#define __NR_setreuid (__NR_Linux + 70) -#define __NR_setregid (__NR_Linux + 71) -#define __NR_sigsuspend (__NR_Linux + 72) -#define __NR_sigpending (__NR_Linux + 73) -#define __NR_sethostname (__NR_Linux + 74) -#define __NR_setrlimit (__NR_Linux + 75) -#define __NR_getrlimit (__NR_Linux + 76) -#define __NR_getrusage (__NR_Linux + 77) -#define __NR_gettimeofday (__NR_Linux + 78) -#define __NR_settimeofday (__NR_Linux + 79) -#define __NR_getgroups (__NR_Linux + 80) -#define __NR_setgroups (__NR_Linux + 81) -#define __NR_reserved82 (__NR_Linux + 82) -#define __NR_symlink (__NR_Linux + 83) -#define __NR_oldlstat (__NR_Linux + 84) -#define __NR_readlink (__NR_Linux + 85) -#define __NR_uselib (__NR_Linux + 86) -#define __NR_swapon (__NR_Linux + 87) -#define __NR_reboot (__NR_Linux + 88) -#define __NR_readdir (__NR_Linux + 89) -#define __NR_mmap (__NR_Linux + 90) -#define __NR_munmap (__NR_Linux + 91) -#define __NR_truncate (__NR_Linux + 92) -#define __NR_ftruncate (__NR_Linux + 93) -#define __NR_fchmod (__NR_Linux + 94) -#define __NR_fchown (__NR_Linux + 95) -#define __NR_getpriority (__NR_Linux + 96) -#define __NR_setpriority (__NR_Linux + 97) -#define __NR_profil (__NR_Linux + 98) -#define __NR_statfs (__NR_Linux + 99) -#define __NR_fstatfs (__NR_Linux + 100) -#define __NR_ioperm (__NR_Linux + 101) -#define __NR_socketcall (__NR_Linux + 102) -#define __NR_syslog (__NR_Linux + 103) -#define __NR_setitimer (__NR_Linux + 104) -#define __NR_getitimer (__NR_Linux + 105) -#define __NR_stat (__NR_Linux + 106) -#define __NR_lstat (__NR_Linux + 107) -#define __NR_fstat (__NR_Linux + 108) -#define __NR_unused109 (__NR_Linux + 109) -#define __NR_iopl (__NR_Linux + 110) -#define __NR_vhangup (__NR_Linux + 111) -#define __NR_idle (__NR_Linux + 112) -#define __NR_vm86 (__NR_Linux + 113) -#define __NR_wait4 (__NR_Linux + 114) -#define __NR_swapoff (__NR_Linux + 115) -#define __NR_sysinfo (__NR_Linux + 116) -#define __NR_ipc (__NR_Linux + 117) -#define __NR_fsync (__NR_Linux + 118) -#define __NR_sigreturn (__NR_Linux + 119) -#define __NR_clone (__NR_Linux + 120) -#define __NR_setdomainname (__NR_Linux + 121) -#define __NR_uname (__NR_Linux + 122) -#define __NR_modify_ldt (__NR_Linux + 123) -#define __NR_adjtimex (__NR_Linux + 124) -#define __NR_mprotect (__NR_Linux + 125) -#define __NR_sigprocmask (__NR_Linux + 126) -#define __NR_create_module (__NR_Linux + 127) -#define __NR_init_module (__NR_Linux + 128) -#define __NR_delete_module (__NR_Linux + 129) -#define __NR_get_kernel_syms (__NR_Linux + 130) -#define __NR_quotactl (__NR_Linux + 131) -#define __NR_getpgid (__NR_Linux + 132) -#define __NR_fchdir (__NR_Linux + 133) -#define __NR_bdflush (__NR_Linux + 134) -#define __NR_sysfs (__NR_Linux + 135) -#define __NR_personality (__NR_Linux + 136) -#define __NR_afs_syscall (__NR_Linux + 137) /* Syscall for Andrew File System */ -#define __NR_setfsuid (__NR_Linux + 138) -#define __NR_setfsgid (__NR_Linux + 139) -#define __NR__llseek (__NR_Linux + 140) -#define __NR_getdents (__NR_Linux + 141) -#define __NR__newselect (__NR_Linux + 142) -#define __NR_flock (__NR_Linux + 143) -#define __NR_msync (__NR_Linux + 144) -#define __NR_readv (__NR_Linux + 145) -#define __NR_writev (__NR_Linux + 146) -#define __NR_cacheflush (__NR_Linux + 147) -#define __NR_cachectl (__NR_Linux + 148) -#define __NR_sysmips (__NR_Linux + 149) -#define __NR_unused150 (__NR_Linux + 150) -#define __NR_getsid (__NR_Linux + 151) -#define __NR_fdatasync (__NR_Linux + 152) -#define __NR__sysctl (__NR_Linux + 153) -#define __NR_mlock (__NR_Linux + 154) -#define __NR_munlock (__NR_Linux + 155) -#define __NR_mlockall (__NR_Linux + 156) -#define __NR_munlockall (__NR_Linux + 157) -#define __NR_sched_setparam (__NR_Linux + 158) -#define __NR_sched_getparam (__NR_Linux + 159) -#define __NR_sched_setscheduler (__NR_Linux + 160) -#define __NR_sched_getscheduler (__NR_Linux + 161) -#define __NR_sched_yield (__NR_Linux + 162) -#define __NR_sched_get_priority_max (__NR_Linux + 163) -#define __NR_sched_get_priority_min (__NR_Linux + 164) -#define __NR_sched_rr_get_interval (__NR_Linux + 165) -#define __NR_nanosleep (__NR_Linux + 166) -#define __NR_mremap (__NR_Linux + 167) -#define __NR_accept (__NR_Linux + 168) -#define __NR_bind (__NR_Linux + 169) -#define __NR_connect (__NR_Linux + 170) -#define __NR_getpeername (__NR_Linux + 171) -#define __NR_getsockname (__NR_Linux + 172) -#define __NR_getsockopt (__NR_Linux + 173) -#define __NR_listen (__NR_Linux + 174) -#define __NR_recv (__NR_Linux + 175) -#define __NR_recvfrom (__NR_Linux + 176) -#define __NR_recvmsg (__NR_Linux + 177) -#define __NR_send (__NR_Linux + 178) -#define __NR_sendmsg (__NR_Linux + 179) -#define __NR_sendto (__NR_Linux + 180) -#define __NR_setsockopt (__NR_Linux + 181) -#define __NR_shutdown (__NR_Linux + 182) -#define __NR_socket (__NR_Linux + 183) -#define __NR_socketpair (__NR_Linux + 184) -#define __NR_setresuid (__NR_Linux + 185) -#define __NR_getresuid (__NR_Linux + 186) -#define __NR_query_module (__NR_Linux + 187) -#define __NR_poll (__NR_Linux + 188) -#define __NR_nfsservctl (__NR_Linux + 189) -#define __NR_setresgid (__NR_Linux + 190) -#define __NR_getresgid (__NR_Linux + 191) -#define __NR_prctl (__NR_Linux + 192) -#define __NR_rt_sigreturn (__NR_Linux + 193) -#define __NR_rt_sigaction (__NR_Linux + 194) -#define __NR_rt_sigprocmask (__NR_Linux + 195) -#define __NR_rt_sigpending (__NR_Linux + 196) -#define __NR_rt_sigtimedwait (__NR_Linux + 197) -#define __NR_rt_sigqueueinfo (__NR_Linux + 198) -#define __NR_rt_sigsuspend (__NR_Linux + 199) -#define __NR_pread64 (__NR_Linux + 200) -#define __NR_pwrite64 (__NR_Linux + 201) -#define __NR_chown (__NR_Linux + 202) -#define __NR_getcwd (__NR_Linux + 203) -#define __NR_capget (__NR_Linux + 204) -#define __NR_capset (__NR_Linux + 205) -#define __NR_sigaltstack (__NR_Linux + 206) -#define __NR_sendfile (__NR_Linux + 207) -#define __NR_getpmsg (__NR_Linux + 208) -#define __NR_putpmsg (__NR_Linux + 209) -#define __NR_root_pivot (__NR_Linux + 210) -#define __NR_mincore (__NR_Linux + 211) -#define __NR_madvise (__NR_Linux + 212) -#define __NR_getdents64 (__NR_Linux + 213) -#define __NR_gettid (__NR_Linux + 214) -#define __NR_tkill (__NR_Linux + 215) +#define __NR_read (__NR_Linux + 0) +#define __NR_write (__NR_Linux + 1) +#define __NR_open (__NR_Linux + 2) +#define __NR_close (__NR_Linux + 3) +#define __NR_stat (__NR_Linux + 4) +#define __NR_fstat (__NR_Linux + 5) +#define __NR_lstat (__NR_Linux + 6) +#define __NR_poll (__NR_Linux + 7) +#define __NR_lseek (__NR_Linux + 8) +#define __NR_mmap (__NR_Linux + 9) +#define __NR_mprotect (__NR_Linux + 10) +#define __NR_munmap (__NR_Linux + 11) +#define __NR_brk (__NR_Linux + 12) +#define __NR_rt_sigaction (__NR_Linux + 13) +#define __NR_rt_sigprocmask (__NR_Linux + 14) +#define __NR_ioctl (__NR_Linux + 15) +#define __NR_pread64 (__NR_Linux + 16) +#define __NR_pwrite64 (__NR_Linux + 17) +#define __NR_readv (__NR_Linux + 18) +#define __NR_writev (__NR_Linux + 19) +#define __NR_access (__NR_Linux + 20) +#define __NR_pipe (__NR_Linux + 21) +#define __NR__newselect (__NR_Linux + 22) +#define __NR_sched_yield (__NR_Linux + 23) +#define __NR_mremap (__NR_Linux + 24) +#define __NR_msync (__NR_Linux + 25) +#define __NR_mincore (__NR_Linux + 26) +#define __NR_madvise (__NR_Linux + 27) +#define __NR_shmget (__NR_Linux + 28) +#define __NR_shmat (__NR_Linux + 29) +#define __NR_shmctl (__NR_Linux + 30) +#define __NR_dup (__NR_Linux + 31) +#define __NR_dup2 (__NR_Linux + 32) +#define __NR_pause (__NR_Linux + 33) +#define __NR_nanosleep (__NR_Linux + 34) +#define __NR_getitimer (__NR_Linux + 35) +#define __NR_setitimer (__NR_Linux + 36) +#define __NR_alarm (__NR_Linux + 37) +#define __NR_getpid (__NR_Linux + 38) +#define __NR_sendfile (__NR_Linux + 39) +#define __NR_socket (__NR_Linux + 40) +#define __NR_connect (__NR_Linux + 41) +#define __NR_accept (__NR_Linux + 42) +#define __NR_sendto (__NR_Linux + 43) +#define __NR_recvfrom (__NR_Linux + 44) +#define __NR_sendmsg (__NR_Linux + 45) +#define __NR_recvmsg (__NR_Linux + 46) +#define __NR_shutdown (__NR_Linux + 47) +#define __NR_bind (__NR_Linux + 48) +#define __NR_listen (__NR_Linux + 49) +#define __NR_getsockname (__NR_Linux + 50) +#define __NR_getpeername (__NR_Linux + 51) +#define __NR_socketpair (__NR_Linux + 52) +#define __NR_setsockopt (__NR_Linux + 53) +#define __NR_getsockopt (__NR_Linux + 54) +#define __NR_clone (__NR_Linux + 55) +#define __NR_fork (__NR_Linux + 56) +#define __NR_execve (__NR_Linux + 57) +#define __NR_exit (__NR_Linux + 58) +#define __NR_wait4 (__NR_Linux + 59) +#define __NR_kill (__NR_Linux + 60) +#define __NR_uname (__NR_Linux + 61) +#define __NR_semget (__NR_Linux + 62) +#define __NR_semop (__NR_Linux + 63) +#define __NR_semctl (__NR_Linux + 64) +#define __NR_shmdt (__NR_Linux + 65) +#define __NR_msgget (__NR_Linux + 66) +#define __NR_msgsnd (__NR_Linux + 67) +#define __NR_msgrcv (__NR_Linux + 68) +#define __NR_msgctl (__NR_Linux + 69) +#define __NR_fcntl (__NR_Linux + 70) +#define __NR_flock (__NR_Linux + 71) +#define __NR_fsync (__NR_Linux + 72) +#define __NR_fdatasync (__NR_Linux + 73) +#define __NR_truncate (__NR_Linux + 74) +#define __NR_ftruncate (__NR_Linux + 75) +#define __NR_getdents (__NR_Linux + 76) +#define __NR_getcwd (__NR_Linux + 77) +#define __NR_chdir (__NR_Linux + 78) +#define __NR_fchdir (__NR_Linux + 79) +#define __NR_rename (__NR_Linux + 80) +#define __NR_mkdir (__NR_Linux + 81) +#define __NR_rmdir (__NR_Linux + 82) +#define __NR_creat (__NR_Linux + 83) +#define __NR_link (__NR_Linux + 84) +#define __NR_unlink (__NR_Linux + 85) +#define __NR_symlink (__NR_Linux + 86) +#define __NR_readlink (__NR_Linux + 87) +#define __NR_chmod (__NR_Linux + 88) +#define __NR_fchmod (__NR_Linux + 89) +#define __NR_chown (__NR_Linux + 90) +#define __NR_fchown (__NR_Linux + 91) +#define __NR_lchown (__NR_Linux + 92) +#define __NR_umask (__NR_Linux + 93) +#define __NR_gettimeofday (__NR_Linux + 94) +#define __NR_getrlimit (__NR_Linux + 95) +#define __NR_getrusage (__NR_Linux + 96) +#define __NR_sysinfo (__NR_Linux + 97) +#define __NR_times (__NR_Linux + 98) +#define __NR_ptrace (__NR_Linux + 99) +#define __NR_getuid (__NR_Linux + 100) +#define __NR_syslog (__NR_Linux + 101) +#define __NR_getgid (__NR_Linux + 102) +#define __NR_setuid (__NR_Linux + 103) +#define __NR_setgid (__NR_Linux + 104) +#define __NR_geteuid (__NR_Linux + 105) +#define __NR_getegid (__NR_Linux + 106) +#define __NR_setpgid (__NR_Linux + 107) +#define __NR_getppid (__NR_Linux + 108) +#define __NR_getpgrp (__NR_Linux + 109) +#define __NR_setsid (__NR_Linux + 110) +#define __NR_setreuid (__NR_Linux + 111) +#define __NR_setregid (__NR_Linux + 112) +#define __NR_getgroups (__NR_Linux + 113) +#define __NR_setgroups (__NR_Linux + 114) +#define __NR_setresuid (__NR_Linux + 115) +#define __NR_getresuid (__NR_Linux + 116) +#define __NR_setresgid (__NR_Linux + 117) +#define __NR_getresgid (__NR_Linux + 118) +#define __NR_getpgid (__NR_Linux + 119) +#define __NR_setfsuid (__NR_Linux + 120) +#define __NR_setfsgid (__NR_Linux + 121) +#define __NR_getsid (__NR_Linux + 122) +#define __NR_capget (__NR_Linux + 123) +#define __NR_capset (__NR_Linux + 124) +#define __NR_rt_sigpending (__NR_Linux + 125) +#define __NR_rt_sigtimedwait (__NR_Linux + 126) +#define __NR_rt_sigqueueinfo (__NR_Linux + 127) +#define __NR_rt_sigsuspend (__NR_Linux + 128) +#define __NR_sigaltstack (__NR_Linux + 129) +#define __NR_utime (__NR_Linux + 130) +#define __NR_mknod (__NR_Linux + 131) +#define __NR_personality (__NR_Linux + 132) +#define __NR_ustat (__NR_Linux + 133) +#define __NR_statfs (__NR_Linux + 134) +#define __NR_fstatfs (__NR_Linux + 135) +#define __NR_sysfs (__NR_Linux + 136) +#define __NR_getpriority (__NR_Linux + 137) +#define __NR_setpriority (__NR_Linux + 138) +#define __NR_sched_setparam (__NR_Linux + 139) +#define __NR_sched_getparam (__NR_Linux + 140) +#define __NR_sched_setscheduler (__NR_Linux + 141) +#define __NR_sched_getscheduler (__NR_Linux + 142) +#define __NR_sched_get_priority_max (__NR_Linux + 143) +#define __NR_sched_get_priority_min (__NR_Linux + 144) +#define __NR_sched_rr_get_interval (__NR_Linux + 145) +#define __NR_mlock (__NR_Linux + 146) +#define __NR_munlock (__NR_Linux + 147) +#define __NR_mlockall (__NR_Linux + 148) +#define __NR_munlockall (__NR_Linux + 149) +#define __NR_vhangup (__NR_Linux + 150) +#define __NR_pivot_root (__NR_Linux + 151) +#define __NR__sysctl (__NR_Linux + 152) +#define __NR_prctl (__NR_Linux + 153) +#define __NR_adjtimex (__NR_Linux + 154) +#define __NR_setrlimit (__NR_Linux + 155) +#define __NR_chroot (__NR_Linux + 156) +#define __NR_sync (__NR_Linux + 157) +#define __NR_acct (__NR_Linux + 158) +#define __NR_settimeofday (__NR_Linux + 159) +#define __NR_mount (__NR_Linux + 160) +#define __NR_umount2 (__NR_Linux + 161) +#define __NR_swapon (__NR_Linux + 162) +#define __NR_swapoff (__NR_Linux + 163) +#define __NR_reboot (__NR_Linux + 164) +#define __NR_sethostname (__NR_Linux + 165) +#define __NR_setdomainname (__NR_Linux + 166) +#define __NR_create_module (__NR_Linux + 167) +#define __NR_init_module (__NR_Linux + 168) +#define __NR_delete_module (__NR_Linux + 169) +#define __NR_get_kernel_syms (__NR_Linux + 170) +#define __NR_query_module (__NR_Linux + 171) +#define __NR_quotactl (__NR_Linux + 172) +#define __NR_nfsservctl (__NR_Linux + 173) +#define __NR_getpmsg (__NR_Linux + 174) +#define __NR_putpmsg (__NR_Linux + 175) +#define __NR_afs_syscall (__NR_Linux + 176) +#define __NR_reserved177 (__NR_Linux + 177) +#define __NR_gettid (__NR_Linux + 178) +#define __NR_readahead (__NR_Linux + 179) +#define __NR_setxattr (__NR_Linux + 180) +#define __NR_lsetxattr (__NR_Linux + 181) +#define __NR_fsetxattr (__NR_Linux + 182) +#define __NR_getxattr (__NR_Linux + 183) +#define __NR_lgetxattr (__NR_Linux + 184) +#define __NR_fgetxattr (__NR_Linux + 185) +#define __NR_listxattr (__NR_Linux + 186) +#define __NR_llistxattr (__NR_Linux + 187) +#define __NR_flistxattr (__NR_Linux + 188) +#define __NR_removexattr (__NR_Linux + 189) +#define __NR_lremovexattr (__NR_Linux + 190) +#define __NR_fremovexattr (__NR_Linux + 191) +#define __NR_tkill (__NR_Linux + 192) +#define __NR_time (__NR_Linux + 193) +#define __NR_futex (__NR_Linux + 194) +#define __NR_sched_setaffinity (__NR_Linux + 195) +#define __NR_sched_getaffinity (__NR_Linux + 196) +#define __NR_cacheflush (__NR_Linux + 197) +#define __NR_cachectl (__NR_Linux + 198) +#define __NR_sysmips (__NR_Linux + 199) +#define __NR_io_setup (__NR_Linux + 200) +#define __NR_io_destroy (__NR_Linux + 201) +#define __NR_io_getevents (__NR_Linux + 202) +#define __NR_io_submit (__NR_Linux + 203) +#define __NR_io_cancel (__NR_Linux + 204) +#define __NR_exit_group (__NR_Linux + 205) +#define __NR_lookup_dcookie (__NR_Linux + 206) +#define __NR_epoll_create (__NR_Linux + 207) +#define __NR_epoll_ctl (__NR_Linux + 208) +#define __NR_epoll_wait (__NR_Linux + 209) +#define __NR_remap_file_page (__NR_Linux + 210) +#define __NR_rt_sigreturn (__NR_Linux + 211) +#define __NR_set_tid_address (__NR_Linux + 212) +#define __NR_restart_syscall (__NR_Linux + 213) +#define __NR_semtimedop (__NR_Linux + 214) +#define __NR_fadvise64 (__NR_Linux + 215) /* * Offset of the last Linux flavoured syscall */ #define __NR_Linux_syscalls 215 -#ifndef _LANGUAGE_ASSEMBLY +/* + * Linux N32 syscalls are in the range from 6000 to 6999. + */ +#define __NR_N32_Linux 6000 +#define __NR_N32_read (__NR_N32_Linux + 0) +#define __NR_N32_write (__NR_N32_Linux + 1) +#define __NR_N32_open (__NR_N32_Linux + 2) +#define __NR_N32_close (__NR_N32_Linux + 3) +#define __NR_N32_stat (__NR_N32_Linux + 4) +#define __NR_N32_fstat (__NR_N32_Linux + 5) +#define __NR_N32_lstat (__NR_N32_Linux + 6) +#define __NR_N32_poll (__NR_N32_Linux + 7) +#define __NR_N32_lseek (__NR_N32_Linux + 8) +#define __NR_N32_mmap (__NR_N32_Linux + 9) +#define __NR_N32_mprotect (__NR_N32_Linux + 10) +#define __NR_N32_munmap (__NR_N32_Linux + 11) +#define __NR_N32_brk (__NR_N32_Linux + 12) +#define __NR_N32_rt_sigaction (__NR_N32_Linux + 13) +#define __NR_N32_rt_sigprocmask (__NR_N32_Linux + 14) +#define __NR_N32_ioctl (__NR_N32_Linux + 15) +#define __NR_N32_pread64 (__NR_N32_Linux + 16) +#define __NR_N32_pwrite64 (__NR_N32_Linux + 17) +#define __NR_N32_readv (__NR_N32_Linux + 18) +#define __NR_N32_writev (__NR_N32_Linux + 19) +#define __NR_N32_access (__NR_N32_Linux + 20) +#define __NR_N32_pipe (__NR_N32_Linux + 21) +#define __NR_N32__newselect (__NR_N32_Linux + 22) +#define __NR_N32_sched_yield (__NR_N32_Linux + 23) +#define __NR_N32_mremap (__NR_N32_Linux + 24) +#define __NR_N32_msync (__NR_N32_Linux + 25) +#define __NR_N32_mincore (__NR_N32_Linux + 26) +#define __NR_N32_madvise (__NR_N32_Linux + 27) +#define __NR_N32_shmget (__NR_N32_Linux + 28) +#define __NR_N32_shmat (__NR_N32_Linux + 29) +#define __NR_N32_shmctl (__NR_N32_Linux + 30) +#define __NR_N32_dup (__NR_N32_Linux + 31) +#define __NR_N32_dup2 (__NR_N32_Linux + 32) +#define __NR_N32_pause (__NR_N32_Linux + 33) +#define __NR_N32_nanosleep (__NR_N32_Linux + 34) +#define __NR_N32_getitimer (__NR_N32_Linux + 35) +#define __NR_N32_setitimer (__NR_N32_Linux + 36) +#define __NR_N32_alarm (__NR_N32_Linux + 37) +#define __NR_N32_getpid (__NR_N32_Linux + 38) +#define __NR_N32_sendfile (__NR_N32_Linux + 39) +#define __NR_N32_socket (__NR_N32_Linux + 40) +#define __NR_N32_connect (__NR_N32_Linux + 41) +#define __NR_N32_accept (__NR_N32_Linux + 42) +#define __NR_N32_sendto (__NR_N32_Linux + 43) +#define __NR_N32_recvfrom (__NR_N32_Linux + 44) +#define __NR_N32_sendmsg (__NR_N32_Linux + 45) +#define __NR_N32_recvmsg (__NR_N32_Linux + 46) +#define __NR_N32_shutdown (__NR_N32_Linux + 47) +#define __NR_N32_bind (__NR_N32_Linux + 48) +#define __NR_N32_listen (__NR_N32_Linux + 49) +#define __NR_N32_getsockname (__NR_N32_Linux + 50) +#define __NR_N32_getpeername (__NR_N32_Linux + 51) +#define __NR_N32_socketpair (__NR_N32_Linux + 52) +#define __NR_N32_setsockopt (__NR_N32_Linux + 53) +#define __NR_N32_getsockopt (__NR_N32_Linux + 54) +#define __NR_N32_clone (__NR_N32_Linux + 55) +#define __NR_N32_fork (__NR_N32_Linux + 56) +#define __NR_N32_execve (__NR_N32_Linux + 57) +#define __NR_N32_exit (__NR_N32_Linux + 58) +#define __NR_N32_wait4 (__NR_N32_Linux + 59) +#define __NR_N32_kill (__NR_N32_Linux + 60) +#define __NR_N32_uname (__NR_N32_Linux + 61) +#define __NR_N32_semget (__NR_N32_Linux + 62) +#define __NR_N32_semop (__NR_N32_Linux + 63) +#define __NR_N32_semctl (__NR_N32_Linux + 64) +#define __NR_N32_shmdt (__NR_N32_Linux + 65) +#define __NR_N32_msgget (__NR_N32_Linux + 66) +#define __NR_N32_msgsnd (__NR_N32_Linux + 67) +#define __NR_N32_msgrcv (__NR_N32_Linux + 68) +#define __NR_N32_msgctl (__NR_N32_Linux + 69) +#define __NR_N32_fcntl (__NR_N32_Linux + 70) +#define __NR_N32_flock (__NR_N32_Linux + 71) +#define __NR_N32_fsync (__NR_N32_Linux + 72) +#define __NR_N32_fdatasync (__NR_N32_Linux + 73) +#define __NR_N32_truncate (__NR_N32_Linux + 74) +#define __NR_N32_ftruncate (__NR_N32_Linux + 75) +#define __NR_N32_getdents (__NR_N32_Linux + 76) +#define __NR_N32_getcwd (__NR_N32_Linux + 77) +#define __NR_N32_chdir (__NR_N32_Linux + 78) +#define __NR_N32_fchdir (__NR_N32_Linux + 79) +#define __NR_N32_rename (__NR_N32_Linux + 80) +#define __NR_N32_mkdir (__NR_N32_Linux + 81) +#define __NR_N32_rmdir (__NR_N32_Linux + 82) +#define __NR_N32_creat (__NR_N32_Linux + 83) +#define __NR_N32_link (__NR_N32_Linux + 84) +#define __NR_N32_unlink (__NR_N32_Linux + 85) +#define __NR_N32_symlink (__NR_N32_Linux + 86) +#define __NR_N32_readlink (__NR_N32_Linux + 87) +#define __NR_N32_chmod (__NR_N32_Linux + 88) +#define __NR_N32_fchmod (__NR_N32_Linux + 89) +#define __NR_N32_chown (__NR_N32_Linux + 90) +#define __NR_N32_fchown (__NR_N32_Linux + 91) +#define __NR_N32_lchown (__NR_N32_Linux + 92) +#define __NR_N32_umask (__NR_N32_Linux + 93) +#define __NR_N32_gettimeofday (__NR_N32_Linux + 94) +#define __NR_N32_getrlimit (__NR_N32_Linux + 95) +#define __NR_N32_getrusage (__NR_N32_Linux + 96) +#define __NR_N32_sysinfo (__NR_N32_Linux + 97) +#define __NR_N32_times (__NR_N32_Linux + 98) +#define __NR_N32_ptrace (__NR_N32_Linux + 99) +#define __NR_N32_getuid (__NR_N32_Linux + 100) +#define __NR_N32_syslog (__NR_N32_Linux + 101) +#define __NR_N32_getgid (__NR_N32_Linux + 102) +#define __NR_N32_setuid (__NR_N32_Linux + 103) +#define __NR_N32_setgid (__NR_N32_Linux + 104) +#define __NR_N32_geteuid (__NR_N32_Linux + 105) +#define __NR_N32_getegid (__NR_N32_Linux + 106) +#define __NR_N32_setpgid (__NR_N32_Linux + 107) +#define __NR_N32_getppid (__NR_N32_Linux + 108) +#define __NR_N32_getpgrp (__NR_N32_Linux + 109) +#define __NR_N32_setsid (__NR_N32_Linux + 110) +#define __NR_N32_setreuid (__NR_N32_Linux + 111) +#define __NR_N32_setregid (__NR_N32_Linux + 112) +#define __NR_N32_getgroups (__NR_N32_Linux + 113) +#define __NR_N32_setgroups (__NR_N32_Linux + 114) +#define __NR_N32_setresuid (__NR_N32_Linux + 115) +#define __NR_N32_getresuid (__NR_N32_Linux + 116) +#define __NR_N32_setresgid (__NR_N32_Linux + 117) +#define __NR_N32_getresgid (__NR_N32_Linux + 118) +#define __NR_N32_getpgid (__NR_N32_Linux + 119) +#define __NR_N32_setfsuid (__NR_N32_Linux + 120) +#define __NR_N32_setfsgid (__NR_N32_Linux + 121) +#define __NR_N32_getsid (__NR_N32_Linux + 122) +#define __NR_N32_capget (__NR_N32_Linux + 123) +#define __NR_N32_capset (__NR_N32_Linux + 124) +#define __NR_N32_rt_sigpending (__NR_N32_Linux + 125) +#define __NR_N32_rt_sigtimedwait (__NR_N32_Linux + 126) +#define __NR_N32_rt_sigqueueinfo (__NR_N32_Linux + 127) +#define __NR_N32_rt_sigsuspend (__NR_N32_Linux + 128) +#define __NR_N32_sigaltstack (__NR_N32_Linux + 129) +#define __NR_N32_utime (__NR_N32_Linux + 130) +#define __NR_N32_mknod (__NR_N32_Linux + 131) +#define __NR_N32_personality (__NR_N32_Linux + 132) +#define __NR_N32_ustat (__NR_N32_Linux + 133) +#define __NR_N32_statfs (__NR_N32_Linux + 134) +#define __NR_N32_fstatfs (__NR_N32_Linux + 135) +#define __NR_N32_sysfs (__NR_N32_Linux + 136) +#define __NR_N32_getpriority (__NR_N32_Linux + 137) +#define __NR_N32_setpriority (__NR_N32_Linux + 138) +#define __NR_N32_sched_setparam (__NR_N32_Linux + 139) +#define __NR_N32_sched_getparam (__NR_N32_Linux + 140) +#define __NR_N32_sched_setscheduler (__NR_N32_Linux + 141) +#define __NR_N32_sched_getscheduler (__NR_N32_Linux + 142) +#define __NR_N32_sched_get_priority_max (__NR_N32_Linux + 143) +#define __NR_N32_sched_get_priority_min (__NR_N32_Linux + 144) +#define __NR_N32_sched_rr_get_interval (__NR_N32_Linux + 145) +#define __NR_N32_mlock (__NR_N32_Linux + 146) +#define __NR_N32_munlock (__NR_N32_Linux + 147) +#define __NR_N32_mlockall (__NR_N32_Linux + 148) +#define __NR_N32_munlockall (__NR_N32_Linux + 149) +#define __NR_N32_vhangup (__NR_N32_Linux + 150) +#define __NR_N32_pivot_root (__NR_N32_Linux + 151) +#define __NR_N32__sysctl (__NR_N32_Linux + 152) +#define __NR_N32_prctl (__NR_N32_Linux + 153) +#define __NR_N32_adjtimex (__NR_N32_Linux + 154) +#define __NR_N32_setrlimit (__NR_N32_Linux + 155) +#define __NR_N32_chroot (__NR_N32_Linux + 156) +#define __NR_N32_sync (__NR_N32_Linux + 157) +#define __NR_N32_acct (__NR_N32_Linux + 158) +#define __NR_N32_settimeofday (__NR_N32_Linux + 159) +#define __NR_N32_mount (__NR_N32_Linux + 160) +#define __NR_N32_umount2 (__NR_N32_Linux + 161) +#define __NR_N32_swapon (__NR_N32_Linux + 162) +#define __NR_N32_swapoff (__NR_N32_Linux + 163) +#define __NR_N32_reboot (__NR_N32_Linux + 164) +#define __NR_N32_sethostname (__NR_N32_Linux + 165) +#define __NR_N32_setdomainname (__NR_N32_Linux + 166) +#define __NR_N32_create_module (__NR_N32_Linux + 167) +#define __NR_N32_init_module (__NR_N32_Linux + 168) +#define __NR_N32_delete_module (__NR_N32_Linux + 169) +#define __NR_N32_get_kernel_syms (__NR_N32_Linux + 170) +#define __NR_N32_query_module (__NR_N32_Linux + 171) +#define __NR_N32_quotactl (__NR_N32_Linux + 172) +#define __NR_N32_nfsservctl (__NR_N32_Linux + 173) +#define __NR_N32_getpmsg (__NR_N32_Linux + 174) +#define __NR_N32_putpmsg (__NR_N32_Linux + 175) +#define __NR_N32_afs_syscall (__NR_N32_Linux + 176) +#define __NR_N32_reserved177 (__NR_N32_Linux + 177) +#define __NR_N32_gettid (__NR_N32_Linux + 178) +#define __NR_N32_readahead (__NR_N32_Linux + 179) +#define __NR_N32_setxattr (__NR_N32_Linux + 180) +#define __NR_N32_lsetxattr (__NR_N32_Linux + 181) +#define __NR_N32_fsetxattr (__NR_N32_Linux + 182) +#define __NR_N32_getxattr (__NR_N32_Linux + 183) +#define __NR_N32_lgetxattr (__NR_N32_Linux + 184) +#define __NR_N32_fgetxattr (__NR_N32_Linux + 185) +#define __NR_N32_listxattr (__NR_N32_Linux + 186) +#define __NR_N32_llistxattr (__NR_N32_Linux + 187) +#define __NR_N32_flistxattr (__NR_N32_Linux + 188) +#define __NR_N32_removexattr (__NR_N32_Linux + 189) +#define __NR_N32_lremovexattr (__NR_N32_Linux + 190) +#define __NR_N32_fremovexattr (__NR_N32_Linux + 191) +#define __NR_N32_tkill (__NR_N32_Linux + 192) +#define __NR_N32_time (__NR_N32_Linux + 193) +#define __NR_N32_futex (__NR_N32_Linux + 194) +#define __NR_N32_sched_setaffinity (__NR_N32_Linux + 195) +#define __NR_N32_sched_getaffinity (__NR_N32_Linux + 196) +#define __NR_N32_cacheflush (__NR_N32_Linux + 197) +#define __NR_N32_cachectl (__NR_N32_Linux + 198) +#define __NR_N32_sysmips (__NR_N32_Linux + 199) +#define __NR_N32_io_setup (__NR_N32_Linux + 200) +#define __NR_N32_io_destroy (__NR_N32_Linux + 201) +#define __NR_N32_io_getevents (__NR_N32_Linux + 202) +#define __NR_N32_io_submit (__NR_N32_Linux + 203) +#define __NR_N32_io_cancel (__NR_N32_Linux + 204) +#define __NR_N32_exit_group (__NR_N32_Linux + 205) +#define __NR_N32_lookup_dcookie (__NR_N32_Linux + 206) +#define __NR_N32_epoll_create (__NR_N32_Linux + 207) +#define __NR_N32_epoll_ctl (__NR_N32_Linux + 208) +#define __NR_N32_epoll_wait (__NR_N32_Linux + 209) +#define __NR_N32_remap_file_page (__NR_N32_Linux + 210) +#define __NR_N32_rt_sigreturn (__NR_N32_Linux + 211) +#define __NR_N32_fcntl64 (__NR_N32_Linux + 212) +#define __NR_N32_set_tid_address (__NR_N32_Linux + 213) +#define __NR_N32_restart_syscall (__NR_N32_Linux + 214) +#define __NR_N32_semtimedop (__NR_N32_Linux + 215) +#define __NR_N32_fadvise64 (__NR_N32_Linux + 216) +#define __NR_N32_statfs64 (__NR_N32_Linux + 217) +#define __NR_N32_fstatfs64 (__NR_N32_Linux + 218) + +/* + * Offset of the last N32 flavoured syscall + */ +#define __NR_N32_Linux_syscalls 218 + +#ifndef __ASSEMBLY__ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ -long __res, __err; \ -__asm__ volatile ("li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name) \ - : "$2", "$7","$8","$9","$10","$11","$12","$13","$14","$15", \ - "$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %2\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } /* @@ -497,89 +766,94 @@ #define _syscall1(type,name,atype,a) \ type name(atype a) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)) \ - : "$2","$4","$7","$8","$9","$10","$11","$12","$13","$14", \ - "$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %3\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall2(type,name,atype,a,btype,b) \ -type name(atype a,btype b) \ +type name(atype a, btype b) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)) \ - : "$2","$4","$5","$7","$8","$9","$10","$11","$12","$13","$14","$15", \ - "$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %4\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall3(type,name,atype,a,btype,b,ctype,c) \ -type name (atype a, btype b, ctype c) \ +type name(atype a, btype b, ctype c) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "=r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name (atype a, btype b, ctype c, dtype d) \ +type name(atype a, btype b, ctype c, dtype d) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "move\t$7, %6\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #if (_MIPS_SIM == _ABIN32) || (_MIPS_SIM == _ABI64) @@ -587,193 +861,189 @@ #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ type name (atype a,btype b,ctype c,dtype d,etype e) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "move\t$7, %6\n\t" \ - "move\t$8, %7\n\t" \ - "sw\t$2, 16($29)\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "r" ((long)(e)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + register unsigned long __a4 asm("$8") = (unsigned long) e; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %6\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3), "+r" (__a4) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "move\t$7, %6\n\t" \ - "move\t$8, %7\n\t" \ - "move\t$9, %8\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + register unsigned long __a4 asm("$8") = (unsigned long) e; \ + register unsigned long __a5 asm("$9") = (unsigned long) f; \ + \ + __asm__ volatile ( "" \ + : "+r" (__a5) \ + : \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %6\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3), "+r" (__a4) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "move\t$7, %6\n\t" \ - "move\t$8, %7\n\t" \ - "move\t$9, %8\n\t" \ - "move\t$10, %9\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "r" ((long)(e)), \ - "r" ((long)(f)), \ - "r" ((long)(g)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + register unsigned long __a4 asm("$8") = (unsigned long) e; \ + register unsigned long __a5 asm("$9") = (unsigned long) f; \ + register unsigned long __a6 asm("$10") = (unsigned long) g; \ + \ + __asm__ volatile ( "" \ + : "+r" (__a5), "+r" (__a6) \ + : \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "li\t$2, %6\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3), "+r" (__a4) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #else /* not N32 or 64 ABI */ -/* These are here for sake of fucking lusercode living in the fucking believe - having to fuck around with the syscall interface themselfes. */ +/* + * Using those means your brain needs more than an oil change ;-) + */ #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name (atype a,btype b,ctype c,dtype d,etype e) \ +type name(atype a, btype b, ctype c, dtype d, etype e) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "lw\t$2, %7\n\t" \ - "move\t$7, %6\n\t" \ - "subu\t$29, 24\n\t" \ - "sw\t$2, 16($29)\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - "addiu\t$29,24" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)) \ - : "$2","$4","$5","$6","$7","$8","$9","$10","$11","$12", \ - "$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "lw\t$2, %7\n\t" \ - "lw\t$3, %8\n\t" \ - "move\t$7, %6\n\t" \ - "subu\t$29, 24\n\t" \ - "sw\t$2, 16($29)\n\t" \ - "sw\t$3, 20($29)\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - "addiu\t$29, 24" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f) \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \ +type name(atype a, btype b, ctype c, dtype d, etype e, ftype f, gtype g) \ { \ -long __res, __err; \ -__asm__ volatile ("move\t$4, %3\n\t" \ - "move\t$5, %4\n\t" \ - "move\t$6, %5\n\t" \ - "lw\t$2, %7\n\t" \ - "lw\t$3, %8\n\t" \ - "move\t$7, %6\n\t" \ - "subu\t$29, 32\n\t" \ - "sw\t$2, 16($29)\n\t" \ - "lw\t$2, %9\n\t" \ - "sw\t$3, 20($29)\n\t" \ - "sw\t$2, 24($29)\n\t" \ - "li\t$2, %2\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "move\t%1, $7" \ - "addiu\t$29, 32" \ - : "=r" (__res), "=r" (__err) \ - : "i" (__NR_##name),"r" ((long)(a)), \ - "r" ((long)(b)), \ - "r" ((long)(c)), \ - "r" ((long)(d)), \ - "m" ((long)(e)), \ - "m" ((long)(f)), \ - "m" ((long)(g)) \ - : "$2","$3","$4","$5","$6","$7","$8","$9","$10","$11", \ - "$12","$13","$14","$15","$24"); \ -if (__err == 0) \ - return (type) __res; \ -errno = __res; \ -return -1; \ + register unsigned long __v0 asm("$2") = __NR_##name; \ + register unsigned long __a0 asm("$4") = (unsigned long) a; \ + register unsigned long __a1 asm("$5") = (unsigned long) b; \ + register unsigned long __a2 asm("$6") = (unsigned long) c; \ + register unsigned long __a3 asm("$7") = (unsigned long) d; \ + \ + __asm__ volatile ( \ + ".set\tnoreorder\n\t" \ + "lw\t$2, %6\n\t" \ + "lw\t$8, %7\n\t" \ + "lw\t$9, %8\n\t" \ + "subu\t$29, 32\n\t" \ + "sw\t$2, 16($29)\n\t" \ + "sw\t$8, 20($29)\n\t" \ + "sw\t$9, 24($29)\n\t" \ + "li\t$2, %5\t\t\t# " #name "\n\t" \ + "syscall\n\t" \ + "addiu\t$29, 32\n\t" \ + ".set\treorder" \ + : "=&r" (__v0), "+r" (__a3) \ + : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ + "m" ((unsigned long)e), "m" ((unsigned long)f), \ + "m" ((unsigned long)g), \ + : "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \ + \ + if (__a3 == 0) \ + return (type) __v0; \ + errno = __v0; \ + return -1; \ } #endif @@ -802,10 +1072,16 @@ static inline _syscall3(int,open,const char *,file,int,flag,int,mode) static inline _syscall1(int,close,int,fd) static inline _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) +struct rusage; +static inline _syscall4(pid_t,wait4,pid_t,pid,int *,stat_addr,int,options,struct rusage *,ru) + +static inline pid_t waitpid(int pid, int * wait_stat, int flags) +{ + return wait4(pid, wait_stat, flags, NULL); +} -#endif /* !defined (__KERNEL_SYSCALLS__) */ -#endif /* !defined (_LANGUAGE_ASSEMBLY) */ +#endif /* __KERNEL_SYSCALLS__ */ +#endif /* !__ASSEMBLY__ */ /* * "Conditional" syscalls @@ -813,6 +1089,6 @@ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), * but it doesn't work on all toolchains, so we just do it by hand */ -#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); +#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall"); #endif /* _ASM_UNISTD_H */ diff -Nru a/include/asm-mips64/user.h b/include/asm-mips64/user.h --- a/include/asm-mips64/user.h Fri Jun 27 14:19:55 2003 +++ b/include/asm-mips64/user.h Fri Jun 27 14:19:55 2003 @@ -8,8 +8,6 @@ #ifndef _ASM_USER_H #define _ASM_USER_H -#include <linux/ptrace.h> - #include <asm/page.h> #include <asm/reg.h> @@ -37,7 +35,7 @@ * to write an integer number of pages. */ struct user { - unsigned long regs[EF_SIZE/4+64]; /* integer and fp regs */ + unsigned long regs[EF_SIZE/8+64]; /* integer and fp regs */ size_t u_tsize; /* text size (pages) */ size_t u_dsize; /* data size (pages) */ size_t u_ssize; /* stack size (pages) */ diff -Nru a/include/asm-mips64/vga.h b/include/asm-mips64/vga.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/vga.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,19 @@ +/* + * Access to VGA videoram + * + * (c) 1998 Martin Mares <mj@ucw.cz> + */ +#ifndef _ASM_VGA_H +#define _ASM_VGA_H + +/* + * On the PC, we can just recalculate addresses and then + * access the videoram directly without any black magic. + */ + +#define VGA_MAP_MEM(x) (0xb0000000L + (unsigned long)(x)) + +#define vga_readb(x) (*(x)) +#define vga_writeb(x,y) (*(y) = (x)) + +#endif /* _ASM_VGA_H */ diff -Nru a/include/asm-mips64/war.h b/include/asm-mips64/war.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/war.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,132 @@ +/* + * 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) 2002 by Ralf Baechle + */ +#ifndef _ASM_WAR_H +#define _ASM_WAR_H + +#include <linux/config.h> + +/* + * Pleassures of the R4600 V1.x. Cite from the IDT R4600 V1.7 errata: + * + * 18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D, + * Hit_Invalidate_D and Create_Dirty_Excl_D should only be + * executed if there is no other dcache activity. If the dcache is + * accessed for another instruction immeidately preceding when these + * cache instructions are executing, it is possible that the dcache + * tag match outputs used by these cache instructions will be + * incorrect. These cache instructions should be preceded by at least + * four instructions that are not any kind of load or store + * instruction. + * + * This is not allowed: lw + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * This is allowed: lw + * nop + * nop + * nop + * nop + * cache Hit_Writeback_Invalidate_D + * + * #define R4600_V1_HIT_CACHEOP_WAR 1 + */ + + +/* + * Writeback and invalidate the primary cache dcache before DMA. + * + * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Inv_D, + * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only + * operate correctly if the internal data cache refill buffer is empty. These + * CACHE instructions should be separated from any potential data cache miss + * by a load instruction to an uncached address to empty the response buffer." + * (Revision 2.0 device errata from IDT available on http://www.idt.com/ + * in .pdf format.) + * + * #define R4600_V2_HIT_CACHEOP_WAR 1 + */ + +/* + * R4600 CPU modules for the Indy come with both V1.7 and V2.0 processors. + */ +#ifdef CONFIG_SGI_IP22 + +#define R4600_V1_HIT_CACHEOP_WAR 1 +#define R4600_V2_HIT_CACHEOP_WAR 1 + +#endif + +/* + * But the RM200C seems to have been shipped only with V2.0 R4600s + */ +#ifdef CONFIG_SNI_RM200_PCI + +#define R4600_V2_HIT_CACHEOP_WAR 1 + +#endif + +#ifdef CONFIG_CPU_R5432 + +/* + * When an interrupt happens on a CP0 register read instruction, CPU may + * lock up or read corrupted values of CP0 registers after it enters + * the exception handler. + * + * This workaround makes sure that we read a "safe" CP0 register as the + * first thing in the exception handler, which breaks one of the + * pre-conditions for this problem. + */ +#define R5432_CP0_INTERRUPT_WAR 1 + +#endif + +#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ + defined(CONFIG_SB1_PASS_2_WORKAROUNDS) + +/* + * Workaround for the Sibyte M3 errata the text of which can be found at + * + * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt + * + * This will enable the use of a special TLB refill handler which does a + * consistency check on the information in c0_badvaddr and c0_entryhi and + * will just return and take the exception again if the information was + * found to be inconsistent. + */ +#define BCM1250_M3_WAR 1 + +/* + * This is a DUART workaround related to glitches around register accesses + */ +#define SIBYTE_1956_WAR 1 + +#endif + +/* + * Workarounds default to off + */ +#ifndef R4600_V1_HIT_CACHEOP_WAR +#define R4600_V1_HIT_CACHEOP_WAR 0 +#endif +#ifndef R4600_V2_HIT_CACHEOP_WAR +#define R4600_V2_HIT_CACHEOP_WAR 0 +#endif +#ifndef R5432_CP0_INTERRUPT_WAR +#define R5432_CP0_INTERRUPT_WAR 0 +#endif +#ifndef BCM1250_M3_WAR +#define BCM1250_M3_WAR 0 +#endif +#ifndef SIBYTE_1956_WAR +#define SIBYTE_1956_WAR 0 +#endif + +#endif /* _ASM_WAR_H */ diff -Nru a/include/asm-mips64/watch.h b/include/asm-mips64/watch.h --- a/include/asm-mips64/watch.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-mips64/watch.h Fri Jun 27 14:20:06 2003 @@ -18,20 +18,18 @@ wr_load = 2 }; -extern char watch_available; - extern asmlinkage void __watch_set(unsigned long addr, enum wref_type ref); extern asmlinkage void __watch_clear(void); extern asmlinkage void __watch_reenable(void); #define watch_set(addr, ref) \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_set(addr, ref) #define watch_clear() \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_clear() #define watch_reenable() \ - if (watch_available) \ + if (cpu_has_watch) \ __watch_reenable() #endif /* _ASM_WATCH_H */ diff -Nru a/include/asm-mips64/wbflush.h b/include/asm-mips64/wbflush.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-mips64/wbflush.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,18 @@ +/* + * Header file for using the wbflush routine + * + * 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) 1998 Harald Koerfgen + * Copyright (C) 2002 Maciej W. Rozycki + */ +#ifndef __ASM_MIPS64_WBFLUSH_H +#define __ASM_MIPS64_WBFLUSH_H + +#define wbflush_setup() do { } while (0) + +#define wbflush() fast_iob() + +#endif /* __ASM_MIPS64_WBFLUSH_H */ diff -Nru a/include/asm-mips64/xtalk/xtalk.h b/include/asm-mips64/xtalk/xtalk.h --- a/include/asm-mips64/xtalk/xtalk.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-mips64/xtalk/xtalk.h Fri Jun 27 14:19:30 2003 @@ -12,7 +12,7 @@ #ifndef _ASM_XTALK_XTALK_H #define _ASM_XTALK_XTALK_H -#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) +#ifndef __ASSEMBLY__ /* * User-level device driver visible types */ @@ -47,6 +47,6 @@ #define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT)) #define XIO_PACK(p,o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS)) -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_XTALK_XTALK_H */ diff -Nru a/include/asm-mips64/xtalk/xwidget.h b/include/asm-mips64/xtalk/xwidget.h --- a/include/asm-mips64/xtalk/xwidget.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-mips64/xtalk/xwidget.h Fri Jun 27 14:19:53 2003 @@ -91,7 +91,7 @@ * widget target flush register are widget dependent thus will not be * defined here */ -#if _LANGUAGE_C +#ifndef __ASSEMBLY__ typedef u32 widgetreg_t; /* widget configuration registers */ @@ -162,6 +162,6 @@ ((hwid2)->mfg_num == XWIDGET_MFG_NUM_NONE) || \ ((hwid1)->mfg_num == (hwid2)->mfg_num))) -#endif /* _LANGUAGE_C */ +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_XTALK_XWIDGET_H */ diff -Nru a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h --- a/include/asm-ppc/hardirq.h Fri Jun 27 14:19:30 2003 +++ b/include/asm-ppc/hardirq.h Fri Jun 27 14:19:30 2003 @@ -104,7 +104,5 @@ extern void synchronize_irq(unsigned int irq); #endif /* CONFIG_SMP */ -extern void show_stack(unsigned long *sp); - #endif /* __ASM_HARDIRQ_H */ #endif /* __KERNEL__ */ diff -Nru a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h --- a/include/asm-ppc/ptrace.h Fri Jun 27 14:19:57 2003 +++ b/include/asm-ppc/ptrace.h Fri Jun 27 14:19:57 2003 @@ -49,6 +49,8 @@ #define instruction_pointer(regs) ((regs)->nip) #define user_mode(regs) (((regs)->msr & MSR_PR) != 0) +#define force_successful_syscall_return() set_thread_flag(TIF_FORCE_NOERROR) + /* * We use the least-significant bit of the trap field to indicate * whether we have saved the full set of registers, or only a diff -Nru a/include/asm-ppc/thread_info.h b/include/asm-ppc/thread_info.h --- a/include/asm-ppc/thread_info.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-ppc/thread_info.h Fri Jun 27 14:19:54 2003 @@ -86,6 +86,8 @@ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling TIF_NEED_RESCHED */ +#define TIF_FORCE_NOERROR 5 /* don't return error from current + syscall even if result < 0 */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) @@ -93,6 +95,7 @@ #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) +#define _TIF_FORCE_NOERROR (1<<TIF_FORCE_NOERROR) #endif /* __KERNEL__ */ diff -Nru a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h --- a/include/asm-s390/ccwdev.h Fri Jun 27 14:20:01 2003 +++ b/include/asm-s390/ccwdev.h Fri Jun 27 14:20:01 2003 @@ -115,6 +115,8 @@ #define CCWDEV_EARLY_NOTIFICATION 0x0001 /* Report all interrupt conditions. */ #define CCWDEV_REPORT_ALL 0x0002 +/* Try to perform path grouping. */ +#define CCWDEV_DO_PATHGROUP 0x0004 /* * ccw_device_start() diff -Nru a/include/asm-s390/compat.h b/include/asm-s390/compat.h --- a/include/asm-s390/compat.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-s390/compat.h Fri Jun 27 14:19:54 2003 @@ -94,6 +94,7 @@ s32 f_ffree; compat_fsid_t f_fsid; s32 f_namelen; + s32 f_frsize; s32 f_spare[6]; }; diff -Nru a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h --- a/include/asm-s390/dasd.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-s390/dasd.h Fri Jun 27 14:19:54 2003 @@ -8,16 +8,8 @@ * any future changes wrt the API will result in a change of the APIVERSION reported * to userspace by the DASDAPIVER-ioctl * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * History of changes (starts July 2000) - * 05/04/01 created by moving the kernel interface to drivers/s390/block/dasd_int.h - * 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2) - * 01/23/02 DASD_API_VERSION 3 - added BIODASDPSRD (and BIODASDENAPAV) IOCTL - * 02/15/02 DASD_API_VERSION 4 - added BIODASDSATTR IOCTL - * ##/##/## DASD_API_VERSION 5 - added boxed dasd support TOBEDONE - * 21/06/02 DASD_API_VERSION 6 - fixed HDIO_GETGEO: geo.start is in sectors! - * */ #ifndef DASD_H @@ -226,6 +218,10 @@ #define BIODASDSLCK _IO(DASD_IOCTL_LETTER,4) /* steal lock */ /* reset profiling information of a device */ #define BIODASDPRRST _IO(DASD_IOCTL_LETTER,5) +/* Quiesce IO on device */ +#define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6) +/* Resume IO on device */ +#define BIODASDRESUME _IO(DASD_IOCTL_LETTER,7) /* retrieve API version number */ diff -Nru a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h --- a/include/asm-s390/hardirq.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-s390/hardirq.h Fri Jun 27 14:20:06 2003 @@ -105,6 +105,4 @@ extern void synchronize_irq(unsigned int irq); #endif /* CONFIG_SMP */ -extern void show_stack(unsigned long * esp); - #endif /* __ASM_HARDIRQ_H */ diff -Nru a/include/asm-s390/queue.h b/include/asm-s390/queue.h --- a/include/asm-s390/queue.h Fri Jun 27 14:19:59 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,170 +0,0 @@ -/* - * include/asm-s390/queue.h - * - * S390 version - * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation - * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) - * - * A little set of queue utilies. - */ -#ifndef __ASM_QUEUE_H -#define __ASM_QUEUE_H -#include <linux/stddef.h> - -typedef struct queue -{ - struct queue *next; -} queue; - -typedef queue list; - -typedef struct -{ - queue *head; - queue *tail; -} qheader; - -static __inline__ void init_queue(qheader *qhead) -{ - memset(qhead,0,sizeof(*qhead)); -} - -static __inline__ void enqueue_tail(qheader *qhead,queue *member) -{ - if(member) - { - queue *tail=qhead->tail; - - if(tail) - tail->next=member; - else - - qhead->head=member; - qhead->tail=member; - member->next=NULL; - } -} - -static __inline__ queue *dequeue_head(qheader *qhead) -{ - queue *head=qhead->head,*next_head; - - if(head) - { - next_head=head->next; - qhead->head=next_head; - if(!next_head) - qhead->tail=NULL; - } - return(head); -} - -static __inline__ void init_list(list **lhead) -{ - *lhead=NULL; -} - -static __inline__ void add_to_list(list **lhead,list *member) -{ - member->next=*lhead; - *lhead=member; -} - -static __inline__ list *remove_listhead(list **lhead) -{ - list *oldhead=*lhead; - - if(oldhead) - *lhead=(*lhead)->next; - return(oldhead); -} - -static __inline__ void add_to_list_tail(list **lhead,list *member) -{ - list *curr,*prev; - if(*lhead==NULL) - *lhead=member; - else - { - prev=*lhead; - for(curr=(*lhead)->next;curr!=NULL;curr=curr->next) - prev=curr; - prev->next=member; - } -} -static __inline__ void add_to_list_tail_null(list **lhead,list *member) -{ - member->next=NULL; - add_to_list_tail_null(lhead,member); -} - - -static __inline__ int is_in_list(list *lhead,list *member) -{ - list *curr; - - for(curr=lhead;curr!=NULL;curr=curr->next) - if(curr==member) - return(1); - return(0); -} - -static __inline__ int get_prev(list *lhead,list *member,list **prev) -{ - list *curr; - - *prev=NULL; - for(curr=lhead;curr!=NULL;curr=curr->next) - { - if(curr==member) - return(1); - *prev=curr; - } - *prev=NULL; - return(0); -} - - - -static __inline__ int remove_from_list(list **lhead,list *member) -{ - list *prev; - - if(get_prev(*lhead,member,&prev)) - { - - if(prev) - prev->next=member->next; - else - *lhead=member->next; - return(1); - } - return(0); -} - -static __inline__ int remove_from_queue(qheader *qhead,queue *member) -{ - queue *prev; - - if(get_prev(qhead->head,(list *)member,(list **)&prev)) - { - - if(prev) - { - prev->next=member->next; - if(prev->next==NULL) - qhead->tail=prev; - } - else - { - if(qhead->head==qhead->tail) - qhead->tail=NULL; - qhead->head=member->next; - } - return(1); - } - return(0); -} - -#endif /* __ASM_QUEUE_H */ - diff -Nru a/include/asm-s390/statfs.h b/include/asm-s390/statfs.h --- a/include/asm-s390/statfs.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-s390/statfs.h Fri Jun 27 14:20:05 2003 @@ -9,6 +9,10 @@ #ifndef _S390_STATFS_H #define _S390_STATFS_H +#ifndef __s390x__ +#include <asm-generic/statfs.h> +#else + #ifndef __KERNEL_STRICT_NAMES #include <linux/types.h> @@ -17,19 +21,25 @@ #endif +/* + * This is ugly -- we're already 64-bit clean, so just duplicate the + * definitions. + */ struct statfs { -#ifndef __s390x__ - long f_type; - long f_bsize; + int f_type; + int f_bsize; long f_blocks; long f_bfree; long f_bavail; long f_files; long f_ffree; __kernel_fsid_t f_fsid; - long f_namelen; - long f_spare[6]; -#else /* __s390x__ */ + int f_namelen; + int f_frsize; + int f_spare[5]; +}; + +struct statfs64 { int f_type; int f_bsize; long f_blocks; @@ -39,8 +49,9 @@ long f_ffree; __kernel_fsid_t f_fsid; int f_namelen; - int f_spare[6]; -#endif /* __s390x__ */ + int f_frsize; + int f_spare[5]; }; +#endif /* __s390x__ */ #endif diff -Nru a/include/asm-sparc/bug.h b/include/asm-sparc/bug.h --- a/include/asm-sparc/bug.h Fri Jun 27 14:20:06 2003 +++ b/include/asm-sparc/bug.h Fri Jun 27 14:20:06 2003 @@ -2,14 +2,19 @@ #ifndef _SPARC_BUG_H #define _SPARC_BUG_H +/* Only use the inline asm until a gcc release that can handle __builtin_trap + * -rob 2003-06-25 */ +#define __bug_trap() \ + __asm__ __volatile__ ("t 0x5\n\t" : : ) + #ifdef CONFIG_DEBUG_BUGVERBOSE extern void do_BUG(const char *file, int line); #define BUG() do { \ do_BUG(__FILE__, __LINE__); \ - __builtin_trap(); \ + __bug_trap(); \ } while (0) #else -#define BUG() __builtin_trap() +#define BUG() __bug_trap() #endif #define BUG_ON(condition) do { \ diff -Nru a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h --- a/include/asm-sparc/unistd.h Fri Jun 27 14:19:53 2003 +++ b/include/asm-sparc/unistd.h Fri Jun 27 14:19:53 2003 @@ -250,6 +250,8 @@ #define __NR_time 231 /* Linux Specific */ /* #define __NR_oldstat 232 Linux Specific */ #define __NR_stime 233 /* Linux Specific */ +#define __NR_statfs64 234 /* Linux Specific */ +#define __NR_fstatfs64 235 /* Linux Specific */ #define __NR__llseek 236 /* Linux Specific */ #define __NR_mlock 237 #define __NR_munlock 238 @@ -270,6 +272,11 @@ #define __NR_fdatasync 253 #define __NR_nfsservctl 254 #define __NR_aplib 255 +/* WARNING: You MAY NOT add syscall numbers larger than 255, since + * all of the syscall tables in the Sparc kernel are + * sized to have 256 entries (starting at zero). Therefore + * find a free slot in the 0-255 range. + */ #define _syscall0(type,name) \ type name(void) \ diff -Nru a/include/asm-sparc64/compat.h b/include/asm-sparc64/compat.h --- a/include/asm-sparc64/compat.h Fri Jun 27 14:19:58 2003 +++ b/include/asm-sparc64/compat.h Fri Jun 27 14:19:58 2003 @@ -92,7 +92,8 @@ int f_ffree; compat_fsid_t f_fsid; int f_namelen; /* SunOS ignores this field. */ - int f_spare[6]; + int f_frsize; + int f_spare[5]; }; #define COMPAT_RLIM_INFINITY 0x7fffffff diff -Nru a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h --- a/include/asm-sparc64/unistd.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-sparc64/unistd.h Fri Jun 27 14:19:54 2003 @@ -252,8 +252,8 @@ #endif /* #define __NR_oldstat 232 Linux Specific */ #define __NR_stime 233 /* Linux Specific */ -/* #define __NR_UNUSED 234 */ -/* #define __NR_UNUSED 235 */ +#define __NR_statfs64 234 /* Linux Specific */ +#define __NR_fstatfs64 235 /* Linux Specific */ #define __NR__llseek 236 /* Linux Specific */ #define __NR_mlock 237 #define __NR_munlock 238 @@ -274,6 +274,11 @@ #define __NR_fdatasync 253 #define __NR_nfsservctl 254 #define __NR_aplib 255 +/* WARNING: You MAY NOT add syscall numbers larger than 255, since + * all of the syscall tables in the Sparc64 kernel are + * sized to have 256 entries (starting at zero). Therefore + * find a free slot in the 0-255 range. + */ #define _syscall0(type,name) \ type name(void) \ diff -Nru a/include/asm-x86_64/floppy.h b/include/asm-x86_64/floppy.h --- a/include/asm-x86_64/floppy.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-x86_64/floppy.h Fri Jun 27 14:19:54 2003 @@ -22,7 +22,7 @@ * floppy accesses go through the track buffer. */ #define _CROSS_64KB(a,s,vdma) \ -(!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) +(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) #define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1) @@ -62,10 +62,8 @@ static int bytes=0; static int dma_wait=0; #endif - if(!doing_pdma) { - floppy_interrupt(irq, dev_id, regs); - return IRQ_HANDLED; - } + if (!doing_pdma) + return floppy_interrupt(irq, dev_id, regs); #ifdef TRACE_FLPY_INT if(!calls) @@ -115,7 +113,6 @@ if(!virtual_dma_count) dma_wait++; #endif - return IRQ_HANDLED; } diff -Nru a/include/asm-x86_64/mtrr.h b/include/asm-x86_64/mtrr.h --- a/include/asm-x86_64/mtrr.h Fri Jun 27 14:19:54 2003 +++ b/include/asm-x86_64/mtrr.h Fri Jun 27 14:19:54 2003 @@ -104,7 +104,7 @@ return -ENODEV; } -static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {;} +static __inline__ void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) {} # endif diff -Nru a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h --- a/include/asm-x86_64/pgtable.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-x86_64/pgtable.h Fri Jun 27 14:19:59 2003 @@ -401,6 +401,9 @@ #define pgtable_cache_init() do { } while (0) #define check_pgt_cache() do { } while (0) +#define PAGE_AGP PAGE_KERNEL_NOCACHE +#define HAVE_PAGE_AGP 1 + /* fs/proc/kcore.c */ #define kc_vaddr_to_offset(v) ((v) & __VIRTUAL_MASK) #define kc_offset_to_vaddr(o) \ diff -Nru a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h --- a/include/asm-x86_64/processor.h Fri Jun 27 14:20:05 2003 +++ b/include/asm-x86_64/processor.h Fri Jun 27 14:20:05 2003 @@ -280,8 +280,6 @@ */ extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -static inline void release_segments(struct mm_struct *mm) { } - /* * Return saved PC of a blocked thread. * What is this good for? it will be always the scheduler or ret_from_fork. diff -Nru a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h --- a/include/asm-x86_64/proto.h Fri Jun 27 14:20:02 2003 +++ b/include/asm-x86_64/proto.h Fri Jun 27 14:20:02 2003 @@ -52,7 +52,6 @@ extern unsigned long cpu_initialized; -extern void show_stack(unsigned long * rsp); extern void show_trace(unsigned long * rsp); extern void show_registers(struct pt_regs *regs); diff -Nru a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h --- a/include/asm-x86_64/unistd.h Fri Jun 27 14:19:59 2003 +++ b/include/asm-x86_64/unistd.h Fri Jun 27 14:19:59 2003 @@ -486,10 +486,10 @@ __SYSCALL(__NR_lookup_dcookie, sys_lookup_dcookie) #define __NR_epoll_create 213 __SYSCALL(__NR_epoll_create, sys_epoll_create) -#define __NR_epoll_ctl 214 -__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) -#define __NR_epoll_wait 215 -__SYSCALL(__NR_epoll_wait, sys_epoll_wait) +#define __NR_epoll_ctl_old 214 +__SYSCALL(__NR_epoll_ctl_old, sys_ni_syscall) +#define __NR_epoll_wait_old 215 +__SYSCALL(__NR_epoll_wait_old, sys_ni_syscall) #define __NR_remap_file_pages 216 __SYSCALL(__NR_remap_file_pages, sys_remap_file_pages) #define __NR_getdents64 217 @@ -522,8 +522,12 @@ __SYSCALL(__NR_clock_nanosleep, sys_clock_nanosleep) #define __NR_exit_group 231 __SYSCALL(__NR_exit_group, sys_exit_group) +#define __NR_epoll_wait 232 +__SYSCALL(__NR_epoll_wait, sys_epoll_wait) +#define __NR_epoll_ctl 233 +__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl) -#define __NR_syscall_max __NR_exit_group +#define __NR_syscall_max __NR_epoll_ctl #ifndef __NO_STUBS /* user-visible error numbers are in the range -1 - -4095 */ diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h --- a/include/linux/atmdev.h Fri Jun 27 14:20:00 2003 +++ b/include/linux/atmdev.h Fri Jun 27 14:20:00 2003 @@ -293,7 +293,6 @@ struct k_atm_aal_stats *stats; /* pointer to AAL stats group */ wait_queue_head_t sleep; /* if socket is busy */ struct sock *sk; /* socket backpointer */ - struct atm_vcc *prev,*next; /* SVC part --- may move later ------------------------------------- */ short itf; /* interface number */ struct sockaddr_atmsvc local; @@ -320,8 +319,6 @@ /* (NULL) */ const char *type; /* device type name */ int number; /* device index */ - struct atm_vcc *vccs; /* VCC table (or NULL) */ - struct atm_vcc *last; /* last VCC (or undefined) */ void *dev_data; /* per-device data */ void *phy_data; /* private PHY date */ unsigned long flags; /* device flags (ATM_DF_*) */ @@ -390,6 +387,9 @@ unsigned long atm_options; /* ATM layer options */ }; +extern struct hlist_head vcc_sklist; +extern rwlock_t vcc_sklist_lock; + #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, @@ -397,7 +397,8 @@ struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); void shutdown_atm_dev(struct atm_dev *dev); -void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev); +void vcc_insert_socket(struct sock *sk); +void vcc_remove_socket(struct sock *sk); /* @@ -436,7 +437,7 @@ } -static inline void atm_dev_release(struct atm_dev *dev) +static inline void atm_dev_put(struct atm_dev *dev) { atomic_dec(&dev->refcnt); diff -Nru a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h --- a/include/linux/dvb/dmx.h Fri Jun 27 14:20:03 2003 +++ b/include/linux/dvb/dmx.h Fri Jun 27 14:20:03 2003 @@ -24,10 +24,10 @@ #ifndef _DVBDMX_H_ #define _DVBDMX_H_ +#include <asm/types.h> #ifdef __KERNEL__ -#include <linux/types.h> +#include <linux/time.h> #else -#include <stdint.h> #include <time.h> #endif @@ -103,18 +103,18 @@ typedef struct dmx_filter { - uint8_t filter[DMX_FILTER_SIZE]; - uint8_t mask[DMX_FILTER_SIZE]; - uint8_t mode[DMX_FILTER_SIZE]; + __u8 filter[DMX_FILTER_SIZE]; + __u8 mask[DMX_FILTER_SIZE]; + __u8 mode[DMX_FILTER_SIZE]; } dmx_filter_t; struct dmx_sct_filter_params { - uint16_t pid; + __u16 pid; dmx_filter_t filter; - uint32_t timeout; - uint32_t flags; + __u32 timeout; + __u32 flags; #define DMX_CHECK_CRC 1 #define DMX_ONESHOT 2 #define DMX_IMMEDIATE_START 4 @@ -124,11 +124,11 @@ struct dmx_pes_filter_params { - uint16_t pid; + __u16 pid; dmx_input_t input; dmx_output_t output; dmx_pes_type_t pes_type; - uint32_t flags; + __u32 flags; }; @@ -143,7 +143,7 @@ }; typedef struct dmx_caps { - uint32_t caps; + __u32 caps; int num_decoders; } dmx_caps_t; @@ -161,7 +161,7 @@ struct dmx_stc { unsigned int num; /* input : which STC? 0..N */ unsigned int base; /* output: divisor for stc to get 90 kHz clock */ - uint64_t stc; /* output: stc in 'base'*90 kHz units */ + __u64 stc; /* output: stc in 'base'*90 kHz units */ }; @@ -171,7 +171,7 @@ #define DMX_SET_PES_FILTER _IOW('o',44,struct dmx_pes_filter_params) #define DMX_SET_BUFFER_SIZE _IO('o',45) #define DMX_GET_EVENT _IOR('o',46,struct dmx_event) -#define DMX_GET_PES_PIDS _IOR('o',47,uint16_t[5]) +#define DMX_GET_PES_PIDS _IOR('o', 47, __u16[5]) #define DMX_GET_CAPS _IOR('o',48,dmx_caps_t) #define DMX_SET_SOURCE _IOW('o',49,dmx_source_t) #define DMX_GET_STC _IOWR('o',50,struct dmx_stc) diff -Nru a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h --- a/include/linux/dvb/frontend.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/dvb/frontend.h Fri Jun 27 14:19:56 2003 @@ -26,11 +26,7 @@ #ifndef _DVBFRONTEND_H_ #define _DVBFRONTEND_H_ -#ifdef __KERNEL__ -#include <linux/types.h> -#else -#include <stdint.h> -#endif +#include <asm/types.h> typedef enum fe_type { @@ -72,14 +68,14 @@ struct dvb_frontend_info { char name[128]; fe_type_t type; - uint32_t frequency_min; - uint32_t frequency_max; - uint32_t frequency_stepsize; - uint32_t frequency_tolerance; - uint32_t symbol_rate_min; - uint32_t symbol_rate_max; - uint32_t symbol_rate_tolerance; /* ppm */ - uint32_t notifier_delay; /* ms */ + __u32 frequency_min; + __u32 frequency_max; + __u32 frequency_stepsize; + __u32 frequency_tolerance; + __u32 symbol_rate_min; + __u32 symbol_rate_max; + __u32 symbol_rate_tolerance; /* ppm */ + __u32 notifier_delay; /* ms */ fe_caps_t caps; }; @@ -89,21 +85,22 @@ * the meaning of this struct... */ struct dvb_diseqc_master_cmd { - uint8_t msg [6]; /* { framing, address, command, data [3] } */ - uint8_t msg_len; /* valid values are 3...6 */ + __u8 msg [6]; /* { framing, address, command, data [3] } */ + __u8 msg_len; /* valid values are 3...6 */ }; struct dvb_diseqc_slave_reply { - uint8_t msg [4]; /* { framing, data [3] } */ - uint8_t msg_len; /* valid values are 0...4, 0 means no msg */ + __u8 msg [4]; /* { framing, data [3] } */ + __u8 msg_len; /* valid values are 0...4, 0 means no msg */ int timeout; /* return from ioctl after timeout ms with */ }; /* errorcode when no message was received */ typedef enum fe_sec_voltage { SEC_VOLTAGE_13, - SEC_VOLTAGE_18 + SEC_VOLTAGE_18, + SEC_VOLTAGE_OFF } fe_sec_voltage_t; @@ -195,13 +192,13 @@ struct dvb_qpsk_parameters { - uint32_t symbol_rate; /* symbol rate in Symbols per second */ + __u32 symbol_rate; /* symbol rate in Symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ }; struct dvb_qam_parameters { - uint32_t symbol_rate; /* symbol rate in Symbols per second */ + __u32 symbol_rate; /* symbol rate in Symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ fe_modulation_t modulation; /* modulation type (see above) */ }; @@ -219,7 +216,7 @@ struct dvb_frontend_parameters { - uint32_t frequency; /* (absolute) frequency in Hz for QAM/OFDM */ + __u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM */ /* intermediate frequency in kHz for QPSK */ fe_spectral_inversion_t inversion; union { @@ -249,10 +246,10 @@ #define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68) /* int */ #define FE_READ_STATUS _IOR('o', 69, fe_status_t) -#define FE_READ_BER _IOR('o', 70, uint32_t) -#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, uint16_t) -#define FE_READ_SNR _IOR('o', 72, uint16_t) -#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, uint32_t) +#define FE_READ_BER _IOR('o', 70, __u32) +#define FE_READ_SIGNAL_STRENGTH _IOR('o', 71, __u16) +#define FE_READ_SNR _IOR('o', 72, __u16) +#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32) #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) diff -Nru a/include/linux/dvb/net.h b/include/linux/dvb/net.h --- a/include/linux/dvb/net.h Fri Jun 27 14:19:53 2003 +++ b/include/linux/dvb/net.h Fri Jun 27 14:19:53 2003 @@ -24,16 +24,12 @@ #ifndef _DVBNET_H_ #define _DVBNET_H_ -#ifdef __KERNEL__ -#include <linux/types.h> -#else -#include <stdint.h> -#endif +#include <asm/types.h> struct dvb_net_if { - uint16_t pid; - uint16_t if_num; + __u16 pid; + __u16 if_num; }; diff -Nru a/include/linux/dvb/version.h b/include/linux/dvb/version.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/dvb/version.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,29 @@ +/* + * version.h + * + * Copyright (C) 2000 Holger Waechtler <holger@convergence.de> + * for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef _DVBVERSION_H_ +#define _DVBVERSION_H_ + +#define DVB_API_VERSION 3 + +#endif /*_DVBVERSION_H_*/ + diff -Nru a/include/linux/dvb/video.h b/include/linux/dvb/video.h --- a/include/linux/dvb/video.h Fri Jun 27 14:19:53 2003 +++ b/include/linux/dvb/video.h Fri Jun 27 14:19:53 2003 @@ -34,7 +34,8 @@ typedef enum { VIDEO_FORMAT_4_3, /* Select 4:3 format */ - VIDEO_FORMAT_16_9 /* Select 16:9 format. */ + VIDEO_FORMAT_16_9, /* Select 16:9 format. */ + VIDEO_FORMAT_221_1 /* 2.21:1 */ } video_format_t; @@ -56,6 +57,11 @@ VIDEO_CENTER_CUT_OUT /* use center cut out format */ } video_displayformat_t; +typedef struct { + int w; + int h; + video_format_t aspect_ratio; +} video_size_t; typedef enum { VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ @@ -74,9 +80,10 @@ struct video_event { int32_t type; +#define VIDEO_EVENT_SIZE_CHANGED 1 time_t timestamp; union { - video_format_t video_format; + video_size_t size; } u; }; @@ -186,6 +193,7 @@ #define VIDEO_SET_SPU_PALETTE _IOW('o', 51, video_spu_palette_t) #define VIDEO_GET_NAVI _IOR('o', 52, video_navi_pack_t) #define VIDEO_SET_ATTRIBUTES _IO('o', 53) +#define VIDEO_GET_SIZE _IOR('o', 55, video_size_t) #endif /*_DVBVIDEO_H_*/ diff -Nru a/include/linux/elf.h b/include/linux/elf.h --- a/include/linux/elf.h Fri Jun 27 14:19:54 2003 +++ b/include/linux/elf.h Fri Jun 27 14:19:54 2003 @@ -163,6 +163,8 @@ #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ #define AT_CLKTCK 17 /* frequency at which times() increments */ +#define AT_SECURE 23 /* secure mode boolean */ + typedef struct dynamic{ Elf32_Sword d_tag; union{ diff -Nru a/include/linux/eventpoll.h b/include/linux/eventpoll.h --- a/include/linux/eventpoll.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/eventpoll.h Fri Jun 27 14:19:56 2003 @@ -23,10 +23,20 @@ /* Set the Edge Triggered behaviour for the target file descriptor */ #define EPOLLET (1 << 31) +/* + * On x86-64 make the 64bit structure have the same alignment as the + * 32bit structure. This makes 32bit emulation easier. + */ +#ifdef __x86_64__ +#define EPOLL_PACKED __attribute__((packed)) +#else +#define EPOLL_PACKED +#endif + struct epoll_event { __u32 events; __u64 data; -}; +} EPOLL_PACKED; #ifdef __KERNEL__ diff -Nru a/include/linux/ide.h b/include/linux/ide.h --- a/include/linux/ide.h Fri Jun 27 14:19:55 2003 +++ b/include/linux/ide.h Fri Jun 27 14:19:55 2003 @@ -726,7 +726,6 @@ unsigned ata_flash : 1; /* 1=present, 0=default */ unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ unsigned vdma : 1; /* 1=doing PIO over DMA 0=doing normal DMA */ - unsigned queue_setup : 1; unsigned addressing; /* : 3; * 0=28-bit * 1=48-bit @@ -1777,7 +1776,8 @@ static inline void ide_release_dma(ide_hwif_t *drive) {;} #endif -extern void hwif_unregister(ide_hwif_t *); +extern int ide_hwif_request_regions(ide_hwif_t *hwif); +extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); extern void export_ide_init_queue(ide_drive_t *); diff -Nru a/include/linux/loop.h b/include/linux/loop.h --- a/include/linux/loop.h Fri Jun 27 14:20:06 2003 +++ b/include/linux/loop.h Fri Jun 27 14:20:06 2003 @@ -14,6 +14,9 @@ #define LO_KEY_SIZE 32 #ifdef __KERNEL__ +#include <linux/bio.h> +#include <linux/blk.h> +#include <linux/spinlock.h> /* Possible states of device */ enum { @@ -22,18 +25,21 @@ Lo_rundown, }; +struct loop_func_table; + struct loop_device { int lo_number; int lo_refcnt; - int lo_offset; - int lo_encrypt_type; - int lo_encrypt_key_size; + loff_t lo_offset; + loff_t lo_sizelimit; int lo_flags; int (*transfer)(struct loop_device *, int cmd, char *raw_buf, char *loop_buf, int size, sector_t real_block); char lo_name[LO_NAME_SIZE]; char lo_encrypt_key[LO_KEY_SIZE]; + int lo_encrypt_key_size; + struct loop_func_table *lo_encryption; __u32 lo_init[2]; uid_t lo_key_owner; /* Who set the key */ int (*ioctl)(struct loop_device *, int cmd, @@ -59,10 +65,6 @@ request_queue_t lo_queue; }; -typedef int (* transfer_proc_t)(struct loop_device *, int cmd, - char *raw_buf, char *loop_buf, int size, - int real_block); - #endif /* __KERNEL__ */ /* @@ -91,13 +93,14 @@ }; struct loop_info64 { - __u64 lo_device; /* ioctl r/o */ - __u64 lo_inode; /* ioctl r/o */ - __u64 lo_rdevice; /* ioctl r/o */ + __u64 lo_device; /* ioctl r/o */ + __u64 lo_inode; /* ioctl r/o */ + __u64 lo_rdevice; /* ioctl r/o */ __u64 lo_offset; - __u32 lo_number; /* ioctl r/o */ + __u64 lo_sizelimit;/* bytes, 0 == max available */ + __u32 lo_number; /* ioctl r/o */ __u32 lo_encrypt_type; - __u32 lo_encrypt_key_size; /* ioctl w/o */ + __u32 lo_encrypt_key_size; /* ioctl w/o */ __u32 lo_flags; /* ioctl r/o */ __u8 lo_name[LO_NAME_SIZE]; __u8 lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ @@ -108,30 +111,29 @@ * Loop filter types */ -#define LO_CRYPT_NONE 0 -#define LO_CRYPT_XOR 1 -#define LO_CRYPT_DES 2 -#define LO_CRYPT_FISH2 3 /* Brand new Twofish encryption */ -#define LO_CRYPT_BLOW 4 -#define LO_CRYPT_CAST128 5 -#define LO_CRYPT_IDEA 6 -#define LO_CRYPT_DUMMY 9 -#define LO_CRYPT_SKIPJACK 10 -#define MAX_LO_CRYPT 20 +#define LO_CRYPT_NONE 0 +#define LO_CRYPT_XOR 1 +#define LO_CRYPT_DES 2 +#define LO_CRYPT_FISH2 3 /* Twofish encryption */ +#define LO_CRYPT_BLOW 4 +#define LO_CRYPT_CAST128 5 +#define LO_CRYPT_IDEA 6 +#define LO_CRYPT_DUMMY 9 +#define LO_CRYPT_SKIPJACK 10 +#define LO_CRYPT_CRYPTOAPI 18 +#define MAX_LO_CRYPT 20 #ifdef __KERNEL__ /* Support for loadable transfer modules */ struct loop_func_table { - int number; /* filter type */ + int number; /* filter type */ int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf, char *loop_buf, int size, sector_t real_block); int (*init)(struct loop_device *, const struct loop_info64 *); /* release is called from loop_unregister_transfer or clr_fd */ int (*release)(struct loop_device *); int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); - /* lock and unlock manage the module use counts */ - void (*lock)(struct loop_device *); - void (*unlock)(struct loop_device *); + struct module *owner; }; int loop_register_transfer(struct loop_func_table *funcs); diff -Nru a/include/linux/mroute.h b/include/linux/mroute.h --- a/include/linux/mroute.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/mroute.h Fri Jun 27 14:19:56 2003 @@ -217,7 +217,6 @@ __u32 flags; }; -extern int pim_rcv(struct sk_buff *); extern int pim_rcv_v1(struct sk_buff *); struct rtmsg; diff -Nru a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h --- a/include/linux/mtd/blktrans.h Fri Jun 27 14:19:58 2003 +++ b/include/linux/mtd/blktrans.h Fri Jun 27 14:19:58 2003 @@ -1,5 +1,5 @@ /* - * $Id: blktrans.h,v 1.4 2003/05/21 01:01:32 dwmw2 Exp $ + * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $ * * (C) 2003 David Woodhouse <dwmw2@infradead.org> * @@ -12,6 +12,7 @@ #include <asm/semaphore.h> +struct hd_geometry; struct mtd_info; struct mtd_blktrans_ops; struct file; @@ -42,17 +43,13 @@ int (*writesect)(struct mtd_blktrans_dev *dev, unsigned long block, char *buffer); - /* HDIO_GETGEO and HDIO_GETGEO_BIG are the only non-private - ioctls which are expected to be passed through */ - int (*ioctl)(struct mtd_blktrans_dev *dev, - struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg); + /* Block layer ioctls */ + int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); + int (*flush)(struct mtd_blktrans_dev *dev); /* Called with mtd_table_mutex held; no race with add/remove */ - int (*open)(struct mtd_blktrans_dev *dev, - struct inode *i, struct file *f); - int (*release)(struct mtd_blktrans_dev *dev, - struct inode *i, struct file *f); + int (*open)(struct mtd_blktrans_dev *dev); + int (*release)(struct mtd_blktrans_dev *dev); /* Called on {de,}registration and on subsequent addition/removal of devices, with mtd_table_mutex held. */ diff -Nru a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h --- a/include/linux/mtd/doc2000.h Fri Jun 27 14:19:57 2003 +++ b/include/linux/mtd/doc2000.h Fri Jun 27 14:19:57 2003 @@ -2,7 +2,7 @@ /* Linux driver for Disk-On-Chip 2000 */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse <dwmw2@mvhi.com> */ -/* $Id: doc2000.h,v 1.16 2003/05/23 11:29:33 dwmw2 Exp $ */ +/* $Id: doc2000.h,v 1.17 2003/06/12 01:20:46 gerg Exp $ */ #ifndef __MTD_DOC2000_H__ #define __MTD_DOC2000_H__ @@ -44,7 +44,7 @@ #define DoC_Mplus_AccessStatus 0x1008 #define DoC_Mplus_DeviceSelect 0x1008 #define DoC_Mplus_Configuration 0x100a -#define DoC_Mplus_OutputControl 0x1002 +#define DoC_Mplus_OutputControl 0x100c #define DoC_Mplus_FlashControl 0x1020 #define DoC_Mplus_FlashSelect 0x1022 #define DoC_Mplus_FlashCmd 0x1024 diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h Fri Jun 27 14:20:04 2003 +++ b/include/linux/netdevice.h Fri Jun 27 14:20:04 2003 @@ -90,11 +90,6 @@ #define MAX_HEADER (LL_MAX_HEADER + 48) #endif -/* Reserve 16byte aligned hard_header_len, but at least 16. - * Alternative is: dev->hard_header_len ? (dev->hard_header_len + 15)&~15 : 0 - */ -#define LL_RESERVED_SPACE(dev) (((dev)->hard_header_len&~15) + 16) - /* * Network device statistics. Akin to the 2.0 ether stats but * with byte counters. @@ -204,6 +199,17 @@ (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1)) unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER)]; }; + +/* Reserve HH_DATA_MOD byte aligned hard_header_len, but at least that much. + * Alternative is: + * dev->hard_header_len ? (dev->hard_header_len + + * (HH_DATA_MOD - 1)) & ~(HH_DATA_MOD - 1) : 0 + * + * We could use other alignment values, but we must maintain the + * relationship HH alignment <= LL alignment. + */ +#define LL_RESERVED_SPACE(dev) \ + (((dev)->hard_header_len&~(HH_DATA_MOD - 1)) + HH_DATA_MOD) /* These flag bits are private to the generic network queueing * layer, they may not be explicitly referenced by any other diff -Nru a/include/linux/netfilter.h b/include/linux/netfilter.h --- a/include/linux/netfilter.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/netfilter.h Fri Jun 27 14:19:56 2003 @@ -19,9 +19,10 @@ #define NF_REPEAT 4 #define NF_MAX_VERDICT NF_REPEAT -/* Generic cache responses from hook functions. */ -#define NFC_ALTERED 0x8000 +/* Generic cache responses from hook functions. + <= 0x2000 is used for protocol-flags. */ #define NFC_UNKNOWN 0x4000 +#define NFC_ALTERED 0x8000 #ifdef __KERNEL__ #include <linux/config.h> diff -Nru a/include/linux/netfilter_arp/arpt_mangle.h b/include/linux/netfilter_arp/arpt_mangle.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_arp/arpt_mangle.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,26 @@ +#ifndef _ARPT_MANGLE_H +#define _ARPT_MANGLE_H +#include <linux/netfilter_arp/arp_tables.h> + +#define ARPT_MANGLE_ADDR_LEN_MAX sizeof(struct in_addr) +struct arpt_mangle +{ + char src_devaddr[ARPT_DEV_ADDR_LEN_MAX]; + char tgt_devaddr[ARPT_DEV_ADDR_LEN_MAX]; + union { + struct in_addr src_ip; + } u_s; + union { + struct in_addr tgt_ip; + } u_t; + u_int8_t flags; + int target; +}; + +#define ARPT_MANGLE_SDEV 0x01 +#define ARPT_MANGLE_TDEV 0x02 +#define ARPT_MANGLE_SIP 0x04 +#define ARPT_MANGLE_TIP 0x08 +#define ARPT_MANGLE_MASK 0x0f + +#endif /* _ARPT_MANGLE_H */ diff -Nru a/include/linux/netfilter_ipv4/ipt_recent.h b/include/linux/netfilter_ipv4/ipt_recent.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/linux/netfilter_ipv4/ipt_recent.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,27 @@ +#ifndef _IPT_RECENT_H +#define _IPT_RECENT_H + +#define RECENT_NAME "ipt_recent" +#define RECENT_VER "v0.3.1" + +#define IPT_RECENT_CHECK 1 +#define IPT_RECENT_SET 2 +#define IPT_RECENT_UPDATE 4 +#define IPT_RECENT_REMOVE 8 +#define IPT_RECENT_TTL 16 + +#define IPT_RECENT_SOURCE 0 +#define IPT_RECENT_DEST 1 + +#define IPT_RECENT_NAME_LEN 200 + +struct ipt_recent_info { + u_int32_t seconds; + u_int32_t hit_count; + u_int8_t check_set; + u_int8_t invert; + char name[IPT_RECENT_NAME_LEN]; + u_int8_t side; +}; + +#endif /*_IPT_RECENT_H*/ diff -Nru a/include/linux/netfilter_ipv4/listhelp.h b/include/linux/netfilter_ipv4/listhelp.h --- a/include/linux/netfilter_ipv4/listhelp.h Fri Jun 27 14:19:53 2003 +++ b/include/linux/netfilter_ipv4/listhelp.h Fri Jun 27 14:19:53 2003 @@ -39,6 +39,22 @@ (type)__i; \ }) +/* Just like LIST_FIND but we search backwards */ +#define LIST_FIND_B(head, cmpfn, type, args...) \ +({ \ + const struct list_head *__i = (head); \ + \ + ASSERT_READ_LOCK(head); \ + do { \ + __i = __i->prev; \ + if (__i == (head)) { \ + __i = NULL; \ + break; \ + } \ + } while (!cmpfn((const type)__i , ## args)); \ + (type)__i; \ +}) + static inline int __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; } diff -Nru a/include/linux/netfilter_ipv4/lockhelp.h b/include/linux/netfilter_ipv4/lockhelp.h --- a/include/linux/netfilter_ipv4/lockhelp.h Fri Jun 27 14:19:53 2003 +++ b/include/linux/netfilter_ipv4/lockhelp.h Fri Jun 27 14:19:53 2003 @@ -42,22 +42,22 @@ printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l); \ } while(0) -/* Write locked OK as well. */ \ +/* Write locked OK as well. */ #define MUST_BE_READ_LOCKED(l) \ -do { if (!((l)->read_locked_map & (1 << smp_processor_id())) \ - && !((l)->write_locked_map & (1 << smp_processor_id()))) \ +do { if (!((l)->read_locked_map & (1UL << smp_processor_id())) \ + && !((l)->write_locked_map & (1UL << smp_processor_id()))) \ printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \ } while(0) #define MUST_BE_WRITE_LOCKED(l) \ -do { if (!((l)->write_locked_map & (1 << smp_processor_id()))) \ +do { if (!((l)->write_locked_map & (1UL << smp_processor_id()))) \ printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \ } while(0) #define MUST_BE_READ_WRITE_UNLOCKED(l) \ -do { if ((l)->read_locked_map & (1 << smp_processor_id())) \ +do { if ((l)->read_locked_map & (1UL << smp_processor_id())) \ printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l); \ - else if ((l)->write_locked_map & (1 << smp_processor_id())) \ + else if ((l)->write_locked_map & (1UL << smp_processor_id())) \ printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \ } while(0) @@ -91,7 +91,7 @@ #define READ_UNLOCK(lk) \ do { \ - if (!((lk)->read_locked_map & (1 << smp_processor_id()))) \ + if (!((lk)->read_locked_map & (1UL << smp_processor_id()))) \ printk("ASSERT: %s:%u %s not readlocked\n", \ __FILE__, __LINE__, #lk); \ clear_bit(smp_processor_id(), &(lk)->read_locked_map); \ diff -Nru a/include/linux/nfs.h b/include/linux/nfs.h --- a/include/linux/nfs.h Fri Jun 27 14:19:59 2003 +++ b/include/linux/nfs.h Fri Jun 27 14:19:59 2003 @@ -100,7 +100,18 @@ NFSERR_RECLAIM_CONFLICT = 10035,/* v4 */ NFSERR_BAD_XDR = 10036, /* v4 */ NFSERR_LOCKS_HELD = 10037, /* v4 */ - NFSERR_REPLAY_ME = 10038 /* v4 */ + NFSERR_OPENMODE = 10038, /* v4 */ + NFSERR_BADOWNER = 10039, /* v4 */ + NFSERR_BADCHAR = 10040, /* v4 */ + NFSERR_BADNAME = 10041, /* v4 */ + NFSERR_BAD_RANGE = 10042, /* v4 */ + NFSERR_LOCK_NOTSUPP = 10043, /* v4 */ + NFSERR_OP_ILLEGAL = 10044, /* v4 */ + NFSERR_DEADLOCK = 10045, /* v4 */ + NFSERR_FILE_OPEN = 10046, /* v4 */ + NFSERR_ADMIN_REVOKED = 10047, /* v4 */ + NFSERR_CB_PATH_DOWN = 10048, /* v4 */ + NFSERR_REPLAY_ME = 10049 /* v4 */ }; /* NFSv2 file types - beware, these are not the same in NFSv3 */ diff -Nru a/include/linux/nfs4.h b/include/linux/nfs4.h --- a/include/linux/nfs4.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/nfs4.h Fri Jun 27 14:19:56 2003 @@ -35,6 +35,8 @@ #define NFS4_SHARE_ACCESS_READ 0x0001 #define NFS4_SHARE_ACCESS_WRITE 0x0002 #define NFS4_SHARE_ACCESS_BOTH 0x0003 +#define NFS4_SHARE_DENY_READ 0x0001 +#define NFS4_SHARE_DENY_WRITE 0x0002 #define NFS4_SET_TO_SERVER_TIME 0 #define NFS4_SET_TO_CLIENT_TIME 1 diff -Nru a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h --- a/include/linux/nfsd/nfsd.h Fri Jun 27 14:20:05 2003 +++ b/include/linux/nfsd/nfsd.h Fri Jun 27 14:20:05 2003 @@ -189,6 +189,7 @@ #define nfserr_not_same __constant_htonl(NFSERR_NOT_SAME) #define nfserr_readdir_nospc __constant_htonl(NFSERR_READDIR_NOSPC) #define nfserr_bad_xdr __constant_htonl(NFSERR_BAD_XDR) +#define nfserr_openmode __constant_htonl(NFSERR_OPENMODE) /* error codes for internal use */ /* if a request fails due to kmalloc failure, it gets dropped. diff -Nru a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h --- a/include/linux/nfsd/state.h Fri Jun 27 14:19:52 2003 +++ b/include/linux/nfsd/state.h Fri Jun 27 14:19:52 2003 @@ -59,6 +59,12 @@ #define si_stateownerid si_opaque.so_stateownerid #define si_fileid si_opaque.so_fileid +extern stateid_t zerostateid; +extern stateid_t onestateid; + +#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t))) +#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t))) + /* * struct nfs4_client - one per client. Clientids live here. * o Each nfs4_client is hashed by clientid. @@ -83,16 +89,12 @@ nfs4_verifier cl_confirm; /* generated by server */ }; -extern time_t nfs4_laundromat(void); -int nfsd4_renew(clientid_t *clid); - static inline void update_stateid(stateid_t *stateid) { -stateid->si_generation++; + stateid->si_generation++; } - /* * nfs4_stateowner can either be an open_owner, or (eventually) a lock_owner * @@ -100,6 +102,7 @@ * reverences when we release a stateowner. */ struct nfs4_stateowner { + struct list_head so_idhash; /* hash by so_id */ struct list_head so_strhash; /* hash by op_name */ struct list_head so_perclient; /* nfs4_client->cl_perclient */ struct list_head so_peropenstate; /* list: nfs4_stateid */ @@ -136,6 +139,7 @@ */ struct nfs4_stateid { + struct list_head st_hash; /* openstateid_hashtbl[]*/ struct list_head st_perfile; /* file_hashtbl[]*/ struct list_head st_peropenstate; /* nfs4_stateowner->so_peropenstate */ struct nfs4_stateowner * st_stateowner; @@ -147,4 +151,22 @@ unsigned int st_share_deny; }; +/* flags for preprocess_seqid_op() */ +#define CHECK_FH 0x00000001 +#define CONFIRM 0x00000002 + +#define seqid_mutating_err(err) \ + (((err) != nfserr_stale_clientid) && \ + ((err) != nfserr_bad_seqid) && \ + ((err) != nfserr_stale_stateid) && \ + ((err) != nfserr_bad_stateid)) + +extern time_t nfs4_laundromat(void); +extern int nfsd4_renew(clientid_t *clid); +extern int nfs4_preprocess_stateid_op(struct svc_fh *current_fh, + stateid_t *stateid, int flags, struct nfs4_stateid **stpp); +extern int nfs4_share_conflict(struct svc_fh *current_fh, + unsigned int deny_type); +extern void nfsd4_lock_state(void); +extern void nfsd4_unlock_state(void); #endif /* NFSD4_STATE_H */ diff -Nru a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h --- a/include/linux/nfsd/xdr4.h Fri Jun 27 14:19:53 2003 +++ b/include/linux/nfsd/xdr4.h Fri Jun 27 14:19:53 2003 @@ -68,6 +68,7 @@ struct nfsd4_close { u32 cl_seqid; /* request */ stateid_t cl_stateid; /* request+response */ + struct nfs4_stateowner * cl_stateowner; /* response */ }; struct nfsd4_commit { @@ -147,6 +148,22 @@ #define op_iattr u.iattr #define op_verf u.verf +struct nfsd4_open_confirm { + stateid_t oc_req_stateid /* request */; + u32 oc_seqid /* request */; + stateid_t oc_resp_stateid /* response */; + struct nfs4_stateowner * oc_stateowner; /* response */ +}; + +struct nfsd4_open_downgrade { + stateid_t od_stateid; + u32 od_seqid; + u32 od_share_access; + u32 od_share_deny; + struct nfs4_stateowner *od_stateowner; +}; + + struct nfsd4_read { stateid_t rd_stateid; /* request */ u64 rd_offset; /* request */ @@ -252,6 +269,8 @@ struct nfsd4_lookup lookup; struct nfsd4_verify nverify; struct nfsd4_open open; + struct nfsd4_open_confirm open_confirm; + struct nfsd4_open_downgrade open_downgrade; struct nfsd4_putfh putfh; struct nfsd4_read read; struct nfsd4_readdir readdir; @@ -315,16 +334,27 @@ } int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *); -int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, struct nfsd4_compoundargs *); -int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, struct nfsd4_compoundres *); - +int nfs4svc_decode_compoundargs(struct svc_rqst *, u32 *, + struct nfsd4_compoundargs *); +int nfs4svc_encode_compoundres(struct svc_rqst *, u32 *, + struct nfsd4_compoundres *); void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); int nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, - struct dentry *dentry, u32 *buffer, int *countp, u32 *bmval); -extern int nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_setclientid *setclid); -extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confirm *setclientid_confirm); + struct dentry *dentry, u32 *buffer, int *countp, + u32 *bmval); +extern int nfsd4_setclientid(struct svc_rqst *rqstp, + struct nfsd4_setclientid *setclid); +extern int nfsd4_setclientid_confirm(struct svc_rqst *rqstp, + struct nfsd4_setclientid_confirm *setclientid_confirm); extern int nfsd4_process_open1(struct nfsd4_open *open); -extern int nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open); +extern int nfsd4_process_open2(struct svc_rqst *rqstp, + struct svc_fh *current_fh, struct nfsd4_open *open); +extern int nfsd4_open_confirm(struct svc_rqst *rqstp, + struct svc_fh *current_fh, struct nfsd4_open_confirm *oc); +extern int nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, + struct nfsd4_close *close); +extern int nfsd4_open_downgrade(struct svc_rqst *rqstp, + struct svc_fh *current_fh, struct nfsd4_open_downgrade *od); #endif /* diff -Nru a/include/linux/pci.h b/include/linux/pci.h --- a/include/linux/pci.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/pci.h Fri Jun 27 14:19:56 2003 @@ -414,7 +414,7 @@ struct resource dma_resource[DEVICE_COUNT_DMA]; struct resource irq_resource[DEVICE_COUNT_IRQ]; - char slot_name[8]; /* slot name */ + char * slot_name; /* pointer to dev.bus_id */ /* These fields are used by common fixups */ unsigned int transparent:1; /* Transparent PCI bridge */ @@ -487,8 +487,8 @@ }; struct pci_raw_ops { - int (*read)(int dom, int bus, int dev, int func, int reg, int len, u32 *val); - int (*write)(int dom, int bus, int dev, int func, int reg, int len, u32 val); + int (*read)(int dom, int bus, int devfn, int reg, int len, u32 *val); + int (*write)(int dom, int bus, int devfn, int reg, int len, u32 val); }; extern struct pci_raw_ops *raw_pci_ops; @@ -802,6 +802,14 @@ static inline void pci_set_drvdata (struct pci_dev *pdev, void *data) { dev_set_drvdata(&pdev->dev, data); +} + +/* If you want to know what to call your pci_dev, ask this function. + * Again, it's a wrapper around the generic device. + */ +static inline char *pci_name(struct pci_dev *pdev) +{ + return pdev->dev.bus_id; } /* diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h Fri Jun 27 14:19:55 2003 +++ b/include/linux/pci_ids.h Fri Jun 27 14:19:55 2003 @@ -668,7 +668,6 @@ #define PCI_DEVICE_ID_TI_1220 0xac17 #define PCI_DEVICE_ID_TI_1221 0xac19 #define PCI_DEVICE_ID_TI_1210 0xac1a -#define PCI_DEVICE_ID_TI_1410 0xac50 #define PCI_DEVICE_ID_TI_1450 0xac1b #define PCI_DEVICE_ID_TI_1225 0xac1c #define PCI_DEVICE_ID_TI_1251A 0xac1d @@ -676,7 +675,9 @@ #define PCI_DEVICE_ID_TI_1251B 0xac1f #define PCI_DEVICE_ID_TI_4410 0xac41 #define PCI_DEVICE_ID_TI_4451 0xac42 +#define PCI_DEVICE_ID_TI_1410 0xac50 #define PCI_DEVICE_ID_TI_1420 0xac51 +#define PCI_DEVICE_ID_TI_1520 0xac55 #define PCI_VENDOR_ID_SONY 0x104d #define PCI_DEVICE_ID_SONY_CXD3222 0x8039 diff -Nru a/include/linux/pnp.h b/include/linux/pnp.h --- a/include/linux/pnp.h Fri Jun 27 14:20:05 2003 +++ b/include/linux/pnp.h Fri Jun 27 14:20:05 2003 @@ -400,7 +400,7 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data); int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data); int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data); -void pnp_init_resources(struct pnp_resource_table *table); +void pnp_init_resource_table(struct pnp_resource_table *table); int pnp_assign_resources(struct pnp_dev *dev, int depnum); int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode); int pnp_auto_config_dev(struct pnp_dev *dev); @@ -448,7 +448,7 @@ static inline int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { return -ENODEV; } static inline int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { return -ENODEV; } static inline int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { return -ENODEV; } -static inline void pnp_init_resources(struct pnp_resource_table *table) { } +static inline void pnp_init_resource_table(struct pnp_resource_table *table) { } static inline int pnp_assign_resources(struct pnp_dev *dev, int depnum) { return -ENODEV; } static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; } static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; } diff -Nru a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h --- a/include/linux/rtnetlink.h Fri Jun 27 14:20:00 2003 +++ b/include/linux/rtnetlink.h Fri Jun 27 14:20:00 2003 @@ -284,9 +284,17 @@ #define RTAX_REORDERING RTAX_REORDERING RTAX_HOPLIMIT, #define RTAX_HOPLIMIT RTAX_HOPLIMIT + RTAX_INITCWND, +#define RTAX_INITCWND RTAX_INITCWND + RTAX_FEATURES, +#define RTAX_FEATURES RTAX_FEATURES }; -#define RTAX_MAX RTAX_HOPLIMIT +#define RTAX_MAX RTAX_FEATURES + +#define RTAX_FEATURE_ECN 0x00000001 +#define RTAX_FEATURE_SACK 0x00000002 +#define RTAX_FEATURE_TIMESTAMP 0x00000004 struct rta_session { diff -Nru a/include/linux/security.h b/include/linux/security.h --- a/include/linux/security.h Fri Jun 27 14:19:59 2003 +++ b/include/linux/security.h Fri Jun 27 14:19:59 2003 @@ -45,6 +45,7 @@ extern void cap_capset_set (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); extern int cap_bprm_set_security (struct linux_binprm *bprm); extern void cap_bprm_compute_creds (struct linux_binprm *bprm); +extern int cap_bprm_secureexec(struct linux_binprm *bprm); extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); extern void cap_task_reparent_to_init (struct task_struct *p); extern int cap_syslog (int type); @@ -131,6 +132,12 @@ * first. * @bprm contains the linux_binprm structure. * Return 0 if the hook is successful and permission is granted. + * @bprm_secureexec: + * Return a boolean value (0 or 1) indicating whether a "secure exec" + * is required. The flag is passed in the auxiliary table + * on the initial stack to the ELF interpreter to indicate whether libc + * should enable secure mode. + * @bprm contains the linux_binprm structure. * * Security hooks for filesystem operations. * @@ -988,6 +995,7 @@ void (*bprm_compute_creds) (struct linux_binprm * bprm); int (*bprm_set_security) (struct linux_binprm * bprm); int (*bprm_check_security) (struct linux_binprm * bprm); + int (*bprm_secureexec) (struct linux_binprm * bprm); int (*sb_alloc_security) (struct super_block * sb); void (*sb_free_security) (struct super_block * sb); @@ -1246,11 +1254,17 @@ { return security_ops->bprm_set_security (bprm); } + static inline int security_bprm_check (struct linux_binprm *bprm) { return security_ops->bprm_check_security (bprm); } +static inline int security_bprm_secureexec (struct linux_binprm *bprm) +{ + return security_ops->bprm_secureexec (bprm); +} + static inline int security_sb_alloc (struct super_block *sb) { return security_ops->sb_alloc_security (sb); @@ -1905,6 +1919,11 @@ static inline int security_bprm_check (struct linux_binprm *bprm) { return 0; +} + +static inline int security_bprm_secureexec (struct linux_binprm *bprm) +{ + return cap_bprm_secureexec(bprm); } static inline int security_sb_alloc (struct super_block *sb) diff -Nru a/include/linux/smb_fs.h b/include/linux/smb_fs.h --- a/include/linux/smb_fs.h Fri Jun 27 14:19:59 2003 +++ b/include/linux/smb_fs.h Fri Jun 27 14:19:59 2003 @@ -198,7 +198,7 @@ return (SMB_I(i)->open == server_from_inode(i)->generation); } - +extern void smb_install_null_ops(struct smb_ops *); #endif /* __KERNEL__ */ #endif /* _LINUX_SMB_FS_H */ diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h --- a/include/linux/spinlock.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/spinlock.h Fri Jun 27 14:19:56 2003 @@ -146,8 +146,13 @@ /* * gcc versions before ~2.95 have a nasty bug with empty initializers. */ -typedef struct { } spinlock_t; -#define SPIN_LOCK_UNLOCKED (spinlock_t) { } +#if (__GNUC__ > 2) + typedef struct { } spinlock_t; + #define SPIN_LOCK_UNLOCKED (spinlock_t) { } +#else + typedef struct { int gcc_is_buggy; } spinlock_t; + #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } +#endif /* * If CONFIG_SMP is unset, declare the _raw_* definitions as nops diff -Nru a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h --- a/include/linux/sunrpc/cache.h Fri Jun 27 14:19:57 2003 +++ b/include/linux/sunrpc/cache.h Fri Jun 27 14:19:57 2003 @@ -80,8 +80,7 @@ int (*cache_show)(struct seq_file *m, struct cache_detail *cd, - struct cache_head *h, - char *pbuf); + struct cache_head *h); /* fields below this comment are for internal use * and should not be touched by cache owners @@ -155,8 +154,9 @@ * TEST tests if "tmp" matches "item" * INIT copies key information from "item" to "new" * UPDATE copies content information from "item" to "tmp" + * INPLACE is true if updates can happen inplace rather than allocating a new structure */ -#define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE) \ +#define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE,INPLACE) \ RTN *FNAME ARGS \ { \ RTN *tmp, *new=NULL; \ @@ -170,12 +170,12 @@ tmp = container_of(*hp, RTN, MEMBER); \ if (TEST) { /* found a match */ \ \ - if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \ + if (set && !INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \ break; \ \ atomic_inc(&tmp->MEMBER.refcnt); \ if (set) { \ - if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\ + if (!INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\ { /* need to swap in new */ \ RTN *t2; \ \ @@ -194,7 +194,7 @@ else read_unlock(&(DETAIL)->hash_lock); \ if (set) \ cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \ - if (set==1 && new) cache_fresh(DETAIL, &new->MEMBER, 0); \ + if (set && !INPLACE && new) cache_fresh(DETAIL, &new->MEMBER, 0); \ if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL); \ return tmp; \ } \ @@ -229,10 +229,10 @@ return NULL; \ } -#define DefineSimpleCacheLookup(STRUCT) \ +#define DefineSimpleCacheLookup(STRUCT,INPLACE) \ DefineCacheLookup(struct STRUCT, h, STRUCT##_lookup, (struct STRUCT *item, int set), /*no setup */, \ & STRUCT##_cache, STRUCT##_hash(item), STRUCT##_match(item, tmp),\ - STRUCT##_init(new, item), STRUCT##_update(tmp, item)) + STRUCT##_init(new, item), STRUCT##_update(tmp, item),INPLACE) #define cache_for_each(pos, detail, index, member) \ for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \ diff -Nru a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h --- a/include/linux/sunrpc/debug.h Fri Jun 27 14:19:55 2003 +++ b/include/linux/sunrpc/debug.h Fri Jun 27 14:19:55 2003 @@ -58,6 +58,7 @@ # define dfprintk(fac, args...) do { ifdebug(fac) printk(args); } while(0) # define RPC_IFDEBUG(x) x #else +# define ifdebug(fac) if (0) # define dfprintk(fac, args...) do ; while (0) # define RPC_IFDEBUG(x) #endif diff -Nru a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h --- a/include/linux/sunrpc/svc.h Fri Jun 27 14:19:57 2003 +++ b/include/linux/sunrpc/svc.h Fri Jun 27 14:19:57 2003 @@ -57,11 +57,11 @@ * Requests are copied into these pages as they arrive. Remaining * pages are available to write the reply into. * - * Currently pages are all re-used by the same server. Later we - * will use ->sendpage to transmit pages with reduced copying. In - * that case we will need to give away the page and allocate new ones. - * In preparation for this, we explicitly move pages off the recv - * list onto the transmit list, and back. + * Pages are sent using ->sendpage so each server thread needs to + * allocate more to replace those used in sending. To help keep track + * of these pages we have a receive list where all pages initialy live, + * and a send list where pages are moved to when there are to be part + * of a reply. * * We use xdr_buf for holding responses as it fits well with NFS * read responses (that have a header, and some data pages, and possibly @@ -72,8 +72,11 @@ * list. xdr_buf.tail points to the end of the first page. * This assumes that the non-page part of an rpc reply will fit * in a page - NFSd ensures this. lockd also has no trouble. + * + * Each request/reply pair can have at most one "payload", plus two pages, + * one for the request, and one for the reply. */ -#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 1) +#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2) static inline u32 svc_getu32(struct iovec *iov) { diff -Nru a/include/linux/usb_gadget.h b/include/linux/usb_gadget.h --- a/include/linux/usb_gadget.h Fri Jun 27 14:19:56 2003 +++ b/include/linux/usb_gadget.h Fri Jun 27 14:19:56 2003 @@ -10,11 +10,6 @@ * All Rights Reserved. * * This software is licensed under the GNU GPL version 2. - * - * ALTERNATIVELY, the kernel API documentation which is included in this - * software may also be licenced under the "GNU Free Documentation - * License" (version 1.2 or, at your choice, any later version), when - * used as part of the "USB Gadget API for Linux" documentation. */ #ifndef __LINUX_USB_GADGET_H diff -Nru a/include/linux/xfrm.h b/include/linux/xfrm.h --- a/include/linux/xfrm.h Fri Jun 27 14:19:54 2003 +++ b/include/linux/xfrm.h Fri Jun 27 14:19:54 2003 @@ -117,8 +117,9 @@ #define XFRM_MSG_EXPIRE (XFRM_MSG_BASE + 8) #define XFRM_MSG_UPDPOLICY (XFRM_MSG_BASE + 9) +#define XFRM_MSG_UPDSA (XFRM_MSG_BASE + 10) -#define XFRM_MSG_MAX (XFRM_MSG_UPDPOLICY+1) +#define XFRM_MSG_MAX (XFRM_MSG_UPDSA+1) struct xfrm_user_tmpl { struct xfrm_id id; @@ -136,6 +137,7 @@ __u16 encap_type; __u16 encap_sport; __u16 encap_dport; + xfrm_address_t encap_oa; }; /* Netlink message attributes. */ @@ -201,6 +203,7 @@ struct xfrm_user_acquire { struct xfrm_id id; xfrm_address_t saddr; + struct xfrm_selector sel; struct xfrm_userpolicy_info policy; __u32 aalgos; __u32 ealgos; diff -Nru a/include/media/saa7146.h b/include/media/saa7146.h --- a/include/media/saa7146.h Fri Jun 27 14:19:52 2003 +++ b/include/media/saa7146.h Fri Jun 27 14:19:52 2003 @@ -12,9 +12,12 @@ #include <linux/i2c.h> /* for i2c subsystem */ #include <asm/io.h> /* for accessing devices */ #include <linux/stringify.h> +#include <linux/vmalloc.h> /* for vmalloc() */ +#include <linux/mm.h> /* for vmalloc_to_page() */ +/* ugly, but necessary to build the dvb stuff under 2.4. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) - #include "compat.h" + #include "dvb_functions.h" #endif #define SAA7146_VERSION_CODE KERNEL_VERSION(0,5,0) @@ -30,7 +33,16 @@ #define DEBUG_VARIABLE saa7146_debug #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51) +#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_BASENAME),__FUNCTION__) +#define INFO(x) { printk("%s: ",__stringify(KBUILD_BASENAME)); printk x; } +#else #define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__) +#define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; } +#endif + +#define ERR(x) { DEBUG_PROLOG; printk x; } + #define DEB_S(x) if (0!=(DEBUG_VARIABLE&0x01)) { DEBUG_PROLOG; printk x; } /* simple debug messages */ #define DEB_D(x) if (0!=(DEBUG_VARIABLE&0x02)) { DEBUG_PROLOG; printk x; } /* more detailed debug messages */ #define DEB_EE(x) if (0!=(DEBUG_VARIABLE&0x04)) { DEBUG_PROLOG; printk x; } /* print enter and exit of functions */ @@ -39,9 +51,6 @@ #define DEB_INT(x) if (0!=(DEBUG_VARIABLE&0x20)) { DEBUG_PROLOG; printk x; } /* interrupt debug messages */ #define DEB_CAP(x) if (0!=(DEBUG_VARIABLE&0x40)) { DEBUG_PROLOG; printk x; } /* capture debug messages */ -#define ERR(x) { DEBUG_PROLOG; printk x; } -#define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; } - #define IER_DISABLE(x,y) \ saa7146_write(x, IER, saa7146_read(x, IER) & ~(y)); #define IER_ENABLE(x,y) \ @@ -97,6 +106,12 @@ void (*irq_func)(struct saa7146_dev*, u32* irq_mask); }; +struct saa7146_dma +{ + dma_addr_t dma_handle; + u32 *cpu_addr; +}; + struct saa7146_dev { struct module *module; @@ -127,13 +142,13 @@ /* i2c-stuff */ struct semaphore i2c_lock; u32 i2c_bitrate; - u32 *i2c_mem; /* pointer to i2c memory */ + struct saa7146_dma d_i2c; /* pointer to i2c memory */ wait_queue_head_t i2c_wq; int i2c_op; /* memories */ - u32 *rps0; - u32 *rps1; + struct saa7146_dma d_rps0; + struct saa7146_dma d_rps1; }; /* from saa7146_i2c.c */ diff -Nru a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h --- a/include/media/saa7146_vv.h Fri Jun 27 14:19:53 2003 +++ b/include/media/saa7146_vv.h Fri Jun 27 14:19:53 2003 @@ -9,6 +9,16 @@ #define MAX_SAA7146_CAPTURE_BUFFERS 32 /* arbitrary */ #define BUFFER_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define WRITE_RPS0(x) do { \ + static int count = 0; \ + dev->d_rps0.cpu_addr[ count++ ] = cpu_to_le32(x); \ + } while (0); + +#define WRITE_RPS1(x) do { \ + static int count = 0; \ + dev->d_rps1.cpu_addr[ count++ ] = cpu_to_le32(x); \ + } while (0); + struct saa7146_video_dma { u32 base_odd; u32 base_even; @@ -126,7 +136,7 @@ int current_hps_source; int current_hps_sync; - u32 *clipping; /* pointer to clipping memory */ + struct saa7146_dma d_clipping; /* pointer to clipping memory */ }; #define SAA7146_EXCLUSIVE 0x1 diff -Nru a/include/net/ipv6.h b/include/net/ipv6.h --- a/include/net/ipv6.h Fri Jun 27 14:20:00 2003 +++ b/include/net/ipv6.h Fri Jun 27 14:20:00 2003 @@ -23,6 +23,8 @@ #define SIN6_LEN_RFC2133 24 +#define IPV6_MAXPLEN 65535 + /* * NextHeader field of IPv6 header */ diff -Nru a/include/net/irda/au1000_ircc.h b/include/net/irda/au1000_ircc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/net/irda/au1000_ircc.h Fri Jun 27 14:20:06 2003 @@ -0,0 +1,128 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Au1000 IrDA driver. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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. + */ + +#ifndef AU1000_IRCC_H +#define AU1000_IRCC_H + +#include <linux/time.h> + +#include <linux/spinlock.h> +#include <linux/pm.h> +#include <asm/io.h> + +#define NUM_IR_IFF 1 +#define NUM_IR_DESC 64 +#define RING_SIZE_4 0x0 +#define RING_SIZE_16 0x3 +#define RING_SIZE_64 0xF +#define MAX_NUM_IR_DESC 64 +#define MAX_BUF_SIZE 2048 + +#define BPS_115200 0 +#define BPS_57600 1 +#define BPS_38400 2 +#define BPS_19200 5 +#define BPS_9600 11 +#define BPS_2400 47 + +/* Ring descriptor flags */ +#define AU_OWN (1<<7) /* tx,rx */ + +#define IR_DIS_CRC (1<<6) /* tx */ +#define IR_BAD_CRC (1<<5) /* tx */ +#define IR_NEED_PULSE (1<<4) /* tx */ +#define IR_FORCE_UNDER (1<<3) /* tx */ +#define IR_DISABLE_TX (1<<2) /* tx */ +#define IR_HW_UNDER (1<<0) /* tx */ +#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER) + +#define IR_PHY_ERROR (1<<6) /* rx */ +#define IR_CRC_ERROR (1<<5) /* rx */ +#define IR_MAX_LEN (1<<4) /* rx */ +#define IR_FIFO_OVER (1<<3) /* rx */ +#define IR_SIR_ERROR (1<<2) /* rx */ +#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \ + IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR) + +typedef struct db_dest { + struct db_dest *pnext; + volatile u32 *vaddr; + dma_addr_t dma_addr; +} db_dest_t; + + +typedef struct ring_desc { + u8 count_0; /* 7:0 */ + u8 count_1; /* 12:8 */ + u8 reserved; + u8 flags; + u8 addr_0; /* 7:0 */ + u8 addr_1; /* 15:8 */ + u8 addr_2; /* 23:16 */ + u8 addr_3; /* 31:24 */ +} ring_dest_t; + + +/* Private data for each instance */ +struct au1k_private { + + db_dest_t *pDBfree; + db_dest_t db[2*NUM_IR_DESC]; + volatile ring_dest_t *rx_ring[NUM_IR_DESC]; + volatile ring_dest_t *tx_ring[NUM_IR_DESC]; + db_dest_t *rx_db_inuse[NUM_IR_DESC]; + db_dest_t *tx_db_inuse[NUM_IR_DESC]; + u32 rx_head; + u32 tx_head; + u32 tx_tail; + u32 tx_full; + + iobuff_t rx_buff; + + struct net_device *netdev; + struct net_device_stats stats; + + struct timeval stamp; + struct timeval now; + struct qos_info qos; + struct irlap_cb *irlap; + + u8 open; + u32 flags; /* Interface flags */ + u32 speed; + u32 newspeed; + + u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ + struct timer_list timer; + + spinlock_t lock; /* For serializing operations */ + struct pm_dev *dev; +}; +#endif /* AU1000_IRCC_H */ diff -Nru a/include/net/irda/vlsi_ir.h b/include/net/irda/vlsi_ir.h --- a/include/net/irda/vlsi_ir.h Fri Jun 27 14:19:58 2003 +++ b/include/net/irda/vlsi_ir.h Fri Jun 27 14:19:58 2003 @@ -3,9 +3,9 @@ * * vlsi_ir.h: VLSI82C147 PCI IrDA controller driver for Linux * - * Version: 0.4 + * Version: 0.4a * - * Copyright (c) 2001-2002 Martin Diehl + * Copyright (c) 2001-2003 Martin Diehl * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -730,9 +730,7 @@ u32 cfg_space[64/sizeof(u32)]; u8 resume_ok; -#ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; -#endif } vlsi_irda_dev_t; diff -Nru a/include/net/ndisc.h b/include/net/ndisc.h --- a/include/net/ndisc.h Fri Jun 27 14:20:00 2003 +++ b/include/net/ndisc.h Fri Jun 27 14:20:00 2003 @@ -56,20 +56,6 @@ __u8 nd_opt_len; } __attribute__((__packed__)); -struct ndisc_options { - struct nd_opt_hdr *nd_opt_array[7]; - struct nd_opt_hdr *nd_opt_piend; -}; - -#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR] -#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR] -#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO] -#define nd_opts_pi_end nd_opt_piend -#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR] -#define nd_opts_mtu nd_opt_array[ND_OPT_MTU] - -extern struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, struct nd_opt_hdr *end); -extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, struct ndisc_options *ndopts); extern int ndisc_init(struct net_proto_family *ops); diff -Nru a/include/net/sctp/constants.h b/include/net/sctp/constants.h --- a/include/net/sctp/constants.h Fri Jun 27 14:19:55 2003 +++ b/include/net/sctp/constants.h Fri Jun 27 14:19:55 2003 @@ -267,7 +267,8 @@ * nearest power of 2. */ enum { SCTP_MIN_PMTU = 576 }; -enum { SCTP_MAX_DUP_TSNS = 128 }; +enum { SCTP_MAX_DUP_TSNS = 16 }; +enum { SCTP_MAX_GABS = 16 }; typedef enum { SCTP_COUNTER_INIT_ERROR, diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h --- a/include/net/sctp/sctp.h Fri Jun 27 14:19:54 2003 +++ b/include/net/sctp/sctp.h Fri Jun 27 14:19:54 2003 @@ -39,6 +39,7 @@ * Daisy Chang <daisyc@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com> * Ardelle Fan <ardelle.fan@intel.com> + * Ryan Layer <rmlayer@us.ibm.com> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -311,6 +312,11 @@ #else static inline void sctp_sysctl_register(void) { return; } static inline void sctp_sysctl_unregister(void) { return; } +static inline int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context) { + return -ENOSYS; +} #endif /* Size of Supported Address Parameter for 'x' address types. */ @@ -470,7 +476,7 @@ WORD_ROUND(ntohs(err->length));\ err = (sctp_errhdr_t *)((void *)err + \ WORD_ROUND(ntohs(err->length)))) - + /* Round an int up to the next multiple of 4. */ #define WORD_ROUND(s) (((s)+3)&~3) @@ -592,7 +598,7 @@ /* Is the association in this state? */ #define sctp_state(asoc, state) __sctp_state((asoc), (SCTP_STATE_##state)) -int static inline __sctp_state(const struct sctp_association *asoc, +int static inline __sctp_state(const struct sctp_association *asoc, sctp_state_t state) { return asoc->state == state; diff -Nru a/include/net/sctp/sla1.h b/include/net/sctp/sla1.h --- a/include/net/sctp/sla1.h Fri Jun 27 14:19:55 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,80 +0,0 @@ -/* SCTP reference Implementation - * Copyright (C) 1999 Cisco, Inc. - * Copyright (C) 1999 Motorola, Inc. - * - * This file originates from Randy Stewart's SCTP reference Implementation. - * - * The SCTP reference implementation is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * ************************ - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Please send any bug reports or fixes you make to the - * email address(es): - * lksctp developers <lksctp-developers@lists.sourceforge.net> - * - * Or submit a bug report through the following website: - * http://www.sf.net/projects/lksctp - * - * Written or modified by: - * Randy Stewart <rstewar1@email.mot.com> - * Ken Morneau <kmorneau@cisco.com> - * Qiaobing Xie <qxie1@email.mot.com> - */ - -#ifndef __SLA1_h__ -#define __SLA1_h__ - -struct SLA_1_Context { - unsigned int A; - unsigned int B; - unsigned int C; - unsigned int D; - unsigned int E; - unsigned int H0; - unsigned int H1; - unsigned int H2; - unsigned int H3; - unsigned int H4; - unsigned int words[80]; - unsigned int TEMP; - - /* block I am collecting to process */ - char SLAblock[64]; - - /* collected so far */ - int howManyInBlock; - unsigned int runningTotal; -}; - - -#define F1(B,C,D) (((B & C) | ((~B) & D))) /* 0 <= t <= 19 */ -#define F2(B,C,D) (B ^ C ^ D) /* 20 <= t <= 39 */ -#define F3(B,C,D) ((B & C) | (B & D) | (C & D)) /* 40 <= t <= 59 */ -#define F4(B,C,D) (B ^ C ^ D) /*600 <= t <= 79 */ -/* circular shift */ - -#define CSHIFT(A,B) ((B << A) | (B >> (32-A))) - -#define K1 0x5a827999 /* 0 <= t <= 19 */ -#define K2 0x6ed9eba1 /* 20 <= t <= 39 */ -#define K3 0x8f1bbcdc /* 40 <= t <= 59 */ -#define K4 0xca62c1d6 /* 60 <= t <= 79 */ - -#define H0INIT 0x67452301 -#define H1INIT 0xefcdab89 -#define H2INIT 0x98badcfe -#define H3INIT 0x10325476 -#define H4INIT 0xc3d2e1f0 - -extern void SLA1_Init(struct SLA_1_Context *); -extern void SLA1_Process(struct SLA_1_Context *, const unsigned char *, int); -extern void SLA1_Final(struct SLA_1_Context *, unsigned char *); - -#endif diff -Nru a/include/net/sctp/sm.h b/include/net/sctp/sm.h --- a/include/net/sctp/sm.h Fri Jun 27 14:19:56 2003 +++ b/include/net/sctp/sm.h Fri Jun 27 14:19:56 2003 @@ -84,7 +84,7 @@ typedef void (sctp_timer_event_t) (unsigned long); typedef struct { sctp_state_fn_t *fn; - char *name; + const char *name; } sctp_sm_table_entry_t; /* A naming convention of "sctp_sf_xxx" applies to all the state functions @@ -176,9 +176,6 @@ sctp_state_fn_t sctp_sf_do_9_2_reshut; sctp_state_fn_t sctp_sf_do_9_2_shutack; -sctp_state_fn_t lucky; -sctp_state_fn_t other_stupid; - /* Prototypes for timeout event state functions. Not in use. */ sctp_state_fn_t sctp_do_4_2_reinit; sctp_state_fn_t sctp_do_4_3_reecho; @@ -193,9 +190,9 @@ /* Prototypes for utility support functions. */ __u8 sctp_get_chunk_type(struct sctp_chunk *chunk); -sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, - sctp_state_t state, - sctp_subtype_t event_subtype); +const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t, + sctp_state_t, + sctp_subtype_t); int sctp_chunk_iif(const struct sctp_chunk *); struct sctp_association *sctp_make_temp_asoc(const struct sctp_endpoint *, struct sctp_chunk *, @@ -284,20 +281,13 @@ int gfp); /* 2nd level prototypes */ -int -sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype, - sctp_state_t state, - struct sctp_endpoint *ep, - struct sctp_association *asoc, - void *event_arg, - sctp_disposition_t status, - sctp_cmd_seq_t *retval, - int gfp); +int sctp_cmd_interpreter(sctp_event_t, sctp_subtype_t, sctp_state_t, + struct sctp_endpoint *, struct sctp_association *, + void *event_arg, sctp_disposition_t, + sctp_cmd_seq_t *retval, int gfp); int sctp_gen_sack(struct sctp_association *, int force, sctp_cmd_seq_t *); -void sctp_do_TSNdup(struct sctp_association *, struct sctp_chunk *, long gap); - void sctp_generate_t3_rtx_event(unsigned long peer); void sctp_generate_heartbeat_event(unsigned long peer); @@ -311,7 +301,7 @@ const struct sctp_chunk *); void sctp_ootb_pkt_free(struct sctp_packet *); -sctp_cookie_param_t * +struct sctp_cookie_param * sctp_pack_cookie(const struct sctp_endpoint *, const struct sctp_association *, const struct sctp_chunk *, int *cookie_len, const __u8 *, int addrs_len); @@ -332,18 +322,18 @@ __u32 sctp_generate_tsn(const struct sctp_endpoint *); /* 4th level prototypes */ -void sctp_param2sockaddr(union sctp_addr *addr, sctp_addr_param_t *, +void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *, __u16 port, int iif); int sctp_addr2sockaddr(const union sctp_params, union sctp_addr *); -int sockaddr2sctp_addr(const union sctp_addr *, sctp_addr_param_t *); +int sockaddr2sctp_addr(const union sctp_addr *, union sctp_addr_param *); /* Extern declarations for major data structures. */ -sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t); -extern sctp_sm_table_entry_t +const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t, sctp_state_t); +extern const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES]; -extern sctp_sm_table_entry_t +extern const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES]; -extern sctp_sm_table_entry_t +extern const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES]; extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES]; diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h --- a/include/net/sctp/structs.h Fri Jun 27 14:20:06 2003 +++ b/include/net/sctp/structs.h Fri Jun 27 14:20:06 2003 @@ -14,7 +14,7 @@ * * The SCTP reference implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * ************************ + * ************************ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * @@ -31,18 +31,20 @@ * http://www.sf.net/projects/lksctp * * Written or modified by: - * Randall Stewart <randall@sctp.chicago.il.us> - * Ken Morneau <kmorneau@cisco.com> - * Qiaobing Xie <qxie1@email.mot.com> + * Randall Stewart <randall@sctp.chicago.il.us> + * Ken Morneau <kmorneau@cisco.com> + * Qiaobing Xie <qxie1@email.mot.com> * La Monte H.P. Yarroll <piggy@acm.org> - * Karl Knutson <karl@athena.chicago.il.us> - * Jon Grimm <jgrimm@us.ibm.com> - * Xingang Guo <xingang.guo@intel.com> - * Hui Huang <hui.huang@nokia.com> - * Sridhar Samudrala <sri@us.ibm.com> + * Karl Knutson <karl@athena.chicago.il.us> + * Jon Grimm <jgrimm@us.ibm.com> + * Xingang Guo <xingang.guo@intel.com> + * Hui Huang <hui.huang@nokia.com> + * Sridhar Samudrala <sri@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com> - * Dajiang Zhang <dajiang.zhang@nokia.com> - * Ardelle Fan <ardelle.fan@intel.com> + * Dajiang Zhang <dajiang.zhang@nokia.com> + * Ardelle Fan <ardelle.fan@intel.com> + * Ryan Layer <rmlayer@us.ibm.com> + * Anup Pemmaiah <pemmaiah@cc.usu.edu> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -54,12 +56,12 @@ #include <linux/time.h> /* We get struct timespec. */ #include <linux/socket.h> /* linux/in.h needs this!! */ #include <linux/in.h> /* We get struct sockaddr_in. */ -#include <linux/in6.h> /* We get struct in6_addr */ +#include <linux/in6.h> /* We get struct in6_addr */ #include <asm/param.h> /* We get MAXHOSTNAMELEN. */ #include <asm/atomic.h> /* This gets us atomic counters. */ #include <linux/skbuff.h> /* We need sk_buff_head. */ -#include <linux/workqueue.h> /* We need tq_struct. */ -#include <linux/sctp.h> /* We need sctp* header structs. */ +#include <linux/workqueue.h> /* We need tq_struct. */ +#include <linux/sctp.h> /* We need sctp* header structs. */ /* A convenience structure for handling sockaddr structures. * We should wean ourselves off this. @@ -93,11 +95,11 @@ /* Structures useful for managing bind/connect. */ struct sctp_bind_bucket { - unsigned short port; + unsigned short port; unsigned short fastreuse; struct sctp_bind_bucket *next; struct sctp_bind_bucket **pprev; - struct hlist_head sk_list; + struct hlist_head owner; }; struct sctp_bind_hashbucket { @@ -118,11 +120,11 @@ * * The following protocol parameters are RECOMMENDED: * - * RTO.Initial - 3 seconds - * RTO.Min - 1 second - * RTO.Max - 60 seconds - * RTO.Alpha - 1/8 (3 when converted to right shifts.) - * RTO.Beta - 1/4 (2 when converted to right shifts.) + * RTO.Initial - 3 seconds + * RTO.Min - 1 second + * RTO.Max - 60 seconds + * RTO.Alpha - 1/8 (3 when converted to right shifts.) + * RTO.Beta - 1/4 (2 when converted to right shifts.) */ __u32 rto_initial; __u32 rto_min; @@ -137,24 +139,24 @@ /* Max.Burst - 4 */ int max_burst; - /* Valid.Cookie.Life - 60 seconds */ + /* Valid.Cookie.Life - 60 seconds */ int valid_cookie_life; /* Whether Cookie Preservative is enabled(1) or not(0) */ int cookie_preserve_enable; /* Association.Max.Retrans - 10 attempts - * Path.Max.Retrans - 5 attempts (per destination address) - * Max.Init.Retransmits - 8 attempts + * Path.Max.Retrans - 5 attempts (per destination address) + * Max.Init.Retransmits - 8 attempts */ int max_retrans_association; int max_retrans_path; int max_retrans_init; - /* HB.interval - 30 seconds */ + /* HB.interval - 30 seconds */ int hb_interval; - /* The following variables are implementation specific. */ + /* The following variables are implementation specific. */ /* Default initialization values to be applied to new associations. */ __u16 max_instreams; @@ -173,7 +175,7 @@ int assoc_hashsize; struct sctp_hashbucket *assoc_hashbucket; - /* This is the sctp port control hash. */ + /* This is the sctp port control hash. */ int port_hashsize; int port_rover; spinlock_t port_alloc_lock; /* Protects port_rover. */ @@ -183,7 +185,7 @@ * We actively maintain this complete list of interfaces on * the system by catching routing events. * - * It is a list of struct sockaddr_storage_list. + * It is a list of sctp_sockaddr_entry. */ struct list_head local_addr_list; spinlock_t local_addr_lock; @@ -223,12 +225,12 @@ int (*sctp_xmit) (struct sk_buff *skb, struct sctp_transport *, int ipfragok); - int (*setsockopt) (struct sock *sk, + int (*setsockopt) (struct sock *sk, int level, int optname, char *optval, int optlen); - int (*getsockopt) (struct sock *sk, + int (*getsockopt) (struct sock *sk, int level, int optname, char *optval, @@ -236,37 +238,37 @@ struct dst_entry *(*get_dst) (struct sctp_association *asoc, union sctp_addr *daddr, union sctp_addr *saddr); - void (*get_saddr) (struct sctp_association *asoc, + void (*get_saddr) (struct sctp_association *asoc, struct dst_entry *dst, union sctp_addr *daddr, - union sctp_addr *saddr); - void (*copy_addrlist) (struct list_head *, + union sctp_addr *saddr); + void (*copy_addrlist) (struct list_head *, struct net_device *); - void (*dst_saddr) (union sctp_addr *saddr, + void (*dst_saddr) (union sctp_addr *saddr, struct dst_entry *dst, unsigned short port); - int (*cmp_addr) (const union sctp_addr *addr1, + int (*cmp_addr) (const union sctp_addr *addr1, const union sctp_addr *addr2); - void (*addr_copy) (union sctp_addr *dst, + void (*addr_copy) (union sctp_addr *dst, union sctp_addr *src); - void (*from_skb) (union sctp_addr *, + void (*from_skb) (union sctp_addr *, struct sk_buff *skb, int saddr); - void (*from_sk) (union sctp_addr *, + void (*from_sk) (union sctp_addr *, struct sock *sk); - void (*to_sk_saddr) (union sctp_addr *, + void (*to_sk_saddr) (union sctp_addr *, struct sock *sk); - void (*to_sk_daddr) (union sctp_addr *, + void (*to_sk_daddr) (union sctp_addr *, struct sock *sk); - int (*addr_valid) (union sctp_addr *); - sctp_scope_t (*scope) (union sctp_addr *); - void (*inaddr_any) (union sctp_addr *, unsigned short); - int (*is_any) (const union sctp_addr *); - int (*available) (const union sctp_addr *); - int (*skb_iif) (const struct sk_buff *sk); - int (*is_ce) (const struct sk_buff *sk); + int (*addr_valid) (union sctp_addr *); + sctp_scope_t (*scope) (union sctp_addr *); + void (*inaddr_any) (union sctp_addr *, unsigned short); + int (*is_any) (const union sctp_addr *); + int (*available) (const union sctp_addr *); + int (*skb_iif) (const struct sk_buff *sk); + int (*is_ce) (const struct sk_buff *sk); void (*seq_dump_addr)(struct seq_file *seq, - union sctp_addr *addr); + union sctp_addr *addr); __u16 net_header_len; int sockaddr_len; sa_family_t sa_family; @@ -325,6 +327,7 @@ struct sctp_rtoinfo rtoinfo; struct sctp_paddrparams paddrparam; struct sctp_event_subscribe subscribe; + struct sctp_assocparams assocparams; int user_frag; __u32 autoclose; __u8 nodelay; @@ -347,23 +350,23 @@ * */ -typedef struct sctp_cookie { +struct sctp_cookie { + + /* My : Tag expected in every inbound packet and sent + * Verification: in the INIT or INIT ACK chunk. + * Tag : + */ + __u32 my_vtag; + + /* Peer's : Tag expected in every outbound packet except + * Verification: in the INIT chunk. + * Tag : + */ + __u32 peer_vtag; - /* My : Tag expected in every inbound packet and sent - * Verification: in the INIT or INIT ACK chunk. - * Tag : - */ - __u32 my_vtag; - - /* Peer's : Tag expected in every outbound packet except - * Verification: in the INIT chunk. - * Tag : - */ - __u32 peer_vtag; - - /* The rest of these are not from the spec, but really need to - * be in the cookie. - */ + /* The rest of these are not from the spec, but really need to + * be in the cookie. + */ /* My Tie Tag : Assist in discovering a restarting association. */ __u32 my_ttag; @@ -371,8 +374,8 @@ /* Peer's Tie Tag: Assist in discovering a restarting association. */ __u32 peer_ttag; - /* When does this cookie expire? */ - struct timeval expiration; + /* When does this cookie expire? */ + struct timeval expiration; /* Number of inbound/outbound streams which are set * and negotiated during the INIT process. @@ -380,7 +383,7 @@ __u16 sinit_num_ostreams; __u16 sinit_max_instreams; - /* This is the first sequence number I used. */ + /* This is the first sequence number I used. */ __u32 initial_tsn; /* This holds the originating address of the INIT packet. */ @@ -393,38 +396,38 @@ * the association TCB is re-constructed from the cookie. */ __u32 raw_addr_list_len; - sctp_init_chunk_t peer_init[0]; -} sctp_cookie_t; + struct sctp_init_chunk peer_init[0]; +}; /* The format of our cookie that we send to our peer. */ -typedef struct sctp_signed_cookie { +struct sctp_signed_cookie { __u8 signature[SCTP_SECRET_SIZE]; - sctp_cookie_t c; -} sctp_signed_cookie_t; + struct sctp_cookie c; +}; /* This is another convenience type to allocate memory for address * params for the maximum size and pass such structures around * internally. */ -typedef union { - sctp_ipv4addr_param_t v4; - sctp_ipv6addr_param_t v6; -} sctp_addr_param_t; +union sctp_addr_param { + struct sctp_ipv4addr_param v4; + struct sctp_ipv6addr_param v6; +}; /* A convenience type to allow walking through the various * parameters and avoid casting all over the place. */ union sctp_params { void *v; - sctp_paramhdr_t *p; - sctp_cookie_preserve_param_t *life; - sctp_hostname_param_t *dns; - sctp_cookie_param_t *cookie; - sctp_supported_addrs_param_t *sat; - sctp_ipv4addr_param_t *v4; - sctp_ipv6addr_param_t *v6; - sctp_addr_param_t *addr; + struct sctp_paramhdr *p; + struct sctp_cookie_preserve_param *life; + struct sctp_hostname_param *dns; + struct sctp_cookie_param *cookie; + struct sctp_supported_addrs_param *sat; + struct sctp_ipv4addr_param *v4; + struct sctp_ipv6addr_param *v6; + union sctp_addr_param *addr; }; /* RFC 2960. Section 3.3.5 Heartbeat. @@ -435,7 +438,7 @@ * HEARTBEAT is sent (see Section 8.3). */ typedef struct sctp_sender_hb_info { - sctp_paramhdr_t param_hdr; + struct sctp_paramhdr param_hdr; union sctp_addr daddr; unsigned long sent_at; } sctp_sender_hb_info_t __attribute__((packed)); @@ -476,7 +479,7 @@ return stream->ssn[id]; } -/* Return the next SSN number for this stream. */ +/* Return the next SSN number for this stream. */ static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id) { return stream->ssn[id]++; @@ -555,23 +558,22 @@ union sctp_params param_hdr; union { __u8 *v; - sctp_datahdr_t *data_hdr; - sctp_inithdr_t *init_hdr; - sctp_sackhdr_t *sack_hdr; - sctp_heartbeathdr_t *hb_hdr; - sctp_sender_hb_info_t *hbs_hdr; - sctp_shutdownhdr_t *shutdown_hdr; - sctp_signed_cookie_t *cookie_hdr; - sctp_ecnehdr_t *ecne_hdr; - sctp_cwrhdr_t *ecn_cwr_hdr; - sctp_errhdr_t *err_hdr; + struct sctp_datahdr *data_hdr; + struct sctp_inithdr *init_hdr; + struct sctp_sackhdr *sack_hdr; + struct sctp_heartbeathdr *hb_hdr; + struct sctp_sender_hb_info *hbs_hdr; + struct sctp_shutdownhdr *shutdown_hdr; + struct sctp_signed_cookie *cookie_hdr; + struct sctp_ecnehdr *ecne_hdr; + struct sctp_cwrhdr *ecn_cwr_hdr; + struct sctp_errhdr *err_hdr; } subh; __u8 *chunk_end; - sctp_chunkhdr_t *chunk_hdr; - - sctp_sctphdr_t *sctp_hdr; + struct sctp_chunkhdr *chunk_hdr; + struct sctphdr *sctp_hdr; /* This needs to be recoverable for SCTP_SEND_FAILED events. */ struct sctp_sndrcvinfo sinfo; @@ -595,7 +597,7 @@ /* For an inbound chunk, this tells us where it came from. * For an outbound chunk, it tells us where we'd like it to - * go. It is NULL if we have no preference. + * go. It is NULL if we have no preference. */ struct sctp_transport *transport; @@ -632,7 +634,7 @@ * sin_port -- ordinary port number * sin_addr -- cast to either (struct in_addr) or (struct in6_addr) */ -struct sockaddr_storage_list { +struct sctp_sockaddr_entry { struct list_head list; union sctp_addr a; }; @@ -685,22 +687,22 @@ typedef int (sctp_outq_ehandler_t)(struct sctp_outq *); typedef struct sctp_packet *(sctp_outq_ohandler_init_t) (struct sctp_packet *, - struct sctp_transport *, - __u16 sport, - __u16 dport); + struct sctp_transport *, + __u16 sport, + __u16 dport); typedef struct sctp_packet *(sctp_outq_ohandler_config_t) - (struct sctp_packet *, + (struct sctp_packet *, __u32 vtag, int ecn_capable, sctp_packet_phandler_t *get_prepend_chunk); typedef sctp_xmit_t (sctp_outq_ohandler_t)(struct sctp_packet *, - struct sctp_chunk *); + struct sctp_chunk *); typedef int (sctp_outq_ohandler_force_t)(struct sctp_packet *); sctp_outq_ohandler_init_t sctp_packet_init; sctp_outq_ohandler_config_t sctp_packet_config; -sctp_outq_ohandler_t sctp_packet_append_chunk; -sctp_outq_ohandler_t sctp_packet_transmit_chunk; +sctp_outq_ohandler_t sctp_packet_append_chunk; +sctp_outq_ohandler_t sctp_packet_transmit_chunk; sctp_outq_ohandler_force_t sctp_packet_transmit; void sctp_packet_free(struct sctp_packet *); @@ -710,19 +712,19 @@ * * RFC2960 Section 1.4 Key Terms * - * o Transport address: A Transport Address is traditionally defined - * by Network Layer address, Transport Layer protocol and Transport - * Layer port number. In the case of SCTP running over IP, a - * transport address is defined by the combination of an IP address - * and an SCTP port number (where SCTP is the Transport protocol). + * o Transport address: A Transport Address is traditionally defined + * by Network Layer address, Transport Layer protocol and Transport + * Layer port number. In the case of SCTP running over IP, a + * transport address is defined by the combination of an IP address + * and an SCTP port number (where SCTP is the Transport protocol). * * RFC2960 Section 7.1 SCTP Differences from TCP Congestion control * - * o The sender keeps a separate congestion control parameter set for - * each of the destination addresses it can send to (not each - * source-destination pair but for each destination). The parameters - * should decay if the address is not used for a long enough time - * period. + * o The sender keeps a separate congestion control parameter set for + * each of the destination addresses it can send to (not each + * source-destination pair but for each destination). The parameters + * should decay if the address is not used for a long enough time + * period. * */ struct sctp_transport { @@ -731,12 +733,12 @@ /* Reference counting. */ atomic_t refcnt; - int dead; + int dead; /* This is the peer's IP address and port. */ union sctp_addr ipaddr; - /* These are the functions we call to handle LLP stuff. */ + /* These are the functions we call to handle LLP stuff. */ struct sctp_af *af_specific; /* Which association do we belong to? */ @@ -750,33 +752,33 @@ * address list derived from the INIT or INIT ACK chunk, a * number of data elements needs to be maintained including: */ - __u32 rtt; /* This is the most recent RTT. */ + __u32 rtt; /* This is the most recent RTT. */ - /* RTO : The current retransmission timeout value. */ + /* RTO : The current retransmission timeout value. */ __u32 rto; /* RTTVAR : The current RTT variation. */ __u32 rttvar; - /* SRTT : The current smoothed round trip time. */ + /* SRTT : The current smoothed round trip time. */ __u32 srtt; /* RTO-Pending : A flag used to track if one of the DATA - * chunks sent to this address is currently being - * used to compute a RTT. If this flag is 0, - * the next DATA chunk sent to this destination - * should be used to compute a RTT and this flag - * should be set. Every time the RTT - * calculation completes (i.e. the DATA chunk - * is SACK'd) clear this flag. - */ + * chunks sent to this address is currently being + * used to compute a RTT. If this flag is 0, + * the next DATA chunk sent to this destination + * should be used to compute a RTT and this flag + * should be set. Every time the RTT + * calculation completes (i.e. the DATA chunk + * is SACK'd) clear this flag. + */ int rto_pending; /* * These are the congestion stats. */ - /* cwnd : The current congestion window. */ - __u32 cwnd; /* This is the actual cwnd. */ + /* cwnd : The current congestion window. */ + __u32 cwnd; /* This is the actual cwnd. */ /* ssthresh : The current slow start threshold value. */ __u32 ssthresh; @@ -789,7 +791,7 @@ /* Data that has been sent, but not acknowledged. */ __u32 flight_size; - /* PMTU : The current known path MTU. */ + /* PMTU : The current known path MTU. */ __u32 pmtu; /* Destination */ @@ -819,23 +821,23 @@ unsigned long last_time_ecne_reduced; /* active : The current active state of this destination, - * : i.e. DOWN, UP, etc. + * : i.e. DOWN, UP, etc. */ int active; /* hb_allowed : The current heartbeat state of this destination, - * : i.e. ALLOW-HB, NO-HEARTBEAT, etc. + * : i.e. ALLOW-HB, NO-HEARTBEAT, etc. */ int hb_allowed; /* These are the error stats for this destination. */ - /* Error count : The current error count for this destination. */ + /* Error count : The current error count for this destination. */ unsigned short error_count; /* Error : Current error threshold for this destination * Threshold : i.e. what value marks the destination down if - * : errorCount reaches this value. + * : errorCount reaches this value. */ unsigned short error_threshold; @@ -845,7 +847,7 @@ */ int max_retrans; - /* Per : A timer used by each destination. + /* Per : A timer used by each destination. * Destination : * Timer : * @@ -874,10 +876,10 @@ /* State information saved for SFR_CACC algorithm. The key * idea in SFR_CACC is to maintain state at the sender on a * per-destination basis when a changeover happens. - * char changeover_active; - * char cycling_changeover; - * __u32 next_tsn_at_change; - * char cacc_saw_newack; + * char changeover_active; + * char cycling_changeover; + * __u32 next_tsn_at_change; + * char cacc_saw_newack; */ struct { /* An unsigned integer, which stores the next TSN to be @@ -938,7 +940,7 @@ */ struct work_struct immediate; - int malloced; /* Is this structure kfree()able? */ + int malloced; /* Is this structure kfree()able? */ }; struct sctp_inq *sctp_inq_new(void); @@ -955,7 +957,7 @@ * This structure covers sections 6.3, 6.4, 6.7, 6.8, 6.10, 7., 8.1, * and 8.2 of the v13 draft. * - * It handles retransmissions. The connection to the timeout portion + * It handles retransmissions. The connection to the timeout portion * of the state machine is through sctp_..._timeout() and timeout_handler. * * If you feed it SACKs, it will eat them. @@ -1001,7 +1003,7 @@ sctp_outq_ohandler_t *build_output; sctp_outq_ohandler_force_t *force_output; - /* How many unackd bytes do we have in-flight? */ + /* How many unackd bytes do we have in-flight? */ __u32 outstanding_bytes; /* Corked? */ @@ -1020,7 +1022,7 @@ void sctp_outq_free(struct sctp_outq*); int sctp_outq_tail(struct sctp_outq *, struct sctp_chunk *chunk); int sctp_outq_flush(struct sctp_outq *, int); -int sctp_outq_sack(struct sctp_outq *, sctp_sackhdr_t *); +int sctp_outq_sack(struct sctp_outq *, struct sctp_sackhdr *); int sctp_outq_is_empty(const struct sctp_outq *); int sctp_outq_set_output_handlers(struct sctp_outq *, sctp_outq_ohandler_init_t init, @@ -1045,8 +1047,8 @@ /* RFC 2960 12.1 Parameters necessary for the SCTP instance * - * SCTP Port: The local SCTP port number the endpoint is - * bound to. + * SCTP Port: The local SCTP port number the endpoint is + * bound to. */ __u16 port; @@ -1058,7 +1060,7 @@ */ struct list_head address_list; - int malloced; /* Are we kfree()able? */ + int malloced; /* Are we kfree()able? */ }; struct sctp_bind_addr *sctp_bind_addr_new(int gfp_mask); @@ -1095,13 +1097,13 @@ * local endpoint. * This common structure is useful for several purposes: * 1) Common interface for lookup routines. - * a) Subfunctions work for either endpoint or association - * b) Single interface to lookup allows hiding the lookup lock rather - * than acquiring it externally. + * a) Subfunctions work for either endpoint or association + * b) Single interface to lookup allows hiding the lookup lock rather + * than acquiring it externally. * 2) Common interface for the inbound chunk handling/state machine. * 3) Common object handling routines for reference counting, etc. * 4) Disentangle association lookup from endpoint lookup, where we - * do not have to find our endpoint to find our association. + * do not have to find our endpoint to find our association. * */ @@ -1120,14 +1122,14 @@ * malloced - Do we need to kfree this object? */ atomic_t refcnt; - char dead; - char malloced; + char dead; + char malloced; /* What socket does this endpoint belong to? */ struct sock *sk; /* This is where we receive inbound chunks. */ - struct sctp_inq inqueue; + struct sctp_inq inqueue; /* This substructure includes the defining parameters of the * endpoint: @@ -1165,22 +1167,22 @@ struct sctp_ep_common base; /* Associations: A list of current associations and mappings - * to the data consumers for each association. This - * may be in the form of a hash table or other - * implementation dependent structure. The data - * consumers may be process identification - * information such as file descriptors, named pipe - * pointer, or table pointers dependent on how SCTP - * is implemented. + * to the data consumers for each association. This + * may be in the form of a hash table or other + * implementation dependent structure. The data + * consumers may be process identification + * information such as file descriptors, named pipe + * pointer, or table pointers dependent on how SCTP + * is implemented. */ /* This is really a list of struct sctp_association entries. */ struct list_head asocs; /* Secret Key: A secret key used by this endpoint to compute - * the MAC. This SHOULD be a cryptographic quality - * random number with a sufficient length. + * the MAC. This SHOULD be a cryptographic quality + * random number with a sufficient length. * Discussion in [RFC1750] can be helpful in - * selection of the key. + * selection of the key. */ __u8 secret_key[SCTP_HOW_MANY_SECRETS][SCTP_SECRET_SIZE]; int current_key; @@ -1190,7 +1192,7 @@ /* Default timeouts. */ int timeouts[SCTP_NUM_TIMEOUT_TYPES]; - /* Various thresholds. */ + /* Various thresholds. */ /* Name for debugging output... */ char *debug_name; @@ -1267,11 +1269,11 @@ */ __u32 eyecatcher; - /* This is our parent endpoint. */ + /* This is our parent endpoint. */ struct sctp_endpoint *ep; /* These are those association elements needed in the cookie. */ - sctp_cookie_t c; + struct sctp_cookie c; /* This is all information about our peer. */ struct { @@ -1283,11 +1285,11 @@ /* transport_addr_list * - * Peer : A list of SCTP transport addresses that the + * Peer : A list of SCTP transport addresses that the * Transport : peer is bound to. This information is derived * Address : from the INIT or INIT ACK and is used to - * List : associate an inbound packet with a given - * : association. Normally this information is + * List : associate an inbound packet with a given + * : association. Normally this information is * : hashed or keyed for quick lookup and access * : of the TCB. * @@ -1303,8 +1305,8 @@ /* primary_path * * Primary : This is the current primary destination - * Path : transport address of the peer endpoint. It - * : may also specify a source transport address + * Path : transport address of the peer endpoint. It + * : may also specify a source transport address * : on this endpoint. * * All of these paths live on transport_addr_list. @@ -1343,25 +1345,25 @@ /* Pointer to last transport I have sent on. */ struct sctp_transport *last_sent_to; - /* This is the last transport I have received DATA on. */ + /* This is the last transport I have received DATA on. */ struct sctp_transport *last_data_from; /* * Mapping An array of bits or bytes indicating which out of * Array order TSN's have been received (relative to the - * Last Rcvd TSN). If no gaps exist, i.e. no out of - * order packets have been received, this array - * will be set to all zero. This structure may be - * in the form of a circular buffer or bit array. + * Last Rcvd TSN). If no gaps exist, i.e. no out of + * order packets have been received, this array + * will be set to all zero. This structure may be + * in the form of a circular buffer or bit array. * * Last Rcvd : This is the last TSN received in * TSN : sequence. This value is set initially by - * : taking the peer's Initial TSN, received in - * : the INIT or INIT ACK chunk, and subtracting - * : one from it. + * : taking the peer's Initial TSN, received in + * : the INIT or INIT ACK chunk, and subtracting + * : one from it. * * Throughout most of the specification this is called the - * "Cumulative TSN ACK Point". In this case, we + * "Cumulative TSN ACK Point". In this case, we * ignore the advice in 12.2 in favour of the term * used in the bulk of the text. This value is hidden * in tsn_map--we get it by calling sctp_tsnmap_get_ctsn(). @@ -1370,13 +1372,13 @@ __u8 _map[sctp_tsnmap_storage_size(SCTP_TSN_MAP_SIZE)]; /* Do we need to sack the peer? */ - __u8 sack_needed; + __u8 sack_needed; /* These are capabilities which our peer advertised. */ - __u8 ecn_capable; /* Can peer do ECN? */ - __u8 ipv4_address; /* Peer understands IPv4 addresses? */ - __u8 ipv6_address; /* Peer understands IPv6 addresses? */ + __u8 ecn_capable; /* Can peer do ECN? */ + __u8 ipv4_address; /* Peer understands IPv4 addresses? */ + __u8 ipv6_address; /* Peer understands IPv6 addresses? */ __u8 hostname_address;/* Peer understands DNS addresses? */ - sctp_inithdr_t i; + struct sctp_inithdr i; int cookie_len; void *cookie; @@ -1387,22 +1389,19 @@ /* State : A state variable indicating what state the * : association is in, i.e. COOKIE-WAIT, - * : COOKIE-ECHOED, ESTABLISHED, SHUTDOWN-PENDING, - * : SHUTDOWN-SENT, SHUTDOWN-RECEIVED, SHUTDOWN-ACK-SENT. + * : COOKIE-ECHOED, ESTABLISHED, SHUTDOWN-PENDING, + * : SHUTDOWN-SENT, SHUTDOWN-RECEIVED, SHUTDOWN-ACK-SENT. * - * Note: No "CLOSED" state is illustrated since if a - * association is "CLOSED" its TCB SHOULD be removed. + * Note: No "CLOSED" state is illustrated since if a + * association is "CLOSED" its TCB SHOULD be removed. * - * In this implementation we DO have a CLOSED + * In this implementation we DO have a CLOSED * state which is used during initiation and shutdown. * - * State takes values from SCTP_STATE_*. + * State takes values from SCTP_STATE_*. */ sctp_state_t state; - /* When did we enter this state? */ - int state_timestamp; - /* The cookie life I award for any cookie. */ struct timeval cookie_life; @@ -1411,12 +1410,6 @@ */ int overall_error_count; - /* Overall : The threshold for this association that if - * Error : the Overall Error Count reaches will cause - * Threshold : this association to be torn down. - */ - int overall_error_threshold; - /* These are the association's initial, max, and min RTO values. * These values will be initialized by system defaults, but can * be modified via the SCTP_RTOINFO socket option. @@ -1450,19 +1443,19 @@ struct sctp_transport *shutdown_last_sent_to; /* Next TSN : The next TSN number to be assigned to a new - * : DATA chunk. This is sent in the INIT or INIT - * : ACK chunk to the peer and incremented each - * : time a DATA chunk is assigned a TSN - * : (normally just prior to transmit or during + * : DATA chunk. This is sent in the INIT or INIT + * : ACK chunk to the peer and incremented each + * : time a DATA chunk is assigned a TSN + * : (normally just prior to transmit or during * : fragmentation). */ __u32 next_tsn; /* * Last Rcvd : This is the last TSN received in sequence. This value - * TSN : is set initially by taking the peer's Initial TSN, - * : received in the INIT or INIT ACK chunk, and - * : subtracting one from it. + * TSN : is set initially by taking the peer's Initial TSN, + * : received in the INIT or INIT ACK chunk, and + * : subtracting one from it. * * Most of RFC 2960 refers to this as the Cumulative TSN Ack Point. */ @@ -1502,7 +1495,7 @@ wait_queue_head_t wait; /* Association : The smallest PMTU discovered for all of the - * PMTU : peer's transport addresses. + * PMTU : peer's transport addresses. */ __u32 pmtu; @@ -1510,14 +1503,14 @@ __u32 frag_point; /* Ack State : This flag indicates if the next received - * : packet is to be responded to with a - * : SACK. This is initializedto 0. When a packet - * : is received it is incremented. If this value - * : reaches 2 or more, a SACK is sent and the - * : value is reset to 0. Note: This is used only - * : when no DATA chunks are received out of - * : order. When DATA chunks are out of order, - * : SACK's are not delayed (see Section 6). + * : packet is to be responded to with a + * : SACK. This is initializedto 0. When a packet + * : is received it is incremented. If this value + * : reaches 2 or more, a SACK is sent and the + * : value is reset to 0. Note: This is used only + * : when no DATA chunks are received out of + * : order. When DATA chunks are out of order, + * : SACK's are not delayed (see Section 6). */ /* Do we need to send an ack? * When counters[SctpCounterAckState] is above 1 we do! @@ -1531,7 +1524,7 @@ __u32 default_context; __u32 default_timetolive; - /* This tracks outbound ssn for a given stream. */ + /* This tracks outbound ssn for a given stream. */ struct sctp_ssnmap *ssnmap; /* All outbound chunks go through this structure. */ @@ -1545,7 +1538,7 @@ /* Last TSN that caused an ECNE Chunk to be sent. */ __u32 last_ecne_tsn; - /* Last TSN that caused a CWR Chunk to be sent. */ + /* Last TSN that caused a CWR Chunk to be sent. */ __u32 last_cwr_tsn; /* How many duplicated TSNs have we seen? */ @@ -1605,7 +1598,7 @@ * * In defining the ASCONF Chunk transfer procedures, it is * essential that these transfers MUST NOT cause congestion - * within the network. To achieve this, we place these + * within the network. To achieve this, we place these * restrictions on the transfer of ASCONF Chunks: * * R1) One and only one ASCONF Chunk MAY be in transit and @@ -1619,8 +1612,8 @@ * * * [I really think this is EXACTLY the sort of intelligence - * which already resides in sctp_outq. Please move this - * queue and its supporting logic down there. --piggy] + * which already resides in sctp_outq. Please move this + * queue and its supporting logic down there. --piggy] */ struct sk_buff_head addip_chunks; @@ -1673,7 +1666,7 @@ return asoc; } -/* These are function signatures for manipulating associations. */ +/* These are function signatures for manipulating associations. */ struct sctp_association * @@ -1710,16 +1703,16 @@ __u32 sctp_association_get_tsn_block(struct sctp_association *, int); void sctp_assoc_sync_pmtu(struct sctp_association *); -void sctp_assoc_rwnd_increase(struct sctp_association *, int); -void sctp_assoc_rwnd_decrease(struct sctp_association *, int); +void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned); +void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned); void sctp_assoc_set_primary(struct sctp_association *, struct sctp_transport *); int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *, int); int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *, - sctp_cookie_t *, int gfp); + struct sctp_cookie*, int gfp); int sctp_cmp_addr_exact(const union sctp_addr *ss1, - const union sctp_addr *ss2); + const union sctp_addr *ss2); struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); struct sctp_chunk *sctp_get_no_prepend(struct sctp_association *asoc); diff -Nru a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h --- a/include/net/sctp/tsnmap.h Fri Jun 27 14:19:59 2003 +++ b/include/net/sctp/tsnmap.h Fri Jun 27 14:19:59 2003 @@ -1,5 +1,8 @@ -/* SCTP kernel reference Implementation Copyright (C) 1999-2001 - * Cisco, Motorola, Intel, and International Business Machines Corp. +/* SCTP kernel reference Implementation + * Copyright (c) 1999-2000 Cisco, Inc. + * Copyright (c) 1999-2001 Motorola, Inc. + * Copyright (c) 2001-2003 International Business Machines, Corp. + * Copyright (c) 2001 Intel Corp. * * This file is part of the SCTP kernel reference Implementation * @@ -97,13 +100,16 @@ /* Data chunks pending receipt. used by SCTP_STATUS sockopt */ __u16 pending_data; - /* We record duplicate TSNs here. We clear this after + /* Record duplicate TSNs here. We clear this after * every SACK. Store up to SCTP_MAX_DUP_TSNS worth of * information. */ __u32 dup_tsns[SCTP_MAX_DUP_TSNS]; __u16 num_dup_tsns; + /* Record gap ack block information here. */ + struct sctp_gap_ack_block gabs[SCTP_MAX_GABS]; + int malloced; __u8 raw_map[0]; @@ -140,12 +146,18 @@ void sctp_tsnmap_mark(struct sctp_tsnmap *, __u32 tsn); /* Retrieve the Cumulative TSN ACK Point. */ -__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *); +static inline __u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map) +{ + return map->cumulative_tsn_ack_point; +} /* Retrieve the highest TSN we've seen. */ -__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *); +static inline __u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map) +{ + return map->max_tsn_seen; +} -/* How many Duplicate TSNs are stored? */ +/* How many duplicate TSNs are stored? */ static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map) { return map->num_dup_tsns; @@ -156,6 +168,27 @@ { map->num_dup_tsns = 0; return map->dup_tsns; +} + +/* How many gap ack blocks do we have recorded? */ +__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map); + +/* Refresh the count on pending data. */ +__u16 sctp_tsnmap_pending(struct sctp_tsnmap *map); + +/* Return pointer to gap ack blocks as needed by SACK. */ +static inline struct sctp_gap_ack_block *sctp_tsnmap_get_gabs(struct sctp_tsnmap *map) +{ + return map->gabs; +} + +/* Is there a gap in the TSN map? */ +static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map) +{ + int has_gap; + + has_gap = (map->cumulative_tsn_ack_point != map->max_tsn_seen); + return has_gap; } /* Mark a duplicate TSN. Note: limit the storage of duplicate TSN diff -Nru a/include/net/sctp/user.h b/include/net/sctp/user.h --- a/include/net/sctp/user.h Fri Jun 27 14:19:52 2003 +++ b/include/net/sctp/user.h Fri Jun 27 14:19:52 2003 @@ -40,6 +40,7 @@ * Karl Knutson <karl@athena.chicago.il.us> * Jon Grimm <jgrimm@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com> + * Ryan Layer <rmlayer@us.ibm.com> * * * Any bugs reported given to us we will try to fix... any fixes shared will @@ -517,10 +518,13 @@ */ struct sctp_assocparams { - __u16 sasoc_asocmaxrxt; sctp_assoc_t sasoc_assoc_id; + __u16 sasoc_asocmaxrxt; + __u16 sasoc_number_peer_destinations; + __u32 sasoc_peer_rwnd; + __u32 sasoc_local_rwnd; + __u32 sasoc_cookie_life; }; - /* * 7.1.9 Set Primary Address (SCTP_SET_PRIMARY_ADDR) diff -Nru a/include/net/tcp.h b/include/net/tcp.h --- a/include/net/tcp.h Fri Jun 27 14:19:53 2003 +++ b/include/net/tcp.h Fri Jun 27 14:19:53 2003 @@ -1244,7 +1244,7 @@ } } -extern __u32 tcp_init_cwnd(struct tcp_opt *tp); +extern __u32 tcp_init_cwnd(struct tcp_opt *tp, struct dst_entry *dst); /* Slow start with delack produces 3 packets of burst, so that * it is safe "de facto". diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h --- a/include/net/xfrm.h Fri Jun 27 14:20:00 2003 +++ b/include/net/xfrm.h Fri Jun 27 14:20:00 2003 @@ -767,6 +767,7 @@ unsigned short family); extern int xfrm_state_check_expire(struct xfrm_state *x); extern void xfrm_state_insert(struct xfrm_state *x); +extern int xfrm_state_replace(struct xfrm_state *x, int excl); extern int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb); extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family); extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); diff -Nru a/kernel/exit.c b/kernel/exit.c --- a/kernel/exit.c Fri Jun 27 14:20:01 2003 +++ b/kernel/exit.c Fri Jun 27 14:20:01 2003 @@ -41,7 +41,7 @@ detach_pid(p, PIDTYPE_PGID); detach_pid(p, PIDTYPE_SID); if (p->pid) - per_cpu(process_counts, smp_processor_id())--; + __get_cpu_var(process_counts)--; } REMOVE_LINKS(p); diff -Nru a/kernel/fork.c b/kernel/fork.c --- a/kernel/fork.c Fri Jun 27 14:19:53 2003 +++ b/kernel/fork.c Fri Jun 27 14:19:53 2003 @@ -1006,7 +1006,7 @@ attach_pid(p, PIDTYPE_PGID, p->pgrp); attach_pid(p, PIDTYPE_SID, p->session); if (p->pid) - per_cpu(process_counts, smp_processor_id())++; + __get_cpu_var(process_counts)++; } else link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid); diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c --- a/kernel/ksyms.c Fri Jun 27 14:19:52 2003 +++ b/kernel/ksyms.c Fri Jun 27 14:19:52 2003 @@ -523,6 +523,7 @@ EXPORT_SYMBOL(csum_partial); /* for networking and md */ EXPORT_SYMBOL(seq_escape); EXPORT_SYMBOL(seq_printf); +EXPORT_SYMBOL(seq_path); EXPORT_SYMBOL(seq_open); EXPORT_SYMBOL(seq_release); EXPORT_SYMBOL(seq_read); diff -Nru a/kernel/sched.c b/kernel/sched.c --- a/kernel/sched.c Fri Jun 27 14:20:00 2003 +++ b/kernel/sched.c Fri Jun 27 14:20:00 2003 @@ -784,7 +784,13 @@ minload = 10000000; for_each_node_with_cpus(i) { - load = atomic_read(&node_nr_running[i]); + /* + * Node load is always divided by nr_cpus_node to normalise + * load values in case cpu count differs from node to node. + * We first multiply node_nr_running by 10 to get a little + * better resolution. + */ + load = 10 * atomic_read(&node_nr_running[i]) / nr_cpus_node(i); if (load < minload) { minload = load; node = i; @@ -820,19 +826,26 @@ * geometrically deccaying weight to the load measure: * load_{t} = load_{t-1}/2 + nr_node_running_{t} * This way sudden load peaks are flattened out a bit. + * Node load is divided by nr_cpus_node() in order to compare nodes + * of different cpu count but also [first] multiplied by 10 to + * provide better resolution. */ static int find_busiest_node(int this_node) { int i, node = -1, load, this_load, maxload; + if (!nr_cpus_node(this_node)) + return node; this_load = maxload = (this_rq()->prev_node_load[this_node] >> 1) - + atomic_read(&node_nr_running[this_node]); + + (10 * atomic_read(&node_nr_running[this_node]) + / nr_cpus_node(this_node)); this_rq()->prev_node_load[this_node] = this_load; - for (i = 0; i < numnodes; i++) { + for_each_node_with_cpus(i) { if (i == this_node) continue; load = (this_rq()->prev_node_load[i] >> 1) - + atomic_read(&node_nr_running[i]); + + (10 * atomic_read(&node_nr_running[i]) + / nr_cpus_node(i)); this_rq()->prev_node_load[i] = load; if (load > maxload && (100*load > NODE_THRESHOLD*this_load)) { maxload = load; @@ -1691,6 +1704,7 @@ { struct sched_param lp; int retval = -EINVAL; + int oldprio; prio_array_t *array; unsigned long flags; runqueue_t *rq; @@ -1757,12 +1771,24 @@ retval = 0; p->policy = policy; p->rt_priority = lp.sched_priority; + oldprio = p->prio; if (policy != SCHED_NORMAL) p->prio = MAX_USER_RT_PRIO-1 - p->rt_priority; else p->prio = p->static_prio; - if (array) + if (array) { __activate_task(p, task_rq(p)); + /* + * Reschedule if we are currently running on this runqueue and + * our priority decreased, or if we are not currently running on + * this runqueue and our priority is higher than the current's + */ + if (rq->curr == p) { + if (p->prio > oldprio) + resched_task(rq->curr); + } else if (p->prio < rq->curr->prio) + resched_task(rq->curr); + } out_unlock: task_rq_unlock(rq, &flags); diff -Nru a/kernel/sys.c b/kernel/sys.c --- a/kernel/sys.c Fri Jun 27 14:19:53 2003 +++ b/kernel/sys.c Fri Jun 27 14:19:53 2003 @@ -5,6 +5,7 @@ */ #include <linux/config.h> +#include <linux/compat.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/utsname.h> @@ -220,6 +221,7 @@ cond_syscall(sys_send) cond_syscall(sys_recvfrom) cond_syscall(sys_recv) +cond_syscall(sys_socket) cond_syscall(sys_setsockopt) cond_syscall(sys_getsockopt) cond_syscall(sys_shutdown) @@ -1219,7 +1221,7 @@ ? -EFAULT : 0; } -#if !defined(__ia64__) && !defined(CONFIG_V850) +#if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64) || defined(CONFIG_V850)) /* * Back compatibility for getrlimit. Needed for some apps. diff -Nru a/kernel/timer.c b/kernel/timer.c --- a/kernel/timer.c Fri Jun 27 14:20:00 2003 +++ b/kernel/timer.c Fri Jun 27 14:20:00 2003 @@ -156,8 +156,7 @@ */ void add_timer(struct timer_list *timer) { - int cpu = get_cpu(); - tvec_base_t *base = &per_cpu(tvec_bases, cpu); + tvec_base_t *base = &get_cpu_var(tvec_bases); unsigned long flags; BUG_ON(timer_pending(timer) || !timer->function); @@ -168,7 +167,7 @@ internal_add_timer(base, timer); timer->base = base; spin_unlock_irqrestore(&base->lock, flags); - put_cpu(); + put_cpu_var(tvec_bases); } /*** @@ -231,7 +230,7 @@ return 1; spin_lock_irqsave(&timer->lock, flags); - new_base = &per_cpu(tvec_bases, smp_processor_id()); + new_base = &__get_cpu_var(tvec_bases); repeat: old_base = timer->base; @@ -789,7 +788,7 @@ */ static void run_timer_softirq(struct softirq_action *h) { - tvec_base_t *base = &per_cpu(tvec_bases, smp_processor_id()); + tvec_base_t *base = &__get_cpu_var(tvec_bases); if (time_after_eq(jiffies, base->timer_jiffies)) __run_timers(base); diff -Nru a/kernel/workqueue.c b/kernel/workqueue.c --- a/kernel/workqueue.c Fri Jun 27 14:20:05 2003 +++ b/kernel/workqueue.c Fri Jun 27 14:20:05 2003 @@ -275,6 +275,7 @@ INIT_LIST_HEAD(&cwq->worklist); init_waitqueue_head(&cwq->more_work); init_waitqueue_head(&cwq->work_done); + init_completion(&cwq->exit); init_completion(&startup.done); startup.cwq = cwq; @@ -320,10 +321,7 @@ cwq = wq->cpu_wq + cpu; if (cwq->thread) { - printk("Cleaning up workqueue thread for %i\n", cpu); - /* Initiate an exit and wait for it: */ - init_completion(&cwq->exit); - wmb(); /* Thread must see !cwq->thread after completion init */ + /* Tell thread to exit and wait for it. */ cwq->thread = NULL; wake_up(&cwq->more_work); diff -Nru a/lib/Makefile b/lib/Makefile --- a/lib/Makefile Fri Jun 27 14:19:52 2003 +++ b/lib/Makefile Fri Jun 27 14:19:52 2003 @@ -24,6 +24,7 @@ include drivers/usb/Makefile.lib include fs/Makefile.lib include net/bluetooth/bnep/Makefile.lib +include drivers/media/dvb/dvb-core/Makefile.lib host-progs := gen_crc32table clean-files := crc32table.h diff -Nru a/mm/mmap.c b/mm/mmap.c --- a/mm/mmap.c Fri Jun 27 14:19:58 2003 +++ b/mm/mmap.c Fri Jun 27 14:19:58 2003 @@ -777,7 +777,7 @@ { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; - int found_hole = 0; + unsigned long start_addr; if (len > TASK_SIZE) return -ENOMEM; @@ -789,21 +789,29 @@ (!vma || addr + len <= vma->vm_start)) return addr; } - addr = mm->free_area_cache; + start_addr = addr = mm->free_area_cache; +full_search: for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ - if (TASK_SIZE - len < addr) + if (TASK_SIZE - len < addr) { + /* + * Start a new search - just in case we missed + * some holes. + */ + if (start_addr != TASK_UNMAPPED_BASE) { + start_addr = addr = TASK_UNMAPPED_BASE; + goto full_search; + } return -ENOMEM; - /* - * Record the first available hole. - */ - if (!found_hole && (!vma || addr < vma->vm_start)) { - mm->free_area_cache = addr; - found_hole = 1; } - if (!vma || addr + len <= vma->vm_start) + if (!vma || addr + len <= vma->vm_start) { + /* + * Remember the place where we stopped the search: + */ + mm->free_area_cache = addr + len; return addr; + } addr = vma->vm_end; } } diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c --- a/mm/page-writeback.c Fri Jun 27 14:19:59 2003 +++ b/mm/page-writeback.c Fri Jun 27 14:19:59 2003 @@ -213,21 +213,19 @@ void balance_dirty_pages_ratelimited(struct address_space *mapping) { static DEFINE_PER_CPU(int, ratelimits) = 0; - int cpu; long ratelimit; ratelimit = ratelimit_pages; if (dirty_exceeded) ratelimit = 8; - cpu = get_cpu(); - if (per_cpu(ratelimits, cpu)++ >= ratelimit) { - per_cpu(ratelimits, cpu) = 0; - put_cpu(); + if (get_cpu_var(ratelimits)++ >= ratelimit) { + __get_cpu_var(ratelimits) = 0; + put_cpu_var(ratelimits); balance_dirty_pages(mapping); return; } - put_cpu(); + put_cpu_var(ratelimits); } /* diff -Nru a/mm/rmap.c b/mm/rmap.c --- a/mm/rmap.c Fri Jun 27 14:20:04 2003 +++ b/mm/rmap.c Fri Jun 27 14:20:04 2003 @@ -477,16 +477,15 @@ */ void __pte_chain_free(struct pte_chain *pte_chain) { - int cpu = get_cpu(); struct pte_chain **pte_chainp; + pte_chainp = &get_cpu_var(local_pte_chain); if (pte_chain->next_and_idx) pte_chain->next_and_idx = 0; - pte_chainp = &per_cpu(local_pte_chain, cpu); if (*pte_chainp) kmem_cache_free(pte_chain_cache, *pte_chainp); *pte_chainp = pte_chain; - put_cpu(); + put_cpu_var(local_pte_chain); } /* @@ -501,21 +500,19 @@ */ struct pte_chain *pte_chain_alloc(int gfp_flags) { - int cpu; struct pte_chain *ret; struct pte_chain **pte_chainp; if (gfp_flags & __GFP_WAIT) might_sleep(); - cpu = get_cpu(); - pte_chainp = &per_cpu(local_pte_chain, cpu); + pte_chainp = &get_cpu_var(local_pte_chain); if (*pte_chainp) { ret = *pte_chainp; *pte_chainp = NULL; - put_cpu(); + put_cpu_var(local_pte_chain); } else { - put_cpu(); + put_cpu_var(local_pte_chain); ret = kmem_cache_alloc(pte_chain_cache, gfp_flags); } return ret; diff -Nru a/mm/swap.c b/mm/swap.c --- a/mm/swap.c Fri Jun 27 14:19:55 2003 +++ b/mm/swap.c Fri Jun 27 14:19:55 2003 @@ -112,35 +112,34 @@ void lru_cache_add(struct page *page) { - struct pagevec *pvec = &per_cpu(lru_add_pvecs, get_cpu()); + struct pagevec *pvec = &get_cpu_var(lru_add_pvecs); page_cache_get(page); if (!pagevec_add(pvec, page)) __pagevec_lru_add(pvec); - put_cpu(); + put_cpu_var(lru_add_pvecs); } void lru_cache_add_active(struct page *page) { - struct pagevec *pvec = &per_cpu(lru_add_active_pvecs, get_cpu()); + struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs); page_cache_get(page); if (!pagevec_add(pvec, page)) __pagevec_lru_add_active(pvec); - put_cpu(); + put_cpu_var(lru_add_active_pvecs); } void lru_add_drain(void) { - int cpu = get_cpu(); - struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu); + struct pagevec *pvec = &get_cpu_var(lru_add_pvecs); if (pagevec_count(pvec)) __pagevec_lru_add(pvec); - pvec = &per_cpu(lru_add_active_pvecs, cpu); + pvec = &__get_cpu_var(lru_add_active_pvecs); if (pagevec_count(pvec)) __pagevec_lru_add_active(pvec); - put_cpu(); + put_cpu_var(lru_add_pvecs); } /* diff -Nru a/net/atm/atm_misc.c b/net/atm/atm_misc.c --- a/net/atm/atm_misc.c Fri Jun 27 14:19:54 2003 +++ b/net/atm/atm_misc.c Fri Jun 27 14:19:54 2003 @@ -47,15 +47,21 @@ static int check_ci(struct atm_vcc *vcc,short vpi,int vci) { + struct hlist_node *node; + struct sock *s; struct atm_vcc *walk; - for (walk = vcc->dev->vccs; walk; walk = walk->next) + sk_for_each(s, node, &vcc_sklist) { + walk = atm_sk(s); + if (walk->dev != vcc->dev) + continue; if (test_bit(ATM_VF_ADDR,&walk->flags) && walk->vpi == vpi && walk->vci == vci && ((walk->qos.txtp.traffic_class != ATM_NONE && vcc->qos.txtp.traffic_class != ATM_NONE) || (walk->qos.rxtp.traffic_class != ATM_NONE && vcc->qos.rxtp.traffic_class != ATM_NONE))) return -EADDRINUSE; + } /* allow VCCs with same VPI/VCI iff they don't collide on TX/RX (but we may refuse such sharing for other reasons, e.g. if protocol requires to have both channels) */ @@ -65,17 +71,16 @@ int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci) { - unsigned long flags; static short p = 0; /* poor man's per-device cache */ static int c = 0; short old_p; int old_c; int err; - spin_lock_irqsave(&vcc->dev->lock, flags); + read_lock(&vcc_sklist_lock); if (*vpi != ATM_VPI_ANY && *vci != ATM_VCI_ANY) { err = check_ci(vcc,*vpi,*vci); - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return err; } /* last scan may have left values out of bounds for current device */ @@ -90,7 +95,7 @@ if (!check_ci(vcc,p,c)) { *vpi = p; *vci = c; - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return 0; } if (*vci == ATM_VCI_ANY) { @@ -105,7 +110,7 @@ } } while (old_p != p || old_c != c); - spin_unlock_irqrestore(&vcc->dev->lock, flags); + read_unlock(&vcc_sklist_lock); return -EADDRINUSE; } diff -Nru a/net/atm/clip.c b/net/atm/clip.c --- a/net/atm/clip.c Fri Jun 27 14:20:05 2003 +++ b/net/atm/clip.c Fri Jun 27 14:20:05 2003 @@ -737,7 +737,8 @@ set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); /* allow replies and avoid getting closed if signaling dies */ - bind_vcc(vcc,&atmarpd_dev); + vcc->dev = &atmarpd_dev; + vcc_insert_socket(vcc->sk); vcc->push = NULL; vcc->pop = NULL; /* crash */ vcc->push_oam = NULL; /* crash */ diff -Nru a/net/atm/common.c b/net/atm/common.c --- a/net/atm/common.c Fri Jun 27 14:20:06 2003 +++ b/net/atm/common.c Fri Jun 27 14:20:06 2003 @@ -157,6 +157,29 @@ #endif +HLIST_HEAD(vcc_sklist); +rwlock_t vcc_sklist_lock = RW_LOCK_UNLOCKED; + +void __vcc_insert_socket(struct sock *sk) +{ + sk_add_node(sk, &vcc_sklist); +} + +void vcc_insert_socket(struct sock *sk) +{ + write_lock_irq(&vcc_sklist_lock); + __vcc_insert_socket(sk); + write_unlock_irq(&vcc_sklist_lock); +} + +void vcc_remove_socket(struct sock *sk) +{ + write_lock_irq(&vcc_sklist_lock); + sk_del_node_init(sk); + write_unlock_irq(&vcc_sklist_lock); +} + + static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size) { struct sk_buff *skb; @@ -175,16 +198,45 @@ } -int atm_create(struct socket *sock,int protocol,int family) +EXPORT_SYMBOL(vcc_sklist); +EXPORT_SYMBOL(vcc_sklist_lock); +EXPORT_SYMBOL(vcc_insert_socket); +EXPORT_SYMBOL(vcc_remove_socket); + +static void vcc_sock_destruct(struct sock *sk) +{ + struct atm_vcc *vcc = atm_sk(sk); + + if (atomic_read(&vcc->sk->sk_rmem_alloc)) + printk(KERN_DEBUG "vcc_sock_destruct: rmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_rmem_alloc)); + + if (atomic_read(&vcc->sk->sk_wmem_alloc)) + printk(KERN_DEBUG "vcc_sock_destruct: wmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_wmem_alloc)); + + kfree(sk->sk_protinfo); +} + +int vcc_create(struct socket *sock, int protocol, int family) { struct sock *sk; struct atm_vcc *vcc; sock->sk = NULL; - if (sock->type == SOCK_STREAM) return -EINVAL; - if (!(sk = alloc_atm_vcc_sk(family))) return -ENOMEM; - vcc = atm_sk(sk); - memset(&vcc->flags,0,sizeof(vcc->flags)); + if (sock->type == SOCK_STREAM) + return -EINVAL; + sk = sk_alloc(family, GFP_KERNEL, 1, NULL); + if (!sk) + return -ENOMEM; + sock_init_data(NULL, sk); + + vcc = atm_sk(sk) = kmalloc(sizeof(*vcc), GFP_KERNEL); + if (!vcc) { + sk_free(sk); + return -ENOMEM; + } + + memset(vcc, 0, sizeof(*vcc)); + vcc->sk = sk; vcc->dev = NULL; vcc->callback = NULL; memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); @@ -199,42 +251,48 @@ vcc->atm_options = vcc->aal_options = 0; init_waitqueue_head(&vcc->sleep); sk->sk_sleep = &vcc->sleep; + sk->sk_destruct = vcc_sock_destruct; sock->sk = sk; return 0; } -void atm_release_vcc_sk(struct sock *sk,int free_sk) +static void vcc_destroy_socket(struct sock *sk) { struct atm_vcc *vcc = atm_sk(sk); struct sk_buff *skb; - clear_bit(ATM_VF_READY,&vcc->flags); + clear_bit(ATM_VF_READY, &vcc->flags); if (vcc->dev) { - if (vcc->dev->ops->close) vcc->dev->ops->close(vcc); - if (vcc->push) vcc->push(vcc,NULL); /* atmarpd has no push */ + if (vcc->dev->ops->close) + vcc->dev->ops->close(vcc); + if (vcc->push) + vcc->push(vcc, NULL); /* atmarpd has no push */ + + vcc_remove_socket(sk); /* no more receive */ + while ((skb = skb_dequeue(&vcc->sk->sk_receive_queue))) { atm_return(vcc,skb->truesize); kfree_skb(skb); } module_put(vcc->dev->ops->owner); - atm_dev_release(vcc->dev); - if (atomic_read(&vcc->sk->sk_rmem_alloc)) - printk(KERN_WARNING "atm_release_vcc: strange ... " - "rmem_alloc == %d after closing\n", - atomic_read(&vcc->sk->sk_rmem_alloc)); - bind_vcc(vcc,NULL); + atm_dev_put(vcc->dev); } - - if (free_sk) free_atm_vcc_sk(sk); } -int atm_release(struct socket *sock) +int vcc_release(struct socket *sock) { - if (sock->sk) - atm_release_vcc_sk(sock->sk,1); + struct sock *sk = sock->sk; + + if (sk) { + lock_sock(sk); + vcc_destroy_socket(sock->sk); + release_sock(sk); + sock_put(sk); + } + return 0; } @@ -289,7 +347,8 @@ if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) return -EPERM; error = 0; - bind_vcc(vcc,dev); + vcc->dev = dev; + vcc_insert_socket(vcc->sk); switch (vcc->qos.aal) { case ATM_AAL0: error = atm_init_aal0(vcc); @@ -313,7 +372,7 @@ if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal); if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal); if (error) { - bind_vcc(vcc,NULL); + vcc_remove_socket(vcc->sk); return error; } DPRINTK("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal); @@ -327,7 +386,7 @@ error = dev->ops->open(vcc,vpi,vci); if (error) { module_put(dev->ops->owner); - bind_vcc(vcc,NULL); + vcc_remove_socket(vcc->sk); return error; } } @@ -371,7 +430,7 @@ dev = atm_dev_lookup(itf); error = __vcc_connect(vcc, dev, vpi, vci); if (error) { - atm_dev_release(dev); + atm_dev_put(dev); return error; } } else { @@ -385,7 +444,7 @@ spin_unlock(&atm_dev_lock); if (!__vcc_connect(vcc, dev, vpi, vci)) break; - atm_dev_release(dev); + atm_dev_put(dev); dev = NULL; spin_lock(&atm_dev_lock); } diff -Nru a/net/atm/common.h b/net/atm/common.h --- a/net/atm/common.h Fri Jun 27 14:19:59 2003 +++ b/net/atm/common.h Fri Jun 27 14:19:59 2003 @@ -10,8 +10,8 @@ #include <linux/poll.h> /* for poll_table */ -int atm_create(struct socket *sock,int protocol,int family); -int atm_release(struct socket *sock); +int vcc_create(struct socket *sock, int protocol, int family); +int vcc_release(struct socket *sock); int vcc_connect(struct socket *sock, int itf, short vpi, int vci); int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int size, int flags); @@ -24,7 +24,6 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen); -void atm_release_vcc_sk(struct sock *sk,int free_sk); void atm_shutdown_dev(struct atm_dev *dev); int atmpvc_init(void); diff -Nru a/net/atm/lec.c b/net/atm/lec.c --- a/net/atm/lec.c Fri Jun 27 14:19:58 2003 +++ b/net/atm/lec.c Fri Jun 27 14:19:58 2003 @@ -48,7 +48,7 @@ #include "lec.h" #include "lec_arpc.h" -#include "resources.h" /* for bind_vcc() */ +#include "resources.h" #if 0 #define DPRINTK printk @@ -810,7 +810,8 @@ lec_arp_init(priv); priv->itfnum = i; /* LANE2 addition */ priv->lecd = vcc; - bind_vcc(vcc, &lecatm_dev); + vcc->dev = &lecatm_dev; + vcc_insert_socket(vcc->sk); vcc->proto_data = dev_lec[i]; set_bit(ATM_VF_META,&vcc->flags); diff -Nru a/net/atm/mpc.c b/net/atm/mpc.c --- a/net/atm/mpc.c Fri Jun 27 14:20:00 2003 +++ b/net/atm/mpc.c Fri Jun 27 14:20:00 2003 @@ -28,7 +28,7 @@ #include "lec.h" #include "mpc.h" -#include "resources.h" /* for bind_vcc() */ +#include "resources.h" /* * mpc.c: Implementation of MPOA client kernel part @@ -789,7 +789,8 @@ } mpc->mpoad_vcc = vcc; - bind_vcc(vcc, &mpc_dev); + vcc->dev = &mpc_dev; + vcc_insert_socket(vcc->sk); set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); diff -Nru a/net/atm/proc.c b/net/atm/proc.c --- a/net/atm/proc.c Fri Jun 27 14:19:54 2003 +++ b/net/atm/proc.c Fri Jun 27 14:19:54 2003 @@ -334,9 +334,8 @@ static int atm_pvc_info(loff_t pos,char *buf) { - unsigned long flags; - struct atm_dev *dev; - struct list_head *p; + struct hlist_node *node; + struct sock *s; struct atm_vcc *vcc; int left, clip_info = 0; @@ -349,25 +348,20 @@ if (try_atm_clip_ops()) clip_info = 1; #endif - spin_lock(&atm_dev_lock); - list_for_each(p, &atm_devs) { - dev = list_entry(p, struct atm_dev, dev_list); - spin_lock_irqsave(&dev->lock, flags); - for (vcc = dev->vccs; vcc; vcc = vcc->next) - if (vcc->sk->sk_family == PF_ATMPVC && - vcc->dev && !left--) { - pvc_info(vcc,buf,clip_info); - spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&atm_dev_lock); + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + if (vcc->sk->sk_family == PF_ATMPVC && vcc->dev && !left--) { + pvc_info(vcc,buf,clip_info); + read_unlock(&vcc_sklist_lock); #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - if (clip_info) - module_put(atm_clip_ops->owner); + if (clip_info) + module_put(atm_clip_ops->owner); #endif - return strlen(buf); - } - spin_unlock_irqrestore(&dev->lock, flags); + return strlen(buf); + } } - spin_unlock(&atm_dev_lock); + read_unlock(&vcc_sklist_lock); #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) if (clip_info) module_put(atm_clip_ops->owner); @@ -378,10 +372,9 @@ static int atm_vc_info(loff_t pos,char *buf) { - unsigned long flags; - struct atm_dev *dev; - struct list_head *p; struct atm_vcc *vcc; + struct hlist_node *node; + struct sock *s; int left; if (!pos) @@ -389,20 +382,16 @@ "Address"," Itf VPI VCI Fam Flags Reply Send buffer" " Recv buffer\n"); left = pos-1; - spin_lock(&atm_dev_lock); - list_for_each(p, &atm_devs) { - dev = list_entry(p, struct atm_dev, dev_list); - spin_lock_irqsave(&dev->lock, flags); - for (vcc = dev->vccs; vcc; vcc = vcc->next) - if (!left--) { - vc_info(vcc,buf); - spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&atm_dev_lock); - return strlen(buf); - } - spin_unlock_irqrestore(&dev->lock, flags); + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + if (!left--) { + vc_info(vcc,buf); + read_unlock(&vcc_sklist_lock); + return strlen(buf); + } } - spin_unlock(&atm_dev_lock); + read_unlock(&vcc_sklist_lock); return 0; } @@ -410,29 +399,24 @@ static int atm_svc_info(loff_t pos,char *buf) { - unsigned long flags; - struct atm_dev *dev; - struct list_head *p; + struct hlist_node *node; + struct sock *s; struct atm_vcc *vcc; int left; if (!pos) return sprintf(buf,"Itf VPI VCI State Remote\n"); left = pos-1; - spin_lock(&atm_dev_lock); - list_for_each(p, &atm_devs) { - dev = list_entry(p, struct atm_dev, dev_list); - spin_lock_irqsave(&dev->lock, flags); - for (vcc = dev->vccs; vcc; vcc = vcc->next) - if (vcc->sk->sk_family == PF_ATMSVC && !left--) { - svc_info(vcc,buf); - spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&atm_dev_lock); - return strlen(buf); - } - spin_unlock_irqrestore(&dev->lock, flags); + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + vcc = atm_sk(s); + if (vcc->sk->sk_family == PF_ATMSVC && !left--) { + svc_info(vcc,buf); + read_unlock(&vcc_sklist_lock); + return strlen(buf); + } } - spin_unlock(&atm_dev_lock); + read_unlock(&vcc_sklist_lock); return 0; } diff -Nru a/net/atm/pvc.c b/net/atm/pvc.c --- a/net/atm/pvc.c Fri Jun 27 14:19:54 2003 +++ b/net/atm/pvc.c Fri Jun 27 14:19:54 2003 @@ -17,10 +17,6 @@ #include "resources.h" /* devs and vccs */ #include "common.h" /* common for PVCs and SVCs */ -#ifndef NULL -#define NULL 0 -#endif - static int pvc_shutdown(struct socket *sock,int how) { @@ -109,7 +105,7 @@ static struct proto_ops pvc_proto_ops = { .family = PF_ATMPVC, - .release = atm_release, + .release = vcc_release, .bind = pvc_bind, .connect = pvc_connect, .socketpair = sock_no_socketpair, @@ -131,7 +127,7 @@ static int pvc_create(struct socket *sock,int protocol) { sock->ops = &pvc_proto_ops; - return atm_create(sock,protocol,PF_ATMPVC); + return vcc_create(sock, protocol, PF_ATMPVC); } diff -Nru a/net/atm/resources.c b/net/atm/resources.c --- a/net/atm/resources.c Fri Jun 27 14:20:04 2003 +++ b/net/atm/resources.c Fri Jun 27 14:20:04 2003 @@ -23,11 +23,6 @@ #include "addr.h" -#ifndef NULL -#define NULL 0 -#endif - - LIST_HEAD(atm_devs); spinlock_t atm_dev_lock = SPIN_LOCK_UNLOCKED; @@ -91,7 +86,7 @@ spin_lock(&atm_dev_lock); if (number != -1) { if ((inuse = __atm_dev_lookup(number))) { - atm_dev_release(inuse); + atm_dev_put(inuse); spin_unlock(&atm_dev_lock); __free_atm_dev(dev); return NULL; @@ -100,7 +95,7 @@ } else { dev->number = 0; while ((inuse = __atm_dev_lookup(dev->number))) { - atm_dev_release(inuse); + atm_dev_put(inuse); dev->number++; } } @@ -402,78 +397,12 @@ else error = 0; done: - atm_dev_release(dev); + atm_dev_put(dev); return error; } -struct sock *alloc_atm_vcc_sk(int family) -{ - struct sock *sk; - struct atm_vcc *vcc; - - sk = sk_alloc(family, GFP_KERNEL, 1, NULL); - if (!sk) - return NULL; - vcc = atm_sk(sk) = kmalloc(sizeof(*vcc), GFP_KERNEL); - if (!vcc) { - sk_free(sk); - return NULL; - } - sock_init_data(NULL, sk); - memset(vcc, 0, sizeof(*vcc)); - vcc->sk = sk; - - return sk; -} - - -static void unlink_vcc(struct atm_vcc *vcc) -{ - unsigned long flags; - if (vcc->dev) { - spin_lock_irqsave(&vcc->dev->lock, flags); - if (vcc->prev) - vcc->prev->next = vcc->next; - else - vcc->dev->vccs = vcc->next; - - if (vcc->next) - vcc->next->prev = vcc->prev; - else - vcc->dev->last = vcc->prev; - spin_unlock_irqrestore(&vcc->dev->lock, flags); - } -} - - -void free_atm_vcc_sk(struct sock *sk) -{ - unlink_vcc(atm_sk(sk)); - sk_free(sk); -} - -void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev) -{ - unsigned long flags; - - unlink_vcc(vcc); - vcc->dev = dev; - if (dev) { - spin_lock_irqsave(&dev->lock, flags); - vcc->next = NULL; - vcc->prev = dev->last; - if (dev->vccs) - dev->last->next = vcc; - else - dev->vccs = vcc; - dev->last = vcc; - spin_unlock_irqrestore(&dev->lock, flags); - } -} - EXPORT_SYMBOL(atm_dev_register); EXPORT_SYMBOL(atm_dev_deregister); EXPORT_SYMBOL(atm_dev_lookup); EXPORT_SYMBOL(shutdown_atm_dev); -EXPORT_SYMBOL(bind_vcc); diff -Nru a/net/atm/resources.h b/net/atm/resources.h --- a/net/atm/resources.h Fri Jun 27 14:20:00 2003 +++ b/net/atm/resources.h Fri Jun 27 14:20:00 2003 @@ -14,8 +14,6 @@ extern spinlock_t atm_dev_lock; -struct sock *alloc_atm_vcc_sk(int family); -void free_atm_vcc_sk(struct sock *sk); int atm_dev_ioctl(unsigned int cmd, unsigned long arg); diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c --- a/net/atm/signaling.c Fri Jun 27 14:20:00 2003 +++ b/net/atm/signaling.c Fri Jun 27 14:20:00 2003 @@ -200,26 +200,22 @@ } -static void purge_vccs(struct atm_vcc *vcc) +static void purge_vcc(struct atm_vcc *vcc) { - while (vcc) { - if (vcc->sk->sk_family == PF_ATMSVC && - !test_bit(ATM_VF_META,&vcc->flags)) { - set_bit(ATM_VF_RELEASED,&vcc->flags); - vcc->reply = -EUNATCH; - vcc->sk->sk_err = EUNATCH; - wake_up(&vcc->sleep); - } - vcc = vcc->next; + if (vcc->sk->sk_family == PF_ATMSVC && + !test_bit(ATM_VF_META,&vcc->flags)) { + set_bit(ATM_VF_RELEASED,&vcc->flags); + vcc->reply = -EUNATCH; + vcc->sk->sk_err = EUNATCH; + wake_up(&vcc->sleep); } } static void sigd_close(struct atm_vcc *vcc) { - unsigned long flags; - struct atm_dev *dev; - struct list_head *p; + struct hlist_node *node; + struct sock *s; DPRINTK("sigd_close\n"); sigd = NULL; @@ -227,14 +223,14 @@ printk(KERN_ERR "sigd_close: closing with requests pending\n"); skb_queue_purge(&vcc->sk->sk_receive_queue); - spin_lock(&atm_dev_lock); - list_for_each(p, &atm_devs) { - dev = list_entry(p, struct atm_dev, dev_list); - spin_lock_irqsave(&dev->lock, flags); - purge_vccs(dev->vccs); - spin_unlock_irqrestore(&dev->lock, flags); + read_lock(&vcc_sklist_lock); + sk_for_each(s, node, &vcc_sklist) { + struct atm_vcc *vcc = atm_sk(s); + + if (vcc->dev) + purge_vcc(vcc); } - spin_unlock(&atm_dev_lock); + read_unlock(&vcc_sklist_lock); } @@ -257,7 +253,8 @@ if (sigd) return -EADDRINUSE; DPRINTK("sigd_attach\n"); sigd = vcc; - bind_vcc(vcc,&sigd_dev); + vcc->dev = &sigd_dev; + vcc_insert_socket(vcc->sk); set_bit(ATM_VF_META,&vcc->flags); set_bit(ATM_VF_READY,&vcc->flags); wake_up(&sigd_sleep); diff -Nru a/net/atm/svc.c b/net/atm/svc.c --- a/net/atm/svc.c Fri Jun 27 14:19:58 2003 +++ b/net/atm/svc.c Fri Jun 27 14:19:58 2003 @@ -88,18 +88,21 @@ static int svc_release(struct socket *sock) { + struct sock *sk = sock->sk; struct atm_vcc *vcc; - if (!sock->sk) return 0; - vcc = ATM_SD(sock); - DPRINTK("svc_release %p\n",vcc); - clear_bit(ATM_VF_READY,&vcc->flags); - atm_release_vcc_sk(sock->sk,0); - svc_disconnect(vcc); - /* VCC pointer is used as a reference, so we must not free it - (thereby subjecting it to re-use) before all pending connections - are closed */ - free_atm_vcc_sk(sock->sk); + if (sk) { + vcc = ATM_SD(sock); + DPRINTK("svc_release %p\n", vcc); + clear_bit(ATM_VF_READY, &vcc->flags); + /* VCC pointer is used as a reference, so we must not free it + (thereby subjecting it to re-use) before all pending connections + are closed */ + sock_hold(sk); + vcc_release(sock); + svc_disconnect(vcc); + sock_put(sk); + } return 0; } @@ -542,7 +545,7 @@ int error; sock->ops = &svc_proto_ops; - error = atm_create(sock,protocol,AF_ATMSVC); + error = vcc_create(sock, protocol, AF_ATMSVC); if (error) return error; ATM_SD(sock)->callback = svc_callback; ATM_SD(sock)->local.sas_family = AF_ATMSVC; diff -Nru a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c --- a/net/ax25/sysctl_net_ax25.c Fri Jun 27 14:20:03 2003 +++ b/net/ax25/sysctl_net_ax25.c Fri Jun 27 14:20:03 2003 @@ -36,7 +36,6 @@ { .ctl_name = NET_AX25, .procname = "ax25", - .maxlen = 0, .mode = 0555, }, { .ctl_name = 0 } @@ -46,7 +45,6 @@ { .ctl_name = CTL_NET, .procname = "net", - .maxlen = 0, .mode = 0555, .child = ax25_dir_table }, diff -Nru a/net/ipv4/icmp.c b/net/ipv4/icmp.c --- a/net/ipv4/icmp.c Fri Jun 27 14:20:04 2003 +++ b/net/ipv4/icmp.c Fri Jun 27 14:20:04 2003 @@ -228,7 +228,7 @@ * On SMP we have one ICMP socket per-cpu. */ static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; -#define icmp_socket per_cpu(__icmp_socket, smp_processor_id()) +#define icmp_socket __get_cpu_var(__icmp_socket) static __inline__ void icmp_xmit_lock(void) { @@ -659,8 +659,12 @@ inet_addr_type(iph->daddr) == RTN_BROADCAST) { if (net_ratelimit()) printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP " - "error to a broadcast.\n", - NIPQUAD(skb->nh.iph->saddr)); + "type %u, code %u " + "error to a broadcast: %u.%u.%u.%u on %s\n", + NIPQUAD(iph->saddr), + icmph->type, icmph->code, + NIPQUAD(iph->daddr), + skb->dev->name); goto out; } diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c --- a/net/ipv4/igmp.c Fri Jun 27 14:20:05 2003 +++ b/net/ipv4/igmp.c Fri Jun 27 14:20:05 2003 @@ -757,9 +757,10 @@ read_unlock(&in_dev->lock); } -static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih, +static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb, int len) { + struct igmphdr *ih = skb->h.igmph; struct igmpv3_query *ih3 = (struct igmpv3_query *)ih; struct ip_mc_list *im; u32 group = ih->group; @@ -790,6 +791,17 @@ } else if (len < 12) { return; /* ignore bogus packet; freed by caller */ } else { /* v3 */ + if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) + return; + + ih3 = (struct igmpv3_query *) skb->h.raw; + if (ih3->nsrcs) { + if (!pskb_may_pull(skb, sizeof(struct igmpv3_query) + + ntohs(ih3->nsrcs)*sizeof(__u32))) + return; + ih3 = (struct igmpv3_query *) skb->h.raw; + } + max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE); if (!max_delay) max_delay = 1; /* can't mod w/ 0 */ @@ -838,7 +850,7 @@ int igmp_rcv(struct sk_buff *skb) { /* This basically follows the spec line by line -- see RFC1112 */ - struct igmphdr *ih = skb->h.igmph; + struct igmphdr *ih; struct in_device *in_dev = in_dev_get(skb->dev); int len = skb->len; @@ -847,23 +859,17 @@ return 0; } - if (skb_is_nonlinear(skb)) { - if (skb_linearize(skb, GFP_ATOMIC) != 0) { - kfree_skb(skb); - return -ENOMEM; - } - ih = skb->h.igmph; - } - - if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)) { + if (!pskb_may_pull(skb, sizeof(struct igmphdr)) || + (u16)csum_fold(skb_checksum(skb, 0, len, 0))) { in_dev_put(in_dev); kfree_skb(skb); return 0; } + ih = skb->h.igmph; switch (ih->type) { case IGMP_HOST_MEMBERSHIP_QUERY: - igmp_heard_query(in_dev, ih, len); + igmp_heard_query(in_dev, skb, len); break; case IGMP_HOST_MEMBERSHIP_REPORT: case IGMPV2_HOST_MEMBERSHIP_REPORT: @@ -2011,7 +2017,7 @@ break; } if (!pmc) - return 0; + return 1; psl = pmc->sflist; if (!psl) return pmc->sfmode == MCAST_EXCLUDE; @@ -2020,11 +2026,11 @@ if (psl->sl_addr[i] == rmt_addr) break; } - if (pmc->sfmode == MCAST_INCLUDE && i < psl->sl_count) - return 1; - if (pmc->sfmode == MCAST_EXCLUDE && i >= psl->sl_count) - return 1; - return 0; + if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count) + return 0; + if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count) + return 0; + return 1; } /* diff -Nru a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c --- a/net/ipv4/ipmr.c Fri Jun 27 14:19:56 2003 +++ b/net/ipv4/ipmr.c Fri Jun 27 14:19:56 2003 @@ -83,13 +83,13 @@ #define VIF_EXISTS(idx) (vif_table[idx].dev != NULL) -int mroute_do_assert; /* Set in PIM assert */ -int mroute_do_pim; +static int mroute_do_assert; /* Set in PIM assert */ +static int mroute_do_pim; static struct mfc_cache *mfc_cache_array[MFC_LINES]; /* Forwarding cache */ static struct mfc_cache *mfc_unres_queue; /* Queue of unresolved entries */ -atomic_t cache_resolve_queue_len; /* Size of unresolved */ +static atomic_t cache_resolve_queue_len; /* Size of unresolved */ /* Special spinlock for queue of unresolved entries */ static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED; @@ -102,7 +102,7 @@ In this case data path is free of exclusive locks at all. */ -kmem_cache_t *mrt_cachep; +static kmem_cache_t *mrt_cachep; static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); @@ -158,6 +158,10 @@ return dev; failure: + /* allow the register to be completed before unregistering. */ + rtnl_unlock(); + rtnl_lock(); + unregister_netdevice(dev); return NULL; } @@ -182,35 +186,23 @@ return (struct net_device_stats*)dev->priv; } -static void vif_dev_destructor(struct net_device *dev) -{ - kfree(dev); -} - -static -struct net_device *ipmr_reg_vif(struct vifctl *v) +static void reg_vif_setup(struct net_device *dev) { - struct net_device *dev; - struct in_device *in_dev; - int size; - - size = sizeof(*dev) + sizeof(struct net_device_stats); - dev = kmalloc(size, GFP_KERNEL); - if (!dev) - return NULL; - - memset(dev, 0, size); - - dev->priv = dev + 1; - - strcpy(dev->name, "pimreg"); - dev->type = ARPHRD_PIMREG; dev->mtu = 1500 - sizeof(struct iphdr) - 8; dev->flags = IFF_NOARP; dev->hard_start_xmit = reg_vif_xmit; dev->get_stats = reg_vif_get_stats; - dev->destructor = vif_dev_destructor; + dev->destructor = (void (*)(struct net_device *)) kfree; +} + +static struct net_device *ipmr_reg_vif(void) +{ + struct net_device *dev; + struct in_device *in_dev; + + dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg", + reg_vif_setup); if (register_netdevice(dev)) { kfree(dev); @@ -229,6 +221,10 @@ return dev; failure: + /* allow the register to be completed before unregistering. */ + rtnl_unlock(); + rtnl_lock(); + unregister_netdevice(dev); return NULL; } @@ -316,7 +312,7 @@ /* Single timer process for all the unresolved queue. */ -void ipmr_expire_process(unsigned long dummy) +static void ipmr_expire_process(unsigned long dummy) { unsigned long now; unsigned long expires; @@ -335,9 +331,8 @@ cp = &mfc_unres_queue; while ((c=*cp) != NULL) { - long interval = c->mfc_un.unres.expires - now; - - if (interval > 0) { + if (time_after(c->mfc_un.unres.expires, now)) { + unsigned long interval = c->mfc_un.unres.expires - now; if (interval < expires) expires = interval; cp = &c->next; @@ -397,7 +392,7 @@ */ if (reg_vif_num >= 0) return -EADDRINUSE; - dev = ipmr_reg_vif(vifc); + dev = ipmr_reg_vif(); if (!dev) return -ENOBUFS; break; @@ -683,7 +678,7 @@ * MFC cache manipulation by user space mroute daemon */ -int ipmr_mfc_delete(struct mfcctl *mfc) +static int ipmr_mfc_delete(struct mfcctl *mfc) { int line; struct mfc_cache *c, **cp; @@ -704,7 +699,7 @@ return -ENOENT; } -int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) +static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) { int line; struct mfc_cache *uc, *c, **cp; @@ -1078,9 +1073,7 @@ static struct notifier_block ip_mr_notifier={ - ipmr_device_event, - NULL, - 0 + .notifier_call = ipmr_device_event, }; /* @@ -1234,7 +1227,7 @@ ipmr_forward_finish); } -int ipmr_find_vif(struct net_device *dev) +static int ipmr_find_vif(struct net_device *dev) { int ct; for (ct=maxvif-1; ct>=0; ct--) { @@ -1246,7 +1239,7 @@ /* "local" means that we should preserve one skb (for local delivery) */ -int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local) +static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local) { int psend = -1; int vif, ct; @@ -1286,7 +1279,8 @@ large chunk of pimd to kernel. Ough... --ANK */ (mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) && - jiffies - cache->mfc_un.res.last_assert > MFC_ASSERT_THRESH) { + time_after(jiffies, + cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { cache->mfc_un.res.last_assert = jiffies; ipmr_cache_report(skb, true_vifi, IGMPMSG_WRONGVIF); } @@ -1406,24 +1400,19 @@ int pim_rcv_v1(struct sk_buff * skb) { - struct igmphdr *pim = (struct igmphdr*)skb->h.raw; + struct igmphdr *pim; struct iphdr *encap; struct net_device *reg_dev = NULL; - if (skb_is_nonlinear(skb)) { - if (skb_linearize(skb, GFP_ATOMIC) != 0) { - kfree_skb(skb); - return -ENOMEM; - } - pim = (struct igmphdr*)skb->h.raw; - } + if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) + goto drop; + + pim = (struct igmphdr*)skb->h.raw; if (!mroute_do_pim || skb->len < sizeof(*pim) + sizeof(*encap) || - pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) { - kfree_skb(skb); - return -EINVAL; - } + pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) + goto drop; encap = (struct iphdr*)(skb->h.raw + sizeof(struct igmphdr)); /* @@ -1433,11 +1422,9 @@ c. packet is not truncated */ if (!MULTICAST(encap->daddr) || - ntohs(encap->tot_len) == 0 || - ntohs(encap->tot_len) + sizeof(*pim) > skb->len) { - kfree_skb(skb); - return -EINVAL; - } + encap->tot_len == 0 || + ntohs(encap->tot_len) + sizeof(*pim) > skb->len) + goto drop; read_lock(&mrt_lock); if (reg_vif_num >= 0) @@ -1446,10 +1433,8 @@ dev_hold(reg_dev); read_unlock(&mrt_lock); - if (reg_dev == NULL) { - kfree_skb(skb); - return -EINVAL; - } + if (reg_dev == NULL) + goto drop; skb->mac.raw = skb->nh.raw; skb_pull(skb, (u8*)encap - skb->data); @@ -1470,41 +1455,35 @@ netif_rx(skb); dev_put(reg_dev); return 0; + drop: + kfree_skb(skb); + return 0; } #endif #ifdef CONFIG_IP_PIMSM_V2 -int pim_rcv(struct sk_buff * skb) +static int pim_rcv(struct sk_buff * skb) { - struct pimreghdr *pim = (struct pimreghdr*)skb->h.raw; + struct pimreghdr *pim; struct iphdr *encap; struct net_device *reg_dev = NULL; - if (skb_is_nonlinear(skb)) { - if (skb_linearize(skb, GFP_ATOMIC) != 0) { - kfree_skb(skb); - return -ENOMEM; - } - pim = (struct pimreghdr*)skb->h.raw; - } + if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) + goto drop; - if (skb->len < sizeof(*pim) + sizeof(*encap) || - pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || + pim = (struct pimreghdr*)skb->h.raw; + if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || (pim->flags&PIM_NULL_REGISTER) || - (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && - ip_compute_csum((void *)pim, skb->len))) { - kfree_skb(skb); - return -EINVAL; - } + (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && + (u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))) + goto drop; /* check if the inner packet is destined to mcast group */ encap = (struct iphdr*)(skb->h.raw + sizeof(struct pimreghdr)); if (!MULTICAST(encap->daddr) || - ntohs(encap->tot_len) == 0 || - ntohs(encap->tot_len) + sizeof(*pim) > skb->len) { - kfree_skb(skb); - return -EINVAL; - } + encap->tot_len == 0 || + ntohs(encap->tot_len) + sizeof(*pim) > skb->len) + goto drop; read_lock(&mrt_lock); if (reg_vif_num >= 0) @@ -1513,10 +1492,8 @@ dev_hold(reg_dev); read_unlock(&mrt_lock); - if (reg_dev == NULL) { - kfree_skb(skb); - return -EINVAL; - } + if (reg_dev == NULL) + goto drop; skb->mac.raw = skb->nh.raw; skb_pull(skb, (u8*)encap - skb->data); @@ -1536,6 +1513,9 @@ #endif netif_rx(skb); dev_put(reg_dev); + return 0; + drop: + kfree_skb(skb); return 0; } #endif diff -Nru a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig --- a/net/ipv4/netfilter/Kconfig Fri Jun 27 14:20:00 2003 +++ b/net/ipv4/netfilter/Kconfig Fri Jun 27 14:20:00 2003 @@ -63,7 +63,7 @@ tristate "Amanda backup protocol support" depends on IP_NF_CONNTRACK help - If you are running the Amanda backup package (http://www.amanda.org/) + If you are running the Amanda backup package <http://www.amanda.org/> on this machine or machines that will be MASQUERADED through this machine, then you may want to enable this feature. This allows the connection tracking and natting code to allow the sub-channels that @@ -120,8 +120,8 @@ tristate "Packet type match support" depends on IP_NF_IPTABLES help - This patch allows you to match packet in accrodance - to its "class", eg. BROADCAST, MULTICAST, ... + Packet type matching allows you to match a packet by + its "class", eg. BROADCAST, MULTICAST, ... Typical usage: iptables -A INPUT -m pkttype --pkt-type broadcast -j LOG @@ -161,6 +161,19 @@ If you want to compile it as a module, say M here and read <file:Documentation/modules.txt>. If unsure, say `N'. +config IP_NF_MATCH_RECENT + tristate "recent match support" + depends on IP_NF_IPTABLES + help + This match is used for creating one or many lists of recently + used addresses and then matching against that/those list(s). + + Short options are available by using 'iptables -m recent -h' + Official Website: <http://snowman.net/projects/ipt_recent/> + + If you want to compile it as a module, say M here and read + <file:Documentation/modules.txt>. If unsure, say `N'. + config IP_NF_MATCH_ECN tristate "ECN match support" depends on IP_NF_IPTABLES @@ -539,6 +552,13 @@ config IP_NF_ARPFILTER tristate "ARP packet filtering" depends on IP_NF_ARPTABLES + +config IP_NF_ARP_MANGLE + tristate "ARP payload mangling" + depends on IP_NF_ARPTABLES + help + Allows altering the ARP packet payload: source and destination + hardware and network addresses. # Backwards compatibility modules: only if you don't build in the others. config IP_NF_COMPAT_IPCHAINS diff -Nru a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile --- a/net/ipv4/netfilter/Makefile Fri Jun 27 14:19:54 2003 +++ b/net/ipv4/netfilter/Makefile Fri Jun 27 14:19:54 2003 @@ -49,6 +49,9 @@ obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o + +obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o + obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o @@ -79,6 +82,7 @@ # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o +obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o # just filtering instance of ARP tables for now obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o diff -Nru a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c --- a/net/ipv4/netfilter/arp_tables.c Fri Jun 27 14:20:00 2003 +++ b/net/ipv4/netfilter/arp_tables.c Fri Jun 27 14:20:00 2003 @@ -136,6 +136,7 @@ dprintf("ARP hardware address length mismatch.\n"); dprintf("ar_hln: %02x info->arhln: %02x info->arhln_mask: %02x\n", arphdr->ar_hln, arpinfo->arhln, arpinfo->arhln_mask); + return 0; } src_devaddr = arpptr; diff -Nru a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/arpt_mangle.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,101 @@ +/* module that allows mangling of the arp payload */ +#include <linux/module.h> +#include <linux/netfilter_arp/arpt_mangle.h> +#include <net/sock.h> + +static unsigned int +target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, + const struct net_device *out, const void *targinfo, void *userinfo) +{ + const struct arpt_mangle *mangle = targinfo; + struct arphdr *arp; + unsigned char *arpptr; + int pln, hln; + + if (skb_shared(*pskb) || skb_cloned(*pskb)) { + struct sk_buff *nskb; + + nskb = skb_copy(*pskb, GFP_ATOMIC); + if (!nskb) + return NF_DROP; + if ((*pskb)->sk) + skb_set_owner_w(nskb, (*pskb)->sk); + kfree_skb(*pskb); + *pskb = nskb; + } + + arp = (*pskb)->nh.arph; + arpptr = (*pskb)->nh.raw + sizeof(*arp); + pln = arp->ar_pln; + hln = arp->ar_hln; + /* We assume that pln and hln were checked in the match */ + if (mangle->flags & ARPT_MANGLE_SDEV) { + if (ARPT_DEV_ADDR_LEN_MAX < hln || + (arpptr + hln > (**pskb).tail)) + return NF_DROP; + memcpy(arpptr, mangle->src_devaddr, hln); + } + arpptr += hln; + if (mangle->flags & ARPT_MANGLE_SIP) { + if (ARPT_MANGLE_ADDR_LEN_MAX < pln || + (arpptr + pln > (**pskb).tail)) + return NF_DROP; + memcpy(arpptr, &mangle->u_s.src_ip, pln); + } + arpptr += pln; + if (mangle->flags & ARPT_MANGLE_TDEV) { + if (ARPT_DEV_ADDR_LEN_MAX < hln || + (arpptr + hln > (**pskb).tail)) + return NF_DROP; + memcpy(arpptr, mangle->tgt_devaddr, hln); + } + arpptr += hln; + if (mangle->flags & ARPT_MANGLE_TIP) { + if (ARPT_MANGLE_ADDR_LEN_MAX < pln || + (arpptr + pln > (**pskb).tail)) + return NF_DROP; + memcpy(arpptr, &mangle->u_t.tgt_ip, pln); + } + return mangle->target; +} + +static int +checkentry(const char *tablename, const struct arpt_entry *e, void *targinfo, + unsigned int targinfosize, unsigned int hook_mask) +{ + const struct arpt_mangle *mangle = targinfo; + + if (mangle->flags & ~ARPT_MANGLE_MASK || + !(mangle->flags & ARPT_MANGLE_MASK)) + return 0; + + if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && + mangle->target != ARPT_CONTINUE) + return 0; + return 1; +} + +static struct arpt_target arpt_mangle_reg += { + .name = "mangle", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE, +}; + +static int __init init(void) +{ + if (arpt_register_target(&arpt_mangle_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + arpt_unregister_target(&arpt_mangle_reg); +} + +module_init(init); +module_exit(fini); +MODULE_LICENSE("GPL"); diff -Nru a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c --- a/net/ipv4/netfilter/ip_conntrack_core.c Fri Jun 27 14:19:30 2003 +++ b/net/ipv4/netfilter/ip_conntrack_core.c Fri Jun 27 14:19:30 2003 @@ -168,8 +168,8 @@ static void destroy_expect(struct ip_conntrack_expect *exp) { - DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use)); - IP_NF_ASSERT(atomic_read(exp->use)); + DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use)); + IP_NF_ASSERT(atomic_read(&exp->use)); IP_NF_ASSERT(!timer_pending(&exp->timeout)); kfree(exp); @@ -258,9 +258,7 @@ DEBUGP("remove_expectations(%p)\n", ct); - for (exp_entry = ct->sibling_list.next; - exp_entry != &ct->sibling_list; exp_entry = next) { - next = exp_entry->next; + list_for_each_safe(exp_entry, next, &ct->sibling_list) { exp = list_entry(exp_entry, struct ip_conntrack_expect, expected_list); @@ -307,9 +305,6 @@ IP_NF_ASSERT(atomic_read(&nfct->use) == 0); IP_NF_ASSERT(!timer_pending(&ct->timeout)); - if (ct->master && master_ct(ct)) - ip_conntrack_put(master_ct(ct)); - /* To make sure we don't get any weird locking issues here: * destroy_conntrack() MUST NOT be called with a write lock * to ip_conntrack_lock!!! -HW */ @@ -326,9 +321,12 @@ /* Delete our master expectation */ if (ct->master) { - /* can't call __unexpect_related here, - * since it would screw up expect_list */ - list_del(&ct->master->expected_list); + if (ct->master->expectant) { + /* can't call __unexpect_related here, + * since it would screw up expect_list */ + list_del(&ct->master->expected_list); + ip_conntrack_put(ct->master->expectant); + } kfree(ct->master); } WRITE_UNLOCK(&ip_conntrack_lock); @@ -576,7 +574,7 @@ int dropped = 0; READ_LOCK(&ip_conntrack_lock); - h = LIST_FIND(chain, unreplied, struct ip_conntrack_tuple_hash *); + h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *); if (h) atomic_inc(&h->ctrack->ct_general.use); READ_UNLOCK(&ip_conntrack_lock); @@ -675,9 +673,6 @@ INIT_LIST_HEAD(&conntrack->sibling_list); - /* Mark clearly that it's not in the hash table. */ - conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list.next = NULL; - WRITE_LOCK(&ip_conntrack_lock); /* Need finding and deleting of expected ONLY if we win race */ READ_LOCK(&ip_conntrack_expect_tuple_lock); @@ -685,6 +680,14 @@ struct ip_conntrack_expect *, tuple); READ_UNLOCK(&ip_conntrack_expect_tuple_lock); + /* If master is not in hash table yet (ie. packet hasn't left + this machine yet), how can other end know about expected? + Hence these are not the droids you are looking for (if + master ct never got confirmed, we'd hold a reference to it + and weird things would happen to future packets). */ + if (expected && !is_confirmed(expected->expectant)) + expected = NULL; + /* Look up the conntrack helper for master connections only */ if (!expected) conntrack->helper = ip_ct_find_helper(&repl_tuple); @@ -695,12 +698,7 @@ && ! del_timer(&expected->timeout)) expected = NULL; - /* If master is not in hash table yet (ie. packet hasn't left - this machine yet), how can other end know about expected? - Hence these are not the droids you are looking for (if - master ct never got confirmed, we'd hold a reference to it - and weird things would happen to future packets). */ - if (expected && is_confirmed(expected->expectant)) { + if (expected) { DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", conntrack, expected); /* Welcome, Mr. Bond. We've been expecting you... */ @@ -1012,18 +1010,11 @@ return -ENOMEM; } - /* Zero out the new structure, then fill out it with the data */ DEBUGP("new expectation %p of conntrack %p\n", new, related_to); - memset(new, 0, sizeof(*expect)); - INIT_LIST_HEAD(&new->list); - INIT_LIST_HEAD(&new->expected_list); memcpy(new, expect, sizeof(*expect)); new->expectant = related_to; new->sibling = NULL; - /* increase usage count. This sucks. The memset above overwrites - * old usage count [if still present] and we increase to one. Only - * works because everything is done under ip_conntrack_lock() */ - atomic_inc(&new->use); + atomic_set(&new->use, 1); /* add to expected list for this connection */ list_add(&new->expected_list, &related_to->sibling_list); @@ -1282,9 +1273,9 @@ struct inet_opt *inet = inet_sk(sk); struct ip_conntrack_tuple_hash *h; struct ip_conntrack_tuple tuple = { { inet->rcv_saddr, - { inet->sport } }, + { .tcp = { inet->sport } } }, { inet->daddr, - { inet->dport }, + { .tcp = { inet->dport } }, IPPROTO_TCP } }; /* We only do TCP at the moment: is there a better way? */ @@ -1473,8 +1464,10 @@ ip_ct_attach = ip_conntrack_attach; return ret; +#ifdef CONFIG_SYSCTL err_free_ct_cachep: kmem_cache_destroy(ip_conntrack_cachep); +#endif /*CONFIG_SYSCTL*/ err_free_hash: vfree(ip_conntrack_hash); err_unreg_sockopt: diff -Nru a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c --- a/net/ipv4/netfilter/ip_conntrack_ftp.c Fri Jun 27 14:20:00 2003 +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c Fri Jun 27 14:20:00 2003 @@ -367,11 +367,11 @@ { 0 } }, { htonl((array[0] << 24) | (array[1] << 16) | (array[2] << 8) | array[3]), - { htons(array[4] << 8 | array[5]) }, + { .tcp = { htons(array[4] << 8 | array[5]) } }, IPPROTO_TCP }}); exp->mask = ((struct ip_conntrack_tuple) { { 0xFFFFFFFF, { 0 } }, - { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); + { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }}); exp->expectfn = NULL; @@ -406,7 +406,6 @@ ports[0] = FTP_PORT; for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { - memset(&ftp[i], 0, sizeof(struct ip_conntrack_helper)); ftp[i].tuple.src.u.tcp.port = htons(ports[i]); ftp[i].tuple.dst.protonum = IPPROTO_TCP; ftp[i].mask.src.u.tcp.port = 0xFFFF; diff -Nru a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c --- a/net/ipv4/netfilter/ip_conntrack_irc.c Fri Jun 27 14:20:00 2003 +++ b/net/ipv4/netfilter/ip_conntrack_irc.c Fri Jun 27 14:20:00 2003 @@ -192,11 +192,11 @@ exp->tuple = ((struct ip_conntrack_tuple) { { 0, { 0 } }, - { htonl(dcc_ip), { htons(dcc_port) }, + { htonl(dcc_ip), { .tcp = { htons(dcc_port) } }, IPPROTO_TCP }}); exp->mask = ((struct ip_conntrack_tuple) { { 0, { 0 } }, - { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); + { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }}); exp->expectfn = NULL; @@ -243,8 +243,6 @@ for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { hlpr = &irc_helpers[i]; - memset(hlpr, 0, - sizeof(struct ip_conntrack_helper)); hlpr->tuple.src.u.tcp.port = htons(ports[i]); hlpr->tuple.dst.protonum = IPPROTO_TCP; hlpr->mask.src.u.tcp.port = 0xFFFF; diff -Nru a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c --- a/net/ipv4/netfilter/ip_nat_amanda.c Fri Jun 27 14:19:54 2003 +++ b/net/ipv4/netfilter/ip_nat_amanda.c Fri Jun 27 14:19:54 2003 @@ -84,7 +84,7 @@ mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; mr.range[0].min = mr.range[0].max = ((union ip_conntrack_manip_proto) - { htons(port) }); + { .udp = { htons(port) } }); } return ip_nat_setup_info(ct, &mr, hooknum); diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c --- a/net/ipv4/netfilter/ip_nat_core.c Fri Jun 27 14:19:53 2003 +++ b/net/ipv4/netfilter/ip_nat_core.c Fri Jun 27 14:19:53 2003 @@ -763,6 +763,11 @@ enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); int proto = (*pskb)->nh.iph->protocol; + /* Skip everything and don't call helpers if there are no + * manips for this connection */ + if (info->num_manips == 0) + return NF_ACCEPT; + /* Need nat lock to protect against modification, but neither conntrack (referenced) and helper (deleted with synchronize_bh()) can vanish. */ @@ -791,6 +796,7 @@ struct ip_conntrack_expect *exp = NULL; struct list_head *cur_item; int ret = NF_ACCEPT; + int helper_called = 0; DEBUGP("do_bindings: helper existing for (%p)\n", ct); @@ -809,19 +815,21 @@ continue; if (exp_for_packet(exp, *pskb)) { - /* FIXME: May be true multiple times in the case of UDP!! */ - DEBUGP("calling nat helper (exp=%p) for packet\n", - exp); + /* FIXME: May be true multiple times in the + * case of UDP!! */ + DEBUGP("calling nat helper (exp=%p) for packet\n", exp); ret = helper->help(ct, exp, info, ctinfo, hooknum, pskb); if (ret != NF_ACCEPT) { READ_UNLOCK(&ip_conntrack_lock); return ret; } + helper_called = 1; } } - /* Helper might want to manip the packet even when there is no expectation */ - if (!exp && helper->flags & IP_NAT_HELPER_F_ALWAYS) { + /* Helper might want to manip the packet even when there is no + * matching expectation for this packet */ + if (!helper_called && helper->flags & IP_NAT_HELPER_F_ALWAYS) { DEBUGP("calling nat helper for packet without expectation\n"); ret = helper->help(ct, NULL, info, ctinfo, hooknum, pskb); diff -Nru a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c --- a/net/ipv4/netfilter/ip_nat_ftp.c Fri Jun 27 14:19:59 2003 +++ b/net/ipv4/netfilter/ip_nat_ftp.c Fri Jun 27 14:19:59 2003 @@ -84,7 +84,7 @@ mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; mr.range[0].min = mr.range[0].max = ((union ip_conntrack_manip_proto) - { htons(exp_ftp_info->port) }); + { .tcp = { htons(exp_ftp_info->port) } }); } return ip_nat_setup_info(ct, &mr, hooknum); } @@ -306,9 +306,6 @@ ports[0] = FTP_PORT; for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { - - memset(&ftp[i], 0, sizeof(struct ip_nat_helper)); - ftp[i].tuple.dst.protonum = IPPROTO_TCP; ftp[i].tuple.src.u.tcp.port = htons(ports[i]); ftp[i].mask.dst.protonum = 0xFFFF; diff -Nru a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c --- a/net/ipv4/netfilter/ip_nat_irc.c Fri Jun 27 14:20:06 2003 +++ b/net/ipv4/netfilter/ip_nat_irc.c Fri Jun 27 14:20:06 2003 @@ -243,9 +243,6 @@ for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++) { hlpr = &ip_nat_irc_helpers[i]; - memset(hlpr, 0, - sizeof(struct ip_nat_helper)); - hlpr->tuple.dst.protonum = IPPROTO_TCP; hlpr->tuple.src.u.tcp.port = htons(ports[i]); hlpr->mask.src.u.tcp.port = 0xFFFF; diff -Nru a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c Fri Jun 27 14:20:00 2003 +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c Fri Jun 27 14:20:00 2003 @@ -1308,9 +1308,9 @@ "snmp", 0, THIS_MODULE, - { { 0, { __constant_htons(SNMP_PORT) } }, + { { 0, { .udp = { __constant_htons(SNMP_PORT) } } }, { 0, { 0 }, IPPROTO_UDP } }, - { { 0, { 0xFFFF } }, + { { 0, { .udp = { 0xFFFF } } }, { 0, { 0 }, 0xFFFF } }, nat_help, NULL }; @@ -1319,9 +1319,9 @@ "snmp_trap", 0, THIS_MODULE, - { { 0, { __constant_htons(SNMP_TRAP_PORT) } }, + { { 0, { .udp = { __constant_htons(SNMP_TRAP_PORT) } } }, { 0, { 0 }, IPPROTO_UDP } }, - { { 0, { 0xFFFF } }, + { { 0, { .udp = { 0xFFFF } } }, { 0, { 0 }, 0xFFFF } }, nat_help, NULL }; diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c --- a/net/ipv4/netfilter/ip_tables.c Fri Jun 27 14:19:54 2003 +++ b/net/ipv4/netfilter/ip_tables.c Fri Jun 27 14:19:54 2003 @@ -1703,14 +1703,15 @@ }; #ifdef CONFIG_PROC_FS -static inline int print_name(const struct ipt_table *t, +static inline int print_name(const char *i, off_t start_offset, char *buffer, int length, off_t *pos, unsigned int *count) { if ((*count)++ >= start_offset) { unsigned int namelen; - namelen = sprintf(buffer + *pos, "%s\n", t->name); + namelen = sprintf(buffer + *pos, "%s\n", + i + sizeof(struct list_head)); if (*pos + namelen > length) { /* Stop iterating */ return 1; @@ -1728,7 +1729,7 @@ if (down_interruptible(&ipt_mutex) != 0) return 0; - LIST_FIND(&ipt_tables, print_name, struct ipt_table *, + LIST_FIND(&ipt_tables, print_name, void *, offset, buffer, length, &pos, &count); up(&ipt_mutex); @@ -1737,6 +1738,46 @@ *start=(char *)((unsigned long)count-offset); return pos; } + +static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return 0; + + LIST_FIND(&ipt_target, print_name, void *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ipt_mutex) != 0) + return 0; + + LIST_FIND(&ipt_match, print_name, void *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = +{ { "ip_tables_names", ipt_get_tables }, + { "ip_tables_targets", ipt_get_targets }, + { "ip_tables_matches", ipt_get_matches }, + { NULL, NULL} }; #endif /*CONFIG_PROC_FS*/ static int __init init(void) @@ -1762,13 +1803,19 @@ #ifdef CONFIG_PROC_FS { struct proc_dir_entry *proc; + int i; - proc = proc_net_create("ip_tables_names", 0, ipt_get_tables); - if (!proc) { - nf_unregister_sockopt(&ipt_sockopts); - return -ENOMEM; + for (i = 0; ipt_proc_entry[i].name; i++) { + proc = proc_net_create(ipt_proc_entry[i].name, 0, + ipt_proc_entry[i].get_info); + if (!proc) { + while (--i >= 0) + proc_net_remove(ipt_proc_entry[i].name); + nf_unregister_sockopt(&ipt_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; } - proc->owner = THIS_MODULE; } #endif @@ -1780,7 +1827,11 @@ { nf_unregister_sockopt(&ipt_sockopts); #ifdef CONFIG_PROC_FS - proc_net_remove("ip_tables_names"); + { + int i; + for (i = 0; ipt_proc_entry[i].name; i++) + proc_net_remove(ipt_proc_entry[i].name); + } #endif } diff -Nru a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c --- a/net/ipv4/netfilter/ipt_ULOG.c Fri Jun 27 14:19:55 2003 +++ b/net/ipv4/netfilter/ipt_ULOG.c Fri Jun 27 14:19:55 2003 @@ -325,7 +325,6 @@ /* initialize ulog_buffers */ for (i = 0; i < ULOG_MAXNLGROUPS; i++) { - memset(&ulog_buffers[i], 0, sizeof(ulog_buff_t)); init_timer(&ulog_buffers[i].timer); ulog_buffers[i].timer.function = ulog_timer; ulog_buffers[i].timer.data = i; diff -Nru a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv4/netfilter/ipt_recent.c Fri Jun 27 14:20:06 2003 @@ -0,0 +1,994 @@ +/* Kernel module to check if the source address has been seen recently. */ +/* Copyright 2002-2003, Stephen Frost, 2.5.x port by laforge@netfilter.org */ +/* Author: Stephen Frost <sfrost@snowman.net> */ +/* Project Page: http://snowman.net/projects/ipt_recent/ */ +/* This software is distributed under the terms of the GPL, Version 2 */ +/* This copyright does not cover user programs that use kernel services + * by normal system calls. */ + +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/proc_fs.h> +#include <linux/spinlock.h> +#include <linux/interrupt.h> +#include <asm/uaccess.h> +#include <linux/ctype.h> +#include <linux/ip.h> +#include <linux/vmalloc.h> + +#include <linux/netfilter_ipv4/ip_tables.h> +#include <linux/netfilter_ipv4/ipt_recent.h> + +#undef DEBUG +#define HASH_LOG 9 + +/* Defaults, these can be overridden on the module command-line. */ +static int ip_list_tot = 100; +static int ip_pkt_list_tot = 20; +static int ip_list_hash_size = 0; +static int ip_list_perms = 0644; +#ifdef DEBUG +static int debug = 1; +#endif + +static char version[] = +KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost <sfrost@snowman.net>. http://snowman.net/projects/ipt_recent/\n"; + +MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>"); +MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER); +MODULE_LICENSE("GPL"); +MODULE_PARM(ip_list_tot,"i"); +MODULE_PARM(ip_pkt_list_tot,"i"); +MODULE_PARM(ip_list_hash_size,"i"); +MODULE_PARM(ip_list_perms,"i"); +#ifdef DEBUG +MODULE_PARM(debug,"i"); +MODULE_PARM_DESC(debug,"debugging level, defaults to 1"); +#endif +MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list"); +MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember"); +MODULE_PARM_DESC(ip_list_hash_size,"size of hash table used to look up IPs"); +MODULE_PARM_DESC(ip_list_perms,"permissions on /proc/net/ipt_recent/* files"); + +/* Structure of our list of recently seen addresses. */ +struct recent_ip_list { + u_int32_t addr; + u_int8_t ttl; + unsigned long last_seen; + unsigned long *last_pkts; + u_int32_t oldest_pkt; + u_int32_t hash_entry; + u_int32_t time_pos; +}; + +struct time_info_list { + u_int32_t position; + u_int32_t time; +}; + +/* Structure of our linked list of tables of recent lists. */ +struct recent_ip_tables { + char name[IPT_RECENT_NAME_LEN]; + int count; + int time_pos; + struct recent_ip_list *table; + struct recent_ip_tables *next; + spinlock_t list_lock; + int *hash_table; + struct time_info_list *time_info; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *status_proc; +#endif /* CONFIG_PROC_FS */ +}; + +/* Our current list of addresses we have recently seen. + * Only added to on a --set, and only updated on --set || --update + */ +static struct recent_ip_tables *r_tables = NULL; + +/* We protect r_list with this spinlock so two processors are not modifying + * the list at the same time. + */ +static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED; + +/* Our /proc/net/ipt_recent entry */ +static struct proc_dir_entry *proc_net_ipt_recent = NULL; + +/* Function declaration for later. */ +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop); + +/* Function to hash a given address into the hash table of table_size size */ +int hash_func(unsigned int addr, int table_size) +{ + int result = 0; + unsigned int value = addr; + do { result ^= value; } while((value >>= HASH_LOG)); + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": %d = hash_func(%u,%d)\n", + result & (table_size - 1), + addr, + table_size); +#endif + + return(result & (table_size - 1)); +} + +#ifdef CONFIG_PROC_FS +/* This is the function which produces the output for our /proc output + * interface which lists each IP address, the last seen time and the + * other recent times the address was seen. + */ + +static int ip_recent_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) +{ + int len = 0, count, last_len = 0, pkt_count; + off_t pos = 0; + off_t begin = 0; + struct recent_ip_tables *curr_table; + + curr_table = (struct recent_ip_tables*) data; + + spin_lock_bh(&curr_table->list_lock); + for(count = 0; count < ip_list_tot; count++) { + if(!curr_table->table[count].addr) continue; + last_len = len; + len += sprintf(buffer+len,"src=%u.%u.%u.%u ",NIPQUAD(curr_table->table[count].addr)); + len += sprintf(buffer+len,"ttl: %u ",curr_table->table[count].ttl); + len += sprintf(buffer+len,"last_seen: %lu ",curr_table->table[count].last_seen); + len += sprintf(buffer+len,"oldest_pkt: %u ",curr_table->table[count].oldest_pkt); + len += sprintf(buffer+len,"last_pkts: %lu",curr_table->table[count].last_pkts[0]); + for(pkt_count = 1; pkt_count < ip_pkt_list_tot; pkt_count++) { + if(!curr_table->table[count].last_pkts[pkt_count]) break; + len += sprintf(buffer+len,", %lu",curr_table->table[count].last_pkts[pkt_count]); + } + len += sprintf(buffer+len,"\n"); + pos = begin + len; + if(pos < offset) { len = 0; begin = pos; } + if(pos > offset + length) { len = last_len; break; } + } + + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) len = length; + + spin_unlock_bh(&curr_table->list_lock); + return len; +} + +/* ip_recent_ctrl provides an interface for users to modify the table + * directly. This allows adding entries, removing entries, and + * flushing the entire table. + * This is done by opening up the appropriate table for writing and + * sending one of: + * xx.xx.xx.xx -- Add entry to table with current time + * +xx.xx.xx.xx -- Add entry to table with current time + * -xx.xx.xx.xx -- Remove entry from table + * clear -- Flush table, remove all entries + */ + +static int ip_recent_ctrl(struct file *file, const char *input, unsigned long size, void *data) +{ + static const u_int32_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff }; + u_int32_t val; + int base, used = 0; + char c, *cp; + union iaddr { + uint8_t bytes[4]; + uint32_t word; + } res; + uint8_t *pp = res.bytes; + int digit; + + char buffer[20]; + int len, check_set = 0, count; + u_int32_t addr = 0; + struct sk_buff *skb; + struct ipt_recent_info *info; + struct recent_ip_tables *curr_table; + + curr_table = (struct recent_ip_tables*) data; + + if(size > 20) len = 20; else len = size; + + if(copy_from_user(buffer,input,len)) return -EFAULT; + + if(len < 20) buffer[len] = '\0'; + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": ip_recent_ctrl len: %d, input: `%.20s'\n",len,buffer); +#endif + + cp = buffer; + while(isspace(*cp)) { cp++; used++; if(used >= len-5) return used; } + + /* Check if we are asked to flush the entire table */ + if(!memcmp(cp,"clear",5)) { + used += 5; + spin_lock_bh(&curr_table->list_lock); + curr_table->time_pos = 0; + for(count = 0; count < ip_list_hash_size; count++) { + curr_table->hash_table[count] = -1; + } + for(count = 0; count < ip_list_tot; count++) { + curr_table->table[count].last_seen = 0; + curr_table->table[count].addr = 0; + curr_table->table[count].ttl = 0; + memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + curr_table->table[count].oldest_pkt = 0; + curr_table->table[count].time_pos = 0; + curr_table->time_info[count].position = count; + curr_table->time_info[count].time = 0; + } + spin_unlock_bh(&curr_table->list_lock); + return used; + } + + check_set = IPT_RECENT_SET; + switch(*cp) { + case '+': check_set = IPT_RECENT_SET; cp++; used++; break; + case '-': check_set = IPT_RECENT_REMOVE; cp++; used++; break; + default: if(!isdigit(*cp)) return (used+1); break; + } + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": ip_recent_ctrl cp: `%c', check_set: %d\n",*cp,check_set); +#endif + /* Get addr (effectively inet_aton()) */ + /* Shamelessly stolen from libc, a function in the kernel for doing + * this would, of course, be greatly preferred, but our options appear + * to be rather limited, so we will just do it ourselves here. + */ + res.word = 0; + + c = *cp; + for(;;) { + if(!isdigit(c)) return used; + val = 0; base = 10; digit = 0; + if(c == '0') { + c = *++cp; + if(c == 'x' || c == 'X') base = 16, c = *++cp; + else { base = 8; digit = 1; } + } + for(;;) { + if(isascii(c) && isdigit(c)) { + if(base == 8 && (c == '8' || c == '0')) return used; + val = (val * base) + (c - '0'); + c = *++cp; + digit = 1; + } else if(base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + digit = 1; + } else break; + } + if(c == '.') { + if(pp > res.bytes + 2 || val > 0xff) return used; + *pp++ = val; + c = *++cp; + } else break; + } + used = cp - buffer; + if(c != '\0' && (!isascii(c) || !isspace(c))) return used; + if(c == '\n') used++; + if(!digit) return used; + + if(val > max[pp - res.bytes]) return used; + addr = res.word | htonl(val); + + if(!addr && check_set == IPT_RECENT_SET) return used; + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": ip_recent_ctrl c: %c, addr: %u used: %d\n",c,addr,used); +#endif + + /* Set up and just call match */ + info = kmalloc(sizeof(struct ipt_recent_info),GFP_KERNEL); + if(!info) { return -ENOMEM; } + info->seconds = 0; + info->hit_count = 0; + info->check_set = check_set; + info->invert = 0; + info->side = IPT_RECENT_SOURCE; + strncpy(info->name,curr_table->name,IPT_RECENT_NAME_LEN); + info->name[IPT_RECENT_NAME_LEN-1] = '\0'; + + skb = kmalloc(sizeof(struct sk_buff),GFP_KERNEL); + if (!skb) { + used = -ENOMEM; + goto out_free_info; + } + skb->nh.iph = kmalloc(sizeof(struct iphdr),GFP_KERNEL); + if (!skb->nh.iph) { + used = -ENOMEM; + goto out_free_skb; + } + + skb->nh.iph->saddr = addr; + skb->nh.iph->daddr = 0; + /* Clear ttl since we have no way of knowing it */ + skb->nh.iph->ttl = 0; + match(skb,NULL,NULL,info,0,NULL); + + kfree(skb->nh.iph); +out_free_skb: + kfree(skb); +out_free_info: + kfree(info); + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": Leaving ip_recent_ctrl addr: %u used: %d\n",addr,used); +#endif + return used; +} + +#endif /* CONFIG_PROC_FS */ + +/* 'match' is our primary function, called by the kernel whenever a rule is + * hit with our module as an option to it. + * What this function does depends on what was specifically asked of it by + * the user: + * --set -- Add or update last seen time of the source address of the packet + * -- matchinfo->check_set == IPT_RECENT_SET + * --rcheck -- Just check if the source address is in the list + * -- matchinfo->check_set == IPT_RECENT_CHECK + * --update -- If the source address is in the list, update last_seen + * -- matchinfo->check_set == IPT_RECENT_UPDATE + * --remove -- If the source address is in the list, remove it + * -- matchinfo->check_set == IPT_RECENT_REMOVE + * --seconds -- Option to --rcheck/--update, only match if last_seen within seconds + * -- matchinfo->seconds + * --hitcount -- Option to --rcheck/--update, only match if seen hitcount times + * -- matchinfo->hit_count + * --seconds and --hitcount can be combined + */ +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + int pkt_count, hits_found, ans; + unsigned long now; + const struct ipt_recent_info *info = matchinfo; + u_int32_t addr = 0, time_temp; + u_int8_t ttl = skb->nh.iph->ttl; + int *hash_table; + int orig_hash_result, hash_result, temp, location = 0, time_loc, end_collision_chain = -1; + struct time_info_list *time_info; + struct recent_ip_tables *curr_table; + struct recent_ip_tables *last_table; + struct recent_ip_list *r_list; + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match() called\n"); +#endif + + /* Default is false ^ info->invert */ + ans = info->invert; + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): name = '%s'\n",info->name); +#endif + + /* if out != NULL then routing has been done and TTL changed. + * We change it back here internally for match what came in before routing. */ + if(out) ttl++; + + /* Find the right table */ + spin_lock_bh(&recent_lock); + curr_table = r_tables; + while( (last_table = curr_table) && strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (curr_table = curr_table->next) ); + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): table found('%s')\n",info->name); +#endif + + spin_unlock_bh(&recent_lock); + + /* Table with this name not found, match impossible */ + if(!curr_table) { return ans; } + + /* Make sure no one is changing the list while we work with it */ + spin_lock_bh(&curr_table->list_lock); + + r_list = curr_table->table; + if(info->side == IPT_RECENT_DEST) addr = skb->nh.iph->daddr; else addr = skb->nh.iph->saddr; + + if(!addr) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match() address (%u) invalid, leaving.\n",addr); +#endif + spin_unlock_bh(&curr_table->list_lock); + return ans; + } + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): checking table, addr: %u, ttl: %u, orig_ttl: %u\n",addr,ttl,skb->nh.iph->ttl); +#endif + + /* Get jiffies now in case they changed while we were waiting for a lock */ + now = jiffies; + hash_table = curr_table->hash_table; + time_info = curr_table->time_info; + + orig_hash_result = hash_result = hash_func(addr,ip_list_hash_size); + /* Hash entry at this result used */ + /* Check for TTL match if requested. If TTL is zero then a match would never + * happen, so match regardless of existing TTL in that case. Zero means the + * entry was added via the /proc interface anyway, so we will just use the + * first TTL we get for that IP address. */ + if(info->check_set & IPT_RECENT_TTL) { + while(hash_table[hash_result] != -1 && !(r_list[hash_table[hash_result]].addr == addr && + (!r_list[hash_table[hash_result]].ttl || r_list[hash_table[hash_result]].ttl == ttl))) { + /* Collision in hash table */ + hash_result = (hash_result + 1) % ip_list_hash_size; + } + } else { + while(hash_table[hash_result] != -1 && r_list[hash_table[hash_result]].addr != addr) { + /* Collision in hash table */ + hash_result = (hash_result + 1) % ip_list_hash_size; + } + } + + if(hash_table[hash_result] == -1 && !(info->check_set & IPT_RECENT_SET)) { + /* IP not in list and not asked to SET */ + spin_unlock_bh(&curr_table->list_lock); + return ans; + } + + /* Check if we need to handle the collision, do not need to on REMOVE */ + if(orig_hash_result != hash_result && !(info->check_set & IPT_RECENT_REMOVE)) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): Collision in hash table. (or: %d,hr: %d,oa: %u,ha: %u)\n", + orig_hash_result, + hash_result, + r_list[hash_table[orig_hash_result]].addr, + addr); +#endif + + /* We had a collision. + * orig_hash_result is where we started, hash_result is where we ended up. + * So, swap them because we are likely to see the same guy again sooner */ +#ifdef DEBUG + if(debug) { + printk(KERN_INFO RECENT_NAME ": match(): Collision; hash_table[orig_hash_result] = %d\n",hash_table[orig_hash_result]); + printk(KERN_INFO RECENT_NAME ": match(): Collision; r_list[hash_table[orig_hash_result]].hash_entry = %d\n", + r_list[hash_table[orig_hash_result]].hash_entry); + } +#endif + + r_list[hash_table[orig_hash_result]].hash_entry = hash_result; + + + temp = hash_table[orig_hash_result]; +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): Collision; hash_table[hash_result] = %d\n",hash_table[hash_result]); +#endif + hash_table[orig_hash_result] = hash_table[hash_result]; + hash_table[hash_result] = temp; + temp = hash_result; + hash_result = orig_hash_result; + orig_hash_result = temp; + time_info[r_list[hash_table[orig_hash_result]].time_pos].position = hash_table[orig_hash_result]; + if(hash_table[hash_result] != -1) { + r_list[hash_table[hash_result]].hash_entry = hash_result; + time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result]; + } + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): Collision handled.\n"); +#endif + } + + if(hash_table[hash_result] == -1) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): New table entry. (hr: %d,ha: %u)\n", + hash_result, addr); +#endif + + /* New item found and IPT_RECENT_SET, so we need to add it */ + location = time_info[curr_table->time_pos].position; + hash_table[r_list[location].hash_entry] = -1; + hash_table[hash_result] = location; + memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + r_list[location].time_pos = curr_table->time_pos; + r_list[location].addr = addr; + r_list[location].ttl = ttl; + r_list[location].last_seen = now; + r_list[location].oldest_pkt = 1; + r_list[location].last_pkts[0] = now; + r_list[location].hash_entry = hash_result; + time_info[curr_table->time_pos].time = r_list[location].last_seen; + curr_table->time_pos = (curr_table->time_pos + 1) % ip_list_tot; + + ans = !info->invert; + } else { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): Existing table entry. (hr: %d,ha: %u)\n", + hash_result, + addr); +#endif + + /* Existing item found */ + location = hash_table[hash_result]; + /* We have a match on address, now to make sure it meets all requirements for a + * full match. */ + if(info->check_set & IPT_RECENT_CHECK || info->check_set & IPT_RECENT_UPDATE) { + if(!info->seconds && !info->hit_count) ans = !info->invert; else ans = info->invert; + if(info->seconds && !info->hit_count) { + if(time_before_eq(now,r_list[location].last_seen+info->seconds*HZ)) ans = !info->invert; else ans = info->invert; + } + if(info->seconds && info->hit_count) { + for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { + if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; + } + if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; + } + if(info->hit_count && !info->seconds) { + for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { + if(r_list[location].last_pkts[pkt_count] == 0) break; + hits_found++; + } + if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; + } + } +#ifdef DEBUG + if(debug) { + if(ans) + printk(KERN_INFO RECENT_NAME ": match(): match addr: %u\n",addr); + else + printk(KERN_INFO RECENT_NAME ": match(): no match addr: %u\n",addr); + } +#endif + + /* If and only if we have been asked to SET, or to UPDATE (on match) do we add the + * current timestamp to the last_seen. */ + if((info->check_set & IPT_RECENT_SET && (ans = !info->invert)) || (info->check_set & IPT_RECENT_UPDATE && ans)) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): SET or UPDATE; updating time info.\n"); +#endif + /* Have to update our time info */ + time_loc = r_list[location].time_pos; + time_info[time_loc].time = now; + time_info[time_loc].position = location; + while((time_info[(time_loc+1) % ip_list_tot].time < time_info[time_loc].time) && ((time_loc+1) % ip_list_tot) != curr_table->time_pos) { + time_temp = time_info[time_loc].time; + time_info[time_loc].time = time_info[(time_loc+1)%ip_list_tot].time; + time_info[(time_loc+1)%ip_list_tot].time = time_temp; + time_temp = time_info[time_loc].position; + time_info[time_loc].position = time_info[(time_loc+1)%ip_list_tot].position; + time_info[(time_loc+1)%ip_list_tot].position = time_temp; + r_list[time_info[time_loc].position].time_pos = time_loc; + r_list[time_info[(time_loc+1)%ip_list_tot].position].time_pos = (time_loc+1)%ip_list_tot; + time_loc = (time_loc+1) % ip_list_tot; + } + r_list[location].time_pos = time_loc; + r_list[location].ttl = ttl; + r_list[location].last_pkts[r_list[location].oldest_pkt] = now; + r_list[location].oldest_pkt = ++r_list[location].oldest_pkt % ip_pkt_list_tot; + r_list[location].last_seen = now; + } + /* If we have been asked to remove the entry from the list, just set it to 0 */ + if(info->check_set & IPT_RECENT_REMOVE) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; clearing entry (or: %d, hr: %d).\n",orig_hash_result,hash_result); +#endif + /* Check if this is part of a collision chain */ + while(hash_table[(orig_hash_result+1) % ip_list_hash_size] != -1) { + orig_hash_result++; + if(hash_func(r_list[hash_table[orig_hash_result]].addr,ip_list_hash_size) == hash_result) { + /* Found collision chain, how deep does this rabbit hole go? */ +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; found collision chain.\n"); +#endif + end_collision_chain = orig_hash_result; + } + } + if(end_collision_chain != -1) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; part of collision chain, moving to end.\n"); +#endif + /* Part of a collision chain, swap it with the end of the chain + * before removing. */ + r_list[hash_table[end_collision_chain]].hash_entry = hash_result; + temp = hash_table[end_collision_chain]; + hash_table[end_collision_chain] = hash_table[hash_result]; + hash_table[hash_result] = temp; + time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result]; + hash_result = end_collision_chain; + r_list[hash_table[hash_result]].hash_entry = hash_result; + time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result]; + } + location = hash_table[hash_result]; + hash_table[r_list[location].hash_entry] = -1; + time_loc = r_list[location].time_pos; + time_info[time_loc].time = 0; + time_info[time_loc].position = location; + while((time_info[(time_loc+1) % ip_list_tot].time < time_info[time_loc].time) && ((time_loc+1) % ip_list_tot) != curr_table->time_pos) { + time_temp = time_info[time_loc].time; + time_info[time_loc].time = time_info[(time_loc+1)%ip_list_tot].time; + time_info[(time_loc+1)%ip_list_tot].time = time_temp; + time_temp = time_info[time_loc].position; + time_info[time_loc].position = time_info[(time_loc+1)%ip_list_tot].position; + time_info[(time_loc+1)%ip_list_tot].position = time_temp; + r_list[time_info[time_loc].position].time_pos = time_loc; + r_list[time_info[(time_loc+1)%ip_list_tot].position].time_pos = (time_loc+1)%ip_list_tot; + time_loc = (time_loc+1) % ip_list_tot; + } + r_list[location].time_pos = time_loc; + r_list[location].last_seen = 0; + r_list[location].addr = 0; + r_list[location].ttl = 0; + memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + r_list[location].oldest_pkt = 0; + ans = !info->invert; + } + spin_unlock_bh(&curr_table->list_lock); + return ans; + } + + spin_unlock_bh(&curr_table->list_lock); +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": match() left.\n"); +#endif + return ans; +} + +/* This function is to verify that the rule given during the userspace iptables + * command is correct. + * If the command is valid then we check if the table name referred to by the + * rule exists, if not it is created. + */ +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + int flag = 0, c; + unsigned long *hold; + const struct ipt_recent_info *info = matchinfo; + struct recent_ip_tables *curr_table, *find_table, *last_table; + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() entered.\n"); +#endif + + if (matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return 0; + + /* seconds and hit_count only valid for CHECK/UPDATE */ + if(info->check_set & IPT_RECENT_SET) { flag++; if(info->seconds || info->hit_count) return 0; } + if(info->check_set & IPT_RECENT_REMOVE) { flag++; if(info->seconds || info->hit_count) return 0; } + if(info->check_set & IPT_RECENT_CHECK) flag++; + if(info->check_set & IPT_RECENT_UPDATE) flag++; + + /* One and only one of these should ever be set */ + if(flag != 1) return 0; + + /* Name must be set to something */ + if(!info->name || !info->name[0]) return 0; + + /* Things look good, create a list for this if it does not exist */ + /* Lock the linked list while we play with it */ + spin_lock_bh(&recent_lock); + + /* Look for an entry with this name already created */ + /* Finds the end of the list and the entry before the end if current name does not exist */ + find_table = r_tables; + while( (last_table = find_table) && strncmp(info->name,find_table->name,IPT_RECENT_NAME_LEN) && (find_table = find_table->next) ); + + /* If a table already exists just increment the count on that table and return */ + if(find_table) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: table found (%s), incrementing count.\n",info->name); +#endif + find_table->count++; + spin_unlock_bh(&recent_lock); + return 1; + } + + spin_unlock_bh(&recent_lock); + + /* Table with this name not found */ + /* Allocate memory for new linked list item */ + +#ifdef DEBUG + if(debug) { + printk(KERN_INFO RECENT_NAME ": checkentry: no table found (%s)\n",info->name); + printk(KERN_INFO RECENT_NAME ": checkentry: Allocationg %d for link-list entry.\n",sizeof(struct recent_ip_tables)); + } +#endif + + curr_table = vmalloc(sizeof(struct recent_ip_tables)); + if(curr_table == NULL) return -ENOMEM; + + curr_table->list_lock = SPIN_LOCK_UNLOCKED; + curr_table->next = NULL; + curr_table->count = 1; + curr_table->time_pos = 0; + strncpy(curr_table->name,info->name,IPT_RECENT_NAME_LEN); + curr_table->name[IPT_RECENT_NAME_LEN-1] = '\0'; + + /* Allocate memory for this table and the list of packets in each entry. */ +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for table (%s).\n", + sizeof(struct recent_ip_list)*ip_list_tot, + info->name); +#endif + + curr_table->table = vmalloc(sizeof(struct recent_ip_list)*ip_list_tot); + if(curr_table->table == NULL) { vfree(curr_table); return -ENOMEM; } + memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot); +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n", + sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot); +#endif + + hold = vmalloc(sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot); +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n"); +#endif + if(hold == NULL) { + printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for pkt_list.\n"); + vfree(curr_table->table); + vfree(curr_table); + return -ENOMEM; + } + for(c = 0; c < ip_list_tot; c++) { + curr_table->table[c].last_pkts = hold + c*ip_pkt_list_tot; + } + + /* Allocate memory for the hash table */ +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for hash_table.\n", + sizeof(int)*ip_list_hash_size); +#endif + + curr_table->hash_table = vmalloc(sizeof(int)*ip_list_hash_size); + if(!curr_table->hash_table) { + printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for hash_table.\n"); + vfree(hold); + vfree(curr_table->table); + vfree(curr_table); + return -ENOMEM; + } + + for(c = 0; c < ip_list_hash_size; c++) { + curr_table->hash_table[c] = -1; + } + + /* Allocate memory for the time info */ +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for time_info.\n", + sizeof(struct time_info_list)*ip_list_tot); +#endif + + curr_table->time_info = vmalloc(sizeof(struct time_info_list)*ip_list_tot); + if(!curr_table->time_info) { + printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for time_info.\n"); + vfree(curr_table->hash_table); + vfree(hold); + vfree(curr_table->table); + vfree(curr_table); + return -ENOMEM; + } + for(c = 0; c < ip_list_tot; c++) { + curr_table->time_info[c].position = c; + curr_table->time_info[c].time = 0; + } + + /* Put the new table in place */ + spin_lock_bh(&recent_lock); + find_table = r_tables; + while( (last_table = find_table) && strncmp(info->name,find_table->name,IPT_RECENT_NAME_LEN) && (find_table = find_table->next) ); + + /* If a table already exists just increment the count on that table and return */ + if(find_table) { + find_table->count++; + spin_unlock_bh(&recent_lock); +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: table found (%s), created by other process.\n",info->name); +#endif + vfree(curr_table->time_info); + vfree(curr_table->hash_table); + vfree(hold); + vfree(curr_table->table); + vfree(curr_table); + return 1; + } + if(!last_table) r_tables = curr_table; else last_table->next = curr_table; + + spin_unlock_bh(&recent_lock); + +#ifdef CONFIG_PROC_FS + /* Create our proc 'status' entry. */ + curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent); + if (!curr_table->status_proc) { + printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n"); + /* Destroy the created table */ + spin_lock_bh(&recent_lock); + last_table = NULL; + curr_table = r_tables; + if(!curr_table) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, no tables.\n"); +#endif + spin_unlock_bh(&recent_lock); + return -ENOMEM; + } + while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) ); + if(!curr_table) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, table already destroyed.\n"); +#endif + spin_unlock_bh(&recent_lock); + return -ENOMEM; + } + if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next; + spin_unlock_bh(&recent_lock); + vfree(curr_table->time_info); + vfree(curr_table->hash_table); + vfree(hold); + vfree(curr_table->table); + vfree(curr_table); + return -ENOMEM; + } + + curr_table->status_proc->owner = THIS_MODULE; + curr_table->status_proc->data = curr_table; + wmb(); + curr_table->status_proc->read_proc = ip_recent_get_info; + curr_table->status_proc->write_proc = ip_recent_ctrl; +#endif /* CONFIG_PROC_FS */ + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() left.\n"); +#endif + + return 1; +} + +/* This function is called in the event that a rule matching this module is + * removed. + * When this happens we need to check if there are no other rules matching + * the table given. If that is the case then we remove the table and clean + * up its memory. + */ +static void +destroy(void *matchinfo, unsigned int matchsize) +{ + const struct ipt_recent_info *info = matchinfo; + struct recent_ip_tables *curr_table, *last_table; + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": destroy() entered.\n"); +#endif + + if(matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return; + + /* Lock the linked list while we play with it */ + spin_lock_bh(&recent_lock); + + /* Look for an entry with this name already created */ + /* Finds the end of the list and the entry before the end if current name does not exist */ + last_table = NULL; + curr_table = r_tables; + if(!curr_table) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": destroy() No tables found, leaving.\n"); +#endif + spin_unlock_bh(&recent_lock); + return; + } + while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) ); + + /* If a table does not exist then do nothing and return */ + if(!curr_table) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table not found, leaving.\n"); +#endif + spin_unlock_bh(&recent_lock); + return; + } + + curr_table->count--; + + /* If count is still non-zero then there are still rules referenceing it so we do nothing */ + if(curr_table->count) { +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table found, non-zero count, leaving.\n"); +#endif + spin_unlock_bh(&recent_lock); + return; + } + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table found, zero count, removing.\n"); +#endif + + /* Count must be zero so we remove this table from the list */ + if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next; + + spin_unlock_bh(&recent_lock); + + /* lock to make sure any late-runners still using this after we removed it from + * the list finish up then remove everything */ + spin_lock_bh(&curr_table->list_lock); + spin_unlock_bh(&curr_table->list_lock); + +#ifdef CONFIG_PROC_FS + if(curr_table->status_proc) remove_proc_entry(curr_table->name,proc_net_ipt_recent); +#endif /* CONFIG_PROC_FS */ + vfree(curr_table->table[0].last_pkts); + vfree(curr_table->table); + vfree(curr_table->hash_table); + vfree(curr_table->time_info); + vfree(curr_table); + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": destroy() left.\n"); +#endif + + return; +} + +/* This is the structure we pass to ipt_register to register our + * module with iptables. + */ +static struct ipt_match recent_match = { + .name = "recent", + .match = &match, + .checkentry = &checkentry, + .destroy = &destroy, + .me = THIS_MODULE +}; + +/* Kernel module initialization. */ +static int __init init(void) +{ + int count; + + printk(version); + proc_net_ipt_recent = proc_mkdir("ipt_recent",proc_net); + if(!proc_net_ipt_recent) return -ENOMEM; + + if(ip_list_hash_size && ip_list_hash_size <= ip_list_tot) { + printk(KERN_WARNING RECENT_NAME ": ip_list_hash_size too small, resetting to default.\n"); + ip_list_hash_size = 0; + } + + if(!ip_list_hash_size) { + ip_list_hash_size = ip_list_tot*3; + count = 2*2; + while(ip_list_hash_size > count) count = count*2; + ip_list_hash_size = count; + } + +#ifdef DEBUG + if(debug) printk(KERN_INFO RECENT_NAME ": ip_list_hash_size: %d\n",ip_list_hash_size); +#endif + + return ipt_register_match(&recent_match); +} + +/* Kernel module destruction. */ +static void __exit fini(void) +{ + ipt_unregister_match(&recent_match); + + remove_proc_entry("ipt_recent",proc_net); +} + +/* Register our module with the kernel. */ +module_init(init); +module_exit(fini); diff -Nru a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c --- a/net/ipv4/tcp_input.c Fri Jun 27 14:19:59 2003 +++ b/net/ipv4/tcp_input.c Fri Jun 27 14:19:59 2003 @@ -598,25 +598,17 @@ } } -/* Increase initial CWND conservatively: if estimated - * RTT is low enough (<20msec) or if we have some preset ssthresh. - * - * Numbers are taken from RFC2414. - */ -__u32 tcp_init_cwnd(struct tcp_opt *tp) +/* Numbers are taken from RFC2414. */ +__u32 tcp_init_cwnd(struct tcp_opt *tp, struct dst_entry *dst) { - __u32 cwnd; - - if (tp->mss_cache > 1460) - return 2; - - cwnd = (tp->mss_cache > 1095) ? 3 : 4; - - if (!tp->srtt || (tp->snd_ssthresh >= 0xFFFF && tp->srtt > ((HZ/50)<<3))) - cwnd = 2; - else if (cwnd > tp->snd_ssthresh) - cwnd = tp->snd_ssthresh; + __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); + if (!cwnd) { + if (tp->mss_cache > 1460) + cwnd = 2; + else + cwnd = (tp->mss_cache > 1095) ? 3 : 4; + } return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } @@ -675,7 +667,7 @@ tcp_bound_rto(tp); if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp) goto reset; - tp->snd_cwnd = tcp_init_cwnd(tp); + tp->snd_cwnd = tcp_init_cwnd(tp, dst); tp->snd_cwnd_stamp = tcp_time_stamp; return; diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c --- a/net/ipv4/tcp_minisocks.c Fri Jun 27 14:19:59 2003 +++ b/net/ipv4/tcp_minisocks.c Fri Jun 27 14:19:59 2003 @@ -23,6 +23,7 @@ #include <linux/config.h> #include <linux/mm.h> #include <linux/sysctl.h> +#include <linux/workqueue.h> #include <net/tcp.h> #include <net/inet_common.h> #include <net/xfrm.h> @@ -407,15 +408,22 @@ #define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ #define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS) +#define TCP_TWKILL_QUOTA 100 + static struct hlist_head tcp_tw_death_row[TCP_TWKILL_SLOTS]; static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED; static struct timer_list tcp_tw_timer = TIMER_INITIALIZER(tcp_twkill, 0, 0); +static void twkill_work(void *); +static DECLARE_WORK(tcp_twkill_work, twkill_work, NULL); +static u32 twkill_thread_slots; -static void tcp_twkill(unsigned long dummy) +/* Returns non-zero if quota exceeded. */ +static int tcp_do_twkill_work(int slot, unsigned int quota) { struct tcp_tw_bucket *tw; struct hlist_node *node, *safe; - int killed = 0; + unsigned int killed; + int ret; /* NOTE: compare this to previous version where lock * was released after detaching chain. It was racy, @@ -423,28 +431,84 @@ * in 2.3 (with netfilter), and with softnet it is common, because * soft irqs are not sequenced. */ - spin_lock(&tw_death_lock); - - if (tcp_tw_count == 0) - goto out; - + killed = 0; + ret = 0; tw_for_each_inmate(tw, node, safe, - &tcp_tw_death_row[tcp_tw_death_row_slot]) { + &tcp_tw_death_row[slot]) { __tw_del_dead_node(tw); spin_unlock(&tw_death_lock); tcp_timewait_kill(tw); tcp_tw_put(tw); killed++; spin_lock(&tw_death_lock); + if (killed > quota) { + ret = 1; + break; + } } - tcp_tw_death_row_slot = - ((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1)); - if ((tcp_tw_count -= killed) != 0) - mod_timer(&tcp_tw_timer, jiffies+TCP_TWKILL_PERIOD); + tcp_tw_count -= killed; NET_ADD_STATS_BH(TimeWaited, killed); + + return ret; +} + +static void tcp_twkill(unsigned long dummy) +{ + int need_timer, ret; + + spin_lock(&tw_death_lock); + + if (tcp_tw_count == 0) + goto out; + + need_timer = 0; + ret = tcp_do_twkill_work(tcp_tw_death_row_slot, TCP_TWKILL_QUOTA); + if (ret) { + twkill_thread_slots |= (1 << tcp_tw_death_row_slot); + mb(); + schedule_work(&tcp_twkill_work); + need_timer = 1; + } else { + /* We purged the entire slot, anything left? */ + if (tcp_tw_count) + need_timer = 1; + } + tcp_tw_death_row_slot = + ((tcp_tw_death_row_slot + 1) & (TCP_TWKILL_SLOTS - 1)); + if (need_timer) + mod_timer(&tcp_tw_timer, jiffies + TCP_TWKILL_PERIOD); out: spin_unlock(&tw_death_lock); +} + +extern void twkill_slots_invalid(void); + +static void twkill_work(void *dummy) +{ + int i; + + if ((TCP_TWKILL_SLOTS - 1) > (sizeof(twkill_thread_slots) * 8)) + twkill_slots_invalid(); + + while (twkill_thread_slots) { + spin_lock_bh(&tw_death_lock); + for (i = 0; i < TCP_TWKILL_SLOTS; i++) { + if (!(twkill_thread_slots & (1 << i))) + continue; + + while (tcp_do_twkill_work(i, TCP_TWKILL_QUOTA) != 0) { + if (need_resched()) { + spin_unlock_bh(&tw_death_lock); + schedule(); + spin_lock_bh(&tw_death_lock); + } + } + + twkill_thread_slots &= ~(1 << i); + } + spin_unlock_bh(&tw_death_lock); + } } /* These are always called from BH context. See callers in diff -Nru a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c --- a/net/ipv4/tcp_output.c Fri Jun 27 14:19:59 2003 +++ b/net/ipv4/tcp_output.c Fri Jun 27 14:19:59 2003 @@ -99,10 +99,10 @@ /* RFC2861. Reset CWND after idle period longer RTO to "restart window". * This is the first part of cwnd validation mechanism. */ -static void tcp_cwnd_restart(struct tcp_opt *tp) +static void tcp_cwnd_restart(struct tcp_opt *tp, struct dst_entry *dst) { s32 delta = tcp_time_stamp - tp->lsndtime; - u32 restart_cwnd = tcp_init_cwnd(tp); + u32 restart_cwnd = tcp_init_cwnd(tp, dst); u32 cwnd = tp->snd_cwnd; tp->snd_ssthresh = tcp_current_ssthresh(tp); @@ -115,12 +115,12 @@ tp->snd_cwnd_used = 0; } -static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb) +static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb, struct sock *sk) { u32 now = tcp_time_stamp; if (!tp->packets_out && (s32)(now - tp->lsndtime) > tp->rto) - tcp_cwnd_restart(tp); + tcp_cwnd_restart(tp, __sk_dst_get(sk)); tp->lsndtime = now; @@ -272,7 +272,7 @@ tcp_event_ack_sent(sk); if (skb->len != tcp_header_size) - tcp_event_data_sent(tp, skb); + tcp_event_data_sent(tp, skb, sk); TCP_INC_STATS(TcpOutSegs); diff -Nru a/net/ipv4/utils.c b/net/ipv4/utils.c --- a/net/ipv4/utils.c Fri Jun 27 14:19:56 2003 +++ b/net/ipv4/utils.c Fri Jun 27 14:19:56 2003 @@ -21,26 +21,8 @@ * 2 of the License, or (at your option) any later version. */ -#include <asm/uaccess.h> -#include <asm/system.h> #include <linux/types.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/errno.h> -#include <linux/stat.h> -#include <stdarg.h> -#include <linux/inet.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <net/ip.h> -#include <net/protocol.h> -#include <net/tcp.h> -#include <linux/skbuff.h> - +#include <asm/byteorder.h> /* * Convert an ASCII string to binary IP. diff -Nru a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c --- a/net/ipv6/exthdrs.c Fri Jun 27 14:19:52 2003 +++ b/net/ipv6/exthdrs.c Fri Jun 27 14:19:52 2003 @@ -432,7 +432,7 @@ } pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); - if (pkt_len < 0x10000) { + if (pkt_len <= IPV6_MAXPLEN) { icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); return 0; } diff -Nru a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c --- a/net/ipv6/ip6_output.c Fri Jun 27 14:19:52 2003 +++ b/net/ipv6/ip6_output.c Fri Jun 27 14:19:52 2003 @@ -621,7 +621,7 @@ if (opt) pktlength += opt->opt_flen + opt->opt_nflen; - if (pktlength > 0xFFFF + sizeof(struct ipv6hdr)) { + if (pktlength > sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { /* Jumbo datagram. It is assumed, that in the case of hdrincl jumbo option is supplied by user. @@ -939,7 +939,7 @@ mtu = dst_pmtu(&rt->u.dst) - hlen - sizeof(struct frag_hdr); if (skb_shinfo(skb)->frag_list) { - int first_len = 0; + int first_len = skb_pagelen(skb); if (first_len - hlen > mtu || ((first_len - hlen) & 7) || @@ -1264,8 +1264,8 @@ fragheaderlen = sizeof(struct ipv6hdr) + (opt ? opt->opt_nflen : 0); maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); - if (mtu < 65576) { - if (inet->cork.length + length > 0xFFFF - fragheaderlen) { + if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { + if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen); return -EMSGSIZE; } @@ -1461,7 +1461,7 @@ *(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000); - if (skb->len < 65536) + if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); else hdr->payload_len = 0; diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c --- a/net/ipv6/mcast.c Fri Jun 27 14:20:01 2003 +++ b/net/ipv6/mcast.c Fri Jun 27 14:20:01 2003 @@ -582,7 +582,7 @@ struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_mc_socklist *mc; struct ip6_sf_socklist *psl; - int rv = 0; + int rv = 1; read_lock(&ipv6_sk_mc_lock); for (mc = np->ipv6_mc_list; mc; mc = mc->next) { @@ -591,7 +591,7 @@ } if (!mc) { read_unlock(&ipv6_sk_mc_lock); - return 0; + return 1; } psl = mc->sflist; if (!psl) { @@ -603,8 +603,10 @@ if (ipv6_addr_cmp(&psl->sl_addr[i], src_addr) == 0) break; } - rv = (mc->sfmode == MCAST_INCLUDE && i < psl->sl_count); - rv |= (mc->sfmode == MCAST_EXCLUDE && i >= psl->sl_count); + if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count); + rv = 0; + if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count); + rv = 0; } read_unlock(&ipv6_sk_mc_lock); diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c --- a/net/ipv6/ndisc.c Fri Jun 27 14:19:58 2003 +++ b/net/ipv6/ndisc.c Fri Jun 27 14:19:58 2003 @@ -144,6 +144,19 @@ .gc_thresh3 = 1024, }; +/* ND options */ +struct ndisc_options { + struct nd_opt_hdr *nd_opt_array[7]; + struct nd_opt_hdr *nd_opt_piend; +}; + +#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR] +#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR] +#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO] +#define nd_opts_pi_end nd_opt_piend +#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR] +#define nd_opts_mtu nd_opt_array[ND_OPT_MTU] + #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7) static u8 *ndisc_fill_option(u8 *opt, int type, void *data, int data_len) @@ -160,8 +173,8 @@ return opt + space; } -struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, - struct nd_opt_hdr *end) +static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, + struct nd_opt_hdr *end) { int type; if (!cur || !end || cur >= end) @@ -173,8 +186,8 @@ return (cur <= end && cur->nd_opt_type == type ? cur : NULL); } -struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, - struct ndisc_options *ndopts) +static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, + struct ndisc_options *ndopts) { struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)opt; @@ -375,7 +388,7 @@ * Send a Neighbour Advertisement */ -int ndisc_output(struct sk_buff *skb) +static int ndisc_output(struct sk_buff *skb) { if (skb) { struct neighbour *neigh = (skb->dst ? skb->dst->neighbour : NULL); @@ -423,7 +436,7 @@ struct in6_addr *daddr, struct in6_addr *solicited_addr, int router, int solicited, int override, int inc_opt) { - static struct in6_addr tmpaddr; + struct in6_addr tmpaddr; struct inet6_ifaddr *ifp; struct inet6_dev *idev; struct flowi fl; @@ -701,7 +714,7 @@ } } -void ndisc_recv_ns(struct sk_buff *skb) +static void ndisc_recv_ns(struct sk_buff *skb) { struct nd_msg *msg = (struct nd_msg *)skb->h.raw; struct in6_addr *saddr = &skb->nh.ipv6h->saddr; @@ -713,6 +726,7 @@ struct net_device *dev = skb->dev; struct inet6_ifaddr *ifp; struct neighbour *neigh; + int addr_type = ipv6_addr_type(saddr); if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) { if (net_ratelimit()) @@ -720,6 +734,20 @@ return; } + /* + * RFC2461 7.1.1: + * DAD has to be destined for solicited node multicast address. + */ + if (addr_type == IPV6_ADDR_ANY && + !(daddr->s6_addr32[0] == htonl(0xff020000) && + daddr->s6_addr32[1] == htonl(0x00000000) && + daddr->s6_addr32[2] == htonl(0x00000001) && + daddr->s6_addr [12] == 0xff )) { + if (net_ratelimit()) + printk(KERN_DEBUG "ICMP6 NS: bad DAD packet (wrong destination)\n"); + return; + } + if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { if (net_ratelimit()) printk(KERN_WARNING "ICMP NS: invalid ND option, ignored.\n"); @@ -734,23 +762,20 @@ printk(KERN_WARNING "ICMP NS: bad lladdr length.\n"); return; } - } - /* XXX: RFC2461 7.1.1: - * If the IP source address is the unspecified address, there - * MUST NOT be source link-layer address option in the message. - * - * NOTE! Linux kernel < 2.4.4 broke this rule. - */ - - /* XXX: RFC2461 7.1.1: - * If the IP source address is the unspecified address, the IP - * destination address MUST be a solicited-node multicast address. - */ + /* XXX: RFC2461 7.1.1: + * If the IP source address is the unspecified address, + * there MUST NOT be source link-layer address option + * in the message. + */ + if (addr_type == IPV6_ADDR_ANY) { + if (net_ratelimit()) + printk(KERN_WARNING "ICMP6 NS: bad DAD packet (link-layer address option)\n"); + return; + } + } if ((ifp = ipv6_get_ifaddr(&msg->target, dev)) != NULL) { - int addr_type = ipv6_addr_type(saddr); - if (ifp->flags & IFA_F_TENTATIVE) { /* Address is tentative. If the source is unspecified address, it is someone @@ -816,7 +841,6 @@ in6_ifa_put(ifp); } else if (ipv6_chk_acast_addr(dev, &msg->target)) { struct inet6_dev *idev = in6_dev_get(dev); - int addr_type = ipv6_addr_type(saddr); /* anycast */ @@ -897,7 +921,7 @@ return; } -void ndisc_recv_na(struct sk_buff *skb) +static void ndisc_recv_na(struct sk_buff *skb) { struct nd_msg *msg = (struct nd_msg *)skb->h.raw; struct in6_addr *saddr = &skb->nh.ipv6h->saddr; diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c --- a/net/ipv6/netfilter/ip6_tables.c Fri Jun 27 14:20:03 2003 +++ b/net/ipv6/netfilter/ip6_tables.c Fri Jun 27 14:20:03 2003 @@ -101,10 +101,8 @@ unsigned int hook_entry[NF_IP6_NUMHOOKS]; unsigned int underflow[NF_IP6_NUMHOOKS]; - char padding[SMP_ALIGN((NF_IP6_NUMHOOKS*2+2)*sizeof(unsigned int))]; - /* ip6t_entry tables: one per CPU */ - char entries[0]; + char entries[0] ____cacheline_aligned; }; static LIST_HEAD(ip6t_target); @@ -1451,7 +1449,7 @@ int ret; struct ip6t_table_info *newinfo; static struct ip6t_table_info bootstrap - = { 0, 0, 0, { 0 }, { 0 }, { }, { } }; + = { 0, 0, 0, { 0 }, { 0 }, { } }; newinfo = vmalloc(sizeof(struct ip6t_table_info) + SMP_ALIGN(table->table->size) * NR_CPUS); @@ -1782,14 +1780,15 @@ }; #ifdef CONFIG_PROC_FS -static inline int print_name(const struct ip6t_table *t, +static inline int print_name(const char *i, off_t start_offset, char *buffer, int length, off_t *pos, unsigned int *count) { if ((*count)++ >= start_offset) { unsigned int namelen; - namelen = sprintf(buffer + *pos, "%s\n", t->name); + namelen = sprintf(buffer + *pos, "%s\n", + i + sizeof(struct list_head)); if (*pos + namelen > length) { /* Stop iterating */ return 1; @@ -1807,7 +1806,7 @@ if (down_interruptible(&ip6t_mutex) != 0) return 0; - LIST_FIND(&ip6t_tables, print_name, struct ip6t_table *, + LIST_FIND(&ip6t_tables, print_name, char *, offset, buffer, length, &pos, &count); up(&ip6t_mutex); @@ -1816,6 +1815,46 @@ *start=(char *)((unsigned long)count-offset); return pos; } + +static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return 0; + + LIST_FIND(&ip6t_target, print_name, char *, + offset, buffer, length, &pos, &count); + + up(&ip6t_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length) +{ + off_t pos = 0; + unsigned int count = 0; + + if (down_interruptible(&ip6t_mutex) != 0) + return 0; + + LIST_FIND(&ip6t_match, print_name, char *, + offset, buffer, length, &pos, &count); + + up(&ip6t_mutex); + + *start = (char *)((unsigned long)count - offset); + return pos; +} + +static struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = +{ { "ip6_tables_names", ip6t_get_tables }, + { "ip6_tables_targets", ip6t_get_targets }, + { "ip6_tables_matches", ip6t_get_matches }, + { NULL, NULL} }; #endif /*CONFIG_PROC_FS*/ static int __init init(void) @@ -1841,13 +1880,19 @@ #ifdef CONFIG_PROC_FS { struct proc_dir_entry *proc; - proc = proc_net_create("ip6_tables_names", 0, - ip6t_get_tables); - if (!proc) { - nf_unregister_sockopt(&ip6t_sockopts); - return -ENOMEM; + int i; + + for (i = 0; ip6t_proc_entry[i].name; i++) { + proc = proc_net_create(ip6t_proc_entry[i].name, 0, + ip6t_proc_entry[i].get_info); + if (!proc) { + while (--i >= 0) + proc_net_remove(ip6t_proc_entry[i].name); + nf_unregister_sockopt(&ip6t_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; } - proc->owner = THIS_MODULE; } #endif @@ -1859,7 +1904,11 @@ { nf_unregister_sockopt(&ip6t_sockopts); #ifdef CONFIG_PROC_FS - proc_net_remove("ip6_tables_names"); + { + int i; + for (i = 0; ip6t_proc_entry[i].name; i++) + proc_net_remove(ip6t_proc_entry[i].name); + } #endif } diff -Nru a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c --- a/net/ipv6/reassembly.c Fri Jun 27 14:19:54 2003 +++ b/net/ipv6/reassembly.c Fri Jun 27 14:19:54 2003 @@ -425,7 +425,7 @@ end = offset + (ntohs(skb->nh.ipv6h->payload_len) - ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1))); - if ((unsigned int)end >= 65536) { + if ((unsigned int)end > IPV6_MAXPLEN) { icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); return; } @@ -597,7 +597,7 @@ /* Unfragmented part is taken from the first segment. */ payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr); - if (payload_len > 65535) + if (payload_len > IPV6_MAXPLEN) goto out_oversize; /* Head of list must not be cloned. */ diff -Nru a/net/ipv6/route.c b/net/ipv6/route.c --- a/net/ipv6/route.c Fri Jun 27 14:19:59 2003 +++ b/net/ipv6/route.c Fri Jun 27 14:19:59 2003 @@ -600,6 +600,22 @@ return mtu; } +static inline unsigned int ipv6_advmss(unsigned int mtu) +{ + if (mtu < ip6_rt_min_advmss) + mtu = ip6_rt_min_advmss; + + /* + * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and + * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. + * IPV6_MAXPLEN is also valid and means: "any MSS, + * rely only on pmtu discovery" + */ + if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr)) + mtu = IPV6_MAXPLEN; + return mtu; +} + static int ipv6_get_hoplimit(struct net_device *dev) { int hoplimit = ipv6_devconf.hop_limit; @@ -790,16 +806,7 @@ if (!rt->u.dst.metrics[RTAX_MTU-1]) rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) - rt->u.dst.metrics[RTAX_ADVMSS-1] = - max_t(unsigned int, dst_pmtu(&rt->u.dst) - 60, - ip6_rt_min_advmss); - - /* Maximal non-jumbo IPv6 payload is 65535 and corresponding - MSS is 65535 - tcp_header_size. 65535 is also valid and - means: "any MSS, rely only on pmtu discovery" - */ - if (dst_metric(&rt->u.dst, RTAX_ADVMSS) > 65535-20) - rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535; + rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst)); rt->u.dst.dev = dev; return rt6_ins(rt, nlh, _rtattr); @@ -952,9 +959,7 @@ nrt->rt6i_nexthop = neigh_clone(neigh); /* Reset pmtu, it may be better */ nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); - nrt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, dst_pmtu(&nrt->u.dst) - 60, ip6_rt_min_advmss); - if (nrt->u.dst.metrics[RTAX_ADVMSS-1] > 65535-20) - nrt->u.dst.metrics[RTAX_ADVMSS-1] = 65535; + nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&nrt->u.dst)); if (rt6_ins(nrt, NULL, NULL)) goto out; @@ -1214,9 +1219,7 @@ rt->u.dst.output = ip6_output; rt->rt6i_dev = &loopback_dev; rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(rt->rt6i_dev); - rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, dst_pmtu(&rt->u.dst) - 60, ip6_rt_min_advmss); - if (rt->u.dst.metrics[RTAX_ADVMSS-1] > 65535-20) - rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535; + rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_pmtu(&rt->u.dst)); rt->u.dst.metrics[RTAX_HOPLIMIT-1] = ipv6_get_hoplimit(rt->rt6i_dev); rt->u.dst.obsolete = -1; @@ -1312,9 +1315,7 @@ (dst_pmtu(&rt->u.dst) < arg->mtu && dst_pmtu(&rt->u.dst) == idev->cnf.mtu6))) rt->u.dst.metrics[RTAX_MTU-1] = arg->mtu; - rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, arg->mtu - 60, ip6_rt_min_advmss); - if (rt->u.dst.metrics[RTAX_ADVMSS-1] > 65535-20) - rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535; + rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(arg->mtu); return 0; } diff -Nru a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c --- a/net/ipv6/sysctl_net_ipv6.c Fri Jun 27 14:19:53 2003 +++ b/net/ipv6/sysctl_net_ipv6.c Fri Jun 27 14:19:53 2003 @@ -86,7 +86,6 @@ { .ctl_name = NET_IPV6, .procname = "ipv6", - .maxlen = 0, .mode = 0555, .child = ipv6_table }, @@ -97,7 +96,6 @@ { .ctl_name = CTL_NET, .procname = "net", - .maxlen = 0, .mode = 0555, .child = ipv6_net_table }, diff -Nru a/net/key/af_key.c b/net/key/af_key.c --- a/net/key/af_key.c Fri Jun 27 14:19:54 2003 +++ b/net/key/af_key.c Fri Jun 27 14:19:54 2003 @@ -1213,7 +1213,7 @@ struct sk_buff *out_skb; struct sadb_msg *out_hdr; struct xfrm_state *x; - struct xfrm_state *x1; + int err; xfrm_probe_algs(); @@ -1221,31 +1221,11 @@ if (IS_ERR(x)) return PTR_ERR(x); - /* XXX there is race condition */ - x1 = pfkey_xfrm_state_lookup(hdr, ext_hdrs); - if (!x1) { - x1 = xfrm_find_acq(x->props.mode, x->props.reqid, x->id.proto, - &x->id.daddr, - &x->props.saddr, 0, x->props.family); - if (x1 && x1->id.spi != x->id.spi && x1->id.spi) { - xfrm_state_put(x1); - x1 = NULL; - } - } - - if (x1 && ((x1->id.spi && hdr->sadb_msg_type == SADB_ADD) || - (hdr->sadb_msg_type == SADB_UPDATE && xfrm_state_kern(x1)))) { + err = xfrm_state_replace(x, hdr->sadb_msg_type == SADB_ADD); + if (err < 0) { x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); - xfrm_state_put(x1); - return -EEXIST; - } - - xfrm_state_insert(x); - - if (x1) { - xfrm_state_delete(x1); - xfrm_state_put(x1); + return err; } out_skb = pfkey_xfrm_state2msg(x, 0, 3); diff -Nru a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c --- a/net/netrom/sysctl_net_netrom.c Fri Jun 27 14:19:54 2003 +++ b/net/netrom/sysctl_net_netrom.c Fri Jun 27 14:19:54 2003 @@ -162,7 +162,6 @@ { .ctl_name = NET_NETROM, .procname = "netrom", - .maxlen = 0, .mode = 0555, .child = nr_table }, @@ -173,7 +172,6 @@ { .ctl_name = CTL_NET, .procname = "net", - .maxlen = 0, .mode = 0555, .child = nr_dir_table }, diff -Nru a/net/netsyms.c b/net/netsyms.c --- a/net/netsyms.c Fri Jun 27 14:19:55 2003 +++ b/net/netsyms.c Fri Jun 27 14:19:55 2003 @@ -306,6 +306,7 @@ EXPORT_SYMBOL(__xfrm_state_destroy); EXPORT_SYMBOL(xfrm_state_find); EXPORT_SYMBOL(xfrm_state_insert); +EXPORT_SYMBOL(xfrm_state_replace); EXPORT_SYMBOL(xfrm_state_check_expire); EXPORT_SYMBOL(xfrm_state_check_space); EXPORT_SYMBOL(xfrm_state_lookup); diff -Nru a/net/rose/sysctl_net_rose.c b/net/rose/sysctl_net_rose.c --- a/net/rose/sysctl_net_rose.c Fri Jun 27 14:19:30 2003 +++ b/net/rose/sysctl_net_rose.c Fri Jun 27 14:19:30 2003 @@ -142,7 +142,6 @@ { .ctl_name = NET_ROSE, .procname = "rose", - .maxlen = 0, .mode = 0555, .child = rose_table }, @@ -153,7 +152,6 @@ { .ctl_name = CTL_NET, .procname = "net", - .maxlen = 0, .mode = 0555, .child = rose_dir_table }, diff -Nru a/net/rxrpc/sysctl.c b/net/rxrpc/sysctl.c --- a/net/rxrpc/sysctl.c Fri Jun 27 14:19:55 2003 +++ b/net/rxrpc/sysctl.c Fri Jun 27 14:19:55 2003 @@ -68,7 +68,6 @@ { .ctl_name = 1, .procname = "rxrpc", - .maxlen = 0, .mode = 0555, .child = rxrpc_sysctl_table }, diff -Nru a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h --- a/net/sched/cls_rsvp.h Fri Jun 27 14:19:53 2003 +++ b/net/sched/cls_rsvp.h Fri Jun 27 14:19:53 2003 @@ -515,7 +515,7 @@ for (sp = &data->ht[h1]; (s=*sp) != NULL; sp = &s->next) { if (dst[RSVP_DST_LEN-1] == s->dst[RSVP_DST_LEN-1] && - pinfo->protocol == s->protocol && + pinfo && pinfo->protocol == s->protocol && memcmp(&pinfo->dpi, &s->dpi, sizeof(s->dpi)) == 0 #if RSVP_DST_LEN == 4 && dst[0] == s->dst[0] @@ -557,9 +557,12 @@ goto errout; memset(s, 0, sizeof(*s)); memcpy(s->dst, dst, sizeof(s->dst)); - s->dpi = pinfo->dpi; - s->protocol = pinfo->protocol; - s->tunnelid = pinfo->tunnelid; + + if (pinfo) { + s->dpi = pinfo->dpi; + s->protocol = pinfo->protocol; + s->tunnelid = pinfo->tunnelid; + } for (sp = &data->ht[h1]; *sp; sp = &(*sp)->next) { if (((*sp)->dpi.mask&s->dpi.mask) != s->dpi.mask) break; diff -Nru a/net/sched/sch_teql.c b/net/sched/sch_teql.c --- a/net/sched/sch_teql.c Fri Jun 27 14:19:54 2003 +++ b/net/sched/sch_teql.c Fri Jun 27 14:19:54 2003 @@ -67,8 +67,9 @@ struct teql_master { struct Qdisc_ops qops; - struct net_device dev; + struct net_device *dev; struct Qdisc *slaves; + struct list_head master_list; struct net_device_stats stats; }; @@ -122,13 +123,13 @@ skb = __skb_dequeue(&dat->q); if (skb == NULL) { - struct net_device *m = dat->m->dev.qdisc->dev; + struct net_device *m = dat->m->dev->qdisc->dev; if (m) { dat->m->slaves = sch; netif_wake_queue(m); } } - sch->q.qlen = dat->q.qlen + dat->m->dev.qdisc->q.qlen; + sch->q.qlen = dat->q.qlen + dat->m->dev->qdisc->q.qlen; return skb; } @@ -165,9 +166,9 @@ master->slaves = NEXT_SLAVE(q); if (q == master->slaves) { master->slaves = NULL; - spin_lock_bh(&master->dev.queue_lock); - qdisc_reset(master->dev.qdisc); - spin_unlock_bh(&master->dev.queue_lock); + spin_lock_bh(&master->dev->queue_lock); + qdisc_reset(master->dev->qdisc); + spin_unlock_bh(&master->dev->queue_lock); } } skb_queue_purge(&dat->q); @@ -185,10 +186,10 @@ struct teql_master *m = (struct teql_master*)sch->ops; struct teql_sched_data *q = (struct teql_sched_data *)sch->data; - if (dev->hard_header_len > m->dev.hard_header_len) + if (dev->hard_header_len > m->dev->hard_header_len) return -EINVAL; - if (&m->dev == dev) + if (m->dev == dev) return -ELOOP; q->m = m; @@ -196,29 +197,29 @@ skb_queue_head_init(&q->q); if (m->slaves) { - if (m->dev.flags & IFF_UP) { - if ((m->dev.flags&IFF_POINTOPOINT && !(dev->flags&IFF_POINTOPOINT)) - || (m->dev.flags&IFF_BROADCAST && !(dev->flags&IFF_BROADCAST)) - || (m->dev.flags&IFF_MULTICAST && !(dev->flags&IFF_MULTICAST)) - || dev->mtu < m->dev.mtu) + if (m->dev->flags & IFF_UP) { + if ((m->dev->flags&IFF_POINTOPOINT && !(dev->flags&IFF_POINTOPOINT)) + || (m->dev->flags&IFF_BROADCAST && !(dev->flags&IFF_BROADCAST)) + || (m->dev->flags&IFF_MULTICAST && !(dev->flags&IFF_MULTICAST)) + || dev->mtu < m->dev->mtu) return -EINVAL; } else { if (!(dev->flags&IFF_POINTOPOINT)) - m->dev.flags &= ~IFF_POINTOPOINT; + m->dev->flags &= ~IFF_POINTOPOINT; if (!(dev->flags&IFF_BROADCAST)) - m->dev.flags &= ~IFF_BROADCAST; + m->dev->flags &= ~IFF_BROADCAST; if (!(dev->flags&IFF_MULTICAST)) - m->dev.flags &= ~IFF_MULTICAST; - if (dev->mtu < m->dev.mtu) - m->dev.mtu = dev->mtu; + m->dev->flags &= ~IFF_MULTICAST; + if (dev->mtu < m->dev->mtu) + m->dev->mtu = dev->mtu; } q->next = NEXT_SLAVE(m->slaves); NEXT_SLAVE(m->slaves) = sch; } else { q->next = sch; m->slaves = sch; - m->dev.mtu = dev->mtu; - m->dev.flags = (m->dev.flags&~FMASK)|(dev->flags&FMASK); + m->dev->mtu = dev->mtu; + m->dev->flags = (m->dev->flags&~FMASK)|(dev->flags&FMASK); } return 0; } @@ -379,9 +380,9 @@ flags &= ~IFF_MULTICAST; } while ((q = NEXT_SLAVE(q)) != m->slaves); - m->dev.mtu = mtu; - m->dev.flags = (m->dev.flags&~FMASK) | flags; - netif_start_queue(&m->dev); + m->dev->mtu = mtu; + m->dev->flags = (m->dev->flags&~FMASK) | flags; + netif_start_queue(m->dev); return 0; } @@ -417,8 +418,30 @@ return 0; } -static int teql_master_init(struct net_device *dev) +static __init int teql_master_init(struct net_device *dev) { + struct teql_master *master = dev->priv; + struct Qdisc_ops *ops = &master->qops; + + master->dev = dev; + + strlcpy(ops->id, dev->name, IFNAMSIZ); + ops->priv_size = sizeof(struct teql_sched_data); + + ops->enqueue = teql_enqueue; + ops->dequeue = teql_dequeue; + ops->requeue = teql_requeue; + ops->init = teql_qdisc_init; + ops->reset = teql_reset; + ops->destroy = teql_destroy; + ops->owner = THIS_MODULE; + + return register_qdisc(ops); +} + +static __init void teql_master_setup(struct net_device *dev) +{ + dev->init = teql_master_init; dev->open = teql_master_open; dev->hard_start_xmit = teql_master_xmit; dev->stop = teql_master_close; @@ -429,62 +452,58 @@ dev->tx_queue_len = 100; dev->flags = IFF_NOARP; dev->hard_header_len = LL_MAX_HEADER; - return 0; + SET_MODULE_OWNER(dev); } -static struct teql_master the_master = { -{ - .next = NULL, - .cl_ops = NULL, - .id = "", - .priv_size = sizeof(struct teql_sched_data), - .enqueue = teql_enqueue, - .dequeue = teql_dequeue, - .requeue = teql_requeue, - .drop = NULL, - .init = teql_qdisc_init, - .reset = teql_reset, - .destroy = teql_destroy, - .dump = NULL, - .owner = THIS_MODULE, -},}; - - -#ifdef MODULE -int init_module(void) -#else +static LIST_HEAD(master_dev_list); +static spinlock_t master_dev_lock = SPIN_LOCK_UNLOCKED; +static int max_equalizers = 1; +MODULE_PARM(max_equalizers, "i"); +MODULE_PARM_DESC(max_equalizers, "Max number of link equalizers"); + int __init teql_init(void) -#endif { - int err; - - rtnl_lock(); + int i; + int err = 0; - the_master.dev.priv = (void*)&the_master; - err = dev_alloc_name(&the_master.dev, "teql%d"); - if (err < 0) - return err; - memcpy(the_master.qops.id, the_master.dev.name, IFNAMSIZ); - the_master.dev.init = teql_master_init; - - SET_MODULE_OWNER(&the_master.dev); - err = register_netdevice(&the_master.dev); - if (err == 0) { - err = register_qdisc(&the_master.qops); - if (err) - unregister_netdevice(&the_master.dev); + for (i = 0; i < max_equalizers; i++) { + struct net_device *dev; + struct teql_master *master; + + dev = alloc_netdev(sizeof(struct teql_master), + "teql%d", teql_master_setup); + if (!dev) + return -ENOMEM; + + if ((err = register_netdev(dev))) + goto out; + + master = dev->priv; + spin_lock(&master_dev_lock); + list_add_tail(&master->master_list, &master_dev_list); + spin_unlock(&master_dev_lock); } - rtnl_unlock(); + out: return err; } -#ifdef MODULE -void cleanup_module(void) +static void __exit teql_exit(void) { - rtnl_lock(); - unregister_qdisc(&the_master.qops); - unregister_netdevice(&the_master.dev); - rtnl_unlock(); + struct teql_master *master, *nxt; + + spin_lock(&master_dev_lock); + list_for_each_entry_safe(master, nxt, &master_dev_list, master_list) { + + list_del(&master->master_list); + + unregister_qdisc(&master->qops); + unregister_netdev(master->dev); + kfree(master->dev); + } + spin_unlock(&master_dev_lock); } -#endif + +module_init(teql_init); +module_exit(teql_exit); + MODULE_LICENSE("GPL"); diff -Nru a/net/sctp/associola.c b/net/sctp/associola.c --- a/net/sctp/associola.c Fri Jun 27 14:19:52 2003 +++ b/net/sctp/associola.c Fri Jun 27 14:19:52 2003 @@ -41,6 +41,7 @@ * Hui Huang <hui.huang@nokia.com> * Sridhar Samudrala <sri@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com> + * Ryan Layer <rmlayer@us.ibm.com> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -125,23 +126,24 @@ asoc->base.addr_lock = RW_LOCK_UNLOCKED; asoc->state = SCTP_STATE_CLOSED; - asoc->state_timestamp = jiffies; - - /* Set things that have constant value. */ - asoc->cookie_life.tv_sec = sctp_valid_cookie_life / HZ; - asoc->cookie_life.tv_usec = (sctp_valid_cookie_life % HZ) * - 1000000L / HZ; + /* Set these values from the socket values, a conversion between + * millsecons to seconds/microseconds must also be done. + */ + asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000; + asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000) + * 1000; asoc->pmtu = 0; asoc->frag_point = 0; - /* Initialize the default association max_retrans and RTO values. */ - asoc->max_retrans = sctp_max_retrans_association; - asoc->rto_initial = sctp_rto_initial; - asoc->rto_max = sctp_rto_max; - asoc->rto_min = sctp_rto_min; + /* Set the association max_retrans and RTO values from the + * socket values. + */ + asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt; + asoc->rto_initial = sp->rtoinfo.srto_initial * HZ / 1000; + asoc->rto_max = sp->rtoinfo.srto_max * HZ / 1000; + asoc->rto_min = sp->rtoinfo.srto_min * HZ / 1000; - asoc->overall_error_threshold = asoc->max_retrans; asoc->overall_error_count = 0; /* Initialize the maximum mumber of new data packets that can be sent @@ -164,7 +166,8 @@ asoc->c.sinit_max_instreams = sp->initmsg.sinit_max_instreams; asoc->c.sinit_num_ostreams = sp->initmsg.sinit_num_ostreams; asoc->max_init_attempts = sp->initmsg.sinit_max_attempts; - asoc->max_init_timeo = sp->initmsg.sinit_max_init_timeo * HZ; + + asoc->max_init_timeo = sp->initmsg.sinit_max_init_timeo * HZ / 1000; /* Allocate storage for the ssnmap after the inbound and outbound * streams have been negotiated during Init. @@ -281,7 +284,7 @@ asoc->default_flags = sp->default_flags; asoc->default_context = sp->default_context; asoc->default_timetolive = sp->default_timetolive; - + return asoc; fail_init: @@ -384,7 +387,7 @@ if (transport->active) asoc->peer.active_path = transport; - /* + /* * SFR-CACC algorithm: * Upon the receipt of a request to change the primary * destination address, on the data structure for the new @@ -491,9 +494,14 @@ /* Initialize the peer's heartbeat interval based on the * sock configured value. */ - peer->hb_interval = sp->paddrparam.spp_hbinterval * HZ; + /* Set the path max_retrans. */ + peer->max_retrans = asoc->max_retrans; + + /* Set the transport's RTO.initial value */ + peer->rto = asoc->rto_initial; + /* Attach the remote transport to our asoc. */ list_add_tail(&peer->transports, &asoc->peer.transport_addr_list); @@ -793,6 +801,26 @@ return transport; } +/* Is this a live association structure. */ +int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc) +{ + + /* First, verify that this is a kernel address. */ + if (!sctp_is_valid_kaddr((unsigned long) asoc)) + return 0; + + /* Verify that this _is_ an sctp_association + * data structure and if so, that the socket matches. + */ + if (SCTP_ASSOC_EYECATCHER != asoc->eyecatcher) + return 0; + if (asoc->base.sk != sk) + return 0; + + /* The association is valid. */ + return 1; +} + /* Do delayed input processing. This is scheduled by sctp_rcv(). */ static void sctp_assoc_bh_rcv(struct sctp_association *asoc) { @@ -801,7 +829,6 @@ struct sock *sk; struct sctp_inq *inqueue; int state, subtype; - sctp_assoc_t associd = sctp_assoc2id(asoc); int error = 0; /* The association should be held so we should be safe. */ @@ -831,7 +858,7 @@ /* Check to see if the association is freed in response to * the incoming chunk. If so, get out of the while loop. */ - if (!sctp_id2assoc(sk, associd)) + if (!sctp_assoc_valid(sk, asoc)) break; /* If there is an error on chunk, discard this packet. */ @@ -1033,7 +1060,7 @@ } /* Increase asoc's rwnd by len and send any window update SACK if needed. */ -void sctp_assoc_rwnd_increase(struct sctp_association *asoc, int len) +void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned len) { struct sctp_chunk *sack; struct timer_list *timer; @@ -1079,7 +1106,7 @@ } /* Decrease asoc's rwnd by len. */ -void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, int len) +void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len) { SCTP_ASSERT(asoc->rwnd, "rwnd zero", return); SCTP_ASSERT(!asoc->rwnd_over, "rwnd_over not zero", return); @@ -1119,11 +1146,11 @@ /* Build the association's bind address list from the cookie. */ int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *asoc, - sctp_cookie_t *cookie, int gfp) + struct sctp_cookie *cookie, int gfp) { int var_size2 = ntohs(cookie->peer_init->chunk_hdr.length); int var_size3 = cookie->raw_addr_list_len; - __u8 *raw = (__u8 *)cookie + sizeof(sctp_cookie_t) + var_size2; + __u8 *raw = (__u8 *)cookie + sizeof(struct sctp_cookie) + var_size2; return sctp_raw_to_bind_addrs(&asoc->base.bind_addr, raw, var_size3, asoc->ep->base.bind_addr.port, gfp); diff -Nru a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c --- a/net/sctp/bind_addr.c Fri Jun 27 14:20:00 2003 +++ b/net/sctp/bind_addr.c Fri Jun 27 14:20:00 2003 @@ -65,7 +65,7 @@ const struct sctp_bind_addr *src, sctp_scope_t scope, int gfp, int flags) { - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; struct list_head *pos; int error = 0; @@ -74,7 +74,7 @@ /* Extract the addresses which are relevant for this scope. */ list_for_each(pos, &src->address_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); error = sctp_copy_one_addr(dest, &addr->a, scope, gfp, flags); if (error < 0) @@ -87,7 +87,7 @@ */ if (list_empty(&dest->address_list) && (SCTP_SCOPE_GLOBAL == scope)) { list_for_each(pos, &src->address_list) { - addr = list_entry(pos, struct sockaddr_storage_list, + addr = list_entry(pos, struct sctp_sockaddr_entry, list); error = sctp_copy_one_addr(dest, &addr->a, SCTP_SCOPE_LINK, gfp, @@ -135,12 +135,12 @@ /* Dispose of the address list. */ static void sctp_bind_addr_clean(struct sctp_bind_addr *bp) { - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; struct list_head *pos, *temp; /* Empty the bind address list. */ list_for_each_safe(pos, temp, &bp->address_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); list_del(pos); kfree(addr); SCTP_DBG_OBJCNT_DEC(addr); @@ -163,14 +163,14 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, int gfp) { - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; /* Add the address to the bind address list. */ - addr = t_new(struct sockaddr_storage_list, gfp); + addr = t_new(struct sctp_sockaddr_entry, gfp); if (!addr) return -ENOMEM; - addr->a = *new; + memcpy(&addr->a, new, sizeof(*new)); /* Fix up the port if it has not yet been set. * Both v4 and v6 have the port at the same offset. @@ -191,10 +191,10 @@ int sctp_del_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *del_addr) { struct list_head *pos, *temp; - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; list_for_each_safe(pos, temp, &bp->address_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); if (sctp_cmp_addr_exact(&addr->a, del_addr)) { /* Found the exact match. */ list_del(pos); @@ -219,22 +219,22 @@ union sctp_params addrparms; union sctp_params retval; int addrparms_len; - sctp_addr_param_t rawaddr; + union sctp_addr_param rawaddr; int len; - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; struct list_head *pos; addrparms_len = 0; len = 0; /* Allocate enough memory at once. */ list_for_each(pos, &bp->address_list) { - len += sizeof(sctp_addr_param_t); + len += sizeof(union sctp_addr_param); } /* Don't even bother embedding an address if there * is only one. */ - if (len == sizeof(sctp_addr_param_t)) { + if (len == sizeof(union sctp_addr_param)) { retval.v = NULL; goto end_raw; } @@ -246,7 +246,7 @@ addrparms = retval; list_for_each(pos, &bp->address_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); len = sockaddr2sctp_addr(&addr->a, &rawaddr); memcpy(addrparms.v, &rawaddr, len); addrparms.v += len; @@ -265,16 +265,16 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, int addrs_len, __u16 port, int gfp) { - sctp_addr_param_t *rawaddr; - sctp_paramhdr_t *param; + union sctp_addr_param *rawaddr; + struct sctp_paramhdr *param; union sctp_addr addr; int retval = 0; int len; /* Convert the raw address to standard address format */ while (addrs_len) { - param = (sctp_paramhdr_t *)raw_addr_list; - rawaddr = (sctp_addr_param_t *)raw_addr_list; + param = (struct sctp_paramhdr *)raw_addr_list; + rawaddr = (union sctp_addr_param *)raw_addr_list; switch (param->type) { case SCTP_PARAM_IPV4_ADDRESS: @@ -312,11 +312,11 @@ const union sctp_addr *addr, struct sctp_opt *opt) { - struct sockaddr_storage_list *laddr; + struct sctp_sockaddr_entry *laddr; struct list_head *pos; list_for_each(pos, &bp->address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, list); + laddr = list_entry(pos, struct sctp_sockaddr_entry, list); if (opt->pf->cmp_addr(&laddr->a, addr, opt)) return 1; } diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c --- a/net/sctp/endpointola.c Fri Jun 27 14:19:53 2003 +++ b/net/sctp/endpointola.c Fri Jun 27 14:19:53 2003 @@ -129,7 +129,7 @@ ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = SCTP_DEFAULT_TIMEOUT_T1_INIT; ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = - sp->rtoinfo.srto_initial; + sp->rtoinfo.srto_initial * HZ / 1000; ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; /* sctpimpguide-05 Section 2.12.2 @@ -137,7 +137,7 @@ * recommended value of 5 times 'RTO.Max'. */ ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] - = 5 * sp->rtoinfo.srto_max; + = 5 * (sp->rtoinfo.srto_max * HZ / 1000); ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; @@ -313,13 +313,13 @@ const union sctp_addr *paddr) { struct list_head *pos; - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; struct sctp_bind_addr *bp; sctp_read_lock(&ep->base.addr_lock); bp = &ep->base.bind_addr; list_for_each(pos, &bp->address_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); if (sctp_has_association(&addr->a, paddr)) { sctp_read_unlock(&ep->base.addr_lock); return 1; diff -Nru a/net/sctp/hashdriver.c b/net/sctp/hashdriver.c --- a/net/sctp/hashdriver.c Fri Jun 27 14:20:00 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,128 +0,0 @@ -/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola - * - * This file origiantes from Randy Stewart's SCTP reference Implementation. - * - * The SCTP reference implementation 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, or (at your option) - * any later version. - * - * The SCTP reference implementation is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * ************************ - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Please send any bug reports or fixes you make to the - * email address(es): - * lksctp developers <lksctp-developers@lists.sourceforge.net> - * - * Or submit a bug report through the following website: - * http://www.sf.net/projects/lksctp - * - * Written or modified by: - * Randy Stewart rstewar1@email.mot.com - * Ken Morneau kmorneau@cisco.com - * Qiaobing Xie qxie1@email.mot.com - * - * Any bugs reported given to us we will try to fix... any fixes shared will - * be incorperated into the next SCTP release. - * - * There are still LOTS of bugs in this code... I always run on the motto - * "it is a wonder any code ever works :)" - */ - -#include <linux/types.h> -#include <asm/string.h> -#include <net/sctp/sctp.h> -#include <net/sctp/sla1.h> - -/* SCTP Main driver. - * passing a two pointers and two lengths, - * returning a digest pointer filled. The md5 code - * was taken directly from the RFC (2104) so to understand it - * you may want to go look at the RFC referenced in the - * SCTP spec. We did modify this code to either user OUR - * implementation of SLA1 or the MD5 that comes from its - * RFC. SLA1 may have IPR issues so you need to check in - * to this if you wish to use it... Or at least that is - * what the FIP-180.1 web page says. - */ - -void sctp_hash_digest(const char *key, const int in_key_len, - const char *text, const int text_len, - __u8 *digest) -{ - int key_len = in_key_len; - struct SLA_1_Context context; - - __u8 k_ipad[65]; /* inner padding - - * key XORd with ipad - */ - __u8 k_opad[65]; /* outer padding - - * key XORd with opad - */ - __u8 tk[20]; - int i; - - /* if key is longer than 64 bytes reset it to key=MD5(key) */ - if (key_len > 64) { - struct SLA_1_Context tctx; - - SLA1_Init(&tctx); - SLA1_Process(&tctx, key, key_len); - SLA1_Final(&tctx,tk); - key = tk; - key_len = 20; - } - - /* - * the HMAC_MD5 transform looks like: - * - * MD5(K XOR opad, MD5(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected - */ - - /* start out by storing key in pads */ - memset(k_ipad, 0, sizeof k_ipad); - memset(k_opad, 0, sizeof k_opad); - memcpy(k_ipad, key, key_len); - memcpy(k_opad, key, key_len); - - /* XOR key with ipad and opad values */ - for (i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - /* perform inner hash */ - SLA1_Init(&context); /* init context for 1st - * pass - */ - SLA1_Process(&context, k_ipad, 64); /* start with inner pad */ - SLA1_Process(&context, text, text_len); /* then text of datagram */ - SLA1_Final(&context,digest); /* finish up 1st pass */ - - /* - * perform outer hash - */ - SLA1_Init(&context); /* init context for 2nd - * pass - */ - SLA1_Process(&context, k_opad, 64); /* start with outer pad */ - SLA1_Process(&context, digest, 20); /* then results of 1st - * hash - */ - SLA1_Final(&context, digest); /* finish up 2nd pass */ -} - diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c --- a/net/sctp/ipv6.c Fri Jun 27 14:19:58 2003 +++ b/net/sctp/ipv6.c Fri Jun 27 14:19:58 2003 @@ -248,7 +248,7 @@ { struct sctp_bind_addr *bp; rwlock_t *addr_lock; - struct sockaddr_storage_list *laddr; + struct sctp_sockaddr_entry *laddr; struct list_head *pos; sctp_scope_t scope; union sctp_addr *baddr = NULL; @@ -277,7 +277,7 @@ */ sctp_read_lock(addr_lock); list_for_each(pos, &bp->address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, list); + laddr = list_entry(pos, struct sctp_sockaddr_entry, list); if ((laddr->a.sa.sa_family == AF_INET6) && (scope <= sctp_scope(&laddr->a))) { bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); @@ -309,7 +309,7 @@ { struct inet6_dev *in6_dev; struct inet6_ifaddr *ifp; - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; read_lock(&addrconf_lock); if ((in6_dev = __in6_dev_get(dev)) == NULL) { @@ -320,7 +320,7 @@ read_lock(&in6_dev->lock); for (ifp = in6_dev->addr_list; ifp; ifp = ifp->if_next) { /* Add the address to the local list. */ - addr = t_new(struct sockaddr_storage_list, GFP_ATOMIC); + addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC); if (addr) { addr->a.v6.sin6_family = AF_INET6; addr->a.v6.sin6_port = 0; diff -Nru a/net/sctp/outqueue.c b/net/sctp/outqueue.c --- a/net/sctp/outqueue.c Fri Jun 27 14:19:54 2003 +++ b/net/sctp/outqueue.c Fri Jun 27 14:19:54 2003 @@ -1012,7 +1012,7 @@ __u32 sack_ctsn, ctsn, tsn; __u32 highest_tsn, highest_new_tsn; __u32 sack_a_rwnd; - int outstanding; + unsigned outstanding; struct sctp_transport *primary = asoc->peer.primary_path; int count_of_newacks = 0; diff -Nru a/net/sctp/proc.c b/net/sctp/proc.c --- a/net/sctp/proc.c Fri Jun 27 14:19:55 2003 +++ b/net/sctp/proc.c Fri Jun 27 14:19:55 2003 @@ -133,12 +133,12 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) { struct list_head *pos; - struct sockaddr_storage_list *laddr; + struct sctp_sockaddr_entry *laddr; union sctp_addr *addr; struct sctp_af *af; list_for_each(pos, &epb->bind_addr.address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, list); + laddr = list_entry(pos, struct sctp_sockaddr_entry, list); addr = (union sctp_addr *)&laddr->a; af = sctp_get_af_specific(addr->sa.sa_family); af->seq_dump_addr(seq, addr); diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c --- a/net/sctp/protocol.c Fri Jun 27 14:19:58 2003 +++ b/net/sctp/protocol.c Fri Jun 27 14:19:58 2003 @@ -143,7 +143,7 @@ { struct in_device *in_dev; struct in_ifaddr *ifa; - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; read_lock(&inetdev_lock); if ((in_dev = __in_dev_get(dev)) == NULL) { @@ -154,7 +154,7 @@ read_lock(&in_dev->lock); for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { /* Add the address to the local list. */ - addr = t_new(struct sockaddr_storage_list, GFP_ATOMIC); + addr = t_new(struct sctp_sockaddr_entry, GFP_ATOMIC); if (addr) { addr->a.v4.sin_family = AF_INET; addr->a.v4.sin_port = 0; @@ -198,11 +198,11 @@ /* Free the existing local addresses. */ static void __sctp_free_local_addr_list(void) { - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; struct list_head *pos, *temp; list_for_each_safe(pos, temp, &sctp_local_addr_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); list_del(pos); kfree(addr); } @@ -222,14 +222,14 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, int gfp, int copy_flags) { - struct sockaddr_storage_list *addr; + struct sctp_sockaddr_entry *addr; int error = 0; struct list_head *pos; unsigned long flags; sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags); list_for_each(pos, &sctp_local_addr_list) { - addr = list_entry(pos, struct sockaddr_storage_list, list); + addr = list_entry(pos, struct sctp_sockaddr_entry, list); if (sctp_in_scope(&addr->a, scope)) { /* Now that the address is in scope, check to see if * the address type is really supported by the local @@ -412,7 +412,7 @@ struct flowi fl; struct sctp_bind_addr *bp; rwlock_t *addr_lock; - struct sockaddr_storage_list *laddr; + struct sctp_sockaddr_entry *laddr; struct list_head *pos; struct dst_entry *dst = NULL; union sctp_addr dst_saddr; @@ -447,7 +447,7 @@ */ sctp_read_lock(addr_lock); list_for_each(pos, &bp->address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, + laddr = list_entry(pos, struct sctp_sockaddr_entry, list); sctp_v4_dst_saddr(&dst_saddr, dst, bp->port); if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) @@ -467,7 +467,7 @@ */ sctp_read_lock(addr_lock); list_for_each(pos, &bp->address_list) { - laddr = list_entry(pos, struct sockaddr_storage_list, list); + laddr = list_entry(pos, struct sctp_sockaddr_entry, list); if (AF_INET == laddr->a.sa.sa_family) { fl.fl4_src = laddr->a.v4.sin_addr.s_addr; diff -Nru a/net/sctp/sla1.c b/net/sctp/sla1.c --- a/net/sctp/sla1.c Fri Jun 27 14:19:56 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,281 +0,0 @@ -/* SCTP kernel reference Implementation - * Copyright (c) 1999-2000 Cisco, Inc. - * Copyright (c) 1999-2001 Motorola, Inc. - * - * This file is part of the SCTP kernel reference Implementation - * - * (It's really SHA-1 but Hey I was tired when I created this - * file, and on a plane to France :-) - * - * The SCTP reference implementation 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, or (at your option) - * any later version. - * - * The SCTP reference implementation is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * ************************ - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU CC; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Please send any bug reports or fixes you make to the - * email address(es): - * lksctp developers <lksctp-developers@lists.sourceforge.net> - * - * Or submit a bug report through the following website: - * http://www.sf.net/projects/lksctp - * - * Written or modified by: - * Randall Stewart <rstewar1@email.mot.com> - * kmorneau@cisco.com - * qxie1@email.mot.com - * - * Based on: - * Randy Stewart, et al. SCTP Reference Implementation which is licenced - * under the GPL. - * - * Any bugs reported given to us we will try to fix... any fixes shared will - * be incorporated into the next SCTP release. - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/fcntl.h> -#include <asm/string.h> /* for memcpy */ -#include <linux/sched.h> /* dead chicken for in.h */ -#include <linux/in.h> /* for htonl and ntohl */ - -#include <net/sctp/sla1.h> - -void SLA1_Init(struct SLA_1_Context *ctx) -{ - /* Init the SLA-1 context structure. */ - ctx->A = 0; - ctx->B = 0; - ctx->C = 0; - ctx->D = 0; - ctx->E = 0; - ctx->H0 = H0INIT; - ctx->H1 = H1INIT; - ctx->H2 = H2INIT; - ctx->H3 = H3INIT; - ctx->H4 = H4INIT; - ctx->TEMP = 0; - memset(ctx->words, 0, sizeof(ctx->words)); - ctx->howManyInBlock = 0; - ctx->runningTotal = 0; -} - -void SLA1processABlock(struct SLA_1_Context *ctx,unsigned int *block) -{ - int i; - /* init the W0-W15 to the block of words being - * hashed. - */ - /* step a) */ - - for (i = 0; i < 16; i++) - ctx->words[i] = ntohl(block[i]); - - /* now init the rest based on the SLA-1 formula, step b) */ - for (i = 16; i < 80; i++) - ctx->words[i] = - CSHIFT(1, ((ctx->words[(i-3)]) ^ - (ctx->words[(i-8)]) ^ - (ctx->words[(i-14)]) ^ - (ctx->words[(i-16)]))); - - /* step c) */ - ctx->A = ctx->H0; - ctx->B = ctx->H1; - ctx->C = ctx->H2; - ctx->D = ctx->H3; - ctx->E = ctx->H4; - - /* step d) */ - for (i = 0; i < 80; i++) { - if (i < 20) { - ctx->TEMP = ((CSHIFT(5, ctx->A)) + - (F1(ctx->B, ctx->C, ctx->D)) + - (ctx->E) + - ctx->words[i] + - K1 - ); - } else if (i < 40) { - ctx->TEMP = ((CSHIFT(5, ctx->A)) + - (F2(ctx->B, ctx->C, ctx->D)) + - (ctx->E) + - (ctx->words[i]) + - K2 - ); - } else if (i < 60) { - ctx->TEMP = ((CSHIFT(5, ctx->A)) + - (F3(ctx->B, ctx->C, ctx->D)) + - (ctx->E) + - (ctx->words[i]) + - K3 - ); - } else { - ctx->TEMP = ((CSHIFT(5, ctx->A)) + - (F4(ctx->B, ctx->C, ctx->D)) + - (ctx->E) + - (ctx->words[i]) + - K4 - ); - } - ctx->E = ctx->D; - ctx->D = ctx->C; - ctx->C = CSHIFT(30, ctx->B); - ctx->B = ctx->A; - ctx->A = ctx->TEMP; - } - - /* step e) */ - ctx->H0 = (ctx->H0) + (ctx->A); - ctx->H1 = (ctx->H1) + (ctx->B); - ctx->H2 = (ctx->H2) + (ctx->C); - ctx->H3 = (ctx->H3) + (ctx->D); - ctx->H4 = (ctx->H4) + (ctx->E); -} - -void SLA1_Process(struct SLA_1_Context *ctx, const unsigned char *ptr, int siz) -{ - int numberLeft, leftToFill; - - numberLeft = siz; - while (numberLeft > 0) { - leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock; - if (leftToFill > numberLeft) { - /* can only partially fill up this one */ - memcpy(&ctx->SLAblock[ctx->howManyInBlock], - ptr, numberLeft); - ctx->howManyInBlock += siz; - ctx->runningTotal += siz; - break; - } else { - /* block is now full, process it */ - memcpy(&ctx->SLAblock[ctx->howManyInBlock], - ptr, leftToFill); - SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock); - numberLeft -= leftToFill; - ctx->runningTotal += leftToFill; - ctx->howManyInBlock = 0; - } - } -} - -void SLA1_Final(struct SLA_1_Context *ctx, unsigned char *digestBuf) -{ - /* if any left in block fill with padding - * and process. Then transfer the digest to - * the pointer. At the last block some special - * rules need to apply. We must add a 1 bit - * following the message, then we pad with - * 0's. The total size is encoded as a 64 bit - * number at the end. Now if the last buffer has - * more than 55 octets in it we cannot fit - * the 64 bit number + 10000000 pad on the end - * and must add the 10000000 pad, pad the rest - * of the message with 0's and then create a - * all 0 message with just the 64 bit size - * at the end and run this block through by itself. - * Also the 64 bit int must be in network byte - * order. - */ - int i, leftToFill; - unsigned int *ptr; - - if (ctx->howManyInBlock > 55) { - /* special case, we need to process two - * blocks here. One for the current stuff - * plus possibly the pad. The other for - * the size. - */ - leftToFill = sizeof(ctx->SLAblock) - ctx->howManyInBlock; - if (leftToFill == 0) { - /* Should not really happen but I am paranoid */ - /* Not paranoid enough! It is possible for leftToFill - * to become negative! AAA!!!! This is another reason - * to pick MD5 :-)... - */ - SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock); - /* init last block, a bit different then the rest :-) */ - ctx->SLAblock[0] = 0x80; - for (i = 1; i < sizeof(ctx->SLAblock); i++) { - ctx->SLAblock[i] = 0x0; - } - } else if (leftToFill == 1) { - ctx->SLAblock[ctx->howManyInBlock] = 0x80; - SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock); - /* init last block */ - memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock)); - } else { - ctx->SLAblock[ctx->howManyInBlock] = 0x80; - for (i = (ctx->howManyInBlock + 1); - i < sizeof(ctx->SLAblock); - i++) { - ctx->SLAblock[i] = 0x0; - } - SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock); - /* init last block */ - memset(ctx->SLAblock, 0, sizeof(ctx->SLAblock)); - } - /* This is in bits so multiply by 8 */ - ctx->runningTotal *= 8; - ptr = (unsigned int *) &ctx->SLAblock[60]; - *ptr = htonl(ctx->runningTotal); - SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock); - } else { - /* easy case, we just pad this - * message to size - end with 0 - * add the magic 0x80 to the next - * word and then put the network byte - * order size in the last spot and - * process the block. - */ - ctx->SLAblock[ctx->howManyInBlock] = 0x80; - for (i = (ctx->howManyInBlock + 1); - i < sizeof(ctx->SLAblock); - i++) { - ctx->SLAblock[i] = 0x0; - } - /* get last int spot */ - ctx->runningTotal *= 8; - ptr = (unsigned int *) &ctx->SLAblock[60]; - *ptr = htonl(ctx->runningTotal); - SLA1processABlock(ctx, (unsigned int *) ctx->SLAblock); - } - /* Now at this point all we need do is transfer the - * digest back to the user - */ - digestBuf[3] = (ctx->H0 & 0xff); - digestBuf[2] = ((ctx->H0 >> 8) & 0xff); - digestBuf[1] = ((ctx->H0 >> 16) & 0xff); - digestBuf[0] = ((ctx->H0 >> 24) & 0xff); - - digestBuf[7] = (ctx->H1 & 0xff); - digestBuf[6] = ((ctx->H1 >> 8) & 0xff); - digestBuf[5] = ((ctx->H1 >> 16) & 0xff); - digestBuf[4] = ((ctx->H1 >> 24) & 0xff); - - digestBuf[11] = (ctx->H2 & 0xff); - digestBuf[10] = ((ctx->H2 >> 8) & 0xff); - digestBuf[9] = ((ctx->H2 >> 16) & 0xff); - digestBuf[8] = ((ctx->H2 >> 24) & 0xff); - - digestBuf[15] = (ctx->H3 & 0xff); - digestBuf[14] = ((ctx->H3 >> 8) & 0xff); - digestBuf[13] = ((ctx->H3 >> 16) & 0xff); - digestBuf[12] = ((ctx->H3 >> 24) & 0xff); - - digestBuf[19] = (ctx->H4 & 0xff); - digestBuf[18] = ((ctx->H4 >> 8) & 0xff); - digestBuf[17] = ((ctx->H4 >> 16) & 0xff); - digestBuf[16] = ((ctx->H4 >> 24) & 0xff); -} diff -Nru a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c --- a/net/sctp/sm_make_chunk.c Fri Jun 27 14:19:53 2003 +++ b/net/sctp/sm_make_chunk.c Fri Jun 27 14:19:53 2003 @@ -589,27 +589,17 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc) { struct sctp_chunk *retval; - sctp_sackhdr_t sack; - sctp_gap_ack_block_t gab; - int length; + struct sctp_sackhdr sack; + int len; __u32 ctsn; - struct sctp_tsnmap_iter iter; __u16 num_gabs, num_dup_tsns; struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; ctsn = sctp_tsnmap_get_ctsn(map); - SCTP_DEBUG_PRINTK("sackCTSNAck sent is 0x%x.\n", ctsn); - - /* Count the number of Gap Ack Blocks. */ - num_gabs = 0; - - if (sctp_tsnmap_has_gap(map)) { - sctp_tsnmap_iter_init(map, &iter); - while (sctp_tsnmap_next_gap_ack(map, &iter, - &gab.start, &gab.end)) - num_gabs++; - } + SCTP_DEBUG_PRINTK("sackCTSNAck sent: 0x%x.\n", ctsn); + /* How much room is needed in the chunk? */ + num_gabs = sctp_tsnmap_num_gabs(map); num_dup_tsns = sctp_tsnmap_num_dups(map); /* Initialize the SACK header. */ @@ -618,12 +608,12 @@ sack.num_gap_ack_blocks = htons(num_gabs); sack.num_dup_tsns = htons(num_dup_tsns); - length = sizeof(sack) - + sizeof(sctp_gap_ack_block_t) * num_gabs + len = sizeof(sack) + + sizeof(struct sctp_gap_ack_block) * num_gabs + sizeof(__u32) * num_dup_tsns; /* Create the chunk. */ - retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, length); + retval = sctp_make_chunk(asoc, SCTP_CID_SACK, 0, len); if (!retval) goto nodata; @@ -662,21 +652,15 @@ retval->subh.sack_hdr = sctp_addto_chunk(retval, sizeof(sack), &sack); - /* Put the Gap Ack Blocks into the chunk. */ - if (num_gabs) { - sctp_tsnmap_iter_init(map, &iter); - while(sctp_tsnmap_next_gap_ack(map, &iter, - &gab.start, &gab.end)) { - gab.start = htons(gab.start); - gab.end = htons(gab.end); - sctp_addto_chunk(retval, sizeof(sctp_gap_ack_block_t), - &gab); - } - } - - /* Register the duplicates. */ - sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, - sctp_tsnmap_get_dups(map)); + /* Add the gap ack block information. */ + if (num_gabs) + sctp_addto_chunk(retval, sizeof(__u32) * num_gabs, + sctp_tsnmap_get_gabs(map)); + + /* Add the duplicate TSN information. */ + if (num_dup_tsns) + sctp_addto_chunk(retval, sizeof(__u32) * num_dup_tsns, + sctp_tsnmap_get_dups(map)); nodata: return retval; @@ -1275,14 +1259,14 @@ const __u8 *raw_addrs, int addrs_len) { sctp_cookie_param_t *retval; - sctp_signed_cookie_t *cookie; + struct sctp_signed_cookie *cookie; struct scatterlist sg; int headersize, bodysize; unsigned int keylen; char *key; headersize = sizeof(sctp_paramhdr_t) + SCTP_SECRET_SIZE; - bodysize = sizeof(sctp_cookie_t) + bodysize = sizeof(struct sctp_cookie) + ntohs(init_chunk->chunk_hdr->length) + addrs_len; /* Pad out the cookie to a multiple to make the signature @@ -1304,7 +1288,7 @@ * out on the network. */ memset(retval, 0x00, *cookie_len); - cookie = (sctp_signed_cookie_t *) retval->body; + cookie = (struct sctp_signed_cookie *) retval->body; /* Set up the parameter header. */ retval->p.type = SCTP_PARAM_STATE_COOKIE; @@ -1351,26 +1335,26 @@ int *error, struct sctp_chunk **errp) { struct sctp_association *retval = NULL; - sctp_signed_cookie_t *cookie; - sctp_cookie_t *bear_cookie; + struct sctp_signed_cookie *cookie; + struct sctp_cookie *bear_cookie; int headersize, bodysize, fixed_size; __u8 digest[SCTP_SIGNATURE_SIZE]; struct scatterlist sg; - unsigned int keylen; + unsigned int keylen, len; char *key; sctp_scope_t scope; struct sk_buff *skb = chunk->skb; headersize = sizeof(sctp_chunkhdr_t) + SCTP_SECRET_SIZE; bodysize = ntohs(chunk->chunk_hdr->length) - headersize; - fixed_size = headersize + sizeof(sctp_cookie_t); + fixed_size = headersize + sizeof(struct sctp_cookie); /* Verify that the chunk looks like it even has a cookie. * There must be enough room for our cookie and our peer's * INIT chunk. */ - if (ntohs(chunk->chunk_hdr->length) < - (fixed_size + sizeof(sctp_chunkhdr_t))) + len = ntohs(chunk->chunk_hdr->length); + if (len < fixed_size + sizeof(struct sctp_chunkhdr)) goto malformed; /* Verify that the cookie has been padded out. */ @@ -1454,7 +1438,7 @@ retval->peer.port = ntohs(chunk->sctp_hdr->source); /* Populate the association from the cookie. */ - retval->c = *bear_cookie; + memcpy(&retval->c, bear_cookie, sizeof(*bear_cookie)); if (sctp_assoc_set_bind_addr_from_cookie(retval, bear_cookie, GFP_ATOMIC) < 0) { @@ -2022,7 +2006,7 @@ ********************************************************************/ /* Convert from an SCTP IP parameter to a union sctp_addr. */ -void sctp_param2sockaddr(union sctp_addr *addr, sctp_addr_param_t *param, +void sctp_param2sockaddr(union sctp_addr *addr, union sctp_addr_param *param, __u16 port, int iif) { switch(param->v4.param_hdr.type) { @@ -2073,7 +2057,7 @@ /* Convert a sockaddr_in to an IP address in an SCTP param. * Returns len if a valid conversion was possible. */ -int sockaddr2sctp_addr(const union sctp_addr *sa, sctp_addr_param_t *p) +int sockaddr2sctp_addr(const union sctp_addr *sa, union sctp_addr_param *p) { int len = 0; diff -Nru a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c --- a/net/sctp/sm_sideeffect.c Fri Jun 27 14:19:59 2003 +++ b/net/sctp/sm_sideeffect.c Fri Jun 27 14:19:59 2003 @@ -608,13 +608,13 @@ } /* Helper function to change the state of an association. */ -static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, struct sctp_association *asoc, +static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, + struct sctp_association *asoc, sctp_state_t state) { struct sock *sk = asoc->base.sk; asoc->state = state; - asoc->state_timestamp = jiffies; if (sctp_style(sk, TCP)) { /* Change the sk->sk_state of a TCP-style socket that has @@ -702,7 +702,7 @@ int gfp) { sctp_cmd_seq_t commands; - sctp_sm_table_entry_t *state_fn; + const sctp_sm_table_entry_t *state_fn; sctp_disposition_t status; int error = 0; typedef const char *(printfn_t)(sctp_subtype_t); diff -Nru a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c --- a/net/sctp/sm_statefuns.c Fri Jun 27 14:19:53 2003 +++ b/net/sctp/sm_statefuns.c Fri Jun 27 14:19:53 2003 @@ -45,6 +45,7 @@ * Dajiang Zhang <dajiang.zhang@nokia.com> * Daisy Chang <daisyc@us.ibm.com> * Ardelle Fan <ardelle.fan@intel.com> + * Ryan Layer <rmlayer@us.ibm.com> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -537,7 +538,7 @@ * are in good shape. */ chunk->subh.cookie_hdr = - (sctp_signed_cookie_t *)chunk->skb->data; + (struct sctp_signed_cookie *)chunk->skb->data; skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); @@ -738,7 +739,7 @@ { struct sctp_transport *transport = (struct sctp_transport *) arg; - if (asoc->overall_error_count > asoc->overall_error_threshold) { + if (asoc->overall_error_count > asoc->max_retrans) { /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -924,16 +925,16 @@ { int len; struct sctp_packet *pkt; - sctp_addr_param_t *addrparm; - sctp_errhdr_t *errhdr; + union sctp_addr_param *addrparm; + struct sctp_errhdr *errhdr; struct sctp_endpoint *ep; - char buffer[sizeof(sctp_errhdr_t) + sizeof(sctp_addr_param_t)]; + char buffer[sizeof(struct sctp_errhdr)+sizeof(union sctp_addr_param)]; /* Build the error on the stack. We are way to malloc crazy * throughout the code today. */ - errhdr = (sctp_errhdr_t *)buffer; - addrparm = (sctp_addr_param_t *)errhdr->variable; + errhdr = (struct sctp_errhdr *)buffer; + addrparm = (union sctp_addr_param *)errhdr->variable; /* Copy into a parm format. */ len = sockaddr2sctp_addr(ssa, addrparm); @@ -1618,7 +1619,7 @@ /* "Decode" the chunk. We have no optional parameters so we * are in good shape. */ - chunk->subh.cookie_hdr = (sctp_signed_cookie_t *)chunk->skb->data; + chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); @@ -1866,7 +1867,7 @@ * yield a higher probability of success on the reattempt. */ stale = ntohl(*(suseconds_t *)((u8 *)err + sizeof(sctp_errhdr_t))); - stale = stale << 1 / 1000; + stale = (stale * 2) / 1000; bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE; bht.param_hdr.length = htons(sizeof(bht)); @@ -1947,22 +1948,23 @@ sctp_cmd_seq_t *commands) { struct sctp_chunk *chunk = arg; + unsigned len; __u16 error = SCTP_ERROR_NO_ERROR; if (!sctp_vtag_verify_either(chunk, asoc)) return sctp_sf_pdiscard(ep, asoc, type, arg, commands); - if (chunk && (ntohs(chunk->chunk_hdr->length) >= - (sizeof(struct sctp_chunkhdr) + - sizeof(struct sctp_errhdr)))) + /* Check that chunk header looks valid. */ + len = ntohs(chunk->chunk_hdr->length); + if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) error = ((sctp_errhdr_t *)chunk->skb->data)->cause; + /* ASSOC_FAILED will DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error)); SCTP_INC_STATS(SctpAborteds); SCTP_DEC_STATS(SctpCurrEstab); - /* BUG? This does not look complete... */ return SCTP_DISPOSITION_ABORT; } @@ -1978,6 +1980,7 @@ sctp_cmd_seq_t *commands) { struct sctp_chunk *chunk = arg; + unsigned len; __u16 error = SCTP_ERROR_NO_ERROR; if (!sctp_vtag_verify_either(chunk, asoc)) @@ -1989,9 +1992,9 @@ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); - if (chunk && (ntohs(chunk->chunk_hdr->length) >= - (sizeof(struct sctp_chunkhdr) + - sizeof(struct sctp_errhdr)))) + /* Check that chunk header looks valid. */ + len = ntohs(chunk->chunk_hdr->length); + if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) error = ((sctp_errhdr_t *)chunk->skb->data)->cause; /* CMD_INIT_FAILED will DELETE_TCB. */ @@ -3201,82 +3204,6 @@ return SCTP_DISPOSITION_CONSUME; } -#if 0 -/* - * We did something stupid but got lucky. Namely, we sent a HEARTBEAT - * before the association was all the way up and we did NOT get an - * ABORT. - * - * Log the fact and then process normally. - * - * Section: Not specified - * Verification Tag: 8.5 Verification Tag [Normal verification] - * Inputs - * (endpoint, asoc, chunk) - * - * Outputs - * (asoc, reply_msg, msg_up, timers, counters) - * - * The return value is the disposition of the chunk. - */ -sctp_disposition_t lucky(const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) -{ - struct sctp_chunk *chunk = arg; - - /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure - * that the value in the Verification Tag field of the - * received SCTP packet matches its own Tag. ... - */ - if (chunk->sctp_hdr->vtag != asoc->c.my_vtag) - return sctp_sf_pdiscard(ep, asoc, type, arg, commands); - - return SCTP_DISPOSITION_CONSUME; - -nomem: - return SCTP_DISPOSITION_NOMEM; -} -#endif /* 0 */ - -#if 0 -/* - * The other end is doing something very stupid. We'll ignore them - * after logging their idiocy. :-) - * - * Section: Not specified - * Verification Tag: 8.5 Verification Tag [Normal verification] - * Inputs - * (endpoint, asoc, chunk) - * - * Outputs - * (asoc, reply_msg, msg_up, timers, counters) - * - * The return value is the disposition of the chunk. - */ -sctp_disposition_t other_stupid(const struct sctp_endpoint *ep, - const struct sctp_association *asoc, - const sctp_subtype_t type, - void *arg, - sctp_cmd_seq_t *commands) -{ - struct sctp_chunk *chunk = arg; - - /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure - * that the value in the Verification Tag field of the - * received SCTP packet matches its own Tag. ... - */ - if (chunk->sctp_hdr->vtag != asoc->c.my_vtag) - return sctp_sf_pdiscard(ep, asoc, type, arg, commands); - - return SCTP_DISPOSITION_CONSUME; - -nomem: - return SCTP_DISPOSITION_NOMEM; -} -#endif /* 0 */ /* * The other end is violating protocol. @@ -4070,7 +3997,7 @@ { struct sctp_transport *transport = arg; - if (asoc->overall_error_count >= asoc->overall_error_threshold) { + if (asoc->overall_error_count >= asoc->max_retrans) { /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -4241,7 +4168,7 @@ struct sctp_chunk *reply = NULL; SCTP_DEBUG_PRINTK("Timer T2 expired.\n"); - if (asoc->overall_error_count >= asoc->overall_error_threshold) { + if (asoc->overall_error_count >= asoc->max_retrans) { /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(SCTP_ERROR_NO_ERROR)); @@ -4500,13 +4427,21 @@ if (asoc) { vtag = asoc->peer.i.init_tag; } else { - /* Special case the INIT as there is no vtag yet. */ - if (SCTP_CID_INIT == chunk->chunk_hdr->type) { + /* Special case the INIT and stale COOKIE_ECHO as there is no + * vtag yet. + */ + switch(chunk->chunk_hdr->type) { + case SCTP_CID_INIT: + { sctp_init_chunk_t *init; + init = (sctp_init_chunk_t *)chunk->chunk_hdr; vtag = ntohl(init->init_hdr.init_tag); - } else { + break; + } + default: vtag = ntohl(chunk->sctp_hdr->vtag); + break; } } @@ -4557,6 +4492,12 @@ if (err_chunk) { packet = sctp_ootb_pkt_new(asoc, chunk); if (packet) { + struct sctp_signed_cookie *cookie; + + /* Override the OOTB vtag from the cookie. */ + cookie = chunk->subh.cookie_hdr; + packet->vtag = cookie->c.peer_vtag; + /* Set the skb to the belonging sock for accounting. */ err_chunk->skb->sk = ep->base.sk; sctp_packet_append_chunk(packet, err_chunk); diff -Nru a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c --- a/net/sctp/sm_statetable.c Fri Jun 27 14:20:05 2003 +++ b/net/sctp/sm_statetable.c Fri Jun 27 14:20:05 2003 @@ -49,7 +49,7 @@ #include <net/sctp/sctp.h> #include <net/sctp/sm.h> -static sctp_sm_table_entry_t bug = { +static const sctp_sm_table_entry_t bug = { .fn = sctp_sf_bug, .name = "sctp_sf_bug" }; @@ -64,9 +64,9 @@ } \ return &_table[event_subtype._type][(int)state]; -sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, - sctp_state_t state, - sctp_subtype_t event_subtype) +const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, + sctp_state_t state, + sctp_subtype_t event_subtype) { switch (event_type) { case SCTP_EVENT_T_CHUNK: @@ -418,7 +418,7 @@ * * For base protocol (RFC 2960). */ -sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { +const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_DATA, TYPE_SCTP_INIT, TYPE_SCTP_INIT_ACK, @@ -437,7 +437,7 @@ }; /* state_fn_t chunk_event_table[][] */ -static sctp_sm_table_entry_t +static const sctp_sm_table_entry_t chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { /* SCTP_STATE_EMPTY */ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, @@ -586,7 +586,7 @@ /* The primary index for this table is the primitive type. * The secondary index for this table is the state. */ -sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = { +const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_PRIMITIVE_ASSOCIATE, TYPE_SCTP_PRIMITIVE_SHUTDOWN, TYPE_SCTP_PRIMITIVE_ABORT, @@ -617,7 +617,7 @@ {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ } -sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { +const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_OTHER_NO_PENDING_TSN, }; @@ -811,7 +811,7 @@ {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ } -sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { +const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { TYPE_SCTP_EVENT_TIMEOUT_NONE, TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE, TYPE_SCTP_EVENT_TIMEOUT_T1_INIT, @@ -823,7 +823,8 @@ TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE, }; -sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, sctp_state_t state) +const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid, + sctp_state_t state) { if (state > SCTP_STATE_MAX) return &bug; diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c --- a/net/sctp/socket.c Fri Jun 27 14:20:06 2003 +++ b/net/sctp/socket.c Fri Jun 27 14:20:06 2003 @@ -48,6 +48,8 @@ * Sridhar Samudrala <samudrala@us.ibm.com> * Inaky Perez-Gonzalez <inaky.gonzalez@intel.com> * Ardelle Fan <ardelle.fan@intel.com> + * Ryan Layer <rmlayer@us.ibm.com> + * Anup Pemmaiah <pemmaiah@cc.usu.edu> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -100,6 +102,7 @@ static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; extern kmem_cache_t *sctp_bucket_cachep; +extern int sctp_assoc_valid(struct sock *sk, struct sctp_association *asoc); /* Look up the association by its id. If this is not a UDP-style * socket, the ID field is always ignored. @@ -110,32 +113,24 @@ /* If this is not a UDP-style socket, assoc id should be ignored. */ if (!sctp_style(sk, UDP)) { - /* Return NULL if the socket state is not ESTABLISHED. It + /* Return NULL if the socket state is not ESTABLISHED. It * could be a TCP-style listening socket or a socket which * hasn't yet called connect() to establish an association. */ if (!sctp_sstate(sk, ESTABLISHED)) return NULL; - /* Get the first and the only association from the list. */ + /* Get the first and the only association from the list. */ if (!list_empty(&sctp_sk(sk)->ep->asocs)) asoc = list_entry(sctp_sk(sk)->ep->asocs.next, struct sctp_association, asocs); return asoc; } - /* First, verify that this is a kernel address. */ - if (sctp_is_valid_kaddr((unsigned long) id)) { - struct sctp_association *temp; - - /* Verify that this _is_ an sctp_association - * data structure and if so, that the socket matches. - */ - temp = (struct sctp_association *)id; - if ((SCTP_ASSOC_EYECATCHER == temp->eyecatcher) && - (temp->base.sk == sk)) - asoc = temp; - } + /* Otherwise this is a UDP-style socket. */ + asoc = (struct sctp_association *)id; + if (!sctp_assoc_valid(sk, asoc)) + return NULL; return asoc; } @@ -1456,7 +1451,7 @@ * spp_pathmaxrxt - This contains the maximum number of * retransmissions before this address shall be * considered unreachable. - */ + */ static int sctp_setsockopt_peer_addr_params(struct sock *sk, char *optval, int optlen) { @@ -1625,6 +1620,110 @@ } /* + * + * 7.1.1 SCTP_RTOINFO + * + * The protocol parameters used to initialize and bound retransmission + * timeout (RTO) are tunable. sctp_rtoinfo structure is used to access + * and modify these parameters. + * All parameters are time values, in milliseconds. A value of 0, when + * modifying the parameters, indicates that the current value should not + * be changed. + * + */ +static int sctp_setsockopt_rtoinfo(struct sock *sk, char *optval, int optlen) { + struct sctp_rtoinfo rtoinfo; + struct sctp_association *asoc; + + if (optlen != sizeof (struct sctp_rtoinfo)) + return -EINVAL; + + if (copy_from_user(&rtoinfo, optval, optlen)) + return -EFAULT; + + asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); + + /* Set the values to the specific association */ + if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) + return -EINVAL; + + if (asoc) { + if (rtoinfo.srto_initial != 0) + asoc->rto_initial = rtoinfo.srto_initial * HZ / 1000; + if (rtoinfo.srto_max != 0) + asoc->rto_max = rtoinfo.srto_max * HZ / 1000; + if (rtoinfo.srto_min != 0) + asoc->rto_min = rtoinfo.srto_min * HZ / 1000; + } else { + /* If there is no association or the association-id = 0 + * set the values to the endpoint. + */ + struct sctp_opt *sp = sctp_sk(sk); + + if (rtoinfo.srto_initial != 0) + sp->rtoinfo.srto_initial = rtoinfo.srto_initial; + if (rtoinfo.srto_max != 0) + sp->rtoinfo.srto_max = rtoinfo.srto_max; + if (rtoinfo.srto_min != 0) + sp->rtoinfo.srto_min = rtoinfo.srto_min; + } + + return 0; +} + +/* + * + * 7.1.2 SCTP_ASSOCINFO + * + * This option is used to tune the the maximum retransmission attempts + * of the association. + * Returns an error if the new association retransmission value is + * greater than the sum of the retransmission value of the peer. + * See [SCTP] for more information. + * + */ +static int sctp_setsockopt_assocrtx(struct sock *sk, char *optval, + int optlen) { + + struct sctp_assocparams assocparams; + struct sctp_association *asoc; + + if (optlen != sizeof(struct sctp_assocparams)) + return -EINVAL; + if (copy_from_user(&assocparams, optval, optlen)) + return -EFAULT; + + asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); + + if (!asoc && assocparams.sasoc_assoc_id && sctp_style(sk, UDP)) + return -EINVAL; + + /* Set the values to the specific association */ + if (asoc) { + if (assocparams.sasoc_asocmaxrxt != 0) + asoc->max_retrans = assocparams.sasoc_asocmaxrxt; + if (assocparams.sasoc_cookie_life != 0) { + asoc->cookie_life.tv_sec = + assocparams.sasoc_cookie_life / 1000; + asoc->cookie_life.tv_usec = + (assocparams.sasoc_cookie_life % 1000) + * 1000; + } + } else { + /* Set the values to the endpoint */ + struct sctp_opt *sp = sctp_sk(sk); + + if (assocparams.sasoc_asocmaxrxt != 0) + sp->assocparams.sasoc_asocmaxrxt = + assocparams.sasoc_asocmaxrxt; + if (assocparams.sasoc_cookie_life != 0) + sp->assocparams.sasoc_cookie_life = + assocparams.sasoc_cookie_life; + } + return 0; +} + +/* * 7.1.16 Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR) * * This socket option is a boolean flag which turns on or off mapped V4 @@ -1771,6 +1870,12 @@ case SCTP_NODELAY: retval = sctp_setsockopt_nodelay(sk, optval, optlen); break; + case SCTP_RTOINFO: + retval = sctp_setsockopt_rtoinfo(sk, optval, optlen); + break; + case SCTP_ASSOCRTXINFO: + retval = sctp_setsockopt_assocrtx(sk, optval, optlen); + break; case SCTP_I_WANT_MAPPED_V4_ADDR: retval = sctp_setsockopt_mappedv4(sk, optval, optlen); break; @@ -2027,15 +2132,25 @@ sp->initmsg.sinit_num_ostreams = sctp_max_outstreams; sp->initmsg.sinit_max_instreams = sctp_max_instreams; sp->initmsg.sinit_max_attempts = sctp_max_retrans_init; - sp->initmsg.sinit_max_init_timeo = sctp_rto_max / HZ; + sp->initmsg.sinit_max_init_timeo = (sctp_rto_max / HZ) * 1000; /* Initialize default RTO related parameters. These parameters can * be modified for with the SCTP_RTOINFO socket option. * FIXME: These are not used yet. */ - sp->rtoinfo.srto_initial = sctp_rto_initial; - sp->rtoinfo.srto_max = sctp_rto_max; - sp->rtoinfo.srto_min = sctp_rto_min; + sp->rtoinfo.srto_initial = (sctp_rto_initial / HZ) * 1000; + sp->rtoinfo.srto_max = (sctp_rto_max / HZ) * 1000; + sp->rtoinfo.srto_min = (sctp_rto_min / HZ) * 1000; + + /* Initialize default association related parameters. These parameters + * can be modified with the SCTP_ASSOCINFO socket option. + */ + sp->assocparams.sasoc_asocmaxrxt = sctp_max_retrans_association; + sp->assocparams.sasoc_number_peer_destinations = 0; + sp->assocparams.sasoc_peer_rwnd = 0; + sp->assocparams.sasoc_local_rwnd = 0; + sp->assocparams.sasoc_cookie_life = (sctp_valid_cookie_life / HZ) + * 1000; /* Initialize default event subscriptions. * the struct sock is initialized to zero, so only @@ -2050,7 +2165,7 @@ /* Default Peer Address Parameters. These defaults can * be modified via SCTP_SET_PEER_ADDR_PARAMS */ - sp->paddrparam.spp_hbinterval = sctp_hb_interval / HZ; + sp->paddrparam.spp_hbinterval = (sctp_hb_interval / HZ) * 1000; sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path; /* If enabled no SCTP message fragmentation will be performed. @@ -2182,7 +2297,8 @@ status.sstat_state = asoc->state; status.sstat_rwnd = asoc->peer.rwnd; status.sstat_unackdata = asoc->unack_data; - status.sstat_penddata = asoc->peer.tsn_map.pending_data; + + status.sstat_penddata = sctp_tsnmap_pending(&asoc->peer.tsn_map); status.sstat_instrms = asoc->c.sinit_max_instreams; status.sstat_outstrms = asoc->c.sinit_num_ostreams; /* Just in time frag_point update. */ @@ -2196,7 +2312,7 @@ status.sstat_primary.spinfo_state = transport->active; status.sstat_primary.spinfo_cwnd = transport->cwnd; status.sstat_primary.spinfo_srtt = transport->srtt; - status.sstat_primary.spinfo_rto = transport->rto; + status.sstat_primary.spinfo_rto = (transport->rto / HZ) * 1000; status.sstat_primary.spinfo_mtu = transport->pmtu; if (put_user(len, optlen)) { @@ -2251,7 +2367,7 @@ pinfo.spinfo_state = transport->active; pinfo.spinfo_cwnd = transport->cwnd; pinfo.spinfo_srtt = transport->srtt; - pinfo.spinfo_rto = transport->rto; + pinfo.spinfo_rto = (transport->rto / HZ) * 1000; pinfo.spinfo_mtu = transport->pmtu; if (put_user(len, optlen)) { @@ -2430,7 +2546,7 @@ * spp_pathmaxrxt - This contains the maximum number of * retransmissions before this address shall be * considered unreachable. - */ + */ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, char *optval, int *optlen) { @@ -2607,7 +2723,7 @@ struct list_head *pos; int cnt = 0; struct sctp_getaddrs getaddrs; - struct sockaddr_storage_list *from; + struct sctp_sockaddr_entry *from; struct sockaddr_storage *to; if (len != sizeof(struct sctp_getaddrs)) @@ -2635,7 +2751,7 @@ to = getaddrs.addrs; list_for_each(pos, &bp->address_list) { from = list_entry(pos, - struct sockaddr_storage_list, + struct sctp_sockaddr_entry, list); if (copy_to_user(to, &from->a, sizeof(from->a))) return -EFAULT; @@ -2763,6 +2879,127 @@ return -EFAULT; return 0; } + +/* + * + * 7.1.1 SCTP_RTOINFO + * + * The protocol parameters used to initialize and bound retransmission + * timeout (RTO) are tunable. sctp_rtoinfo structure is used to access + * and modify these parameters. + * All parameters are time values, in milliseconds. A value of 0, when + * modifying the parameters, indicates that the current value should not + * be changed. + * + */ +static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, char *optval, + int *optlen) { + struct sctp_rtoinfo rtoinfo; + struct sctp_association *asoc; + + if (len != sizeof (struct sctp_rtoinfo)) + return -EINVAL; + + if (copy_from_user(&rtoinfo, optval, sizeof (struct sctp_rtoinfo))) + return -EFAULT; + + asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); + + if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP)) + return -EINVAL; + + /* Values corresponding to the specific association. */ + if (asoc) { + rtoinfo.srto_initial = (asoc->rto_initial / HZ) * 1000; + rtoinfo.srto_max = (asoc->rto_max / HZ) * 1000; + rtoinfo.srto_min = (asoc->rto_min / HZ) * 1000; + } else { + /* Values corresponding to the endpoint. */ + struct sctp_opt *sp = sctp_sk(sk); + + rtoinfo.srto_initial = sp->rtoinfo.srto_initial; + rtoinfo.srto_max = sp->rtoinfo.srto_max; + rtoinfo.srto_min = sp->rtoinfo.srto_min; + } + + if (put_user(len, optlen)) + return -EFAULT; + + if (copy_to_user(optval, &rtoinfo, len)) + return -EFAULT; + + return 0; +} + +/* + * + * 7.1.2 SCTP_ASSOCINFO + * + * This option is used to tune the the maximum retransmission attempts + * of the association. + * Returns an error if the new association retransmission value is + * greater than the sum of the retransmission value of the peer. + * See [SCTP] for more information. + * + */ +static int sctp_getsockopt_assocrtx(struct sock *sk, int len, char *optval, + int *optlen) { + + struct sctp_assocparams assocparams; + struct sctp_association *asoc; + struct list_head *pos; + int cnt = 0; + + if (len != sizeof (struct sctp_assocparams)) + return -EINVAL; + + if (copy_from_user(&assocparams, optval, + sizeof (struct sctp_assocparams))) + return -EFAULT; + + asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); + + if (!asoc && assocparams.sasoc_assoc_id && sctp_style(sk, UDP)) + return -EINVAL; + + /* Values correspoinding to the specific association */ + if (assocparams.sasoc_assoc_id != 0) { + assocparams.sasoc_asocmaxrxt = asoc->max_retrans; + assocparams.sasoc_peer_rwnd = asoc->peer.rwnd; + assocparams.sasoc_local_rwnd = asoc->a_rwnd; + assocparams.sasoc_cookie_life = (asoc->cookie_life.tv_sec + * 1000) + + (asoc->cookie_life.tv_usec + / 1000); + + list_for_each(pos, &asoc->peer.transport_addr_list) { + cnt ++; + } + + assocparams.sasoc_number_peer_destinations = cnt; + } else { + /* Values corresponding to the endpoint */ + struct sctp_opt *sp = sctp_sk(sk); + + assocparams.sasoc_asocmaxrxt = sp->assocparams.sasoc_asocmaxrxt; + assocparams.sasoc_peer_rwnd = sp->assocparams.sasoc_peer_rwnd; + assocparams.sasoc_local_rwnd = sp->assocparams.sasoc_local_rwnd; + assocparams.sasoc_cookie_life = + sp->assocparams.sasoc_cookie_life; + assocparams.sasoc_number_peer_destinations = + sp->assocparams. + sasoc_number_peer_destinations; + } + + if (put_user(len, optlen)) + return -EFAULT; + + if (copy_to_user(optval, &assocparams, len)) + return -EFAULT; + + return 0; +} + /* * 7.1.16 Set/clear IPv4 mapped addresses (SCTP_I_WANT_MAPPED_V4_ADDR) * @@ -2896,6 +3133,12 @@ case SCTP_NODELAY: retval = sctp_getsockopt_nodelay(sk, len, optval, optlen); break; + case SCTP_RTOINFO: + retval = sctp_getsockopt_rtoinfo(sk, len, optval, optlen); + break; + case SCTP_ASSOCRTXINFO: + retval = sctp_getsockopt_assocrtx(sk, len, optval, optlen); + break; case SCTP_I_WANT_MAPPED_V4_ADDR: retval = sctp_getsockopt_mappedv4(sk, len, optval, optlen); break; @@ -2952,7 +3195,6 @@ snum = addr->v4.sin_port; SCTP_DEBUG_PRINTK("sctp_get_port() begins, snum=%d\n", snum); - sctp_local_bh_disable(); if (snum == 0) { @@ -2999,7 +3241,6 @@ * mutex. */ snum = rover; - pp = NULL; } else { /* We are given an specific port number; we verify * that it is not being used. If it is used, we will @@ -3011,23 +3252,23 @@ sctp_spin_lock(&head->lock); for (pp = head->chain; pp; pp = pp->next) { if (pp->port == snum) - break; + goto pp_found; } } - - - if (pp && !hlist_empty(&pp->sk_list)) { + pp = NULL; + goto pp_not_found; +pp_found: + if (!hlist_empty(&pp->owner)) { /* We had a port hash table hit - there is an * available port (pp != NULL) and it is being - * used by other socket (pp->sk_list not empty); that other + * used by other socket (pp->owner not empty); that other * socket is going to be sk2. */ int reuse = sk->sk_reuse; struct sock *sk2; struct hlist_node *node; - SCTP_DEBUG_PRINTK("sctp_get_port() found a " - "possible match\n"); + SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); if (pp->fastreuse && sk->sk_reuse) goto success; @@ -3041,7 +3282,7 @@ * that this port/socket (sk) combination are already * in an endpoint. */ - sk_for_each_bound(sk2, node, &pp->sk_list) { + sk_for_each_bound(sk2, node, &pp->owner) { struct sctp_endpoint *ep2; ep2 = sctp_sk(sk2)->ep; @@ -3056,10 +3297,9 @@ } SCTP_DEBUG_PRINTK("sctp_get_port(): Found a match\n"); } - +pp_not_found: /* If there was a hash table miss, create a new port. */ ret = 1; - if (!pp && !(pp = sctp_bucket_create(head, snum))) goto fail_unlock; @@ -3067,7 +3307,7 @@ * if sk->sk_reuse is too (that is, if the caller requested * SO_REUSEADDR on this socket -sk-). */ - if (hlist_empty(&pp->sk_list)) + if (hlist_empty(&pp->owner)) pp->fastreuse = sk->sk_reuse ? 1 : 0; else if (pp->fastreuse && !sk->sk_reuse) pp->fastreuse = 0; @@ -3079,7 +3319,7 @@ success: inet_sk(sk)->num = snum; if (!sctp_sk(sk)->bind_hash) { - sk_add_bind_node(sk, &pp->sk_list); + sk_add_bind_node(sk, &pp->owner); sctp_sk(sk)->bind_hash = pp; } ret = 0; @@ -3089,8 +3329,6 @@ fail: sctp_local_bh_enable(); - - SCTP_DEBUG_PRINTK("sctp_get_port() ends, ret=%d\n", ret); addr->v4.sin_port = htons(addr->v4.sin_port); return ret; } @@ -3316,7 +3554,7 @@ if (pp) { pp->port = snum; pp->fastreuse = 0; - INIT_HLIST_HEAD(&pp->sk_list); + INIT_HLIST_HEAD(&pp->owner); if ((pp->next = head->chain) != NULL) pp->next->pprev = &pp->next; head->chain = pp; @@ -3328,7 +3566,7 @@ /* Caller must hold hashbucket lock for this tb with local BH disabled */ static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) { - if (hlist_empty(&pp->sk_list)) { + if (hlist_empty(&pp->owner)) { if (pp->next) pp->next->pprev = pp->pprev; *(pp->pprev) = pp->next; @@ -3337,8 +3575,8 @@ } } -/* FIXME: Comments! */ -static __inline__ void __sctp_put_port(struct sock *sk) +/* Release this socket's reference to a local port. */ +static inline void __sctp_put_port(struct sock *sk) { struct sctp_bind_hashbucket *head = &sctp_port_hashtable[sctp_phashfn(inet_sk(sk)->num)]; @@ -3942,6 +4180,7 @@ { struct sctp_opt *oldsp = sctp_sk(oldsk); struct sctp_opt *newsp = sctp_sk(newsk); + struct sctp_bind_bucket *pp; /* hash list port iterator */ struct sctp_endpoint *newep = newsp->ep; struct sk_buff *skb, *tmp; struct sctp_ulpevent *event; @@ -3951,13 +4190,20 @@ */ newsk->sk_sndbuf = oldsk->sk_sndbuf; newsk->sk_rcvbuf = oldsk->sk_rcvbuf; - *newsp = *oldsp; + /* Brute force copy old sctp opt. */ + memcpy(newsp, oldsp, sizeof(struct sctp_opt)); /* Restore the ep value that was overwritten with the above structure * copy. */ newsp->ep = newep; newsp->hmac = NULL; + + /* Hook this new socket in to the bind_hash list. */ + pp = sctp_sk(oldsk)->bind_hash; + sk_add_bind_node(newsk, &pp->owner); + sctp_sk(newsk)->bind_hash = pp; + inet_sk(newsk)->num = inet_sk(oldsk)->num; /* Move any messages in the old socket's receive queue that are for the * peeled off association to the new socket's receive queue. diff -Nru a/net/sctp/sysctl.c b/net/sctp/sysctl.c --- a/net/sctp/sysctl.c Fri Jun 27 14:19:55 2003 +++ b/net/sctp/sysctl.c Fri Jun 27 14:19:55 2003 @@ -1,39 +1,40 @@ -/* SCTP kernel reference Implementation +/* SCTP kernel reference Implementation * Copyright (c) 2002 International Business Machines Corp. * Copyright (c) 2002 Intel Corp. - * + * * This file is part of the SCTP kernel reference Implementation - * - * Sysctl related interfaces for SCTP. - * - * The SCTP reference implementation is free software; - * you can redistribute it and/or modify it under the terms of + * + * Sysctl related interfaces for SCTP. + * + * The SCTP reference implementation 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, or (at your option) * any later version. - * - * The SCTP reference implementation is distributed in the hope that it + * + * The SCTP reference implementation is distributed in the hope that it * will be useful, but WITHOUT ANY WARRANTY; without even the implied * ************************ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with GNU CC; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * + * Boston, MA 02111-1307, USA. + * * Please send any bug reports or fixes you make to the * email address(es): * lksctp developers <lksctp-developers@lists.sourceforge.net> - * + * * Or submit a bug report through the following website: * http://www.sf.net/projects/lksctp * - * Written or modified by: + * Written or modified by: * Mingqin Liu <liuming@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com> * Ardelle Fan <ardelle.fan@intel.com> + * Ryan Layer <rmlayer@us.ibm.com> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -42,42 +43,54 @@ #include <net/sctp/structs.h> #include <linux/sysctl.h> +static ctl_handler sctp_sysctl_jiffies_ms; +static long rto_timer_min = 0; +static long rto_timer_max = 86400000; /* One day */ + static ctl_table sctp_table[] = { { .ctl_name = NET_SCTP_RTO_INITIAL, .procname = "rto_initial", .data = &sctp_rto_initial, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &rto_timer_min, + .extra2 = &rto_timer_max }, { .ctl_name = NET_SCTP_RTO_MIN, .procname = "rto_min", .data = &sctp_rto_min, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &rto_timer_min, + .extra2 = &rto_timer_max }, { .ctl_name = NET_SCTP_RTO_MAX, .procname = "rto_max", .data = &sctp_rto_max, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &rto_timer_min, + .extra2 = &rto_timer_max }, { .ctl_name = NET_SCTP_VALID_COOKIE_LIFE, .procname = "valid_cookie_life", .data = &sctp_valid_cookie_life, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &rto_timer_min, + .extra2 = &rto_timer_max }, { .ctl_name = NET_SCTP_MAX_BURST, @@ -115,19 +128,23 @@ .ctl_name = NET_SCTP_HB_INTERVAL, .procname = "hb_interval", .data = &sctp_hb_interval, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &rto_timer_min, + .extra2 = &rto_timer_max }, { .ctl_name = NET_SCTP_PRESERVE_ENABLE, .procname = "cookie_preserve_enable", .data = &sctp_cookie_preserve_enable, - .maxlen = sizeof(int), + .maxlen = sizeof(long), .mode = 0644, - .proc_handler = &proc_dointvec_jiffies, - .strategy = &sysctl_jiffies + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &rto_timer_min, + .extra2 = &rto_timer_max }, { .ctl_name = NET_SCTP_RTO_ALPHA, @@ -152,7 +169,6 @@ { .ctl_name = NET_SCTP, .procname = "sctp", - .maxlen = 0, .mode = 0555, .child = sctp_table }, @@ -163,7 +179,6 @@ { .ctl_name = CTL_NET, .procname = "net", - .maxlen = 0, .mode = 0555, .child = sctp_net_table }, @@ -182,4 +197,38 @@ void sctp_sysctl_unregister(void) { unregister_sysctl_table(sctp_sysctl_header); +} + +/* Strategy function to convert jiffies to milliseconds. */ +static int sctp_sysctl_jiffies_ms(ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context) { + + if (oldval) { + size_t olen; + + if (oldlenp) { + if (get_user(olen, oldlenp)) + return -EFAULT; + + if (olen != sizeof (int)) + return -EINVAL; + } + if (put_user((*(int *)(table->data) / HZ) * 1000, + (int *)oldval) || + (oldlenp && put_user(sizeof (int), oldlenp))) + return -EFAULT; + } + if (newval && newlen) { + int new; + + if (newlen != sizeof (int)) + return -EINVAL; + + if (get_user(new, (int *)newval)) + return -EFAULT; + + *(int *)(table->data) = (new * HZ) * 1000; + } + return 1; } diff -Nru a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c --- a/net/sctp/tsnmap.c Fri Jun 27 14:20:05 2003 +++ b/net/sctp/tsnmap.c Fri Jun 27 14:20:05 2003 @@ -1,7 +1,7 @@ /* SCTP kernel reference Implementation * Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2001 Motorola, Inc. - * Copyright (c) 2001 International Business Machines, Corp. + * Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001 Intel Corp. * * This file is part of the SCTP kernel reference Implementation @@ -46,7 +46,6 @@ #include <net/sctp/sm.h> static void sctp_tsnmap_update(struct sctp_tsnmap *map); -static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map); static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off, __u16 len, __u16 base, int *started, __u16 *start, @@ -92,7 +91,6 @@ map->cumulative_tsn_ack_point = initial_tsn - 1; map->max_tsn_seen = map->cumulative_tsn_ack_point; map->malloced = 0; - map->pending_data = 0; map->num_dup_tsns = 0; return map; @@ -135,14 +133,6 @@ return dup; } -/* Is there a gap in the TSN map? */ -int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map) -{ - int has_gap; - - has_gap = (map->cumulative_tsn_ack_point != map->max_tsn_seen); - return has_gap; -} /* Mark this TSN as seen. */ void sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) @@ -176,21 +166,6 @@ sctp_tsnmap_update(map); } -void sctp_tsnmap_report_dup(struct sctp_tsnmap *map, __u32 tsn) -{ -} - -/* Retrieve the Cumulative TSN Ack Point. */ -__u32 sctp_tsnmap_get_ctsn(const struct sctp_tsnmap *map) -{ - return map->cumulative_tsn_ack_point; -} - -/* Retrieve the highest TSN we've seen. */ -__u32 sctp_tsnmap_get_max_tsn_seen(const struct sctp_tsnmap *map) -{ - return map->max_tsn_seen; -} /* Dispose of a tsnmap. */ void sctp_tsnmap_free(struct sctp_tsnmap *map) @@ -219,6 +194,10 @@ /* We haven't found a gap yet. */ started = ended = 0; + /* If there are no more gap acks possible, get out fast. */ + if (TSN_lte(map->max_tsn_seen, iter->start)) + return 0; + /* Search the first mapping array. */ if (iter->start - map->base_tsn < map->len) { @@ -304,10 +283,11 @@ } while (map->tsn_map[ctsn - map->base_tsn]); map->cumulative_tsn_ack_point = ctsn - 1; /* Back up one. */ - sctp_tsnmap_update_pending_data(map); } -static void sctp_tsnmap_update_pending_data(struct sctp_tsnmap *map) +/* How many data chunks are we missing from our peer? + */ +__u16 sctp_tsnmap_pending(struct sctp_tsnmap *map) { __u32 cum_tsn = map->cumulative_tsn_ack_point; __u32 max_tsn = map->max_tsn_seen; @@ -339,7 +319,7 @@ } out: - map->pending_data = pending_data; + return pending_data; } /* This is a private helper for finding Gap Ack Blocks. It searches a @@ -359,6 +339,8 @@ * early if we have found the end of the Gap Ack Block. */ + /* Also, stop looking past the maximum TSN seen. */ + /* Look for the start. */ if (!(*started)) { for (; i < len; i++) { @@ -403,4 +385,27 @@ map->tsn_map[gap] = 0; else map->overflow_map[gap - map->len] = 0; +} + +/* How many gap ack blocks do we have recorded? */ +__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map) +{ + struct sctp_tsnmap_iter iter; + int gabs = 0; + + /* Refresh the gap ack information. */ + if (sctp_tsnmap_has_gap(map)) { + sctp_tsnmap_iter_init(map, &iter); + while (sctp_tsnmap_next_gap_ack(map, &iter, + &map->gabs[gabs].start, + &map->gabs[gabs].end)) { + + map->gabs[gabs].start = htons(map->gabs[gabs].start); + map->gabs[gabs].end = htons(map->gabs[gabs].end); + gabs++; + if (gabs >= SCTP_MAX_GABS) + break; + } + } + return gabs; } diff -Nru a/net/sunrpc/cache.c b/net/sunrpc/cache.c --- a/net/sunrpc/cache.c Fri Jun 27 14:19:57 2003 +++ b/net/sunrpc/cache.c Fri Jun 27 14:19:57 2003 @@ -25,6 +25,7 @@ #include <linux/seq_file.h> #include <linux/proc_fs.h> #include <linux/net.h> +#include <linux/workqueue.h> #include <asm/ioctls.h> #include <linux/sunrpc/types.h> #include <linux/sunrpc/cache.h> @@ -165,6 +166,9 @@ static struct file_operations content_file_operations; static struct file_operations cache_flush_operations; +static void do_cache_clean(void *data); +static DECLARE_WORK(cache_cleaner, do_cache_clean, NULL); + void cache_register(struct cache_detail *cd) { cd->proc_ent = proc_mkdir(cd->name, proc_net_rpc); @@ -208,6 +212,9 @@ cd->last_close = 0; list_add(&cd->others, &cache_list); spin_unlock(&cache_list_lock); + + /* start the cleaning process */ + schedule_work(&cache_cleaner); } int cache_unregister(struct cache_detail *cd) @@ -229,6 +236,11 @@ cd->proc_ent = NULL; remove_proc_entry(cd->name, proc_net_rpc); } + if (list_empty(&cache_list)) { + /* module must be being unloaded so its safe to kill the worker */ + cancel_delayed_work(&cache_cleaner); + flush_scheduled_work(); + } return 0; } @@ -319,8 +331,8 @@ if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) queue_loose(current_detail, ch); - if (atomic_read(&ch->refcnt)) - continue; + if (!atomic_read(&ch->refcnt)) + break; } if (ch) { cache_get(ch); @@ -341,6 +353,23 @@ return rv; } +/* + * We want to regularly clean the cache, so we need to schedule some work ... + */ +static void do_cache_clean(void *data) +{ + int delay = 5; + if (cache_clean() == -1) + delay = 30*HZ; + + if (list_empty(&cache_list)) + delay = 0; + + if (delay) + schedule_delayed_work(&cache_cleaner, delay); +} + + /* * Clean all caches promptly. This just calls cache_clean * repeatedly until we are sure that every cache has had a chance to @@ -989,7 +1018,6 @@ struct handle { struct cache_detail *cd; - char *pbuf; }; static void *c_start(struct seq_file *m, loff_t *pos) @@ -1058,17 +1086,21 @@ { struct cache_head *cp = p; struct cache_detail *cd = ((struct handle*)m->private)->cd; - char *pbuf = ((struct handle*)m->private)->pbuf; if (p == (void *)1) - return cd->cache_show(m, cd, NULL, pbuf); + return cd->cache_show(m, cd, NULL); + ifdebug(CACHE) + seq_printf(m, "# expiry=%ld refcnt=%d\n", + cp->expiry_time, atomic_read(&cp->refcnt)); cache_get(cp); if (cache_check(cd, cp, NULL)) - return 0; - cache_put(cp, cd); + /* cache_check does a cache_put on failure */ + seq_printf(m, "# "); + else + cache_put(cp, cd); - return cd->cache_show(m, cd, cp, pbuf); + return cd->cache_show(m, cd, cp); } struct seq_operations cache_content_op = { @@ -1081,26 +1113,19 @@ static int content_open(struct inode *inode, struct file *file) { int res; - char *namebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); struct handle *han; struct cache_detail *cd = PDE(inode)->data; - if (namebuf == NULL) - return -ENOMEM; - han = kmalloc(sizeof(*han), GFP_KERNEL); - if (han == NULL) { - kfree(namebuf); + if (han == NULL) return -ENOMEM; - } - han->pbuf = namebuf; + han->cd = cd; res = seq_open(file, &cache_content_op); - if (res) { - kfree(namebuf); + if (res) kfree(han); - } else + else ((struct seq_file *)file->private_data)->private = han; return res; @@ -1109,7 +1134,6 @@ { struct seq_file *m = (struct seq_file *)file->private_data; struct handle *han = m->private; - kfree(han->pbuf); kfree(han); m->private = NULL; return seq_release(inode, file); diff -Nru a/net/sunrpc/svc.c b/net/sunrpc/svc.c --- a/net/sunrpc/svc.c Fri Jun 27 14:20:04 2003 +++ b/net/sunrpc/svc.c Fri Jun 27 14:20:04 2003 @@ -113,9 +113,12 @@ static int svc_init_buffer(struct svc_rqst *rqstp, unsigned int size) { - int pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE; + int pages; int arghi; + if (size > RPCSVC_MAXPAYLOAD) + size = RPCSVC_MAXPAYLOAD; + pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE; rqstp->rq_argused = 0; rqstp->rq_resused = 0; arghi = 0; diff -Nru a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c --- a/net/sunrpc/svcauth.c Fri Jun 27 14:20:00 2003 +++ b/net/sunrpc/svcauth.c Fri Jun 27 14:20:00 2003 @@ -152,7 +152,8 @@ auth_domain_match(tmp, item), kfree(new); if(!set) return NULL; new=item; atomic_inc(&new->h.refcnt), - /* no update */ + /* no update */, + 0 /* no inplace updates */ ) struct auth_domain *auth_domain_find(char *name) diff -Nru a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c --- a/net/sunrpc/svcauth_unix.c Fri Jun 27 14:19:58 2003 +++ b/net/sunrpc/svcauth_unix.c Fri Jun 27 14:19:58 2003 @@ -209,17 +209,17 @@ auth_domain_put(dom); if (!ipmp) return -ENOMEM; - + cache_flush(); return 0; } static int ip_map_show(struct seq_file *m, struct cache_detail *cd, - struct cache_head *h, - char *pbuf) + struct cache_head *h) { struct ip_map *im; struct in_addr addr; + char *dom = "-no-domain-"; if (h == NULL) { seq_puts(m, "#class IP domain\n"); @@ -228,13 +228,18 @@ im = container_of(h, struct ip_map, h); /* class addr domain */ addr = im->m_addr; + + if (test_bit(CACHE_VALID, &h->flags) && + !test_bit(CACHE_NEGATIVE, &h->flags)) + dom = im->m_client->h.name; + seq_printf(m, "%s %d.%d.%d.%d %s\n", im->m_class, htonl(addr.s_addr) >> 24 & 0xff, htonl(addr.s_addr) >> 16 & 0xff, htonl(addr.s_addr) >> 8 & 0xff, htonl(addr.s_addr) >> 0 & 0xff, - im->m_client->h.name + dom ); return 0; } @@ -250,7 +255,7 @@ .cache_show = ip_map_show, }; -static DefineSimpleCacheLookup(ip_map) +static DefineSimpleCacheLookup(ip_map, 0) int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c --- a/net/sunrpc/svcsock.c Fri Jun 27 14:19:53 2003 +++ b/net/sunrpc/svcsock.c Fri Jun 27 14:19:53 2003 @@ -32,6 +32,7 @@ #include <linux/slab.h> #include <linux/netdevice.h> #include <linux/skbuff.h> +#include <linux/suspend.h> #include <net/sock.h> #include <net/checksum.h> #include <net/ip.h> @@ -1189,6 +1190,9 @@ spin_unlock_bh(&serv->sv_lock); schedule_timeout(timeout); + + if (current->flags & PF_FREEZE) + refrigerator(PF_IOTHREAD); spin_lock_bh(&serv->sv_lock); remove_wait_queue(&rqstp->rq_wait, &wait); diff -Nru a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c --- a/net/sunrpc/sysctl.c Fri Jun 27 14:19:52 2003 +++ b/net/sunrpc/sysctl.c Fri Jun 27 14:19:52 2003 @@ -155,7 +155,6 @@ { .ctl_name = CTL_SUNRPC, .procname = "sunrpc", - .maxlen = 0, .mode = 0555, .child = debug_table }, diff -Nru a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c --- a/net/unix/sysctl_net_unix.c Fri Jun 27 14:19:55 2003 +++ b/net/unix/sysctl_net_unix.c Fri Jun 27 14:19:55 2003 @@ -30,7 +30,6 @@ { .ctl_name = NET_UNIX, .procname = "unix", - .maxlen = 0, .mode = 0555, .child = unix_table }, @@ -41,7 +40,6 @@ { .ctl_name = CTL_NET, .procname = "net", - .maxlen = 0, .mode = 0555, .child = unix_net_table }, diff -Nru a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c --- a/net/xfrm/xfrm_state.c Fri Jun 27 14:19:59 2003 +++ b/net/xfrm/xfrm_state.c Fri Jun 27 14:19:59 2003 @@ -370,11 +370,10 @@ return x; } -void xfrm_state_insert(struct xfrm_state *x) +static void __xfrm_state_insert(struct xfrm_state *x) { unsigned h = xfrm_dst_hash(&x->id.daddr, x->props.family); - spin_lock_bh(&xfrm_state_lock); list_add(&x->bydst, xfrm_state_bydst+h); xfrm_state_hold(x); @@ -386,8 +385,60 @@ if (!mod_timer(&x->timer, jiffies + HZ)) xfrm_state_hold(x); - spin_unlock_bh(&xfrm_state_lock); wake_up(&km_waitq); +} + +void xfrm_state_insert(struct xfrm_state *x) +{ + spin_lock_bh(&xfrm_state_lock); + __xfrm_state_insert(x); + spin_unlock_bh(&xfrm_state_lock); +} + +int xfrm_state_replace(struct xfrm_state *x, int excl) +{ + struct xfrm_state_afinfo *afinfo; + struct xfrm_state *x1; + int err; + + afinfo = xfrm_state_get_afinfo(x->props.family); + x1 = NULL; + + spin_lock_bh(&xfrm_state_lock); + + if (afinfo) { + x1 = afinfo->state_lookup(&x->id.daddr, x->id.spi, x->id.proto); + if (!x1) { + x1 = afinfo->find_acq( + x->props.mode, x->props.reqid, x->id.proto, + &x->id.daddr, &x->props.saddr, 0); + if (x1 && x1->id.spi != x->id.spi && x1->id.spi) { + xfrm_state_put(x1); + x1 = NULL; + } + } + + if (x1 && (excl ? x1->id.spi : xfrm_state_kern(x1))) { + xfrm_state_put(x1); + x1 = NULL; + err = -EEXIST; + goto out; + } + } + + __xfrm_state_insert(x); + err = 0; + +out: + spin_unlock_bh(&xfrm_state_lock); + + if (x1) { + xfrm_state_delete(x1); + xfrm_state_put(x1); + } + + xfrm_state_put_afinfo(afinfo); + return err; } int xfrm_state_check_expire(struct xfrm_state *x) diff -Nru a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c --- a/net/xfrm/xfrm_user.c Fri Jun 27 14:19:57 2003 +++ b/net/xfrm/xfrm_user.c Fri Jun 27 14:19:57 2003 @@ -249,7 +249,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) { struct xfrm_usersa_info *p = NLMSG_DATA(nlh); - struct xfrm_state *x, *x1; + struct xfrm_state *x; int err; err = verify_newsa_info(p, (struct rtattr **) xfrma); @@ -260,16 +260,13 @@ if (!x) return err; - x1 = xfrm_state_lookup(&x->id.daddr, x->id.spi, x->id.proto, x->props.family); - if (x1) { + err = xfrm_state_replace(x, nlh->nlmsg_type == XFRM_MSG_NEWSA); + if (err < 0) { + x->km.state = XFRM_STATE_DEAD; xfrm_state_put(x); - xfrm_state_put(x1); - return -EEXIST; } - xfrm_state_insert(x); - - return 0; + return err; } static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) @@ -563,7 +560,7 @@ } } -static int copy_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma) +static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma) { struct rtattr *rt = xfrma[XFRMA_TMPL-1]; struct xfrm_user_tmpl *utmpl; @@ -619,7 +616,7 @@ } copy_from_user_policy(xp, p); - err = copy_user_tmpl(xp, xfrma); + err = copy_from_user_tmpl(xp, xfrma); if (err) { *errp = err; kfree(xp); @@ -656,6 +653,38 @@ return 0; } +static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb) +{ + struct xfrm_user_tmpl vec[XFRM_MAX_DEPTH]; + int i; + + if (xp->xfrm_nr == 0) + return 0; + + for (i = 0; i < xp->xfrm_nr; i++) { + struct xfrm_user_tmpl *up = &vec[i]; + struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; + + memcpy(&up->id, &kp->id, sizeof(up->id)); + memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); + up->reqid = kp->reqid; + up->mode = kp->mode; + up->share = kp->share; + up->optional = kp->optional; + up->aalgos = kp->aalgos; + up->ealgos = kp->ealgos; + up->calgos = kp->calgos; + } + RTA_PUT(skb, XFRMA_TMPL, + (sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr), + vec); + + return 0; + +rtattr_failure: + return -1; +} + static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) { struct xfrm_dump_info *sp = ptr; @@ -675,29 +704,8 @@ nlh->nlmsg_flags = 0; copy_to_user_policy(xp, p, dir); - - if (xp->xfrm_nr) { - struct xfrm_user_tmpl vec[XFRM_MAX_DEPTH]; - int i; - - for (i = 0; i < xp->xfrm_nr; i++) { - struct xfrm_user_tmpl *up = &vec[i]; - struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; - - memcpy(&up->id, &kp->id, sizeof(up->id)); - memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); - up->reqid = kp->reqid; - up->mode = kp->mode; - up->share = kp->share; - up->optional = kp->optional; - up->aalgos = kp->aalgos; - up->ealgos = kp->ealgos; - up->calgos = kp->calgos; - } - RTA_PUT(skb, XFRMA_TMPL, - (sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr), - vec); - } + if (copy_to_user_tmpl(xp, skb) < 0) + goto nlmsg_failure; nlh->nlmsg_len = skb->tail - b; out: @@ -705,7 +713,6 @@ return 0; nlmsg_failure: -rtattr_failure: skb_trim(skb, b - skb->data); return -1; } @@ -801,6 +808,7 @@ NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ + NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)), /* UPD SA */ }; static struct xfrm_link { @@ -823,6 +831,7 @@ {}, {}, { .doit = xfrm_add_policy }, + { .doit = xfrm_add_sa, }, }; static int xfrm_done(struct netlink_callback *cb) @@ -1012,12 +1021,16 @@ memcpy(&ua->id, &x->id, sizeof(ua->id)); memcpy(&ua->saddr, &x->props.saddr, sizeof(ua->saddr)); + memcpy(&ua->sel, &x->sel, sizeof(ua->sel)); copy_to_user_policy(xp, &ua->policy, dir); ua->aalgos = xt->aalgos; ua->ealgos = xt->ealgos; ua->calgos = xt->calgos; ua->seq = x->km.seq = seq; + if (copy_to_user_tmpl(xp, skb) < 0) + goto nlmsg_failure; + nlh->nlmsg_len = skb->tail - b; return skb->len; @@ -1030,8 +1043,12 @@ struct xfrm_policy *xp, int dir) { struct sk_buff *skb; + size_t len; - skb = alloc_skb(sizeof(struct xfrm_user_acquire) + 16, GFP_ATOMIC); + len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr); + len = RTA_ALIGN(len); + len += NLMSG_ALIGN(NLMSG_LENGTH(sizeof(struct xfrm_user_acquire))); + skb = alloc_skb(len, GFP_ATOMIC); if (skb == NULL) return -ENOMEM; diff -Nru a/security/capability.c b/security/capability.c --- a/security/capability.c Fri Jun 27 14:19:55 2003 +++ b/security/capability.c Fri Jun 27 14:19:55 2003 @@ -158,6 +158,17 @@ current->keep_capabilities = 0; } +int cap_bprm_secureexec (struct linux_binprm *bprm) +{ + /* If/when this module is enhanced to incorporate capability + bits on files, the test below should be extended to also perform a + test between the old and new capability sets. For now, + it simply preserves the legacy decision algorithm used by + the old userland. */ + return (current->euid != current->uid || + current->egid != current->gid); +} + /* moved from kernel/sys.c. */ /* * cap_emulate_setxuid() fixes the effective / permitted capabilities of @@ -271,6 +282,7 @@ EXPORT_SYMBOL(cap_capset_set); EXPORT_SYMBOL(cap_bprm_set_security); EXPORT_SYMBOL(cap_bprm_compute_creds); +EXPORT_SYMBOL(cap_bprm_secureexec); EXPORT_SYMBOL(cap_task_post_setuid); EXPORT_SYMBOL(cap_task_reparent_to_init); EXPORT_SYMBOL(cap_syslog); @@ -289,6 +301,7 @@ .bprm_compute_creds = cap_bprm_compute_creds, .bprm_set_security = cap_bprm_set_security, + .bprm_secureexec = cap_bprm_secureexec, .task_post_setuid = cap_task_post_setuid, .task_reparent_to_init = cap_task_reparent_to_init, diff -Nru a/security/dummy.c b/security/dummy.c --- a/security/dummy.c Fri Jun 27 14:19:54 2003 +++ b/security/dummy.c Fri Jun 27 14:19:54 2003 @@ -122,6 +122,16 @@ return 0; } +static int dummy_bprm_secureexec (struct linux_binprm *bprm) +{ + /* The new userland will simply use the value provided + in the AT_SECURE field to decide whether secure mode + is required. Hence, this logic is required to preserve + the legacy decision algorithm used by the old userland. */ + return (current->euid != current->uid || + current->egid != current->gid); +} + static int dummy_sb_alloc_security (struct super_block *sb) { return 0; @@ -788,6 +798,7 @@ set_to_dummy_if_null(ops, bprm_compute_creds); set_to_dummy_if_null(ops, bprm_set_security); set_to_dummy_if_null(ops, bprm_check_security); + set_to_dummy_if_null(ops, bprm_secureexec); set_to_dummy_if_null(ops, sb_alloc_security); set_to_dummy_if_null(ops, sb_free_security); set_to_dummy_if_null(ops, sb_kern_mount);